lib/minjs/func.rb in minjs-0.2.2 vs lib/minjs/func.rb in minjs-0.3.0

- old
+ new

@@ -1,93 +1,107 @@ module Minjs module Func - # #13 # + # FunctionDeclaration : + # function Identifier ( FormalParameterListopt ) { FunctionBody } + # + # NOTE: + # + # The function declaration in statement(block) is not permitted by ECMA262. + # However, almost all implementation permit it. + # def func_declaration(lex, context) - return nil if lex.match_lit(ECMA262::ID_FUNCTION).nil? - lex.eval_lit { - new_context = ECMA262::Context.new - new_context.lex_env = context.lex_env.new_declarative_env() - new_context.var_env = context.var_env.new_declarative_env() + return nil if lex.eql_lit?(ECMA262::ID_FUNCTION).nil? - if id=identifier(lex, context) and - lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and - args = formal_parameter_list(lex, new_context) and - lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and - lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and - b=func_body(lex, new_context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC) - f = ECMA262::StFunc.new(new_context, id, args, b, {:decl => true}) + new_context = ECMA262::Context.new + new_context.lex_env = context.lex_env.new_declarative_env() + new_context.var_env = context.var_env.new_declarative_env() - context.var_env.record.create_mutable_binding(id, nil) - context.var_env.record.set_mutable_binding(id, f, nil) - context.lex_env.record.create_mutable_binding(id, nil) - context.lex_env.record.set_mutable_binding(id, f, nil) - f + if id=identifier(lex, context) and + lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and + args = formal_parameter_list(lex, new_context) and + lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and + lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC) and + b=func_body(lex, new_context) and lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC) + f = ECMA262::StFunc.new(new_context, id, args, b, {:decl => true}) + + context.var_env.record.create_mutable_binding(id, nil) + context.var_env.record.set_mutable_binding(id, f, nil) + context.lex_env.record.create_mutable_binding(id, nil) + context.lex_env.record.set_mutable_binding(id, f, nil) + f + else + if b + raise ParseError.new("No `}' at end of function", lex) else - if b - raise ParseError.new("No `}' at end of function", lex) - else - raise ParseError.new("Bad function declaration", lex) - end + raise ParseError.new("Bad function declaration", lex) end - } + end end + #13 + # + # FunctionExpression : + # function Identifieropt ( FormalParameterListopt ) { FunctionBody } + # def func_exp(lex, context) - return nil if lex.match_lit(ECMA262::ID_FUNCTION).nil? + return nil if lex.eql_lit?(ECMA262::ID_FUNCTION).nil? @logger.debug "*** func_exp" - lex.eval_lit { - id_opt = identifier(lex, context) - new_context = ECMA262::Context.new - new_context.lex_env = context.lex_env.new_declarative_env() - new_context.var_env = context.var_env.new_declarative_env() + id_opt = identifier(lex, context) + new_context = ECMA262::Context.new + new_context.lex_env = context.lex_env.new_declarative_env() + new_context.var_env = context.var_env.new_declarative_env() - if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and - args = formal_parameter_list(lex, new_context) and - lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and - lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and - b = func_body(lex, new_context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC) - f = ECMA262::StFunc.new(new_context, id_opt, args, b) - if id_opt - new_context.var_env.record.create_mutable_binding(id_opt, nil) - new_context.var_env.record.set_mutable_binding(id_opt, f, nil) - new_context.lex_env.record.create_mutable_binding(id_opt, nil) - new_context.lex_env.record.set_mutable_binding(id_opt, f, nil) - id_opt.context = new_context - end - f - else - if b - raise ParseError.new("No `}' at end of function", lex) - else - raise ParseError.new("Bad function declaration", lex) - end - end - } + if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and + args = formal_parameter_list(lex, new_context) and + lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and + lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC) and + b = func_body(lex, new_context) and lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC) + f = ECMA262::StFunc.new(new_context, id_opt, args, b) + if id_opt + new_context.var_env.record.create_mutable_binding(id_opt, nil) + new_context.var_env.record.set_mutable_binding(id_opt, f, nil) + new_context.lex_env.record.create_mutable_binding(id_opt, nil) + new_context.lex_env.record.set_mutable_binding(id_opt, f, nil) + id_opt.context = new_context + end + f + else + if b + raise ParseError.new("No `}' at end of function", lex) + else + raise ParseError.new("Bad function expression", lex) + end + end end def formal_parameter_list(lex, context) - lex.eval_lit{ - ret = [] + ret = [] + unless lex.peek_lit(nil).eql? ECMA262::PUNC_RPARENTHESIS while true - a = identifier(lex, context) - if a - ret.push(a) - break if lex.match_lit(ECMA262::PUNC_COMMA).nil? + if arg = identifier(lex, context) + ret.push(arg) else + raise ParseError.new("unexpceted token", lex) + end + if lex.peek_lit(nil).eql? ECMA262::PUNC_RPARENTHESIS break + elsif lex.eql_lit? ECMA262::PUNC_COMMA + ; + else + raise ParseError.new("unexpceted token", lex) end end - ret.each do |argName| - context.var_env.record.create_mutable_binding(argName, nil) - context.var_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true}) - context.lex_env.record.create_mutable_binding(argName, nil) - context.lex_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true}) - end - ret - } + end + ret.each do |argName| + context.var_env.record.create_mutable_binding(argName, nil) + context.var_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true}) + context.lex_env.record.create_mutable_binding(argName, nil) + context.lex_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true}) + end + ret end def func_body(lex, context) source_elements(lex, context) end