From 252798b1340abb86c34f3b036498892714b2b8c8 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Tue, 3 Jun 2014 01:12:05 -0400 Subject: [PATCH 1/7] return type alias bindings along with ast --- desugar.js | 22 +++++++++++++--------- free_vars.js | 6 +++--- parse.js | 11 ++++++++--- typecheck.js | 1 - 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/desugar.js b/desugar.js index 9da5d4e..2c9d9be 100644 --- a/desugar.js +++ b/desugar.js @@ -57,30 +57,34 @@ function sugarTypeDecl(stx) { return new typ.TypeDecl(expression, type); } -function desugarDefType(stx) { +function desugarDefType(stx, typeEnv) { var result; - result = new typ.DefType(desugar(stx.lhs), desugar(stx.rhs)); + var rhs = desugar(stx.rhs); + var name = stx.lhs.name; + typeEnv[name] = rhs; + + result = new typ.DefType(stx.lhs, desugar(stx.rhs)); result.linenum = stx.linenum; result.charnum = stx.charnum; return result; } -function desugar(stx) { +function desugar(stx, typeAliases, typeEnv) { var typeExpTest; switch (stx.exprType) { case "If": if (stx.elseexp) { - return new typ.If(desugar(stx.condition), desugar(stx.thenexp), desugar(stx.elseexp)); + return new typ.If(desugar(stx.condition, typeEnv), desugar(stx.thenexp, typeEnv), desugar(stx.elseexp, typeEnv)); } - return new typ.If(desugar(stx.condition), desugar(stx.thenexp)); + return new typ.If(desugar(stx.condition, typeEnv), desugar(stx.thenexp, typeEnv)); case "FunctionDefinition": return desugarDefFunc(stx); case "Definition": - return new typ.Def(stx.ident, desugar(stx.val)); + return new typ.Def(stx.ident, desugar(stx.val, typeEnv)); case "TypeDefinition": - return desugarDefType(stx); + return desugarDefType(stx, typeEnv); case "Name": return stx; case "Application": @@ -104,10 +108,10 @@ function desugar(stx) { if ((stx.func.ident === "-" || stx.func.ident === "+") && stx.p) { - return new typ.UnaryOp(desugar(stx.func), desugar(stx.p)); + return new typ.UnaryOp(desugar(stx.func, typeEnv), desugar(stx.p, typeEnv)); } if (stx.p) { - return new typ.App(desugar(stx.func), desugar(stx.p)); + return new typ.App(desugar(stx.func, typeEnv), desugar(stx.p, typeEnv)); } return new typ.App(stx.func); case "Function": diff --git a/free_vars.js b/free_vars.js index 602c31d..bb57da3 100644 --- a/free_vars.js +++ b/free_vars.js @@ -149,11 +149,11 @@ function annotate_fvs_all(stx) { function test(src) { - var ast = parser.parse(src)[0]; - console.log(JSON.stringify(annotate_fvs_all(ast), null, 4)); + var ast = parser.parse(src); + console.log(JSON.stringify(ast.map(annotate_fvs_all), null, 4)); } -//console.log(test("if something then if a then if b then c else d else rtrrt else some_other_thing")); +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, annotate_fvs: annotate_fvs_all diff --git a/parse.js b/parse.js index 2c4e23a..5da6f0f 100755 --- a/parse.js +++ b/parse.js @@ -807,11 +807,12 @@ function parse(tokens) { function parseFull(tokenized) { var ast = []; + var typeBindings = {}; try { while (tokenized.length > 0) { - ast.push(desugarer.desugar(parse(tokenized))); + ast.push(desugarer.desugar(parse(tokenized), typeBindings)); } - return ast; + return [ast, typeBindings]; } catch (e) { if (e.stxerror !== undefined) { e.stxerror(); @@ -829,5 +830,9 @@ module.exports = { parse : function(str) { }, tokenize : tokenizer.tokenize }; +/* var istr = fs.readFileSync('/dev/stdin').toString(); -console.log(parseFull(tokenizer.tokenize(istr)).map(pprint.pprint)); +var testParse = parseFull(tokenizer.tokenize(istr)); +console.log(testParse[1]); +console.log(testParse[0].map(pprint.pprint)); +*/ diff --git a/typecheck.js b/typecheck.js index e105e94..c39306c 100644 --- a/typecheck.js +++ b/typecheck.js @@ -16,4 +16,3 @@ var env = require("./environments.js"); /* * Map all bindings with explicit type annotations in the environment */ -function gather_annotations(stx) { -- 2.30.2 From a6c721da56a3615a5dab91a0f2091e0d7289147a Mon Sep 17 00:00:00 2001 From: Dan Kaplun Date: Tue, 3 Jun 2014 00:14:32 -0500 Subject: [PATCH 2/7] Adds simple NodeJS .gitignore --- .gitignore | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da23d0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Deployed apps should consider commenting this line out: +# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git +node_modules -- 2.30.2 From c29edfa7e1d8e676d46d384212c197aa71dd6f4f Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Tue, 3 Jun 2014 01:16:50 -0400 Subject: [PATCH 3/7] remove extra parameter --- desugar.js | 2 +- parse.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/desugar.js b/desugar.js index 2c9d9be..a404fef 100644 --- a/desugar.js +++ b/desugar.js @@ -70,7 +70,7 @@ function desugarDefType(stx, typeEnv) { } -function desugar(stx, typeAliases, typeEnv) { +function desugar(stx, typeEnv) { var typeExpTest; switch (stx.exprType) { diff --git a/parse.js b/parse.js index 5da6f0f..39bd0d0 100755 --- a/parse.js +++ b/parse.js @@ -811,7 +811,9 @@ function parseFull(tokenized) { try { while (tokenized.length > 0) { ast.push(desugarer.desugar(parse(tokenized), typeBindings)); + console.log(ast); } + console.log(ast); return [ast, typeBindings]; } catch (e) { if (e.stxerror !== undefined) { @@ -830,9 +832,7 @@ module.exports = { parse : function(str) { }, tokenize : tokenizer.tokenize }; -/* var istr = fs.readFileSync('/dev/stdin').toString(); var testParse = parseFull(tokenizer.tokenize(istr)); console.log(testParse[1]); console.log(testParse[0].map(pprint.pprint)); -*/ -- 2.30.2 From bd801f8e18a95cd4fd55aa7e97b48049234489b2 Mon Sep 17 00:00:00 2001 From: Dan Kaplun Date: Tue, 3 Jun 2014 00:17:14 -0500 Subject: [PATCH 4/7] Adds package.json --- package.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..f3044c2 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "JLambda", + "version": "0.0.0", + "description": "yet another static functional language implemented in JS", + "scripts": { + "test": "./test.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/nisstyre56/JLambda.git" + }, + "keywords": [ + "static", + "functional", + "language" + ], + "author": "nisstyre56", + "license": "ΩF:∅", + "bugs": { + "url": "https://github.com/nisstyre56/JLambda/issues" + }, + "homepage": "https://github.com/nisstyre56/JLambda", + "dependencies": { + "underscore": "^1.6.0" + } +} -- 2.30.2 From 5b847fe09070f4db6c7ec075b44cc6f4692fcfca Mon Sep 17 00:00:00 2001 From: Dan Kaplun Date: Tue, 3 Jun 2014 00:21:27 -0500 Subject: [PATCH 5/7] Adds installation and usage instructions to README --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 69e5928..57ad6bb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +JLambda +======= + JLambda is a functional language in the spirit of languages such as Scheme, SML, or Clean. It aims to have a very flexible syntax and a clean and easy to understand type system. Another goal is to generate very efficient JavaScript @@ -11,3 +14,18 @@ JLambda also aims to support concurrency which will be built on a continuation-passing style intermediate language. I have not figured out how scheduling threads will work, or whether I will provide any programmer directed way of scheduling (i.e. yield). + +Installation +------------ + + git clone git@github.com:nisstyre56/JLambda.git + cd JLambda + npm install + +Usage +----- + +Since the language is currently under heavy construction, the parser is the +entry point for now: + + cat example.jl | ./parse.js -- 2.30.2 From c34fd71244a728e14ae6a36589c20d08c07496a5 Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Wed, 4 Jun 2014 01:38:48 -0400 Subject: [PATCH 6/7] fix bug where defops were not being included by the tokenizer properly, fixed precedence order mixup in prelude.jl --- free_vars.js | 3 +-- parse.js | 2 -- prelude.jl | 34 +++++++++++++++++----------------- tokenize.js | 7 +++++-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/free_vars.js b/free_vars.js index bb57da3..caf3198 100644 --- a/free_vars.js +++ b/free_vars.js @@ -150,10 +150,9 @@ function annotate_fvs_all(stx) { function test(src) { var ast = parser.parse(src); - console.log(JSON.stringify(ast.map(annotate_fvs_all), null, 4)); } -console.log(test("if something then if a then if b then c else d else rtrrt else some_other_thing")); +//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, annotate_fvs: annotate_fvs_all diff --git a/parse.js b/parse.js index 39bd0d0..08b6052 100755 --- a/parse.js +++ b/parse.js @@ -811,9 +811,7 @@ function parseFull(tokenized) { try { while (tokenized.length > 0) { ast.push(desugarer.desugar(parse(tokenized), typeBindings)); - console.log(ast); } - console.log(ast); return [ast, typeBindings]; } catch (e) { if (e.stxerror !== undefined) { diff --git a/prelude.jl b/prelude.jl index 1ed259f..2099588 100644 --- a/prelude.jl +++ b/prelude.jl @@ -63,56 +63,56 @@ deftype (Either a b) ;; Operator definitions -defop 3 Left (a + b) +defop 1 Left (a + b) (add a b) -defop 3 Left (a - b) +defop 1 Left (a - b) (minus a b) -defop 4 Left (a * b) +defop 2 Left (a * b) (mul a b) -defop 4 Left (a / b) +defop 2 Left (a / b) (div a b) -defop 5 Right (a ^ b) +defop 2 Right (a ^ b) (pow a b) defop 3 Left (a ++ b) (listConcat a b) -defop 2 Left (a == b) +defop 3 Left (a == b) (eq a b) -defop 2 Left (a > b) +defop 3 Left (a > b) (gt a b) -defop 2 Left (a >= b) +defop 3 Left (a >= b) (gte a b) -defop 2 Left (a < b) +defop 3 Left (a < b) (lt a b) -defop 2 Left (a <= b) +defop 3 Left (a <= b) (lte a b) -defop 2 Left (a && b) +defop 3 Left (a && b) (and a b) -defop 2 Left (a || b) +defop 3 Left (a || b) (or a b) -defop 1 Left (x : xs) +defop 4 Left (x : xs) (cons x xs) -defop 1 Left (f $ x) +defop 5 Left (f $ x) (fapply f x) -defop 1 Left (f . g) +defop 5 Left (f . g) (compose f g) -defop 1 Left (a | b) +defop 3 Left (a | b) (bitwiseOr a b) -defop 1 Left (a & b) +defop 3 Left (a & b) (bitwiseAnd a b) diff --git a/tokenize.js b/tokenize.js index c522acd..1171a6c 100755 --- a/tokenize.js +++ b/tokenize.js @@ -14,7 +14,10 @@ function isDigit(c) { if (isNaN(code)) { return false; } - return (47 < code && code < 58); + if ((47 < code) && (code < 58)) { + return true; + } + return false; } function isWhitespace(c) { @@ -411,9 +414,9 @@ function checkPattern(x, i) { function tokenizeFull(input) { var preludeSrc = fs.readFileSync("./prelude.jl"); var matchop; + input = [preludeSrc, input].join(""); 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 a4d81a0bf79ae53421f7d640f40a429f9fdf1b1e Mon Sep 17 00:00:00 2001 From: nisstyre56 Date: Wed, 4 Jun 2014 01:40:03 -0400 Subject: [PATCH 7/7] remove code leftover from debugging --- tokenize.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tokenize.js b/tokenize.js index 1171a6c..cbe748a 100755 --- a/tokenize.js +++ b/tokenize.js @@ -14,10 +14,7 @@ function isDigit(c) { if (isNaN(code)) { return false; } - if ((47 < code) && (code < 58)) { - return true; - } - return false; + return (47 < code) && (code < 58) } function isWhitespace(c) { -- 2.30.2