Progress on bootstrap, better keyword handling, etc

This commit is contained in:
Daniella / Tove 2022-02-08 20:23:05 +01:00
parent 0dfe8dc93f
commit 09030ddc93
3 changed files with 260 additions and 52 deletions

View file

@ -1,6 +1,204 @@
#!/bin/node #!/bin/node
const fs = require('fs') const fs = require('fs');
const process = require('process') const process = require('process');
const stack = [];
const vars = [{}];
const keywords = [
"native",
"func",
"if",
"def",
"stop",
];
let insns;
let die = 0;
const natives = {
"alen": function () {
stack.push(stack.pop().length);
},
"aget": function () {
let idx = stack.pop();
let array = stack.pop();
stack.push(array[idx]);
},
"aput": function () {
let val = stack.pop();
let idx = stack.pop();
let array = stack.pop();
array[idx] = val;
},
"anew": function () {
let length = stack.pop();
let val = stack.pop();
stack.push(Array.apply(val, Array(length));
},
"_char": function () {
stack.push(String.fromCharCode(stack.pop()));
},
"_int": function () {
stack.push(Number(stack.pop()));
},
"_file": function () {
stack.push(String(stack.pop()));
},
"_float": function () {
stack.push(Number(stack.pop()));
},
"_long": function () {
stack.push(Number(stack.pop()));
},
"_double": function () {
stack.push(Number(stack.pop()));
},
"ischar": function () {
let x = stack.pop();
stack.push(x instanceof String && x.length == 1)
},
"isint": function () {
let x = stack.pop();
stack.push(x instanceof Number)
},
"isfloat": function () {
let x = stack.pop();
stack.push(x instanceof Number)
},
"islong": function () {
let x = stack.pop();
stack.push(x instanceof Number)
},
"isdouble": function () {
let x = stack.pop();
stack.push(x instanceof Number)
},
"putchar": function () {
if(x instanceof String && x.length == 1)
process.stdout.write(x);
else
process.stdout.write(Number(x))
process.stdout.flush();
},
"read": function () {
let filename = stack.pop();
stack.push(fs.readFileSync(filename, "iso-8859-1"));
},
"write": function () {
let content = stack.pop();
let filename = stack.pop();
fs.writeFileSync(filename, content, { encoding: "iso-8859-1" });
},
"flength": function () {
let filename = stack.pop();
stack.push(fs.statSync(filename).size);
},
"mktype": function () {
},
"type": function () {
},
"call": function () {
resolve(stack.pop(), 0);
},
"typename": function () {
}
}
function beginBlock(i) {
if(insns[i++] !== "{") {
console.err("Exoected { at " + insns[i] + " at beginning of block!")
process.exit(1);
}
const finsns = [];
let n = 1;
while(n > 0) {
finsns.push(insns[i]);
if(insns[i] === "{") n++;
if(insns[i] === "}") n--;
i++;
}
finsns.pop();
return [
function call () {
for(let j = 0; j < finsns.length; ) {
j = resolve(finsns[j], j);
if(die > 0) {
die--;
return;
}
}
},
i
]
}
function handleKeyword(id, i) {
if(id === "def") {
i++;
vars.peek()[insns[i]] = 0
vars.peek()["=" + insns[i]] = function set() {
vars.peek()[insns[i]] = stack.pop();
};
}
if(id === "native") {
i++;
vars.peek()[insns[i]] = natives[insns[i]];
}
if(id === "if") {
i++;
const block = beginBlock();
if(stack.pop()) {
block[0]();
}
i = block[1];
}
if(id === "func") {
i++;
const block = beginBlock(i);
vars.peek()[insns[i]] = block[0];
i = block[1];
}
if(id === "while") {
i++;
const n = i;
// This is needed to set the insn pointer to the right location after the block
let block;
while((function check() {
while(insns[i] !== "{") {
i = resolve(insns[i], i);
}
i--;
return stack.pop()
})()) {
block = block || beginBlock(i);
block[0]();
i = n;
}
block = block || beginBlock(i);
i = block[1];
}
if(id === "stop") {
die = stack.pop()
}
return i + 1;
}
function resolve(id, i) {
if(keywords.contains(keywords)) {
return handleKeyword(id, i);
}
let toRun = vars.peek()[id] || vars[0][id];
if(!toRun) {
console.err("Could not find keyword " + id + "!");
process.exit(1);
}
else {
toRun();
}
return ++i;
}
for(let i = 0; i < isns.length; ) {
i = resolve(insns[i]);
}

View file

@ -1,7 +1,7 @@
def insns
"" =insns
func main { # entry point returning int func main { # entry point returning int
def insns filename
=args # put arg array into args var =args # put arg array into args var
args 0 aget =filename args 0 aget =filename
@ -12,6 +12,12 @@ func main { # entry point returning int
} }
func compile { func compile {
def file
def content
def i
def ln
def j
def c
=file =file
# read & split content # read & split content
@ -49,6 +55,11 @@ func compile {
} }
func mkcode { func mkcode {
def allowfunc
def content
def definefunc
def level
def i
=allowfunc =allowfunc
=content =content

View file

@ -1,18 +1,18 @@
native func alen native alen
native func aget native aget
native func aput native aput
native func anew native anew
native func _array native _array
func __array { func __array {
"NotImplemented" "Not implemented" throw "NotImplemented" "Not implemented" throw
} }
native func _char native _char
native func _int native _int
native func _file native _file
native func _float native _float
native func _long native _long
native func _double native _double
func __char { func __char {
_char _char
@ -23,53 +23,52 @@ func __int {
func __file { func __file {
_file _file
} }
native func __float native __float
func __long { func __long {
_long _long
} }
native func __double native __double
native func ischar native ischar
native func isint native isint
native func isfloat native isfloat
native func islong native islong
native func isdouble native isdouble
native func stop native include
native func include native putchar
native func putchar native read
native func read native flength
native func flength native write
native func write native type
native func type native mktype
native func mktype
# call a dynamically computed function # call a dynamically computed function
native func call native call
native func typename native typename
native func istype native istype
native func settype native settype
native func throw
# try and catch are keywords, not functions # try and catch are keywords, not functions
native throw
# storelength # storelength
native func stlen native stlen
native func eq native eq
native func gt native gt
native func lt native lt
native func not native not
native func or native or
native func and native and
native func + native +
native func - native -
native func / native /
native func * native *
native func ** native **
native func % native %
native func ^ native ^
native func dup native dup
native func pop native pop
native func swap native swap
"char" mktype =TYPE_CHAR "char" mktype =TYPE_CHAR
"int" mktype =TYPE_INT "int" mktype =TYPE_INT