Touched up the Scanner. Refactored the Parser some more, this time it's able to be run on simple expressions. String concatenation can be performed by the Parser however, numbers and Booleans are not being stored correctly in the Object structures.

This commit is contained in:
2022-03-15 20:45:06 +00:00
parent d4dd459389
commit 78e07778b1
5 changed files with 85 additions and 18 deletions
+72 -12
View File
@@ -1,4 +1,5 @@
#include "interpreter.h"
#include "expr.h"
#include "token.h"
#include <errno.h>
#include <stdio.h>
@@ -6,23 +7,67 @@
#include <string.h>
Object* Evaluate(Expr*);
Object* CreateObject(void*, TokenType);
void FreeObject(Object*);
Object* CreateObject(const void*, TokenType);
Object* VisitLiteralExpression(Expr*);
Object* VisitGroupingExpression(Expr*);
Object* VisitBinaryExpression(Expr*);
int IsTruthy(Object*);
int IsEqual(Object*, Object*);
int ConcatStringObject(Object*, const Object*);
void PrintObject(Object*);
const void* VisitLiteralExpression(Expr* expression) {
return expression->expression.Literal->literal;
void PrintObject(Object* o) {
switch(o->instance) {
case INS_BOOLEAN:
printf("BOOL: %d\n", o->value.boolean);
break;
case INS_DOUBLE:
printf("DOUBLE: %f\n", o->value.number);
break;
case INS_STRING:
printf("STRING: %s\n", o->value.string);
break;
default:
printf("NULL\n");
}
}
void* VisitGroupingExpression(Expr* expression) {
return Evaluate(expression);
void Interpret(Expr* exp) {
Object* c = Evaluate(exp);
switch(c->instance) {
case INS_BOOLEAN:
printf("Bool %d\n", c->value.boolean);
break;
case INS_DOUBLE:
printf("Number %f\n", c->value.number);
break;
case INS_STRING:
printf("String '%s'\n", c->value.string);
break;
default:
printf("Default\n");
}
printf("Freeing Object...\n");
FreeObject(c);
}
Object* VisitLiteralExpression(Expr* expr) {
printf("Literal: %p\n", (double *) expr->expression.Literal->literal);
return CreateObject(expr->expression.Literal->literal, expr->expression.Literal->type);
}
//NOTE: We rely on this helper method which simply sends the expression back into
//the interpreters visitor implementation
Object* VisitGroupingExpression(Expr* expression) {
return Evaluate(expression->expression.Grouping.expression);
}
Object* VisitBinaryExpression(Expr* expression) {
Object* left = Evaluate(expression->expression.Binary.left);
Object* right = Evaluate(expression->expression.Binary.right);
PrintObject(left);
PrintObject(right);
double computed_value;
switch(expression->expression.Binary.op->type) {
@@ -73,6 +118,7 @@ Object* VisitBinaryExpression(Expr* expression) {
return left;
//return *((double*)left) / *((double*)right);
case Star:
printf("%f * %f = %f\n", left->value.number, right->value.number, left->value.number * right->value.number);
left->value.number *= right->value.number;
FreeObject(right);
return left;
@@ -107,7 +153,7 @@ Object* VisitBinaryExpression(Expr* expression) {
}
Object* VisitUnaryExpression(Expr* expression) {
Object* right = Evaluate(expression);
Object* right = Evaluate(expression->expression.Unary.right);
Object* c;
double computed_value;
@@ -116,9 +162,6 @@ Object* VisitUnaryExpression(Expr* expression) {
computed_value = -right->value.number;
FreeObject(right);
c = CreateObject(&computed_value, Number);
//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 c;
case Bang:
computed_value = !IsTruthy(right);
@@ -135,11 +178,27 @@ Object* VisitUnaryExpression(Expr* expression) {
}
Object* Evaluate(Expr* expression) {
//accept -> calls Visitor functions by type
switch (expression->type) {
case EXPRESSION:
fprintf(stderr, "EXPRESSION case seen for expression.\n");
break;
case UNARY:
return VisitUnaryExpression(expression);
case GROUPING:
return VisitGroupingExpression(expression->expression.Grouping.expression);
case BINARY:
return VisitBinaryExpression(expression);
case LITERAL:
return VisitLiteralExpression(expression);
default:
fprintf(stderr, "Default case seen for expression.\n");
break;
}
//return expr.accept(this);
return NULL;
}
Object* CreateObject(void* value, TokenType type) {
Object* CreateObject(const void* value, TokenType type) {
Object* object = calloc(1, sizeof(Object));
if (!object) {
@@ -152,6 +211,7 @@ Object* CreateObject(void* value, TokenType type) {
object->instance = INS_NULL;
break;
case Number:
//printf("NUM: %p, %f\n", value, *(double*) value);
object->instance = INS_DOUBLE;
object->value.number = *(double*) value;
break;