Note: This post is a continuation of LISPy-JSON Part 1, Part 2 and Part-3, you should read these prior to reading the current post.
Comparison and Boolean Operators are very simple to implement in our Interpreter’s model, If you remember how we implemented binary operators like +, – and so on, These would follow a similar pattern as Comparison and Boolean are binary operators too.
As shown in the image above, we just add their implementation to our map of binaryOperator functions. I forgot to add the ‘>=’ and the ‘<=’ operator but you could add them if you would like.
The entire program is as follows:
let program = [ { def: { 'a': 10 }}, { def: { 'b': 20 }}, { print: { '>': [{val: 'b'},{val:'a'}]}}, { print: { '<': [{val: 'a'},{val:'b'}]}}, { print: { '==': [{val: 'a'},{val:'b'}]}}, //b > a OR a == b { print: { '||': [{ '>': [{val: 'b'},{val:'a'}]},{ '==': [{val: 'a'},{val:'b'}]}] } }, //b > a AND a ==b { print: { '&&': [{ '>': [{val: 'b'},{val:'a'}]},{ '==': [{val: 'a'},{val:'b'}]}] } }, ] let builtins = { print: (text) => { console.log(text) } } let binaryOperators = { '+': (a,b) => { return a+b }, '-': (a,b) => { return a-b }, '*': (a,b) => { return a*b }, '>': (a,b) => { return a > b }, '<': (a,b) => { return a < b }, '==': (a,b) => { return a == b }, '||': (a,b) => { return a || b }, '&&': (a,b) => { return a && b }, } interpret = (program,state) => { for (let stmt of program) { exec(stmt,state) } }; varDefinition = (defObj, state) => { let variable = Object.keys(defObj)[0]; state[variable] = exec(defObj[variable],state) } varValue = (varKey,state) => { return state[varKey] } exec = (stmt,state) => { if(typeof stmt === 'number' || typeof stmt === 'string'){ return stmt; } let key = Object.keys(stmt)[0] if (typeof builtins[key] === 'function') { builtins[key](exec(stmt[key],state),state) } else if (typeof binaryOperators[key] === 'function') { let firstArgument = stmt[key][0]; let secondArgument = stmt[key][1]; return binaryOperators[key](exec(firstArgument,state), exec(secondArgument,state)) }else if (key === 'def') { let firstArgument = stmt[key] return varDefinition(firstArgument, state) }else if (key === 'val') { let firstArgument = stmt[key] return varValue(firstArgument, state) }else{ console.error('unknown instruction: '+key) } } interpret(program,{})
The output looks as follows:
$ node interpret.js
true
true
false
true
false
The diff from the previous version can be found here: https://github.com/avierr/LISPy-JSON-interpreter/commit/26b3d8efad83565089f7dff472faa16fa1aea341
The next post will focus on how to implement an if-else statement in our interpreter.
Tags: interpreter javascript