インタープリタを作る その3

#概要

インタープリタを作ってみた。
スタックマシン、インタープリタを作って見た。

#出来ること。

ループできる。


```
  push  0
  set  i
loop:  get  i
  push  25
  >
  jz  pass 
  get  i
  push  97
  +
  out
  get  i
  push  1
  +
  set  i
  jmp loop
pass:  end

```

#文法

コマンドとニーモニックがある。
コマンドは、new,list,runの3個。
ニーモニックは、push,get,set,>,jmp,jz,+,-,/,%,endの11個
ステートメントは、ラベル、2個のスペース、ニーモニック

#ニーモニック

##push  48

スタックに４８を積む。

##set  i

変数iにスタックトップをセットする。

##get  i

変数iからスタックに積む。

##+

スタックの一番と二番を加算する。

##-

スタックの一番と二番を減算する。

##/

スタックの一番と二番を除算する。

##%

スタックの一番と二番を剰余する。

##>

スタックの一番と二番を比較する。

##jmp  loop

loopに飛ぶ。

##jz  loop

スタックが０ならloopに飛ぶ。

##out

スタックトップを出力する。

##end

終了。

#コマンド

##new

ソースを消す。

##list

ソースを表示する。

##run

実行する。

#サンプルコード


```
var out = document.getElementById("out");
var src = document.getElementById("src"); 
var lines = "";

function run2(str) {
  str = str.replace(/\t/g, " ");
  str = str.replace(/  /g, " ");
  str = str.replace(/  /g, " ");
  str = str.replace(/  /g, " ");
  var codes = str.split("\n");  
  var pc = 0;  
  var sp = 0;
  var len = codes.length;
  var i;
  var label = {};
  var val = {};
  var ram = [];
  var res = "";
  for (i = 0; i < len; i++)
  {
    if (codes[i].indexOf(":") > -1) 
    {
      label[codes[i]] = i;
    }
  }
  while (i > 0)
  {
    var code = codes[pc].split(" ");
    switch (code[1])
    {
    case "push":
      if (code[2].charAt(0) == "'") 
      {
        ram[sp] = code[2].charCodeAt(1);
      }
      else
      {  
        ram[sp] = code[2];
      }
      sp++;
      pc++;
    break;
    case "set":  
      sp--;
      val[code[2]] = ram[sp];
      pc++;
    break;
    case "get":
      ram[sp] = val[code[2]];
      sp++;  
      pc++;
    break; 
    case "in":
      var c = prompt("char code", "");
      ram[sp] = parseInt(c);
      sp++;  
      pc++;
    break; 
    case "out":
      sp--;
      res += String.fromCharCode(ram[sp]);
      pc++;
    break;
    case "jz": 
      sp--;
      if (ram[sp] == 0)
      {
        pc = label[code[2] + ":"];
      }
      else
      {
        pc++;
      }
    break;
    case ">":  
      sp--;
      if (parseInt(ram[sp - 1]) > parseInt(ram[sp]))
      {
        ram[sp - 1] = 0;
      }
      else
      {
        ram[sp - 1] = 1;
      }
      pc++;
    break;
    case "+":  
      sp--;
      ram[sp - 1] = parseInt(ram[sp - 1]) + parseInt(ram[sp]);
      pc++;
    break;
    case "-":  
      sp--;
      ram[sp - 1] = parseInt(ram[sp - 1]) - parseInt(ram[sp]);
      pc++;
    break;
    case "/":  
      sp--;
      ram[sp - 1] = parseInt(ram[sp - 1]) / parseInt(ram[sp]);
      pc++;
    break;
    case "%":  
      sp--;
      ram[sp - 1] = parseInt(ram[sp - 1]) % parseInt(ram[sp]);
      pc++;
    break;
    case "jmp": 
      pc = label[code[2] + ":"];
    break;
    case "end":  
      i = 0;
    break;
    default:
      pc++;
    break;
    }
  }
  alert("ok");
  out.value = res;
}

function run() {
  var str = src.value;
  var code = str.split("  ");
  switch (code[0])
  {
  case "new":
    lines = "";
  break;
  case "list":
    out.value = lines;
  break;
  case "run": 
    run2(lines);
  break;
  default:
    lines += str + "\n";
  break;
  }
  src.value = "";
}



```

#成果物

https://embed.plnkr.co/plunk/KdrqOpp928qDBVEf

以上。