足し算、引き算を追加する
言語仕様
– 文字列
– 整数123, 実数123.4
– グローバル変数、変数の値の参照
– 代入演算子(=)
– print関数でカンマ区切りで複数の引数指定
– 複数文は、セミコロンで区切る
– // から行末まではコメント
– 足し算、引き算
### source.3
a = 1 + 2 - 4; print("a = 1 + 2 - 4 =", a); b = 3.5 - 1.2 + 0.1; print("b = 3.5 - 1.2 + 0.1 =", b);
### parse.js
function plus(){ var left = funccall(); var op; while(op = accept(tokens,"+","-")){ var right = funccall(); left = {left, op, right}; } return left; }
### run.js
const { error } = require("./utils"); module.exports = run; var global = {}; function run(a){ if(!a) return; if(!a.op){ if(a[0] == '"') return a.substr(1, a.length-2); if(/\d/.test(a[0])) return 1*a; if(global.hasOwnProperty(a)) return global[a]; return a; } else if (a.op==";"){ run(a.left); run(a.right); } else if (a.op==","){ return [run(a.left), run(a.right)].flat(); } else if (a.op=="="){ return global[run(a.left)] = run(a.right); } else if (a.op=="+"){ return run(a.left) + run(a.right); } else if (a.op=="-"){ return run(a.left) - run(a.right); } else if(a.op == "()") { var func = run(a.left); if(func == "print"){ var msg = [run(a.right)].flat().join(""); console.log(msg); } else { error("未実装の関数呼び出し func=", func); } } else { error("未実装の演算子 op=", a.op) } }
$ node interpretor.js
token =[
‘a’,
‘=’,
‘1’,
‘+’,
‘2’,
‘-‘,
‘4’,
‘;’,
‘print’,
‘(‘,
‘”a = 1 + 2 – 4 =”‘,
‘,’,
‘a’,
‘)’,
‘;’,
‘b’,
‘=’,
‘3.5’,
‘-‘,
‘1.2’,
‘+’,
‘0.1’,
‘;’,
‘print’,
‘(‘,
‘”b = 3.5 – 1.2 + 0.1 =”‘,
‘,’,
‘b’,
‘)’,
‘;’
]
ast={
left: {
left: {
left: {
left: {
left: ‘a’,
op: ‘=’,
right: {
left: { left: ‘1’, op: ‘+’, right: ‘2’ },
op: ‘-‘,
right: ‘4’
}
},
op: ‘;’,
right: {
left: ‘print’,
op: ‘()’,
right: { left: ‘”a = 1 + 2 – 4 =”‘, op: ‘,’, right: ‘a’ }
}
},
op: ‘;’,
right: {
left: ‘b’,
op: ‘=’,
right: {
left: { left: ‘3.5’, op: ‘-‘, right: ‘1.2’ },
op: ‘+’,
right: ‘0.1’
}
}
},
op: ‘;’,
right: {
left: ‘print’,
op: ‘()’,
right: { left: ‘”b = 3.5 – 1.2 + 0.1 =”‘, op: ‘,’, right: ‘b’ }
}
},
op: ‘;’,
right: undefined
}
a = 1 + 2 – 4 =-1
b = 3.5 – 1.2 + 0.1 =2.4
流れがわかってきましたね。