From f5ee0f6fc84c47a47454499c29a79e8aa55f5d24 Mon Sep 17 00:00:00 2001 From: William Bell <62452284+Ugric@users.noreply.github.com> Date: Tue, 2 Sep 2025 02:59:47 +0100 Subject: [PATCH] fix operations not performing correctly and trying to fix cached code not executing correctly --- anonymous-function-test.ar | 4 +- src/main.c | 12 +- src/parser/operations/operations.c | 6 +- src/runtime/objects/number/number.c | 23 +- src/runtime/objects/string/string.c | 2 + src/runtime/runtime.c | 491 ++++++++++++++-------------- testing.ar | 2 +- 7 files changed, 272 insertions(+), 268 deletions(-) diff --git a/anonymous-function-test.ar b/anonymous-function-test.ar index 2c929db..3707bdb 100644 --- a/anonymous-function-test.ar +++ b/anonymous-function-test.ar @@ -1,3 +1 @@ -let i = 1e7 -while (i) do - i=i-1 \ No newline at end of file +term.log(1+2+3-4+5-100+10) diff --git a/src/main.c b/src/main.c index 6a15811..90c5559 100644 --- a/src/main.c +++ b/src/main.c @@ -430,20 +430,20 @@ Translated load_argon_file(char *path, ArErr *err) { Translated gc_translated = { translated.registerCount, translated.registerAssignment, NULL, {}, {}, translated.path}; - gc_translated.bytecode.data = ar_alloc_atomic(translated.bytecode.capacity); + gc_translated.bytecode.data = ar_alloc_atomic(translated.bytecode.size); memcpy(gc_translated.bytecode.data, translated.bytecode.data, - translated.bytecode.capacity); + translated.bytecode.size); gc_translated.bytecode.element_size = translated.bytecode.element_size; gc_translated.bytecode.size = translated.bytecode.size; gc_translated.bytecode.resizable = false; gc_translated.bytecode.capacity = translated.bytecode.size * translated.bytecode.element_size; - gc_translated.constants.data = ar_alloc_atomic(translated.constants.capacity); + gc_translated.constants.data = ar_alloc_atomic(translated.constants.size); memcpy(gc_translated.constants.data, translated.constants.data, - translated.constants.capacity); + translated.constants.size); gc_translated.constants.size = translated.constants.size; - gc_translated.constants.capacity = translated.constants.capacity; - darray_free(&translated.bytecode, NULL); + gc_translated.constants.capacity = translated.constants.size * translated.bytecode.element_size; + free(translated.bytecode.data); free(translated.constants.data); total_time_spent = (double)(clock() - beginning) / CLOCKS_PER_SEC; fprintf(stderr, "total time taken loading file (%s): %f seconds\n", path, diff --git a/src/parser/operations/operations.c b/src/parser/operations/operations.c index 43b8782..1bcd5e2 100644 --- a/src/parser/operations/operations.c +++ b/src/parser/operations/operations.c @@ -12,8 +12,6 @@ #include #include -struct operation {}; - ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { if (to_operate_on->size == 1) { return *((ParsedValue *)darray_get(to_operate_on, 0)); @@ -31,7 +29,9 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { operation = *current_operation; darray_init(&positions, sizeof(size_t)); } - darray_push(&positions, &i); + if (operation_type == current_operation->type) { + darray_push(&positions, &i); + } } ParsedValue parsedValue; parsedValue.type = AST_OPERATION; diff --git a/src/runtime/objects/number/number.c b/src/runtime/objects/number/number.c index 1c63918..14ebbcd 100644 --- a/src/runtime/objects/number/number.c +++ b/src/runtime/objects/number/number.c @@ -412,17 +412,20 @@ ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv, return result; } -ArgonObject small_ints[UINT8_MAX * 2]; +#define small_ints_min -256 +#define small_ints_max 256 +ArgonObject small_ints[small_ints_max-small_ints_min+1]; void init_small_ints() { - for (uint64_t i = 0; i < UINT8_MAX * 2; i++) { + for (int64_t i = 0; i <= small_ints_max-small_ints_min; i++) { + int64_t n = i+small_ints_min; small_ints[i].type = TYPE_NUMBER; small_ints[i].dict = createHashmap_GC(); add_builtin_field(&small_ints[i], __class__, ARGON_NUMBER_TYPE); add_builtin_field(&small_ints[i], __base__, BASE_CLASS); small_ints[i].value.as_number.is_int64 = true; - small_ints[i].value.as_number.n.i64 = i; - small_ints[i].as_bool = i; + small_ints[i].value.as_number.n.i64 = n; + small_ints[i].as_bool = n; } } @@ -530,8 +533,8 @@ bool double_to_int64(double x, int64_t *out) { ArgonObject *new_number_object(mpq_t number) { int64_t i64 = 0; bool is_int64 = mpq_to_int64(number, &i64); - if (is_int64 && i64 >= INT8_MIN * 2 && i64 <= INT8_MAX * 2) { - return &small_ints[i64]; + if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) { + return &small_ints[i64-small_ints_min]; } ArgonObject *object = new_object(); add_builtin_field(object, __class__, ARGON_NUMBER_TYPE); @@ -548,8 +551,8 @@ ArgonObject *new_number_object(mpq_t number) { } ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) { - if (d == 1 && n >= INT8_MIN && n <= INT8_MAX) { - return &small_ints[(int8_t)n]; + if (d == 1 && n >= small_ints_min && n <= small_ints_max) { + return &small_ints[n-small_ints_min]; } ArgonObject *object = new_object(); add_builtin_field(object, __class__, ARGON_NUMBER_TYPE); @@ -573,8 +576,8 @@ ArgonObject *new_number_object_from_num_and_den(int64_t n, uint64_t d) { ArgonObject *new_number_object_from_double(double d) { int64_t i64 = 0; bool is_int64 = double_to_int64(d, &i64); - if (is_int64 && i64 >= INT8_MIN && i64 <= INT8_MAX) { - return &small_ints[(int8_t)i64]; + if (is_int64 && i64 >= small_ints_min && i64 <= small_ints_max) { + return &small_ints[i64-small_ints_min]; } ArgonObject *object = new_object(); add_builtin_field(object, __class__, ARGON_NUMBER_TYPE); diff --git a/src/runtime/objects/string/string.c b/src/runtime/objects/string/string.c index cf0980f..fa153a9 100644 --- a/src/runtime/objects/string/string.c +++ b/src/runtime/objects/string/string.c @@ -21,6 +21,8 @@ ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash, new_number_object_from_num_and_den(length, 1)); object->type = TYPE_STRING; object->value.as_str.data = ar_alloc_atomic(length); + printf("%zu, %p\n", length,data); + printf("%.*s\n", (int)length,data); memcpy(object->value.as_str.data, data, length); object->value.as_str.prehash = prehash; object->value.as_str.hash_computed = hash; diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index fca1a97..d9b322f 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -626,10 +626,8 @@ static inline void load_const(Translated *translated, RuntimeState *state) { uint64_t to_register = pop_byte(translated, state); size_t length = pop_bytecode(translated, state); uint64_t offset = pop_bytecode(translated, state); - - void *data = ar_alloc_atomic(length); - memcpy(data, arena_get(&translated->constants, offset), length); - ArgonObject *object = new_string_object(data, length, 0, 0); + printf("offset %zu\n", offset); + ArgonObject *object = new_string_object(arena_get(&translated->constants, offset), length, 0, 0); state->registers[to_register] = object; } @@ -671,8 +669,28 @@ static inline void load_variable(Translated *translated, RuntimeState *state, arena_get(&translated->constants, offset)); return; } -static inline void run_instructions(Translated *translated, RuntimeState *state, - struct Stack **stack, ArErr *err) { + +RuntimeState init_runtime_state(Translated translated, char *path) { + RuntimeState runtime = { + ar_alloc(translated.registerCount * sizeof(ArgonObject *)), + 0, + path, + NULL, + NULL, + {0, 0, 0}, + {}}; + return runtime; +} + +Stack *create_scope(Stack *prev) { + Stack *stack = ar_alloc(sizeof(Stack)); + stack->scope = createHashmap_GC(); + stack->prev = prev; + return stack; +} + +void runtime(Translated translated, RuntimeState state, Stack *stack, + ArErr *err) { static void *dispatch_table[] = { [OP_LOAD_STRING] = &&DO_LOAD_STRING, [OP_DECLARE] = &&DO_DECLARE, @@ -696,243 +714,6 @@ static inline void run_instructions(Translated *translated, RuntimeState *state, [OP_ADDITION] = &&DO_ADDITION, [OP_SUBTRACTION] = &&DO_SUBTRACTION, [OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION}; -START: - if (unlikely(state->head >= translated->bytecode.size || err->exists)) - return; - goto *dispatch_table[pop_byte(translated, state)]; -DO_LOAD_NULL: - state->registers[pop_byte(translated, state)] = ARGON_NULL; - goto START; -DO_LOAD_STRING: - load_const(translated, state); - goto START; -DO_LOAD_NUMBER: - load_number(translated, state); - goto START; -DO_LOAD_FUNCTION: - load_argon_function(translated, state, *stack); - goto START; -DO_IDENTIFIER: - load_variable(translated, state, *stack, err); - goto START; -DO_DECLARE: - runtime_declaration(translated, state, *stack, err); - goto START; -DO_ASSIGN: - runtime_assignment(translated, state, *stack); - goto START; -DO_BOOL: { - uint8_t to_register = pop_byte(translated, state); - if (likely(state->registers[0]->type != TYPE_OBJECT)) { - state->registers[to_register] = - state->registers[0]->as_bool ? ARGON_TRUE : ARGON_FALSE; - goto START; - } - ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]}; - state->registers[to_register] = ARGON_BOOL_TYPE___new__(2, args, err, state); - goto START; -} -DO_JUMP_IF_FALSE: { - uint8_t from_register = pop_byte(translated, state); - uint64_t to = pop_bytecode(translated, state); - if (state->registers[from_register] == ARGON_FALSE) { - state->head = to; - } - goto START; -} -DO_JUMP: - state->head = pop_bytecode(translated, state); - goto START; -DO_NEW_SCOPE: - *stack = create_scope(*stack); - goto START; -DO_EMPTY_SCOPE: - clear_hashmap_GC((*stack)->scope); - goto START; -DO_POP_SCOPE: - *stack = (*stack)->prev; - goto START; -DO_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}; - state->call_instance = ar_alloc(sizeof(call_instance)); - *state->call_instance = call_instance; - goto START; -} -DO_INSERT_ARG:; - size_t index = pop_bytecode(translated, state); - state->call_instance->args[index] = state->registers[0]; - goto START; -DO_CALL: { - run_call(state->call_instance->to_call, state->call_instance->args_length, - state->call_instance->args, state, false, err); - state->call_instance = (*state->call_instance).previous; - goto START; -} -DO_SOURCE_LOCATION: - state->source_location = (SourceLocation){pop_bytecode(translated, state), - pop_bytecode(translated, state), - pop_bytecode(translated, state)}; - goto START; -DO_LOAD_BOOL: - state->registers[0] = pop_byte(translated, state) ? ARGON_TRUE : ARGON_FALSE; - goto START; -DO_LOAD_ACCESS_FUNCTION: - state->registers[0] = ACCESS_FUNCTION; - goto START; -DO_COPY_TO_REGISTER: { - uint8_t from_register = pop_byte(translated, state); - uint64_t to_register = pop_byte(translated, state); - state->registers[to_register] = state->registers[from_register]; - goto START; -} -DO_ADDITION: { - uint8_t registerA = pop_byte(translated, state); - uint64_t registerB = pop_byte(translated, state); - uint64_t registerC = pop_byte(translated, state); - - ArgonObject *valueA = state->registers[registerA]; - ArgonObject *valueB = state->registers[registerB]; - - if (likely(valueA->type == TYPE_NUMBER && valueB->type == TYPE_NUMBER)) { - if (likely(valueA->value.as_number.is_int64 && - valueB->value.as_number.is_int64)) { - int64_t a = valueA->value.as_number.n.i64; - int64_t b = valueB->value.as_number.n.i64; - bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) || - (a < 0 && b < 0 && a < INT64_MIN - b); - if (!gonna_overflow) { - state->registers[registerC] = - new_number_object_from_num_and_den(a + b, 1); - goto START; - } - mpq_t a_GMP, b_GMP; - mpq_init(a_GMP); - mpq_init(b_GMP); - mpq_set_si(a_GMP, a, 1); - mpq_set_si(b_GMP, b, 1); - mpq_add(a_GMP, a_GMP, b_GMP); - state->registers[registerC] = new_number_object(a_GMP); - mpq_clear(a_GMP); - mpq_clear(b_GMP); - } else if (!valueA->value.as_number.is_int64 && - !valueB->value.as_number.is_int64) { - mpq_t r; - mpq_init(r); - mpq_add(r, *valueA->value.as_number.n.mpq, - *valueB->value.as_number.n.mpq); - state->registers[registerC] = new_number_object(r); - mpq_clear(r); - } else { - mpq_t a_GMP, b_GMP; - mpq_init(a_GMP); - mpq_init(b_GMP); - if (valueA->value.as_number.is_int64) { - mpq_set_si(a_GMP, valueA->value.as_number.n.i64, 1); - mpq_set(b_GMP, *valueB->value.as_number.n.mpq); - } else { - mpq_set(a_GMP, *valueA->value.as_number.n.mpq); - mpq_set_si(b_GMP, valueB->value.as_number.n.i64, 1); - } - mpq_add(a_GMP, a_GMP, b_GMP); - state->registers[registerC] = new_number_object(a_GMP); - mpq_clear(a_GMP); - mpq_clear(b_GMP); - } - goto START; - } - - ArgonObject *args[] = {valueA, valueB}; - state->registers[registerC] = ARGON_ADDITION_FUNCTION(2, args, err, state); - goto START; -} -DO_SUBTRACTION: { - uint8_t registerA = pop_byte(translated, state); - uint64_t registerB = pop_byte(translated, state); - uint64_t registerC = pop_byte(translated, state); - - ArgonObject *valueA = state->registers[registerA]; - ArgonObject *valueB = state->registers[registerB]; - - if (likely(valueA->type == TYPE_NUMBER && valueB->type == TYPE_NUMBER)) { - if (likely(valueA->value.as_number.is_int64 && - valueB->value.as_number.is_int64)) { - int64_t a = valueA->value.as_number.n.i64; - int64_t b = valueB->value.as_number.n.i64; - int64_t neg_a = -a; - bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) || - (neg_a < 0 && b < 0 && b < INT64_MIN - neg_a); - if (!gonna_overflow) { - state->registers[registerC] = - new_number_object_from_num_and_den(a - b, 1); - goto START; - } - mpq_t a_GMP, b_GMP; - mpq_init(a_GMP); - mpq_init(b_GMP); - mpq_set_si(a_GMP, a, 1); - mpq_set_si(b_GMP, b, 1); - mpq_sub(a_GMP, a_GMP, b_GMP); - state->registers[registerC] = new_number_object(a_GMP); - mpq_clear(a_GMP); - mpq_clear(b_GMP); - } else if (!valueA->value.as_number.is_int64 && - !valueB->value.as_number.is_int64) { - mpq_t r; - mpq_init(r); - mpq_sub(r, *valueA->value.as_number.n.mpq, - *valueB->value.as_number.n.mpq); - state->registers[registerC] = new_number_object(r); - mpq_clear(r); - } else { - mpq_t a_GMP, b_GMP; - mpq_init(a_GMP); - mpq_init(b_GMP); - if (valueA->value.as_number.is_int64) { - mpq_set_si(a_GMP, valueA->value.as_number.n.i64, 1); - mpq_set(b_GMP, *valueB->value.as_number.n.mpq); - } else { - mpq_set(a_GMP, *valueA->value.as_number.n.mpq); - mpq_set_si(b_GMP, valueB->value.as_number.n.i64, 1); - } - mpq_sub(a_GMP, a_GMP, b_GMP); - state->registers[registerC] = new_number_object(a_GMP); - mpq_clear(a_GMP); - mpq_clear(b_GMP); - } - goto START; - } - - ArgonObject *args[] = {valueA, valueB}; - state->registers[registerC] = ARGON_ADDITION_FUNCTION(2, args, err, state); - goto START; -} - goto START; -} - -RuntimeState init_runtime_state(Translated translated, char *path) { - RuntimeState runtime = { - ar_alloc(translated.registerCount * sizeof(ArgonObject *)), - 0, - path, - NULL, - NULL, - {0, 0, 0}, - {}}; - return runtime; -} - -Stack *create_scope(Stack *prev) { - Stack *stack = ar_alloc(sizeof(Stack)); - stack->scope = createHashmap_GC(); - stack->prev = prev; - return stack; -} - -void runtime(Translated translated, RuntimeState state, Stack *stack, - ArErr *err) { state.head = 0; StackFrame *currentStackFrame = @@ -940,8 +721,228 @@ void runtime(Translated translated, RuntimeState state, Stack *stack, *currentStackFrame = (StackFrame){translated, state, stack, NULL, 0}; currentStackFrame->state.currentStackFramePointer = ¤tStackFrame; while (currentStackFrame) { - run_instructions(¤tStackFrame->translated, ¤tStackFrame->state, - ¤tStackFrame->stack, err); + while (likely(currentStackFrame->state.head < + currentStackFrame->translated.bytecode.size && + !err->exists)) { + Translated *translated = ¤tStackFrame->translated; + RuntimeState *state = ¤tStackFrame->state; + uint8_t instruction = pop_byte(translated, state); + printf("opcode: %d\n",instruction); + goto *dispatch_table[instruction]; + DO_LOAD_NULL: + state->registers[pop_byte(translated, state)] = ARGON_NULL; + continue; + DO_LOAD_STRING: + load_const(translated, state); + continue; + DO_LOAD_NUMBER: + load_number(translated, state); + continue; + DO_LOAD_FUNCTION: + load_argon_function(translated, state, currentStackFrame->stack); + continue; + DO_IDENTIFIER: + load_variable(translated, state, currentStackFrame->stack, err); + continue; + DO_DECLARE: + runtime_declaration(translated, state, currentStackFrame->stack, err); + continue; + DO_ASSIGN: + runtime_assignment(translated, state, currentStackFrame->stack); + continue; + DO_BOOL: { + uint8_t to_register = pop_byte(translated, state); + if (likely(state->registers[0]->type != TYPE_OBJECT)) { + state->registers[to_register] = + state->registers[0]->as_bool ? ARGON_TRUE : ARGON_FALSE; + continue; + } + ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]}; + state->registers[to_register] = + ARGON_BOOL_TYPE___new__(2, args, err, state); + continue; + } + DO_JUMP_IF_FALSE: { + uint8_t from_register = pop_byte(translated, state); + uint64_t to = pop_bytecode(translated, state); + if (state->registers[from_register] == ARGON_FALSE) { + state->head = to; + } + continue; + } + DO_JUMP: + state->head = pop_bytecode(translated, state); + continue; + DO_NEW_SCOPE: + currentStackFrame->stack = create_scope(currentStackFrame->stack); + continue; + DO_EMPTY_SCOPE: + clear_hashmap_GC(currentStackFrame->stack->scope); + continue; + DO_POP_SCOPE: + currentStackFrame->stack = currentStackFrame->stack->prev; + continue; + DO_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}; + state->call_instance = ar_alloc(sizeof(call_instance)); + *state->call_instance = call_instance; + continue; + } + DO_INSERT_ARG:; + size_t index = pop_bytecode(translated, state); + state->call_instance->args[index] = state->registers[0]; + continue; + DO_CALL: { + run_call(state->call_instance->to_call, state->call_instance->args_length, + state->call_instance->args, state, false, err); + state->call_instance = (*state->call_instance).previous; + continue; + } + DO_SOURCE_LOCATION: + state->source_location = (SourceLocation){ + pop_bytecode(translated, state), pop_bytecode(translated, state), + pop_bytecode(translated, state)}; + continue; + DO_LOAD_BOOL: + state->registers[0] = + pop_byte(translated, state) ? ARGON_TRUE : ARGON_FALSE; + continue; + DO_LOAD_ACCESS_FUNCTION: + state->registers[0] = ACCESS_FUNCTION; + continue; + DO_COPY_TO_REGISTER: { + uint8_t from_register = pop_byte(translated, state); + uint64_t to_register = pop_byte(translated, state); + state->registers[to_register] = state->registers[from_register]; + continue; + } + DO_ADDITION: { + uint8_t registerA = pop_byte(translated, state); + uint64_t registerB = pop_byte(translated, state); + uint64_t registerC = pop_byte(translated, state); + + ArgonObject *valueA = state->registers[registerA]; + ArgonObject *valueB = state->registers[registerB]; + + if (likely(valueA->type == TYPE_NUMBER && valueB->type == TYPE_NUMBER)) { + if (likely(valueA->value.as_number.is_int64 && + valueB->value.as_number.is_int64)) { + int64_t a = valueA->value.as_number.n.i64; + int64_t b = valueB->value.as_number.n.i64; + bool gonna_overflow = (a > 0 && b > 0 && a > INT64_MAX - b) || + (a < 0 && b < 0 && a < INT64_MIN - b); + if (!gonna_overflow) { + state->registers[registerC] = + new_number_object_from_num_and_den(a + b, 1); + continue; + } + mpq_t a_GMP, b_GMP; + mpq_init(a_GMP); + mpq_init(b_GMP); + mpq_set_si(a_GMP, a, 1); + mpq_set_si(b_GMP, b, 1); + mpq_add(a_GMP, a_GMP, b_GMP); + state->registers[registerC] = new_number_object(a_GMP); + mpq_clear(a_GMP); + mpq_clear(b_GMP); + } else if (!valueA->value.as_number.is_int64 && + !valueB->value.as_number.is_int64) { + mpq_t r; + mpq_init(r); + mpq_add(r, *valueA->value.as_number.n.mpq, + *valueB->value.as_number.n.mpq); + state->registers[registerC] = new_number_object(r); + mpq_clear(r); + } else { + mpq_t a_GMP, b_GMP; + mpq_init(a_GMP); + mpq_init(b_GMP); + if (valueA->value.as_number.is_int64) { + mpq_set_si(a_GMP, valueA->value.as_number.n.i64, 1); + mpq_set(b_GMP, *valueB->value.as_number.n.mpq); + } else { + mpq_set(a_GMP, *valueA->value.as_number.n.mpq); + mpq_set_si(b_GMP, valueB->value.as_number.n.i64, 1); + } + mpq_add(a_GMP, a_GMP, b_GMP); + state->registers[registerC] = new_number_object(a_GMP); + mpq_clear(a_GMP); + mpq_clear(b_GMP); + } + continue; + } + + ArgonObject *args[] = {valueA, valueB}; + state->registers[registerC] = + ARGON_ADDITION_FUNCTION(2, args, err, state); + continue; + } + DO_SUBTRACTION: { + uint8_t registerA = pop_byte(translated, state); + uint8_t registerB = pop_byte(translated, state); + uint8_t registerC = pop_byte(translated, state); + + ArgonObject *valueA = state->registers[registerA]; + ArgonObject *valueB = state->registers[registerB]; + + if (likely(valueA->type == TYPE_NUMBER && valueB->type == TYPE_NUMBER)) { + if (likely(valueA->value.as_number.is_int64 && + valueB->value.as_number.is_int64)) { + int64_t a = valueA->value.as_number.n.i64; + int64_t b = valueB->value.as_number.n.i64; + int64_t neg_a = -a; + bool gonna_overflow = (neg_a > 0 && b > 0 && b > INT64_MAX - neg_a) || + (neg_a < 0 && b < 0 && b < INT64_MIN - neg_a); + if (!gonna_overflow) { + state->registers[registerC] = + new_number_object_from_num_and_den(a - b, 1); + continue; + } + mpq_t a_GMP, b_GMP; + mpq_init(a_GMP); + mpq_init(b_GMP); + mpq_set_si(a_GMP, a, 1); + mpq_set_si(b_GMP, b, 1); + mpq_sub(a_GMP, a_GMP, b_GMP); + state->registers[registerC] = new_number_object(a_GMP); + mpq_clear(a_GMP); + mpq_clear(b_GMP); + } else if (!valueA->value.as_number.is_int64 && + !valueB->value.as_number.is_int64) { + mpq_t r; + mpq_init(r); + mpq_sub(r, *valueA->value.as_number.n.mpq, + *valueB->value.as_number.n.mpq); + state->registers[registerC] = new_number_object(r); + mpq_clear(r); + } else { + mpq_t a_GMP, b_GMP; + mpq_init(a_GMP); + mpq_init(b_GMP); + if (valueA->value.as_number.is_int64) { + mpq_set_si(a_GMP, valueA->value.as_number.n.i64, 1); + mpq_set(b_GMP, *valueB->value.as_number.n.mpq); + } else { + mpq_set(a_GMP, *valueA->value.as_number.n.mpq); + mpq_set_si(b_GMP, valueB->value.as_number.n.i64, 1); + } + mpq_sub(a_GMP, a_GMP, b_GMP); + state->registers[registerC] = new_number_object(a_GMP); + mpq_clear(a_GMP); + mpq_clear(b_GMP); + } + continue; + } + + ArgonObject *args[] = {valueA, valueB}; + state->registers[registerC] = + ARGON_ADDITION_FUNCTION(2, args, err, state); + continue; + } + } currentStackFrame = currentStackFrame->previousStackFrame; } } \ No newline at end of file diff --git a/testing.ar b/testing.ar index 0b54559..13ab4e8 100644 --- a/testing.ar +++ b/testing.ar @@ -39,7 +39,7 @@ term.log( ) call(()=do term.log(( - (x)=x*x*x*x*x*x*x*x*x*x*x*x + (x)=x )( 10000675435574942378423458324823473205237523053278452368578032472390453275238558438905348905894035890348905349805345485843578934268954328902589607469328905490832678934728969834689057843267854736890256743928563256749016078596789416895657435690769013674516750941765438576867893726789543789345678576846715416789058903890549045839804538905389045890435890349580348905894035890435784785236523656237985678342523678 )