coffee-script 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'coffee-script'
3
- s.version = '0.2.3' # Keep version in sync with coffee-script.rb
4
- s.date = '2010-1-10'
3
+ s.version = '0.2.4' # Keep version in sync with coffee-script.rb
4
+ s.date = '2010-1-12'
5
5
 
6
6
  s.homepage = "http://jashkenas.github.com/coffee-script/"
7
7
  s.summary = "The CoffeeScript Compiler"
data/lib/coffee-script.rb CHANGED
@@ -10,7 +10,7 @@ require "coffee_script/parse_error"
10
10
  # Namespace for all CoffeeScript internal classes.
11
11
  module CoffeeScript
12
12
 
13
- VERSION = '0.2.3' # Keep in sync with the gemspec.
13
+ VERSION = '0.2.4' # Keep in sync with the gemspec.
14
14
 
15
15
  # Compile a script (String or IO) to JavaScript.
16
16
  def self.compile(script, options={})
@@ -93,6 +93,30 @@
93
93
  <key>name</key>
94
94
  <string>constant.numeric.coffee</string>
95
95
  </dict>
96
+ <dict>
97
+ <key>name</key>
98
+ <string>string.quoted.heredoc.coffee</string>
99
+ <key>begin</key>
100
+ <string>("""|''')</string>
101
+ <key>end</key>
102
+ <string>("""|''')</string>
103
+ <key>beginCaptures</key>
104
+ <dict>
105
+ <key>0</key>
106
+ <dict>
107
+ <key>name</key>
108
+ <string>punctuation.definition.string.begin.coffee</string>
109
+ </dict>
110
+ </dict>
111
+ <key>endCaptures</key>
112
+ <dict>
113
+ <key>0</key>
114
+ <dict>
115
+ <key>name</key>
116
+ <string>punctuation.definition.string.end.coffee</string>
117
+ </dict>
118
+ </dict>
119
+ </dict>
96
120
  <dict>
97
121
  <key>begin</key>
98
122
  <string>'</string>
@@ -22,6 +22,7 @@ module CoffeeScript
22
22
  IDENTIFIER = /\A([a-zA-Z$_](\w|\$)*)/
23
23
  NUMBER = /\A(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i
24
24
  STRING = /\A(""|''|"(.*?)([^\\]|\\\\)"|'(.*?)([^\\]|\\\\)')/m
25
+ HEREDOC = /\A("{6}|'{6}|"{3}\n?(\s*)(.*?)\n?(\s*)"{3}|'{3}\n?(\s*)(.*?)\n?(\s*)'{3})/m
25
26
  JS = /\A(``|`(.*?)([^\\]|\\\\)`)/m
26
27
  OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/
27
28
  WHITESPACE = /\A([ \t]+)/
@@ -69,6 +70,7 @@ module CoffeeScript
69
70
  def extract_next_token
70
71
  return if identifier_token
71
72
  return if number_token
73
+ return if heredoc_token
72
74
  return if string_token
73
75
  return if js_token
74
76
  return if regex_token
@@ -87,7 +89,7 @@ module CoffeeScript
87
89
  # 'if' will result in an [:IF, "if"] token.
88
90
  tag = KEYWORDS.include?(identifier) ? identifier.upcase.to_sym : :IDENTIFIER
89
91
  tag = :LEADING_WHEN if tag == :WHEN && [:OUTDENT, :INDENT, "\n"].include?(last_tag)
90
- @tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.' && !(@tokens[-2][1] == '.')
92
+ @tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.' && !(@tokens[-2] && @tokens[-2][1] == '.')
91
93
  @tokens[-1][0] = :PROTOTYPE_ACCESS if tag == :IDENTIFIER && last_value == '::'
92
94
  token(tag, identifier)
93
95
  @i += identifier.length
@@ -103,14 +105,24 @@ module CoffeeScript
103
105
  # Matches strings, including multi-line strings.
104
106
  def string_token
105
107
  return false unless string = @chunk[STRING, 1]
106
- escaped = string.gsub(MULTILINER) do |match|
107
- @line += 1
108
- " \\\n"
109
- end
108
+ escaped = string.gsub(MULTILINER, " \\\n")
110
109
  token(:STRING, escaped)
110
+ @line += string.count("\n")
111
111
  @i += string.length
112
112
  end
113
113
 
114
+ # Matches heredocs, adjusting indentation to the correct level.
115
+ def heredoc_token
116
+ return false unless match = @chunk.match(HEREDOC)
117
+ indent = match[2] || match[5]
118
+ doc = match[3] || match[6]
119
+ doc.gsub!(/\n#{indent}/, "\\n")
120
+ doc.gsub!('"', '\\"')
121
+ token(:STRING, "\"#{doc}\"")
122
+ @line += match[1].count("\n")
123
+ @i += match[1].length
124
+ end
125
+
114
126
  # Matches interpolated JavaScript.
115
127
  def js_token
116
128
  return false unless script = @chunk[JS, 1]
@@ -320,6 +320,18 @@ module CoffeeScript
320
320
  return !@properties.empty?
321
321
  end
322
322
 
323
+ def array?
324
+ @base.is_a?(ArrayNode) && !properties?
325
+ end
326
+
327
+ def object?
328
+ @base.is_a?(ObjectNode) && !properties?
329
+ end
330
+
331
+ def splice?
332
+ properties? && @properties.last.is_a?(SliceNode)
333
+ end
334
+
323
335
  # Values are statements if their base is a statement.
324
336
  def statement?
325
337
  @base.is_a?(Node) && @base.statement? && !properties?
@@ -435,7 +447,9 @@ module CoffeeScript
435
447
  end
436
448
 
437
449
  def compile_node(o)
438
- return compile_splice(o) if @variable.properties.last.is_a?(SliceNode)
450
+ return compile_pattern_match(o) if @variable.array? || @variable.object?
451
+ return compile_splice(o) if @variable.splice?
452
+ stmt = o.delete(:as_statement)
439
453
  name = @variable.compile(o)
440
454
  last = @variable.last.to_s.sub(LEADING_DOT, '')
441
455
  proto = name[PROTO_ASSIGN, 1]
@@ -444,9 +458,31 @@ module CoffeeScript
444
458
  return write("#{name}: #{@value.compile(o)}") if @context == :object
445
459
  o[:scope].find(name) unless @variable.properties?
446
460
  val = "#{name} = #{@value.compile(o)}"
461
+ return write("#{idt}#{val};") if stmt
447
462
  write(o[:return] ? "#{idt}return (#{val})" : val)
448
463
  end
449
464
 
465
+ def statement?
466
+ @variable.array? || @variable.object?
467
+ end
468
+
469
+ # Implementation of recursive pattern matching, when assigning array or
470
+ # object literals to a value. Peeks at their properties to assign inner names.
471
+ # See: http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
472
+ def compile_pattern_match(o)
473
+ val_var = o[:scope].free_variable
474
+ assigns = ["#{idt}#{val_var} = #{@value.compile(o)};"]
475
+ o.merge!(:top => true, :as_statement => true)
476
+ @variable.base.objects.each_with_index do |obj, i|
477
+ obj, i = obj.value, obj.variable.base if @variable.object?
478
+ access_class = @variable.array? ? IndexNode : AccessorNode
479
+ assigns << AssignNode.new(
480
+ obj, ValueNode.new(Value.new(val_var), [access_class.new(Value.new(i.to_s))])
481
+ ).compile(o)
482
+ end
483
+ write(assigns.join("\n"))
484
+ end
485
+
450
486
  def compile_splice(o)
451
487
  var = @variable.compile(o.merge(:only_first => true))
452
488
  range = @variable.properties.last.range
@@ -564,6 +600,7 @@ module CoffeeScript
564
600
  # An object literal.
565
601
  class ObjectNode < Node
566
602
  attr_reader :properties
603
+ alias_method :objects, :properties
567
604
 
568
605
  def initialize(properties = [])
569
606
  @properties = properties
@@ -655,9 +692,9 @@ module CoffeeScript
655
692
  name_found = @name && scope.find(@name)
656
693
  index_found = @index && scope.find(@index)
657
694
  body_dent = idt(1)
695
+ rvar = scope.free_variable unless top_level
658
696
  svar = scope.free_variable
659
697
  ivar = range ? name : @index ? @index : scope.free_variable
660
- rvar = scope.free_variable unless top_level
661
698
  if range
662
699
  index_var = scope.free_variable
663
700
  source_part = source.compile_variables(o)
data/package.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "description": "Unfancy JavaScript",
6
6
  "keywords": ["javascript", "language"],
7
7
  "author": "Jeremy Ashkenas",
8
- "version": "0.2.3"
8
+ "version": "0.2.4"
9
9
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coffee-script
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Ashkenas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-10 00:00:00 -05:00
12
+ date: 2010-01-12 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15