Merge
This commit is contained in:
commit
a133ab8c55
4 changed files with 264 additions and 52 deletions
|
@ -2,3 +2,7 @@
|
|||
Improved Stack-Based Programming Language
|
||||
|
||||
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.
|
||||
|
|
|
@ -1,6 +1,204 @@
|
|||
#!/bin/node
|
||||
|
||||
const fs = require('fs')
|
||||
const process = require('process')
|
||||
const fs = require('fs');
|
||||
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 @@
|
|||
|
||||
"" =insns
|
||||
def insns
|
||||
|
||||
func main { # entry point returning int
|
||||
def insns filename
|
||||
=args # put arg array into args var
|
||||
args 0 aget =filename
|
||||
|
||||
|
@ -12,6 +12,12 @@ func main { # entry point returning int
|
|||
}
|
||||
|
||||
func compile {
|
||||
def file
|
||||
def content
|
||||
def i
|
||||
def ln
|
||||
def j
|
||||
def c
|
||||
=file
|
||||
|
||||
# read & split content
|
||||
|
@ -49,6 +55,11 @@ func compile {
|
|||
}
|
||||
|
||||
func mkcode {
|
||||
def allowfunc
|
||||
def content
|
||||
def definefunc
|
||||
def level
|
||||
def i
|
||||
=allowfunc
|
||||
=content
|
||||
|
||||
|
|
95
std.isbpl
95
std.isbpl
|
@ -1,18 +1,18 @@
|
|||
native func alen
|
||||
native func aget
|
||||
native func aput
|
||||
native func anew
|
||||
native func _array
|
||||
native alen
|
||||
native aget
|
||||
native aput
|
||||
native anew
|
||||
native _array
|
||||
func __array {
|
||||
"NotImplemented" "Not implemented" throw
|
||||
}
|
||||
|
||||
native func _char
|
||||
native func _int
|
||||
native func _file
|
||||
native func _float
|
||||
native func _long
|
||||
native func _double
|
||||
native _char
|
||||
native _int
|
||||
native _file
|
||||
native _float
|
||||
native _long
|
||||
native _double
|
||||
|
||||
func __char {
|
||||
_char
|
||||
|
@ -23,59 +23,58 @@ func __int {
|
|||
func __file {
|
||||
_file
|
||||
}
|
||||
native func __float
|
||||
native __float
|
||||
func __long {
|
||||
_long
|
||||
}
|
||||
native func __double
|
||||
native __double
|
||||
|
||||
native func ischar
|
||||
native func isint
|
||||
native func isfloat
|
||||
native func islong
|
||||
native func isdouble
|
||||
native ischar
|
||||
native isint
|
||||
native isfloat
|
||||
native islong
|
||||
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
|
||||
# "Please keep in mind that this will throw a native error if" pop
|
||||
# "called incorrectly - this means wrong layer parameter will" pop
|
||||
# "instantly crash the program." pop
|
||||
native func _layer_call
|
||||
native _layer_call
|
||||
func call {
|
||||
0 _layer_call
|
||||
}
|
||||
native func typename
|
||||
native func istype
|
||||
native func settype
|
||||
native func throw
|
||||
native include
|
||||
native putchar
|
||||
native read
|
||||
native flength
|
||||
native write
|
||||
native type
|
||||
native mktype
|
||||
native typename
|
||||
native istype
|
||||
native settype
|
||||
# try and catch are keywords, not functions
|
||||
native throw
|
||||
# storelength
|
||||
native func stlen
|
||||
native stlen
|
||||
|
||||
native func eq
|
||||
native func gt
|
||||
native func lt
|
||||
native func not
|
||||
native func or
|
||||
native func and
|
||||
native func +
|
||||
native func -
|
||||
native func /
|
||||
native func *
|
||||
native func **
|
||||
native func %
|
||||
native func ^
|
||||
native eq
|
||||
native gt
|
||||
native lt
|
||||
native not
|
||||
native or
|
||||
native and
|
||||
native +
|
||||
native -
|
||||
native /
|
||||
native *
|
||||
native **
|
||||
native %
|
||||
native ^
|
||||
|
||||
native func dup
|
||||
native func pop
|
||||
native func swap
|
||||
native dup
|
||||
native pop
|
||||
native swap
|
||||
|
||||
"char" mktype =TYPE_CHAR
|
||||
"int" mktype =TYPE_INT
|
||||
|
|
Loading…
Add table
Reference in a new issue