Browse Source

vm stuff

master
Martin Dørum 3 years ago
parent
commit
64ec7d4725
4 changed files with 79 additions and 16 deletions
  1. 3
    0
      include/lang2/bytecode.h
  2. 1
    1
      include/lang2/parse/lex.h
  3. 17
    11
      include/lang2/vm/vm.h
  4. 58
    4
      src/vm/vm.c

+ 3
- 0
include/lang2/bytecode.h View File

@@ -10,6 +10,9 @@ enum l2_opcode {
L2_OP_ADD,
L2_OP_JUMP,
L2_OP_CALL,
L2_OP_RET,
L2_OP_ALLOC_INTEGER,
L2_OP_ALLOC_REAL,
L2_OP_ALLOC_STRING,
L2_OP_ALLOC_ARRAY,
L2_OP_HALT,

+ 1
- 1
include/lang2/parse/lex.h View File

@@ -1,7 +1,7 @@
#ifndef L2_PARSE_LEX_H
#define L2_PARSE_LEX_H

#include "../io.h"
#include "io.h"

enum l2_token_kind {
L2_TOK_OPEN_PAREN,

+ 17
- 11
include/lang2/vm/vm.h View File

@@ -3,26 +3,31 @@

#include <stdlib.h>

#include "../bytecode.h"
#include "bytecode.h"
#include "bitset.h"

enum {
L2_VAL_TYPE_STRING = (1 << 30) + 0,
L2_VAL_TYPE_ARRAY = (1 << 30) + 1,
L2_VAL_MARKED = 1 << 29,
};
struct l2_vm_value {
l2_word flags;
enum l2_value_flags {
L2_VAL_TYPE_INTEGER,
L2_VAL_TYPE_REAL,
L2_VAL_TYPE_STRING,
L2_VAL_TYPE_ARRAY,
L2_VAL_MARKED = 1 << 7,
} flags;
union {
int64_t integer;
double real;
void *data;
};
};

struct l2_vm_string {
struct l2_vm_value val;
char *mem;
size_t len;
};

struct l2_vm_array {
struct l2_vm_value val;
l2_word *data;
size_t len;
size_t size;
};
@@ -31,8 +36,9 @@ struct l2_vm {
struct l2_op *ops;
size_t opcount;

struct l2_vm_value *allocs[1024];
size_t allocslen;
struct l2_vm_value *values;
size_t valuessize;
struct l2_bitset valueset;

l2_word stack[1024];
l2_word iptr;

+ 58
- 4
src/vm/vm.c View File

@@ -5,17 +5,33 @@ void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount) {
vm->opcount = opcount;
vm->iptr = 0;
vm->sptr = 0;

vm->values = NULL;
vm->valuessize = 0;
l2_bitset_init(&vm->valueset);
}

static l2_word alloc(struct l2_vm *vm, size_t size) {
l2_word id = vm->allocslen++;
vm->allocs[id] = malloc(size);
return id | 1 << 31;
static l2_word alloc_val(struct l2_vm *vm) {
size_t id = l2_bitset_set_next(&vm->valueset);
if (id > vm->valuessize) {
if (vm->valuessize == 0) {
vm->valuessize = 16;
}

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

vm->values = realloc(vm->values, sizeof(*vm->values) * vm->valuessize);
}

return (l2_word)id;
}

void l2_vm_step(struct l2_vm *vm) {
struct l2_op op = vm->ops[vm->iptr++];

l2_word word;
switch (op.code) {
case L2_OP_PUSH:
vm->stack[vm->sptr++] = op.val;
@@ -30,6 +46,44 @@ void l2_vm_step(struct l2_vm *vm) {
vm->iptr = vm->stack[--vm->sptr];
break;

case L2_OP_CALL:
word = vm->stack[--vm->sptr];
vm->stack[vm->sptr++] = vm->iptr + 1;
vm->iptr = word;
break;

case L2_OP_RET:
vm->iptr = vm->stack[--vm->sptr];
break;

case L2_OP_ALLOC_INTEGER:
word = alloc_val(vm);
vm->values[word].flags = L2_VAL_TYPE_INTEGER;
vm->values[word].integer = 0;
vm->stack[vm->sptr++] = word;
break;

case L2_OP_ALLOC_REAL:
word = alloc_val(vm);
vm->values[word].flags = L2_VAL_TYPE_REAL;
vm->values[word].real = 0;
vm->stack[vm->sptr++] = word;
break;

case L2_OP_ALLOC_STRING:
word = alloc_val(vm);
vm->values[word].flags = L2_VAL_TYPE_STRING;
vm->values[word].data = calloc(1, sizeof(struct l2_vm_string));
vm->stack[vm->sptr++] = word;
break;

case L2_OP_ALLOC_ARRAY:
word = alloc_val(vm);
vm->values[word].flags = L2_VAL_TYPE_ARRAY;
vm->values[word].data = calloc(1, sizeof(struct l2_vm_array));
vm->stack[vm->sptr++] = word;
break;

case L2_OP_HALT:
break;
}

Loading…
Cancel
Save