Permalink
Browse files

add __loop_include__ macro to include files

  • Loading branch information...
smtlaissezfaire committed Feb 25, 2013
1 parent c159b17 commit b41f21a1458b379a43bf9e17d3e7abd0b41943ea
View
@@ -92,7 +92,7 @@ var loopEval = function(syntaxTree) {
case 'number':
case 'comment':
case 'regexp':
- case '__raw_js__':
+ case 'raw_js':
return syntaxTree;
default:
throw new Error('unknown type of syntaxTree, type: ' + syntaxTree.type);
View
@@ -2,6 +2,8 @@ var _ = require("./util/underscore");
var printTree = require('./util/tree-inspector').withLineNumbers;
var helpers = require('./util/helpers');
var compiler = {};
+var loop = require('../loop');
+var fs = require('fs');
var macros = {};
@@ -81,14 +83,15 @@ compiler.addEval = function() {
type: 'list',
contents: [
{ type: 'id', contents: '__loop_js_eval__'},
- { type: 'id', contents: 'args' }
+ { type: 'id', contents: 'args' },
+ { type: 'macro-pattern' }
]
},
replacement: {
type: '__loop_js_eval__',
fn: function(locals) {
var str = locals.args[0].contents;
- return require('vm').runInNewContext(str, {}).toString();
+ return require('vm').runInNewContext(str).toString();
}
}
});
@@ -98,7 +101,8 @@ compiler.addEval = function() {
type: 'list',
contents: [
{ type: 'id', contents: '__loop_eval__'},
- { type: 'id', contents: 'args' },
+ { type: 'id', contents: 'body' },
+ { type: 'macro-pattern' }
]
},
replacement: {
@@ -110,7 +114,12 @@ compiler.addEval = function() {
var uglifyAst = loop.toUglifyTree(ast, {});
var pro = require("uglify-js").uglify;
var jsCode = pro.gen_code(uglifyAst, {});
- return require('vm').runInNewContext(jsCode, {}).toString();
+
+ return require('vm').runInNewContext(jsCode, {
+ require: require,
+ loop: loop,
+ fs: fs
+ }).toString();
}
}
});
@@ -409,12 +418,12 @@ var replaceFormalsFromList = function(replacement, locals, shouldShift) {
if (replacement.type === '__loop_js_eval__') {
return {
- type: '__raw_js__',
+ type: 'raw_js',
contents: replacement.fn(locals)
};
} else if (replacement.type === '__loop_eval__') {
return {
- type: '__raw_js__',
+ type: 'raw_js',
contents: replacement.fn(locals)
};
} else if (replacement.type === 'list') {
@@ -11,3 +11,10 @@
body ...)
((lambda (key ...)
body ...) value ...))
+
+(define-macro
+ (__loop_include__ filename)
+ (__loop_eval__
+ (let ((buf (fs.readFileSync filename)))
+ ; eek! shouldn't need this return
+ (return (loop.compile (buf.toString))))))
View
@@ -161,8 +161,8 @@ var _var = function(pairs) {
var progn = function(tree) {
switch (tree.type) {
- case '__raw_js__':
- return require('uglify-js').parser.parse(tree.contents);
+ case 'raw_js':
+ return require('uglify-js').parser.parse(tree.contents.toString());
case 'funcall':
var f = tree.function;
var processedArgs;
@@ -426,6 +426,7 @@ processStatementOrExpression = function(statementOrExpression) {
case 'prop-access':
case 'number':
case 'regexp':
+ case 'raw_js':
return stmt(progn(statementOrExpression));
case 'comment':
return progn(statementOrExpression);
@@ -0,0 +1 @@
+(define x 1)
@@ -0,0 +1,3 @@
+(define-macro
+ (my-unless condition body)
+ (if (! condition) body))
@@ -0,0 +1,43 @@
+var assert = require("assert");
+var loop = require(__dirname + "/../../lib/loop");
+var path = require('path');
+
+describe("include", function() {
+ beforeEach(function() {
+ loop.macroCompiler.reset();
+ });
+
+ it('should be able to include a file with .loop extension', function() {
+ var filePath = path.join(__dirname, '..', 'fixtures', 'define_x_equal_to_one.loop');
+ var code = "";
+ code += "(__loop_include__ '" + filePath + "')";
+ var expectedCode = "var x=1";
+ assert.equal(loop.compile(code), expectedCode);
+ });
+
+ it('should be able to use the variables from a required file', function() {
+ var filePath = path.join(__dirname, '..', 'fixtures', 'define_x_equal_to_one.loop');
+ var code = "";
+ code += "(__loop_include__ '" + filePath + "')";
+ code += "(define y (+ x 10))";
+ var expectedCode = '';
+ expectedCode += "var x=1;";
+ expectedCode += 'var y=x+10';
+ assert.equal(loop.compile(code), expectedCode);
+ });
+
+ it('should be able to use a macro from a required file', function() {
+ var filePath = path.join(__dirname, '..', 'fixtures', 'macro-my-unless.loop');
+ var code = "";
+ code += "(__loop_include__ \"" + filePath + "\")";
+ code += '(my-unless x';
+ code += ' (console.log "foo!"))';
+
+ var expectedCode = '';
+ expectedCode += 'if(!x){';
+ expectedCode += 'console.log("foo!")';
+ expectedCode += '}';
+
+ assert.equal(loop.compile(code), expectedCode);
+ });
+});

0 comments on commit b41f21a

Please sign in to comment.