ID:1349941
 
Using this as a pastebin for the moment so I can go home from work and retrieve it. Unfortunately, and ironically, this is the only site my overlords haven't blocked that I've found.

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
You're writing a VM within a VM? That's so meta! :P
In response to DarkCampainger
DarkCampainger wrote:
You're writing a VM within a VM? That's so meta! :P

VMception.
If you want VMception make DM that emulates DM and launch it few levels deep.