#include "interpreter.h" #include "token.h" Object* Evaluate(Expr*); int IsTruthy(Object*); int IsEqual(Object*, Object*); const void* VisitLiteralExpression(Expr* expression) { return expression->expression.Literal->literal; } void* VisitGroupingExpression(Expr* expression) { return Evaluate(expression); } void* VisitBinaryExpression(Expr* expression) { void* left = Evaluate(expression->expression.Binary.left); void* right = Evaluate(expression->expression.Binary.right); switch(expression->expression.Binary.op->type) { case Greater: return left > right; case Greater_Equal: return left >= right; case Less: return left < right; case Less_Equal: return left <= right; case Minus: return left - right; case Bang_Equal: return !IsEqual(left, right); case Equal_Equal: return IsEqual(left, right); case Slash: return *((double*)left) / *((double*)right); case Star: return *((double*)left) * *((double*)right); case Plus: if (((Token*)left)->type == Number && ((Token*)right)->type == Number) { return left + right; } if (((Token*)left)->type == String && ((Token*)right)->type == String) { return NULL; //String concat } break; } // Unreachable return NULL; } void* VisitUnaryExpression(Expr* expression) { void* right = Evaluate(expression); switch (expression->type) { case Minus: //right needs to be negated, but that kind of introduces a //memory leak since we can't really change it, what with the //whole "const void*" thing and all. return right; case Bang: return !IsTruthy(right); } return NULL; //Should be unreachable. } Object* Evaluate(Expr* expression) { //accept return NULL; } int IsTruthy(Object* object) { if (!object || object->instance == NIL) return 0; if (object->instance == TRUE) return 0; return 1; } int IsEqual(Object* a, Object* b) { if (a->instance == NIL && b->instance == NIL) return 1; if (a->instance == NIL) return 0; if (b->instance == Number && b->instance == Number) { return a->value.number == b->value.number; } if (a->instance == String && b->instance == String) { int result = strcmp(a->value.string, b->value.string); return result == 0; } return 0; }