1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

with shelling out to javascript

This commit is contained in:
Jeremy Ashkenas 2009-12-15 09:11:27 -05:00
parent 5dd295bd08
commit f7a0bf19cb
4 changed files with 809 additions and 695 deletions

View file

@ -1,9 +1,9 @@
# TODO: switch/case statements
# Flow: For loops, etc.
# ++ and -- (prefix and postfix)
# postfix ifs and unlesses
# Fix array comprehensions -- they're mad busted.
# Start looking up all free assignments in scope -- to var or not to var.
# Literal javascript interpolation.
# Think of a name for this crazy thing.
# Functions:
@ -65,6 +65,11 @@ wine &&= cheese
# Nested property access and calls.
((moon.turn(360))).shapes[3].move({x: 45, y: 30}).position
# Embedded JavaScript.
callback(
`function(e) { e.stop(); }`
)
# Try/Catch/Finally/Throw.
try
all_hell_breaks_loose()

View file

@ -10,6 +10,7 @@ token TRY CATCH FINALLY THROW
token BREAK CONTINUE
token FOR IN WHILE
token NEWLINE
token JS
prechigh
nonassoc UMINUS NOT '!'
@ -82,6 +83,7 @@ rule
Literal:
NUMBER { result = LiteralNode.new(val[0]) }
| STRING { result = LiteralNode.new(val[0]) }
| JS { result = LiteralNode.new(val[0]) }
| REGEX { result = LiteralNode.new(val[0]) }
| TRUE { result = LiteralNode.new(true) }
| FALSE { result = LiteralNode.new(false) }
@ -179,16 +181,6 @@ rule
| ObjectStart AssignList ObjectEnd { result = ObjectNode.new(val[1]) }
;
ObjectStart:
"{" { result = nil }
| "{" "\n" { result = nil }
;
ObjectEnd:
"}" { result = nil }
| "\n" "}" { result = nil }
;
AssignList:
/* nothing */ { result = []}
| AssignObj { result = val }
@ -203,12 +195,12 @@ rule
;
Invocation:
Value "(" ArgList ")" { result = CallNode.new(val[0], val[2]) }
Value ParenStart ArgList ParenEnd { result = CallNode.new(val[0], val[2]) }
;
# An Array.
Array:
"[" ArgList "]" { result = ArrayNode.new(val[1]) }
ArrayStart ArgList ArrayEnd { result = ArrayNode.new(val[1]) }
;
# A list of arguments to a method call.
@ -244,7 +236,7 @@ rule
;
Parenthetical:
"(" Expressions ")" { result = ParentheticalNode.new(val[1]) }
ParenStart Expressions ParenEnd { result = ParentheticalNode.new(val[1]) }
;
While:
@ -260,6 +252,36 @@ rule
IF Expression "." { result = ForNode.new(IfNode.new(val[6], Nodes.new([val[0]])), val[2], val[4]) }
;
ObjectStart:
"{" { result = nil }
| "{" "\n" { result = nil }
;
ObjectEnd:
"}" { result = nil }
| "\n" "}" { result = nil }
;
ParenStart:
"(" { result = nil }
| "(" "\n" { result = nil }
;
ParenEnd:
")" { result = nil }
| "\n" ")" { result = nil }
;
ArrayStart:
"[" { result = nil }
| "[" "\n" { result = nil }
;
ArrayEnd:
"]" { result = nil }
| "\n" "]" { result = nil }
;
end
---- header

View file

@ -11,6 +11,7 @@ class Lexer
IDENTIFIER = /\A([a-zA-Z$_]\w*)/
NUMBER = /\A([0-9]+(\.[0-9]+)?)/
STRING = /\A("(.*?)"|'(.*?)')/
JS = /\A(`(.*?)`)/
OPERATOR = /\A([+\*&|\/\-%=<>]+)/
WHITESPACE = /\A([ \t\r]+)/
NEWLINE = /\A([\r\n]+)/
@ -18,6 +19,8 @@ class Lexer
CODE = /\A(=>)/
REGEX = /\A(\/(.*?)\/[imgy]{0,4})/
JS_CLEANER = /(\A`|`\Z)/
# This is how to implement a very simple scanner.
# Scan one caracter at the time until you find something to parse.
def tokenize(code)
@ -35,6 +38,7 @@ class Lexer
return if identifier_token
return if number_token
return if string_token
return if js_token
return if regex_token
return if remove_comment
return if whitespace_token
@ -67,6 +71,12 @@ class Lexer
@i += string.length
end
def js_token
return false unless script = @chunk[JS, 1]
@tokens << [:JS, script.gsub(JS_CLEANER, '')]
@i += script.length
end
def regex_token
return false unless regex = @chunk[REGEX, 1]
@tokens << [:REGEX, regex]

1439
parser.rb

File diff suppressed because it is too large Load diff