diff --git a/src/ast_interpreter.c b/src/ast_interpreter.c index 1edde294b1520692cb99f5f59d625942b47f9f63..48f8976d9c0aebdea1b7ce805dfaabbcd6ffc22c 100644 --- a/src/ast_interpreter.c +++ b/src/ast_interpreter.c @@ -5,11 +5,11 @@ #include "parser.h" #include "ast_interpreter.h" -bool value_to_bool ( Value value ) { - if ( value . kind == VALUE_NULL ) +bool value_to_bool ( Value * value ) { + if ( value -> kind == VALUE_NULL ) return false; - if ( value . kind == VALUE_BOOLEAN ) - return value . boolean; + if ( value -> kind == VALUE_BOOLEAN ) + return ((BoolValue*) value ) -> boolean; return true; } @@ -31,7 +31,7 @@ void env_pop ( ASTInterpreterState * state ) { free (tmp); } -void env_put ( ASTInterpreterState * state, Str name, Value value ) { +void env_put ( ASTInterpreterState * state, Str name, Value * value ) { Environment * env = state -> current_env; EnvironmentEntry * entry; while ( env ) { @@ -58,11 +58,9 @@ void env_put ( ASTInterpreterState * state, Str name, Value value ) { entry = (EnvironmentEntry*) malloc ( sizeof (EnvironmentEntry) ); (*entry) = (EnvironmentEntry) {.name = name, .value = value, .next = env -> start }; env -> start = entry; - // fprintf ( stderr, "Variable with name %.*s does not exist.\n", (int) name . len, name . str ); - // exit ( 1 ); } -void env_def ( ASTInterpreterState * state, Str name, Value value ) { +void env_def ( ASTInterpreterState * state, Str name, Value * value ) { Environment * env = state -> current_env ? state -> current_env : & state -> global_env; EnvironmentEntry * parent = NULL; EnvironmentEntry * entry = env -> start; @@ -70,8 +68,6 @@ void env_def ( ASTInterpreterState * state, Str name, Value value ) { if ( str_eq ( name, entry -> name ) ) { entry -> value = value; return; - //fprintf ( stderr, "Variable with name %.*s already exists.\n", (int) name . len, name . str ); - //exit ( 1 ); } parent = entry; entry = entry -> next; @@ -102,9 +98,6 @@ Value env_get ( ASTInterpreterState * state, Str name ) { return entry -> value; entry = entry -> next; } - // fprintf ( stderr, "Variable with name %.*s does not exist.\n", (int) name . len, name . str ); - // exit ( 1 ); - // return (Value) { .kind = VALUE_NULL }; env = state -> current_env; env = env ? env : & state -> global_env; entry = (EnvironmentEntry*) malloc ( sizeof (EnvironmentEntry) ); @@ -113,15 +106,25 @@ Value env_get ( ASTInterpreterState * state, Str name ) { return entry -> value; } -void * heap_alloc ( Heap * heap, size_t len, size_t align ) { +void * heap_alloc_alligned ( Heap * heap, size_t len, size_t align ) { size_t pos = (size_t) heap -> next; size_t rem = pos % align; if ( rem ) heap -> next = heap -> next + align - rem; + if ( heap -> next + len >= heap -> end ) + return NULL; + void * ret = heap -> next; + heap -> next += len; + return ret; +} - if ( heap -> next >= heap -> end ) - return NULL; - +void * heap_alloc ( Heap * heap, size_t len ) { + size_t pos = (size_t) heap -> next; + size_t rem = pos % 8; + if ( rem ) + heap -> next = heap -> next + 8 - rem; + if ( heap -> next + len >= heap -> end ) + return NULL; void * ret = heap -> next; heap -> next += len; return ret; @@ -164,6 +167,24 @@ void state_destroy ( ASTInterpreterState * state ) { } } +NullValue * make_null ( ASTInterpreterState * state ) { + NullValue * value = heap_alloc ( state -> heap, sizeof (NullValue) ); + *value = (NullValue) { .kind = (Value) { .kind = VALUE_NULL } }; + return value; +} + +IntValue * make_int ( ASTInterpreterState * state, i32 val ) { + IntValue * value = heap_alloc ( state -> heap, sizeof (IntValue) ); + *value = (IntValue) { .kind = (Value) { .kind = VALUE_INTEGER }, .integer = val }; + return value; +} + +BoolValue * make_bool ( ASTInterpreterState * state, bool val ) { + BoolValue * value = heap_alloc ( state -> heap, sizeof (BoolValue) ); + *value = (BoolValue) { .kind = (Value) { .kind = VALUE_BOOLEAN }, .boolean = val }; + return value; +} + Value * get_base ( Value * object ) { Value * curr = object; Object * tmp; @@ -174,7 +195,7 @@ Value * get_base ( Value * object ) { return curr; } -Value try_operator ( Value object, Value * arguments, size_t argc, Str * name ) { +Value * try_operator ( Value object, Value * arguments, size_t argc, Str * name ) { switch ( object . kind ) { case VALUE_INTEGER: { if ( argc != 1 ) { @@ -267,19 +288,17 @@ Value try_operator ( Value object, Value * arguments, size_t argc, Str * name ) default: break; } - //fprintf ( stderr, "Method %.*s does not exist.\n", (int) name -> len, name -> str ); - //exit ( 13 ); - return (Value) { .kind = VALUE_INVALID }; + return NULL; } -Value function_call ( ASTInterpreterState * state, Value callee, bool is_function, Ast ** arguments, size_t argc, Str * name ) { +Value function_call ( ASTInterpreterState * state, Value * callee, bool is_function, Ast ** arguments, size_t argc, Str * name ) { Value * values = (Value *) malloc ( argc * sizeof (Value) ); for ( size_t i = 0; i < argc; ++i ) values [ i ] = evaluate ( state, arguments [ i ] ); - Value ret = (Value) { .kind = VALUE_NULL }; - Value function = callee; + Value * ret = NULL; + Value * function = callee; if ( ! is_function ) { - function = (Value) { .kind = VALUE_NULL }; + function = NULL; Value * next = &callee; Value * curr; Object * tmp; @@ -297,18 +316,11 @@ Value function_call ( ASTInterpreterState * state, Value callee, bool is_functio if ( function . kind == VALUE_NULL ) { curr = &callee; Value * base = get_base ( &callee ); - //while ( curr ) { ret = try_operator ( *base, values, argc, name ); - if ( ret . kind != VALUE_INVALID ) { + if ( ! ret ) { free ( values ); return ret; } - // if ( curr -> kind == VALUE_OBJECT ) { - // tmp = (Object *) curr -> address; - // curr = &tmp -> extends; - // } else - // break; - //} free ( values ); fprintf ( stderr, "Method %.*s does not exist for this object and/or arguments.\n", (int) name -> len, name -> str ); exit ( 13 ); @@ -318,20 +330,19 @@ Value function_call ( ASTInterpreterState * state, Value callee, bool is_functio exit ( 4 ); } Environment * tmp; - //if ( is_function ) { - tmp = state -> current_env; - state -> current_env = NULL; - //} + tmp = state -> current_env; + state -> current_env = NULL; env_push ( state ); - env_def ( state, STR ("this"), is_function ? (Value) { .kind = VALUE_NULL } : callee ); + env_def ( state, STR ("this"), is_function ? make_null ( state ) : callee ); for ( size_t i = 0; i < argc; ++i ) env_def ( state, function . function -> parameters [ i ], values [ i ] ); ret = evaluate ( state, function . function -> body ); env_pop ( state ); - //if ( is_function ) - state -> current_env = tmp; + state -> current_env = tmp; free ( values ); + if ( ! ret ) + ret = make_null ( state ); return ret; } @@ -403,7 +414,7 @@ void print_value ( Value value ) { } } -void fml_print ( Str format, Value * args, size_t argc ) { +void fml_print ( Str format, Value ** args, size_t argc ) { u8 c; size_t arg = 0; for ( size_t i = 0; i < format . len; ++i ) { @@ -448,19 +459,19 @@ void fml_print ( Str format, Value * args, size_t argc ) { Value evaluate ( ASTInterpreterState * state, Ast * ast ) { switch ( ast -> kind ) { case AST_INTEGER: - return (Value) { .kind = VALUE_INTEGER, .integer = ((AstInteger*) ast ) -> value }; + return make_int ( state, ((AstInteger*) ast ) -> value ); case AST_BOOLEAN: - return (Value) { .kind = VALUE_BOOLEAN, .boolean = ((AstBoolean*) ast ) -> value }; + return make_int ( state, ((AstBoolean*) ast ) -> value ); case AST_NULL: - return (Value) { .kind = VALUE_NULL }; + return make_null ( state ); case AST_PRINT: { AstPrint * printAst = (AstPrint*) ast; - Value * args = (Value *) malloc ( sizeof (Value) * printAst -> argument_cnt ); + Value ** args = (Value **) malloc ( sizeof (Value*) * printAst -> argument_cnt ); for ( size_t i = 0; i < printAst -> argument_cnt; ++i ) args [ i ] = evaluate ( state, printAst -> arguments [ i ] ); fml_print ( printAst -> format, args, printAst -> argument_cnt ); free ( args ); - return (Value) { .kind = VALUE_NULL }; + return make_null ( state ); } case AST_TOP: { AstTop * topAst = (AstTop*) ast; @@ -509,10 +520,12 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) { evaluate ( state, loopAst -> body ); env_pop ( state ); } - return (Value) { .kind = VALUE_NULL }; + return (NullValue) { .kind = (Value) { .kind = VALUE_NULL } }; } case AST_FUNCTION: - return (Value) { .kind = VALUE_FUNCTION, .function = (AstFunction*) ast }; + FunctionValue * value = heap_alloc ( state -> heap, sizeof (FunctionValue) ); + *value = (FunctionValue) { .kind = (Value) { .kind = VALUE_FUNCTION }, .function = (AstFunction*) ast }; + return *value; case AST_FUNCTION_CALL: { AstFunctionCall * callAst = (AstFunctionCall*) ast; Value function = evaluate ( state, callAst -> function ); @@ -534,7 +547,7 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) { fprintf ( stderr, "Invalid array size.\n" ); exit ( 5 ); } - Value * addr = (Value*) heap_alloc ( state -> heap, sizeof (Value) * (size . integer + 1), alignof (Value) ); + Value * addr = (Value*) heap_alloc ( state -> heap, sizeof (ArrayValue) + sizeof (Value) * (size . integer) ); addr [ 0 ] = (Value) { .kind = VALUE_INTEGER, .integer = size . integer }; for ( i32 i = 1; i <= size . integer; ++i ) { env_push ( state ); @@ -562,10 +575,10 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) { case AST_OBJECT: { AstObject * objAst = (AstObject*) ast; Value extends = evaluate ( state, objAst -> extends ); - Object * addr = (Object*) heap_alloc ( state -> heap, sizeof (Object), alignof (Object) ); + Object * addr = (Object*) heap_alloc ( state -> heap, sizeof (Object) ); addr -> member_cnt = objAst -> member_cnt; addr -> extends = extends; - addr -> members = (SimpleEntry*) heap_alloc ( state -> heap, sizeof (SimpleEntry) * addr -> member_cnt, alignof (SimpleEntry) ); + addr -> members = (SimpleEntry*) heap_alloc ( state -> heap, sizeof (SimpleEntry) * addr -> member_cnt ); Value value; AstDefinition * defAst; for ( size_t i = 0; i < addr -> member_cnt; ++i ) { @@ -574,9 +587,9 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) { exit ( 7 ); } defAst = (AstDefinition*) objAst -> members [ i ]; - env_push ( state ); - value = evaluate ( state, objAst -> members [ i ] ); - env_pop ( state ); + //env_push ( state ); + value = evaluate ( state, defAst -> value ); + //env_pop ( state ); addr -> members [ i ] . name = defAst -> name; addr -> members [ i ] . value = value; } diff --git a/src/ast_interpreter.h b/src/ast_interpreter.h index 2c92701220a374115875659f2f8c5a23b3f0f6ea..17d3df0f4645c03e95236c7618de7056aab78212 100644 --- a/src/ast_interpreter.h +++ b/src/ast_interpreter.h @@ -16,6 +16,51 @@ typedef struct Heap { u8 * end; } Heap; +typedef struct Value { + ValueType kind; +} Value; + +typedef struct Object { + struct Value * extends; + size_t member_cnt; + SimpleEntry members []; +} Object; + +typedef struct Array { + i32 length; + Value * members []; +} Array; + +typedef struct NullValue { + Value kind; +} NullValue; + +typedef struct IntValue { + Value kind; + i32 integer; +} IntValue; + +typedef struct BoolValue { + Value kind; + bool boolean; +} BoolValue; + +typedef struct FunctionValue { + Value kind; + AstFunction * function; +} FunctionValue; + +typedef struct ObjectValue { + Value kind; + Object obj; +} ObjectValue; + +typedef struct ArrayValue { + Value kind; + Array obj; +} ArrayValue; + +/* typedef struct Value { ValueType kind; union { @@ -25,22 +70,17 @@ typedef struct Value { void * address; }; } Value; +*/ typedef struct SimpleEntry { Str name; - Value value; + Value * value; } SimpleEntry; -typedef struct Object { - struct Value extends; - size_t member_cnt; - SimpleEntry * members; -} Object; - typedef struct EnvironmentEntry { struct EnvironmentEntry * next; Str name; - Value value; + Value * value; } EnvironmentEntry; typedef struct Environment { @@ -54,25 +94,30 @@ typedef struct ASTInterpreterState { Environment * current_env; } ASTInterpreterState; -bool value_to_bool ( Value value ); +bool value_to_bool ( Value * value ); void env_push ( ASTInterpreterState * state ); void env_pop ( ASTInterpreterState * state ); -Value env_get ( ASTInterpreterState * state, Str name ); -void env_put ( ASTInterpreterState * state, Str name, Value value ); -void env_def ( ASTInterpreterState * state, Str name, Value value ); -void * heap_alloc ( Heap * heap, size_t len, size_t align ); +Value * env_get ( ASTInterpreterState * state, Str name ); +void env_put ( ASTInterpreterState * state, Str name, Value * value ); +void env_def ( ASTInterpreterState * state, Str name, Value * value ); +void * heap_alloc_alligned ( Heap * heap, size_t len, size_t align ); +void * heap_alloc ( Heap * heap, size_t len ); void heap_init ( Heap * heap, size_t heap_size ); void heap_destroy ( Heap * heap ); void state_init ( ASTInterpreterState * state, Heap * heap ); void state_destroy ( ASTInterpreterState * state ); +NullValue * make_null ( ASTInterpreterState * state ); +IntValue * make_int ( ASTInterpreterState * state, i32 val ); +BoolValue * make_bool ( ASTInterpreterState * state, bool val ); + Value * get_base ( Value * object ); Value * get_object_field (Value * object, Str name ); -Value try_operator ( Value object, Value * arguments, size_t argc, Str * name ); -Value function_call ( ASTInterpreterState * state, Value callee, bool is_function, Ast ** arguments, size_t argc, Str * name ); +Value * try_operator ( Value object, Value * arguments, size_t argc, Str * name ); +Value * function_call ( ASTInterpreterState * state, Value * callee, bool is_function, Ast ** arguments, size_t argc, Str * name ); void print_value ( Value value ); void fml_print ( Str format, Value * args, size_t argc ); -Value evaluate ( ASTInterpreterState * state, Ast * ast ); +Value * evaluate ( ASTInterpreterState * state, Ast * ast ); int compare_entry ( const void * a, const void * b ); \ No newline at end of file