From dd753d3b7848950fe8f7bfef84964afb5d0d791c Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Fri, 19 Feb 2010 07:51:52 -0500 Subject: [PATCH] Removing the notion of a ThisNode so that we don't have to worry about the special cases. Fixes Issue 180 --- lib/grammar.js | 6 +++--- lib/nodes.js | 15 ++------------- lib/parser.js | 6 +++--- src/grammar.coffee | 6 +++--- src/nodes.coffee | 15 +-------------- test/test_assignment.coffee | 8 +++++++- 6 files changed, 19 insertions(+), 37 deletions(-) diff --git a/lib/grammar.js b/lib/grammar.js index d34384d9..a1e7c576 100644 --- a/lib/grammar.js +++ b/lib/grammar.js @@ -264,7 +264,7 @@ }), o("Range", function() { return new ValueNode($1); }), o("This", function() { - return new ValueNode($1); + return $1; }), o("Value Accessor", function() { return $1.push($2); }), o("Invocation Accessor", function() { @@ -340,9 +340,9 @@ ], // This references, either naked or to a property. This: [o("@", function() { - return new ThisNode(); + return new ValueNode(new LiteralNode('this')); }), o("@ Identifier", function() { - return new ThisNode($2); + return new ValueNode(new LiteralNode('this'), [new AccessorNode($2)]); }) ], // The range literal. diff --git a/lib/nodes.js b/lib/nodes.js index ba3d1381..d6624cf3 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1,5 +1,5 @@ (function(){ - var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, Node, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThisNode, ThrowNode, TryNode, ValueNode, WhileNode, compact, del, flatten, inherit, merge, statement; + var AccessorNode, ArrayNode, AssignNode, CallNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IfNode, IndexNode, LiteralNode, Node, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, ValueNode, WhileNode, compact, del, flatten, inherit, merge, statement; var __hasProp = Object.prototype.hasOwnProperty; (typeof process !== "undefined" && process !== null) ? process.mixin(require('scope')) : (this.exports = this); // Some helper functions @@ -327,7 +327,7 @@ return this; }, has_properties: function has_properties() { - return this.properties.length || this.base instanceof ThisNode; + return !!this.properties.length; }, is_array: function is_array() { return this.base instanceof ArrayNode && !this.has_properties(); @@ -524,17 +524,6 @@ return '[' + this.index.compile(o) + ']'; } })); - // A this-reference, using '@'. - ThisNode = (exports.ThisNode = inherit(Node, { - type: 'This', - constructor: function constructor(property) { - this.property = property || null; - return this; - }, - compile_node: function compile_node(o) { - return 'this' + (this.property ? '.' + this.property.compile(o) : ''); - } - })); // A range literal. Ranges can be used to extract portions (slices) of arrays, // or to specify a range for list comprehensions. RangeNode = (exports.RangeNode = inherit(Node, { diff --git a/lib/parser.js b/lib/parser.js index 082435a1..6eeb5cf2 100755 --- a/lib/parser.js +++ b/lib/parser.js @@ -227,7 +227,7 @@ case 108:this.$ = new ValueNode($$[$0-1+1-1]); break; case 109:this.$ = new ValueNode($$[$0-1+1-1]); break; -case 110:this.$ = new ValueNode($$[$0-1+1-1]); +case 110:this.$ = $$[$0-1+1-1]; break; case 111:this.$ = $$[$0-2+1-1].push($$[$0-2+2-1]); break; @@ -275,9 +275,9 @@ case 132:this.$ = $$[$0-3+2-1]; break; case 133:this.$ = new CallNode('super', $$[$0-4+3-1]); break; -case 134:this.$ = new ThisNode(); +case 134:this.$ = new ValueNode(new LiteralNode('this')); break; -case 135:this.$ = new ThisNode($$[$0-2+2-1]); +case 135:this.$ = new ValueNode(new LiteralNode('this'), [new AccessorNode($$[$0-2+2-1])]); break; case 136:this.$ = new RangeNode($$[$0-6+2-1], $$[$0-6+5-1]); break; diff --git a/src/grammar.coffee b/src/grammar.coffee index cf7426be..9965a79f 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -234,7 +234,7 @@ grammar: { o "Object", -> new ValueNode($1) o "Parenthetical", -> new ValueNode($1) o "Range", -> new ValueNode($1) - o "This", -> new ValueNode($1) + o "This", -> $1 o "Value Accessor", -> $1.push($2) o "Invocation Accessor", -> new ValueNode($1, [$2]) ] @@ -298,8 +298,8 @@ grammar: { # This references, either naked or to a property. This: [ - o "@", -> new ThisNode() - o "@ Identifier", -> new ThisNode($2) + o "@", -> new ValueNode(new LiteralNode('this')) + o "@ Identifier", -> new ValueNode(new LiteralNode('this'), [new AccessorNode($2)]) ] # The range literal. diff --git a/src/nodes.coffee b/src/nodes.coffee index 3cdb2499..f0ea8613 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -240,7 +240,7 @@ ValueNode: exports.ValueNode: inherit Node, { this has_properties: -> - @properties.length or @base instanceof ThisNode + !!@properties.length is_array: -> @base instanceof ArrayNode and not @has_properties() @@ -423,19 +423,6 @@ IndexNode: exports.IndexNode: inherit Node, { } -# A this-reference, using '@'. -ThisNode: exports.ThisNode: inherit Node, { - type: 'This' - - constructor: (property) -> - @property: property or null - this - - compile_node: (o) -> - 'this' + (if @property then '.' + @property.compile(o) else '') - -} - # A range literal. Ranges can be used to extract portions (slices) of arrays, # or to specify a range for list comprehensions. RangeNode: exports.RangeNode: inherit Node, { diff --git a/test/test_assignment.coffee b/test/test_assignment.coffee index 1a634a7f..7fdb6129 100644 --- a/test/test_assignment.coffee +++ b/test/test_assignment.coffee @@ -16,4 +16,10 @@ ok x is 10, 'can assign a conditional statement' x: if get_x() then 100 -ok x is 100, 'can assign a conditional statement' \ No newline at end of file +ok x is 100, 'can assign a conditional statement' + +tester: -> + @example: -> puts 'example function' + this + +ok tester().example.name is 'example' \ No newline at end of file