[プログラミング言語の作り方] 足し算、引き算対応を作る

足し算、引き算を追加する

言語仕様
– 文字列
– 整数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

流れがわかってきましたね。