diff --git a/expr.c b/expr.c index 42515bd..351907d 100644 --- a/expr.c +++ b/expr.c @@ -1,6 +1,18 @@ #include "expr.h" -void VisitBinary(struct binary); +char* Parenthesize(char*, int, ...); + +void VisitBinary(struct binary expr) { + +} + void VisitGrouping(struct grouping); void VisitLiteral(Token); -void VisitUnary(struct unary); \ No newline at end of file +void VisitUnary(struct unary); + +char* Parenthesize(char* operator, int count, ...) { + va_list list; + va_start(list, count); + + va_arg(list, Expr); +} \ No newline at end of file diff --git a/expr.h b/expr.h index ba0ff14..02334d1 100644 --- a/expr.h +++ b/expr.h @@ -2,6 +2,7 @@ #define EXPRESSION_H #include "scanner.h" +#include typedef enum { EXPRESSION, diff --git a/interpreter.c b/interpreter.c new file mode 100644 index 0000000..337bacb --- /dev/null +++ b/interpreter.c @@ -0,0 +1,87 @@ +#include "interpreter.h" +#include "token.h" + +void* Evaluate(Expr*); +int IsTruthy(void*); +int IsEqual(void*, void*); + +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. +} + +void* Evaluate(Expr* expression) { + //accept + return NULL; +} + +int IsTruthy(void* object) { + if (!object) return 0; + if (*((int *) object) == 0) return 0; + + return 1; +} + +int IsEqual(void* a, void* b) { + if (!a && !b) return 1; + if (!a) return 0; + + //Oh this'll be fun... + return 0; +} \ No newline at end of file diff --git a/interpreter.h b/interpreter.h new file mode 100644 index 0000000..5dc0981 --- /dev/null +++ b/interpreter.h @@ -0,0 +1,10 @@ +#ifndef INTERPRETER_H +#define INTERPRETER_H + +#include "expr.h" +#include "token.h" + +const void* VisitLiteralExpression(Expr*); +void* VisitGroupingExpression(Expr*); + +#endif \ No newline at end of file