Advertisement
WarPie90

Untitled

Aug 6th, 2016
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.22 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. (*Lape code:
  98.  
  99.   start := 0;
  100.   increment := 1;
  101.   stop := 10000;
  102.   repeat
  103.     start := start + increment;
  104.   until not(start < stop);
  105. *)
  106. procedure Test_Iterate(out vars: TVariantArray; out ops:TInstructions);
  107. begin
  108.   vars.Append(0);      //var "a"
  109.   vars.Append(1);      //var "b"
  110.   vars.Append(10);  //var "stop"
  111.  
  112.   ops := [
  113.       [LOAD,      0], //LOAD a           //from vars
  114.       [LOAD,      1], //LOAD b           //from vars
  115.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  116.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  117.  
  118.       [LOAD,      0], //LOAD a           //from vars
  119.       [LOAD,      2], //LOAD stop        //from vars
  120.       [OP_CMPLT,   ], //tmp := a < stop  //pops a and stop from stack and adds
  121.       [POP_JMP_IF_FALSE,  9],            //pop tmp, jump past `JMP`-instruction if false
  122.       [JMP,       0],                    //jumps to 0
  123.  
  124.       [RETURN,     ]  //done...
  125.     ];
  126. end;
  127.  
  128. (*Lape code:
  129.  
  130.   a := 5;
  131.   b := 10;
  132.   c := 100000;
  133.   repeat
  134.     a := a + b;
  135.     b := a * b;
  136.   until not(b < c);
  137. *)
  138. procedure Test_DoLoopThing(out vars: TVariantArray; out ops:TInstructions);
  139. begin
  140.   vars.Append(5);      //var "a"
  141.   vars.Append(10);     //var "b"
  142.   vars.Append(100000); //var "c"
  143.  
  144.   ops := [
  145.       [LOAD,      0], //LOAD a           //from vars
  146.       [LOAD,      1], //LOAD b           //from vars
  147.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  148.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  149.       [LOAD,      0], //LOAD a           //from vars
  150.       [LOAD,      1], //LOAD b           //from vars
  151.       [OP_MUL,     ], //tmp := a * b     //pops a and b from stack and muls
  152.       [STORE,     1], //b := tmp         //pops tmp from stack, adds to vars
  153.  
  154.       [LOAD,      1], //LOAD b           //from vars
  155.       [LOAD,      2], //LOAD c           //from vars
  156.       [OP_CMPLT,   ], //tmp := b < c
  157.       [POP_JMP_IF_FALSE,  13],           //pop tmp, jump past `JMP`-instruction if false
  158.       [JMP,       0],                    //jumps to 0
  159.  
  160.       [RETURN,     ]  //done...
  161.     ];
  162. end;
  163.  
  164. (*Lape code:
  165.  
  166.   a := 0;
  167.   b := 1;
  168.   stop := 100000;
  169.   repeat
  170.     a := a + b;
  171.     writeLn(a);
  172.   until not(a < stop);
  173. *)
  174. procedure Test_Iterate2(out vars: TVariantArray; out ops:TInstructions);
  175. begin
  176.   vars.Append(1);      //var "a"
  177.   vars.Append(1);      //var "b"
  178.   vars.Append(10000);  //var "stop" at
  179.  
  180.   ops := [
  181.       [LOAD,      0], //LOAD a           //from vars
  182.       [LOAD,      1], //LOAD b           //from vars
  183.       [OP_ADD,     ], //tmp := a + b     //pops a and b from stack and adds
  184.       [STORE,     0], //a := tmp         //pops tmp from stack, adds to vars
  185.  
  186.       //[PRINTFUNC, 0], //writeLn(a)
  187.  
  188.       [LOAD,      0], //LOAD a           //from vars
  189.       [LOAD,      2], //LOAD stop        //from vars
  190.       [OP_CMPLT,   ], //tmp := a < stop  //pops a and stop from stack and adds
  191.       [POP_JMP_IF_FALSE,  9],           //pop tmp, jump past `JMP`-instruction if false
  192.       [JMP,       0],                     //jumps to 0
  193.  
  194.       [RETURN,     ]  //done...
  195.     ];
  196. end;
  197.  
  198.  
  199. var
  200.   vars: TVariantArray;
  201.   ops: TInstructions;
  202.   t:Int64;
  203. begin
  204.   //Test_Iterate(vars,ops);
  205.   Test_Iterate2(vars,ops);
  206.   //Test_DoLoopThing(vars,ops);
  207.  
  208.   t := GetTickCount();
  209.   Interpret(ops,vars);
  210.   WriteLn('Executed in: ', GetTickCount() - t,'ms');
  211. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement