lib/minjs/statement.rb in minjs-0.2.2 vs lib/minjs/statement.rb in minjs-0.3.0
- old
+ new
@@ -5,468 +5,480 @@
module Statement
#
# check next literal is ';' or '}' or LT
#
def semicolon(lex, context)
- lex.eval_lit{
- a = lex.fwd_lit(:nolt => true)
- if a == ECMA262::PUNC_SEMICOLON
- a
- elsif a == ECMA262::PUNC_RCURLYBRAC
- lex.rewind_pos
- a
- elsif a == ECMA262::LIT_LINE_FEED
- a
- elsif a.nil?
- ECMA262::LIT_LINE_FEED
- elsif a.lt?
- a
- else
- nil
- end
- }
+ a = lex.peek_lit_nolt(nil)
+ # ; ?
+ if a == ECMA262::PUNC_SEMICOLON
+ lex.fwd_after_peek
+ a
+ # } ?
+ elsif a == ECMA262::PUNC_RCURLYBRAC
+ a
+ # line feed?
+ elsif a == ECMA262::LIT_LINE_FEED
+ lex.fwd_after_peek
+ a
+ # end of program
+ elsif a.nil?
+ lex.fwd_after_peek
+ ECMA262::LIT_LINE_FEED
+ # line terminator?
+ elsif a.lt?
+ lex.fwd_after_peek
+ a
+ else
+ nil
+ end
end
#12
def statement(lex, context)
- [:block,
- :var_statement,
- :if_statement,
- :iteration_statement,
- :continue_statement,
- :break_statement,
- :return_statement,
- :with_statement,
- :labelled_statement,
- :switch_statement,
- :throw_statement,
- :try_statement,
- :debugger_statement,
- :exp_statement,
- #
- # function declaration in statement(block) is not permitted by ECMA262.
- # however, almost all implementation permit it.
- #
- :func_declaration,
- :empty_statement,
- ].each do |f|
- t = lex.eval_lit {
- __send__(f, lex, context)
- }
- return t if t
- end
- nil
+ (
+ block(lex, context) or #12.1
+ var_statement(lex, context) or #12.2
+ if_statement(lex, context) or #12.5
+ iteration_statement(lex, context) or #12.6
+ continue_statement(lex, context) or #12.7
+ break_statement(lex, context) or #12.8
+ return_statement(lex, context) or #12.9
+ with_statement(lex, context) or #12.10
+ switch_statement(lex, context) or #12.11
+ labelled_statement(lex, context) or #12.12
+ throw_statement(lex, context) or #12.13
+ try_statement(lex, context) or #12.14
+ debugger_statement(lex, context) or #12.15
+ func_declaration(lex, context) or #13 => func.rb
+ exp_statement(lex, context) or #12.4
+ empty_statement(lex, context) #12.3
+ )
end
#
#12.1
# block
def block(lex, context)
pos0 = lex.pos
- return nil unless lex.match_lit(ECMA262::PUNC_LCURLYBRAC)
- if lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
+ return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
+ if lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
return ECMA262::StBlock.new(ECMA262::StatementList.new([]))
end
- lex.eval_lit {
- if s = statement_list(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
- ECMA262::StBlock.new(s)
- else
- raise ParseError.new('no "}" end of block', lex)
- end
- }
+
+ if s = statement_list(lex, context) and lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
+ ECMA262::StBlock.new(s)
+ else
+ raise ParseError.new('no "}" end of block', lex)
+ end
end
def statement_list(lex, context)
- lex.eval_lit {
- t = []
- while !lex.eof?
- if s = statement(lex, context)
- t.push(s)
- else
- break
- end
- end
- ECMA262::StatementList.new(t)
- }
+ t = []
+ while !lex.eof? and s = statement(lex, context)
+ t.push(s)
+ end
+ ECMA262::StatementList.new(t)
end
#
#12.2
# variable_statement
#
def var_statement(lex, context)
raise 'internal error' if context.nil?
- return nil unless lex.match_lit(ECMA262::ID_VAR)
- lex.eval_lit {
- if vl = var_decl_list(lex, context, {}) and semicolon(lex, context)
- #10.5
- vl.each do |v|
- dn = v[0]
- context.var_env.record.create_mutable_binding(dn, nil)
- context.var_env.record.set_mutable_binding(dn, :undefined, nil)
- context.lex_env.record.create_mutable_binding(dn, nil)
- context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
- end
- ECMA262::StVar.new(context, vl)
- else
- raise Minjs::ParseError.new("var_statement", lex)
+ return nil unless lex.eql_lit?(ECMA262::ID_VAR)
+
+ if vl = var_decl_list(lex, context, {}) and semicolon(lex, context)
+ #10.5
+ vl.each do |v|
+ dn = v[0]
+ context.var_env.record.create_mutable_binding(dn, nil)
+ context.var_env.record.set_mutable_binding(dn, :undefined, nil)
+ context.lex_env.record.create_mutable_binding(dn, nil)
+ context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
end
- }
+ ECMA262::StVar.new(context, vl)
+ else
+ raise Minjs::ParseError.new("unexpected token", lex)
+ end
end
-
+ # 12.2
+ #
+ # VariableDeclarationList :
+ # VariableDeclaration
+ # VariableDeclarationList , VariableDeclaration
+ #
def var_decl_list(lex, context, options)
- lex.eval_lit {
- a = var_decl(lex, context, options)
- next nil if !a
+ list = []
+ list.push(var_decl(lex, context, options))
- if lex.match_lit(ECMA262::PUNC_COMMA) and b = var_decl_list(lex, context, options)
- next [a] + b
- else
- next [a]
- end
- }
+ while lex.eql_lit?(ECMA262::PUNC_COMMA) and b = var_decl(lex, context, options)
+ list.push(b)
+ end
+ list
end
+ # 12.2
+ #
+ # VariableDeclaration :
+ # Identifier Initialiser[opt]
+ #
+ # return tuple of [name, initialiser]
+ #
def var_decl(lex, context, options)
- lex.eval_lit {
- a = identifier(lex, context)
- if !a
- raise ParseError.new("bad identifier");
- else
- b = initialiser(lex, context, options)
- [a, b]
- end
- }
+ a = identifier(lex, context)
+ if !a
+ raise ParseError.new("bad identifier", lex);
+ else
+ b = initialiser(lex, context, options)
+ [a, b]
+ end
end
+ # 12.2
+ #
+ # Initialiser :
+ # = AssignmentExpression
+ #
def initialiser(lex, context, options)
- if lex.match_lit(ECMA262::PUNC_LET) and a = assignment_exp(lex, context, options)
- return a
+ if lex.eql_lit?(ECMA262::PUNC_LET)
+ if a = assignment_exp(lex, context, options)
+ return a
+ else
+ raise ParseError.new("unexpceted token", lex);
+ end
end
-
nil
end
#
#12.3
#
def empty_statement(lex, context)
- lex.eval_lit{
- a = lex.fwd_lit
- if a == ECMA262::PUNC_SEMICOLON
- ECMA262::StEmpty.new
- else
- nil
- end
- }# || lex.eval_lit {
-# a = lex.fwd_lit(:nolt => true)
-# if a == ECMA262::LIT_LINE_FEED
-# ECMA262::StEmpty.new
-# elsif a.lt?
-# ECMA262::StEmpty.new
-# else
-# nil
-# end
-# }
+ a = lex.peek_lit(nil)
+ if a == ECMA262::PUNC_SEMICOLON
+ lex.fwd_after_peek
+ ECMA262::StEmpty.new
+ else
+ nil
+ end
end
#
#12.4
#
def exp_statement(lex, context)
- return false if lex.next_lit == ECMA262::PUNC_LCURLYBRAC
- return false if lex.next_lit == ECMA262::ID_FUNCTION
- lex.eval_lit{
- if a=exp(lex, context, {}) and semicolon(lex, context)
+ if (a = lex.peek_lit(nil)).eql? ECMA262::PUNC_LCURLYBRAC
+ return block(lex, context)
+ end
+ if a.eql? ECMA262::ID_FUNCTION
+ return func_declaration(lex, context)
+ end
+
+
+ if a = exp(lex, context, {})
+ if semicolon(lex, context)
ECMA262::StExp.new(a)
+ # There is a possibility of labelled statemet if
+ # exp_statement call before labelled_statement
else
- if a
- raise ParseError.new("no semicolon at end of expression statement", lex)
- else
- nil
- end
+ raise ParseError.new("no semicolon at end of expression statement", lex)
end
- }
+ else
+ nil
+ end
end
#
#12.5
#
def if_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_IF)
- lex.eval_lit {
- unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and cond=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- raise ParseError.new("bad statement", lex)
- end
- if lex.match_lit(ECMA262::ID_ELSE) and e=statement(lex, context)
- ECMA262::StIf.new(cond, s, e)
- else
- ECMA262::StIf.new(cond, s, nil)
- end
- }
+ return nil unless lex.eql_lit?(ECMA262::ID_IF)
+ unless lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and cond=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ raise ParseError.new("unexpected token", lex)
+ end
+ if lex.eql_lit?(ECMA262::ID_ELSE) and e=statement(lex, context)
+ ECMA262::StIf.new(cond, s, e)
+ else
+ ECMA262::StIf.new(cond, s, nil)
+ end
end
#
# 12.6
#
def iteration_statement(lex, context)
for_statement(lex, context) or while_statement(lex, context) or do_while_statement(lex, context)
end
def while_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_WHILE)
- if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ return nil unless lex.eql_lit?(ECMA262::ID_WHILE)
+ if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
ECMA262::StWhile.new(e, s)
else
- raise ParseError.new("while_statement", lex)
+ raise ParseError.new("unexpected token", lex)
end
end
def do_while_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_DO)
- if s=statement(lex, context) and lex.match_lit(ECMA262::ID_WHILE) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and semicolon(lex, context)
+ return nil unless lex.eql_lit?(ECMA262::ID_DO)
+ if s=statement(lex, context) and lex.eql_lit?(ECMA262::ID_WHILE) and lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and semicolon(lex, context)
ECMA262::StDoWhile.new(e, s)
else
- raise ParseError.new("do_while_statement", lex)
+ raise ParseError.new("unexpected token", lex)
end
end
+ #12.6
+ #
+ # for ( ExpressionNoInopt ; Expressionopt ; Expressionopt ) Statement
+ # for ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statement
+ # for ( LeftHandSideExpression in Expression ) Statement
+ # for ( var VariableDeclarationNoIn in Expression ) Statement
+ #
def for_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_FOR)
+ return nil unless lex.eql_lit?(ECMA262::ID_FOR)
+ raise ParseError('unexpected token', lex) unless lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS)
lex.eval_lit{
# for(var i in a)
- next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
- if lex.match_lit(ECMA262::ID_VAR) and v=var_decl(lex, context, :no_in => true) and lex.match_lit(ECMA262::ID_IN) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- #10.5
- context.var_env.record.create_mutable_binding(v[0], nil)
- context.var_env.record.set_mutable_binding(v[0], :undefined, nil)
- context.lex_env.record.create_mutable_binding(v[0], nil)
- context.lex_env.record.set_mutable_binding(v[0], :undefined, nil)
- ECMA262::StForInVar.new(context, v, e, s)
- else
- nil
+ if lex.eql_lit?(ECMA262::ID_VAR)
+ lex.eval_lit{
+ if v=var_decl(lex, context, :no_in => true) and lex.eql_lit?(ECMA262::ID_IN)
+ if e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ #10.5
+ context.var_env.record.create_mutable_binding(v[0], nil)
+ context.var_env.record.set_mutable_binding(v[0], :undefined, nil)
+ context.lex_env.record.create_mutable_binding(v[0], nil)
+ context.lex_env.record.set_mutable_binding(v[0], :undefined, nil)
+ ECMA262::StForInVar.new(context, v, e, s)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ end
+ } or lex.eval_lit {
+ # for(var i ; cond ; exp)
+ if vl=var_decl_list(lex, context, :no_in =>true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {})||true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ e = nil if e == true
+ e2 = nil if e2 == true
+ #10.5
+ vl.each do |v|
+ dn = v[0]
+ context.var_env.record.create_mutable_binding(dn, nil)
+ context.var_env.record.set_mutable_binding(dn, :undefined, nil)
+ context.lex_env.record.create_mutable_binding(dn, nil)
+ context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
+ end
+ ECMA262::StForVar.new(context, vl, e, e2, s)
+ else
+ if !s1
+ raise ParseError.new("no semicolon", lex)
+ elsif !s2
+ raise ParseError.new("no semicolon", lex)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ end
+ }
+ else # => for(i in exp) / for(i ; cond; exp)
+ lex.eval_lit{
+ # for(i in exp)
+ if v=left_hand_side_exp(lex, context, {}) and lex.eql_lit?(ECMA262::ID_IN)
+ if e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ ECMA262::StForIn.new(v, e, s)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ end
+ } or lex.eval_lit{
+ # for(i ; cond; exp)
+ if (v=exp(lex, context, :no_in => true) || true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {}) || true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ v = nil if v == true
+ e = nil if e == true
+ e2 = nil if e2 == true
+ ECMA262::StFor.new(v, e, e2, s)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ }
end
- } or lex.eval_lit {
- # for(var i ; cond ; exp)
- next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
- if lex.match_lit(ECMA262::ID_VAR) and vl=var_decl_list(lex, context, :no_in =>true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- e = nil if e == true
- e2 = nil if e2 == true
- #10.5
- vl.each do |v|
- dn = v[0]
- context.var_env.record.create_mutable_binding(dn, nil)
- context.var_env.record.set_mutable_binding(dn, :undefined, nil)
- context.lex_env.record.create_mutable_binding(dn, nil)
- context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
- end
- ECMA262::StForVar.new(context, vl, e, e2, s)
- else
- nil
- end
- } or lex.eval_lit{
- # for(i in exp)
- next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
- if v=left_hand_side_exp(lex, context, {}) and lex.match_lit(ECMA262::ID_IN) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- ECMA262::StForIn.new(v, e, s)
- else
- nil
- end
- } or lex.eval_lit{
- # for(i ; cond; exp)
- next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
- if (v=exp(lex, context, :no_in => true) || true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {}) || true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- v = nil if v == true
- e = nil if e == true
- e2 = nil if e2 == true
- ECMA262::StFor.new(v, e, e2, s)
- else
- nil
- end
}
end
#
# 12.7
#
def continue_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_CONTINUE)
- lex.eval_lit {
- if semicolon(lex, context)
- ECMA262::StContinue.new
- elsif e=identifier(lex, context) and semicolon(lex, context)
- ECMA262::StContinue.new(e)
+ return nil unless lex.eql_lit?(ECMA262::ID_CONTINUE)
+
+ if semicolon(lex, context)
+ ECMA262::StContinue.new
+ elsif e=identifier(lex, context) and semicolon(lex, context)
+ ECMA262::StContinue.new(e)
+ else
+ if e
+ raise ParseError.new("no semicolon at end of continue statement", lex)
else
- if e
- raise ParseError.new("no semicolon at end of continue statement", lex)
- else
- raise ParseError.new("bad continue statement", lex)
- end
+ raise ParseError.new("unexpected token", lex)
end
- }
+ end
end
#
# 12.8
#
def break_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_BREAK)
- lex.eval_lit {
- if semicolon(lex, context)
- ECMA262::StBreak.new
- elsif e=identifier(lex, context) and semicolon(lex, context)
- ECMA262::StBreak.new(e)
+ return nil unless lex.eql_lit?(ECMA262::ID_BREAK)
+
+ if semicolon(lex, context)
+ ECMA262::StBreak.new
+ elsif e=identifier(lex, context) and semicolon(lex, context)
+ ECMA262::StBreak.new(e)
+ else
+ if e
+ raise ParseError.new("no semicolon at end of break statement", lex)
else
- if e
- raise ParseError.new("no semicolon at end of break statement", lex)
- else
- raise ParseError.new("bad break statement", lex)
- end
+ raise ParseError.new("unexpected token", lex)
end
- }
+ end
end
#
# 12.9
#
def return_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_RETURN)
- lex.eval_lit {
- if semicolon(lex, context)
- ECMA262::StReturn.new
- elsif e=exp(lex, context, {}) and semicolon(lex, context)
- ECMA262::StReturn.new(e)
- else
- nil
- end
- }
+ return nil unless lex.eql_lit?(ECMA262::ID_RETURN)
+
+ if semicolon(lex, context)
+ ECMA262::StReturn.new
+ elsif e=exp(lex, context, {}) and semicolon(lex, context)
+ ECMA262::StReturn.new(e)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
end
#
# 12.10
#
def with_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_WITH)
- lex.eval_lit {
- if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
- ECMA262::StWith.new(context, e, s)
- else
- raise ParseError.new("switch_statement", lex)
- end
- }
+ return nil unless lex.eql_lit?(ECMA262::ID_WITH)
+
+ if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
+ ECMA262::StWith.new(context, e, s)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
end
#
# 12.11
#
def switch_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_SWITCH)
- lex.eval_lit {
- if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and c = case_block(lex, context)
- ECMA262::StSwitch.new(e, c)
- else
- raise ParseError.new("switch_statement", lex)
- end
- }
+ return nil unless lex.eql_lit?(ECMA262::ID_SWITCH)
+
+ if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and c = case_block(lex, context)
+ ECMA262::StSwitch.new(e, c)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
end
def case_block(lex, context)
- return nil unless lex.match_lit(ECMA262::PUNC_LCURLYBRAC)
+ return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
_case_block = []
while true
- t = lex.eval_lit{
- break unless lex.match_lit(ECMA262::ID_CASE) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_COLON)
- sl = statement_list(lex, context)
- [e, sl]
- } || lex.eval_lit{
- break unless lex.match_lit(ECMA262::ID_DEFAULT) and lex.match_lit(ECMA262::PUNC_COLON)
- sl = statement_list(lex, context)
- [nil, sl]
- }
- break if t.nil?
- _case_block.push(t)
+ if lex.eql_lit?(ECMA262::ID_CASE)
+ if e = exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_COLON)
+ sl = statement_list(lex, context)
+ _case_block.push [e, sl]
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ elsif lex.eql_lit?(ECMA262::ID_DEFAULT)
+ if lex.eql_lit?(ECMA262::PUNC_COLON)
+ sl = statement_list(lex, context)
+ _case_block.push [nil, sl]
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
+ elsif lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
+ break
+ end
end
- return nil unless lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
_case_block
end
#
# 12.12
#
def labelled_statement(lex, context)
lex.eval_lit {
- if i=identifier(lex, context) and lex.match_lit(ECMA262::PUNC_COLON) and s=statement(lex, context)
- ECMA262::StLabelled.new(i, s)
+ if i=identifier(lex, context) and s1=lex.eql_lit?(ECMA262::PUNC_COLON)
+ if s=statement(lex, context)
+ ECMA262::StLabelled.new(i, s)
+ else
+ raise ParseError.new("unexpected token", lex)
+ end
else
nil
end
}
end
#
# 12.13
#
def throw_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_THROW)
- lex.eval_lit{
- if semicolon(lex, context)
- raise ParseError.new("no line terminator here", lex)
- elsif e=exp(lex, context, {}) and semi = semicolon(lex, context)
- ECMA262::StThrow.new(e)
+ return nil unless lex.eql_lit?(ECMA262::ID_THROW)
+
+ if semicolon(lex, context)
+ raise ParseError.new("no line terminator here", lex)
+ elsif e=exp(lex, context, {}) and semi = semicolon(lex, context)
+ ECMA262::StThrow.new(e)
+ else
+ if e
+ raise ParseError.new("no semicolon at end of throw statement", lex)
else
- if e
- raise ParseError.new("no semicolon at end of throw statement", lex)
- else
- raise ParseError.new("bad throw statement", lex)
- end
+ raise ParseError.new("unexpected token", lex)
end
- }
+ end
end
#
# 12.14
#
def try_statement(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_TRY)
- lex.eval_lit {
- #
- # The catch argument context must be executable lexical environment.
- # See compress_var
- #
- #catch_context = ECMA262::Context.new
- #catch_context.lex_env = context.lex_env
- #catch_context.var_env = context.var_env
- catch_context = context
+ return nil unless lex.eql_lit?(ECMA262::ID_TRY)
+ #
+ # The catch argument context must be executable lexical environment.
+ # See compress_var
+ #
+ t = block(lex, context)
+ return nil unless t
- t = block(lex, context)
- break nil unless t
-
- lex.eval_lit{
- c = try_catch(lex, catch_context)
- break nil unless c
-
- f = try_finally(lex, context)
- ECMA262::StTry.new(context, t, c, f)
- } || lex.eval_lit{
- f = try_finally(lex, context)
- break nil unless f
- ECMA262::StTry.new(context, t, nil, f)
- }
- }
+ c = try_catch(lex, context)
+ f = try_finally(lex, context)
+ ECMA262::StTry.new(context, t, c, f)
end
- def try_catch(lex, catch_context)
- return nil unless lex.match_lit(ECMA262::ID_CATCH)
+ # 12.14
+ #
+ # Catch :
+ # catch ( Identifier ) Block
+ #
+ # return [identigier, block]
+ #
+ def try_catch(lex, context)
+ return nil unless lex.eql_lit?(ECMA262::ID_CATCH)
- if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and i=identifier(lex, catch_context) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and b=block(lex, catch_context)
-# catch_context.lex_env.record.create_mutable_binding(i, nil)
-# catch_context.lex_env.record.set_mutable_binding(i, :undefined, nil, {:_parameter_list => true})
-# catch_context.var_env.record.create_mutable_binding(i, nil)
-# catch_context.var_env.record.set_mutable_binding(i, :undefined, nil, {:_parameter_list => true})
-# catch_context.var_env.record.binding.each do|k, v|
-# end
+ if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and i=identifier(lex, context) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and b=block(lex, context)
[i, b]
else
- nil
+ raise ParseError.new("unexpected token", lex)
end
end
def try_finally(lex, context)
- return nil unless lex.match_lit(ECMA262::ID_FINALLY)
- block(lex, context)
+ return nil unless lex.eql_lit?(ECMA262::ID_FINALLY)
+ b = block(lex, context)
+ raise ParseError.new("unexpected token", lex) if b.nil?
+ b
end
#
# 12.15
#
def debugger_statement(lex, context)
- if lex.match_lit(ECMA262::ID_DEBUGGER) and semicolon(lex, context)
- t = ECMA262::StDebugger.new
+ return nil unless lex.eql_lit?(ECMA262::ID_DEBUGGER)
+ if semicolon(lex, context)
+ ECMA262::StDebugger.new
+ else
+ raise ParseError.new("no semicolon at end of debugger statement", lex)
end
end
end
end