#include #include #include #include "precedent.h" #include "hashtable.h" #include "parse.h" hashtable_t* ht; const int trueVal = 1; sym_t trueSym = {LITERAL, INT, (void*)&trueVal, NULL, 0}; const int falseVal = 0; sym_t falseSym = {LITERAL, INT, (void*)&falseVal, NULL, 0}; int main() { sym_t* finalSymbol = parse_symbol_final("print(eq(0; 1;))"); printf("drawing program:\n"); write_symbol_visual(finalSymbol, 0); printf("\nexecuting program:\n"); ht = init_hashtable(1000); eval(finalSymbol); return 0; } /* TODO: read base hashtable from file to allow modularity pair value value? */ void exec_all(symset_t symset) { for (int i = 0; i < symset.count; i++) { /* dispose of result */ eval(symset.symbols[i]); } } sym_t* eval(sym_t* symbol) { if (symbol->province == LITERAL) { return(symbol); } else if (symbol->province == KEY_REF) { sym_t* ir = try_eval_internal(symbol); if (ir != NULL) { return ir; } else { /* not an internal function, search hashtable for next symbol */ /* TODO: scope */ pair_t* p = hashtable_get_pair(ht, (char*)symbol->name); if (p != NULL) { return eval((sym_t*)p->value); } else { return NULL; } } } else { return NULL; } } /* internal functions? this function has side-effects */ sym_t* try_eval_internal(sym_t* symbol) { unsigned int hash = get_hash((char*)symbol->name); /* TODO: return last arg. that's the function return line */ if (hash == get_hash("root")) { /* execute all args as roots */ symset_t symset; symset.symbols = symbol->args; symset.count = symbol->argCount; exec_all(symset); return &trueSym; } else if (hash == get_hash("store")) { /* TODO: scope */ /* first arg is value, remaining args are names */ /* TODO: recursion for multiple pairs */ sym_t* v = eval(symbol->args[0]); char* key = symtos(v); sym_t* value = symbol->args[0]; pair_t* p = init_pair(key, (void*)value); hashtable_add_pair(ht, p); return &trueSym; } else if (hash == get_hash("eq")) { litType_t type = NO_TYPE; void* lastVal = NULL; for (int i = 0; i < symbol->argCount; i++) { sym_t* v = eval(symbol->args[i]); /* initialize */ if (type == NO_TYPE) { type = v->litType; lastVal = v->name; } else { /* interpret type */ if (type == INT) { if (symtoi(v) != *((int*)lastVal)) { return &falseSym; } } if (type == STRING) { if (strcmp(symtos(v), (char*)lastVal) != 0) { return &falseSym; } } /* TODO: float */ } } return &trueSym; } else if (hash == get_hash("print")) { sym_t* v = eval(symbol->args[0]); switch (v->litType) { case NO_TYPE: break; case INT: printf("%d\n", symtoi(v)); break; case FLOAT: break; case STRING: printf("%s\n", symtos(v)); break; } return &trueSym; } else { return NULL; } }