khepri-compile
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -74,8 +74,9 @@ /* | ||
examineState = (function(f) { | ||
return bind(extract, (function(s) { | ||
return f(s); | ||
})); | ||
return bind(extract, f); | ||
}), | ||
unique = (function(s, ok, err) { | ||
return ok(s.unique, s.setUnique((s.unique + 1))); | ||
}), | ||
examineScope = (function(f) { | ||
return bind(extract, (function(s) { | ||
return examineState((function(s) { | ||
return f(s.scope); | ||
@@ -85,22 +86,8 @@ })); | ||
modifyScope = (function(f) { | ||
return (function(s, ok, err) { | ||
var scope = f(s.scope), | ||
newState = State.setScope(s, scope); | ||
return ok(scope, newState); | ||
}); | ||
}), | ||
setScope = (function(s) { | ||
return modifyScope((function() { | ||
return s; | ||
return modifyState((function(s) { | ||
return State.setScope(s, f(s.scope)); | ||
})); | ||
}), | ||
unique = (function(s, ok, err) { | ||
return ok(s.unique, s.setUnique((s.unique + 1))); | ||
}), | ||
push = examineScope((function(s) { | ||
return setScope(scope.push(s)); | ||
})), | ||
pop = examineScope((function(s) { | ||
return setScope(scope.pop(s)); | ||
})), | ||
push = modifyScope(scope.push), | ||
pop = modifyScope(scope.pop), | ||
move = (function(op) { | ||
@@ -117,3 +104,3 @@ return modifyState((function(s) { | ||
var args = arguments; | ||
return seq(move(tree.child.bind(null, edge)), seq.apply(undefined, [].slice.call(args, 1)), up); | ||
return seq(move(tree.child.bind(null, edge)), seqa([].slice.call(args, 1)), up); | ||
}), | ||
@@ -120,0 +107,0 @@ checkCtx = (function(ctx) { |
@@ -16,2 +16,3 @@ /* | ||
ast_pattern = require("khepri-ast")["pattern"], | ||
ast_package = require("khepri-ast")["package"], | ||
ast_value = require("khepri-ast")["value"], | ||
@@ -30,2 +31,8 @@ fun = require("./fun"), | ||
}); | ||
addPeephole(["PackageExport"], true, (function(node) { | ||
return (!node.alias); | ||
}), (function(node) { | ||
return ast_package.PackageExport.create(node.loc, node.id, ast_value.Literal.create(null, "string", node.id | ||
.name)); | ||
})); | ||
addPeephole(["LetExpression"], true, (function(node) { | ||
@@ -32,0 +39,0 @@ return (node.bindings.length > 1); |
@@ -13,2 +13,3 @@ /* | ||
ast_value = require("khepri-ast")["value"], | ||
fun = require("../fun"), | ||
definePackage, importPackage, concat = Function.prototype.call.bind(Array.prototype.concat), | ||
@@ -27,15 +28,19 @@ map = Function.prototype.call.bind(Array.prototype.map), | ||
(definePackage = (function(loc, exports, imports, targets, body) { | ||
var exportHeader = ast_declaration.VariableDeclaration.create(null, map(exports, (function(x) { | ||
return ast_declaration.VariableDeclarator.create(null, ast_value.Identifier.create(null, x)); | ||
}))), | ||
exportBody = map(exports, (function(x) { | ||
return ast_statement.ExpressionStatement.create(null, ast_expression.AssignmentExpression.create( | ||
null, "=", ast_expression.MemberExpression.create(null, ast_value.Identifier.create( | ||
null, "exports"), ast_value.Identifier.create(null, x)), ast_value.Identifier.create( | ||
null, x))); | ||
})), | ||
var exportedNames = ((exports.type === "PackageExports") ? fun.map((function(x) { | ||
return x.id.name; | ||
}), exports.exports) : [exports.id.name]), | ||
exportHeader = ast_declaration.VariableDeclaration.create(null, map(exportedNames, (function(x) { | ||
return ast_declaration.VariableDeclarator.create(null, ast_value.Identifier.create(null, | ||
x)); | ||
}))), | ||
exportBody = ((exports.type === "PackageExports") ? map(exports.exports, (function(x) { | ||
return ast_statement.ExpressionStatement.create(null, ast_expression.AssignmentExpression | ||
.create(null, "=", ast_expression.MemberExpression.create(null, ast_value.Identifier | ||
.create(null, "exports"), x.alias, true), x.id)); | ||
})) : ast_statement.ReturnStatement.create(null, exports.id)), | ||
packageBody = setData(ast_expression.FunctionExpression.create(null, null, ast_pattern.ArgumentsPattern | ||
.create(null, null, concat(ast_pattern.IdentifierPattern.create(null, ast_value.Identifier.create( | ||
null, "require")), ast_pattern.IdentifierPattern.create(null, ast_value.Identifier.create( | ||
null, "exports")), map(imports, (function(x) { | ||
null, "exports")), ast_pattern.IdentifierPattern.create(null, ast_value.Identifier.create( | ||
null, "module")), map(imports, (function(x) { | ||
return targets[x.from.value]; | ||
@@ -42,0 +47,0 @@ })))), ast_statement.BlockStatement.create(body.loc, concat(exportHeader, body, exportBody))), |
@@ -10,2 +10,3 @@ /* | ||
ast_value = require("khepri-ast")["value"], | ||
fun = require("../fun"), | ||
definePackage, importPackage, concat = Array.prototype.concat.bind([]), | ||
@@ -24,11 +25,16 @@ map = Function.prototype.call.bind(Array.prototype.map); | ||
(definePackage = (function(loc, exports, imports, targets, body) { | ||
var exportHeader = ast_declaration.VariableDeclaration.create(null, map(exports, (function(x) { | ||
return ast_declaration.VariableDeclarator.create(null, ast_value.Identifier.create(null, x)); | ||
}))), | ||
exportBody = map(exports, (function(x) { | ||
return ast_statement.ExpressionStatement.create(null, ast_expression.AssignmentExpression.create( | ||
null, "=", ast_expression.MemberExpression.create(null, ast_value.Identifier.create( | ||
null, "exports"), ast_value.Identifier.create(null, x)), ast_value.Identifier.create( | ||
null, x))); | ||
})); | ||
var exportedNames = ((exports.type === "PackageExports") ? fun.map((function(x) { | ||
return x.id.name; | ||
}), exports.exports) : [exports.id.name]), | ||
exportHeader = ast_declaration.VariableDeclaration.create(null, map(exportedNames, (function(x) { | ||
return ast_declaration.VariableDeclarator.create(null, ast_value.Identifier.create(null, | ||
x)); | ||
}))), | ||
exportBody = ((exports.type === "PackageExports") ? map(exports.exports, (function(x) { | ||
return ast_statement.ExpressionStatement.create(null, ast_expression.AssignmentExpression | ||
.create(null, "=", ast_expression.MemberExpression.create(null, ast_value.Identifier | ||
.create(null, "exports"), x.alias, true), x.id)); | ||
})) : ast_statement.ExpressionStatement.create(null, ast_expression.AssignmentExpression.create( | ||
null, "=", ast_expression.MemberExpression.create(null, ast_value.Identifier.create(null, | ||
"module"), ast_value.Identifier.create(null, "exports")), exports.id))); | ||
return ast_statement.BlockStatement.create(body.loc, [ast_statement.ExpressionStatement.create(null, | ||
@@ -35,0 +41,0 @@ ast_value.Literal.create(null, "string", "use strict")), ast_statement.WithStatement.create( |
@@ -337,5 +337,2 @@ /* | ||
}), body.bindings) : []), | ||
exportedNames = fun.map((function(x) { | ||
return x.id.name; | ||
}), exports.exports), | ||
targets = fun.reduce(imports, (function(p, c) { | ||
@@ -349,3 +346,3 @@ (p[c.from.value] = c.pattern); | ||
}), body.bindings), body.body) : body); | ||
return packageManager.definePackage(loc, exportedNames, imports, targets, fBody); | ||
return packageManager.definePackage(loc, exports, imports, targets, fBody); | ||
}), | ||
@@ -352,0 +349,0 @@ transformers = ({}), |
{ | ||
"name": "khepri-compile", | ||
"version": "0.0.1", | ||
"description": "Khepri compiler", | ||
"version": "0.1.0", | ||
"description": "Compiler for the Khepri programming language", | ||
"author": "Matt Bierner", | ||
@@ -51,3 +51,3 @@ "license": "MIT", | ||
"khepri-parse": "0.4.x", | ||
"khepri-parse": "0.5.x", | ||
"ecma-unparse": "3.2.x" | ||
@@ -54,0 +54,0 @@ }, |
194
README.md
@@ -1,193 +0,5 @@ | ||
# Khepri | ||
ECMAScript derived programming language | ||
# Khepri Compiler | ||
Compiler for the [Khepri programming language][khepri]. | ||
### About | ||
Khepri is an ECMAScript derived programming language that tweaks | ||
ECMAScript and introduces new features to make the language more concise | ||
and consistent. Khepri compiles to plain old Javascript and does not require | ||
any runtime libraries and Khepri and Javascript can also be freely mixed in a | ||
project. | ||
Unlike most other *script languages, Khepri's goal is not to replace Javascript | ||
by introducing new heavy weight language features, but to make writing Javascript | ||
more fun, with a focus on functional style programming. | ||
### Links | ||
* [Documentation][documentation] | ||
## Overview | ||
See documentation for details: | ||
``` | ||
/* Functions | ||
----------------------*/ | ||
// lambda single argument | ||
\x -> x + 3; | ||
// lambda multiple arguments, commas are optional | ||
\x y -> x + y; | ||
\x, y -> x + y; | ||
// lambda with function body | ||
\x y -> { | ||
var z = x + 10; | ||
return z + y; | ||
}; | ||
// Named function | ||
function f \x -> ?x < 10 :f x + 1 :x; | ||
// Named Args access | ||
var f = \args(...) -> args.length; | ||
// Fat Arrow This Unpacks | ||
\x =self-> self.z + x; | ||
// Function Application | ||
f 10; f(10); // single arg | ||
f(10, 20); // multiple args | ||
f 1 2 3; // f(1)(2)(3) | ||
// Binding | ||
f@10; f@(10); // single argument bind | ||
f@(10, 20); // multiple argument bind | ||
/* Unpacks | ||
----------------------*/ | ||
// Unpack values from array | ||
var sum = \[x y] -> x + y; | ||
sum [1, 2]; // 3, note application | ||
// Unpack values from object | ||
var swapAB = \{a b} -> ({'a': b, 'b': a}); | ||
swapAB {'a': 3, 'b': 5}; // {'a': 5, 'b': 3}; | ||
// Nesting unpacks | ||
var dot2 = \[[a b] [x y]] -> a * x + b * y; | ||
dot2 [[1, 2], [3, 4]]; // 11 | ||
// As unpacks | ||
var dup = \arr#[x ...] -> [x, arr]; | ||
dup [1, [2]]; // [1, [1, [2]]]; | ||
/* Lexical Scope | ||
----------------------*/ | ||
var x = 10; | ||
{ | ||
var x; | ||
x = 20; | ||
} | ||
x; // 10 | ||
/* Let Expression | ||
----------------------*/ | ||
// Simple | ||
4 * let a = 2 in a + 3; // 20 | ||
// With unpacks | ||
let | ||
o#{x, y} = {'a': 3, 'x': 6, 'z': 5, 'y': 8}, | ||
[first] = [1, 2, 3] | ||
in | ||
first + y + x + o.a; // 18 | ||
/* Packages | ||
----------------------*/ | ||
// Exports | ||
package (min max) { | ||
min = \x y -> ?x < y :x :y; | ||
max = \x y -> ?x < y :y :x; | ||
} | ||
// imports using unpacks | ||
package () | ||
with | ||
import 'math' math#{min max} | ||
in { | ||
min(max(3, 7), 4); | ||
} | ||
/* New Operators | ||
----------------------*/ | ||
// Pipe | ||
10 |> f; // f(10); | ||
// Reverse Pipe | ||
f <| 10; // f(10); | ||
// Compose | ||
f \> g; // \x -> g(f(x)) | ||
// Reverse Compose | ||
f <\ g; // \x -> f(g(x)) | ||
/* Other Important Changes | ||
----------------------*/ | ||
// Operator to function | ||
(+); | ||
// Conditional | ||
min = \x y -> ?x < y :x :y; | ||
// Computed Member Access | ||
a.(1 + x * 4); | ||
// Unary plus and minus | ||
++x; --x; | ||
// Removed compound assign and inc/dec ops | ||
x = x + 1; | ||
``` | ||
## Using Khepri | ||
### Install | ||
$ npm install -g khepri | ||
### Compiling | ||
``` | ||
# Compile file to stdout | ||
$ khepri file.kep | ||
# Get help | ||
$ khepri --help | ||
# Compile file to output file | ||
$ khepri file.kep -o build/file.js | ||
# Generate node package code in output | ||
$ khepri file.kep -o build/file.js --package_manager=node | ||
# Compile all *.kep files in a directory to an output directory | ||
$ khepri lib -o dist | ||
# Compile stdin to stdout | ||
$ echo "\x->x;" | khepri | ||
# Watch files for changes and compile to outdir. | ||
# If in_file is a directory, watch all *.kep files in the directory. | ||
$ khepri -w lib/ -o dist/ | ||
``` | ||
### Clone From Git and use AMD | ||
git clone https://github.com/mattbierner/khepri khepri | ||
cd khepri | ||
git submodule update --init | ||
## Code | ||
Khepri is written in Javascript / Khepri. | ||
Node files are generated into `dist_node`. Amd files in `dist` | ||
[documentation]: https://github.com/mattbierner/khepri/wiki | ||
[parsejs]: https://github.com/mattbierner/parse.js | ||
[ecma51]: http://www.ecma-international.org/publications/standards/Ecma-262.htm | ||
[nu]: http://mattbierner.github.io/nu/ | ||
[ecmaunparse]: https://github.com/mattbierner/ecma-unparse | ||
[ecmaast]: https://github.com/mattbierner/ecma-ast | ||
[khepriast]: https://github.com/mattbierner/khepri-ast | ||
[khepri]: https://github.com/mattbierner/khepri |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2299
161516
6