diff --git a/desugar.js b/desugar.js index cf79a35..acbd464 100644 --- a/desugar.js +++ b/desugar.js @@ -42,6 +42,15 @@ function desugarLet(stx) { return new typ.LetExp(values, desugar(stx.body)); } +function sugarTypeApp(stx) { + var type; + var expression; + type = stx.p; + expression = desugar(stx.func.p); + return new typ.TypeApp(expression, type); +} + + function desugar(stx) { switch (stx.exprType) { case "If": @@ -55,6 +64,15 @@ function desugar(stx) { case "Name": return stx; case "Application": + if ((stx.func.func != undefined ) && + (stx.func.func.ident === "::")) { + /* It's a type application probably (will be verified later) + * In this case we actually *add* syntax here to differentiate type applications + * from normal applications + */ + return sugarTypeApp(stx); + } + if ((stx.func.ident === "-" || stx.func.ident === "+") && stx.p) { diff --git a/example.jl b/example.jl index 3a04409..5c99288 100644 --- a/example.jl +++ b/example.jl @@ -1,11 +1,8 @@ defop 2 Left (a ++#$ b) (a - b) -def (f a b) - (a ++ b) - -(qat :: (Int -> Int -> Int -> Int)) +(qat :: A) def qat (lambda a b c -> (a + b)) def (add a b) diff --git a/parse.js b/parse.js index c1f299e..4f5e520 100755 --- a/parse.js +++ b/parse.js @@ -458,7 +458,6 @@ function parseLambda(tokens) { tokens, charnum, linenum); - console.log(tokens); if (fst(tokens)[1] !== "->") { throw error.JSyntaxError(fst(tokens)[3], fst(tokens)[2], diff --git a/pprint.js b/pprint.js index 8656512..305ea8c 100644 --- a/pprint.js +++ b/pprint.js @@ -30,9 +30,6 @@ function pprint(expr) { if (expr.exprType === "Name") { return expr.val; } - else if (expr.exprType === "TypeOperator") { - return expr.val; - } else if (expr.exprType === "Bool") { if (expr.val) { return "True"; @@ -77,6 +74,15 @@ function pprint(expr) { return pprint(v); }).join(" ; ") + "} in " + pprint(expr.body); } + else if (expr.exprType === "TypeOperator") { + return "("+expr.val+")"; + } + else if (expr.exprType === "TypeVar") { + return "("+expr.name+")"; + } + else if (expr.exprType === "TypeApplication") { + return "( " + pprint(expr.expression) + " :: " + pprint(expr.type) + " )"; + } } module.exports = {pprint : pprint}; diff --git a/representation.js b/representation.js index efb34f9..6b2732a 100644 --- a/representation.js +++ b/representation.js @@ -176,6 +176,7 @@ function If(condition, thenexp, elseexp) { function TypeVar(name) { this.exprtype = "TypeVar"; this.name = name; + this.exprType = "TypeVar"; return this; } @@ -188,20 +189,29 @@ function TypeOp(name) { return this; } +function isTypeExpr(expr) { + if (!expr.exprType) { + throw errors.JInternalError(expr); + } + return ((expr.exprType === "TypeOperator") || + (expr.exprType === "TypeVar") || + (expr.exprType === "TypeApplication")); +} + TypeOp.prototype = TypeExpression; function TypeApp(expression, type) { - if (expression.prototype.isTypeExpr) { + if (isTypeExpr(expression)) { throw errors.JInternalError( "Left-hand-side of type application must not be in the type language" ); } - if (!type.prototype.isTypeExpr) { + if (!isTypeExpr(type)) { throw errors.JInternalError( "Right-hand-side of type application must be a type expression" ); } - this.expr = expression; + this.expression = expression; this.type = type; this.exprType = "TypeApplication"; return this;