I'm uh... Working on something.
Don't worry about it too hard.
Cookies for anybody that figures out what it is.
#define INSTRUCTION_DEFINE 1
#define INSTRUCTION_ASSIGN 2
#define INSTRUCTION_ACCESS 3
#define INSTRUCTION_PUSH 4
#define INSTRUCTION_OPERATE 5
#define INSTRUCTION_IF 6
#define INSTRUCTION_ELSE 7
#define INSTRUCTION_LOOP 8
#define INSTRUCTION_DO 9
#define INSTRUCTION_CALL 10
#define INSTRUCTION_RETURN 11
#define INSTRUCTION_BREAK 12
#define INSTRUCTION_CONTINUE 13
#define OPERATION_ADD 1
#define OPERATION_SUB 2
#define OPERATION_MUL 3
#define OPERATION_DIV 4
#define OPERATION_MOD 5
#define OPERATION_SHIFTL 17
#define OPERATION_SHIFTR 18
#define OPERATION_EQUAL 33
#define OPERATION_NOT 34
#define OPERATION_GREATER 35
#define OPERATION_LESSER 36
#define OPERATION_GREATER_EQ 37
#define OPERATION_LESSER_EQ 38
#define OPERATION_AND 65
#define OPERATION_OR 66
#define OPERATION_NAND 67
#define OPERATION_XOR 68
programlet
var/tmp
list/funcs = list()
list/stack = list()
stackoffset = 1
proc
process(var/list/code,var/codestart=1,var/endat=0)
var/stackstart = stackoffset
var/codeoffset = codestart
if(endat==0)
endat = code.length+1
else
endat += codestart
var/r
while(codeoffset<endat)
r = instruction(code,codeoffset)
if(r==0)
break
codeoffset += r
. = pop()
instruction(var/list/code,var/codestart)
switch(code[codestart])
//define a variable for use later by stack position
if(INSTRUCTION_DEFINE)
//increase stack by 1 to create a variable reference
push(null)
. = 1
//assign a value to a variable by stack position
if(INSTRUCTION_ASSIGN)
stack[code[codestart+1]] = pop()
. = 2
//access a variable in the stack and push it to front
if(INSTRUCTION_ACCESS)
push(stack[code[codestart+1]])
. = 2
//temporarily push a value for immediate popping
if(INSTRUCTION_PUSH)
push(code[codestart+1])
. = 2
//pop last two values in stack and operate on them
//push result back into stack
if(INSTRUCTION_OPERATE)
push(operate(code[codestart+1],pop()))
. = 2
//perform an if statement
//return exit location of the loop
//then compare results. Increment skip pattern accordingly
if(INSTRUCTION_IF)
if(pop())
//increase the depth
process(code,codestart+3,code[codestart+1])
else
//capture the else block.
//else and end block will be the same
//if there is no else block
. = code[codestart+1]
. = code[codestart+2]
//else statements just parse a stack region.
//else statements are followed by the end offset
//else statements are skipped by successful if statements
if(INSTRUCTION_ELSE)
//increase the depth
process(code,codestart+2,code[codestart+1])
. = code[codestart+1]
//loop statements loop while a condition is true
//the loop function is called, which increases the depth
//the first value in the code after the loop instruction
//is the skip value, which tells us where the end of the loop is.
//the first instruction of the condition is after the skip value
if(INSTRUCTION_LOOP)
if(!loop(code,codestart+2,code[codestart+1]))
return pop()
. = code[codestart+1]
if(INSTRUCTION_CALL)
push(process(funcs[pop()]))
if(INSTRUCTION_RETURN)
return 0
operate(var/operation,var/value)
if(operation<OPERATION_EQUAL)
switch(operation)
if(OPERATION_ADD)
return pop()+value
if(OPERATION_SUB)
return pop()-value
if(OPERATION_MUL)
return pop()*value
if(OPERATION_DIV)
return pop()/value
if(OPERATION_MOD)
return pop()%value
if(OPERATION_SHIFTL)
return pop() << value
if(OPERATION_SHIFTR)
return pop() >> value
else if(operation<OPERATION_AND)
switch(operation)
if(OPERATION_EQUAL)
return pop()==value
if(OPERATION_NOT)
return !value
if(OPERATION_GREATER)
return pop()>value
if(OPERATION_LESSER)
return pop()<value
if(OPERATION_GREATER_EQ)
return pop()>=value
if(OPERATION_LESSER_EQ)
return pop()<=value
else
switch(operation)
if(OPERATION_AND)
return pop()&value
if(OPERATION_OR)
return pop()|value
if(OPERATION_NAND)
return pop()~value
if(OPERATION_XOR)
return pop()^value
loop(var/list/code,var/codestart,var/endat)
var/stackstart = stackoffset
var/codeoffset = codestart
endat += codestart
var/repeat = 1
var/ret
while(repeat)
while(code[codeoffset]!=INSTRUCTION_DO)
codeoffset += instruction(code,codeoffset)
repeat = pop()
if(repeat)
while(codeoffset<endat)
if(code[codeoffset]==INSTRUCTION_BREAK)
repeat = 0
if(code[codeoffset]==INSTRUCTION_CONTINUE)
break
else
ret = instruction(code,codeoffset)
if(ret==0)
. = pop()
stackoffset = stackstart
push(.)
return 0
codeoffset += ret
codeoffset = codestart
stackoffset = stackstart
return 1
pop()
. = stack[stackoffset]
stackoffset--
push(var/value)
stackoffset++
stack[stackoffset] = value