diff options
author | ubq323 <ubq323@ubq323.website> | 2023-07-31 18:51:46 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2023-07-31 18:51:46 +0100 |
commit | f80e73ee8d7f7b68f403033001c632e91cb5ac68 (patch) | |
tree | 359f785f785949191286214681b56058b4f025c4 | |
parent | cd6edc3cb4423672e92d3daaad8e12965ebc70e3 (diff) |
bytecode vm start, can print constants currently
-rw-r--r-- | run.h | 2 | ||||
-rw-r--r-- | run_old.c (renamed from run.c) | 0 | ||||
-rw-r--r-- | val.c | 16 | ||||
-rw-r--r-- | val.h | 9 | ||||
-rwxr-xr-x | vm | bin | 0 -> 20840 bytes | |||
-rw-r--r-- | vm.c | 102 | ||||
-rw-r--r-- | vm.h | 42 |
7 files changed, 169 insertions, 2 deletions
@@ -3,8 +3,8 @@ #include "ast.h" #include "ht.h" +#include "val.h" -int eval(Env *s, AstNode a); #endif @@ -0,0 +1,16 @@ +#include <stdio.h> +#include "val.h" + +void print_val(Val v) { + switch (v.ty) { + case TY_NIL: + printf("nil\n"); + break; + case TY_NUM: + printf("%f\n",AS_NUM(v)); + break; + case TY_BOOL: + printf("%s\n",AS_BOOL(v) ? "true" : "false"); + break; + } +} @@ -10,9 +10,9 @@ typedef struct _obj Obj; typedef enum { + TY_NIL, TY_NUM, TY_BOOL, - TY_NIL, } ValTy; struct _val { @@ -29,11 +29,18 @@ struct _obj { int foo; }; +void print_val(Val v); + #define IS_NUM(x) (x.ty == TY_NUM) #define IS_BOOL(x) (x.ty == TY_BOOL) #define IS_NIL(x) (x.ty == NIL) +#define AS_NUM(x) (x.as.d) +#define AS_BOOL(x) (x.as.b) +#define VAL_NUM(x) ((Val){.ty=TY_NUM, .as.d=x}) +#define VAL_BOOL(x) ((Val){.ty=TY_BOOL, .as.b=x}) +#define VAL_NIL ((Val){.ty=TY_NIL}) #endif Binary files differ@@ -0,0 +1,102 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> + +#include "val.h" +#include "vm.h" + +void *M(void *p, size_t sz) { + if (sz == 0) { + free(p); + return NULL; + } else { + return realloc(p, sz); + } +} + + +Chunk chunk_new() { + return (Chunk){ + .blen = 0, .bcap = 0, .b = NULL, + .clen = 0, .ccap = 0, .c = NULL, + }; +} +size_t chunk_wbc(Chunk *ch, uint8_t byte) { + if (ch->blen == ch->bcap) { + size_t newsz = (ch->bcap == 0 ? 8 : ch->bcap * 2); + ch->b = M(ch->b, newsz * sizeof(uint8_t)); + ch->bcap = newsz; + } + size_t ix = ch->blen; + ch->b[ix] = byte; + ch->blen ++; + return ix; +} +size_t chunk_wconst(Chunk *ch, Val v) { + if (ch->clen == ch->ccap) { + size_t newsz = (ch->ccap == 0 ? 8 : ch->ccap *2); + ch->c = M(ch->c, newsz * sizeof(Val)); + ch->ccap = newsz; + } + size_t ix = ch->clen; + ch->c[ix] = v; + ch->clen ++; + return ix; +} + +Vm vm_new(Chunk *ch) { + Vm vm = (Vm){ + .ch = ch, + .ip = 0, + .sp = 0 + }; + for (int i = 0; i < STACKSIZE; i++) { + vm.stack[i] = VAL_NIL; + } + return vm; +} + + +static void runvm() { + Chunk ch = chunk_new(); + chunk_wbc(&ch, OP_LOADK); + chunk_wbc(&ch, 1); + chunk_wbc(&ch, OP_PRINT); + chunk_wbc(&ch, OP_LOADK); + chunk_wbc(&ch, 2); + chunk_wbc(&ch, OP_LOADK); + chunk_wbc(&ch, 0); + chunk_wbc(&ch, OP_RET); + + chunk_wconst(&ch, VAL_BOOL(false)); + chunk_wconst(&ch, VAL_NIL); + chunk_wconst(&ch, VAL_NUM(420.69)); + + Vm vm = vm_new(&ch); +#define RBYTE() (vm.ch->b[vm.ip++]) + + while (1) { + uint8_t instr = RBYTE(); + switch (instr) { + case OP_RET: + printf("done!\n"); + goto done; + break; + case OP_LOADK: + uint8_t cix = RBYTE(); + Val v = vm.ch->c[cix]; + print_val(v); + break; + case OP_PRINT: + printf("print\n"); + break; + } + } + done:; +} + +int main() { runvm(); } + + @@ -0,0 +1,42 @@ +#ifndef _vm_h +#define _vm_h + +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> + +#include "val.h" + +void *M(void *p, size_t sz); + +typedef struct { + // bytecode + size_t blen; + size_t bcap; + uint8_t *b; + // constants + size_t clen; + size_t ccap; + Val *c; +} Chunk; +Chunk chunk_new(); +size_t chunk_wbc(Chunk *ch, uint8_t byte); +size_t chunk_wconst(Chunk *ch, Val v); + +#define STACKSIZE 128 +typedef struct { + Chunk *ch; + size_t ip; + Val stack[STACKSIZE]; + size_t sp; +} Vm; +Vm vm_new(Chunk *ch); + +typedef enum { + OP_RET, + OP_LOADK, + OP_PRINT, +} Op; + + +#endif |