#include "AST.h" #include "pseudocode.h" #include static void show_position(ostream &os, unsigned depth, const string &s, size_t min_s_length = 5); static void show_position(ostream &os, unsigned depth, const string &s, size_t min_s_length) { if (s.length() >= min_s_length) { os << "/* " << s << " */\n"; indent(os, depth); } } static void printlist(const TreeNode *t, ostream &os, int depth=0, char *delim=", ") { if (!t->absent()) { int i = 0, a = t->arity(); bool first = true; while (i < a) { if (!first) os << delim; else first = false; t->child(i)->pseudoprint(os, depth); i++; } } } void TreeNode::pseudoprint(ostream &os, unsigned depth) const { print(os, depth); os << endl; } void TreeListNode::pseudoprint(ostream &os, unsigned depth) const { os << "{ "; printlist(this, os); os << " }"; } void StatementNode::pseudoprint(ostream &os, unsigned depth) const { indent(os, depth); os << oper_name() << endl; } void OmittedNode::pseudoprint (ostream& os, unsigned depth) const { os << " -*- "; } void ObjectNode::pseudoprint(ostream& os, unsigned depth) const { name()->pseudoprint(os, depth); } void NameNode::pseudoprint(ostream& os, unsigned depth) const { if (!qualifier()->absent()) { qualifier()->pseudoprint(os, depth); os << '.'; } os << *ident(); } void ObjectFieldAccessNode::pseudoprint(ostream& os, unsigned depth) const { object()->pseudoprint(os, depth); os << '.'; simpName()->pseudoprint(os, depth); } void SuperFieldAccessNode::pseudoprint(ostream& os, unsigned depth) const { os << "super."; simpName()->pseudoprint(os, depth); } void ThisFieldAccessNode::pseudoprint(ostream& os, unsigned depth) const { os << "this."; simpName()->pseudoprint(os, depth); } void TypeFieldAccessNode::pseudoprint(ostream& os, unsigned depth) const { ftype()->pseudoprint(os, depth); os << '.'; simpName()->pseudoprint(os, depth); } void PrimitiveLitNode::pseudoprint(ostream& os, unsigned depth) const { Literal l = literal(); switch (l.kind()) { case Common::ByteKind: os << l.intValue(); break; case Common::ShortKind: os << l.intValue(); break; case Common::CharKind: os << l.intValue(); break; case Common::IntKind: os << l.intValue(); break; case Common::LongKind: os << l.intValue(); break; case Common::FloatKind: os << l.doubleValue(); break; case Common::DoubleKind: os << l.doubleValue(); break; case Common::BoolKind: os << l.boolValue(); break; default: fatal_error(""); } } void StringLitNode::pseudoprint(ostream& os, unsigned depth) const { os << text(); } void TypeNode::pseudoprint(ostream &os, unsigned) const { os << typeName(); } void CompileUnitNode::pseudoprint(ostream& os, unsigned depth) const { os << endl << "package "; package()->pseudoprint(os, depth); os << ";" << endl; if (!imports()->absent() && imports()->arity()) { os << "imports "; imports()->pseudoprint(os, depth); os << ";" << endl; } int i = 0, a = types()->arity(); while (i < a) { types()->child(i)->pseudoprint(os, depth + 1); os << endl << endl; i++; } } #define FLAGS() stringifyModifiers(flags()) void ClassDeclNode::pseudoprint(ostream& os, unsigned depth) const { os << FLAGS() << " class "; simpName()->pseudoprint(os, depth); if (!superClass()->absent()) { os << " extends "; superClass()->pseudoprint(os, depth); } if (!interfaces()->absent() && interfaces()->arity()) { os << " implements "; printlist(interfaces(), os); } os << " {" << endl; int i = 0, a = members()->arity(); while (i < a) { members()->child(i)->pseudoprint(os, depth + 1); os << endl; i++; } os << "}" << endl; } void InterfaceDeclNode::pseudoprint(ostream& os, unsigned depth) const { os << FLAGS() << " "; simpName()->pseudoprint(os, depth); if (!interfaces()->absent() && interfaces()->arity()) { os << " extends "; printlist(interfaces(), os); } os << " {" << endl; int i = 0, a = members()->arity(); while (i < a) { members()->child(i)->pseudoprint(os, depth + 1); os << endl; i++; } os << "}" << endl; } void FieldDeclNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << FLAGS() << ' '; dtype()->pseudoprint(os, depth); os << ' '; simpName()->pseudoprint(os, depth); if (!initExpr()->absent()) { os << " = "; initExpr()->pseudoprint(os, depth); } os << ';'; } void VarDeclNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); dtype()->pseudoprint(os, depth); os << ' '; if (isfinal()) os << "final "; simpName()->pseudoprint(os, depth); if (!initExpr()->absent()) { os << " = "; initExpr()->pseudoprint(os, depth); } os << ';'; } void MethodDeclNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << FLAGS() << " /*method*/ "; returnType()->pseudoprint(os, depth); os << ' '; simpName()->pseudoprint(os, depth); os << "("; printlist(params(), os); os << ")"; if (!throws()->absent() && throws()->arity()) { os << " throws "; printlist(throws(), os); } if (!overlaps()->absent() && overlaps()->arity()) { os << " overlaps "; printlist(overlaps(), os); } if (body()->absent()) { os << ";" << endl; } else { os << " {"; body()->pseudoprint(os, depth + 1); os << endl; indent(os, depth); os << "}" << endl; } } void MethodSignatureNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << FLAGS() << " /*method*/ "; returnType()->pseudoprint(os, depth); os << ' '; simpName()->pseudoprint(os, depth); os << "("; printlist(params(), os); os << ")"; if (!throws()->absent() && throws()->arity()) { os << " throws "; printlist(throws(), os); } os << ";" << endl; } void ConstructorDeclNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << FLAGS() << " /*constructor*/ "; simpName()->pseudoprint(os, depth); os << "("; printlist(params(), os); os << ")"; if (!throws()->absent() && throws()->arity()) { os << " throws "; throws()->pseudoprint(os, depth); } os << " {" << endl; constructorCall()->pseudoprint(os, depth + 1); body()->pseudoprint(os, depth + 1); os << endl; indent(os, depth); os << "}" << endl; } void StaticInitNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "static"; block()->pseudoprint(os, depth); } void InstanceInitNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; block()->pseudoprint(os, depth); } void ArrayInitNode::pseudoprint(ostream& os, unsigned depth) const { initializers()->pseudoprint(os, depth); } void BlockNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "{"; int i = 0, a = child(0)->arity(); while (i < a) { child(0)->child(i)->pseudoprint(os, depth + 1); i++; } os << endl; indent(os, depth); os << "}"; } void ReorderNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "/* BEGIN REORDERNODE */ {"; stmt()->pseudoprint(os, depth + 1); os << endl; indent(os, depth); os << "/* END REORDERNODE */ }"; } void SynchronizedNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "synchronized ("; expr()->pseudoprint(os, depth + 1); os << ")"; stmt()->pseudoprint(os, depth + 1); os << endl; } void EmptyStmtNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << ';'; } void GotoNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "goto " << "Label_" << destination() << ';' << endl; } void LabeledStmtNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth - 1); os << "Label_" << this << ':'; if (!stmt()->absent()) stmt()->pseudoprint(os, depth); } void AssertNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "assert "; condition()->pseudoprint(os, depth); if (!value()->absent()) { os << " : "; value()->pseudoprint(os, depth); } os << ";"; } void IfStmtNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "if ("; condition()->pseudoprint(os, depth); os << ")"; thenPart()->pseudoprint(os, depth + 1); if (!elsePart()->absent()) { os << endl; indent(os, depth); os << "else"; elsePart()->pseudoprint(os, depth + 1); } } void ReturnNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); foreach (f, llist, *(cleanups())) (*f)->pseudoprint(os, depth); os << "return"; if (!expr()->absent()) { os << ' '; expr()->pseudoprint(os, depth); } os << ';'; } void BreakNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "break"; if (!label()->absent()) { os << " Label_" << destination(); } os << ';'; } void ContinueNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "continue"; if (!label()->absent()) { os << " Label_" << destination(); } os << ';'; } void ThrowNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "throw "; expr()->pseudoprint(os, depth); os << ';'; } void CatchNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "catch ("; param()->pseudoprint(os, depth); os << ")"; block()->pseudoprint(os, depth); } void TryNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "try"; block()->pseudoprint(os, depth + 1); } void FinallyNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "finally"; block()->pseudoprint(os, depth + 1); } void TryStmtNode::pseudoprint(ostream& os, unsigned depth) const { block()->pseudoprint(os, depth); if (!catches()->absent()) printlist(catches(), os, depth, ""); if (!finally()->absent()) finally()->pseudoprint(os, depth); } void ExpressionStmtNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); expr()->pseudoprint(os, depth); os << ';'; } void PragmaNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); os << "PRAGMA (" << (int) requests() << ")"; stmt()->pseudoprint(os, depth + 1); } void DummyNode::pseudoprint(ostream& os, unsigned depth) const { #if SHOW_DUMMY_NODES os << endl; indent(os, depth); os << "/* DUMMY: "; expr()->pseudoprint(os, depth); os << "; */"; #endif } void ParameterNode::pseudoprint(ostream& os, unsigned depth) const { dtype()->pseudoprint(os, depth); os << ' '; if (isfinal()) os << "final "; simpName()->pseudoprint(os, depth); } void NullPntrNode::pseudoprint(ostream& os, unsigned depth) const { os << "null"; } void ThisNode::pseudoprint(ostream& os, unsigned depth) const { os << "(this or super)"; } void ArrayAccessNode::pseudoprint(ostream& os, unsigned depth) const { array()->pseudoprint(os, depth); os << '['; index()->pseudoprint(os, depth); os << ']'; } void SRArrayAccessNode::pseudoprint(ostream& os, unsigned depth) const { string s = "*" + codeString(); if (((ForEachStmtNode *) WRTloop())->partialDomain()) { os << "(bounds_check("; array()->pseudoprint(os, depth); os << ", "; index()->pseudoprint(os, depth); os << "), " << s << ")"; } else os << s; } void OSRArrayAccessNode::pseudoprint(ostream& os, unsigned depth) const { string s = "*(" + codeString() + " + " + offsetString() + ")"; if (((ForEachStmtNode *) WRTloop())->partialDomain()) { os << "(bounds_check("; array()->pseudoprint(os, depth); os << ", "; index()->pseudoprint(os, depth); os << "), " << s << ")"; } else os << s; } void MethodCallNode::pseudoprint(ostream& os, unsigned depth) const { method()->pseudoprint(os, depth); os << '('; printlist(args(), os); os << ')'; } void SuperConstructorCallNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << "super("; printlist(args(), os); os << ");"; } void ThisConstructorCallNode::pseudoprint(ostream& os, unsigned depth) const { indent(os, depth); os << "this("; printlist(args(), os); os << ");"; } #define PRINTREGION(os) \ do \ if (!region()->absent()) { \ os << " ("; \ region()->pseudoprint(os, depth); \ os << ")"; \ } \ while (0) void AllocateNode::pseudoprint(ostream& os, unsigned depth) const { os << "new"; PRINTREGION(os); os << ' '; dtype()->pseudoprint(os, depth); os << " ("; printlist(args(), os); os << ") "; } void AllocateSpaceNode::pseudoprint(ostream& os, unsigned depth) const { os << "new"; PRINTREGION(os); os << ' '; dtype()->pseudoprint(os, depth); } void AllocateArrayNode::pseudoprint(ostream& os, unsigned depth) const { os << "new"; PRINTREGION(os); os << ' '; dtype()->pseudoprint(os, depth); printlist(dimExprs(), os, depth, ""); } void AllocateArrayDimensionNode::pseudoprint(ostream& os, unsigned depth) const { os << " [ "; expr()->pseudoprint(os, depth); os << " ] "; os << FLAGS(); } /* Return pseudocode for t; parenthesize unless trivial. */ static string parenthesized_pseudocode(TreeNode *t) { string s = pseudocode1(t); return (s.find(' ') == s.npos ? s : ('(' + s + ')')); } #define UNARY(FOO, OP) \ void FOO ## Node::pseudoprint(ostream& os, unsigned depth) const \ { \ os << OP << parenthesized_pseudocode(opnd0()); \ } #define POST_UNARY(FOO, OP) \ void FOO ## Node::pseudoprint(ostream& os, unsigned depth) const \ { \ os << parenthesized_pseudocode(opnd0()) << OP; \ } UNARY(UnaryPlus, '+') UNARY(UnaryMinus, '-') UNARY(Complement, '~') UNARY(Not, '!') UNARY(PreIncr, "++") POST_UNARY(PostIncr, "++") UNARY(PreDecr, "--") POST_UNARY(PostDecr, "--") #define BINARY(FOO, OP) \ void FOO ## Node::pseudoprint(ostream& os, unsigned depth) const \ { \ os << parenthesized_pseudocode(opnd0()) << ' ' << OP << ' ' << \ parenthesized_pseudocode(opnd1()); \ } BINARY(Mult, '*') BINARY(Div, '/') BINARY(Rem, '%') BINARY(Plus, '+') BINARY(Minus, '-') BINARY(LeftShiftLog, "<<") BINARY(RightShiftLog, ">>") BINARY(RightShiftArith, ">>>") BINARY(LT, '<') BINARY(GT, '>') BINARY(LE, "<=") BINARY(GE, ">=") BINARY(EQ, "==") BINARY(NE, "!=") BINARY(BitAnd, '&') BINARY(BitOr, '|') BINARY(BitXor, '^') BINARY(Cand, "&&") BINARY(Cor, "||") BINARY(Assign, '=') BINARY(HasNoOverlap, "does not overlap") BINARY(MultAssign, "*=") BINARY(DivAssign, "/=") BINARY(RemAssign, "%=") BINARY(PlusAssign, "+=") BINARY(MinusAssign, "-=") BINARY(LeftShiftLogAssign, "<<=") BINARY(RightShiftLogAssign, ">>=") BINARY(RightShiftArithAssign, ">>>=") BINARY(BitAndAssign, "&=") BINARY(BitXorAssign, "^=") BINARY(BitOrAssign, "|=") void StringConcatAssignNode::pseudoprint(ostream& os, unsigned depth) const { opnd0()->pseudoprint(os,depth); os << " +=/*StringConcatAssign*/ "; printlist(addends(), os, 0, " +/*StringConcat*/ "); } void StringConcatNode::pseudoprint(ostream& os, unsigned depth) const { printlist(addends(), os, 0, " +/*StringConcat*/ "); } void IfExprNode::pseudoprint(ostream& os, unsigned depth) const { os << "( " << parenthesized_pseudocode(condition()) << " ? " << parenthesized_pseudocode(thenOpnd()) << " : " << parenthesized_pseudocode(elseOpnd()) << " )"; } void CastNode::pseudoprint(ostream& os, unsigned depth) const { os << '('; dtype()->pseudoprint(os, depth); os << ')'; opnd0()->pseudoprint(os, depth); } void InstanceOfNode::pseudoprint(ostream& os, unsigned depth) const { os << '('; opnd0()->pseudoprint(os, depth); os << " instanceof "; dtype()->pseudoprint(os, depth); os << ')'; } void PointTypeNode::pseudoprint(ostream& os, unsigned depth) const { os << "Point<"; expr()->pseudoprint(os, depth); os << '>'; } void RectDomainTypeNode::pseudoprint(ostream& os, unsigned depth) const { os << "RectDomain<"; expr()->pseudoprint(os, depth); os << '>'; } void DomainTypeNode::pseudoprint(ostream& os, unsigned depth) const { os << "Domain<"; expr()->pseudoprint(os, depth); os << '>'; } void TitaniumArrayTypeNode::pseudoprint(ostream& os, unsigned depth) const { elementType()->pseudoprint(os, depth); os << " ["; expr()->pseudoprint(os, depth); os << "d]"; if (modifiers() & Common::Local) os << " local"; } void ForEachPairNode::pseudoprint(ostream& os, unsigned depth) const { simpName()->pseudoprint(os, depth); os << " in "; initExpr()->pseudoprint(os, depth); } void ForEachStmtNode_pseudoprint_no_body(const ForEachStmtNode *f, ostream& os, unsigned depth) { os << endl; indent(os, depth); show_position(os, depth, f->position().asString()); os << "foreach"; if (f->cannotBeEmpty()) os << '+'; if (f->tentative()) os << '?'; if (f->ordered()) os << 'o'; os << " ("; if (f->stride() != NULL) { const string s = pseudocode(f->vars()->child(0)->simpName()); os << "Point<1> " << s << " = [" << (f->lo() ? pseudocode(f->lo()) : "-infinity") << "]; " << s << " <= [" << (f->hi() ? pseudocode(f->hi()) : "+infinity") << "]; " << s << " += [" << pseudocode(f->stride()) << "]"; } else f->vars()->child(0)->pseudoprint(os, depth); os << ')'; } void ForEachStmtNode::pseudoprint(ostream& os, unsigned depth) const { ForEachStmtNode_pseudoprint_no_body(this, os, depth); stmt()->pseudoprint(os, depth + 1); } void ForNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); show_position(os, depth, position().asString()); os << "for ("; string s = pseudocode(init()); int l = s.size(); if (l > 3 && s[0] == '{' && s[1] == ' ') { for (int i = 2; i < l - 3; i++) if (s[i] != '\n') os << ((s[i] == ';') ? ',' : s[i]); } else os << s; // shouldn't happen os << "; "; test()->pseudoprint(os, depth + 1); os << "; "; s = pseudocode(update()); l = s.size(); if (l > 3 && s[0] == '{' && s[1] == ' ') { for (int i = 2; i < l - 3; i++) if (s[i] != '\n') os << ((s[i] == ';') ? ',' : s[i]); } else os << s; // shouldn't happen os << ")"; stmt()->pseudoprint(os, depth + 1); } void DoNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); show_position(os, depth, position().asString()); os << "do"; stmt()->pseudoprint(os, depth + 1); os << endl; indent(os, depth); os << "while ("; test()->pseudoprint(os, depth + 1); os << ");"; } void WhileNode::pseudoprint(ostream& os, unsigned depth) const { os << endl; indent(os, depth); show_position(os, depth, position().asString()); os << "while ("; test()->pseudoprint(os, depth + 1); os << ")"; stmt()->pseudoprint(os, depth + 1); } void IBroadcastNode::pseudoprint(ostream& os, unsigned depth) const { os << "ibroadcast "; expr()->pseudoprint(os, depth); os << " from "; proc()->pseudoprint(os, depth); } void BroadcastNode::pseudoprint(ostream& os, unsigned depth) const { os << "broadcast "; expr()->pseudoprint(os, depth); os << " from "; proc()->pseudoprint(os, depth); } void PointNode::pseudoprint(ostream& os, unsigned depth) const { os << '['; printlist(args(), os); os << ']'; } void DomainNode::pseudoprint(ostream& os, unsigned depth) const { os << '['; args()->pseudoprint(os, depth); os << ']'; } void CodeLiteralExprNode::pseudoprint(ostream& os, unsigned depth) const { os << " /* begin C */ " << codeString() << " /* end C */ "; } void CodeLiteralFieldAccessNode::pseudoprint(ostream& os, unsigned depth) const { opnd0()->pseudoprint(os, depth); os << " /* begin C */ ." << codeString() << " /* end C */ "; } void CodeLiteralNode::pseudoprint(ostream& os, unsigned depth) const { os << " /* begin C */ " << codeString() << " /* end C */ "; } void LazyOptimizeNode::pseudoprint(ostream& os, unsigned depth) const { os << "optimize "; body()->pseudoprint(os, depth + 1); } /* void Node::pseudoprint(ostream& os, unsigned depth) const { ->pseudoprint(os, depth); os << } */