#include "moka.h" void moka_init(struct moka* self) { assert(self); vec_init(&self->frame_stack); vec_init(&self->global_values); struct frame* frame = malloc(sizeof(struct frame)); frame_init(frame); vec_push(&self->frame_stack, frame); } void frame_init(struct frame* self) { vec_init(&self->local_values); vec_init(&self->stack); } void frame_free(struct frame* self) { assert(self); vec_free_elements(&self->local_values, (void*)value_free); vec_free(&self->local_values); vec_free(&self->stack); } void moka_free(struct moka* self) { assert(self); vec_free_elements(&self->frame_stack, (void*) frame_free); vec_free(&self->frame_stack); vec_free(&self->global_values); } struct frame* moka_frame(struct moka* self) { assert(self); assert(self->frame_stack.size > 0); return self->frame_stack.data[ self->frame_stack.size - 1 ]; } bool moka_has_top(struct moka* self) { assert(self); struct frame* frame = moka_frame(self); return frame->stack.size > 0; } MOKA moka_top(struct moka* self) { assert(self); struct frame* frame = moka_frame(self); assert(frame->stack.size > 0); MOKA val = (MOKA) frame->stack.data[frame->stack.size - 1]; return val; } bool moka_is(struct moka* self, MOKA value, TypeKind type) { return moka_type_of(self, value) == type; } TypeKind moka_type_of(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value const* val = frame->local_values.data[value]; return val->type; } void moka_dump(struct moka* self, MOKA value) { if (moka_is(self, value, TY_INT)) { printf("%d", moka_get_int(self, value)); return; } if (moka_is(self, value, TY_FLOAT)) { printf("%f", moka_get_float(self, value)); return; } if (moka_is(self, value, TY_BOOL)) { printf("%s", moka_get_bool(self, value) ? "true" : "false"); return; } if (moka_is(self, value, TY_STRING)) { printf("%s", moka_get_string(self, value)); return; } if (moka_is(self, value, TY_SYMBOL)) { printf("'%s", moka_get_symbol(self, value)); return; } fprintf(stderr, "cannot dump value of type <%s>\n", TypeKindStr[moka_type_of(self, value)] ); abort(); } MOKA moka_push_int(struct moka* self, int value, int line) { assert(self); struct frame* frame = moka_frame(self); struct value* val = malloc(sizeof(struct value)); value_init_int(val, value, line); vec_push(&frame->local_values, val); size_t addr = frame->local_values.size - 1; vec_push(&frame->stack, (void*) addr); return addr; } int moka_get_int(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value* val = frame->local_values.data[value]; assert(val->type == TY_INT); return val->data.integer; } MOKA moka_push_float(struct moka* self, float value, int line) { assert(self); struct frame* frame = moka_frame(self); struct value* val = malloc(sizeof(struct value)); value_init_float(val, value, line); vec_push(&frame->local_values, val); size_t addr = frame->local_values.size - 1; vec_push(&frame->stack, (void*) addr); return addr; } float moka_get_float(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value* val = frame->local_values.data[value]; assert(val->type == TY_FLOAT); return val->data.real; } MOKA moka_push_bool(struct moka* self, bool value, int line) { assert(self); struct frame* frame = moka_frame(self); struct value* val = malloc(sizeof(struct value)); value_init_bool(val, value, line); vec_push(&frame->local_values, val); size_t addr = frame->local_values.size - 1; vec_push(&frame->stack, (void*) addr); return addr; } float moka_get_bool(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value* val = frame->local_values.data[value]; assert(val->type == TY_BOOL); return val->data.boolean; } MOKA moka_push_string(struct moka* self, char const* value, int line) { assert(self); struct frame* frame = moka_frame(self); struct value* val = malloc(sizeof(struct value)); value_init_string(val, value, line); vec_push(&frame->local_values, val); size_t addr = frame->local_values.size - 1; vec_push(&frame->stack, (void*) addr); return addr; } char* moka_get_string(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value* val = frame->local_values.data[value]; assert(val->type == TY_STRING); return val->data.str; } MOKA moka_push_symbol(struct moka* self, char const* value, int line) { assert(self); struct frame* frame = moka_frame(self); struct value* val = malloc(sizeof(struct value)); value_init_symbol(val, value, line); vec_push(&frame->local_values, val); size_t addr = frame->local_values.size - 1; vec_push(&frame->stack, (void*) addr); return addr; } char* moka_get_symbol(struct moka* self, MOKA value) { assert(self); struct frame* frame = moka_frame(self); struct value* val = frame->local_values.data[value]; assert(val->type == TY_SYMBOL); return val->data.sym; }