#include #include #include "utils.h" #include "AST.h" #include "ClassDecl.h" #include "CodeContext.h" #include "CtExternal.h" #include "CtGlobal.h" #include "CtLocal.h" #include "PrimitiveDecl.h" #include "code.h" #include "code-util.h" #include "compiler.h" #include "decls.h" #include "delimit.h" #include "lgMacro.h" #include "UniqueId.h" typedef map< TreeNode *, string *, less< TreeNode * > > Map; // ThisConstructorCallNode and SuperConstructorCallNode now get removed during lowering void StaticInitNode::codeGen( CodeContext &context ) { context.setPosition( position() ); // semantics?? block()->codeGen( context ); } void EmptyStmtNode::emitStatement( CodeContext & context) { } bool & BlockNode::declContainer() { return _declContainer; } CodeContext *& BlockNode::blockContext() { return _blockContext; } void BlockNode::emitStatement( CodeContext &context ) { if (stmts()->arity() == 0) context << " ;" << endCline; else if (stmts()->arity() == 1) stmts()->codeGen( context ); else { CodeContext subcontext( context ); if (declContainer()) { subcontext << "/* Decl container */" << endCline; blockContext() = &subcontext; } stmts()->codeGen( subcontext ); subcontext.setPosition( position() ); } } CodeContext * enclosingDeclContainer(TreeNode *t) { while (true) { if (isBlockNode(t)) { BlockNode *b = static_cast(t); if (b->declContainer()) return b->blockContext(); } t = t->parent(); } } UniqueId gotoLabelGenerator("L"); static string *gotolabel(TreeNode *t) { static Map m; string *& result = m[t]; if (result) return result; else return (result = new string(gotoLabelGenerator.next())); } void LabeledStmtNode::emitStatement( CodeContext &context ) { context << *gotolabel(this) << ": ;\n"; stmt()->codeGen( context ); } void GotoNode::emitStatement( CodeContext &context ) { context << "goto " << *gotolabel(destination()) << ";" << endCline; } void IfStmtNode::emitStatement( CodeContext &context ) { const string predicate = condition()->emitExpression( context ); context << "if (" << predicate << ")" << endCline; { CodeContext thenContext( context ); thenPart()->codeGen( thenContext ); } if (!elsePart()->absent()) { context << "else" << endCline; CodeContext elseContext( context ); elsePart()->codeGen( elseContext ); } } void CodeLiteralNode::emitStatement ( CodeContext &context ) { context << codeString() << endCline; } void ThrowNode::emitStatement( CodeContext &context ) { string exception = expr()->emitExpression( context ); context << "THROW(" << exception << ");" << endCline; } void PartitionStmtNode::emitStatement( CodeContext & context) { } void CheckNullNode::emitStatement( CodeContext &context ) { if (isThisNode(expr())) return; // can always elide null checks on this const string subject = expr()->emitExpression( context ); context << lgMacro( "CHECK_NULL", *expr()->type() ) << "_IFBC(" << subject << ", \"" << expr()->position().asString() << "\");" << endCline; }