diff --git a/SLS_C/src/builtin.c b/SLS_C/src/builtin.c index 5424c4b..ea2f30e 100644 --- a/SLS_C/src/builtin.c +++ b/SLS_C/src/builtin.c @@ -1776,8 +1776,129 @@ Boolean builtin_rand(InterpreterState *interpreter_state) { } Boolean builtin_roll(InterpreterState *interpreter_state) { - (void)interpreter_state; - return FALSE; + if (interpreter_state->stack == NULL) return FALSE; + if (interpreter_state->stack->next == NULL) return FALSE; + + StackItem *times_item = interpreter_state->stack; + StackItem *count_item = times_item->next; + + size_t times; + switch (times_item->type) { + case STACK_IDENTIFIER: + return FALSE; + case STACK_I64: + if (times_item->i64 < 0) return FALSE; + times = times_item->i64; + break; + case STACK_I32: + if (times_item->i32 < 0) return FALSE; + times = times_item->i32; + break; + case STACK_I16: + if (times_item->i16 < 0) return FALSE; + times = times_item->i16; + break; + case STACK_I8: + if (times_item->i8 < 0) return FALSE; + times = times_item->i8; + break; + case STACK_U64: + times = times_item->u64; + break; + case STACK_U32: + times = times_item->u32; + break; + case STACK_U16: + times = times_item->u16; + break; + case STACK_U8: + times = times_item->u8; + break; + case STACK_FLOAT: + return FALSE; + case STACK_DOUBLE: + return FALSE; + case STACK_CHARACTER: + times = times_item->character; + break; + case STACK_BOOLEAN: + times = times_item->boolean; + break; + case STACK_TOKEN_STRING: + case STACK_CALLABLE: + return FALSE; + } + + size_t count; + switch (count_item->type) { + case STACK_IDENTIFIER: + return FALSE; + case STACK_I64: + if (count_item->i64 < 0) return FALSE; + count = count_item->i64; + break; + case STACK_I32: + if (count_item->i32 < 0) return FALSE; + count = count_item->i32; + break; + case STACK_I16: + if (count_item->i16 < 0) return FALSE; + count = count_item->i16; + break; + case STACK_I8: + if (count_item->i8 < 0) return FALSE; + count = count_item->i8; + break; + case STACK_U64: + count = count_item->u64; + break; + case STACK_U32: + count = count_item->u32; + break; + case STACK_U16: + count = count_item->u16; + break; + case STACK_U8: + count = count_item->u8; + break; + case STACK_FLOAT: + return FALSE; + case STACK_DOUBLE: + return FALSE; + case STACK_CHARACTER: + count = count_item->character; + break; + case STACK_BOOLEAN: + count = count_item->boolean; + break; + case STACK_TOKEN_STRING: + case STACK_CALLABLE: + return FALSE; + } + + StackItem *head = NULL, *tail = NULL, *prev = NULL; + if (count > 0) { + StackItem *node = count_item->next; + for (size_t i = 0; i < count; i++) { + if (node == NULL) return FALSE; + if (i == (count - times) - 1) { + tail = node; + head = node->next; + } + prev = node; + node = node->next; + } + } + + if (head == NULL || tail == NULL) return FALSE; + + interpreter_state->stack = head; + tail->next = prev->next; + prev->next = count_item->next; + count_item->next = NULL; + clean_stack(times_item); + + return TRUE; } Boolean builtin_rot(InterpreterState *interpreter_state) {