add multiplication, division, and &&
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -9,7 +9,7 @@
|
|||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/argon",
|
"program": "${workspaceFolder}/bin/argon",
|
||||||
"args": ["testing.ar"],
|
"args": [],
|
||||||
"stopAtEntry": true,
|
"stopAtEntry": true,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
let i = 1000000
|
let factorial(x) = do
|
||||||
|
if (x-1) return x * factorial(x-1)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
let i = 10000000
|
||||||
|
term.log(factorial(10000))
|
||||||
while (i) do
|
while (i) do
|
||||||
i=i-1
|
i=i-1
|
||||||
term.log(add)
|
|
||||||
1
app.py
1
app.py
@@ -1,4 +1,3 @@
|
|||||||
i = 1_000_000
|
i = 1_000_000
|
||||||
while i:
|
while i:
|
||||||
print(i)
|
|
||||||
i=i-1
|
i=i-1
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "call.h"
|
#include "call.h"
|
||||||
#include "../../hash_data/hash_data.h"
|
#include "../../hash_data/hash_data.h"
|
||||||
|
#include "../objects/literals/literals.h"
|
||||||
#include "../objects/string/string.h"
|
#include "../objects/string/string.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -143,7 +144,8 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
object->value.argon_fn.bytecode_length, false},
|
object->value.argon_fn.bytecode_length, false},
|
||||||
object->value.argon_fn.translated.constants,
|
object->value.argon_fn.translated.constants,
|
||||||
object->value.argon_fn.translated.path},
|
object->value.argon_fn.translated.path},
|
||||||
{ar_alloc(object->value.argon_fn.translated.registerCount * sizeof(ArgonObject *)),
|
{ar_alloc(object->value.argon_fn.translated.registerCount *
|
||||||
|
sizeof(ArgonObject *)),
|
||||||
0,
|
0,
|
||||||
object->value.argon_fn.translated.path,
|
object->value.argon_fn.translated.path,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -153,6 +155,9 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
scope,
|
scope,
|
||||||
*state->currentStackFramePointer,
|
*state->currentStackFramePointer,
|
||||||
(*state->currentStackFramePointer)->depth + 1};
|
(*state->currentStackFramePointer)->depth + 1};
|
||||||
|
for (size_t i = 0; i < new_stackFrame.translated.registerCount; i++) {
|
||||||
|
new_stackFrame.state.registers[i] = ARGON_NULL;
|
||||||
|
}
|
||||||
if (CStackFrame) {
|
if (CStackFrame) {
|
||||||
runtime(new_stackFrame.translated, new_stackFrame.state,
|
runtime(new_stackFrame.translated, new_stackFrame.state,
|
||||||
new_stackFrame.stack, err);
|
new_stackFrame.stack, err);
|
||||||
|
|||||||
@@ -147,8 +147,6 @@ ArgonObject *ARGON_NUMBER_TYPE___subtract__(size_t argc, ArgonObject **argv,
|
|||||||
"__subtract__ expects 2 arguments, got %" PRIu64, argc);
|
"__subtract__ expects 2 arguments, got %" PRIu64, argc);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
mpq_t r;
|
|
||||||
mpq_init(r);
|
|
||||||
if (argv[1]->type != TYPE_NUMBER) {
|
if (argv[1]->type != TYPE_NUMBER) {
|
||||||
ArgonObject *type_name = get_builtin_field_for_class(
|
ArgonObject *type_name = get_builtin_field_for_class(
|
||||||
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
||||||
@@ -158,6 +156,7 @@ ArgonObject *ARGON_NUMBER_TYPE___subtract__(size_t argc, ArgonObject **argv,
|
|||||||
type_name->value.as_str.length, type_name->value.as_str.data);
|
type_name->value.as_str.length, type_name->value.as_str.data);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[0]->value.as_number.is_int64 && argv[1]->value.as_number.is_int64) {
|
if (argv[0]->value.as_number.is_int64 && argv[1]->value.as_number.is_int64) {
|
||||||
int64_t a = argv[0]->value.as_number.n.i64;
|
int64_t a = argv[0]->value.as_number.n.i64;
|
||||||
int64_t b = argv[1]->value.as_number.n.i64;
|
int64_t b = argv[1]->value.as_number.n.i64;
|
||||||
@@ -213,8 +212,6 @@ ArgonObject *ARGON_NUMBER_TYPE___multiply__(size_t argc, ArgonObject **argv,
|
|||||||
"__multiply__ expects 2 arguments, got %" PRIu64, argc);
|
"__multiply__ expects 2 arguments, got %" PRIu64, argc);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
mpq_t r;
|
|
||||||
mpq_init(r);
|
|
||||||
if (argv[1]->type != TYPE_NUMBER) {
|
if (argv[1]->type != TYPE_NUMBER) {
|
||||||
ArgonObject *type_name = get_builtin_field_for_class(
|
ArgonObject *type_name = get_builtin_field_for_class(
|
||||||
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
||||||
@@ -224,10 +221,52 @@ ArgonObject *ARGON_NUMBER_TYPE___multiply__(size_t argc, ArgonObject **argv,
|
|||||||
type_name->value.as_str.length, type_name->value.as_str.data);
|
type_name->value.as_str.length, type_name->value.as_str.data);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
mpq_mul(r, *argv[0]->value.as_number.n.mpq, *argv[1]->value.as_number.n.mpq);
|
|
||||||
|
if (argv[0]->value.as_number.is_int64 && argv[1]->value.as_number.is_int64) {
|
||||||
|
int64_t a = argv[0]->value.as_number.n.i64;
|
||||||
|
int64_t b = argv[1]->value.as_number.n.i64;
|
||||||
|
bool gonna_overflow =
|
||||||
|
a > 0 ? (b > 0 ? a > INT64_MAX / b : b < INT64_MIN / a)
|
||||||
|
: (b > 0 ? a < INT64_MIN / b : a != 0 && b < INT64_MAX / a);
|
||||||
|
if (!gonna_overflow) {
|
||||||
|
return new_number_object_from_int64(a * b);
|
||||||
|
}
|
||||||
|
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_mul(a_GMP, a_GMP, b_GMP);
|
||||||
|
ArgonObject *result = new_number_object(a_GMP);
|
||||||
|
mpq_clear(a_GMP);
|
||||||
|
mpq_clear(b_GMP);
|
||||||
|
return result;
|
||||||
|
} else if (!argv[0]->value.as_number.is_int64 &&
|
||||||
|
!argv[1]->value.as_number.is_int64) {
|
||||||
|
mpq_t r;
|
||||||
|
mpq_init(r);
|
||||||
|
mpq_mul(r, *argv[0]->value.as_number.n.mpq,
|
||||||
|
*argv[1]->value.as_number.n.mpq);
|
||||||
ArgonObject *result = new_number_object(r);
|
ArgonObject *result = new_number_object(r);
|
||||||
mpq_clear(r);
|
mpq_clear(r);
|
||||||
return result;
|
return result;
|
||||||
|
} else {
|
||||||
|
mpq_t a_GMP, b_GMP;
|
||||||
|
mpq_init(a_GMP);
|
||||||
|
mpq_init(b_GMP);
|
||||||
|
if (argv[0]->value.as_number.is_int64) {
|
||||||
|
mpq_set_si(a_GMP, argv[0]->value.as_number.n.i64, 1);
|
||||||
|
mpq_set(b_GMP, *argv[1]->value.as_number.n.mpq);
|
||||||
|
} else {
|
||||||
|
mpq_set(a_GMP, *argv[0]->value.as_number.n.mpq);
|
||||||
|
mpq_set_si(b_GMP, argv[1]->value.as_number.n.i64, 1);
|
||||||
|
}
|
||||||
|
mpq_mul(a_GMP, a_GMP, b_GMP);
|
||||||
|
ArgonObject *result = new_number_object(a_GMP);
|
||||||
|
mpq_clear(a_GMP);
|
||||||
|
mpq_clear(b_GMP);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgonObject *ARGON_NUMBER_TYPE___division__(size_t argc, ArgonObject **argv,
|
ArgonObject *ARGON_NUMBER_TYPE___division__(size_t argc, ArgonObject **argv,
|
||||||
@@ -238,8 +277,6 @@ ArgonObject *ARGON_NUMBER_TYPE___division__(size_t argc, ArgonObject **argv,
|
|||||||
"__division__ expects 2 arguments, got %" PRIu64, argc);
|
"__division__ expects 2 arguments, got %" PRIu64, argc);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
mpq_t r;
|
|
||||||
mpq_init(r);
|
|
||||||
if (argv[1]->type != TYPE_NUMBER) {
|
if (argv[1]->type != TYPE_NUMBER) {
|
||||||
ArgonObject *type_name = get_builtin_field_for_class(
|
ArgonObject *type_name = get_builtin_field_for_class(
|
||||||
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
get_builtin_field(argv[1], __class__, false, false), __name__, argv[1]);
|
||||||
@@ -249,10 +286,36 @@ ArgonObject *ARGON_NUMBER_TYPE___division__(size_t argc, ArgonObject **argv,
|
|||||||
type_name->value.as_str.length, type_name->value.as_str.data);
|
type_name->value.as_str.length, type_name->value.as_str.data);
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
mpq_div(r, *argv[0]->value.as_number.n.mpq, *argv[1]->value.as_number.n.mpq);
|
if (argv[0]->value.as_number.is_int64 && argv[1]->value.as_number.is_int64) {
|
||||||
|
int64_t a = argv[0]->value.as_number.n.i64;
|
||||||
|
int64_t b = argv[1]->value.as_number.n.i64;
|
||||||
|
return new_number_object_from_num_and_den(a, b);
|
||||||
|
} else if (!argv[0]->value.as_number.is_int64 &&
|
||||||
|
!argv[1]->value.as_number.is_int64) {
|
||||||
|
mpq_t r;
|
||||||
|
mpq_init(r);
|
||||||
|
mpq_div(r, *argv[0]->value.as_number.n.mpq,
|
||||||
|
*argv[1]->value.as_number.n.mpq);
|
||||||
ArgonObject *result = new_number_object(r);
|
ArgonObject *result = new_number_object(r);
|
||||||
mpq_clear(r);
|
mpq_clear(r);
|
||||||
return result;
|
return result;
|
||||||
|
} else {
|
||||||
|
mpq_t a_GMP, b_GMP;
|
||||||
|
mpq_init(a_GMP);
|
||||||
|
mpq_init(b_GMP);
|
||||||
|
if (argv[0]->value.as_number.is_int64) {
|
||||||
|
mpq_set_si(a_GMP, argv[0]->value.as_number.n.i64, 1);
|
||||||
|
mpq_set(b_GMP, *argv[1]->value.as_number.n.mpq);
|
||||||
|
} else {
|
||||||
|
mpq_set(a_GMP, *argv[0]->value.as_number.n.mpq);
|
||||||
|
mpq_set_si(b_GMP, argv[1]->value.as_number.n.i64, 1);
|
||||||
|
}
|
||||||
|
mpq_div(a_GMP, a_GMP, b_GMP);
|
||||||
|
ArgonObject *result = new_number_object(a_GMP);
|
||||||
|
mpq_clear(a_GMP);
|
||||||
|
mpq_clear(b_GMP);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv,
|
ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv,
|
||||||
|
|||||||
@@ -681,6 +681,9 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
|
|||||||
NULL,
|
NULL,
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{}};
|
{}};
|
||||||
|
for (size_t i = 0;i<translated.registerCount;i++) {
|
||||||
|
runtime.registers[i] = ARGON_NULL;
|
||||||
|
}
|
||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +718,9 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
[OP_COPY_TO_REGISTER] = &&DO_COPY_TO_REGISTER,
|
[OP_COPY_TO_REGISTER] = &&DO_COPY_TO_REGISTER,
|
||||||
[OP_ADDITION] = &&DO_ADDITION,
|
[OP_ADDITION] = &&DO_ADDITION,
|
||||||
[OP_SUBTRACTION] = &&DO_SUBTRACTION,
|
[OP_SUBTRACTION] = &&DO_SUBTRACTION,
|
||||||
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION};
|
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION,
|
||||||
|
[OP_MULTIPLICATION] = &&DO_MULTIPLICATION,
|
||||||
|
[OP_DIVISION] = &&DO_DIVISION};
|
||||||
_state.head = 0;
|
_state.head = 0;
|
||||||
|
|
||||||
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||||
@@ -752,9 +757,9 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
continue;
|
continue;
|
||||||
DO_BOOL: {
|
DO_BOOL: {
|
||||||
uint8_t to_register = pop_byte(translated, state);
|
uint8_t to_register = pop_byte(translated, state);
|
||||||
if (likely(state->registers[0]->type != TYPE_OBJECT)) {
|
if (likely(state->registers[to_register]->type != TYPE_OBJECT)) {
|
||||||
state->registers[to_register] =
|
state->registers[to_register] =
|
||||||
state->registers[0]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
state->registers[to_register]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
||||||
@@ -937,13 +942,122 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
|
|
||||||
ArgonObject *args[] = {valueA, valueB};
|
ArgonObject *args[] = {valueA, valueB};
|
||||||
state->registers[registerC] =
|
state->registers[registerC] =
|
||||||
ARGON_ADDITION_FUNCTION(2, args, err, state);
|
ARGON_SUBTRACTION_FUNCTION(2, args, err, state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DO_MULTIPLICATION: {
|
||||||
|
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;
|
||||||
|
bool gonna_overflow =
|
||||||
|
a > 0 ? (b > 0 ? a > INT64_MAX / b : b < INT64_MIN / a)
|
||||||
|
: (b > 0 ? a < INT64_MIN / b : a != 0 && b < INT64_MAX / a);
|
||||||
|
if (!gonna_overflow) {
|
||||||
|
state->registers[registerC] = new_number_object_from_int64(a * b);
|
||||||
|
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_mul(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_mul(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_mul(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_MULTIPLY_FUNCTION(2, args, err, state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DO_DIVISION: {
|
||||||
|
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;
|
||||||
|
state->registers[registerC] =
|
||||||
|
new_number_object_from_num_and_den(a, b);
|
||||||
|
} else if (!valueA->value.as_number.is_int64 &&
|
||||||
|
!valueB->value.as_number.is_int64) {
|
||||||
|
mpq_t r;
|
||||||
|
mpq_init(r);
|
||||||
|
mpq_div(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_div(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_DIVISION_FUNCTION(2, args, err, state);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgonObject *result = currentStackFrame->state.registers[0];
|
ArgonObject *result = currentStackFrame->state.registers[0];
|
||||||
currentStackFrame = currentStackFrame->previousStackFrame;
|
currentStackFrame = currentStackFrame->previousStackFrame;
|
||||||
if(currentStackFrame) currentStackFrame->state.registers[0] = result;
|
if (currentStackFrame)
|
||||||
|
currentStackFrame->state.registers[0] = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ int execute_code(FILE *stream, char *path, Stack *scope,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArErr err;
|
ArErr err = no_err;
|
||||||
|
|
||||||
DArray tokens;
|
DArray tokens;
|
||||||
darray_init(&tokens, sizeof(Token));
|
darray_init(&tokens, sizeof(Token));
|
||||||
@@ -263,7 +263,7 @@ int shell() {
|
|||||||
if (resp) {
|
if (resp) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ArErr err;
|
ArErr err = no_err;
|
||||||
argon_call(output_object, 1, (ArgonObject *[]){runtime_state.registers[0]},
|
argon_call(output_object, 1, (ArgonObject *[]){runtime_state.registers[0]},
|
||||||
&err, &runtime_state);
|
&err, &runtime_state);
|
||||||
totranslatelength = 0;
|
totranslatelength = 0;
|
||||||
|
|||||||
@@ -82,13 +82,12 @@ jumps when a the value in the given register is false.
|
|||||||
1. the register to read. (*)
|
1. the register to read. (*)
|
||||||
1. the index to jump to.
|
1. the index to jump to.
|
||||||
|
|
||||||
## OP_JUMP_IF_FALSE
|
## OP_JUMP
|
||||||
|
|
||||||
jumps unconditionally to an index.
|
jumps unconditionally to an index.
|
||||||
|
|
||||||
1. the index to jump to.
|
1. the index to jump to.
|
||||||
|
|
||||||
|
|
||||||
## OP_NEW_SCOPE
|
## OP_NEW_SCOPE
|
||||||
|
|
||||||
creates a new stack
|
creates a new stack
|
||||||
@@ -159,3 +158,27 @@ performs an addition between register A and register B, storing the result in re
|
|||||||
1. the register A (*)
|
1. the register A (*)
|
||||||
2. the register B (*)
|
2. the register B (*)
|
||||||
2. the register C (*)
|
2. the register C (*)
|
||||||
|
|
||||||
|
## OP_SUBTRACTION
|
||||||
|
|
||||||
|
performs an subtraction between register A and register B, storing the result in register C
|
||||||
|
|
||||||
|
1. the register A (*)
|
||||||
|
2. the register B (*)
|
||||||
|
2. the register C (*)
|
||||||
|
|
||||||
|
## OP_MULTIPLICATION
|
||||||
|
|
||||||
|
performs an multiplication between register A and register B, storing the result in register C
|
||||||
|
|
||||||
|
1. the register A (*)
|
||||||
|
2. the register B (*)
|
||||||
|
2. the register C (*)
|
||||||
|
|
||||||
|
## OP_DIVISION
|
||||||
|
|
||||||
|
performs an division between register A and register B, storing the result in register C
|
||||||
|
|
||||||
|
1. the register A (*)
|
||||||
|
2. the register B (*)
|
||||||
|
2. the register C (*)
|
||||||
@@ -11,15 +11,54 @@
|
|||||||
|
|
||||||
size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
||||||
ArErr *err) {
|
ArErr *err) {
|
||||||
|
if (operation->operation == TOKEN_AND) {
|
||||||
|
size_t *jump_to_if_false =
|
||||||
|
checked_malloc(operation->to_operate_on.size * sizeof(size_t));
|
||||||
|
uint8_t registerA = translated->registerAssignment++;
|
||||||
|
set_registers(translated, translated->registerAssignment);
|
||||||
|
uint64_t first = 0;
|
||||||
|
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
|
||||||
|
uint64_t position = translate_parsed(
|
||||||
|
translated, darray_get(&operation->to_operate_on, i), err);
|
||||||
|
if (i == 0)
|
||||||
|
position = first;
|
||||||
|
if (err->exists) {
|
||||||
|
free(jump_to_if_false);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
||||||
|
push_instruction_byte(translated, 0);
|
||||||
|
push_instruction_byte(translated, registerA);
|
||||||
|
|
||||||
|
push_instruction_byte(translated, OP_BOOL);
|
||||||
|
push_instruction_byte(translated, registerA);
|
||||||
|
|
||||||
|
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||||
|
push_instruction_byte(translated, registerA);
|
||||||
|
jump_to_if_false[i] = push_instruction_code(translated, 0);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
|
||||||
|
set_instruction_code(translated, jump_to_if_false[i],
|
||||||
|
translated->bytecode.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(jump_to_if_false);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
uint8_t registerA = translated->registerAssignment++;
|
uint8_t registerA = translated->registerAssignment++;
|
||||||
uint8_t registerB = translated->registerAssignment++;
|
uint8_t registerB = translated->registerAssignment++;
|
||||||
set_registers(translated, translated->registerAssignment);
|
set_registers(translated, translated->registerAssignment);
|
||||||
uint64_t first = translate_parsed(translated, darray_get(&operation->to_operate_on, 0), err);
|
uint64_t first = translate_parsed(
|
||||||
|
translated, darray_get(&operation->to_operate_on, 0), err);
|
||||||
|
if (err->exists)
|
||||||
|
return first;
|
||||||
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
||||||
push_instruction_byte(translated, 0);
|
push_instruction_byte(translated, 0);
|
||||||
push_instruction_byte(translated, registerA);
|
push_instruction_byte(translated, registerA);
|
||||||
for (size_t i = 1; i < operation->to_operate_on.size; i++) {
|
for (size_t i = 1; i < operation->to_operate_on.size; i++) {
|
||||||
translate_parsed(translated, darray_get(&operation->to_operate_on, i), err);
|
translate_parsed(translated, darray_get(&operation->to_operate_on, i), err);
|
||||||
|
if (err->exists)
|
||||||
|
return first;
|
||||||
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
||||||
push_instruction_byte(translated, 0);
|
push_instruction_byte(translated, 0);
|
||||||
push_instruction_byte(translated, registerB);
|
push_instruction_byte(translated, registerB);
|
||||||
@@ -30,6 +69,12 @@ size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
|||||||
case TOKEN_MINUS:;
|
case TOKEN_MINUS:;
|
||||||
push_instruction_byte(translated, OP_SUBTRACTION);
|
push_instruction_byte(translated, OP_SUBTRACTION);
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_STAR:;
|
||||||
|
push_instruction_byte(translated, OP_MULTIPLICATION);
|
||||||
|
break;
|
||||||
|
case TOKEN_SLASH:;
|
||||||
|
push_instruction_byte(translated, OP_DIVISION);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
*err = create_err(operation->line, operation->column, operation->length,
|
*err = create_err(operation->line, operation->column, operation->length,
|
||||||
translated->path, "Syntax Error", "unknown operation");
|
translated->path, "Syntax Error", "unknown operation");
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ typedef enum {
|
|||||||
OP_COPY_TO_REGISTER,
|
OP_COPY_TO_REGISTER,
|
||||||
OP_ADDITION,
|
OP_ADDITION,
|
||||||
OP_SUBTRACTION,
|
OP_SUBTRACTION,
|
||||||
OP_LOAD_ACCESS_FUNCTION
|
OP_LOAD_ACCESS_FUNCTION,
|
||||||
|
OP_MULTIPLICATION,
|
||||||
|
OP_DIVISION
|
||||||
} OperationType;
|
} OperationType;
|
||||||
|
|
||||||
void arena_resize(ConstantArena *arena, size_t new_size);
|
void arena_resize(ConstantArena *arena, size_t new_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user