Skip to content

Commit

Permalink
*: revert GC-safe API, turn to conservative GC
Browse files Browse the repository at this point in the history
GC-safe API is inconvenient, essentially operating on a stack machine.
No variables available, just Push/Pop etc...
  • Loading branch information
tiancaiamao committed Sep 20, 2023
1 parent 7d50baa commit 83dcc25
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 117 deletions.
9 changes: 3 additions & 6 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

static void
repl(struct VM *vm, int pos, FILE* stream) {
int ref = pos++;
struct SexpReader r = {.pkgMapping = Nil};
int errCode = 0;

Expand All @@ -18,23 +17,21 @@ repl(struct VM *vm, int pos, FILE* stream) {
printf("%d #> ", i);
}

Obj exp = sexpRead(vm, pos, &r, stream, &errCode);
Obj exp = sexpRead(&r, stream, &errCode);
if (errCode != 0) {
break;
}

/* printf("before macro expand =="); */
/* sexpWrite(stdout, exp); */

vmSet(vm, ref, exp);
exp = macroExpand(vm, pos, ref);
exp = macroExpand(vm, pos, exp);

/* printf("after macro expand =="); */
/* sexpWrite(stdout, exp); */
/* printf("\n"); */

vmSet(vm, ref, exp);
Obj res = eval(vm, pos, ref);
Obj res = eval(vm, pos, exp);

if (stream == stdin) {
sexpWrite(stdout, res);
Expand Down
21 changes: 7 additions & 14 deletions src/bootstrap_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,23 @@
#include "reader.h"
#include "vm.h"

extern Obj reverse(struct VM *vm, int pos, int O);
extern Obj reverse(Obj exp);

void readFileAsSexp(void *pc, Obj val, struct VM *vm, int pos) {
Obj path = vmGet(vm, 1);
Obj pkg = vmGet(vm, 2);

struct SexpReader r = {.pkgMapping = Nil, .selfPath = toCStr(stringStr(pkg))};
strBuf pathStr = stringStr(path);
FILE* f = fopen(toCStr(pathStr), "r");
int errCode = 0;

int ret = pos++;
vmSet(vm, ret, Nil);
int v = pos++;
Obj ret = Nil;
while(errCode == 0) {
vmSet(vm, v, sexpRead(vm, pos, &r, f, &errCode));
vmSet(vm, ret, vmCons(vm, v, ret));
Obj v = sexpRead(&r, f, &errCode);
ret = cons(v, ret);
}
fclose(f);

Obj tmp = reverse(vm, pos, ret);
vmReturn(vm, tmp);
ret = reverse(ret);
vmReturn(vm, ret);
}

void writeSexpToFile(void *pc, Obj val, struct VM *vm, int pos) {
Expand All @@ -51,9 +46,7 @@ int main(int argc, char *argv[]) {

// (load "lib/bootstrap.cora" "") to generate the new init.bc and compile.bc
char *s = "../lib/bootstrap.cora";
int tmp = pos++;
vmSet(vm, tmp, cons(intern("load"), cons(makeString(s, strlen(s)), cons(makeString("", 0), Nil))));
eval(vm, pos, tmp);
eval(vm, pos, cons(intern("load"), cons(makeString(s, strlen(s)), cons(makeString("", 0), Nil))));

// Check the new generated bytecode can be load successfully
loadByteCode(vm, pos, cstr("./init.bc"));
Expand Down
25 changes: 10 additions & 15 deletions src/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,18 @@ primLoad(struct VM *vm, int pos, str path, str pkg) {

struct SexpReader r = {.pkgMapping = Nil, .selfPath = pkg.str};
int err = 0;
Obj ast = sexpRead(vm, pos, &r, in, &err);
int ref = pos++;
Obj ast = sexpRead(&r, in, &err);
while(err == 0) {

/* printf("========================================= read == \n"); */
/* sexpWrite(stdout, ast); */
/* printf("\n"); */

vmSet(vm, ref, ast);
Obj exp = macroExpand(vm, pos, ref);
Obj exp = macroExpand(vm, pos, ast);

/* printObj(stdout, exp); */
/* printf("\n"); */

vmSet(vm, ref, exp);
eval(vm, pos, ref);
ast = sexpRead(vm, pos, &r, in, &err);
eval(vm, pos, exp);
ast = sexpRead(&r, in, &err);
}
fclose(in);
}
Expand Down Expand Up @@ -541,7 +536,7 @@ loadByteCode(struct VM *vm, int pos, str path) {
}
struct SexpReader r = {.pkgMapping = Nil, .selfPath = ""};
int err = 0;
Obj ast = sexpRead(vm, pos, &r, in, &err);
Obj ast = sexpRead(&r, in, &err);
while(ast != Nil) {
/* printf("========================================= read == \n"); */
Obj code = car(ast);
Expand All @@ -557,11 +552,11 @@ loadByteCode(struct VM *vm, int pos, str path) {


Obj
eval(struct VM *vm, int pos, Ref exp) {
eval(struct VM *vm, int pos, Obj exp) {
// call (cora/lib/compile.cc exp) to generate the bytecode
Obj compile = symbolGet(makeSymbol("cora/lib/compile.cc"));
vmPush(vm, pos++, compile);
vmPush(vm, pos++, vmRef(vm, exp));
vmPush(vm, pos++, exp);
Obj res = vmCall(vm, pos, 2);

/* printf("the byte code is ===\n"); */
Expand All @@ -578,12 +573,12 @@ eval(struct VM *vm, int pos, Ref exp) {
}

Obj
macroExpand(struct VM *vm, int pos, Ref exp) {
macroExpand(struct VM *vm, int pos, Obj exp) {
Obj val = symbolGet(symMacroExpand);
if (val == Nil || val == Undef) {
return vmRef(vm, exp);
return exp;
}
vmPush(vm, pos++, val);
vmPush(vm, pos++, vmRef(vm, exp));
vmPush(vm, pos++, exp);
return vmCall(vm, pos, 2);
}
15 changes: 5 additions & 10 deletions src/eval_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,8 @@ TestEvalBasic() {
struct SexpReader r = {.pkgMapping = Nil};
FILE* f = fmemopen(c->input, strlen(c->input), "r");
int errCode;
Obj s = sexpRead(vm, pos, &r, f, &errCode);
int ref = pos++;
vmSet(vm, ref, s);
Obj res = eval(vm, pos, ref);
Obj s = sexpRead(&r, f, &errCode);
Obj res = eval(vm, pos, s);

char output[512];
memset(output, 0, 512);
Expand Down Expand Up @@ -328,7 +326,6 @@ TestTryCatch() {
/* char *pkgName = "cora/init"; */
/* eval(vm, cons(intern("import"), cons(makeString(pkgName, strlen(pkgName)), Nil))); */

int ref = pos++;
for (int i=0; i<sizeof(cases)/sizeof(struct testCase); i++) {
struct testCase *c = &cases[i];

Expand All @@ -337,11 +334,9 @@ TestTryCatch() {
struct SexpReader r = {.pkgMapping = Nil};
FILE* f = fmemopen(c->input, strlen(c->input), "r");
int errCode;
Obj s = sexpRead(vm, pos, &r, f, &errCode);
vmSet(vm, ref, s);
Obj exp = macroExpand(vm, pos, ref);
vmSet(vm, ref, exp);
Obj res = eval(vm, pos, ref);
Obj s = sexpRead(&r, f, &errCode);
Obj exp = macroExpand(vm, pos, s);
Obj res = eval(vm, pos, exp);

char output[512];
memset(output, 0, 512);
Expand Down
48 changes: 20 additions & 28 deletions src/reader.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "reader.h"
#include "types.h"
#include "vm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -55,21 +54,21 @@ peekFirstChar(FILE *in) {
}

static Obj
readCons(struct VM *vm, int pos, struct SexpReader *r, FILE *in, int *errCode) {
readCons(struct SexpReader *r, FILE *in, int *errCode) {
int c = getc(in);
if (c == ')') {
// read the empty list
return Nil;
}

ungetc(c, in);
Obj hd = sexpRead(vm, pos, r, in, errCode);
Obj hd = sexpRead(r, in, errCode);

c = peekFirstChar(in);
ungetc(c, in);

/* read list */
Obj tl = readCons(vm, pos, r, in, errCode);
Obj tl = readCons(r, in, errCode);

/* printf("read cdr"); */
/* printObj(cdr); */
Expand Down Expand Up @@ -97,38 +96,31 @@ readCons(struct VM *vm, int pos, struct SexpReader *r, FILE *in, int *errCode) {
}

Obj
reverse(struct VM *vm, int pos, int O) {
const int RET = pos++;
const int TMP = pos++;
vmSet(vm, RET, Nil);
while(vmRef(vm, O) != Nil) {
vmSet(vm, TMP, vmCar(vm, O));
vmSet(vm, RET, vmCons(vm, TMP, RET));
vmSet(vm, O, vmCdr(vm, O));
reverse(Obj o) {
Obj ret = Nil;
while (o != Nil) {
ret = cons(car(o), ret);
o = cdr(o);
}
return vmRef(vm, RET);
return ret;
}

static Obj
readListMacro(struct VM *vm, int pos, struct SexpReader *r, FILE *in, int *errCode) {
const int hd = pos;
vmPush(vm, pos++, intern("list"));
const int ret = pos;
vmPush(vm, pos++, Nil);
const int o = pos++;
readListMacro(struct SexpReader *r, FILE *in, int *errCode) {
Obj hd = intern("list");
Obj ret = Nil;
char b = peekFirstChar(in);
while (b != EOF && b != ']') {
if (b == '.') {
vmSet(vm, hd, intern("list-rest"));
hd = intern("list-rest");
} else {
ungetc(b, in);
vmSet(vm, o, sexpRead(vm, pos, r, in, errCode));
vmSet(vm, ret, vmCons(vm, o, ret));
Obj o = sexpRead(r, in, errCode);
ret = cons(o, ret);
}
b = peekFirstChar(in);
}
vmSet(vm, ret, reverse(vm, pos, ret));
return vmCons(vm, hd, ret);
return cons(hd, reverse(ret));
}

static Obj
Expand All @@ -151,7 +143,7 @@ readNumber(FILE *in) {
}

Obj
sexpRead(struct VM *vm, int pos, struct SexpReader* r, FILE *in, int *errCode) {
sexpRead(struct SexpReader* r, FILE *in, int *errCode) {
int c;
int i;
char buffer[512];
Expand All @@ -167,18 +159,18 @@ sexpRead(struct VM *vm, int pos, struct SexpReader* r, FILE *in, int *errCode) {

// read quote
if (c == '\'') {
Obj o = sexpRead(vm, pos, r, in, errCode);
Obj o = sexpRead( r, in, errCode);
return cons(symQuote, cons(o, Nil));
}

// read the empty list or pair
if (c == '(') {
return readCons(vm, pos, r, in, errCode);
return readCons(r, in, errCode);
}

// read list macro
if (c == '[') {
return readListMacro(vm, pos, r, in, errCode);
return readListMacro( r, in, errCode);
}

// read a string
Expand Down
4 changes: 1 addition & 3 deletions src/reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ struct SexpReader {
char *selfPath;
};

Obj sexpRead(struct VM *vm, int pos, struct SexpReader *r, FILE *in, int *errCode);
Obj sexpRead(struct SexpReader *r, FILE *in, int *errCode);
void sexpWrite(FILE *out, Obj obj);

/* Obj reverse(Obj o); */

void printObj(FILE* f, Obj o);

#endif
10 changes: 3 additions & 7 deletions src/reader_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@

static void
TestReadSexp() {
struct VM *vm = newVM();
int pos = 0;
char buffer[] = "(a b c)";
/* char buffer[] = "(a)"; */
FILE *stream = fmemopen(buffer, strlen(buffer), "r");

struct SexpReader reader = {.pkgMapping = Nil};
int errCode;
Obj o = sexpRead(vm, pos, &reader, stream, &errCode);
Obj o = sexpRead(&reader, stream, &errCode);

/* Obj r = cons(intern("a"), cons(intern("b"), cons(intern("c"), Nil))); */
Obj z = cons(intern("a"), cons(intern("b"), cons(intern("c"), Nil)));
Expand All @@ -39,19 +37,17 @@ TestImport() {
char buffer[] = "(@import \"std/cora/basic\" xxx)\n(xxx.yyy 42)";
FILE *stream = fmemopen(buffer, strlen(buffer), "r");

struct VM *vm = newVM();
int pos = 0;
struct SexpReader r = {.pkgMapping = Nil};
int errCode;
Obj o = sexpRead(vm, pos, &r, stream, &errCode);
Obj o = sexpRead(&r, stream, &errCode);
Obj pathStr = makeString("std/cora/basic", 14);
Obj s = cons(intern("import"), cons(pathStr, Nil));
assert(eq(o, s));
/* printObj(stdout, r.pkgMapping); */
/* printf("\n"); */
assert(eq(r.pkgMapping, cons(cons(intern("xxx"), pathStr), Nil)));

Obj x = sexpRead(vm, pos, &r, stream, &errCode);
Obj x = sexpRead(&r, stream, &errCode);
/* printObj(stdout, x); */
/* printf("\n"); */
assert(eq(car(x), intern("std/cora/basic.yyy")));
Expand Down
25 changes: 0 additions & 25 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,16 +655,6 @@ vmReturn(struct VM *vm, Obj val) {
opExit(NULL, val, vm, 0);
}

void
vmSet(struct VM* vm, int ref, Obj val) {
vm->stack[ref] = val;
}

Obj
vmRef(struct VM *vm, int ref) {
return vm->stack[ref];
}

void
vmPush(struct VM *vm, int pos, Obj val) {
vm->stack[pos] = val;
Expand All @@ -686,18 +676,3 @@ vmCall(struct VM *vm, int pos, int n) {
makeTheCall(NULL, Nil, vm, pos);
return vm->result;
}

Obj
vmCar(struct VM *vm, int ref) {
return car(vm->stack[ref]);
}

Obj
vmCdr(struct VM *vm, int ref) {
return cdr(vm->stack[ref]);
}

Obj
vmCons(struct VM *vm, int r1, int r2) {
return cons(vm->stack[r1], vm->stack[r2]);
}
Loading

0 comments on commit 83dcc25

Please sign in to comment.