├── demo ├── correct0.lambda ├── correct2.lambda ├── incorrect1.lambda ├── high-order.lambda ├── correct1.lambda ├── correct5.lambda ├── correct3.lambda └── correct4.lambda ├── ast.js ├── symbol-table.js ├── package.json ├── README.md ├── .gitignore ├── index.js ├── simply-typed.peg ├── eval.js ├── compile.js ├── check.js ├── yarn.lock └── simply-typed.js /demo/correct0.lambda: -------------------------------------------------------------------------------- 1 | (λ a: Nat → succ succ a) 0 2 | -------------------------------------------------------------------------------- /demo/correct2.lambda: -------------------------------------------------------------------------------- 1 | (λ a: Bool → succ succ 0) iszero 0 -------------------------------------------------------------------------------- /demo/incorrect1.lambda: -------------------------------------------------------------------------------- 1 | (λ a: Nat → succ succ 0) iszero true -------------------------------------------------------------------------------- /demo/high-order.lambda: -------------------------------------------------------------------------------- 1 | ((λ a: Nat → λ b: Nat → succ a) 0) succ 0 2 | -------------------------------------------------------------------------------- /demo/correct1.lambda: -------------------------------------------------------------------------------- 1 | (λ a: Nat → a) if (λ a: Nat → iszero a) pred 0 then succ 0 else 0 -------------------------------------------------------------------------------- /demo/correct5.lambda: -------------------------------------------------------------------------------- 1 | ((((λ a: Nat → λ a: Nat → λ a: Nat → λ a: Nat → a) 0) 0) 0) 0 2 | -------------------------------------------------------------------------------- /demo/correct3.lambda: -------------------------------------------------------------------------------- 1 | ( 2 | λ x: Nat → 3 | (λ y: Nat → x) 0 4 | ) 5 | succ ( 6 | λ f: Nat → 7 | (λ g: Nat → g) 0 8 | ) 0 -------------------------------------------------------------------------------- /demo/correct4.lambda: -------------------------------------------------------------------------------- 1 | (λ a: Nat → a) 2 | (if 3 | (λ a: Nat → iszero a) pred 0 4 | then 5 | (λ a: Nat → succ a) 6 | else 7 | (λ a: Nat → pred a)) 8 | 0 9 | -------------------------------------------------------------------------------- /ast.js: -------------------------------------------------------------------------------- 1 | const ASTNodes = { 2 | Abstraction: 'abstraction', 3 | Condition: 'conditional_expression', 4 | Identifier: 'identifier', 5 | Literal: 'literal', 6 | Arithmetic: 'arithmetic', 7 | IsZero: 'is_zero', 8 | Application: 'application' 9 | }; 10 | 11 | const Types = { 12 | Boolean: 'Bool', 13 | Natural: 'Nat' 14 | } 15 | 16 | module.exports.ASTNodes = ASTNodes; 17 | module.exports.Types = Types; 18 | -------------------------------------------------------------------------------- /symbol-table.js: -------------------------------------------------------------------------------- 1 | module.exports.SymbolTableImpl = class SymbolTableImpl { 2 | constructor() { 3 | this.table = []; 4 | } 5 | push(scope) { 6 | this.table.push(scope); 7 | } 8 | lookup(x) { 9 | for (let i = this.table.length - 1; i >= 0; i -= 1) { 10 | const val = this.table[i].get(x); 11 | if (val !== undefined) { 12 | return val; 13 | } 14 | } 15 | return undefined; 16 | } 17 | } 18 | 19 | module.exports.Scope = class Scope { 20 | constructor() { 21 | this.map = {}; 22 | } 23 | add(x, val) { 24 | this.map[x] = val; 25 | } 26 | get(x) { 27 | return this.map[x]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typed-calc", 3 | "version": "1.0.0", 4 | "description": "Simply typed lambda calculus", 5 | "main": "index.js", 6 | "scripts": { 7 | "gen": "pegjs simply-typed.peg" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/mgechev/typed-calc.git" 12 | }, 13 | "author": "Minko Gechev ", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/mgechev/typed-calc/issues" 17 | }, 18 | "homepage": "https://github.com/mgechev/typed-calc#readme", 19 | "devDependencies": { 20 | "pegjs": "^0.10.0" 21 | }, 22 | "dependencies": { 23 | "chalk": "^1.1.3", 24 | "prettier": "^0.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simply Typed Lambda Calculus 2 | 3 | A type checker and interpreter for simply typed lambda calculus written in JavaScript. 4 | 5 | # Example 6 | 7 | The following program: 8 | 9 | ``` 10 | (λ a: Int → a) if (λ a: Int → iszero a) pred 0 then succ 0 else 0 11 | ``` 12 | 13 | Is correct and evaluates to `0`. 14 | 15 | # How to use? 16 | 17 | ## Interpreter 18 | 19 | ``` 20 | $ node index.js demo/correct1.lambda 21 | 22 | 0 23 | ``` 24 | 25 | ## Compiler 26 | 27 | ``` 28 | $ node index.js compile demo/correct1.lambda 29 | 30 | (function(a) { 31 | return a; 32 | })( 33 | (function(a) { 34 | return a === 0; 35 | })(0 - 1) 36 | ? 0 + 1 37 | : 0 38 | ); 39 | ``` 40 | 41 | # License 42 | 43 | MIT 44 | 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | typings 30 | dist 31 | .vscode 32 | 33 | demo/dist 34 | demo/vendor 35 | dist 36 | dist-test 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { parse } = require('./simply-typed'); 2 | const { Check } = require('./check'); 3 | const { Eval } = require('./eval'); 4 | const { green, red } = require('chalk'); 5 | const { CompileJS } = require('./compile'); 6 | // const { CompileWat } = require('./compile-wat'); 7 | const { readFileSync, existsSync } = require('fs'); 8 | 9 | const getAst = program => { 10 | const ast = parse(program); 11 | 12 | const diagnostics = Check(ast).diagnostics; 13 | if (diagnostics.length) { 14 | console.error(red(diagnostics.join('\n'))); 15 | process.exit(1); 16 | } 17 | 18 | return ast; 19 | }; 20 | 21 | const fileName = process.argv.pop(); 22 | let mode = process.argv.pop(); 23 | let target = process.argv.pop(); 24 | 25 | if (mode === 'wat' || target === 'compile') { 26 | [mode, target] = [target, mode]; 27 | } 28 | 29 | if (!existsSync(fileName)) { 30 | console.error(`"${fileName}" does not exist.`) 31 | process.exit(1); 32 | } 33 | 34 | const shouldCompile = mode === 'compile'; 35 | 36 | const userMessage = (shouldCompile ? 'Compiling' : 'Evaluating') + 37 | ` "${fileName}"` + 38 | (shouldCompile ? ` to ` + (target === 'wat' ? 'WebAssembly' : 'JavaScript') : '') + '.'; 39 | 40 | console.log(green(userMessage)); 41 | console.log(); 42 | 43 | const program = readFileSync(fileName, { encoding: 'utf-8' }); 44 | const ast = getAst(program); 45 | 46 | if (mode === 'compile') { 47 | let result = ''; 48 | if (target === 'wat') { 49 | result = CompileWat(ast); 50 | } else { 51 | result = CompileJS(ast); 52 | } 53 | console.log(result); 54 | } else { 55 | console.log(Eval(ast)); 56 | } 57 | -------------------------------------------------------------------------------- /simply-typed.peg: -------------------------------------------------------------------------------- 1 | Program = _'('*_ a:Application _')'?_ { 2 | return a; 3 | } 4 | 5 | Application = l:ExprAbs r:Application* { 6 | if (!r || !r.length) { 7 | return l; 8 | } else { 9 | r = r.pop(); 10 | return { type: 'application', left: l, right: r}; 11 | } 12 | }; 13 | 14 | ExprAbs = Expr / Abstraction; 15 | 16 | Abstraction = _ '('* _ 'λ' _ id:Identifier ':' t:Type '→' f:Application _ ')'? _ { 17 | return { type: 'abstraction', arg: { type: t, id: id }, body: f }; 18 | } 19 | 20 | Expr = IfThen / IsZeroCheck / ArithmeticOperation / Zero / True / False / Identifier / ParanExpression 21 | 22 | ArithmeticOperation = o:Operator e:Application { 23 | return { type: 'arithmetic', operator: o, expression: e }; 24 | }; 25 | 26 | IsZeroCheck = IsZero e:Application { 27 | return { type: 'is_zero', expression: e }; 28 | } 29 | 30 | Operator = Succ / Pred 31 | 32 | IfThen = If expr:Application Then then:Application Else el:Application { 33 | return { type: 'conditional_expression', condition: expr, then: then, el: el }; 34 | } 35 | 36 | Type = Nat / Bool 37 | 38 | _ = [ \t\r\n]* 39 | 40 | __ = [ \t\r\n]+ 41 | 42 | Identifier = !ReservedWord _ id:[a-z]+ _ { 43 | return { name: id.join(''), type: 'identifier' }; 44 | } 45 | 46 | ParanExpression = _'('_ expr:Expr _')'_ { 47 | return expr; 48 | } 49 | 50 | True = _ 'true' _ { 51 | return { type: 'literal', value: true }; 52 | } 53 | 54 | False = _ 'false' _ { 55 | return { type: 'literal', value: false }; 56 | } 57 | 58 | Zero = _ '0' _ { 59 | return { type: 'literal', value: 0 }; 60 | } 61 | 62 | ReservedWord = If / Then / Else / Pred / Succ / Nat / Bool / IsZero / False 63 | 64 | If = _'if'_ 65 | 66 | Then = _'then'_ 67 | 68 | Else = _'else'_ 69 | 70 | Pred = _'pred'_ { 71 | return 'pred'; 72 | } 73 | 74 | Succ = _'succ'_ { 75 | return 'succ'; 76 | } 77 | 78 | Nat = _'Nat'_ { 79 | return 'Nat'; 80 | } 81 | 82 | Bool = _'Bool'_ { 83 | return 'Bool'; 84 | } 85 | 86 | IsZero = _'iszero'_ { 87 | return 'iszero'; 88 | } 89 | -------------------------------------------------------------------------------- /eval.js: -------------------------------------------------------------------------------- 1 | const { SymbolTableImpl, Scope } = require('./symbol-table'); 2 | const { ASTNodes } = require('./ast'); 3 | 4 | const SymbolTable = new SymbolTableImpl(); 5 | 6 | const Eval = ast => { 7 | // The empty program evaluates to null. 8 | if (!ast) { 9 | return null; 10 | } 11 | 12 | // The literals evaluate to their values. 13 | if (ast.type === ASTNodes.Literal) { 14 | return ast.value; 15 | 16 | // The variables evaluate to the values 17 | // that are bound to them in the SymbolTable. 18 | } else if (ast.type === ASTNodes.Identifier) { 19 | return SymbolTable.lookup(ast.name); 20 | 21 | // if-then-else evaluates to the expression of the 22 | // then clause if the condition is true, otherwise 23 | // to the value of the else clause. 24 | } else if (ast.type === ASTNodes.Condition) { 25 | if (Eval(ast.condition)) { 26 | return Eval(ast.then); 27 | } else { 28 | return Eval(ast.el); 29 | } 30 | 31 | // The abstraction creates a new context of execution 32 | // and registers it's argument in the SymbolTable. 33 | } else if (ast.type === ASTNodes.Abstraction) { 34 | const scope = new Scope(); 35 | return x => { 36 | scope.add(ast.arg.id.name, x); 37 | SymbolTable.push(scope); 38 | return Eval(ast.body); 39 | }; 40 | 41 | // IsZero checks if the evaluated value of its 42 | // expression equals `0`. 43 | } else if (ast.type === ASTNodes.IsZero) { 44 | return Eval(ast.expression) === 0; 45 | 46 | // The arithmetic operations manipulate the value 47 | // of their corresponding expressions: 48 | // - `succ` adds 1. 49 | // - `pred` subtracts 1. 50 | } else if (ast.type === ASTNodes.Arithmetic) { 51 | const op = ast.operator; 52 | const val = Eval(ast.expression); 53 | switch (op) { 54 | case 'succ': 55 | return val + 1; 56 | case 'pred': 57 | return (val - 1 >= 0) ? val - 1 : val; 58 | } 59 | 60 | // The application evaluates to: 61 | // - Evaluation of the left expression. 62 | // - Evaluation of the right expression. 63 | // Application of the evaluation of the left expression over 64 | // the evaluated right expression. 65 | } else if (ast.type === ASTNodes.Application) { 66 | const l = Eval(ast.left); 67 | const r = Eval(ast.right); 68 | return l(r); 69 | } 70 | return true; 71 | }; 72 | 73 | module.exports.Eval = Eval; 74 | 75 | -------------------------------------------------------------------------------- /compile.js: -------------------------------------------------------------------------------- 1 | const { SymbolTableImpl, Scope } = require('./symbol-table'); 2 | const { ASTNodes } = require('./ast'); 3 | 4 | const prettier = require("prettier"); 5 | 6 | const SymbolTable = new SymbolTableImpl(); 7 | 8 | // Doesn't support lazy evaluation 9 | // so examples like `demo/correct4.lambda` will 10 | // not be transpiled correctly. 11 | const CompileJS = ast => { 12 | // The empty program compiles to an empty program ''. 13 | if (!ast) { 14 | return ''; 15 | } 16 | 17 | // The literals compile to their values. 18 | if (ast.type === ASTNodes.Literal) { 19 | return ast.value; 20 | 21 | // The variables compile to the identifiers. 22 | } else if (ast.type === ASTNodes.Identifier) { 23 | return ast.name; 24 | 25 | // if-then-else compiles to an if-then-else 26 | // construct in the target language. 27 | } else if (ast.type === ASTNodes.Condition) { 28 | const targetCondition = CompileJS(ast.condition); 29 | const targetThen = CompileJS(ast.then); 30 | const targetElse = CompileJS(ast.el); 31 | return `${targetCondition} ? ${targetThen} : ${targetElse}\n`; 32 | // The abstraction compiles to a function 33 | // from the target language. 34 | } else if (ast.type === ASTNodes.Abstraction) { 35 | return `(${ast.arg.id.name} => { 36 | return ${CompileJS(ast.body)} 37 | })`; 38 | 39 | // IsZero checks if the evaluated value of its 40 | // expression equals `0`. 41 | } else if (ast.type === ASTNodes.IsZero) { 42 | return `${CompileJS(ast.expression)} === 0\n`; 43 | 44 | // The arithmetic operations manipulate the value 45 | // of their corresponding expressions: 46 | // - `succ` adds 1. 47 | // - `pred` substracts 1. 48 | } else if (ast.type === ASTNodes.Arithmetic) { 49 | const op = ast.operator; 50 | const val = CompileJS(ast.expression); 51 | switch (op) { 52 | case 'succ': 53 | return `${val} + 1\n`; 54 | case 'pred': 55 | return `(${val} - 1 >= 0) ? ${val} - 1 : 0\n`; 56 | } 57 | 58 | // The application compiles to: 59 | // Invocation of the compiled left expression over 60 | // the compiled right expression. 61 | } else if (ast.type === ASTNodes.Application) { 62 | const l = CompileJS(ast.left); 63 | const r = CompileJS(ast.right); 64 | return `${l}(${r})\n`; 65 | } else { 66 | return ''; 67 | } 68 | }; 69 | 70 | module.exports.CompileJS = ast => 71 | prettier.format(CompileJS(ast), { 72 | printWidth: 80, 73 | tabWidth: 2, 74 | trailingComma: 'none', 75 | bracketSpacing: true, 76 | parser: 'babylon' 77 | }); 78 | -------------------------------------------------------------------------------- /check.js: -------------------------------------------------------------------------------- 1 | const { SymbolTableImpl, Scope } = require('./symbol-table'); 2 | const { ASTNodes, Types } = require('./ast'); 3 | 4 | const SymbolTable = new SymbolTableImpl(); 5 | 6 | const typeEq = (a, b) => { 7 | if (a instanceof Array && b instanceof Array) { 8 | if (a.length !== b.length) { 9 | return false; 10 | } else { 11 | for (let i = 0; i < a.length; i += 1) { 12 | if (!typeEq(a[i], b[i])) { 13 | return false; 14 | } 15 | } 16 | return true; 17 | } 18 | } else { 19 | if (typeof a === 'string' && typeof b === 'string') { 20 | return a === b; 21 | } 22 | } 23 | return false; 24 | }; 25 | 26 | const Check = (ast, diagnostics) => { 27 | diagnostics = diagnostics || []; 28 | 29 | // By definition empty AST is correct 30 | if (!ast) { 31 | return { 32 | diagnostics 33 | }; 34 | } 35 | 36 | // Literals: 37 | // - 0 is of type Natural 38 | // - false and true are of type Boolean 39 | // Everything else is incorrect. 40 | if (ast.type === ASTNodes.Literal) { 41 | if (ast.value === 0) { 42 | return { 43 | diagnostics, 44 | type: Types.Natural 45 | }; 46 | } else if (ast.value === false || ast.value === true) { 47 | return { 48 | diagnostics, 49 | type: Types.Boolean 50 | }; 51 | } else { 52 | diagnostics.push('Unknown type literal'); 53 | return { 54 | diagnostics 55 | }; 56 | } 57 | 58 | // We get the type of identifier from the symbol table 59 | } else if (ast.type === ASTNodes.Identifier) { 60 | return { 61 | diagnostics, 62 | type: SymbolTable.lookup(ast.name) 63 | }; 64 | 65 | // if-then-else block is correct if: 66 | // - The condition is of type Boolean. 67 | // - Then and else are of the same type. 68 | } else if (ast.type === ASTNodes.Condition) { 69 | if (!ast.then || !ast.el || !ast.condition) { 70 | diagnostics.push('No condition for a conditional expression'); 71 | return { 72 | diagnostics 73 | }; 74 | } 75 | const c = Check(ast.condition); 76 | diagnostics = diagnostics.concat(c.diagnostics); 77 | const conditionType = c.type; 78 | if (!typeEq(conditionType, Types.Boolean)) { 79 | diagnostics.push('Incorrect type of condition of condition'); 80 | return { 81 | diagnostics 82 | }; 83 | } 84 | const thenBranch = Check(ast.then); 85 | diagnostics = diagnostics.concat(thenBranch.diagnostics); 86 | const thenBranchType = thenBranch.type; 87 | const elseBranch = Check(ast.el); 88 | diagnostics = diagnostics.concat(elseBranch.diagnostics); 89 | const elseBranchType = elseBranch.type; 90 | if (typeEq(thenBranchType, elseBranchType)) { 91 | return thenBranch; 92 | } else { 93 | diagnostics.push('Incorrect type of then/else branches'); 94 | return { 95 | diagnostics 96 | }; 97 | } 98 | 99 | // Abstraction registers its argument in the SymbolTable 100 | // and returns a pair: 101 | // - The type of its argument. 102 | // - Type of its body, which may depend on the type 103 | // of the argument registered in the SymbolTable. 104 | } else if (ast.type === ASTNodes.Abstraction) { 105 | const scope = new Scope(); 106 | scope.add(ast.arg.id.name, ast.arg.type); 107 | SymbolTable.push(scope); 108 | if (!ast.body) { 109 | diagnostics.push('No body of a function'); 110 | return { 111 | diagnostics 112 | }; 113 | } 114 | const body = Check(ast.body); 115 | const bodyType = body.type; 116 | diagnostics = diagnostics.concat(body.diagnostics); 117 | if (!bodyType) { 118 | diagnostics.push('Incorrect type of the body'); 119 | return { 120 | diagnostics 121 | }; 122 | } 123 | return { 124 | diagnostics, 125 | type: [ast.arg.type, bodyType] 126 | }; 127 | 128 | // The type of IsZero is Boolean but in case 129 | // its argument is not Natural the program is incorrect. 130 | } else if (ast.type === ASTNodes.IsZero) { 131 | const body = Check(ast.expression); 132 | diagnostics = diagnostics.concat(body.diagnostics); 133 | const bodyType = body.type; 134 | if (!typeEq(bodyType, Types.Natural)) { 135 | diagnostics.push('Incorrect type of IsZero'); 136 | return { 137 | diagnostics 138 | }; 139 | } 140 | return { 141 | diagnostics, 142 | type: Types.Boolean 143 | }; 144 | 145 | // The type of the arithmetic operations are Natural 146 | // but in case the type of the body is not the entire 147 | // program is incorrect. 148 | } else if (ast.type === ASTNodes.Arithmetic) { 149 | const body = Check(ast.expression); 150 | diagnostics = diagnostics.concat(body.diagnostics); 151 | const bodyType = body.type; 152 | if (!typeEq(bodyType, Types.Natural)) { 153 | diagnostics.push(`Incorrect type of ${ast.operation}`); 154 | return { 155 | diagnostics 156 | }; 157 | } 158 | return { 159 | diagnostics, 160 | type: Types.Natural 161 | }; 162 | 163 | // The type of: 164 | // e1: T1, e2: T2, e1 e2: T1 165 | } else if (ast.type === ASTNodes.Application) { 166 | const l = Check(ast.left); 167 | const leftType = l.type || []; 168 | diagnostics = diagnostics.concat(l.diagnostics); 169 | const r = Check(ast.right); 170 | const rightType = r.type || []; 171 | diagnostics = diagnostics.concat(r.diagnostics); 172 | if (leftType.length) { 173 | if (!ast.right || leftType[0] === rightType) { 174 | return { 175 | diagnostics, 176 | type: leftType[1] 177 | }; 178 | } else { 179 | diagnostics.push('Incorrect type of application'); 180 | return { 181 | diagnostics 182 | }; 183 | } 184 | } else { 185 | return { diagnostics }; 186 | } 187 | } 188 | return { diagnostics }; 189 | }; 190 | 191 | module.exports.Check = ast => Check(ast); 192 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^2.0.0: 6 | version "2.1.1" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 8 | 9 | ansi-styles@^2.2.1: 10 | version "2.2.1" 11 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 12 | 13 | ansi-styles@^3.0.0: 14 | version "3.0.0" 15 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1" 16 | dependencies: 17 | color-convert "^1.0.0" 18 | 19 | ast-types@0.8.18: 20 | version "0.8.18" 21 | resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.18.tgz#c8b98574898e8914e9d8de74b947564a9fe929af" 22 | 23 | ast-types@0.9.4: 24 | version "0.9.4" 25 | resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.4.tgz#410d1f81890aeb8e0a38621558ba5869ae53c91b" 26 | 27 | babel-code-frame@6.22.0: 28 | version "6.22.0" 29 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" 30 | dependencies: 31 | chalk "^1.1.0" 32 | esutils "^2.0.2" 33 | js-tokens "^3.0.0" 34 | 35 | babylon@6.15.0: 36 | version "6.15.0" 37 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" 38 | 39 | balanced-match@^0.4.1: 40 | version "0.4.2" 41 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 42 | 43 | brace-expansion@^1.0.0: 44 | version "1.1.6" 45 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" 46 | dependencies: 47 | balanced-match "^0.4.1" 48 | concat-map "0.0.1" 49 | 50 | chalk@1.1.3, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: 51 | version "1.1.3" 52 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 53 | dependencies: 54 | ansi-styles "^2.2.1" 55 | escape-string-regexp "^1.0.2" 56 | has-ansi "^2.0.0" 57 | strip-ansi "^3.0.0" 58 | supports-color "^2.0.0" 59 | 60 | color-convert@^1.0.0: 61 | version "1.9.0" 62 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" 63 | dependencies: 64 | color-name "^1.1.1" 65 | 66 | color-name@^1.1.1: 67 | version "1.1.1" 68 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" 69 | 70 | colors@>=0.6.2: 71 | version "1.1.2" 72 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" 73 | 74 | concat-map@0.0.1: 75 | version "0.0.1" 76 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 77 | 78 | escape-string-regexp@^1.0.2: 79 | version "1.0.5" 80 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 81 | 82 | esutils@2.0.2, esutils@^2.0.2: 83 | version "2.0.2" 84 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 85 | 86 | flow-parser@0.40.0: 87 | version "0.40.0" 88 | resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.40.0.tgz#b3444742189093323c4319c4fe9d35391f46bcbc" 89 | dependencies: 90 | ast-types "0.8.18" 91 | colors ">=0.6.2" 92 | minimist ">=0.2.0" 93 | 94 | fs.realpath@^1.0.0: 95 | version "1.0.0" 96 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 97 | 98 | get-stdin@5.0.1: 99 | version "5.0.1" 100 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" 101 | 102 | glob@7.1.1: 103 | version "7.1.1" 104 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" 105 | dependencies: 106 | fs.realpath "^1.0.0" 107 | inflight "^1.0.4" 108 | inherits "2" 109 | minimatch "^3.0.2" 110 | once "^1.3.0" 111 | path-is-absolute "^1.0.0" 112 | 113 | has-ansi@^2.0.0: 114 | version "2.0.0" 115 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 116 | dependencies: 117 | ansi-regex "^2.0.0" 118 | 119 | inflight@^1.0.4: 120 | version "1.0.6" 121 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 122 | dependencies: 123 | once "^1.3.0" 124 | wrappy "1" 125 | 126 | inherits@2: 127 | version "2.0.3" 128 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 129 | 130 | jest-matcher-utils@^19.0.0: 131 | version "19.0.0" 132 | resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d" 133 | dependencies: 134 | chalk "^1.1.3" 135 | pretty-format "^19.0.0" 136 | 137 | jest-validate@19.0.0: 138 | version "19.0.0" 139 | resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.0.tgz#8c6318a20ecfeaba0ba5378bfbb8277abded4173" 140 | dependencies: 141 | chalk "^1.1.1" 142 | jest-matcher-utils "^19.0.0" 143 | leven "^2.0.0" 144 | pretty-format "^19.0.0" 145 | 146 | js-tokens@^3.0.0: 147 | version "3.0.1" 148 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" 149 | 150 | leven@^2.0.0: 151 | version "2.1.0" 152 | resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" 153 | 154 | minimatch@^3.0.2: 155 | version "3.0.3" 156 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 157 | dependencies: 158 | brace-expansion "^1.0.0" 159 | 160 | minimist@1.2.0, minimist@>=0.2.0: 161 | version "1.2.0" 162 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 163 | 164 | once@^1.3.0: 165 | version "1.4.0" 166 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 167 | dependencies: 168 | wrappy "1" 169 | 170 | path-is-absolute@^1.0.0: 171 | version "1.0.1" 172 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 173 | 174 | pegjs@^0.10.0: 175 | version "0.10.0" 176 | resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" 177 | 178 | prettier@^0.21.0: 179 | version "0.21.0" 180 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-0.21.0.tgz#5187ab95fdd9ca63dccf6217ed03b434d72771f8" 181 | dependencies: 182 | ast-types "0.9.4" 183 | babel-code-frame "6.22.0" 184 | babylon "6.15.0" 185 | chalk "1.1.3" 186 | esutils "2.0.2" 187 | flow-parser "0.40.0" 188 | get-stdin "5.0.1" 189 | glob "7.1.1" 190 | jest-validate "19.0.0" 191 | minimist "1.2.0" 192 | 193 | pretty-format@^19.0.0: 194 | version "19.0.0" 195 | resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84" 196 | dependencies: 197 | ansi-styles "^3.0.0" 198 | 199 | strip-ansi@^3.0.0: 200 | version "3.0.1" 201 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 202 | dependencies: 203 | ansi-regex "^2.0.0" 204 | 205 | supports-color@^2.0.0: 206 | version "2.0.0" 207 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 208 | 209 | wrappy@1: 210 | version "1.0.2" 211 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 212 | -------------------------------------------------------------------------------- /simply-typed.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by PEG.js 0.10.0. 3 | * 4 | * http://pegjs.org/ 5 | */ 6 | 7 | "use strict"; 8 | 9 | function peg$subclass(child, parent) { 10 | function ctor() { this.constructor = child; } 11 | ctor.prototype = parent.prototype; 12 | child.prototype = new ctor(); 13 | } 14 | 15 | function peg$SyntaxError(message, expected, found, location) { 16 | this.message = message; 17 | this.expected = expected; 18 | this.found = found; 19 | this.location = location; 20 | this.name = "SyntaxError"; 21 | 22 | if (typeof Error.captureStackTrace === "function") { 23 | Error.captureStackTrace(this, peg$SyntaxError); 24 | } 25 | } 26 | 27 | peg$subclass(peg$SyntaxError, Error); 28 | 29 | peg$SyntaxError.buildMessage = function(expected, found) { 30 | var DESCRIBE_EXPECTATION_FNS = { 31 | literal: function(expectation) { 32 | return "\"" + literalEscape(expectation.text) + "\""; 33 | }, 34 | 35 | "class": function(expectation) { 36 | var escapedParts = "", 37 | i; 38 | 39 | for (i = 0; i < expectation.parts.length; i++) { 40 | escapedParts += expectation.parts[i] instanceof Array 41 | ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) 42 | : classEscape(expectation.parts[i]); 43 | } 44 | 45 | return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; 46 | }, 47 | 48 | any: function(expectation) { 49 | return "any character"; 50 | }, 51 | 52 | end: function(expectation) { 53 | return "end of input"; 54 | }, 55 | 56 | other: function(expectation) { 57 | return expectation.description; 58 | } 59 | }; 60 | 61 | function hex(ch) { 62 | return ch.charCodeAt(0).toString(16).toUpperCase(); 63 | } 64 | 65 | function literalEscape(s) { 66 | return s 67 | .replace(/\\/g, '\\\\') 68 | .replace(/"/g, '\\"') 69 | .replace(/\0/g, '\\0') 70 | .replace(/\t/g, '\\t') 71 | .replace(/\n/g, '\\n') 72 | .replace(/\r/g, '\\r') 73 | .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) 74 | .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); 75 | } 76 | 77 | function classEscape(s) { 78 | return s 79 | .replace(/\\/g, '\\\\') 80 | .replace(/\]/g, '\\]') 81 | .replace(/\^/g, '\\^') 82 | .replace(/-/g, '\\-') 83 | .replace(/\0/g, '\\0') 84 | .replace(/\t/g, '\\t') 85 | .replace(/\n/g, '\\n') 86 | .replace(/\r/g, '\\r') 87 | .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) 88 | .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); 89 | } 90 | 91 | function describeExpectation(expectation) { 92 | return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); 93 | } 94 | 95 | function describeExpected(expected) { 96 | var descriptions = new Array(expected.length), 97 | i, j; 98 | 99 | for (i = 0; i < expected.length; i++) { 100 | descriptions[i] = describeExpectation(expected[i]); 101 | } 102 | 103 | descriptions.sort(); 104 | 105 | if (descriptions.length > 0) { 106 | for (i = 1, j = 1; i < descriptions.length; i++) { 107 | if (descriptions[i - 1] !== descriptions[i]) { 108 | descriptions[j] = descriptions[i]; 109 | j++; 110 | } 111 | } 112 | descriptions.length = j; 113 | } 114 | 115 | switch (descriptions.length) { 116 | case 1: 117 | return descriptions[0]; 118 | 119 | case 2: 120 | return descriptions[0] + " or " + descriptions[1]; 121 | 122 | default: 123 | return descriptions.slice(0, -1).join(", ") 124 | + ", or " 125 | + descriptions[descriptions.length - 1]; 126 | } 127 | } 128 | 129 | function describeFound(found) { 130 | return found ? "\"" + literalEscape(found) + "\"" : "end of input"; 131 | } 132 | 133 | return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; 134 | }; 135 | 136 | function peg$parse(input, options) { 137 | options = options !== void 0 ? options : {}; 138 | 139 | var peg$FAILED = {}, 140 | 141 | peg$startRuleFunctions = { Program: peg$parseProgram }, 142 | peg$startRuleFunction = peg$parseProgram, 143 | 144 | peg$c0 = "(", 145 | peg$c1 = peg$literalExpectation("(", false), 146 | peg$c2 = ")", 147 | peg$c3 = peg$literalExpectation(")", false), 148 | peg$c4 = function(a) { 149 | return a; 150 | }, 151 | peg$c5 = function(l, r) { 152 | if (!r || !r.length) { 153 | return l; 154 | } else { 155 | r = r.pop(); 156 | return { type: 'application', left: l, right: r}; 157 | } 158 | }, 159 | peg$c6 = "\u03BB", 160 | peg$c7 = peg$literalExpectation("\u03BB", false), 161 | peg$c8 = ":", 162 | peg$c9 = peg$literalExpectation(":", false), 163 | peg$c10 = "\u2192", 164 | peg$c11 = peg$literalExpectation("\u2192", false), 165 | peg$c12 = function(id, t, f) { 166 | return { type: 'abstraction', arg: { type: t, id: id }, body: f }; 167 | }, 168 | peg$c13 = function(o, e) { 169 | return { type: 'arithmetic', operator: o, expression: e }; 170 | }, 171 | peg$c14 = function(e) { 172 | return { type: 'is_zero', expression: e }; 173 | }, 174 | peg$c15 = function(expr, then, el) { 175 | return { type: 'conditional_expression', condition: expr, then: then, el: el }; 176 | }, 177 | peg$c16 = /^[ \t\r\n]/, 178 | peg$c17 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false), 179 | peg$c18 = /^[a-z]/, 180 | peg$c19 = peg$classExpectation([["a", "z"]], false, false), 181 | peg$c20 = function(id) { 182 | return { name: id.join(''), type: 'identifier' }; 183 | }, 184 | peg$c21 = function(expr) { 185 | return expr; 186 | }, 187 | peg$c22 = "true", 188 | peg$c23 = peg$literalExpectation("true", false), 189 | peg$c24 = function() { 190 | return { type: 'literal', value: true }; 191 | }, 192 | peg$c25 = "false", 193 | peg$c26 = peg$literalExpectation("false", false), 194 | peg$c27 = function() { 195 | return { type: 'literal', value: false }; 196 | }, 197 | peg$c28 = "0", 198 | peg$c29 = peg$literalExpectation("0", false), 199 | peg$c30 = function() { 200 | return { type: 'literal', value: 0 }; 201 | }, 202 | peg$c31 = "if", 203 | peg$c32 = peg$literalExpectation("if", false), 204 | peg$c33 = "then", 205 | peg$c34 = peg$literalExpectation("then", false), 206 | peg$c35 = "else", 207 | peg$c36 = peg$literalExpectation("else", false), 208 | peg$c37 = "pred", 209 | peg$c38 = peg$literalExpectation("pred", false), 210 | peg$c39 = function() { 211 | return 'pred'; 212 | }, 213 | peg$c40 = "succ", 214 | peg$c41 = peg$literalExpectation("succ", false), 215 | peg$c42 = function() { 216 | return 'succ'; 217 | }, 218 | peg$c43 = "Nat", 219 | peg$c44 = peg$literalExpectation("Nat", false), 220 | peg$c45 = function() { 221 | return 'Nat'; 222 | }, 223 | peg$c46 = "Bool", 224 | peg$c47 = peg$literalExpectation("Bool", false), 225 | peg$c48 = function() { 226 | return 'Bool'; 227 | }, 228 | peg$c49 = "iszero", 229 | peg$c50 = peg$literalExpectation("iszero", false), 230 | peg$c51 = function() { 231 | return 'iszero'; 232 | }, 233 | 234 | peg$currPos = 0, 235 | peg$savedPos = 0, 236 | peg$posDetailsCache = [{ line: 1, column: 1 }], 237 | peg$maxFailPos = 0, 238 | peg$maxFailExpected = [], 239 | peg$silentFails = 0, 240 | 241 | peg$result; 242 | 243 | if ("startRule" in options) { 244 | if (!(options.startRule in peg$startRuleFunctions)) { 245 | throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); 246 | } 247 | 248 | peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; 249 | } 250 | 251 | function text() { 252 | return input.substring(peg$savedPos, peg$currPos); 253 | } 254 | 255 | function location() { 256 | return peg$computeLocation(peg$savedPos, peg$currPos); 257 | } 258 | 259 | function expected(description, location) { 260 | location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) 261 | 262 | throw peg$buildStructuredError( 263 | [peg$otherExpectation(description)], 264 | input.substring(peg$savedPos, peg$currPos), 265 | location 266 | ); 267 | } 268 | 269 | function error(message, location) { 270 | location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) 271 | 272 | throw peg$buildSimpleError(message, location); 273 | } 274 | 275 | function peg$literalExpectation(text, ignoreCase) { 276 | return { type: "literal", text: text, ignoreCase: ignoreCase }; 277 | } 278 | 279 | function peg$classExpectation(parts, inverted, ignoreCase) { 280 | return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; 281 | } 282 | 283 | function peg$anyExpectation() { 284 | return { type: "any" }; 285 | } 286 | 287 | function peg$endExpectation() { 288 | return { type: "end" }; 289 | } 290 | 291 | function peg$otherExpectation(description) { 292 | return { type: "other", description: description }; 293 | } 294 | 295 | function peg$computePosDetails(pos) { 296 | var details = peg$posDetailsCache[pos], p; 297 | 298 | if (details) { 299 | return details; 300 | } else { 301 | p = pos - 1; 302 | while (!peg$posDetailsCache[p]) { 303 | p--; 304 | } 305 | 306 | details = peg$posDetailsCache[p]; 307 | details = { 308 | line: details.line, 309 | column: details.column 310 | }; 311 | 312 | while (p < pos) { 313 | if (input.charCodeAt(p) === 10) { 314 | details.line++; 315 | details.column = 1; 316 | } else { 317 | details.column++; 318 | } 319 | 320 | p++; 321 | } 322 | 323 | peg$posDetailsCache[pos] = details; 324 | return details; 325 | } 326 | } 327 | 328 | function peg$computeLocation(startPos, endPos) { 329 | var startPosDetails = peg$computePosDetails(startPos), 330 | endPosDetails = peg$computePosDetails(endPos); 331 | 332 | return { 333 | start: { 334 | offset: startPos, 335 | line: startPosDetails.line, 336 | column: startPosDetails.column 337 | }, 338 | end: { 339 | offset: endPos, 340 | line: endPosDetails.line, 341 | column: endPosDetails.column 342 | } 343 | }; 344 | } 345 | 346 | function peg$fail(expected) { 347 | if (peg$currPos < peg$maxFailPos) { return; } 348 | 349 | if (peg$currPos > peg$maxFailPos) { 350 | peg$maxFailPos = peg$currPos; 351 | peg$maxFailExpected = []; 352 | } 353 | 354 | peg$maxFailExpected.push(expected); 355 | } 356 | 357 | function peg$buildSimpleError(message, location) { 358 | return new peg$SyntaxError(message, null, null, location); 359 | } 360 | 361 | function peg$buildStructuredError(expected, found, location) { 362 | return new peg$SyntaxError( 363 | peg$SyntaxError.buildMessage(expected, found), 364 | expected, 365 | found, 366 | location 367 | ); 368 | } 369 | 370 | function peg$parseProgram() { 371 | var s0, s1, s2, s3, s4, s5, s6, s7; 372 | 373 | s0 = peg$currPos; 374 | s1 = peg$parse_(); 375 | if (s1 !== peg$FAILED) { 376 | s2 = []; 377 | if (input.charCodeAt(peg$currPos) === 40) { 378 | s3 = peg$c0; 379 | peg$currPos++; 380 | } else { 381 | s3 = peg$FAILED; 382 | if (peg$silentFails === 0) { peg$fail(peg$c1); } 383 | } 384 | while (s3 !== peg$FAILED) { 385 | s2.push(s3); 386 | if (input.charCodeAt(peg$currPos) === 40) { 387 | s3 = peg$c0; 388 | peg$currPos++; 389 | } else { 390 | s3 = peg$FAILED; 391 | if (peg$silentFails === 0) { peg$fail(peg$c1); } 392 | } 393 | } 394 | if (s2 !== peg$FAILED) { 395 | s3 = peg$parse_(); 396 | if (s3 !== peg$FAILED) { 397 | s4 = peg$parseApplication(); 398 | if (s4 !== peg$FAILED) { 399 | s5 = peg$parse_(); 400 | if (s5 !== peg$FAILED) { 401 | if (input.charCodeAt(peg$currPos) === 41) { 402 | s6 = peg$c2; 403 | peg$currPos++; 404 | } else { 405 | s6 = peg$FAILED; 406 | if (peg$silentFails === 0) { peg$fail(peg$c3); } 407 | } 408 | if (s6 === peg$FAILED) { 409 | s6 = null; 410 | } 411 | if (s6 !== peg$FAILED) { 412 | s7 = peg$parse_(); 413 | if (s7 !== peg$FAILED) { 414 | peg$savedPos = s0; 415 | s1 = peg$c4(s4); 416 | s0 = s1; 417 | } else { 418 | peg$currPos = s0; 419 | s0 = peg$FAILED; 420 | } 421 | } else { 422 | peg$currPos = s0; 423 | s0 = peg$FAILED; 424 | } 425 | } else { 426 | peg$currPos = s0; 427 | s0 = peg$FAILED; 428 | } 429 | } else { 430 | peg$currPos = s0; 431 | s0 = peg$FAILED; 432 | } 433 | } else { 434 | peg$currPos = s0; 435 | s0 = peg$FAILED; 436 | } 437 | } else { 438 | peg$currPos = s0; 439 | s0 = peg$FAILED; 440 | } 441 | } else { 442 | peg$currPos = s0; 443 | s0 = peg$FAILED; 444 | } 445 | 446 | return s0; 447 | } 448 | 449 | function peg$parseApplication() { 450 | var s0, s1, s2, s3; 451 | 452 | s0 = peg$currPos; 453 | s1 = peg$parseExprAbs(); 454 | if (s1 !== peg$FAILED) { 455 | s2 = []; 456 | s3 = peg$parseApplication(); 457 | while (s3 !== peg$FAILED) { 458 | s2.push(s3); 459 | s3 = peg$parseApplication(); 460 | } 461 | if (s2 !== peg$FAILED) { 462 | peg$savedPos = s0; 463 | s1 = peg$c5(s1, s2); 464 | s0 = s1; 465 | } else { 466 | peg$currPos = s0; 467 | s0 = peg$FAILED; 468 | } 469 | } else { 470 | peg$currPos = s0; 471 | s0 = peg$FAILED; 472 | } 473 | 474 | return s0; 475 | } 476 | 477 | function peg$parseExprAbs() { 478 | var s0; 479 | 480 | s0 = peg$parseExpr(); 481 | if (s0 === peg$FAILED) { 482 | s0 = peg$parseAbstraction(); 483 | } 484 | 485 | return s0; 486 | } 487 | 488 | function peg$parseAbstraction() { 489 | var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; 490 | 491 | s0 = peg$currPos; 492 | s1 = peg$parse_(); 493 | if (s1 !== peg$FAILED) { 494 | s2 = []; 495 | if (input.charCodeAt(peg$currPos) === 40) { 496 | s3 = peg$c0; 497 | peg$currPos++; 498 | } else { 499 | s3 = peg$FAILED; 500 | if (peg$silentFails === 0) { peg$fail(peg$c1); } 501 | } 502 | while (s3 !== peg$FAILED) { 503 | s2.push(s3); 504 | if (input.charCodeAt(peg$currPos) === 40) { 505 | s3 = peg$c0; 506 | peg$currPos++; 507 | } else { 508 | s3 = peg$FAILED; 509 | if (peg$silentFails === 0) { peg$fail(peg$c1); } 510 | } 511 | } 512 | if (s2 !== peg$FAILED) { 513 | s3 = peg$parse_(); 514 | if (s3 !== peg$FAILED) { 515 | if (input.charCodeAt(peg$currPos) === 955) { 516 | s4 = peg$c6; 517 | peg$currPos++; 518 | } else { 519 | s4 = peg$FAILED; 520 | if (peg$silentFails === 0) { peg$fail(peg$c7); } 521 | } 522 | if (s4 !== peg$FAILED) { 523 | s5 = peg$parse_(); 524 | if (s5 !== peg$FAILED) { 525 | s6 = peg$parseIdentifier(); 526 | if (s6 !== peg$FAILED) { 527 | if (input.charCodeAt(peg$currPos) === 58) { 528 | s7 = peg$c8; 529 | peg$currPos++; 530 | } else { 531 | s7 = peg$FAILED; 532 | if (peg$silentFails === 0) { peg$fail(peg$c9); } 533 | } 534 | if (s7 !== peg$FAILED) { 535 | s8 = peg$parseType(); 536 | if (s8 !== peg$FAILED) { 537 | if (input.charCodeAt(peg$currPos) === 8594) { 538 | s9 = peg$c10; 539 | peg$currPos++; 540 | } else { 541 | s9 = peg$FAILED; 542 | if (peg$silentFails === 0) { peg$fail(peg$c11); } 543 | } 544 | if (s9 !== peg$FAILED) { 545 | s10 = peg$parseApplication(); 546 | if (s10 !== peg$FAILED) { 547 | s11 = peg$parse_(); 548 | if (s11 !== peg$FAILED) { 549 | if (input.charCodeAt(peg$currPos) === 41) { 550 | s12 = peg$c2; 551 | peg$currPos++; 552 | } else { 553 | s12 = peg$FAILED; 554 | if (peg$silentFails === 0) { peg$fail(peg$c3); } 555 | } 556 | if (s12 === peg$FAILED) { 557 | s12 = null; 558 | } 559 | if (s12 !== peg$FAILED) { 560 | s13 = peg$parse_(); 561 | if (s13 !== peg$FAILED) { 562 | peg$savedPos = s0; 563 | s1 = peg$c12(s6, s8, s10); 564 | s0 = s1; 565 | } else { 566 | peg$currPos = s0; 567 | s0 = peg$FAILED; 568 | } 569 | } else { 570 | peg$currPos = s0; 571 | s0 = peg$FAILED; 572 | } 573 | } else { 574 | peg$currPos = s0; 575 | s0 = peg$FAILED; 576 | } 577 | } else { 578 | peg$currPos = s0; 579 | s0 = peg$FAILED; 580 | } 581 | } else { 582 | peg$currPos = s0; 583 | s0 = peg$FAILED; 584 | } 585 | } else { 586 | peg$currPos = s0; 587 | s0 = peg$FAILED; 588 | } 589 | } else { 590 | peg$currPos = s0; 591 | s0 = peg$FAILED; 592 | } 593 | } else { 594 | peg$currPos = s0; 595 | s0 = peg$FAILED; 596 | } 597 | } else { 598 | peg$currPos = s0; 599 | s0 = peg$FAILED; 600 | } 601 | } else { 602 | peg$currPos = s0; 603 | s0 = peg$FAILED; 604 | } 605 | } else { 606 | peg$currPos = s0; 607 | s0 = peg$FAILED; 608 | } 609 | } else { 610 | peg$currPos = s0; 611 | s0 = peg$FAILED; 612 | } 613 | } else { 614 | peg$currPos = s0; 615 | s0 = peg$FAILED; 616 | } 617 | 618 | return s0; 619 | } 620 | 621 | function peg$parseExpr() { 622 | var s0; 623 | 624 | s0 = peg$parseIfThen(); 625 | if (s0 === peg$FAILED) { 626 | s0 = peg$parseIsZeroCheck(); 627 | if (s0 === peg$FAILED) { 628 | s0 = peg$parseArithmeticOperation(); 629 | if (s0 === peg$FAILED) { 630 | s0 = peg$parseZero(); 631 | if (s0 === peg$FAILED) { 632 | s0 = peg$parseTrue(); 633 | if (s0 === peg$FAILED) { 634 | s0 = peg$parseFalse(); 635 | if (s0 === peg$FAILED) { 636 | s0 = peg$parseIdentifier(); 637 | if (s0 === peg$FAILED) { 638 | s0 = peg$parseParanExpression(); 639 | } 640 | } 641 | } 642 | } 643 | } 644 | } 645 | } 646 | 647 | return s0; 648 | } 649 | 650 | function peg$parseArithmeticOperation() { 651 | var s0, s1, s2; 652 | 653 | s0 = peg$currPos; 654 | s1 = peg$parseOperator(); 655 | if (s1 !== peg$FAILED) { 656 | s2 = peg$parseApplication(); 657 | if (s2 !== peg$FAILED) { 658 | peg$savedPos = s0; 659 | s1 = peg$c13(s1, s2); 660 | s0 = s1; 661 | } else { 662 | peg$currPos = s0; 663 | s0 = peg$FAILED; 664 | } 665 | } else { 666 | peg$currPos = s0; 667 | s0 = peg$FAILED; 668 | } 669 | 670 | return s0; 671 | } 672 | 673 | function peg$parseIsZeroCheck() { 674 | var s0, s1, s2; 675 | 676 | s0 = peg$currPos; 677 | s1 = peg$parseIsZero(); 678 | if (s1 !== peg$FAILED) { 679 | s2 = peg$parseApplication(); 680 | if (s2 !== peg$FAILED) { 681 | peg$savedPos = s0; 682 | s1 = peg$c14(s2); 683 | s0 = s1; 684 | } else { 685 | peg$currPos = s0; 686 | s0 = peg$FAILED; 687 | } 688 | } else { 689 | peg$currPos = s0; 690 | s0 = peg$FAILED; 691 | } 692 | 693 | return s0; 694 | } 695 | 696 | function peg$parseOperator() { 697 | var s0; 698 | 699 | s0 = peg$parseSucc(); 700 | if (s0 === peg$FAILED) { 701 | s0 = peg$parsePred(); 702 | } 703 | 704 | return s0; 705 | } 706 | 707 | function peg$parseIfThen() { 708 | var s0, s1, s2, s3, s4, s5, s6; 709 | 710 | s0 = peg$currPos; 711 | s1 = peg$parseIf(); 712 | if (s1 !== peg$FAILED) { 713 | s2 = peg$parseApplication(); 714 | if (s2 !== peg$FAILED) { 715 | s3 = peg$parseThen(); 716 | if (s3 !== peg$FAILED) { 717 | s4 = peg$parseApplication(); 718 | if (s4 !== peg$FAILED) { 719 | s5 = peg$parseElse(); 720 | if (s5 !== peg$FAILED) { 721 | s6 = peg$parseApplication(); 722 | if (s6 !== peg$FAILED) { 723 | peg$savedPos = s0; 724 | s1 = peg$c15(s2, s4, s6); 725 | s0 = s1; 726 | } else { 727 | peg$currPos = s0; 728 | s0 = peg$FAILED; 729 | } 730 | } else { 731 | peg$currPos = s0; 732 | s0 = peg$FAILED; 733 | } 734 | } else { 735 | peg$currPos = s0; 736 | s0 = peg$FAILED; 737 | } 738 | } else { 739 | peg$currPos = s0; 740 | s0 = peg$FAILED; 741 | } 742 | } else { 743 | peg$currPos = s0; 744 | s0 = peg$FAILED; 745 | } 746 | } else { 747 | peg$currPos = s0; 748 | s0 = peg$FAILED; 749 | } 750 | 751 | return s0; 752 | } 753 | 754 | function peg$parseType() { 755 | var s0; 756 | 757 | s0 = peg$parseNat(); 758 | if (s0 === peg$FAILED) { 759 | s0 = peg$parseBool(); 760 | } 761 | 762 | return s0; 763 | } 764 | 765 | function peg$parse_() { 766 | var s0, s1; 767 | 768 | s0 = []; 769 | if (peg$c16.test(input.charAt(peg$currPos))) { 770 | s1 = input.charAt(peg$currPos); 771 | peg$currPos++; 772 | } else { 773 | s1 = peg$FAILED; 774 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 775 | } 776 | while (s1 !== peg$FAILED) { 777 | s0.push(s1); 778 | if (peg$c16.test(input.charAt(peg$currPos))) { 779 | s1 = input.charAt(peg$currPos); 780 | peg$currPos++; 781 | } else { 782 | s1 = peg$FAILED; 783 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 784 | } 785 | } 786 | 787 | return s0; 788 | } 789 | 790 | function peg$parse__() { 791 | var s0, s1; 792 | 793 | s0 = []; 794 | if (peg$c16.test(input.charAt(peg$currPos))) { 795 | s1 = input.charAt(peg$currPos); 796 | peg$currPos++; 797 | } else { 798 | s1 = peg$FAILED; 799 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 800 | } 801 | if (s1 !== peg$FAILED) { 802 | while (s1 !== peg$FAILED) { 803 | s0.push(s1); 804 | if (peg$c16.test(input.charAt(peg$currPos))) { 805 | s1 = input.charAt(peg$currPos); 806 | peg$currPos++; 807 | } else { 808 | s1 = peg$FAILED; 809 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 810 | } 811 | } 812 | } else { 813 | s0 = peg$FAILED; 814 | } 815 | 816 | return s0; 817 | } 818 | 819 | function peg$parseIdentifier() { 820 | var s0, s1, s2, s3, s4; 821 | 822 | s0 = peg$currPos; 823 | s1 = peg$currPos; 824 | peg$silentFails++; 825 | s2 = peg$parseReservedWord(); 826 | peg$silentFails--; 827 | if (s2 === peg$FAILED) { 828 | s1 = void 0; 829 | } else { 830 | peg$currPos = s1; 831 | s1 = peg$FAILED; 832 | } 833 | if (s1 !== peg$FAILED) { 834 | s2 = peg$parse_(); 835 | if (s2 !== peg$FAILED) { 836 | s3 = []; 837 | if (peg$c18.test(input.charAt(peg$currPos))) { 838 | s4 = input.charAt(peg$currPos); 839 | peg$currPos++; 840 | } else { 841 | s4 = peg$FAILED; 842 | if (peg$silentFails === 0) { peg$fail(peg$c19); } 843 | } 844 | if (s4 !== peg$FAILED) { 845 | while (s4 !== peg$FAILED) { 846 | s3.push(s4); 847 | if (peg$c18.test(input.charAt(peg$currPos))) { 848 | s4 = input.charAt(peg$currPos); 849 | peg$currPos++; 850 | } else { 851 | s4 = peg$FAILED; 852 | if (peg$silentFails === 0) { peg$fail(peg$c19); } 853 | } 854 | } 855 | } else { 856 | s3 = peg$FAILED; 857 | } 858 | if (s3 !== peg$FAILED) { 859 | s4 = peg$parse_(); 860 | if (s4 !== peg$FAILED) { 861 | peg$savedPos = s0; 862 | s1 = peg$c20(s3); 863 | s0 = s1; 864 | } else { 865 | peg$currPos = s0; 866 | s0 = peg$FAILED; 867 | } 868 | } else { 869 | peg$currPos = s0; 870 | s0 = peg$FAILED; 871 | } 872 | } else { 873 | peg$currPos = s0; 874 | s0 = peg$FAILED; 875 | } 876 | } else { 877 | peg$currPos = s0; 878 | s0 = peg$FAILED; 879 | } 880 | 881 | return s0; 882 | } 883 | 884 | function peg$parseParanExpression() { 885 | var s0, s1, s2, s3, s4, s5, s6, s7; 886 | 887 | s0 = peg$currPos; 888 | s1 = peg$parse_(); 889 | if (s1 !== peg$FAILED) { 890 | if (input.charCodeAt(peg$currPos) === 40) { 891 | s2 = peg$c0; 892 | peg$currPos++; 893 | } else { 894 | s2 = peg$FAILED; 895 | if (peg$silentFails === 0) { peg$fail(peg$c1); } 896 | } 897 | if (s2 !== peg$FAILED) { 898 | s3 = peg$parse_(); 899 | if (s3 !== peg$FAILED) { 900 | s4 = peg$parseExpr(); 901 | if (s4 !== peg$FAILED) { 902 | s5 = peg$parse_(); 903 | if (s5 !== peg$FAILED) { 904 | if (input.charCodeAt(peg$currPos) === 41) { 905 | s6 = peg$c2; 906 | peg$currPos++; 907 | } else { 908 | s6 = peg$FAILED; 909 | if (peg$silentFails === 0) { peg$fail(peg$c3); } 910 | } 911 | if (s6 !== peg$FAILED) { 912 | s7 = peg$parse_(); 913 | if (s7 !== peg$FAILED) { 914 | peg$savedPos = s0; 915 | s1 = peg$c21(s4); 916 | s0 = s1; 917 | } else { 918 | peg$currPos = s0; 919 | s0 = peg$FAILED; 920 | } 921 | } else { 922 | peg$currPos = s0; 923 | s0 = peg$FAILED; 924 | } 925 | } else { 926 | peg$currPos = s0; 927 | s0 = peg$FAILED; 928 | } 929 | } else { 930 | peg$currPos = s0; 931 | s0 = peg$FAILED; 932 | } 933 | } else { 934 | peg$currPos = s0; 935 | s0 = peg$FAILED; 936 | } 937 | } else { 938 | peg$currPos = s0; 939 | s0 = peg$FAILED; 940 | } 941 | } else { 942 | peg$currPos = s0; 943 | s0 = peg$FAILED; 944 | } 945 | 946 | return s0; 947 | } 948 | 949 | function peg$parseTrue() { 950 | var s0, s1, s2, s3; 951 | 952 | s0 = peg$currPos; 953 | s1 = peg$parse_(); 954 | if (s1 !== peg$FAILED) { 955 | if (input.substr(peg$currPos, 4) === peg$c22) { 956 | s2 = peg$c22; 957 | peg$currPos += 4; 958 | } else { 959 | s2 = peg$FAILED; 960 | if (peg$silentFails === 0) { peg$fail(peg$c23); } 961 | } 962 | if (s2 !== peg$FAILED) { 963 | s3 = peg$parse_(); 964 | if (s3 !== peg$FAILED) { 965 | peg$savedPos = s0; 966 | s1 = peg$c24(); 967 | s0 = s1; 968 | } else { 969 | peg$currPos = s0; 970 | s0 = peg$FAILED; 971 | } 972 | } else { 973 | peg$currPos = s0; 974 | s0 = peg$FAILED; 975 | } 976 | } else { 977 | peg$currPos = s0; 978 | s0 = peg$FAILED; 979 | } 980 | 981 | return s0; 982 | } 983 | 984 | function peg$parseFalse() { 985 | var s0, s1, s2, s3; 986 | 987 | s0 = peg$currPos; 988 | s1 = peg$parse_(); 989 | if (s1 !== peg$FAILED) { 990 | if (input.substr(peg$currPos, 5) === peg$c25) { 991 | s2 = peg$c25; 992 | peg$currPos += 5; 993 | } else { 994 | s2 = peg$FAILED; 995 | if (peg$silentFails === 0) { peg$fail(peg$c26); } 996 | } 997 | if (s2 !== peg$FAILED) { 998 | s3 = peg$parse_(); 999 | if (s3 !== peg$FAILED) { 1000 | peg$savedPos = s0; 1001 | s1 = peg$c27(); 1002 | s0 = s1; 1003 | } else { 1004 | peg$currPos = s0; 1005 | s0 = peg$FAILED; 1006 | } 1007 | } else { 1008 | peg$currPos = s0; 1009 | s0 = peg$FAILED; 1010 | } 1011 | } else { 1012 | peg$currPos = s0; 1013 | s0 = peg$FAILED; 1014 | } 1015 | 1016 | return s0; 1017 | } 1018 | 1019 | function peg$parseZero() { 1020 | var s0, s1, s2, s3; 1021 | 1022 | s0 = peg$currPos; 1023 | s1 = peg$parse_(); 1024 | if (s1 !== peg$FAILED) { 1025 | if (input.charCodeAt(peg$currPos) === 48) { 1026 | s2 = peg$c28; 1027 | peg$currPos++; 1028 | } else { 1029 | s2 = peg$FAILED; 1030 | if (peg$silentFails === 0) { peg$fail(peg$c29); } 1031 | } 1032 | if (s2 !== peg$FAILED) { 1033 | s3 = peg$parse_(); 1034 | if (s3 !== peg$FAILED) { 1035 | peg$savedPos = s0; 1036 | s1 = peg$c30(); 1037 | s0 = s1; 1038 | } else { 1039 | peg$currPos = s0; 1040 | s0 = peg$FAILED; 1041 | } 1042 | } else { 1043 | peg$currPos = s0; 1044 | s0 = peg$FAILED; 1045 | } 1046 | } else { 1047 | peg$currPos = s0; 1048 | s0 = peg$FAILED; 1049 | } 1050 | 1051 | return s0; 1052 | } 1053 | 1054 | function peg$parseReservedWord() { 1055 | var s0; 1056 | 1057 | s0 = peg$parseIf(); 1058 | if (s0 === peg$FAILED) { 1059 | s0 = peg$parseThen(); 1060 | if (s0 === peg$FAILED) { 1061 | s0 = peg$parseElse(); 1062 | if (s0 === peg$FAILED) { 1063 | s0 = peg$parsePred(); 1064 | if (s0 === peg$FAILED) { 1065 | s0 = peg$parseSucc(); 1066 | if (s0 === peg$FAILED) { 1067 | s0 = peg$parseNat(); 1068 | if (s0 === peg$FAILED) { 1069 | s0 = peg$parseBool(); 1070 | if (s0 === peg$FAILED) { 1071 | s0 = peg$parseIsZero(); 1072 | if (s0 === peg$FAILED) { 1073 | s0 = peg$parseFalse(); 1074 | } 1075 | } 1076 | } 1077 | } 1078 | } 1079 | } 1080 | } 1081 | } 1082 | 1083 | return s0; 1084 | } 1085 | 1086 | function peg$parseIf() { 1087 | var s0, s1, s2, s3; 1088 | 1089 | s0 = peg$currPos; 1090 | s1 = peg$parse_(); 1091 | if (s1 !== peg$FAILED) { 1092 | if (input.substr(peg$currPos, 2) === peg$c31) { 1093 | s2 = peg$c31; 1094 | peg$currPos += 2; 1095 | } else { 1096 | s2 = peg$FAILED; 1097 | if (peg$silentFails === 0) { peg$fail(peg$c32); } 1098 | } 1099 | if (s2 !== peg$FAILED) { 1100 | s3 = peg$parse_(); 1101 | if (s3 !== peg$FAILED) { 1102 | s1 = [s1, s2, s3]; 1103 | s0 = s1; 1104 | } else { 1105 | peg$currPos = s0; 1106 | s0 = peg$FAILED; 1107 | } 1108 | } else { 1109 | peg$currPos = s0; 1110 | s0 = peg$FAILED; 1111 | } 1112 | } else { 1113 | peg$currPos = s0; 1114 | s0 = peg$FAILED; 1115 | } 1116 | 1117 | return s0; 1118 | } 1119 | 1120 | function peg$parseThen() { 1121 | var s0, s1, s2, s3; 1122 | 1123 | s0 = peg$currPos; 1124 | s1 = peg$parse_(); 1125 | if (s1 !== peg$FAILED) { 1126 | if (input.substr(peg$currPos, 4) === peg$c33) { 1127 | s2 = peg$c33; 1128 | peg$currPos += 4; 1129 | } else { 1130 | s2 = peg$FAILED; 1131 | if (peg$silentFails === 0) { peg$fail(peg$c34); } 1132 | } 1133 | if (s2 !== peg$FAILED) { 1134 | s3 = peg$parse_(); 1135 | if (s3 !== peg$FAILED) { 1136 | s1 = [s1, s2, s3]; 1137 | s0 = s1; 1138 | } else { 1139 | peg$currPos = s0; 1140 | s0 = peg$FAILED; 1141 | } 1142 | } else { 1143 | peg$currPos = s0; 1144 | s0 = peg$FAILED; 1145 | } 1146 | } else { 1147 | peg$currPos = s0; 1148 | s0 = peg$FAILED; 1149 | } 1150 | 1151 | return s0; 1152 | } 1153 | 1154 | function peg$parseElse() { 1155 | var s0, s1, s2, s3; 1156 | 1157 | s0 = peg$currPos; 1158 | s1 = peg$parse_(); 1159 | if (s1 !== peg$FAILED) { 1160 | if (input.substr(peg$currPos, 4) === peg$c35) { 1161 | s2 = peg$c35; 1162 | peg$currPos += 4; 1163 | } else { 1164 | s2 = peg$FAILED; 1165 | if (peg$silentFails === 0) { peg$fail(peg$c36); } 1166 | } 1167 | if (s2 !== peg$FAILED) { 1168 | s3 = peg$parse_(); 1169 | if (s3 !== peg$FAILED) { 1170 | s1 = [s1, s2, s3]; 1171 | s0 = s1; 1172 | } else { 1173 | peg$currPos = s0; 1174 | s0 = peg$FAILED; 1175 | } 1176 | } else { 1177 | peg$currPos = s0; 1178 | s0 = peg$FAILED; 1179 | } 1180 | } else { 1181 | peg$currPos = s0; 1182 | s0 = peg$FAILED; 1183 | } 1184 | 1185 | return s0; 1186 | } 1187 | 1188 | function peg$parsePred() { 1189 | var s0, s1, s2, s3; 1190 | 1191 | s0 = peg$currPos; 1192 | s1 = peg$parse_(); 1193 | if (s1 !== peg$FAILED) { 1194 | if (input.substr(peg$currPos, 4) === peg$c37) { 1195 | s2 = peg$c37; 1196 | peg$currPos += 4; 1197 | } else { 1198 | s2 = peg$FAILED; 1199 | if (peg$silentFails === 0) { peg$fail(peg$c38); } 1200 | } 1201 | if (s2 !== peg$FAILED) { 1202 | s3 = peg$parse_(); 1203 | if (s3 !== peg$FAILED) { 1204 | peg$savedPos = s0; 1205 | s1 = peg$c39(); 1206 | s0 = s1; 1207 | } else { 1208 | peg$currPos = s0; 1209 | s0 = peg$FAILED; 1210 | } 1211 | } else { 1212 | peg$currPos = s0; 1213 | s0 = peg$FAILED; 1214 | } 1215 | } else { 1216 | peg$currPos = s0; 1217 | s0 = peg$FAILED; 1218 | } 1219 | 1220 | return s0; 1221 | } 1222 | 1223 | function peg$parseSucc() { 1224 | var s0, s1, s2, s3; 1225 | 1226 | s0 = peg$currPos; 1227 | s1 = peg$parse_(); 1228 | if (s1 !== peg$FAILED) { 1229 | if (input.substr(peg$currPos, 4) === peg$c40) { 1230 | s2 = peg$c40; 1231 | peg$currPos += 4; 1232 | } else { 1233 | s2 = peg$FAILED; 1234 | if (peg$silentFails === 0) { peg$fail(peg$c41); } 1235 | } 1236 | if (s2 !== peg$FAILED) { 1237 | s3 = peg$parse_(); 1238 | if (s3 !== peg$FAILED) { 1239 | peg$savedPos = s0; 1240 | s1 = peg$c42(); 1241 | s0 = s1; 1242 | } else { 1243 | peg$currPos = s0; 1244 | s0 = peg$FAILED; 1245 | } 1246 | } else { 1247 | peg$currPos = s0; 1248 | s0 = peg$FAILED; 1249 | } 1250 | } else { 1251 | peg$currPos = s0; 1252 | s0 = peg$FAILED; 1253 | } 1254 | 1255 | return s0; 1256 | } 1257 | 1258 | function peg$parseNat() { 1259 | var s0, s1, s2, s3; 1260 | 1261 | s0 = peg$currPos; 1262 | s1 = peg$parse_(); 1263 | if (s1 !== peg$FAILED) { 1264 | if (input.substr(peg$currPos, 3) === peg$c43) { 1265 | s2 = peg$c43; 1266 | peg$currPos += 3; 1267 | } else { 1268 | s2 = peg$FAILED; 1269 | if (peg$silentFails === 0) { peg$fail(peg$c44); } 1270 | } 1271 | if (s2 !== peg$FAILED) { 1272 | s3 = peg$parse_(); 1273 | if (s3 !== peg$FAILED) { 1274 | peg$savedPos = s0; 1275 | s1 = peg$c45(); 1276 | s0 = s1; 1277 | } else { 1278 | peg$currPos = s0; 1279 | s0 = peg$FAILED; 1280 | } 1281 | } else { 1282 | peg$currPos = s0; 1283 | s0 = peg$FAILED; 1284 | } 1285 | } else { 1286 | peg$currPos = s0; 1287 | s0 = peg$FAILED; 1288 | } 1289 | 1290 | return s0; 1291 | } 1292 | 1293 | function peg$parseBool() { 1294 | var s0, s1, s2, s3; 1295 | 1296 | s0 = peg$currPos; 1297 | s1 = peg$parse_(); 1298 | if (s1 !== peg$FAILED) { 1299 | if (input.substr(peg$currPos, 4) === peg$c46) { 1300 | s2 = peg$c46; 1301 | peg$currPos += 4; 1302 | } else { 1303 | s2 = peg$FAILED; 1304 | if (peg$silentFails === 0) { peg$fail(peg$c47); } 1305 | } 1306 | if (s2 !== peg$FAILED) { 1307 | s3 = peg$parse_(); 1308 | if (s3 !== peg$FAILED) { 1309 | peg$savedPos = s0; 1310 | s1 = peg$c48(); 1311 | s0 = s1; 1312 | } else { 1313 | peg$currPos = s0; 1314 | s0 = peg$FAILED; 1315 | } 1316 | } else { 1317 | peg$currPos = s0; 1318 | s0 = peg$FAILED; 1319 | } 1320 | } else { 1321 | peg$currPos = s0; 1322 | s0 = peg$FAILED; 1323 | } 1324 | 1325 | return s0; 1326 | } 1327 | 1328 | function peg$parseIsZero() { 1329 | var s0, s1, s2, s3; 1330 | 1331 | s0 = peg$currPos; 1332 | s1 = peg$parse_(); 1333 | if (s1 !== peg$FAILED) { 1334 | if (input.substr(peg$currPos, 6) === peg$c49) { 1335 | s2 = peg$c49; 1336 | peg$currPos += 6; 1337 | } else { 1338 | s2 = peg$FAILED; 1339 | if (peg$silentFails === 0) { peg$fail(peg$c50); } 1340 | } 1341 | if (s2 !== peg$FAILED) { 1342 | s3 = peg$parse_(); 1343 | if (s3 !== peg$FAILED) { 1344 | peg$savedPos = s0; 1345 | s1 = peg$c51(); 1346 | s0 = s1; 1347 | } else { 1348 | peg$currPos = s0; 1349 | s0 = peg$FAILED; 1350 | } 1351 | } else { 1352 | peg$currPos = s0; 1353 | s0 = peg$FAILED; 1354 | } 1355 | } else { 1356 | peg$currPos = s0; 1357 | s0 = peg$FAILED; 1358 | } 1359 | 1360 | return s0; 1361 | } 1362 | 1363 | peg$result = peg$startRuleFunction(); 1364 | 1365 | if (peg$result !== peg$FAILED && peg$currPos === input.length) { 1366 | return peg$result; 1367 | } else { 1368 | if (peg$result !== peg$FAILED && peg$currPos < input.length) { 1369 | peg$fail(peg$endExpectation()); 1370 | } 1371 | 1372 | throw peg$buildStructuredError( 1373 | peg$maxFailExpected, 1374 | peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, 1375 | peg$maxFailPos < input.length 1376 | ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) 1377 | : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) 1378 | ); 1379 | } 1380 | } 1381 | 1382 | module.exports = { 1383 | SyntaxError: peg$SyntaxError, 1384 | parse: peg$parse 1385 | }; 1386 | --------------------------------------------------------------------------------