From 3b129e3802dadd348c0646641c095f2faaa1c076 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 16:07:09 -0400 Subject: [PATCH 1/7] fix silly mistake from when I must have been drunk or tired --- tokenize.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tokenize.js b/tokenize.js index d04c61d..7775a15 100755 --- a/tokenize.js +++ b/tokenize.js @@ -13,10 +13,7 @@ function isDigit(c) { if (isNaN(code)) { return false; } - return (46 < code && - code < 58 || - code < 58 && - code > 46); + return (47 < code && code < 58); } function isWhitespace(c) { -- 2.30.2 From 914598e3e98497a6c2cfcb31b407d9c0374421e6 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 16:08:01 -0400 Subject: [PATCH 2/7] start moving operator definitions to prelude.jl --- prelude.jl | 14 ++++++++++++++ representation.js | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/prelude.jl b/prelude.jl index f94ff6c..1826fe1 100644 --- a/prelude.jl +++ b/prelude.jl @@ -55,3 +55,17 @@ deftype (Either a b) ;; I/O functions (print :: (String -> (IO Void))) + +;; Operator definitions + +defop 3 Left (a + b) + (add a b) + +defop 3 Left (a - b) + (minus a b) + +defop 4 Left (a * b) + (mul a b) + +defop 4 Left (a / b) + (div a b) diff --git a/representation.js b/representation.js index 3d843d3..c669882 100644 --- a/representation.js +++ b/representation.js @@ -370,10 +370,11 @@ var gensym = makeGensym(); //console.log(isTypeExpr(new Name("T"))); -OPInfo = {"+" : [3, "Left"], +OPInfo = { + /*"+" : [3, "Left"], "-" : [3, "Left"], "*" : [4, "Left"], - "/" : [4, "Left"], + "/" : [4, "Left"],*/ "^" : [5, "Right"], "++" : [3, "Left"], "==" : [2, "Left"], -- 2.30.2 From 64419eeb0727572b807a9397ea0e33d1e7f53dbe Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 16:19:40 -0400 Subject: [PATCH 3/7] move as many operator definitions to prelude.jl as possible, remove some ones I don't care about right now --- example.jl | 12 +++++------- prelude.jl | 42 ++++++++++++++++++++++++++++++++++++++++++ representation.js | 16 ++++++---------- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/example.jl b/example.jl index ada6c55..4599e01 100644 --- a/example.jl +++ b/example.jl @@ -1,7 +1,3 @@ -defop 2 Left (a ++ b) - (a - b) - - def foo# 3 deftype Foo (A -> B) @@ -40,9 +36,9 @@ def empty [] def getFile (readFile "./parse.js") -def fileLines - (getFile >>= - ((mapM_ putStrLn) . lines)) +;;def fileLines +;; (getFile >>= +;; ((mapM_ putStrLn) . lines)) def (testUnary n) ((-n) + n) @@ -94,3 +90,5 @@ def main (unary + fileLines + (print splitted)) + +def blah (3 / 4) diff --git a/prelude.jl b/prelude.jl index 1826fe1..3fa12cc 100644 --- a/prelude.jl +++ b/prelude.jl @@ -69,3 +69,45 @@ defop 4 Left (a * b) defop 4 Left (a / b) (div a b) + +defop 5 Right (a ^ b) + (pow a b) + +defop 3 Left (a ++ b) + (listConcat a b) + +defop 2 Left (a == b) + (eq a b) + +defop 2 Left (a > b) + (gt a b) + +defop 2 Left (a >= b) + (gte a b) + +defop 2 Left (a < b) + (lt a b) + +defop 2 Left (a <= b) + (lte a b) + +defop 2 Left (a && b) + (and a b) + +defop 2 Left (a || b) + (or a b) + +defop 1 Left (x : xs) + (cons x xs) + +defop 1 Left (f $ x) + (fapply f x) + +defop 1 Left (f . g) + (compose f g) + +defop 1 Left (a | b) + (bitwiseOr a b) + +defop 1 Left (a & b) + (bitwiseAnd a b) diff --git a/representation.js b/representation.js index c669882..0a80723 100644 --- a/representation.js +++ b/representation.js @@ -374,8 +374,8 @@ OPInfo = { /*"+" : [3, "Left"], "-" : [3, "Left"], "*" : [4, "Left"], - "/" : [4, "Left"],*/ - "^" : [5, "Right"], + "/" : [4, "Left"], + "^" : [5, "Right"] "++" : [3, "Left"], "==" : [2, "Left"], ">" : [2, "Left"], @@ -383,17 +383,13 @@ OPInfo = { "<" : [2, "Left"], "<=" : [2, "Left"], "&&" : [2, "Left"], - "||" : [2, "Left"], + "||" : [2, "Left"],*/ "::" : [2, "Left"], - ":" : [1, "Left"], + /*":" : [1, "Left"], "$" : [1, "Left"], - ">>" : [1, "Left"], - ">>=" : [1, "Left"], - "<$>" : [1, "Left"], - "." : [1, "Left"], + "." : [1, "Left"],*/ "," : [1, "Left"], - "->" : [1, "Right"], - "|" : [1, "Left"]}; + "->" : [1, "Right"]}; module.exports = { -- 2.30.2 From d38fba9b26d71fcefc8439f3cc3c4c59df64cfee Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 16:28:44 -0400 Subject: [PATCH 4/7] pull in prelude automatically --- tokenize.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tokenize.js b/tokenize.js index 7775a15..c522acd 100755 --- a/tokenize.js +++ b/tokenize.js @@ -1,5 +1,6 @@ #! /usr/bin/node +var fs = require("fs"); var rep = require("./representation.js"); var $ = require("./tools.js"); var error = require("./errors.js"); @@ -408,8 +409,11 @@ function checkPattern(x, i) { } function tokenizeFull(input) { + var preludeSrc = fs.readFileSync("./prelude.jl"); var matchop; var initialPass = tokenizeHelp(input, _.constant(false), true).reverse(); + + input = [preludeSrc, input].join(""); for (var i = 0; i < initialPass.length; i++) { if (initialPass.slice(i, i+8). map(_.first). -- 2.30.2 From cd3d5f40db2a6ec5bf1e3f321d0b2bcee3cfd7e4 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 18:49:17 -0400 Subject: [PATCH 5/7] rename file to be more inline with what it actually does --- closure_conversion.js => free_vars.js | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) rename closure_conversion.js => free_vars.js (82%) diff --git a/closure_conversion.js b/free_vars.js similarity index 82% rename from closure_conversion.js rename to free_vars.js index ff8e104..da87a60 100644 --- a/closure_conversion.js +++ b/free_vars.js @@ -68,7 +68,7 @@ function fvs(stx) { } } -function closure_convert(stx) { +function annotate_fvs(stx) { /* Takes a stx object that is either * a lambda * a let @@ -106,40 +106,40 @@ function closure_convert(stx) { return new rep.Closure(bound_vars, free_variables, stx, []); } -function closure_convert_all(stx) { +function annotate_fvs_all(stx) { var closure; switch (stx.exprType) { case "Let": - closure = closure_convert(stx); - closure.body.pairs = closure.body.pairs.map(closure_convert_all); - closure.body = closure_convert_all(closure.body.body); + closure = annotate_fvs(stx); + closure.body.pairs = closure.body.pairs.map(annotate_fvs_all); + closure.body = annotate_fvs_all(closure.body.body); return closure; case "Function": - closure = closure_convert(stx); - closure.body.body = closure_convert_all(closure.body.body); + closure = annotate_fvs(stx); + closure.body.body = annotate_fvs_all(closure.body.body); return closure; case "Unary": - stx.val = closure_convert_all(stx.val); + stx.val = annotate_fvs_all(stx.val); return stx; case "Application": - stx.func = closure_convert_all(stx.func); - stx.p = closure_convert_all(stx.p); + stx.func = annotate_fvs_all(stx.func); + stx.p = annotate_fvs_all(stx.p); return stx; case "If": if (stx.elseexp) { - stx.condition = closure_convert_all(stx.condition); - stx.thenexp = closure_convert_all(stx.thenexp); - stx.elseexp = closure_convert_all(stx.elseexp); + stx.condition = annotate_fvs_all(stx.condition); + stx.thenexp = annotate_fvs_all(stx.thenexp); + stx.elseexp = annotate_fvs_all(stx.elseexp); return stx; } else { - stx.condition = closure_convert_all(stx.condition); - stx.thenexp = closure_convert_all(stx.thenexp); + stx.condition = annotate_fvs_all(stx.condition); + stx.thenexp = annotate_fvs_all(stx.thenexp); return stx; } break; case "Definition": - stx.val = closure_convert_all(stx.val); + stx.val = annotate_fvs_all(stx.val); return stx; default: return stx; @@ -149,11 +149,11 @@ function closure_convert_all(stx) { function test(src) { var ast = parser.parse(src)[0]; - console.log(JSON.stringify(closure_convert_all(ast), null, 4)); + console.log(JSON.stringify(annotate_fvs_all(ast), null, 4)); } //console.log(test("if something then if a then if b then c else d else rtrrt else some_other_thing")); module.export = { test : test, - closureConvert : closure_convert_all + annotate_fvs: annotate_fvs_all }; -- 2.30.2 From 70d6090d68c38585cfb15a617a2d36b0508f6aa0 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 18:52:46 -0400 Subject: [PATCH 6/7] remove old cruft --- environments.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/environments.js b/environments.js index 51ee39e..44558fc 100644 --- a/environments.js +++ b/environments.js @@ -42,14 +42,7 @@ function lookup(name, env) { return value; } -var prelude = makeEnv("prelude", [[new rep.Name("e"), new rep.FloatT(Math.E)], - [new rep.Name("pi"), new rep.FloatT(Math.PI)]]); - -var prelude_types = makeEnv("prelude_types", - [[new rep.Name("e"), new rep.TypeOp("Float", [], false)], - [new rep.Name("pi"), new rep.TypeOp("Float", [], false)]]); - -module.exports = { prelude : prelude, - prelude_types : prelude_types, - lookup : lookup, - extend : extend }; +module.exports = { + lookup : lookup, + extend : extend +}; -- 2.30.2 From cd23678c5ac8a216b70fdb6fcdc78ad99c0f3b8f Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Sun, 1 Jun 2014 19:39:57 -0400 Subject: [PATCH 7/7] fix semantic ambiguity with type aliases vs. data types with no parameters --- environments.js | 7 ++++--- free_vars.js | 7 ++++--- parse.js | 13 +++++++++---- prelude.jl | 19 ++++++++++++------- representation.js | 21 ++------------------- typecheck.js | 8 ++++---- 6 files changed, 35 insertions(+), 40 deletions(-) diff --git a/environments.js b/environments.js index 44558fc..d88426e 100644 --- a/environments.js +++ b/environments.js @@ -3,13 +3,14 @@ * with a few built-in (a standard Prelude environment) */ -// returns the new environment after mutating it -// values = [(identifier, JLambda expression)] - var errors = require("./errors.js"); var rep = require("./representation.js"); +/* + * returns the new environment after mutating it + * values = [(identifier, JLambda expression)] + */ function extend(env, values) { var new_env = {}; var env_keys = Object.keys(env); diff --git a/free_vars.js b/free_vars.js index da87a60..602c31d 100644 --- a/free_vars.js +++ b/free_vars.js @@ -1,4 +1,4 @@ -/* Takes an AST and converts all of the functions into closures. +/* Takes an AST and converts all of the functions into "closures" * A closure is a triple of: * the bound variables in a function or let * the free variables in a function or let @@ -19,10 +19,8 @@ */ var rep = require("./representation.js"); -var env = require("./environments.js"); var errors = require("./errors.js"); var parser = require("./parse.js"); -var pprint = require("./pprint.js"); var $ = require("./tools.js"); var _ = require("underscore"); @@ -106,6 +104,9 @@ function annotate_fvs(stx) { return new rep.Closure(bound_vars, free_variables, stx, []); } +/* + * This traverse the tree and gathers up all of the free variables of various functions/let bindings + */ function annotate_fvs_all(stx) { var closure; switch (stx.exprType) { diff --git a/parse.js b/parse.js index fa25ccb..2c4e23a 100755 --- a/parse.js +++ b/parse.js @@ -367,12 +367,17 @@ function parseDataType(tokens, linenum, charnum) { typeName.charnum, "Expected a type operator in data type definition"); } - parameters = parseMany(parse, + if (fst(tokens)[0] !== "right_paren") { + parameters = parseMany(parse, validName, validFormPar, tokens, charnum, linenum); + } + else { + parameters = []; + } if (!tokens || (fst(tokens)[0]) !== "right_paren") { throw error.JSyntaxError(_.last(parameters).linenum, _.last(parameters).charnum, @@ -402,7 +407,7 @@ function parseDefType(tokens, linenum, charnum) { } if (fst(tokens)[0] === "left_paren") { /* It's an actual data type definition - * i.e. not just a newtype + * i.e. not just an alias */ tokens.pop(); return parseDataType(tokens, linenum, charnum); @@ -424,7 +429,7 @@ function parseDefType(tokens, linenum, charnum) { if (lhs.exprType !== "TypeOperator") { throw error.JSyntaxError(lhs.linenum, lhs.charnum, - "left-hand side of type definition was not a type operator"); + "left-hand side of type alias was not a type operator"); } rhs = parse(tokens, linenum, charnum); @@ -432,7 +437,7 @@ function parseDefType(tokens, linenum, charnum) { rhs.exprType !== "TypeOperator") { throw error.JSyntaxError(rhs.linenum, rhs.charnum, - "was expecting an application or type operator on the right-hand side of a type definition"); + "was expecting an application or type operator on the right-hand side of a type alias"); } result = addSrcPos(new typ.DefType(lhs, rhs), tokens, rhs.linenum, rhs.charnum); return result; diff --git a/prelude.jl b/prelude.jl index 3fa12cc..1ed259f 100644 --- a/prelude.jl +++ b/prelude.jl @@ -4,24 +4,29 @@ ;; Type definitions -deftype String (A300 Char) +deftype String (Vector Char) -deftype Int Intrinsic +deftype (Int) Intrinsic -deftype Float Intrinsic +deftype (Float) Intrinsic -deftype Char Intrinsic +deftype (Char) Intrinsic -deftype Byte Intrinsic +deftype (Byte) Intrinsic -deftype Void Intrinsic +deftype (Void) Intrinsic -deftype IO Intrinsic +deftype (IO a) Intrinsic + +deftype (Vector a) Intrinsic deftype (List a) (Empty | (Cons a (List a))) +deftype (Bottom) + Undefined + deftype (Maybe a) (Nothing | (Just a)) diff --git a/representation.js b/representation.js index 0a80723..39c3543 100644 --- a/representation.js +++ b/representation.js @@ -368,28 +368,11 @@ function makeGensym() { var gensym = makeGensym(); -//console.log(isTypeExpr(new Name("T"))); - OPInfo = { - /*"+" : [3, "Left"], - "-" : [3, "Left"], - "*" : [4, "Left"], - "/" : [4, "Left"], - "^" : [5, "Right"] - "++" : [3, "Left"], - "==" : [2, "Left"], - ">" : [2, "Left"], - ">=" : [2, "Left"], - "<" : [2, "Left"], - "<=" : [2, "Left"], - "&&" : [2, "Left"], - "||" : [2, "Left"],*/ "::" : [2, "Left"], - /*":" : [1, "Left"], - "$" : [1, "Left"], - "." : [1, "Left"],*/ "," : [1, "Left"], - "->" : [1, "Right"]}; + "->" : [1, "Right"] + }; module.exports = { diff --git a/typecheck.js b/typecheck.js index 7c198c6..e105e94 100644 --- a/typecheck.js +++ b/typecheck.js @@ -13,7 +13,7 @@ var rep = require("./representation.js"); var env = require("./environments.js"); -var TypeOp = rep.TypeOp; -var TypeVar = rep.TypeVar; - - +/* + * Map all bindings with explicit type annotations in the environment + */ +function gather_annotations(stx) { -- 2.30.2