From 3d419f071cd6c02e7bb4e270c41249188a1e7cd0 Mon Sep 17 00:00:00 2001 From: Kyler Date: Sat, 29 Nov 2025 13:09:22 -0700 Subject: [PATCH] Implemented addition, subtraction, and multiplication --- SLS_C/src/builtin.c | 245 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 239 insertions(+), 6 deletions(-) diff --git a/SLS_C/src/builtin.c b/SLS_C/src/builtin.c index f990884..b84bcaa 100644 --- a/SLS_C/src/builtin.c +++ b/SLS_C/src/builtin.c @@ -105,6 +105,16 @@ static inline Boolean hash_table_put_funcs(HashTable *ht, SlsStr key, FunctionIt return hash_table_put(ht, key, (void *)item); } +typedef enum { + NUMERIC_FLOAT = 1 << 0, + NUMERIC_SIGNED = 1 << 1, + NUMERIC_64 = 1 << 2, + NUMERIC_32 = 1 << 3, + NUMERIC_16 = 1 << 4, + NUMERIC_8 = 1 << 5, +} NumericTypes; + + Boolean load_builtins(InterpreterState *interpreter_state) { FunctionItem *func; @@ -645,19 +655,242 @@ Boolean load_builtins(InterpreterState *interpreter_state) { return TRUE; } +#define arithmetic(op) \ + double af = 0, bf = 0; \ + uint64_t ai = 0, bi = 0; \ + uint64_t type = 0; \ + if (interpreter_state->stack == NULL) return FALSE; \ + if (interpreter_state->stack->next == NULL) return FALSE; \ + \ + switch (interpreter_state->stack->type) { \ + case STACK_IDENTIFIER: \ + return FALSE; \ + case STACK_I64: \ + ai = interpreter_state->stack->i64; \ + af = interpreter_state->stack->i64; \ + type |= NUMERIC_64; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I32: \ + ai = interpreter_state->stack->i32; \ + af = interpreter_state->stack->i32; \ + type |= NUMERIC_32; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I16: \ + ai = interpreter_state->stack->i16; \ + af = interpreter_state->stack->i16; \ + type |= NUMERIC_16; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I8: \ + ai = interpreter_state->stack->i8; \ + af = interpreter_state->stack->i8; \ + type |= NUMERIC_8; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_U64: \ + ai = interpreter_state->stack->u64; \ + af = interpreter_state->stack->u64; \ + type |= NUMERIC_64; \ + break; \ + case STACK_U32: \ + ai = interpreter_state->stack->u32; \ + af = interpreter_state->stack->u32; \ + type |= NUMERIC_32; \ + break; \ + case STACK_U16: \ + ai = interpreter_state->stack->u16; \ + af = interpreter_state->stack->u16; \ + type |= NUMERIC_16; \ + break; \ + case STACK_U8: \ + ai = interpreter_state->stack->u8; \ + af = interpreter_state->stack->u8; \ + type |= NUMERIC_8; \ + break; \ + case STACK_FLOAT: \ + af = interpreter_state->stack->f32; \ + type |= NUMERIC_32; \ + type |= NUMERIC_FLOAT; \ + break; \ + case STACK_DOUBLE: \ + af = interpreter_state->stack->f64; \ + type |= NUMERIC_64; \ + type |= NUMERIC_FLOAT; \ + break; \ + case STACK_CHARACTER: \ + ai = interpreter_state->stack->character; \ + af = interpreter_state->stack->character; \ + break; \ + case STACK_BOOLEAN: \ + ai = interpreter_state->stack->boolean; \ + af = interpreter_state->stack->boolean; \ + break; \ + case STACK_TOKEN_STRING: \ + return FALSE; \ + } \ + \ + switch (interpreter_state->stack->next->type) { \ + case STACK_IDENTIFIER: \ + return FALSE; \ + case STACK_I64: \ + bi = interpreter_state->stack->next->i64; \ + bf = interpreter_state->stack->next->i64; \ + type |= NUMERIC_64; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I32: \ + bi = interpreter_state->stack->next->i32; \ + bf = interpreter_state->stack->next->i32; \ + type |= NUMERIC_32; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I16: \ + bi = interpreter_state->stack->next->i16; \ + bf = interpreter_state->stack->next->i16; \ + type |= NUMERIC_16; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_I8: \ + bi = interpreter_state->stack->next->i8; \ + bf = interpreter_state->stack->next->i8; \ + type |= NUMERIC_8; \ + type |= NUMERIC_SIGNED; \ + break; \ + case STACK_U64: \ + bi = interpreter_state->stack->next->u64; \ + bf = interpreter_state->stack->next->u64; \ + type |= NUMERIC_64; \ + break; \ + case STACK_U32: \ + bi = interpreter_state->stack->next->u32; \ + bf = interpreter_state->stack->next->u32; \ + type |= NUMERIC_32; \ + break; \ + case STACK_U16: \ + bi = interpreter_state->stack->next->u16; \ + bf = interpreter_state->stack->next->u16; \ + type |= NUMERIC_16; \ + break; \ + case STACK_U8: \ + bi = interpreter_state->stack->next->u8; \ + bf = interpreter_state->stack->next->u8; \ + type |= NUMERIC_8; \ + break; \ + case STACK_FLOAT: \ + bf = interpreter_state->stack->next->f32; \ + type |= NUMERIC_32; \ + type |= NUMERIC_FLOAT; \ + break; \ + case STACK_DOUBLE: \ + bf = interpreter_state->stack->next->f64; \ + type |= NUMERIC_64; \ + type |= NUMERIC_FLOAT; \ + break; \ + case STACK_CHARACTER: \ + bi = interpreter_state->stack->next->character; \ + bf = interpreter_state->stack->next->character; \ + break; \ + case STACK_BOOLEAN: \ + bi = interpreter_state->stack->next->boolean; \ + bf = interpreter_state->stack->next->boolean; \ + break; \ + case STACK_TOKEN_STRING: \ + return FALSE; \ + } \ + \ + StackItem *node = interpreter_state->stack; \ + interpreter_state->stack = interpreter_state->stack->next->next; \ + node->next->next = NULL; \ + clean_stack(node); \ + \ + if (type & NUMERIC_FLOAT && type & NUMERIC_64) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_DOUBLE, \ + .double_literal = bf op af, \ + }); \ + } else if (type & NUMERIC_FLOAT) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_FLOAT, \ + .float_literal = (float)bf op (float)af, \ + }); \ + } else if (type & NUMERIC_SIGNED && type & NUMERIC_64) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_I64, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_SIGNED && type & NUMERIC_32) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_I32, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_SIGNED && type & NUMERIC_16) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_I16, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_SIGNED) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_I8, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_64) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_U64, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_32) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_U32, \ + .value = bi op ai, \ + }, \ + }); \ + } else if (type & NUMERIC_16) { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_U16, \ + .value = bi op ai, \ + }, \ + }); \ + } else { \ + return push_token(interpreter_state, (Token){ \ + .type = TOKEN_INTEGER, \ + .integer_literal = (IntegerLiteral){ \ + .type = INTEGER_U8, \ + .value = bi op ai, \ + }, \ + }); \ + } + Boolean builtin_addition(InterpreterState *interpreter_state) { - (void)interpreter_state; - return FALSE; + arithmetic(+); } Boolean builtin_subtraction(InterpreterState *interpreter_state) { - (void)interpreter_state; - return FALSE; + arithmetic(-); } Boolean builtin_multiplication(InterpreterState *interpreter_state) { - (void)interpreter_state; - return FALSE; + arithmetic(*); } Boolean builtin_division(InterpreterState *interpreter_state) {