#include #include #include #include "eval.h" #include "hashtable.h" #include "parse.h" hashtable_t* ht; const int hashtableSize = 1000; 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}; void init_eval() { ht = init_hashtable(hashtableSize); } /* TODO: read base hashtable from file to allow modularity pair value value? */ void exec_all(sym_t** symbols, int count) { for (int i = 0; i < count; i++) { /* dispose of result */ eval(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 { printf("no matching pair in hashtable\n"); return NULL; } } } else { printf("no symbol province\n"); 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 */ exec_all(symbol->args, symbol->argCount); return &trueSym; } else if (hash == get_hash("store")) { /* TODO: scope */ /* first arg is value, remaining args are names */ /* TODO: recursion for multiple pairs */ char* k = symtos(eval(symbol->args[1])); sym_t* v = eval(symbol->args[0]); pair_t* p = init_pair(k, (void*)v); 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("if")) { sym_t* v = eval(symbol->args[0]); if (symtoi(v) != 0) { exec_all(symbol->args + 1, symbol->argCount - 1); return &trueSym; } return &falseSym; } else if (hash == get_hash("not")) { sym_t* v = eval(symbol->args[0]); int b = symtoi(v); return b ? &falseSym : &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; } }