diff --git a/cli.js b/cli.js index d2931f7..37aa531 100755 --- a/cli.js +++ b/cli.js @@ -26,9 +26,24 @@ const printErrorMessage = (e, code) => { } } +let cache = [] +const getChar = () => { + if (cache.length <= 0) { + const input = fs.readFileSync(0).toString() + input.split('').forEach(char => cache.push(char)) + } + return cache.shift() +} + const makeCLIEnvironment = () => { const env = new Environment() env.setBuiltin('readFile', (_vars, args) => fs.readFileSync(args[0], 'utf8')) + env.setBuiltin('exit', (_vars, args) => process.exit(args[0] || 0)) + env.setBuiltin('chr', (_vars, args) => String.fromCharCode(args[0])) + env.setBuiltin('getc', () => { + const val = getChar() + return val ? val.charCodeAt(0) : -1 + }) return env } diff --git a/examples/getc.lox b/examples/getc.lox new file mode 100644 index 0000000..d9d8e74 --- /dev/null +++ b/examples/getc.lox @@ -0,0 +1,6 @@ + +var c = getc(); + +print c; + +print "done"; \ No newline at end of file diff --git a/hi.py b/hi.py deleted file mode 100644 index 573c6e4..0000000 --- a/hi.py +++ /dev/null @@ -1,19 +0,0 @@ -class Doughnut(): - def __init__(this, name): - this.name = name - def cook(this): - name = "" - if this.name: - name = this.name + " " - print "You fry the " + name + "Doughnut until golden brown." -class BostonCream(Doughnut): - def __init__(this): - Doughnut.__init__(this, "Boston Cream") -Doughnut("Cruller").cook() -BostonCream().cook() -def hello(): - print "Would you like some breakfast?" -print BostonCream -print Doughnut -print BostonCream() -print hello diff --git a/package-lock.json b/package-lock.json index 17c76ab..4c32dfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "yali", - "version": "0.10.2", + "name": "yalijs", + "version": "1.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -7622,7 +7622,7 @@ }, "prettier": { "version": "1.17.0", - "resolved": "http://registry.prod.auction.local:8081/repository/npm-internal/prettier/-/prettier-1.17.0.tgz", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", "dev": true }, diff --git a/transpilers/python.js b/transpilers/python.js index 29db5a8..9ef24f8 100644 --- a/transpilers/python.js +++ b/transpilers/python.js @@ -22,7 +22,6 @@ const { Condition } = require('../types') -// const condChar = (condition, replacer = ' ') => condition ? replacer : '' const indentation = (scope, options) => options.indent.repeat(scope) let lastSuperclass = 'super' @@ -104,7 +103,12 @@ ASTNodeMap.set(Super, ({ method: { lexeme: methodName }}) => { ASTNodeMap.set(This, ({ keyword }) => keyword.lexeme) -ASTNodeMap.set(Block, ({ statements }, scope, options, initialIndent) => statements.map(stmt => loxToPython2(stmt, scope, options, initialIndent)).join('\n')) +ASTNodeMap.set(Block, ({ statements }, scope, options, initialIndent) => { + if (statements.length <= 0) { + return indentation(scope, options) + 'pass' + } + return statements.map(stmt => loxToPython2(stmt, scope, options, initialIndent)).join('\n') +}) // Expressions ASTNodeMap.set(Var, ({ name: { lexeme } }) => lexeme) @@ -123,8 +127,10 @@ ASTNodeMap.set(Binary, handleBinary) ASTNodeMap.set(Logical, handleBinary) +const handleUnary = unary => unary === '!' ? 'not ' : unary + ASTNodeMap.set(Unary, node => { - const operator = node.operator.lexeme + const operator = handleUnary(node.operator.lexeme) const right = loxToPython2(node.right) return operator + right }) @@ -144,21 +150,25 @@ ASTNodeMap.set(Assignment, node => { return name + ' = ' + value }) -ASTNodeMap.set(Literal, ({ value }) => { +const handleLiteral = value => { if (typeof value === 'string') { return `"${value}"` + } else if (typeof value === 'boolean') { + return value ? 'True' : 'False' } else if (value === null) { return 'None' } else { return value } -}) +} + +ASTNodeMap.set(Literal, ({ value }) => handleLiteral(value)) const loxToPython2 = (node, scope = 0, optionsOverride = {}) => { const options = Object.assign({}, { indent: '\t', }, optionsOverride) - + if (!(node instanceof Object)) return handleLiteral(node) if (ASTNodeMap.has(node.constructor)) { return ASTNodeMap.get(node.constructor)(node, scope, options) }