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(),