Browse Source

don't allocate arguments array for builtins

master
Martin Dørum 3 years ago
parent
commit
928f7cfc33
4 changed files with 50 additions and 41 deletions
  1. 1
    1
      include/lang2/vm/builtins.h
  2. 6
    1
      include/lang2/vm/vm.h
  3. 29
    26
      lib/vm/builtins.c
  4. 14
    13
      lib/vm/vm.c

+ 1
- 1
include/lang2/vm/builtins.h View File

#include "vm.h" #include "vm.h"


#define X(name, f) \ #define X(name, f) \
l2_word f(struct l2_vm *vm, struct l2_vm_array *args);
l2_word f(struct l2_vm *vm, l2_word argc, l2_word *argv);
#include "../builtins.x.h" #include "../builtins.x.h"
#undef X #undef X

+ 6
- 1
include/lang2/vm/vm.h View File



struct l2_vm; struct l2_vm;
struct l2_vm_array; struct l2_vm_array;
typedef l2_word (*l2_vm_cfunction)(struct l2_vm *vm, struct l2_vm_array *args);
struct l2_vm_args;
typedef l2_word (*l2_vm_cfunction)(struct l2_vm *vm, l2_word argc, l2_word *argv);

struct l2_vm_args {
l2_word argc;
};


enum l2_value_type { enum l2_value_type {
L2_VAL_TYPE_NONE, L2_VAL_TYPE_NONE,

+ 29
- 26
lib/vm/builtins.c View File

} }
} }


l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_add(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0; return 0;
} }


struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }


double sum = val->real; double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }
return id; return id;
} }


l2_word l2_builtin_sub(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_sub(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0; return 0;
} }


struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }


double sum = val->real; double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }
return id; return id;
} }


l2_word l2_builtin_mul(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_mul(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0; return 0;
} }


struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }


double sum = val->real; double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }
return id; return id;
} }


l2_word l2_builtin_div(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_div(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0; return 0;
} }


struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }


double sum = val->real; double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) { if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val); return l2_vm_type_error(vm, val);
} }
return id; return id;
} }


l2_word l2_builtin_print(struct l2_vm *vm, struct l2_vm_array *args) {
for (size_t i = 0; i < args->len; ++i) {
l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (size_t i = 0; i < argc; ++i) {
if (i != 0) { if (i != 0) {
vm->std_output->write(vm->std_output, " ", 1); vm->std_output->write(vm->std_output, " ", 1);
} }


struct l2_vm_value *val = &vm->values[args->data[i]];
struct l2_vm_value *val = &vm->values[argv[i]];
print_val(vm, vm->std_output, val); print_val(vm, vm->std_output, val);
} }


return 0; return 0;
} }


l2_word l2_builtin_len(struct l2_vm *vm, struct l2_vm_array *args) {
// TODO: error if wrong argc
l2_word l2_builtin_len(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return l2_vm_error(vm, "Expected at least 1 argument");
}

l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0); l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
struct l2_vm_value *ret = &vm->values[ret_id]; struct l2_vm_value *ret = &vm->values[ret_id];
ret->real = 0; ret->real = 0;


struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
switch (l2_vm_value_type(val)) { switch (l2_vm_value_type(val)) {
case L2_VAL_TYPE_NONE: case L2_VAL_TYPE_NONE:
case L2_VAL_TYPE_ATOM: case L2_VAL_TYPE_ATOM:

+ 14
- 13
lib/vm/vm.c View File

case L2_OP_FUNC_CALL: case L2_OP_FUNC_CALL:
{ {
l2_word argc = vm->ops[vm->iptr++]; l2_word argc = vm->ops[vm->iptr++];

l2_word arr_id = alloc_val(vm);
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * argc);
struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = argc;
arr->size = argc;

vm->sptr -= argc; vm->sptr -= argc;
for (l2_word i = 0; i < argc; ++i) {
arr->data[i] = vm->stack[vm->sptr + i];
}
l2_word *argv = vm->stack + vm->sptr;


l2_word func_id = vm->stack[--vm->sptr]; l2_word func_id = vm->stack[--vm->sptr];
struct l2_vm_value *func = &vm->values[func_id]; struct l2_vm_value *func = &vm->values[func_id];


// C functions are called differently from language functions // C functions are called differently from language functions
if (typ == L2_VAL_TYPE_CFUNCTION) { if (typ == L2_VAL_TYPE_CFUNCTION) {
vm->stack[vm->sptr++] = func->cfunc(vm, arr);
vm->stack[vm->sptr++] = func->cfunc(vm, argc, argv);
break; break;
} }


break; break;
} }


l2_word arr_id = alloc_val(vm);
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * argc);
struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = argc;
arr->size = argc;

for (l2_word i = 0; i < argc; ++i) {
arr->data[i] = argv[i];
}

vm->stack[vm->sptr++] = arr_id; vm->stack[vm->sptr++] = arr_id;


l2_word ns_id = alloc_val(vm); l2_word ns_id = alloc_val(vm);

Loading…
Cancel
Save