Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,113 @@
// This is a little endian machine
const WORD_SIZE=4;
const{ var _n=-1; var[proxy]N=fcn{ _n+=1 }; } // enumerator
const FETCH=N, STORE=N, PUSH=N, ADD=N, SUB=N, MUL=N, DIV=N, MOD=N,
LT=N, GT=N, LE=N, GE=N, EQ=N, NE=N,
AND=N, OR=N, NEG=N, NOT=N,
JMP=N, JZ=N, PRTC=N, PRTS=N, PRTI=N, HALT=N;
const nd_String=N, nd_Sequence=N, nd_If=N, nd_While=N;
var all_syms=Dictionary(
"Identifier" ,FETCH, "String" ,nd_String,
"Integer" ,PUSH, "Sequence" ,nd_Sequence,
"If" ,nd_If, "Prtc" ,PRTC,
"Prts" ,PRTS, "Prti" ,PRTI,
"While" ,nd_While, "Assign" ,STORE,
"Negate" ,NEG, "Not" ,NOT,
"Multiply" ,MUL, "Divide" ,DIV,
"Mod" ,MOD, "Add" ,ADD,
"Subtract" ,SUB, "Less" ,LT,
"LessEqual" ,LE, "Greater" ,GT,
"GreaterEqual",GE, "Equal" ,EQ,
"NotEqual" ,NE, "And" ,AND,
"Or" ,OR, "halt" ,HALT);
var binOps=T(LT,GT,LE,GE,EQ,NE, AND,OR, SUB,ADD,DIV,MUL,MOD),
unaryOps=T(NEG,NOT);
class Node{
fcn init(_node_type, _value, _left=Void, _right=Void){
var type=_node_type, left=_left, right=_right, value=_value;
}
}
var vars=Dictionary(), strings=Dictionary(); // ( value:offset, ...)
fcn doVar(value){
var offset=-1; // fcn local static var
offset=_doValue(value,vars,offset)
}
fcn doString(str){ str=str[1,-1]; // str is \"text\"
var offset=-1; // fcn local static var
str=str.replace("\\n","\n");
offset=_doValue(str,strings,offset)
}
fcn _doValue(value,vars,offset){ //--> offset of value in vars
if(Void!=(n:=vars.find(value))) return(n); // fetch existing value
vars[value]=offset+=1; // store new value
}
fcn asm(node,code){
if(Void==node) return(code);
emitB:='wrap(n){ code.append(n) };
emitW:='wrap(n){ code.append(n.toLittleEndian(WORD_SIZE)) }; // signed
switch(node.type){
case(FETCH) { emitB(FETCH); emitW(doVar(node.value)); }
case(PUSH) { emitB(PUSH); emitW(node.value); }
case(nd_String){ emitB(PUSH); emitW(doString(node.value)); }
case(STORE){
asm(node.right,code);
emitB(STORE); emitW(doVar(node.left.value));
}
case(nd_If){
asm(node.left,code); # expr
emitB(JZ); # if false, jump
p1,p2 := code.len(),0;
emitW(0); # place holder for jump dest
asm(node.right.left,code); # if true statements
if (node.right.right!=Void){
emitB(JMP); # jump over else statements
p2=code.len();
emitW(0);
}
code[p1,WORD_SIZE]=(code.len() - p1).toLittleEndian(WORD_SIZE);
if(node.right.right!=Void){
asm(node.right.right,code); # else statements
code[p2,WORD_SIZE]=(code.len() - p2).toLittleEndian(WORD_SIZE)
}
}
case(nd_While){
p1:=code.len();
asm(node.left,code);
emitB(JZ);
p2:=code.len();
emitW(0); # place holder
asm(node.right,code);
emitB(JMP); # jump back to the top
emitW(p1 - code.len());
code[p2,WORD_SIZE]=(code.len() - p2).toLittleEndian(WORD_SIZE);
}
case(nd_Sequence){ asm(node.left,code); asm(node.right,code); }
case(PRTC,PRTI,PRTS){ asm(node.left,code); emitB(node.type); }
else{
if(binOps.holds(node.type)){
asm(node.left,code); asm(node.right,code);
emitB(node.type);
}
else if(unaryOps.holds(node.type))
{ asm(node.left,code); emitB(node.type); }
else throw(Exception.AssertionError(
"error in code generator - found %d, expecting operator"
.fmt(node.type)))
}
}
code
}
fcn code_finish(code){
code.append(HALT);
// prepend the strings to the code,
// using my magic [66,1 byte len,text], no trailing '\0' needed
idxs:=strings.pump(Dictionary(),"reverse");
idxs.keys.sort().reverse().pump(Void,'wrap(n){
text:=idxs[n];
code.insert(0,66,text.len(),text);
})
}

View file

@ -0,0 +1,35 @@
fcn unasm(code){
all_ops,nthString := all_syms.pump(Dictionary(),"reverse"),-1;
println("Datasize: %d bytes, Strings: %d bytes"
.fmt(vars.len()*WORD_SIZE,strings.reduce(fcn(s,[(k,v)]){ s+k.len() },0)));
word:='wrap(pc){ code.toLittleEndian(pc,WORD_SIZE,False) }; // signed
pc:=0; while(pc<code.len()){
op:=code[pc]; print("%4d: %2d ".fmt(pc,op));
pc+=1;
switch(op){
case(66){
n,str := code[pc], code[pc+=1,n].text;
println("String #%d %3d \"%s\"".fmt(nthString+=1,n,
Compiler.Asm.quotify(str)));
pc+=n;
}
case(FETCH,STORE,PUSH){
println("%s [%d]".fmt(all_ops[op],word(pc)));
pc+=WORD_SIZE;
}
case(ADD,SUB,MUL,DIV,MOD,LT,GT,LE,GE,EQ,NE,AND,OR,NEG,NOT,
PRTC,PRTI,PRTS,HALT){ println(all_ops[op]) }
case(JMP){
n:=word(pc);
println("jmp (%d) %d".fmt(n, pc + n));
pc+=WORD_SIZE;
}
case(JZ){
n:=word(pc);
println("jz (%d) %d".fmt(n, pc + n));
pc+=WORD_SIZE;
}
else throw(Exception.AssertionError("Unknown opcode %d".fmt(op)));
}
}
}

View file

@ -0,0 +1,12 @@
fcn load_ast(file){
line:=file.readln().strip(); // one or two tokens
if(line[0]==";") return(Void);
parts,type,value := line.split(),parts[0],parts[1,*].concat(" ");
type=all_syms[type];
if(value){
try{ value=value.toInt() }catch{}
return(Node(type,value));
}
left,right := load_ast(file),load_ast(file);
Node(type,Void,left,right)
}

View file

@ -0,0 +1,6 @@
ast:=load_ast(File(vm.nthArg(0)));
code:=asm(ast,Data());
code_finish(code);
unasm(code);
File("code.bin","wb").write(code);
println("Wrote %d bytes to code.bin".fmt(code.len()));