Browse Source

builtins, functions, etc

master
Martin Dørum 3 years ago
parent
commit
1d30f3c869
8 changed files with 98 additions and 3 deletions
  1. 4
    0
      include/lang2/builtins.x.h
  2. 1
    0
      include/lang2/vm/vm.h
  3. 2
    0
      lib/gen/gen.c
  4. 1
    0
      lib/parse/lex.c
  5. 1
    0
      lib/strset.c
  6. 79
    1
      lib/vm/builtins.c
  7. 1
    0
      lib/vm/print.c
  8. 9
    2
      lib/vm/vm.c

+ 4
- 0
include/lang2/builtins.x.h View File

@@ -1,5 +1,9 @@
// X macro: Define a macro named X, then include this file, then undef X.

#ifdef X
X("+", l2_builtin_add);
X("-", l2_builtin_sub);
X("*", l2_builtin_mul);
X("/", l2_builtin_div);
X("print", l2_builtin_print);
#endif

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

@@ -94,6 +94,7 @@ struct l2_vm {
};

void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount);
l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flags flags);
void l2_vm_free(struct l2_vm *vm);
void l2_vm_step(struct l2_vm *vm);
void l2_vm_run(struct l2_vm *vm);

+ 2
- 0
lib/gen/gen.c View File

@@ -28,6 +28,7 @@ void l2_gen_flush(struct l2_generator *gen) {
void l2_gen_free(struct l2_generator *gen) {
l2_strset_free(&gen->atomset);
l2_strset_free(&gen->stringset);
free(gen->strings);
}

void l2_gen_halt(struct l2_generator *gen) {
@@ -90,6 +91,7 @@ void l2_gen_string(struct l2_generator *gen, char **str) {
put(gen, L2_OP_RJMP);
l2_word pos = gen->pos;

gen->pos += aligned / sizeof(l2_word);
l2_bufio_put_n(&gen->writer, *str, len);
for (size_t i = len; i < aligned; ++i) {
l2_bufio_put(&gen->writer, '\0');

+ 1
- 0
lib/parse/lex.c View File

@@ -127,6 +127,7 @@ static void read_string(struct l2_lexer *lexer, struct l2_token *tok) {
while (1) {
int ch = read_ch(lexer);
if (ch == '"') {
tok->v.str[idx] = '\0';
return;
} else if (ch == EOF) {
tok->kind = L2_TOK_EOF;

+ 1
- 0
lib/strset.c View File

@@ -1,6 +1,7 @@
#include "strset.h"

#include <string.h>
#include <stdio.h>

// sdbm from http://www.cse.yorku.ca/~oz/hash.html;
// there are probably better algorithms out there

+ 79
- 1
lib/vm/builtins.c View File

@@ -2,7 +2,85 @@

#include <stdio.h>

static void print_val(struct l2_vm *vm, struct l2_vm_value *val) {
switch (l2_vm_value_type(val)) {
case L2_VAL_TYPE_NONE:
printf("(none)");
break;

case L2_VAL_TYPE_INTEGER:
printf("%zi", val->integer);
break;

case L2_VAL_TYPE_REAL:
printf("%g", val->real);
break;

case L2_VAL_TYPE_BUFFER:
fwrite(val->buffer->data, 1, val->buffer->len, stdout);
break;

case L2_VAL_TYPE_ARRAY:
putchar('[');
for (size_t i = 0; i < val->array->len; ++i) {
if (i != 0) {
printf(", ");
}

print_val(vm, &vm->values[val->array->data[i]]);
}
putchar(']');
break;

case L2_VAL_TYPE_NAMESPACE:
printf("(namespace)");
break;

case L2_VAL_TYPE_FUNCTION:
case L2_VAL_TYPE_CFUNCTION:
printf("(function)");
break;
}
}

l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
double sum = 0;
for (size_t i = 0; i < args->len; ++i) {
struct l2_vm_value *val = &vm->values[args->data[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
// TODO: Error
}

sum += val->real;
}

l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
vm->values[id].real = sum;
return id;
}

l2_word l2_builtin_sub(struct l2_vm *vm, struct l2_vm_array *args) {
return 0;
}

l2_word l2_builtin_mul(struct l2_vm *vm, struct l2_vm_array *args) {
return 0;
}

l2_word l2_builtin_div(struct l2_vm *vm, struct l2_vm_array *args) {
return 0;
}

l2_word l2_builtin_print(struct l2_vm *vm, struct l2_vm_array *args) {
printf("hey this is test\n");
for (size_t i = 0; i < args->len; ++i) {
if (i != 0) {
putchar(' ');
}

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

putchar('\n');
return 0;
}

+ 1
- 0
lib/vm/print.c View File

@@ -226,6 +226,7 @@ void l2_vm_print_op(l2_word *ops, size_t opcount, size_t *ptr) {
void l2_vm_print_bytecode(l2_word *ops, size_t opcount) {
size_t ptr = 0;
while (ptr < opcount) {
printf("%04zu ", ptr);
l2_vm_print_op(ops, opcount, &ptr);
}
}

+ 9
- 2
lib/vm/vm.c View File

@@ -12,7 +12,7 @@ static l2_word alloc_val(struct l2_vm *vm) {
vm->valuessize = 16;
}

while (id > vm->valuessize) {
while (id >= vm->valuessize) {
vm->valuessize *= 2;
}

@@ -164,6 +164,13 @@ void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount) {
#undef X
}

l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flags flags) {
l2_word id = alloc_val(vm);
memset(&vm->values[id], 0, sizeof(vm->values[id]));
vm->values[id].flags = typ | flags;
return id;
}

void l2_vm_free(struct l2_vm *vm) {
// Skip ID 0, because that's always NONE
for (size_t i = 1; i < vm->valuessize; ++i) {
@@ -266,7 +273,7 @@ void l2_vm_step(struct l2_vm *vm) {
vm->stack[vm->sptr++] = arr_id;

l2_word ns_id = alloc_val(vm);
vm->values[ns_id].extra.ns_parent = ns_id;
vm->values[ns_id].extra.ns_parent = func->func.namespace;
vm->values[ns_id].ns = NULL;
vm->values[ns_id].flags = L2_VAL_TYPE_NAMESPACE;
vm->nstack[vm->nsptr++] = ns_id;

Loading…
Cancel
Save