LoginSignup
0
0

More than 5 years have passed since last update.

俺言語

Posted at

概要

俺言語をやってみた。
スタックマシーンでバイトコードインタープリタを書いてみた。

バイトコード

  push  "x"
  push  ""
  set  
  push  "i"
  push  "0"
  set
loop  push  "i"
  push  "i"
  push  "i"
  get
  ++
  set
  get
  push  "x"
  push  "x"
  get
  push  "i"
  get
  add
  set
  push  "x"
  push  "x"
  get
  push  " "
  add
  set  
  push  "i"
  get
  push  "100"
  >
  !
  if  skip
  jp  loop
skip  end

出力

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

仕様

一行は、ラベル、オペコード、値の順。
オペコードと意味は、以下。

push "x"   xをスタックに積む。
set        スタックのトップをスタックの2番目を変数として、メモリーにセーブして、トップと2番目を消費する。
get        スタックのトップを変数として、メモリーからロードして消費してから、積む。
++         スタックのトップをインクリメント。
add        スタックのトップと2番目を合体する。
>          スタックのトップと2番目を評価する。
!          スタックのトップを否定する。
if         スタックのトップが真なら、ラベルへジャンプ。
jp     ラベルへジャンプ。

スタックマシーンなバイトコードインタープリタ

function run() {
    var memory = [];
    var stack = [];
    var tmp;
    var v;
    var pc = 0;
    var src = document.getElementById('src0').value;
    var m = src.split("\n");
    var i;
    var flg = 0;
    while (flg == 0)
    {
        var cm = m[pc].split("  ");
        switch (cm[1])
        {
        case "push":
            tmp = cm[2].replace(/\"/g, "");
            stack.push(tmp);
        break;
        case "set":
            tmp = stack.pop();
            v = stack.pop();    
            memory[v] = tmp;
        break;
        case "get":
            v = stack.pop();    
            tmp = memory[v];
            stack.push(tmp);
        break;   
        case "++":
            tmp = stack.pop();
            tmp = new Number(tmp) + 1;
            stack.push(tmp);     
        break;   
        case "add":
            tmp = stack.pop(); 
            tmp = stack.pop() + " " + tmp;
            stack.push(tmp);
        break; 
        case ">":
            stack.push(stack.pop() > stack.pop());
        break;
        case "!":
            tmp = stack.pop();
            stack.push(!tmp); 
        break;        
        case "if":
            if (stack.pop())
            {
                for (i = 0; i < m.length; i++)
                {
                    var la = m[i].split("  ");
                    if (la[0] == cm[2])
                    {
                        pc = i - 1;
                    }
                }
            }
        break;
        case "jp":
            for (i = 0; i < m.length; i++)
            {
                var la = m[i].split("  ");
                if (la[0] == cm[2])
                {
                    pc = i - 1;
                }
            }
        break;          
        case "end":
            flg = 1;
        break;
        case "+":

                break;
        case "-":

                break;
        case "*":

                break;
        case "/":

                break;
        case "=":

                break;
        case "&":

                break;
        case "|":

                break;  
        case "^":

                break;
        case "%":

                break;   

        case "&&":
            stack.push(stack.pop() && stack.pop());
        break;
        case "||":
            stack.push(stack.pop() || stack.pop());
        break;

        case "==":
            stack.push(stack.pop() == stack.pop());
        break;
        case "pop":

        break;
        }
        pc++;
    }       
    var list = document.getElementById('out');
    list.innerHTML = memory["x"];
}



成果物

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0