ext/iv/phonic/creator.h in iv-phonic-0.1.5 vs ext/iv/phonic/creator.h in iv-phonic-0.1.6

- old
+ new

@@ -3,10 +3,11 @@ extern "C" { #include <ruby.h> } #include <iv/ast_visitor.h> #include <iv/utils.h> +#include <iv/maybe.h> #include "factory.h" #include "encoding.h" #define SYM(str) ID2SYM(rb_intern(str)) // create RubyObject of AST from iv AST namespace iv { @@ -76,12 +77,12 @@ void Visit(const Declaration* decl) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("Declaration")); Visit(decl->name()); rb_hash_aset(hash, SYM("name"), ret_); - if (decl->expr()) { - decl->expr()->Accept(this); + if (const core::Maybe<const Expression> expr = decl->expr()) { + (*expr).Accept(this); rb_hash_aset(hash, SYM("expr"), ret_); } SetLocation(hash, decl); ret_ = hash; } @@ -98,12 +99,12 @@ rb_hash_aset(hash, SYM("type"), SYM("IfStatement")); stmt->cond()->Accept(this); rb_hash_aset(hash, SYM("cond"), ret_); stmt->then_statement()->Accept(this); rb_hash_aset(hash, SYM("then"), ret_); - if (stmt->else_statement()) { - stmt->else_statement()->Accept(this); + if (const core::Maybe<const Statement> else_stmt = stmt->else_statement()) { + (*else_stmt).Accept(this); rb_hash_aset(hash, SYM("else"), ret_); } SetLocation(hash, stmt); ret_ = hash; } @@ -131,20 +132,20 @@ } void Visit(const ForStatement* stmt) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ForStatement")); - if (stmt->init()) { - stmt->init()->Accept(this); + if (const core::Maybe<const Statement> init = stmt->init()) { + (*init).Accept(this); rb_hash_aset(hash, SYM("init"), ret_); } - if (stmt->cond()) { - stmt->cond()->Accept(this); + if (const core::Maybe<const Expression> cond = stmt->cond()) { + (*cond).Accept(this); rb_hash_aset(hash, SYM("cond"), ret_); } - if (stmt->next()) { - stmt->next()->Accept(this); + if (const core::Maybe<const Statement> next = stmt->next()) { + (*next).Accept(this); rb_hash_aset(hash, SYM("next"), ret_); } stmt->body()->Accept(this); rb_hash_aset(hash, SYM("body"), ret_); SetLocation(hash, stmt); @@ -165,34 +166,36 @@ } void Visit(const ContinueStatement* stmt) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ContinueStatement")); - if (stmt->label()) { - stmt->label()->Accept(this); + if (const core::Maybe<const Identifier> label = stmt->label()) { + (*label).Accept(this); rb_hash_aset(hash, SYM("label"), ret_); } SetLocation(hash, stmt); ret_ = hash; } void Visit(const BreakStatement* stmt) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("BreakStatement")); - if (stmt->label()) { - stmt->label()->Accept(this); + if (const core::Maybe<const Identifier> label = stmt->label()) { + (*label).Accept(this); rb_hash_aset(hash, SYM("label"), ret_); } SetLocation(hash, stmt); ret_ = hash; } void Visit(const ReturnStatement* stmt) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ReturnStatement")); - stmt->expr()->Accept(this); - rb_hash_aset(hash, SYM("expr"), ret_); + if (const core::Maybe<const Expression> expr = stmt->expr()) { + (*expr).Accept(this); + rb_hash_aset(hash, SYM("expr"), ret_); + } SetLocation(hash, stmt); ret_ = hash; } void Visit(const WithStatement* stmt) { @@ -234,16 +237,16 @@ } void Visit(const CaseClause* cl) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("CaseClause")); - if (cl->IsDefault()) { - rb_hash_aset(hash, SYM("kind"), SYM("Default")); - } else { + if (const core::Maybe<const Expression> expr = cl->expr()) { rb_hash_aset(hash, SYM("kind"), SYM("Case")); - cl->expr()->Accept(this); + (*expr).Accept(this); rb_hash_aset(hash, SYM("expr"), ret_); + } else { + rb_hash_aset(hash, SYM("kind"), SYM("Default")); } VALUE stmts = rb_ary_new(); for (Statements::const_iterator st = cl->body().begin(), stlast = cl->body().end(); st != stlast; ++st) { (*st)->Accept(this); @@ -255,17 +258,32 @@ } void Visit(const ThrowStatement* stmt) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ThrowStatement")); + stmt->expr()->Accept(this); + rb_hash_aset(hash, SYM("expr"), ret_); SetLocation(hash, stmt); ret_ = hash; } void Visit(const TryStatement* stmt) { + assert(stmt->catch_block() || stmt->finally_block()); VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("TryStatement")); + stmt->body()->Accept(this); + rb_hash_aset(hash, SYM("body"), ret_); + if (const core::Maybe<const Identifier> ident = stmt->catch_name()) { + Visit(ident.Address()); + rb_hash_aset(hash, SYM("catch_name"), ret_); + Visit(stmt->catch_block().Address()); + rb_hash_aset(hash, SYM("catch_block"), ret_); + } + if (const core::Maybe<const Block> block = stmt->finally_block()) { + Visit(block.Address()); + rb_hash_aset(hash, SYM("finally_block"), ret_); + } SetLocation(hash, stmt); ret_ = hash; } void Visit(const DebuggerStatement* stmt) { @@ -414,17 +432,10 @@ rb_hash_aset(hash, SYM("type"), SYM("FalseLiteral")); SetLocation(hash, literal); ret_ = hash; } - void Visit(const Undefined* literal) { - // Undefined has no location - VALUE hash = rb_hash_new(); - rb_hash_aset(hash, SYM("type"), SYM("Undefined")); - ret_ = hash; - } - void Visit(const RegExpLiteral* literal) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("RegExpLiteral")); const RegExpLiteral::value_type& content = literal->value(); rb_hash_aset(hash, SYM("value"), @@ -446,20 +457,30 @@ void Visit(const ArrayLiteral* literal) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ArrayLiteral")); VALUE array = rb_ary_new(); - for (Expressions::const_iterator it = literal->items().begin(), + for (MaybeExpressions::const_iterator it = literal->items().begin(), last = literal->items().end(); it != last; ++it) { - (*it)->Accept(this); - rb_ary_push(array, ret_); + if (*it) { + (**it).Accept(this); + rb_ary_push(array, ret_); + } else { + rb_ary_push(array, NewArrayHole()); + } } rb_hash_aset(hash, SYM("value"), array); SetLocation(hash, literal); ret_ = hash; } + static VALUE NewArrayHole() { + VALUE hash = rb_hash_new(); + rb_hash_aset(hash, SYM("type"), SYM("ArrayHole")); + return hash; + } + void Visit(const ObjectLiteral* literal) { using std::tr1::get; VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("ObjectLiteral")); VALUE array = rb_ary_new(); @@ -495,11 +516,11 @@ } void Visit(const FunctionLiteral* literal) { VALUE hash = rb_hash_new(); rb_hash_aset(hash, SYM("type"), SYM("FunctionLiteral")); - if (literal->name()) { - Visit(literal->name()); + if (const core::Maybe<const Identifier> name = literal->name()) { + Visit(name.Address()); rb_hash_aset(hash, SYM("name"), ret_); } { VALUE array = rb_ary_new(); for (Identifiers::const_iterator it = literal->params().begin(),