proc/SanitizeText(syntax)
syntax = replacetext(syntax," "," ")
syntax = replacetext(syntax,"\n"," ")
syntax = replacetext(syntax," "," ")
syntax = replacetext(syntax," "," ")
syntax = trimtext(syntax)
return syntax
proc/Encapsulate(syntax,mram,counter,start,end=start)
var a,b,list/tram = new
for()
a = findlasttext(syntax,start)
b = findtext(syntax,end,a+length(end))
if(!a||!b){break}
tram["_[++*counter]"] = trimtext(copytext(syntax,a+1,b))
syntax = copytext(syntax,1,a) + " _[*counter] " + copytext(syntax,b+length(end))
*mram = *mram + tram
return syntax
proc/Compile(syntax)
var list/ram = new, counter = 0
syntax = SanitizeText(syntax)
syntax = Encapsulate(syntax,&ram,&counter,"(",")")
syntax = Encapsulate(syntax,&ram,&counter,"{","}")
syntax = SanitizeText(syntax)
world << "<b>Syntax</b><br><tt>[syntax]<br><b>RAM</b>"
for(var/i in ram)
world << "<tt>Token([i]) = Value([ram[i]])"
var syntax = @{" i = 123 j = 321 if(j >= i){ print("[j] >= [i]") } else{ print("[i] > [j]") } "}
mob/Login()
Compile(syntax)
Problem description:
What would be the best coarse of action to go from here, How would you guys read the tokens, in what order, how should they be contained? How do I make trees?
Currently I'm encapsulating it all in order starting with () and then {}
The final results are
The tokens below the syntax are the base tokens that get read resulting in the other tokens being read.
There are two jump point instructions that you will be interested in, because you can emulate almost all high level patterns using them.
Let's call them jmp and cndjmp.
Jmp is a simple command. jmp tells the interpreter to move the spindle position (read index) to a specific instruction.
This covers the high level pattern: goto.
Cndjmp is a little more complicated. A cndjmp can take two values. One is a boolean conditional. The second is an instruction address. If the boolean condition evaluates to true, jump to the specified instruction address. If it is not true, discard the condition and the jump address.
This is the magic that makes if, else, switch, while, and for patterns work.
This would boil down to, in instructions:
Note that a cndjmp can be tuned to jump only when a value is NOT true, which will remove the not operation here, or you can have a cndjmp that has an else jump point included in the bytecode. The trick is, while you are parsing your tree, you need to be keeping track of label points and scope traversals, and then loop back to fill in the jump points after you have completed compiling the scope.
In essence, trees of logic patterns aren't really trees when they hit the interpreter. It's like a choose your own adventure book the computer is reading.