From 71ace9d8d06be8bf6ce4da0bfc2150c50aa2f227 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sun, 7 Mar 2010 22:26:25 -0500 Subject: [PATCH] allowing naked interpolation of dotted properties. .property --- lib/lexer.js | 2 +- lib/nodes.js | 12 ++++++------ src/lexer.coffee | 2 +- src/nodes.coffee | 12 ++++++------ test/test_string_interpolation.coffee | 1 + 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/lexer.js b/lib/lexer.js index b2f9cbad..161ae53b 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -567,7 +567,7 @@ IDENTIFIER = /^([a-zA-Z$_](\w|\$)*)/; NUMBER = /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i; HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/; - INTERPOLATION = /^\$([a-zA-Z_@]\w*)/; + INTERPOLATION = /^\$([a-zA-Z_@]\w*(\.\w+)*)/; OPERATOR = /^([+\*&|\/\-%=<>:!?]+)/; WHITESPACE = /^([ \t]+)/; COMMENT = /^(((\n?[ \t]*)?#[^\n]*)+)/; diff --git a/lib/nodes.js b/lib/nodes.js index 28e84114..cba69e39 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -464,8 +464,8 @@ idt += TAB CallNode.prototype.compile_super = function compile_super(args, o) { var meth, methname; methname = o.scope.method.name; - meth = o.scope.method.proto ? (o.scope.method.proto) + ".__superClass__." + methname : methname + ".__superClass__.constructor"; - return meth + ".call(this" + (args.length ? ', ' : '') + args + ")"; + meth = o.scope.method.proto ? (o.scope.method.proto) + ".__superClass__." + methname : (methname) + ".__superClass__.constructor"; + return (meth) + ".call(this" + (args.length ? ', ' : '') + args + ")"; }; // If you call a function with a splat, it's converted into a JavaScript // `.apply()` call to allow the variable-length arguments. @@ -490,7 +490,7 @@ idt += TAB } return _a; }).call(this); - return this.prefix + meth + ".apply(" + obj + ", " + (args.join('')) + ")"; + return this.prefix + (meth) + ".apply(" + obj + ", " + (args.join('')) + ")"; }; return CallNode; }).call(this); @@ -698,7 +698,7 @@ idt += TAB _a.push((function() { code = obj.compile(o); if (obj instanceof CommentNode) { - return "\n" + code + "\n" + (o.indent); + return "\n" + code + "\n" + o.indent; } else if (i === this.objects.length - 1) { return code; } else { @@ -911,7 +911,7 @@ idt += TAB from = range.from.compile(o); to = range.to.compile(o) + ' - ' + from + plus; val = this.value.compile(o); - return name + ".splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + val + "))"; + return (name) + ".splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + val + "))"; }; return AssignNode; }).call(this); @@ -1328,7 +1328,7 @@ idt += TAB if (!this.object) { lvar = scope.free_variable(); step_part = this.step ? ivar + " += " + (this.step.compile(o)) : ivar + "++"; - for_part = ivar + " = 0, " + lvar + " = " + svar + ".length; " + ivar + " < " + lvar + "; " + step_part; + for_part = ivar + " = 0, " + lvar + " = " + (svar) + ".length; " + ivar + " < " + lvar + "; " + step_part; } } set_result = rvar ? this.idt() + rvar + ' = []; ' : this.idt(); diff --git a/src/lexer.coffee b/src/lexer.coffee index daf1ce5d..74c96d97 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -440,7 +440,7 @@ JS_FORBIDDEN: JS_KEYWORDS.concat RESERVED IDENTIFIER : /^([a-zA-Z$_](\w|\$)*)/ NUMBER : /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i HEREDOC : /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/ -INTERPOLATION : /^\$([a-zA-Z_@]\w*)/ +INTERPOLATION : /^\$([a-zA-Z_@]\w*(\.\w+)*)/ OPERATOR : /^([+\*&|\/\-%=<>:!?]+)/ WHITESPACE : /^([ \t]+)/ COMMENT : /^(((\n?[ \t]*)?#[^\n]*)+)/ diff --git a/src/nodes.coffee b/src/nodes.coffee index 0c50dc44..fc78fed5 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -357,8 +357,8 @@ exports.CallNode: class CallNode extends BaseNode meth: if o.scope.method.proto "${o.scope.method.proto}.__superClass__.$methname" else - "$methname.__superClass__.constructor" - "$meth.call(this${ if args.length then ', ' else '' }$args)" + "${methname}.__superClass__.constructor" + "${meth}.call(this${ if args.length then ', ' else '' }$args)" # If you call a function with a splat, it's converted into a JavaScript # `.apply()` call to allow the variable-length arguments. @@ -373,7 +373,7 @@ exports.CallNode: class CallNode extends BaseNode code: arg.compile o code: if arg instanceof SplatNode then code else "[$code]" if i is 0 then code else ".concat($code)" - "$@prefix$meth.apply($obj, ${ args.join('') })" + "$@prefix${meth}.apply($obj, ${ args.join('') })" #### ExtendsNode @@ -535,7 +535,7 @@ exports.ArrayNode: class ArrayNode extends BaseNode objects: for obj, i in @objects code: obj.compile(o) if obj instanceof CommentNode - "\n$code\n${o.indent}" + "\n$code\n$o.indent" else if i is @objects.length - 1 code else @@ -704,7 +704,7 @@ exports.AssignNode: class AssignNode extends BaseNode from: range.from.compile(o) to: range.to.compile(o) + ' - ' + from + plus val: @value.compile(o) - "$name.splice.apply($name, [$from, $to].concat($val))" + "${name}.splice.apply($name, [$from, $to].concat($val))" #### CodeNode @@ -1007,7 +1007,7 @@ exports.ForNode: class ForNode extends BaseNode if not @object lvar: scope.free_variable() step_part: if @step then "$ivar += ${ @step.compile(o) }" else "$ivar++" - for_part: "$ivar = 0, $lvar = $svar.length; $ivar < $lvar; $step_part" + for_part: "$ivar = 0, $lvar = ${svar}.length; $ivar < $lvar; $step_part" set_result: if rvar then @idt() + rvar + ' = []; ' else @idt() return_result: rvar or '' body: ClosureNode.wrap(body, true) if top_level and @contains (n) -> n instanceof CodeNode diff --git a/test/test_string_interpolation.coffee b/test/test_string_interpolation.coffee index 2356202b..5ae223a0 100644 --- a/test/test_string_interpolation.coffee +++ b/test/test_string_interpolation.coffee @@ -54,6 +54,7 @@ ok "I can has ${"cheeze"}" is 'I can has cheeze' ok 'I can has ${"cheeze"}' is 'I can has ${"cheeze"}' ok "Where is ${obj["name"] + '?'}" is 'Where is Joe?' +ok "Where is $obj.name?" is 'Where is Joe?' ok "Where is ${"the new ${obj["name"]}"}?" is 'Where is the new Joe?' ok "Hello ${world ? "$hello"}" is 'Hello World'