diff --git a/Rakefile b/Rakefile
index 432a9d16..0616f0fc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -17,8 +17,16 @@ end
desc "Build the documentation page"
task :doc do
- rendered = ERB.new(File.read('documentation/index.html.erb')).result(binding)
- File.open('index.html', 'w+') {|f| f.write(rendered) }
+ source = 'documentation/index.html.erb'
+ loop do
+ mtime = File.stat(source).mtime
+ if !@mtime || mtime > @mtime
+ rendered = ERB.new(File.read(source)).result(binding)
+ File.open('index.html', 'w+') {|f| f.write(rendered) }
+ end
+ @mtime = mtime
+ sleep 1
+ end
end
namespace :gem do
diff --git a/TODO b/TODO
index 7761c3a3..7ec3b61e 100644
--- a/TODO
+++ b/TODO
@@ -7,10 +7,12 @@ TODO:
* Figure out a generic way to transform statements into expressions, and
use it recursively for returns and assigns on whiles, fors, ifs, etc.
-* If we manage to get array comprehensions working ... object comprehensions?
-
* Create the documentation page. (amy, idle)
uv -c . -s coffeescript -t amy --no-lines examples/code.cs > code.html
+
+* Object comprehensions would be easy to add to array comprehensions -- if
+ we knew that the variable in question is, indeed, an object. Check for
+ length? Special syntax to tag it?
* Is it possible to close blocks (functions, ifs, trys) without an explicit
block delimiter or significant whitespace?
diff --git a/documentation/css/docs.css b/documentation/css/docs.css
new file mode 100644
index 00000000..f50ad3b1
--- /dev/null
+++ b/documentation/css/docs.css
@@ -0,0 +1,59 @@
+body {
+ font-size: 16px;
+ line-height: 24px;
+ background: #f0f0e5;
+ color: #252519;
+ font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+}
+div.container {
+ width: 720px;
+ margin: 50px 0 50px 50px;
+}
+p {
+ width: 550px;
+}
+ #documentation p {
+ margin-bottom: 4px;
+ }
+a, a:visited {
+ padding: 0 2px;
+ text-decoration: none;
+ background: #dadaba;
+ color: #252519;
+}
+a:active, a:hover {
+ color: #000;
+ background: #f0c095;
+}
+h1, h2, h3, h4, h5, h6 {
+ margin-top: 40px;
+}
+b.header {
+ font-size: 18px;
+}
+span.alias {
+ font-size: 14px;
+ font-style: italic;
+ margin-left: 20px;
+}
+table, tr, td {
+ margin: 0; padding: 0;
+}
+ td {
+ padding: 2px 12px 2px 0;
+ }
+code, pre, tt {
+ font-family: Monaco, Consolas, "Lucida Console", monospace;
+ font-size: 12px;
+ line-height: 18px;
+ color: #555529;
+}
+ code {
+ margin-left: 20px;
+ }
+ pre {
+ font-size: 12px;
+ padding: 2px 0 2px 12px;
+ border-left: 6px solid #aaaa99;
+ margin: 0px 0 30px;
+ }
\ No newline at end of file
diff --git a/documentation/index.html.erb b/documentation/index.html.erb
new file mode 100644
index 00000000..cb032b44
--- /dev/null
+++ b/documentation/index.html.erb
@@ -0,0 +1,23 @@
+
+
+
+
+ CoffeeScript
+
+
+
+
+
+
+
CoffeeScript
+
+
+ CoffeeScript is a little language that compiles into JavaScript. Think
+ of it as JavaScript's simpleminded kid brother — the same genes,
+ the same accent, but another kind of way of doing things.
+
+ CoffeeScript is a little language that compiles into JavaScript. Think
+ of it as JavaScript's simpleminded kid brother — the same genes,
+ the same accent, but another kind of way of doing things.
+
+
+
+
+
+
diff --git a/lib/coffee_script/command_line.rb b/lib/coffee_script/command_line.rb
index bee6e079..105292dd 100644
--- a/lib/coffee_script/command_line.rb
+++ b/lib/coffee_script/command_line.rb
@@ -23,6 +23,7 @@ Usage:
def initialize
@mtimes = {}
parse_options
+ return eval_scriptlet if @options[:eval]
check_sources
@sources.each {|source| compile_javascript(source) }
watch_coffee_scripts if @options[:watch]
@@ -88,6 +89,11 @@ Usage:
stdout.close and stderr.close
end
+ # Eval a little piece of CoffeeScript directly from the command line.
+ def eval_scriptlet
+ puts CoffeeScript.compile(@sources.join(' '))
+ end
+
# Print the tokens that the lexer generates from a source script.
def tokens(source)
puts Lexer.new.tokenize(File.read(source)).inspect
@@ -135,6 +141,9 @@ Usage:
opts.on('-l', '--lint', 'pipe the compiled JavaScript through JSLint') do |l|
@options[:lint] = true
end
+ opts.on('-e', '--eval', 'eval a little scriptlet directly from the cli') do |e|
+ @options[:eval] = true
+ end
opts.on('-t', '--tokens', 'print the tokens that the lexer produces') do |t|
@options[:tokens] = true
end
diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y
index b7cdfc21..39be9602 100644
--- a/lib/coffee_script/grammar.y
+++ b/lib/coffee_script/grammar.y
@@ -17,9 +17,11 @@ token JS
# Declare order of operations.
prechigh
- nonassoc UMINUS NOT '!'
+ nonassoc UMINUS NOT '!' '~'
left '*' '/' '%'
left '+' '-'
+ left '<<' '>>' '>>>'
+ left '&' '|' '^'
left '<=' '<' '>' '>='
right '==' '!=' IS AINT
left '&&' '||' AND OR
@@ -127,6 +129,7 @@ rule
'!' Expression { result = OpNode.new(val[0], val[1]) }
| '-' Expression = UMINUS { result = OpNode.new(val[0], val[1]) }
| NOT Expression { result = OpNode.new(val[0], val[1]) }
+ | '~' Expression { result = OpNode.new(val[0], val[1]) }
| Expression '*' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '/' Expression { result = OpNode.new(val[1], val[0], val[2]) }
@@ -135,6 +138,14 @@ rule
| Expression '+' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '-' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+ | Expression '<<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+ | Expression '>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+ | Expression '>>>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+
+ | Expression '&' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+ | Expression '|' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+ | Expression '^' Expression { result = OpNode.new(val[1], val[0], val[2]) }
+
| Expression '<=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '<' Expression { result = OpNode.new(val[1], val[0], val[2]) }
| Expression '>' Expression { result = OpNode.new(val[1], val[0], val[2]) }
diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb
index 7825dbca..f91e7589 100644
--- a/lib/coffee_script/nodes.rb
+++ b/lib/coffee_script/nodes.rb
@@ -68,8 +68,8 @@ module CoffeeScript
"(function(){\n#{compile(TAB, Scope.new)}\n})();"
end
- # The extra fancy is to handle pushing down returns recursively to the
- # final lines of inner statements (so as to make expressions out of them).
+ # The extra fancy is to handle pushing down returns and assignments
+ # recursively to the final lines of inner statements.
def compile(indent='', scope=nil, opts={})
return root_compile unless scope
code = @expressions.map { |n|
@@ -171,7 +171,7 @@ module CoffeeScript
end
end
- # A value, indexed or dotted into or vanilla.
+ # A value, indexed or dotted into, or vanilla.
class ValueNode < Node
attr_reader :literal, :properties, :last