feat: implement objects and classes

This commit is contained in:
samsonium
2026-10-16 18:11:28 +03:00
parent 683dd08181
commit bc5d887ec4
22 changed files with 848 additions and 116 deletions
+90 -9
View File
@@ -1,4 +1,3 @@
#include "vm/fzl_vm_env.h"
#include <common/fzl_builtins.h>
#include <common/fzl_opcodes.h>
#include <common/fzl_types.h>
@@ -10,6 +9,8 @@
#include <stdlib.h>
#include <string.h>
#include <vm/fzl_vm.h>
#include <vm/fzl_vm_env.h>
#include <vm/fzl_vm_object.h>
char last_err[256];
@@ -24,18 +25,20 @@ fzl_vm_t *fzl_mkvm(const char *filepath)
return NULL;
}
vm->consts = NULL;
vm->consts_count = 0;
vm->ops = NULL;
vm->ops_count = 0;
vm->ip = 0;
vm->dtop = 0;
vm->ctop = 0;
vm->etop = 0;
vm->consts = NULL;
vm->consts_count = 0;
vm->ops = NULL;
vm->ops_count = 0;
vm->ip = 0;
vm->dtop = 0;
vm->ctop = 0;
vm->etop = 0;
vm->objects_count = 0;
memset(vm->dstack, 0, sizeof(vm->dstack));
memset(vm->cstack, 0, sizeof(vm->cstack));
memset(vm->estack, 0, sizeof(vm->estack));
memset(vm->objects, 0, sizeof(vm->objects));
FILE *fd = fopen(filepath, "rb");
if (!fd)
@@ -122,6 +125,84 @@ int fzl_vm_run(fzl_vm_t *vm)
switch (opcode)
{
case FZL_OPCODE_ALLOC_OBJECT:
{
uint64_t values_count = vm->ops[++vm->ip];
fzl_vm_object_t *obj = malloc(sizeof(fzl_vm_object_t));
obj->values = malloc(values_count * sizeof(fzl_value_t));
obj->values_count = values_count;
vm->objects[vm->objects_count++] = obj;
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_OBJECT, .as.obj = obj};
break;
}
case FZL_OPCODE_GET_FIELD:
{
if (vm->dtop < 1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected value in data stack");
return -1;
}
uint64_t field_slot = vm->ops[++vm->ip];
fzl_value_t val = vm->dstack[--vm->dtop];
if (val.type != FZL_TYPE_OBJECT)
{
snprintf(
last_err, sizeof(last_err),
"runtime error - cannot access field #%lu of non-object type",
field_slot);
return -1;
}
fzl_vm_object_t *obj = val.as.obj;
if (obj->values_count <= field_slot)
{
snprintf(last_err, sizeof(last_err),
"runtime error - cannot access field #%lu", field_slot);
return -1;
}
vm->dstack[vm->dtop++] = obj->values[field_slot];
break;
}
case FZL_OPCODE_SET_FIELD:
{
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
uint64_t field_slot = vm->ops[++vm->ip];
fzl_value_t objval = vm->dstack[--vm->dtop];
fzl_value_t wrval = vm->dstack[--vm->dtop];
if (objval.type != FZL_TYPE_OBJECT)
{
snprintf(
last_err, sizeof(last_err),
"runtime error - cannot access field #%lu of non-object type",
field_slot);
return -1;
}
fzl_vm_object_t *obj = objval.as.obj;
if (obj->values_count <= field_slot)
{
snprintf(last_err, sizeof(last_err),
"runtime error - cannot access field #%lu", field_slot);
return -1;
}
obj->values[field_slot] = wrval;
break;
}
case FZL_OPCODE_CALL:
{
uint64_t ip = vm->ops[++vm->ip];
+16 -4
View File
@@ -20,15 +20,27 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
switch (vm->ops[i])
{
case FZL_OPCODE_ALLOC_OBJECT:
printf("ALLOC_OBJECT: %lu fields\n", vm->ops[++i]);
break;
case FZL_OPCODE_GET_FIELD:
printf("GET_FIELD #%lu\n", vm->ops[++i]);
break;
case FZL_OPCODE_SET_FIELD:
printf("SET_FIELD #%lu\n", vm->ops[++i]);
break;
case FZL_OPCODE_CALL:
{
size_t ip = vm->ops[++i];
printf("Call IP: %lu\n", ip);
printf("CALL IP: %lu\n", ip);
break;
}
case FZL_OPCODE_RET:
printf("Return\n");
printf("RET\n");
break;
case FZL_OPCODE_LOADCONST:
@@ -77,7 +89,7 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
case FZL_OPCODE_DIV:
case FZL_OPCODE_POW:
case FZL_OPCODE_MOD:
printf("Math opcode\n");
printf("MATH\n");
break;
case FZL_OPCODE_AND:
@@ -129,7 +141,7 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
break;
default:
printf("<Unknown>\n");
printf("<UNKNOWN>\n");
}
}
}