Progress on bootstrap, better keyword handling, etc
This commit is contained in:
parent
0dfe8dc93f
commit
09030ddc93
3 changed files with 260 additions and 52 deletions
|
@ -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]);
|
||||||
|
}
|
||||||
|
|
15
isbpl.isbpl
15
isbpl.isbpl
|
@ -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
|
||||||
|
|
||||||
|
|
95
std.isbpl
95
std.isbpl
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue