Browse Source

bytecode/vm stuff

master
Martin Dørum 3 years ago
parent
commit
3a5ceb9f33
5 changed files with 160 additions and 14 deletions
  1. 23
    0
      include/lang2/bytecode.h
  2. 8
    0
      include/lang2/parse/parse.h
  3. 45
    0
      include/lang2/vm/vm.h
  4. 48
    14
      src/main.c
  5. 36
    0
      src/vm/vm.c

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

@@ -0,0 +1,23 @@
#ifndef L2_BYTECODE_H
#define L2_BYTECODE_H

#include <stdint.h>

typedef uint32_t l2_word;

enum l2_opcode {
L2_OP_PUSH,
L2_OP_ADD,
L2_OP_JUMP,
L2_OP_CALL,
L2_OP_ALLOC_STRING,
L2_OP_ALLOC_ARRAY,
L2_OP_HALT,
};

struct l2_op {
enum l2_opcode code;
l2_word val;
};

#endif

+ 8
- 0
include/lang2/parse/parse.h View File

@@ -0,0 +1,8 @@
#ifndef L2_PARSE_H
#define L2_PARSE_H

#include "lex.h"

void l2_parse();

#endif

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

@@ -0,0 +1,45 @@
#ifndef L2_VM_H
#define L2_VM_H

#include <stdlib.h>

#include "../bytecode.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;
};

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;
};

struct l2_vm {
struct l2_op *ops;
size_t opcount;

struct l2_vm_value *allocs[1024];
size_t allocslen;

l2_word stack[1024];
l2_word iptr;
l2_word sptr;
};

void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount);
void l2_vm_step(struct l2_vm *vm);

#endif

+ 48
- 14
src/main.c View File

@@ -1,19 +1,53 @@
#include "io.h"
#include "parse/lex.h"
#include "vm/vm.h"
#include "bitmap.h"

#include <stdio.h>
#include <assert.h>

int main() {
struct l2_io_mem_reader r = { l2_io_mem_read };
r.mem = " \"Hello\", [], {}.";
r.len = strlen(r.mem);

struct l2_lexer lexer;
l2_lexer_init(&lexer, &r.r);

while (1) {
struct l2_token *tok = l2_lexer_get(&lexer);
printf("%s\n", l2_token_kind_name(tok->kind));
if (tok->kind == L2_TOK_EOF) {
break;
struct l2_bitmap bm;
l2_bitmap_init(&bm);
for (size_t i = 0; i < 8191; ++i) {
size_t id = l2_bitmap_set_next(&bm);
assert(id == i);
assert(l2_bitmap_get(&bm, i));
}

for (size_t i = 0; i < 10000; ++i) {
if (i < 8191) {
assert(l2_bitmap_get(&bm, i));
} else {
assert(!l2_bitmap_get(&bm, i));
}
}

l2_bitmap_unset(&bm, 100);
assert(l2_bitmap_set_next(&bm) == 8191);
assert(l2_bitmap_set_next(&bm) == 100);

l2_bitmap_free(&bm);
}

/*
int main() {
struct l2_op ops[] = {
{ L2_OP_PUSH, 100 },
{ L2_OP_PUSH, 100 },
{ L2_OP_ADD },
{ L2_OP_HALT },
};

struct l2_vm vm;
l2_vm_init(&vm, ops, sizeof(ops) / sizeof(*ops));

while (vm.ops[vm.iptr].code != L2_OP_HALT) {
printf("Exec %i\n", vm.ops[vm.iptr].code);
l2_vm_step(&vm);
}

printf("Done. Stack:\n");
for (l2_word i = 0; i < vm.sptr; ++i) {
printf(" %i: %i\n", i, vm.stack[i]);
}
}
*/

+ 36
- 0
src/vm/vm.c View File

@@ -0,0 +1,36 @@
#include "vm/vm.h"

void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount) {
vm->ops = ops;
vm->opcount = opcount;
vm->iptr = 0;
vm->sptr = 0;
}

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;
}

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

switch (op.code) {
case L2_OP_PUSH:
vm->stack[vm->sptr++] = op.val;
break;

case L2_OP_ADD:
vm->sptr -= 1;
vm->stack[vm->sptr - 1] += vm->stack[vm->sptr];
break;

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

case L2_OP_HALT:
break;
}
}

Loading…
Cancel
Save