From 12b3eb58b212ad6ee73f5cd142e1c8ea0168b5d1 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Fri, 9 May 2014 14:22:42 -0400 Subject: [PATCH 1/3] fix brace style of conditionals --- parse.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/parse.js b/parse.js index 6415f2f..eaefa35 100755 --- a/parse.js +++ b/parse.js @@ -77,26 +77,33 @@ function parseMany(parse, exprType, valid, tokens, charnum, linenum) { //make sure there are at least 2 tokens to parse if (tokens.length > 1 && fst(tokens) && valid(fst(tokens))) { while (valid(snd(tokens))) { - if (!(valid(fst(tokens)))) + if (!(valid(fst(tokens)))) { break; + } results.push(parse(tokens)); - if (!exprType(fst(results).exprType)) + if (!exprType(fst(results).exprType)) { break; - if (fst(tokens)) + } + if (fst(tokens)) { current = fst(tokens)[0]; - else + } + else { throw error.JSyntaxError(charnum, linenum, "Unexpected end of source"); - if (tokens.length <= 1) + } + if (tokens.length <= 1) { break; + } } } //do the same validity check as before and in the loop - if (!fst(tokens)) + if (!fst(tokens)) { throw error.JSyntaxError(linenum, charnum, "unexpected end of source"); - if (valid(fst(tokens))) + } + if (valid(fst(tokens))) { results.push(parse(tokens)); + } return results; } -- 2.30.2 From dd58dffc70281a79c5cecd86b4d0797b766a4183 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 11 May 2014 02:12:56 -0400 Subject: [PATCH 2/3] experimental support for full type application syntax, basic error checking, still needs syntax for user created types --- desugar.js | 10 +++++++-- example.jl | 2 +- parse.js | 8 +++++--- representation.js | 52 ++++++++++++++++++++++++++++++++++++++++------- tokenize.js | 10 +++++---- tools.js | 2 +- 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/desugar.js b/desugar.js index 16fadad..40a242a 100644 --- a/desugar.js +++ b/desugar.js @@ -5,6 +5,7 @@ */ var typ = require("./representation.js"); +var errors = require("./errors.js"); var _ = require("underscore"); // Lists get desugared to nested function calls @@ -54,8 +55,9 @@ function sugarTypeApp(stx) { function desugar(stx) { switch (stx.exprType) { case "If": - if (stx.elseexp) + if (stx.elseexp) { return new typ.If(desugar(stx.condition), desugar(stx.thenexp), desugar(stx.elseexp)); + } return new typ.If(desugar(stx.condition), desugar(stx.thenexp)); case "FunctionDefinition": return desugarDefFunc(stx); @@ -70,6 +72,9 @@ function desugar(stx) { * In this case we actually *add* syntax here to differentiate type applications * from normal applications */ + if (!typ.isTypeExpr(stx.p)) { + throw errors.JInternalError("Type application error"); + } return sugarTypeApp(stx); } @@ -78,8 +83,9 @@ function desugar(stx) { stx.p) { return new typ.UnaryOp(desugar(stx.func), desugar(stx.p)); } - if (stx.p) + if (stx.p) { return new typ.App(desugar(stx.func), desugar(stx.p)); + } return new typ.App(stx.func); case "Function": return curryFunc(stx.p, stx.body); diff --git a/example.jl b/example.jl index 5c99288..bc75ac7 100644 --- a/example.jl +++ b/example.jl @@ -2,7 +2,7 @@ defop 2 Left (a ++#$ b) (a - b) -(qat :: A) +(qat :: (A -> B)) def qat (lambda a b c -> (a + b)) def (add a b) diff --git a/parse.js b/parse.js index eaefa35..b7bbda0 100755 --- a/parse.js +++ b/parse.js @@ -143,7 +143,9 @@ function parseList(tokens) { xs = []; } else { - xs = parseBetween(function (x) { return true; }, "comma", tokens, fst(tokens)[3], fst(tokens)[2]); + xs = parseBetween(function (x) { + return true; + }, "comma", tokens, fst(tokens)[3], fst(tokens)[2]); } if (!fst(tokens) || fst(tokens)[0] !== "right_square") { throw error.JSyntaxError(fst(tokens)[3], @@ -158,7 +160,7 @@ function parseList(tokens) { function parseDefFunction(tokens) { var fname = parse(tokens); var parameters; - if (fname.exprType != "Name") { + if (fname.exprType !== "Name") { throw error.JSyntaxError(fst(tokens)[3], fst(tokens)[2], "Expected an identifier in function definition"); @@ -647,4 +649,4 @@ module.exports = { parse : function(str) { tokenize : tokenizer.tokenize }; var istr = fs.readFileSync('/dev/stdin').toString(); -parseFull(tokenizer.tokenize(istr)).map(pprint.pprint); +console.log(parseFull(tokenizer.tokenize(istr)).map(pprint.pprint)); diff --git a/representation.js b/representation.js index 3df95fa..1563270 100644 --- a/representation.js +++ b/representation.js @@ -25,7 +25,42 @@ var TypeExpression = { isTypeExpr : true }; -var isTypeExpr = _.property("isTypeExpr"); +function isTypeExpr(x) { + return x.isTypeExpr !== undefined; +} + +function isIrregularTypeOp(x) { + return (x === "->"); +} + +function isTypeExprRec(stx, isTypeOp) { + if (isTypeExpr(stx)) { + return true; + } + if (stx.exprType === "Application") { + /* it might be a type application so recursively check it */ + if (stx.p !== undefined) { + return (isTypeExprRec(stx.p) && + isTypeExprRec(stx.func)); + } + else { + return isTypeExprRec(stx.func); + } + } + if (stx.exprType === "Name") { + /* Check if it might be a type operator that is not capitalized */ + return isIrregularTypeOp(stx.ident); + } + return false; +} + +function App(func, p) { + this.func = func; + this.exprType = "Application"; + if (p) + this.p = p; + return this; +} function Closure(bound_vars, free_vars, body, env) { this.bound_vars = bound_vars; @@ -41,7 +76,7 @@ function LetExp(pairs, body) { return (x.exprType === "Definition" || x.exprType === "FunctionDefinition"); })) { - throw Errors.JInternalError( + throw errors.JInternalError( "let can only be used to bind things to names or functions" ); } @@ -189,6 +224,8 @@ function TypeOp(name) { return this; } +TypeOp.prototype = TypeExpression; + function isTypeExpr(expr) { if (!expr.exprType) { throw errors.JInternalError(expr); @@ -198,15 +235,13 @@ function isTypeExpr(expr) { (expr.exprType === "TypeApplication")); } -TypeOp.prototype = TypeExpression; - function TypeApp(expression, type) { - if (isTypeExpr(expression)) { + if (isTypeExprRec(expression)) { throw errors.JInternalError( "Left-hand-side of type application must not be in the type language" ); } - if (!isTypeExpr(type)) { + if (!isTypeExprRec(type)) { throw errors.JInternalError( "Right-hand-side of type application must be a type expression" ); @@ -242,6 +277,8 @@ function makeGensym() { var gensym = makeGensym(); +//console.log(isTypeExpr(new Name("T"))); + OPInfo = {"+" : [3, "Left"], "-" : [3, "Left"], "*" : [4, "Left"], @@ -288,5 +325,6 @@ module.exports = TypeVar : TypeVar, TypeOp : TypeOp, TypeApp: TypeApp, - Closure : Closure + Closure : Closure, + isTypeExpr : isTypeExprRec }; diff --git a/tokenize.js b/tokenize.js index a4f37d1..3662933 100755 --- a/tokenize.js +++ b/tokenize.js @@ -400,11 +400,13 @@ function tokenizeFull(input) { var matchop; var initialPass = tokenizeHelp(input, _.constant(false), true).reverse(); for (var i = 0; i < initialPass.length; i++) { - if (initialPass.slice(i, i+8).map(_.first).every(checkPattern)) { - rep.OPInfo[initialPass[i+5][1]] = [parseInt(initialPass[i+1][1], 10), - initialPass[i+2][1]]; + if (initialPass.slice(i, i+8). + map(_.first). + every(checkPattern)) { + rep.OPInfo[initialPass[i+5][1]] = + [parseInt(initialPass[i+1][1], 10), + initialPass[i+2][1]]; } - } operators = Object.keys(rep.OPInfo); matchop = $.opMatch(operators); diff --git a/tools.js b/tools.js index b4d387f..e8a4bf5 100644 --- a/tools.js +++ b/tools.js @@ -5,7 +5,7 @@ function empty(xs) { } function not(x) { - return !x; + return !x; } function min(a, b) { -- 2.30.2 From 17dff62f1ed1652cad0ae5ff3565288e3fc0c80d Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 11 May 2014 02:25:23 -0400 Subject: [PATCH 3/3] fixed annoyance with exception handling, will have to be more robust in the future though --- parse.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/parse.js b/parse.js index b7bbda0..297b6b0 100755 --- a/parse.js +++ b/parse.js @@ -638,7 +638,12 @@ function parseFull(tokenized) { } return ast; } catch (e) { - e.stxerror(); + if (e.stxerror !== undefined) { + e.stxerror(); + } + else { + console.log(e.errormessage); + } process.exit(1); } } -- 2.30.2