coffee-script 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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