This commit is contained in:
Daniella / Tove 2022-02-23 17:20:09 +01:00
commit a133ab8c55
4 changed files with 264 additions and 52 deletions

View file

@ -2,3 +2,7 @@
Improved Stack-Based Programming Language Improved Stack-Based Programming Language
Incomplete, not currently compilable! Incomplete, not currently compilable!
JS Bootstrap is very, very, very DIRTY! Do not use it to run anything but
the compiler until the compiler is fully finished and can compile itself!!!
A pre-compiled compiler will be added as bootstrap as soon as possible.

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,59 +23,58 @@ 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 func include
native func putchar
native func read
native func flength
native func write
native func type
native func mktype
# "call a dynamically computed function" pop # "call a dynamically computed function" pop
# "Please keep in mind that this will throw a native error if" pop # "Please keep in mind that this will throw a native error if" pop
# "called incorrectly - this means wrong layer parameter will" pop # "called incorrectly - this means wrong layer parameter will" pop
# "instantly crash the program." pop # "instantly crash the program." pop
native func _layer_call native _layer_call
func call { func call {
0 _layer_call 0 _layer_call
} }
native func typename native include
native func istype native putchar
native func settype native read
native func throw native flength
native write
native type
native mktype
native typename
native istype
native settype
# 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