From 49059be2feef7210bd078205df784de51902ae3c Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 18 May 2014 17:54:01 -0400 Subject: [PATCH 1/3] preliminary support for full data type definition syntax, misc improvements on error reporting (hopefully) --- parse.js | 38 +++++++++++++++++++++++++++++++++----- representation.js | 3 ++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/parse.js b/parse.js index 84c1959..f7337ef 100755 --- a/parse.js +++ b/parse.js @@ -207,7 +207,7 @@ function parseDefFunction(tokens, linenum, charnum) { fst(tokens)[2], fst(tokens)[3]); } - if ((fst(tokens)[0]) !== "right_paren") { + if (!tokens || (fst(tokens)[0]) !== "right_paren") { throw error.JSyntaxError(fst(tokens)[3], fst(tokens)[2], "Formal parameters must be followed by )"); @@ -353,6 +353,34 @@ function parseLetItem(tokens) { } } +function parseDataType(tokens, linenum, charnum) { + var typeName = parse(tokens, linenum, charnum); + var typeParams; + var typeBody; + + if (typeName.exprType !== "TypeOperator") { + throw error.JSyntaxError(typeName.linenum, + typeName.charnum, + "Expected a type operator in data type definition"); + } + parameters = parseMany(parse, + validName, + validFormPar, + tokens, + charnum, + linenum); + if (!tokens || (fst(tokens)[0]) !== "right_paren") { + throw error.JSyntaxError(fst(tokens)[3], + fst(tokens)[2], + "Data type parameters must be followed by )"); + } + tokens.pop(); + typeBody = parse(tokens); + return addSrcPos(new typ.DataType, tokens, typeBody.linenum, typeBody.charnum); +} + + + function parseDefType(tokens, linenum, charnum) { var result; var rhs; @@ -464,7 +492,7 @@ function parseDef(tokens, linenum, charnum) { charnum, "A definition cannot be the value of a binding"); } - result = addSrcPos(new typ.Def(identifier, bound), tokens, linenum, charnum); + result = addSrcPos(new typ.Def(identifier, bound), tokens, bound.linenum, bound.charnum); return result; } } @@ -562,7 +590,7 @@ function parseIf(tokens) { } else { var elseC = parse(tokens); - result = addSrcPos(new typ.If(ifC, thenC, elseC), tokens, linenum, charnum); + result = addSrcPos(new typ.If(ifC, thenC, elseC), tokens, elseC.linenum, elseC.charnum); return result; } } @@ -599,7 +627,7 @@ function parseLambda(tokens) { } tokens.pop(); var body = parse(tokens); - result = addSrcPos(new typ.FuncT(parameters, body), tokens, linenum, charnum); + result = addSrcPos(new typ.FuncT(parameters, body), tokens, body.linenum, body.charnum); return result; } @@ -687,7 +715,7 @@ function parseInfix(tokens, minPrec, lhs, linenum, charnum) { tokens.pop(); /*remove the operator token*/ var rhs = parseInfix(tokens, nextMinPrec); - lhs = addSrcPos(typ.makeApp(op, [lhs, rhs]), tokens, linenum, charnum); + lhs = addSrcPos(typ.makeApp(op, [lhs, rhs]), tokens, rhs.linenum, rhs.charnum); } return lhs; } diff --git a/representation.js b/representation.js index bea8317..ea87fec 100644 --- a/representation.js +++ b/representation.js @@ -410,5 +410,6 @@ module.exports = TypeApp: TypeApp, Closure : Closure, isTypeExpr : isTypeExprRec, - DefType : DefType + DefType : DefType, + DataType : DataType }; -- 2.30.2 From 71640b2c48c4faca282e6c40b8bcc9675cf1d128 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 18 May 2014 18:01:02 -0400 Subject: [PATCH 2/3] fix typo and add test case for data type defs --- example.jl | 3 +++ parse.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/example.jl b/example.jl index bc9ccae..32fe00a 100644 --- a/example.jl +++ b/example.jl @@ -3,6 +3,9 @@ defop 2 Left (a ++ b) deftype Foo (A -> B) +deftype (Foo a b) + (a -> b) + (qat :: A -> b) def tdeftype (lambda a b c -> (a + b)) diff --git a/parse.js b/parse.js index f7337ef..e993f36 100755 --- a/parse.js +++ b/parse.js @@ -357,6 +357,7 @@ function parseDataType(tokens, linenum, charnum) { var typeName = parse(tokens, linenum, charnum); var typeParams; var typeBody; + var result; if (typeName.exprType !== "TypeOperator") { throw error.JSyntaxError(typeName.linenum, @@ -376,7 +377,9 @@ function parseDataType(tokens, linenum, charnum) { } tokens.pop(); typeBody = parse(tokens); - return addSrcPos(new typ.DataType, tokens, typeBody.linenum, typeBody.charnum); + result = addSrcPos(new typ.DataType(parameters, typeBody), tokens, typeBody.linenum, typeBody.charnum); + + return result; } -- 2.30.2 From f33ee5ae70611a8c1e0020d8ea51bc571e9ef273 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 18 May 2014 18:14:00 -0400 Subject: [PATCH 3/3] pretty print debugging for data type defs, fixed another mistake --- parse.js | 2 +- pprint.js | 7 +++++++ representation.js | 10 +++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/parse.js b/parse.js index e993f36..780f9d7 100755 --- a/parse.js +++ b/parse.js @@ -377,7 +377,7 @@ function parseDataType(tokens, linenum, charnum) { } tokens.pop(); typeBody = parse(tokens); - result = addSrcPos(new typ.DataType(parameters, typeBody), tokens, typeBody.linenum, typeBody.charnum); + result = addSrcPos(new typ.DataType(typeName, parameters, typeBody), tokens, typeBody.linenum, typeBody.charnum); return result; } diff --git a/pprint.js b/pprint.js index da57019..6986b0c 100644 --- a/pprint.js +++ b/pprint.js @@ -30,6 +30,10 @@ function pprintDefType(stx) { return pprint(stx.lhs) + " = " + pprint(stx.rhs); } +function pprintTypeFunc(stx) { + return "(" + stx.name.name + " " + stx.params.map(pprint).join(" ") + ") = " + pprint(stx.type); +} + function pprint(expr) { if (expr.exprType === "Name") { return expr.val; @@ -63,6 +67,9 @@ function pprint(expr) { else if (expr.exprType === "TypeDefinition") { return pprintDefType(expr); } + else if (expr.exprType === "TypeFuncDefinition") { + return pprintTypeFunc(expr); + } else if (expr.exprType === "If") { return pprintIf(expr); } diff --git a/representation.js b/representation.js index ea87fec..2b83669 100644 --- a/representation.js +++ b/representation.js @@ -319,10 +319,17 @@ function checkName(exp) { } } -function DataType(params, type) { +function DataType(name, params, type) { /* Params is a list of type variables * type is a type expression */ + if (name.exprType !== "TypeOperator") { + throw errors.JSyntaxError( + name.linenum, + name.charnum, + "First element in a data type definition must be its name " + + "which is a type operator"); + } _.each(params, checkName); if (!isTypeExprRec(type)) { throw errors.JSyntaxError( @@ -330,6 +337,7 @@ function DataType(params, type) { type.charnum, "Body of a type definition must be a valid type expression"); } + this.name = name; this.params = params; this.type = type; this.exprType = "TypeFuncDefinition"; -- 2.30.2