Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* add (quote) to turn a symbol into a string (useful in macros

* fix a bug where multiple instances of a value inside a macro was only being replaced once
  • Loading branch information...
commit 2d04df3bbd9bb6d83034b4adabb78418f0d65fa0 1 parent c8a5eca
Scott Taylor authored
20 lib/loop/macro-compiler.js
View
@@ -361,7 +361,7 @@ extractFormals = function(template, ast) {
return locals;
};
-var replaceFormalsFromList = function(replacement, locals) {
+var replaceFormalsFromList = function(replacement, locals, shouldShift) {
replacement = helpers.deepCopy(replacement);
if (replacement.type === 'list') {
@@ -382,7 +382,17 @@ var replaceFormalsFromList = function(replacement, locals) {
var extraMacroPattern;
_.each(replacement.contents, function(el) {
- var newValue = replaceFormalsFromList(el, locals);
+ var newValue;
+
+ // in a macro pattern we'll have multiple values, so
+ // we'll want to shift an element off the variable list. Otherwise
+ // we don't want to touch the variables, though, as in the
+ // case of a repeated variable
+ if (replacement.hasMacroPattern) {
+ newValue = replaceFormalsFromList(el, locals, true);
+ } else {
+ newValue = replaceFormalsFromList(el, locals);
+ }
if (newValue instanceof Array) {
_.each(newValue, function(el) {
@@ -414,7 +424,11 @@ var replaceFormalsFromList = function(replacement, locals) {
if (replacement.hasMacroPattern) {
return locals[replacement.contents];
} else {
- return locals[replacement.contents].shift();
+ if (shouldShift) {
+ return locals[replacement.contents].shift();
+ } else {
+ return locals[replacement.contents][0];
+ }
}
} else { // we found no actual value for this macro
// if it is a macro pattern like ((a b) ...),
7 lib/loop/uglify.js
View
@@ -174,7 +174,12 @@ var progn = function(tree) {
args = args.contents;
if (f.type === 'id') {
- if (f.contents === 'lambda' || f.contents === 'function') {
+ if (f.contents === 'quote') {
+ if (args.length !== 1) {
+ throw new Error("quote must take one argument");
+ }
+ return ['string', car(args).contents];
+ } else if (f.contents === 'lambda' || f.contents === 'function') {
var formalArgs = _.map(car(args).contents, function(arg) {
return arg.contents;
});
41 spec/integration/macro-spec.js
View
@@ -493,7 +493,44 @@ vows.describe("integration specs (macros)").addBatch({
expected += "})(10)";
assert.equal(loop.compile(code), expected);
- }
- }
+ },
+ },
+ 'quote': {
+ 'it should be able to quote': function() {
+ var code = "(quote Foo)";
+ var expected = "\"Foo\"";
+ assert.equal(loop.compile(code), expected);
+ },
+ 'it should be able to quote inside a define-macro': function() {
+ var code = '';
+ code += '(define-macro';
+ code += ' (my-quote some-var)';
+ code += ' (quote some-var))';
+ code += '(my-quote Foo)';
+ var expected = '"Foo"';
+
+ assert.equal(loop.compile(code), expected);
+ },
+ },
+ 'it should allow substitution in the body of the macro more than once': function() {
+ var code = '';
+ code += '(define-macro ';
+ code += ' (my-square num)';
+ code += ' (mult num num))';
+ code += '(my-square 2)';
+
+ var expected = "mult(2,2)";
+ assert.equal(loop.compile(code), expected);
+ },
+ 'it should allow multiple substiution on multiple levels': function() {
+ var code = '';
+ code += '(define-macro ';
+ code += ' (foo num)';
+ code += ' (mult num (mult num 1)))';
+ code += '(foo 2)';
+
+ var expected = "mult(2,mult(2,1))";
+ assert.equal(loop.compile(code), expected);
+ }
}).export(module);
Please sign in to comment.
Something went wrong with that request. Please try again.