13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdarg.h>
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "prettyprinter.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPrettyPrinter::PrettyPrinter() {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  output_ = NULL;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  size_ = 0;
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pos_ = 0;
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPrettyPrinter::~PrettyPrinter() {
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DeleteArray(output_);
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitBlock(Block* node) {
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!node->is_initializer_block()) Print("{ ");
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintStatements(node->statements());
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->statements()->length() > 0) Print(" ");
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!node->is_initializer_block()) Print("}");
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("var ");
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->proxy()->name(), false);
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("function ");
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), false);
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(" = ");
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintFunctionLiteral(node->fun());
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(";");
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("module ");
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), false);
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(" = ");
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->module());
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(";");
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("import ");
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), false);
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(" from ");
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->module());
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(";");
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("export ");
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), false);
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(";");
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VisitBlock(node->body());
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->proxy());
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitModulePath(ModulePath* node) {
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->module());
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(".");
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->name(), false);
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("at ");
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->url(), true);
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitIfStatement(IfStatement* node) {
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("if (");
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->condition());
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") ");
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->then_statement());
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->HasElseStatement()) {
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(" else ");
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->else_statement());
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("continue");
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneStringList* labels = node->target()->labels();
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (labels != NULL) {
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(" ");
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(labels->length() > 0);  // guaranteed to have at least one entry
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteral(labels->at(0), false);  // any label from the list is fine
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("break");
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneStringList* labels = node->target()->labels();
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (labels != NULL) {
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(" ");
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(labels->length() > 0);  // guaranteed to have at least one entry
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteral(labels->at(0), false);  // any label from the list is fine
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("return ");
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(";");
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid PrettyPrinter::VisitWithStatement(WithStatement* node) {
18069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Print("with (");
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") ");
18369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Visit(node->statement());
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabels(node->labels());
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("switch (");
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->tag());
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") { ");
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<CaseClause*>* cases = node->cases();
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < cases->length(); i++)
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintCaseClause(cases->at(i));
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("}");
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabels(node->labels());
2013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print("do ");
2023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
2033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print(" while (");
2043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->cond());
2053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print(");");
2063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
2103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintLabels(node->labels());
2113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print("while (");
2123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->cond());
2133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print(") ");
2143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
2153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
2163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid PrettyPrinter::VisitForStatement(ForStatement* node) {
2193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintLabels(node->labels());
2203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print("for (");
2213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (node->init() != NULL) {
2223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Visit(node->init());
2233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Print(" ");
2243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Print("; ");
2263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (node->cond() != NULL) Visit(node->cond());
2283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print("; ");
2293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (node->next() != NULL) {
2303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Visit(node->next());  // prints extra ';', unfortunately
2313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // to fix: should use Expression for next
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Print(") ");
2343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitForInStatement(ForInStatement* node) {
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabels(node->labels());
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("for (");
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->each());
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" in ");
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->enumerable());
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") ");
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->body());
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("try ");
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" catch (");
2533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const bool quote = false;
2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PrintLiteral(node->variable()->name(), quote);
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") ");
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->catch_block());
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("try ");
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" finally ");
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->finally_block());
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("debugger ");
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintFunctionLiteral(node);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid PrettyPrinter::VisitSharedFunctionInfoLiteral(
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    SharedFunctionInfoLiteral* node) {
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  PrintLiteral(node->shared_function_info(), true);
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitConditional(Conditional* node) {
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->condition());
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" ? ");
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->then_expression());
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" : ");
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->else_expression());
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitLiteral(Literal* node) {
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->handle(), true);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" RegExp(");
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->pattern(), false);
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(",");
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->flags(), false);
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(") ");
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("{ ");
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->properties()->length(); i++) {
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i != 0) Print(",");
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ObjectLiteral::Property* property = node->properties()->at(i);
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(" ");
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(property->key());
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(": ");
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(property->value());
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" }");
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("[ ");
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->values()->length(); i++) {
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i != 0) Print(",");
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->values()->at(i));
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" ]");
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->name(), false);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitAssignment(Assignment* node) {
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->target());
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" %s ", Token::String(node->op()));
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->value());
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitThrow(Throw* node) {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("throw ");
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->exception());
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitProperty(Property* node) {
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* key = node->key();
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Literal* literal = key->AsLiteral();
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (literal != NULL && literal->handle()->IsSymbol()) {
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("(");
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->obj());
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(").");
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteral(literal->handle(), false);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->obj());
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("[");
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(key);
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("]");
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitCall(Call* node) {
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitCallNew(CallNew* node) {
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("new (");
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("%%");
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(node->name(), false);
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Token::Value op = node->op();
393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool needsSpace =
394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Print("(%s%s", Token::String(op), needsSpace ? " " : "");
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitCountOperation(CountOperation* node) {
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->is_prefix()) Print("%s", Token::String(node->op()));
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->is_postfix()) Print("%s", Token::String(node->op()));
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Print(" %s ", Token::String(node->op()));
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Print(" %s ", Token::String(node->op()));
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::VisitThisFunction(ThisFunction* node) {
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("<this-function>");
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* PrettyPrinter::Print(AstNode* node) {
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Init();
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node);
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return output_;
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Init();
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ExpressionStatement* statement =
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    program->body()->at(0)->AsExpressionStatement();
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(statement->expression());
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return output_;
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Init();
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintStatements(program->body());
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("\n");
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return output_;
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintOut(AstNode* node) {
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrettyPrinter printer;
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintF("%s", printer.Print(node));
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::Init() {
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (size_ == 0) {
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(output_ == NULL);
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const int initial_size = 256;
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    output_ = NewArray<char>(initial_size);
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    size_ = initial_size;
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  output_[0] = '\0';
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pos_ = 0;
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::Print(const char* format, ...) {
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (;;) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    va_list arguments;
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    va_start(arguments, format);
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          format,
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          arguments);
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    va_end(arguments);
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (n >= 0) {
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // there was enough space - we are done
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pos_ += n;
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return;
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // there was not enough space - allocate more and try again
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      const int slack = 32;
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int new_size = size_ + (size_ >> 1) + slack;
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      char* new_output = NewArray<char>(new_size);
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      memcpy(new_output, output_, pos_);
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      DeleteArray(output_);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      output_ = new_output;
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      size_ = new_size;
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (statements == NULL) return;
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < statements->length(); i++) {
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i != 0) Print(" ");
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(statements->at(i));
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintLabels(ZoneStringList* labels) {
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (labels != NULL) {
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < labels->length(); i++) {
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PrintLiteral(labels->at(i), false);
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print(": ");
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < arguments->length(); i++) {
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i != 0) Print(", ");
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(arguments->at(i));
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* object = *value;
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->IsString()) {
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    String* string = String::cast(object);
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (quote) Print("\"");
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < string->length(); i++) {
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print("%c", string->Get(i));
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (quote) Print("\"");
54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (object->IsNull()) {
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("null");
54244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (object->IsTrue()) {
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("true");
54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (object->IsFalse()) {
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("false");
54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (object->IsUndefined()) {
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("undefined");
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (object->IsNumber()) {
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("%g", object->Number());
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (object->IsJSObject()) {
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // regular expression
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (object->IsJSFunction()) {
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print("JS-Function");
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (object->IsJSArray()) {
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print("JS-array[%u]", JSArray::cast(object)->length());
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (object->IsJSObject()) {
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print("JS-Object");
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Print("?UNKNOWN?");
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (object->IsFixedArray()) {
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("FixedArray");
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("<unknown literal %p>", object);
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintParameters(Scope* scope) {
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("(");
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < scope->num_parameters(); i++) {
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i  > 0) Print(", ");
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteral(scope->parameter(i)->name(), false);
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(")");
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < declarations->length(); i++) {
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i > 0) Print(" ");
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(declarations->at(i));
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("function ");
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(function->name(), false);
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintParameters(function->scope());
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" { ");
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintDeclarations(function->scope()->declarations());
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintStatements(function->body());
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" }");
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid PrettyPrinter::PrintCaseClause(CaseClause* clause) {
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (clause->is_default()) {
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("default");
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print("case ");
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(clause->label());
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(": ");
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintStatements(clause->statements());
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (clause->statements()->length() > 0)
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(" ");
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//-----------------------------------------------------------------------------
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IndentedScope BASE_EMBEDDED {
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
61644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit IndentedScope(AstPrinter* printer) : ast_printer_(printer) {
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ast_printer_->inc_indent();
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope(AstPrinter* printer, const char* txt, AstNode* node = NULL)
62144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      : ast_printer_(printer) {
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ast_printer_->PrintIndented(txt);
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ast_printer_->Print("\n");
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ast_printer_->inc_indent();
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~IndentedScope() {
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ast_printer_->dec_indent();
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  AstPrinter* ast_printer_;
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//-----------------------------------------------------------------------------
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockAstPrinter::AstPrinter() : indent_(0) {
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAstPrinter::~AstPrinter() {
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(indent_ == 0);
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintIndented(const char* txt) {
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < indent_; i++) {
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Print(". ");
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(txt);
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintLiteralIndented(const char* info,
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Handle<Object> value,
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      bool quote) {
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndented(info);
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print(" ");
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteral(value, quote);
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Print("\n");
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintLiteralWithModeIndented(const char* info,
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                              Variable* var,
6688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                              Handle<Object> value) {
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (var == NULL) {
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteralIndented(info, value, true);
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EmbeddedVector<char, 256> buf;
6734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
6744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                           Variable::Mode2String(var->mode()));
6754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    OS::SNPrintF(buf + pos, ")");
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteralIndented(buf.start(), value, true);
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) {
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (labels != NULL && labels->length() > 0) {
683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    PrintIndented(info == NULL ? "LABELS" : info);
684589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Print(" ");
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLabels(labels);
686589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Print("\n");
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (info != NULL) {
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintIndented(info);
689589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Print("\n");
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, s, node);
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node);
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* AstPrinter::PrintProgram(FunctionLiteral* program) {
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Init();
70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { IndentedScope indent(this, "FUNC");
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteralIndented("NAME", program->name(), true);
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintParameters(program->scope());
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintDeclarations(program->scope()->declarations());
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintStatements(program->body());
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Output();
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (declarations->length() > 0) {
71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope indent(this, "DECLS");
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < declarations->length(); i++) {
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Visit(declarations->at(i));
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintParameters(Scope* scope) {
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (scope->num_parameters() > 0) {
72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope indent(this, "PARAMS");
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < scope->num_parameters(); i++) {
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      PrintLiteralWithModeIndented("VAR", scope->parameter(i),
7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                   scope->parameter(i)->name());
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < statements->length(); i++) {
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(statements->at(i));
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < arguments->length(); i++) {
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(arguments->at(i));
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::PrintCaseClause(CaseClause* clause) {
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (clause->is_default()) {
75044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope indent(this, "DEFAULT");
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintStatements(clause->statements());
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
75344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope indent(this, "CASE");
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(clause->label());
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintStatements(clause->statements());
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitBlock(Block* node) {
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, block_txt);
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintStatements(node->statements());
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               node->proxy()->var(),
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               node->proxy()->name());
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintIndented("FUNCTION ");
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), true);
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print(" = function ");
7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->fun()->name(), false);
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Print("\n");
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IndentedScope indent(this, "MODULE");
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteralIndented("NAME", node->proxy()->name(), true);
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->module());
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IndentedScope indent(this, "IMPORT");
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteralIndented("NAME", node->proxy()->name(), true);
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->module());
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IndentedScope indent(this, "EXPORT ");
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteral(node->proxy()->name(), true);
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VisitBlock(node->body());
8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitModuleVariable(ModuleVariable* node) {
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Visit(node->proxy());
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitModulePath(ModulePath* node) {
8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IndentedScope indent(this, "PATH");
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintIndentedVisit("MODULE", node->module());
8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteralIndented("NAME", node->name(), false);
8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid AstPrinter::VisitModuleUrl(ModuleUrl* node) {
8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrintLiteralIndented("URL", node->url(), true);
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndented("EMPTY\n");
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitIfStatement(IfStatement* node) {
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("IF", node->condition());
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("THEN", node->then_statement());
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->HasElseStatement()) {
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintIndentedVisit("ELSE", node->else_statement());
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitContinueStatement(ContinueStatement* node) {
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabelsIndented("CONTINUE", node->target()->labels());
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitBreakStatement(BreakStatement* node) {
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabelsIndented("BREAK", node->target()->labels());
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitReturnStatement(ReturnStatement* node) {
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("RETURN", node->expression());
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid AstPrinter::VisitWithStatement(WithStatement* node) {
86069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  IndentedScope indent(this, "WITH");
86169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  PrintIndentedVisit("OBJECT", node->expression());
86269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  PrintIndentedVisit("BODY", node->statement());
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
86744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "SWITCH");
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabelsIndented(NULL, node->labels());
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("TAG", node->tag());
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->cases()->length(); i++) {
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintCaseClause(node->cases()->at(i));
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
87744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "DO");
8783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintLabelsIndented(NULL, node->labels());
8793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintIndentedVisit("BODY", node->body());
8803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintIndentedVisit("COND", node->cond());
8813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
8823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstPrinter::VisitWhileStatement(WhileStatement* node) {
88544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "WHILE");
8863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintLabelsIndented(NULL, node->labels());
8873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintIndentedVisit("COND", node->cond());
8883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintIndentedVisit("BODY", node->body());
8893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
8903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstPrinter::VisitForStatement(ForStatement* node) {
89344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "FOR");
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLabelsIndented(NULL, node->labels());
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->init()) PrintIndentedVisit("INIT", node->init());
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->cond()) PrintIndentedVisit("COND", node->cond());
8973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  PrintIndentedVisit("BODY", node->body());
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->next()) PrintIndentedVisit("NEXT", node->next());
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitForInStatement(ForInStatement* node) {
90344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "FOR IN");
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("FOR", node->each());
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("IN", node->enumerable());
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("BODY", node->body());
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
91144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "TRY CATCH");
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("TRY", node->try_block());
9133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PrintLiteralWithModeIndented("CATCHVAR",
9143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                               node->variable(),
9153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                               node->variable()->name());
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("CATCH", node->catch_block());
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
92144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "TRY FINALLY");
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("TRY", node->try_block());
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("FINALLY", node->finally_block());
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
92844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "DEBUGGER");
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
93344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "FUNC LITERAL");
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("NAME", node->name(), false);
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintParameters(node->scope());
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We don't want to see the function literal in this case: it
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // will be printed via PrintProgram when the code for it is
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // generated.
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // PrintStatements(node->body());
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9446ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid AstPrinter::VisitSharedFunctionInfoLiteral(
9456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    SharedFunctionInfoLiteral* node) {
94644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "FUNC LITERAL");
9476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitConditional(Conditional* node) {
95244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "CONDITIONAL");
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("?", node->condition());
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("THEN", node->then_expression());
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("ELSE", node->else_expression());
956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitLiteral(Literal* node) {
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("LITERAL", node->handle(), true);
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
96544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "REGEXP LITERAL");
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("PATTERN", node->pattern(), false);
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("FLAGS", node->flags(), false);
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
97244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "OBJ LITERAL");
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->properties()->length(); i++) {
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const char* prop_kind = NULL;
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    switch (node->properties()->at(i)->kind()) {
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::CONSTANT:
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - CONSTANT";
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::COMPUTED:
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - COMPUTED";
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::PROTOTYPE:
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - PROTOTYPE";
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::GETTER:
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - GETTER";
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case ObjectLiteral::Property::SETTER:
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        prop_kind = "PROPERTY - SETTER";
993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      default:
995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        UNREACHABLE();
996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
99744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope prop(this, prop_kind);
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintIndentedVisit("KEY", node->properties()->at(i)->key());
999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "ARRAY LITERAL");
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->values()->length() > 0) {
100744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    IndentedScope indent(this, "VALUES");
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < node->values()->length(); i++) {
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Visit(node->values()->at(i));
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitVariableProxy(VariableProxy* node) {
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* var = node->var();
1017589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  EmbeddedVector<char, 128> buf;
1018589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int pos = OS::SNPrintF(buf, "VAR PROXY");
1019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (var->location()) {
1020589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case Variable::UNALLOCATED:
1021589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1022589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case Variable::PARAMETER:
1023589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      OS::SNPrintF(buf + pos, " parameter[%d]", var->index());
1024589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1025589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case Variable::LOCAL:
1026589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      OS::SNPrintF(buf + pos, " local[%d]", var->index());
1027589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1028589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case Variable::CONTEXT:
1029589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      OS::SNPrintF(buf + pos, " context[%d]", var->index());
1030589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1031589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case Variable::LOOKUP:
1032589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      OS::SNPrintF(buf + pos, " lookup");
1033589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1035589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  PrintLiteralWithModeIndented(buf.start(), var, node->name());
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitAssignment(Assignment* node) {
104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, Token::Name(node->op()), node);
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->target());
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->value());
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitThrow(Throw* node) {
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit("THROW", node->exception());
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitProperty(Property* node) {
105244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "PROPERTY", node);
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->obj());
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Literal* literal = node->key()->AsLiteral();
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (literal != NULL && literal->handle()->IsSymbol()) {
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintLiteralIndented("NAME", literal->handle(), false);
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PrintIndentedVisit("KEY", node->key());
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitCall(Call* node) {
106444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "CALL");
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitCallNew(CallNew* node) {
107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "CALL NEW");
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitCallRuntime(CallRuntime* node) {
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintLiteralIndented("CALL RUNTIME ", node->name(), false);
107944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this);
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintArguments(node->arguments());
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit(Token::Name(node->op()), node->expression());
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitCountOperation(CountOperation* node) {
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmbeddedVector<char, 128> buf;
10918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
10928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch               Token::Name(node->op()));
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndentedVisit(buf.start(), node->expression());
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
109844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, Token::Name(node->op()), node);
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitCompareOperation(CompareOperation* node) {
110544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, Token::Name(node->op()), node);
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstPrinter::VisitThisFunction(ThisFunction* node) {
111244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IndentedScope indent(this, "THIS-FUNCTION");
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // DEBUG
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1118