Trying a more object oriented approach and created an 'Object' struct to have metadata for the values the interpreter works with.
This commit is contained in:
+20
-11
@@ -1,9 +1,9 @@
|
|||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
void* Evaluate(Expr*);
|
Object* Evaluate(Expr*);
|
||||||
int IsTruthy(void*);
|
int IsTruthy(Object*);
|
||||||
int IsEqual(void*, void*);
|
int IsEqual(Object*, Object*);
|
||||||
|
|
||||||
const void* VisitLiteralExpression(Expr* expression) {
|
const void* VisitLiteralExpression(Expr* expression) {
|
||||||
return expression->expression.Literal->literal;
|
return expression->expression.Literal->literal;
|
||||||
@@ -66,22 +66,31 @@ void* VisitUnaryExpression(Expr* expression) {
|
|||||||
return NULL; //Should be unreachable.
|
return NULL; //Should be unreachable.
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Evaluate(Expr* expression) {
|
Object* Evaluate(Expr* expression) {
|
||||||
//accept
|
//accept
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IsTruthy(void* object) {
|
int IsTruthy(Object* object) {
|
||||||
if (!object) return 0;
|
if (!object || object->instance == NIL) return 0;
|
||||||
if (*((int *) object) == 0) return 0;
|
if (object->instance == TRUE) return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IsEqual(void* a, void* b) {
|
int IsEqual(Object* a, Object* b) {
|
||||||
if (!a && !b) return 1;
|
if (a->instance == NIL && b->instance == NIL) return 1;
|
||||||
if (!a) return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
//Oh this'll be fun...
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,17 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
typedef struct Object {
|
||||||
|
TokenType instance;
|
||||||
|
union {
|
||||||
|
char* string;
|
||||||
|
double number;
|
||||||
|
int boolean;
|
||||||
|
} value;
|
||||||
|
} Object;
|
||||||
|
|
||||||
const void* VisitLiteralExpression(Expr*);
|
const void* VisitLiteralExpression(Expr*);
|
||||||
void* VisitGroupingExpression(Expr*);
|
void* VisitGroupingExpression(Expr*);
|
||||||
|
void* VisitBinaryExpression(Expr*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
KeyValuePair TokenTypeMappings[TOKENTYPE_MAPPINGS_COUNT] = {
|
KeyValuePair TokenTypeMappings[TOKENTYPE_MAPPINGS_COUNT] = {
|
||||||
{ "(", LParen}, { ")", RParen}, { ",", Comma }, { ".", Dot },
|
{ "(", LParen}, { ")", RParen}, { ",", Comma }, { ".", Dot },
|
||||||
@@ -36,7 +38,7 @@ Token* CreateToken(const char* lexeme, void* literal, int line, TokenType type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
token->literal = mapping_result;
|
if (type != NIL) token->literal = mapping_result;
|
||||||
token->lexeme = mapping_result;
|
token->lexeme = mapping_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,3 +63,31 @@ void FreeToken(Token* token) {
|
|||||||
|
|
||||||
free(token);
|
free(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* GetTokenStringValue(Token* token, int* length) {
|
||||||
|
length = 0;
|
||||||
|
|
||||||
|
if (!token) return NULL;
|
||||||
|
if (token->type != String) return NULL;
|
||||||
|
|
||||||
|
*length = strlen(token->lexeme);
|
||||||
|
|
||||||
|
if (length == 0) return NULL;
|
||||||
|
|
||||||
|
char* value = calloc(strlen(token->lexeme) + 1, sizeof(char));
|
||||||
|
|
||||||
|
strncpy(value, token->lexeme, *length);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTokenNumberValue(Token* token, double* value) {
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
if (!token) return 0;
|
||||||
|
if (token->type != Number) return 0;
|
||||||
|
|
||||||
|
*value = *((double*)token->literal);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -50,6 +50,8 @@ extern KeyValuePair TokenTypeMappings[TOKENTYPE_MAPPINGS_COUNT];
|
|||||||
|
|
||||||
//If the first parameter is NULL, the token creation will attempt to infer the lexeme from the TokenType.
|
//If the first parameter is NULL, the token creation will attempt to infer the lexeme from the TokenType.
|
||||||
Token* CreateToken(const char*, void*, int, TokenType);
|
Token* CreateToken(const char*, void*, int, TokenType);
|
||||||
|
char* GetTokenStringValue(Token*, int*);
|
||||||
|
int GetTokenNumberValue(Token*, double*);
|
||||||
void FreeToken(Token*);
|
void FreeToken(Token*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user