Created
March 18, 2010 16:41
-
-
Save StanAngeloff/336542 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/grammar.coffee b/src/grammar.coffee | |
index 0c98198..d77293f 100644 | |
--- a/src/grammar.coffee | |
+++ b/src/grammar.coffee | |
@@ -306,6 +306,7 @@ grammar: { | |
Slice: [ | |
o "INDEX_START Expression . . Expression INDEX_END", -> new RangeNode $2, $5 | |
o "INDEX_START Expression . . . Expression INDEX_END", -> new RangeNode $2, $6, true | |
+ o "[ Expression : Expression : Expression ]", -> new SteppingRangeNode $2, $4, $6 | |
] | |
# The array literal. | |
diff --git a/src/nodes.coffee b/src/nodes.coffee | |
index a277c41..2b7cad2 100644 | |
--- a/src/nodes.coffee | |
+++ b/src/nodes.coffee | |
@@ -513,6 +513,45 @@ exports.RangeNode: class RangeNode extends BaseNode | |
arr: Expressions.wrap([new ForNode(body, {source: (new ValueNode(this))}, literal(name))]) | |
(new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o) | |
+#### SteppingRangeNode | |
+ | |
+# A Python-like slice literal. | |
+exports.SteppingRangeNode: class SteppingRangeNode extends BaseNode | |
+ type: 'SteppingRange' | |
+ | |
+ constructor: (start, end, step) -> | |
+ @children: [@start: start, @end: end, @step: step] | |
+ | |
+ # Compiles the range's source variables -- where it starts and where it ends. | |
+ # TODO: compile_variables: (o) -> | |
+ # TODO: @tab: o.indent | |
+ # TODO: [@from_var, @to_var]: [o.scope.free_variable(), o.scope.free_variable()] | |
+ # TODO: [from, to]: [@from.compile(o), @to.compile(o)] | |
+ # TODO: "$@from_var = $from; $@to_var = $to;\n$@tab" | |
+ | |
+ # When compiled normally, the range returns the contents of the *for loop* | |
+ # needed to iterate over the values in the range. Used by comprehensions. | |
+ # TODO: compile_node: (o) -> | |
+ # TODO: return @compile_array(o) unless o.index | |
+ # TODO: idx: del o, 'index' | |
+ # TODO: step: del o, 'step' | |
+ # TODO: vars: "$idx = $@from_var" | |
+ # TODO: step: if step then step.compile(o) else '1' | |
+ # TODO: equals: if @exclusive then '' else '=' | |
+ # TODO: intro: "($@from_var <= $@to_var ? $idx" | |
+ # TODO: compare: "$intro <$equals $@to_var : $idx >$equals $@to_var)" | |
+ # TODO: incr: "$intro += $step : $idx -= $step)" | |
+ # TODO: "$vars; $compare; $incr" | |
+ | |
+ # When used as a value, expand the range into the equivalent array. In the | |
+ # future, the code this generates should probably be cleaned up by handwriting | |
+ # it instead of wrapping nodes. | |
+ # TODO: compile_array: (o) -> | |
+ # TODO: name: o.scope.free_variable() | |
+ # TODO: body: Expressions.wrap([literal(name)]) | |
+ # TODO: arr: Expressions.wrap([new ForNode(body, {source: (new ValueNode(this))}, literal(name))]) | |
+ # TODO: (new ParentheticalNode(new CallNode(new CodeNode([], arr)))).compile(o) | |
+ | |
#### SliceNode | |
# An array slice literal. Unlike JavaScript's `Array#slice`, the second parameter | |
@@ -525,12 +564,21 @@ exports.SliceNode: class SliceNode extends BaseNode | |
@children: [@range: range] | |
this | |
- compile_node: (o) -> | |
+ compile_range: (o) -> | |
from: @range.from.compile(o) | |
to: @range.to.compile(o) | |
plus_part: if @range.exclusive then '' else ' + 1' | |
".slice($from, $to$plus_part)" | |
+ compile_stepping_range: (o) -> | |
+ "// Look ma !" | |
+ | |
+ compile_node: (o) -> | |
+ if @range instanceof RangeNode | |
+ @compile_range o | |
+ else if @range instanceof SteppingRange | |
+ @compile_stepping_range o | |
+ | |
#### ObjectNode | |
# An object literal, nothing fancy. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment