/* * This code is part of the programming language flup * flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later. * Copyright (C) 2024 VegOwOtenks * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "callframe.h" #include int CallFrame_Create(CallFrame* self, FlupFunction* self_function) { if (DynamicArray_Create(&self->stack, sizeof(Value), 8, NULL)) { return ENOMEM; } self->memory_pad.memory = NULL; self->self_function = self_function; self->alternative = self->self_function->alternatives; self->instruction_pointer = self->alternative->condition_token_start; self->variables = NULL; self->functions = NULL; return EXIT_SUCCESS; } int CallFrame_DefineVariable(CallFrame* self, StringView name, Value value) { FlupVariable* v = CallFrame_Reserve(self, sizeof(FlupVariable), alignof(FlupVariable)); if (v == NULL) { return ENOMEM; } v->name = name; v->value = value; v->next = self->variables; self->variables = v; return EXIT_SUCCESS; } int CallFrame_StackPop(CallFrame* self, Value* dest) { size_t stack_size = DynamicArray_GetLength(&self->stack); Value* popped = DynamicArray_GetPointer(&self->stack, stack_size - 1); if (popped == NULL) { return ENOTFOUND; } *dest = *popped; DynamicArray_Remove(&self->stack, stack_size - 1); return EXIT_SUCCESS; } int CallFrame_StackPush(CallFrame* self, Value* value) { return DynamicArray_Append(&self->stack, value); } FlupVariable* CallFrame_FindVariable(CallFrame* self, StringView name) { for (FlupVariable* variable = self->variables; variable != NULL; variable = variable->next) { if (StringView_Equal(variable->name, name)) { return variable; } } return NULL; } void CallFrame_Destroy(CallFrame* self) { if (self->memory_pad.memory != NULL) { Scratchpad_Destroy(&self->memory_pad); } DynamicArray_Destroy(&self->stack); } void* CallFrame_Reserve(CallFrame* self, size_t amount, size_t alignment) { if (self->memory_pad.memory == NULL) { if (Scratchpad_Create(&self->memory_pad, 1024, NULL)) return NULL; } return Scratchpad_ReserveAligned(&self->memory_pad, amount, alignment); } bool CallFrame_IsExecutingCondition(CallFrame* frame) { return frame->instruction_pointer >= frame->alternative->condition_token_start && frame->instruction_pointer <= frame->alternative->condition_token_end; } bool CallFrame_IsSelectingCondition(CallFrame* frame) { return frame->instruction_pointer == frame->alternative->condition_token_end + 1; } bool CallFrame_IsExecutingBody(CallFrame* frame) { return frame->instruction_pointer < frame->alternative->body_token_end; } bool CallFrame_IsReturningBody(CallFrame* frame) { return frame->instruction_pointer == frame->alternative->body_token_end; }