Advertisement
WarPie90

Minified bytecode interpreter

Jan 1st, 2015
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.11 KB | None | 0 0
  1. program interpreter;
  2.  
  3. type
  4.   EByteCode = (
  5.     RETURN,
  6.     LOAD,
  7.     STORE,
  8.     POP_JMP_IF_FALSE,
  9.     DISCARD_TOP,
  10.     JMP,
  11.  
  12.     OP_ADD,
  13.     OP_SUB,
  14.     OP_MUL,
  15.     OP_CMPLT,
  16.  
  17.     PRINTFUNC
  18.   );
  19.  
  20.   TInstruction = record code:EByteCode; value:Int32; end;
  21.   TInstructions = Array of TInstruction;
  22.  
  23.  
  24. function TVariantArray.Pop(): Variant;
  25. var H:Int32;
  26. begin
  27.   H := High(Self);
  28.   Result := Self[H];
  29.   SetLength(Self, H);
  30. end;
  31.  
  32. procedure TVariantArray.Append(const Value:Variant);
  33. begin
  34.   Self += Value;
  35. end;
  36.  
  37.  
  38. procedure Interpret(ops:TInstructions; vars:TVariantArray);
  39. var
  40.   pc,left,right,tmp:Int32;
  41.   stack: TVariantArray;
  42.   instr: TInstruction;
  43. begin
  44.   pc := 0;
  45.   while True do
  46.   begin
  47.     instr := ops[pc];
  48.     inc(pc);
  49.     case instr.code of
  50.       LOAD:
  51.         stack.append(vars[instr.value]);
  52.       STORE:
  53.         vars[instr.value] := stack.pop();
  54.       DISCARD_TOP:
  55.         stack.pop();
  56.       POP_JMP_IF_FALSE:
  57.         if not stack.pop() then
  58.           pc := instr.value;
  59.       JMP:
  60.         pc := instr.value;
  61.       OP_ADD:
  62.         begin
  63.           right := stack.pop();
  64.           left  := stack.pop();
  65.           stack.append( Variant(left + right) );
  66.         end;
  67.       OP_SUB:
  68.         begin
  69.           right := stack.pop();
  70.           left  := stack.pop();
  71.           stack.append( Variant(left - right) );
  72.         end;
  73.       OP_MUL:
  74.         begin
  75.           right := stack.pop();
  76.           left  := stack.pop();
  77.           stack.append( Variant(left * right) );
  78.         end;
  79.       OP_CMPLT:
  80.         begin
  81.           right := stack.pop();
  82.           left  := stack.pop();
  83.           stack.append( Variant(left < right) );
  84.         end;
  85.       PRINTFUNC:
  86.         WriteLn(vars[instr.value]);
  87.       RETURN:
  88.         break;
  89.     end;
  90.   end;
  91.  
  92.   WriteLn('>>> Variables: ', vars);
  93. end;
  94.  
  95.  
  96.  
  97. (*
  98.   start := 0;
  99.   increment := 1;
  100.   stop := 10000;
  101.   repeat
  102.     start := start + increment;
  103.   until not(start < stop);
  104. *)
  105. procedure Test_Iterate(out vars: TVariantArray; out ops:TInstructions);
  106. begin
  107.   vars.Append(0);      //var "a"
  108.   vars.Append(1);      //var "b"
  109.   vars.Append(10);  //var "stop"
  110.  
  111.   ops := [
  112.       [LOAD,      0], //LOAD a           //from vars
  113.       [LOAD,      1], //LOAD b           //from vars
  114.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  115.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  116.  
  117.       [LOAD,      0], //LOAD a           //from vars
  118.       [LOAD,      2], //LOAD stop        //from vars
  119.       [OP_CMPLT,   ], //tmp := a < stop  //pops a and stop from stack and adds
  120.       [POP_JMP_IF_FALSE,  9],            //pop tmp, jump past `JMP`-instruction if false
  121.       [JMP,       0],                    //jumps to 0
  122.  
  123.       [RETURN,     ]  //done...
  124.     ];
  125. end;
  126.  
  127. (*
  128.   a := 5;
  129.   b := 10;
  130.   c := 100000;
  131.   repeat
  132.     a := a + b;
  133.     b := a * b;
  134.   until not(b < c);
  135. *)
  136. procedure Test_DoLoopThing(out vars: TVariantArray; out ops:TInstructions);
  137. begin
  138.   vars.Append(5);      //var "a"
  139.   vars.Append(10);     //var "b"
  140.   vars.Append(100000); //var "c"
  141.  
  142.   ops := [
  143.       [LOAD,      0], //LOAD a           //from vars
  144.       [LOAD,      1], //LOAD b           //from vars
  145.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  146.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  147.       [LOAD,      0], //LOAD a           //from vars
  148.       [LOAD,      1], //LOAD b           //from vars
  149.       [OP_MUL,     ], //tmp := a * b     //pops a and b from stack and muls
  150.       [STORE,     1], //b := tmp         //pops tmp from stack, adds to vars
  151.  
  152.       [LOAD,      1], //LOAD b           //from vars
  153.       [LOAD,      2], //LOAD c           //from vars
  154.       [OP_CMPLT,   ], //tmp := b < c
  155.       [POP_JMP_IF_FALSE,  13],           //pop tmp, jump past `JMP`-instruction if false
  156.       [JMP,       0],                    //jumps to 0
  157.  
  158.       [RETURN,     ]  //done...
  159.     ];
  160. end;
  161.  
  162. (*
  163.   a := 0;
  164.   b := 1;
  165.   stop := 500;
  166.   repeat
  167.     a := a + b;
  168.     writeLn(a);
  169.   until not(a < stop);
  170. *)
  171. procedure Test_Iterate2(out vars: TVariantArray; out ops:TInstructions);
  172. begin
  173.   vars.Append(1);      //var "a"
  174.   vars.Append(1);      //var "b"
  175.   vars.Append(500);    //var "stop"
  176.  
  177.   ops := [
  178.       [LOAD,      0], //LOAD a           //from vars
  179.       [LOAD,      1], //LOAD b           //from vars
  180.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  181.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  182.  
  183.       [PRINTFUNC, 0], //writeLn(a)       //hack to print
  184.  
  185.       [LOAD,      0], //LOAD a           //from vars
  186.       [LOAD,      2], //LOAD stop        //from vars
  187.       [OP_CMPLT,   ], //tmp := a < stop  //pops a and stop from stack and adds
  188.       [POP_JMP_IF_FALSE,  10],           //pop tmp, jump past `JMP`-instruction if false
  189.       [JMP,       0],                     //jumps to 0
  190.  
  191.       [RETURN,     ]  //done...
  192.     ];
  193. end;
  194.  
  195.  
  196. var
  197.   vars: TVariantArray;
  198.   ops: TInstructions;
  199. begin
  200.   Test_Iterate(vars,ops);
  201.   //Test_Iterate2(vars,ops);
  202.   //Test_DoLoopThing(vars,ops);
  203.  
  204.   Interpret(ops,vars);
  205. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement