self-compiler: handles try/catch/finally blocks

This commit is contained in:
Jeremy Ashkenas
2010-02-10 18:33:03 -05:00
parent 76dac9c09c
commit 4e7408dc25
5 changed files with 220 additions and 183 deletions

View File

@@ -805,7 +805,25 @@ OpNode: exports.OpNode: inherit Node, {
}
# A try/catch/finally block.
TryNode: exports.TryNode: inherit Node, {
constructor: (attempt, error, recovery, ensure) ->
@children: [@attempt: attempt, @recovery: recovery, @ensure: ensure]
@error: error
this
compile_node: (o) ->
o.indent: @idt(1)
o.top: true
error_part: if @error then ' (' + @error.compile(o) + ') ' else ' '
catch_part: (@recovery or '') and ' catch' + error_part + '{\n' + @recovery.compile(o) + '\n' + @idt() + '}'
finally_part: (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o, {returns: null})) + '\n' + @idt() + '}'
@idt() + 'try {\n' + @attempt.compile(o) + '\n' + @idt() + '}' + catch_part + finally_part
}
statement TryNode

View File

@@ -17,25 +17,25 @@ o: (pattern_string, func, options) ->
# Precedence ===========================================================
operators: [
["left", '?']
["right", 'UMINUS', 'UPLUS', 'NOT', '!', '!!', '~', '++', '--']
["left", '*', '/', '%']
["left", '+', '-']
["left", '<<', '>>', '>>>']
["left", '&', '|', '^']
["left", '<=', '<', '>', '>=']
["right", 'DELETE', 'INSTANCEOF', 'TYPEOF']
["right", '==', '!=', 'IS', 'ISNT']
["left", '&&', '||', 'AND', 'OR']
["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=']
["left", '.']
["right", 'INDENT']
["left", 'OUTDENT']
["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY']
["right", 'THROW', 'FOR', 'NEW', 'SUPER']
["left", 'EXTENDS']
["right", 'ASSIGN', 'RETURN']
["right", '->', '=>', 'UNLESS', 'IF', 'ELSE', 'WHILE']
["left", '?']
["nonassoc", 'UMINUS', 'UPLUS', 'NOT', '!', '!!', '~', '++', '--']
["left", '*', '/', '%']
["left", '+', '-']
["left", '<<', '>>', '>>>']
["left", '&', '|', '^']
["left", '<=', '<', '>', '>=']
["right", 'DELETE', 'INSTANCEOF', 'TYPEOF']
["right", '==', '!=', 'IS', 'ISNT']
["left", '&&', '||', 'AND', 'OR']
["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=']
["left", '.']
["right", 'INDENT']
["left", 'OUTDENT']
["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY']
["right", 'THROW', 'FOR', 'NEW', 'SUPER']
["left", 'EXTENDS']
["right", 'ASSIGN', 'RETURN']
["right", '->', '=>', 'UNLESS', 'IF', 'ELSE', 'WHILE']
]
# Grammar ==============================================================
@@ -138,60 +138,59 @@ grammar: {
# https://www.cs.auckland.ac.nz/references/ruby/ProgrammingRuby/language.html
Operation: [
o "! Expression", -> new OpNode('!', $2)
o "!! Expression", -> new OpNode('!!', $2)
# o "!! Expression", -> new OpNode('!!', $2)
o "- Expression", (-> new OpNode('-', $2)), {prec: 'UMINUS'}
o "+ Expression", (-> new OpNode('+', $2)), {prec: 'UPLUS'}
# o "+ Expression", (-> new OpNode('+', $2)), {prec: 'UPLUS'}
o "NOT Expression", -> new OpNode('not', $2)
o "~ Expression", -> new OpNode('~', $2)
o "-- Expression", -> new OpNode('--', $2)
o "++ Expression", -> new OpNode('++', $2)
# o "~ Expression", -> new OpNode('~', $2)
# o "-- Expression", -> new OpNode('--', $2)
# o "++ Expression", -> new OpNode('++', $2)
o "DELETE Expression", -> new OpNode('delete', $2)
o "TYPEOF Expression", -> new OpNode('typeof', $2)
o "Expression --", -> new OpNode('--', $1, null, true)
o "Expression ++", -> new OpNode('++', $1, null, true)
# o "Expression --", -> new OpNode('--', $1, null, true)
# o "Expression ++", -> new OpNode('++', $1, null, true)
o "Expression * Expression", -> new OpNode('*', $1, $3)
o "Expression / Expression", -> new OpNode('/', $1, $3)
o "Expression % Expression", -> new OpNode('%', $1, $3)
# o "Expression % Expression", -> new OpNode('%', $1, $3)
o "Expression + Expression", -> new OpNode('+', $1, $3)
o "Expression - Expression", -> new OpNode('-', $1, $3)
o "Expression << Expression", -> new OpNode('<<', $1, $3)
o "Expression >> Expression", -> new OpNode('>>', $1, $3)
o "Expression >>> Expression", -> new OpNode('>>>', $1, $3)
o "Expression & Expression", -> new OpNode('&', $1, $3)
o "Expression | Expression", -> new OpNode('|', $1, $3)
o "Expression ^ Expression", -> new OpNode('^', $1, $3)
# o "Expression << Expression", -> new OpNode('<<', $1, $3)
# o "Expression >> Expression", -> new OpNode('>>', $1, $3)
# o "Expression >>> Expression", -> new OpNode('>>>', $1, $3)
# o "Expression & Expression", -> new OpNode('&', $1, $3)
# o "Expression | Expression", -> new OpNode('|', $1, $3)
# o "Expression ^ Expression", -> new OpNode('^', $1, $3)
o "Expression <= Expression", -> new OpNode('<=', $1, $3)
o "Expression < Expression", -> new OpNode('<', $1, $3)
o "Expression > Expression", -> new OpNode('>', $1, $3)
o "Expression >= Expression", -> new OpNode('>=', $1, $3)
o "Expression == Expression", -> new OpNode('==', $1, $3)
# o "Expression != Expression", -> new OpNode($2, $1, $3)
# o "Expression IS Expression", -> new OpNode($2, $1, $3)
# o "Expression ISNT Expression", -> new OpNode($2, $1, $3)
#
# o "Expression && Expression", -> new OpNode($2, $1, $3)
# o "Expression || Expression", -> new OpNode($2, $1, $3)
# o "Expression AND Expression", -> new OpNode($2, $1, $3)
# o "Expression OR Expression", -> new OpNode($2, $1, $3)
# o "Expression ? Expression", -> new OpNode($2, $1, $3)
#
# o "Expression -= Expression", -> new OpNode($2, $1, $3)
# o "Expression += Expression", -> new OpNode($2, $1, $3)
# o "Expression == Expression", -> new OpNode('==', $1, $3)
# o "Expression != Expression", -> new OpNode($2, $1, $3)
o "Expression IS Expression", -> new OpNode($2, $1, $3)
o "Expression ISNT Expression", -> new OpNode($2, $1, $3)
# o "Expression && Expression", -> new OpNode($2, $1, $3)
# o "Expression || Expression", -> new OpNode($2, $1, $3)
o "Expression AND Expression", -> new OpNode($2, $1, $3)
o "Expression OR Expression", -> new OpNode($2, $1, $3)
o "Expression ? Expression", -> new OpNode($2, $1, $3)
o "Expression -= Expression", -> new OpNode($2, $1, $3)
o "Expression += Expression", -> new OpNode($2, $1, $3)
# o "Expression /= Expression", -> new OpNode($2, $1, $3)
# o "Expression *= Expression", -> new OpNode($2, $1, $3)
# o "Expression %= Expression", -> new OpNode($2, $1, $3)
# o "Expression ||= Expression", -> new OpNode($2, $1, $3)
# o "Expression &&= Expression", -> new OpNode($2, $1, $3)
# o "Expression ?= Expression", -> new OpNode($2, $1, $3)
#
# o "Expression INSTANCEOF Expression", -> new OpNode($2, $1, $3)
# o "Expression IN Expression", -> new OpNode($2, $1, $3)
o "Expression ||= Expression", -> new OpNode($2, $1, $3)
o "Expression &&= Expression", -> new OpNode($2, $1, $3)
# o "Expression ?= Expression", -> new OpNode($2, $1, $3)
o "Expression INSTANCEOF Expression", -> new OpNode($2, $1, $3)
# o "Expression IN Expression", -> new OpNode($2, $1, $3)
]
# The existence operator.