diff --git a/src/main.c b/src/main.c index bfffeae..ebf02f0 100644 --- a/src/main.c +++ b/src/main.c @@ -332,7 +332,6 @@ Execution execute(char *path, Stack *stack) { Translated translated; if (load_cache(&translated, cache_file_path, hash, path) != 0) { - translated = init_translator(path); DArray tokens; darray_init(&tokens, sizeof(Token)); @@ -368,8 +367,13 @@ Execution execute(char *path, Stack *stack) { darray_free(&tokens, free_token); start = clock(); + + translated = init_translator(path); err = translate(&translated, &ast); if (err.exists) { + darray_free(&translated.bytecode, NULL); + free(translated.constants.data); + hashmap_free(translated.constants.hashmap, NULL); darray_free(&ast, free_parsed); return (Execution){err, (Stack){NULL, NULL}}; } @@ -381,7 +385,7 @@ Execution execute(char *path, Stack *stack) { darray_free(&ast, free_parsed); malloc_trim(0); - + ensure_dir_exists(cache_folder_path); file = fopen(cache_file_path, "wb"); diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index d00fc8b..6df7bd7 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -122,7 +122,10 @@ ArgonObject *BASE_CLASS___string__(size_t argc, ArgonObject **argv, ArErr *err, get_field(argv[0], "__class__", false, false), "__name__", NULL); char buffer[100]; - snprintf(buffer, sizeof(buffer), "<%.*s %.*s at %p>", (int)class_name->value.as_str.length, class_name->value.as_str.data, (int)object_name->value.as_str.length, object_name->value.as_str.data,argv[0]); + snprintf(buffer, sizeof(buffer), "<%.*s %.*s at %p>", + (int)class_name->value.as_str.length, class_name->value.as_str.data, + (int)object_name->value.as_str.length, + object_name->value.as_str.data, argv[0]); return new_string_object_null_terminated(buffer); } @@ -188,6 +191,26 @@ ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv, return argv[0]; } +ArgonObject *ARGON_STRING_TYPE___boolean__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + (void)state; + if (argc != 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__boolean__ expects 1 arguments, got %" PRIu64, argc); + } + return argv[0]->value.as_str.length == 0 ? ARGON_FALSE : ARGON_TRUE; +} + +ArgonObject *ARGON_BOOL_TYPE___boolean__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + (void)state; + if (argc != 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__boolean__ expects 1 arguments, got %" PRIu64, argc); + } + return argv[0]; +} + void bootstrap_types() { BASE_CLASS = new_object(); ARGON_TYPE_TYPE = new_object(); @@ -248,6 +271,12 @@ void bootstrap_types() { create_argon_native_function("__string__", ARGON_STRING_TYPE___string__)); add_field(ARGON_BOOL_TYPE, "__new__", create_argon_native_function("__new__", ARGON_BOOL_TYPE___new__)); + add_field( + ARGON_BOOL_TYPE, "__boolean__", + create_argon_native_function("__boolean__", ARGON_BOOL_TYPE___boolean__)); + add_field(ARGON_STRING_TYPE, "__boolean__", + create_argon_native_function("__boolean__", + ARGON_STRING_TYPE___boolean__)); ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION", ARGON_TYPE_TYPE___get_attr__); } @@ -409,9 +438,9 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, break; case OP_INIT_CALL:; size_t length = pop_bytecode(translated, state); - call_instance call_instance = { - state->call_instance, state->registers[0], - ar_alloc(length * sizeof(ArgonObject *)), length}; + call_instance call_instance = {state->call_instance, state->registers[0], + ar_alloc(length * sizeof(ArgonObject *)), + length}; state->call_instance = ar_alloc(sizeof(call_instance)); *state->call_instance = call_instance; break; diff --git a/src/translator/if/if.c b/src/translator/if/if.c index cd3559b..d21e393 100644 --- a/src/translator/if/if.c +++ b/src/translator/if/if.c @@ -10,25 +10,48 @@ #include #include -size_t translate_parsed_if(Translated *translated, DArray *parsedIf, ArErr * err) { +size_t translate_parsed_if(Translated *translated, DArray *parsedIf, + ArErr *err) { size_t *jump_after_body_positions = - checked_malloc(parsedIf->size * sizeof(size_t)); + checked_malloc((parsedIf->size) * sizeof(size_t)); size_t first = translated->bytecode.size; set_registers(translated, 1); + DArray return_jumps; + DArray *old_return_jumps = NULL; + if (translated->return_jumps) { + darray_init(&return_jumps, sizeof(size_t)); + old_return_jumps = translated->return_jumps; + translated->return_jumps = &return_jumps; + } + for (uint64_t i = 0; i < parsedIf->size; i++) { ParsedConditional *condition = darray_get(parsedIf, i); push_instruction_byte(translated, OP_NEW_SCOPE); if (condition->condition) { translate_parsed(translated, condition->condition, err); + if (err->exists) { + if (translated->return_jumps) { + darray_free(&return_jumps, NULL); + translated->return_jumps = old_return_jumps; + } + return 0; + } push_instruction_byte(translated, OP_BOOL); push_instruction_byte(translated, 0); push_instruction_byte(translated, OP_JUMP_IF_FALSE); push_instruction_byte(translated, 0); uint64_t last_jump_index = push_instruction_code(translated, 0); translate_parsed(translated, condition->content, err); + if (err->exists) { + if (translated->return_jumps) { + darray_free(&return_jumps, NULL); + translated->return_jumps = old_return_jumps; + } + return 0; + } push_instruction_byte(translated, OP_POP_SCOPE); push_instruction_byte(translated, OP_JUMP); jump_after_body_positions[i] = push_instruction_code(translated, 0); @@ -42,9 +65,27 @@ size_t translate_parsed_if(Translated *translated, DArray *parsedIf, ArErr * err jump_after_body_positions[i] = push_instruction_code(translated, 0); } } + + if (translated->return_jumps) { + push_instruction_byte(translated, OP_JUMP); + size_t skip_return = push_instruction_code(translated, 0); + + size_t return_jump_to = push_instruction_byte(translated, OP_POP_SCOPE); + push_instruction_byte(translated, OP_JUMP); + size_t return_up = push_instruction_code(translated, 0); + darray_push(old_return_jumps, &return_up); + for (size_t i = 0; i < return_jumps.size; i++) { + size_t *index = darray_get(&return_jumps, i); + set_instruction_code(translated, *index, return_jump_to); + } + set_instruction_code(translated, skip_return, translated->bytecode.size); + darray_free(&return_jumps, NULL); + translated->return_jumps = old_return_jumps; + } + for (uint64_t i = 0; i < parsedIf->size; i++) { set_instruction_code(translated, jump_after_body_positions[i], - translated->bytecode.size); + translated->bytecode.size); } free(jump_after_body_positions); return first; diff --git a/testing.ar b/testing.ar index a5290ce..9ab5a46 100644 --- a/testing.ar +++ b/testing.ar @@ -1,4 +1,3 @@ -let split(url) = do - let split = url.splitN("?", 2) - if (split.length != 2) return {path: split[0], query: {}} - else return {path: split[0], query: decodeURLQuery(split[1])} \ No newline at end of file +let x = "hello" +if (x) term.log('bruh') +else term.log('not bruh') \ No newline at end of file