Code:
@name G3P Compiler
@inputs RPN:string Device:wirelink Offset
@persist Bytecodes:table Index Compiling:array
@outputs Compiled:array
if(~RPN & RPN:length()){Compiled = array(30,4)
#All functions produced start by popping (30)
#the return value off the stack into edx (4)
#Make sure to push it back on before the ret! (9,4,40)
Compiling = RPN:explode(" ")
}
while(Compiling:count()){
if(minquota()<300){interval(20) break} #Don't run out of quota
Token = Compiling:shiftString()
if(Token:toNumber()|Token == "0"){Compiled:pushNumber(9)
Compiled:pushNumber(0)
Compiled:pushNumber(Token:toNumber())}
elseif(Bytecodes[Token,string]){
Temp = Bytecodes[Token,string]:explode(",")
while(Temp:count()){Compiled:pushNumber(Temp:shiftString():toNumber())}
}
else{print("Compiler error: \"" + Token + "\" is not a recognized token.")}
#Todo: Finish clause, including pushing the return pointer onto stack
#Todo: Check for stack safety. Balance between pushes(9) and pops(30)
#How to exclude values which are not code but the numbers?
#Check for next value being 1-4?
#Output to hispeed memory
}
if(!Compiling:count()){Compiled:pushNumber(9)
Compiled:pushNumber(4)
Compiled:pushNumber(40)
printTable(Compiled)}
if(first()){
#Initialize bytecodes for operations
#General structure of operations: Pop any arguments off stack, do operation, push result back on
#Numbers: handled at compiletime, except for
Bytecodes["par",string] = "9,3" #The parameter, which is kept in ecx and can be pushed to stack as needed
#Operators:
Bytecodes["+",string] = "30,1,30,2,10,20001,9,1"
Bytecodes["-",string] = "30,1,30,2,11,20001,9,1"
Bytecodes["*",string] = "30,1,30,2,12,20001,9,1"
Bytecodes["/",string] = "30,1,30,2,14,20001,9,1"
Bytecodes["^",string] = "30,1,30,2,80,20001,9,1"
#Functions:
Bytecodes["sin",string] = "30,1,54,10001,9,1"
Bytecodes["cos",string] = "30,1,55,10001,9,1"
Bytecodes["tan",string] = "30,1,57,10001,9,1"
Bytecodes["asin",string] = "30,1,58,10001,9,1"
Bytecodes["acos",string] = "30,1,59,10001,9,1"
Bytecodes["asin",string] = "30,1,58,10001,9,1"
Bytecodes["log",string] = "30,1,82,10001,9,1" #Natural logarithm
Bytecodes["log10",string] = "30,1,83,10001,9,1" #Briggs logarithm
} A sample of its output is perhaps also in order. For the input "3 8 * sin 20 *", or in other words the calculation 20*sin(3*8) ~ -18.1, it outputs this machine code: Code:
db 30,4,9,0,3,9,0,8,30,1,30,2,12,20001,9,1,30,1,54,10001,9,1,9,0,20,30,1,30,2,12,20001,9,1,9,4,40
or, in zASM
Bookmarks