ref: 948d6a9fa86fa0e10f0a7674873ac08f0627a173
parent: 747a93838216bb85d7184d75143cbc759fadf3aa
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 9 22:27:52 EST 2014
Pretty-print AST to javascript syntax.
--- a/js-ast.c
+++ b/js-ast.c
@@ -148,7 +148,7 @@
putchar('\t');}
-void printlist(js_Ast *n, int level, const char *sep)
+static void printlist(js_Ast *n, int level, const char *sep)
{ while (n) {printast(n->a, level);
@@ -163,11 +163,47 @@
while (n) {indent(level);
printast(n->a, level);
- putchar('\n');+ if (n->a->type < STM_BLOCK) // expression
+ putchar(';');n = n->b;
+ if (n)
+ putchar('\n');}
}
+static void printstm(js_Ast *n, int level)
+{+ if (n->type == STM_BLOCK) {+ printf(" {\n");+ printblock(n->a, level + 1);
+ putchar('\n');+ indent(level);
+ printf("}");+ } else {+ putchar('\n');+ indent(level + 1);
+ printast(n, level + 1);
+ if (n->type < STM_BLOCK) // expression
+ putchar(';');+ }
+}
+
+static void printunary(int level, js_Ast *n, const char *pre, const char *suf)
+{+ printf(pre);
+ printast(n, level);
+ printf(suf);
+}
+
+static void printbinary(int level, js_Ast *a, js_Ast *b, const char *op)
+{+ printf("(");+ printast(a, level);
+ printf(" %s ", op);+ printast(b, level);
+ printf(")");+}
+
void printast(js_Ast *n, int level)
{ switch (n->type) {@@ -180,13 +216,322 @@
printlist(n, level, " ");
putchar(']');break;
+
case STM_BLOCK:
putchar('{'); putchar('\n');printblock(n->a, level + 1);
+ putchar('\n');indent(level);
putchar('}');break;
+
+ case STM_FOR:
+ printf("for (");+ printast(n->a, level); printf("; ");+ printast(n->b, level); printf("; ");+ printast(n->c, level); printf(")");+ printstm(n->d, level);
+ break;
+ case STM_FOR_VAR:
+ printf("for (var ");+ printlist(n->a, level, ", "); printf("; ");+ printast(n->b, level); printf("; ");+ printast(n->c, level); printf(")");+ printstm(n->d, level);
+ break;
+ case STM_FOR_IN:
+ printf("for (");+ printast(n->a, level); printf(" in ");+ printast(n->b, level); printf(")");+ printstm(n->c, level);
+ break;
+ case STM_FOR_IN_VAR:
+ printf("for (var ");+ printlist(n->a, level, ", "); printf(" in ");+ printast(n->b, level); printf(")");+ printstm(n->c, level);
+ break;
+
+ case STM_NOP:
+ putchar(';');+ break;
+
+ case STM_VAR:
+ printf("var ");+ printlist(n->a, level, ", ");
+ putchar(';');+ break;
+
+ case STM_IF:
+ printf("if (");+ printast(n->a, level);
+ printf(")");+ printstm(n->b, level);
+ if (n->c) {+ putchar('\n');+ indent(level);
+ printf("else");+ printstm(n->c, level);
+ }
+ break;
+
+ case STM_DO:
+ printf("do");+ printstm(n->a, level);
+ if (n->a->type == STM_BLOCK) {+ putchar(' ');+ } else {+ putchar('\n');+ indent(level);
+ }
+ printf("while (");+ printast(n->b, level);
+ printf(");");+ break;
+
+ case STM_WHILE:
+ printf("while (");+ printast(n->a, level);
+ printf(")");+ printstm(n->b, level);
+ break;
+
+ case STM_CONTINUE:
+ if (n->a) {+ printf("continue ");+ printast(n->a, level);
+ printf(";");+ } else {+ printf("continue;");+ }
+ break;
+
+ case STM_BREAK:
+ if (n->a) {+ printf("break ");+ printast(n->a, level);
+ printf(";");+ } else {+ printf("break;");+ }
+ break;
+
+ case STM_RETURN:
+ if (n->a) {+ printf("return ");+ printast(n->a, level);
+ printf(";");+ } else {+ printf("return;");+ }
+ break;
+
+ case STM_THROW:
+ printf("throw ");+ printast(n->a, level);
+ printf(";");+ break;
+
+ case STM_SWITCH:
+ printf("switch (");+ printast(n->a, level);
+ printf(")");+ printstm(n->b, level);
+ break;
+
+ case STM_CASE:
+ printf("case ");+ printast(n->a, level);
+ printf(":");+ if (n->b) {+ printf("\n");+ printblock(n->b, level + 1);
+ }
+ break;
+
+ case STM_DEFAULT:
+ printf("default:");+ if (n->a) {+ printf("\n");+ printblock(n->a, level + 1);
+ }
+ break;
+
+ case STM_LABEL:
+ printast(n->a, level);
+ printf(":");+ printstm(n->b, level - 1);
+ break;
+
+ case STM_WITH:
+ printf("with (");+ printast(n->a, level);
+ printf(")");+ printstm(n->b, level);
+ break;
+
+ case STM_TRY:
+ printf("try");+ printstm(n->a, level);
+ if (n->b && n->c) {+ printf(" catch (");+ printast(n->b, level);
+ printf(")");+ printstm(n->c, level);
+ }
+ if (n->d) {+ printf(" finally");+ printstm(n->d, level);
+ }
+ break;
+
+ case STM_DEBUGGER:
+ printf("debugger");+ break;
+
+ case AST_INIT:
+ printast(n->a, level);
+ if (n->b) {+ printf(" = ");+ printast(n->b, level);
+ }
+ break;
+
+ case STM_FUNC:
+ printf("function ");+ printast(n->a, level);
+ printf("(");+ printlist(n->b, level, ", ");
+ printf(")");+ printstm(n->c, level);
+ break;
+
+ case EXP_FUNC:
+ printf("(function ");+ if (n->a)
+ printast(n->a, level);
+ printf("(");+ printlist(n->b, level, ", ");
+ printf(")");+ printstm(n->c, level);
+ printf(")");+ break;
+
+ case EXP_OBJECT:
+ printf("{ ");+ printlist(n->a, level, ", ");
+ printf(" }");+ break;
+
+ case EXP_PROP_VAL:
+ printast(n->a, level);
+ printf(": ");+ printast(n->b, level);
+ break;
+
+ case EXP_ARRAY:
+ printf("[ ");+ printlist(n->a, level, ", ");
+ printf(" ]");+ break;
+
+ case EXP_NEW:
+ printf("(new ");+ printast(n->a, level);
+ printf("(");+ printlist(n->b, level, ", ");
+ printf("))");+ break;
+
+ case EXP_CALL:
+ printf("(");+ printast(n->a, level);
+ printf("(");+ printlist(n->b, level, ", ");
+ printf("))");+ break;
+
+ case EXP_MEMBER:
+ printf("(");+ printast(n->a, level);
+ printf(".");+ printast(n->b, level);
+ printf(")");+ break;
+
+ case EXP_INDEX:
+ printf("(");+ printast(n->a, level);
+ printf("[");+ printast(n->b, level);
+ printf("])");+ break;
+
+ case EXP_COND:
+ printf("(");+ printast(n->a, level);
+ printf(" ? ");+ printast(n->b, level);
+ printf(" : ");+ printast(n->c, level);
+ printf(")");+ break;
+
+ case EXP_NULL: printf("null"); break;+ case EXP_TRUE: printf("true"); break;+ case EXP_FALSE: printf("false"); break;+ case EXP_THIS: printf("this"); break;+
+ case EXP_DELETE: printunary(level, n->a, "(delete ", ")"); break;
+ case EXP_VOID: printunary(level, n->a, "(void ", ")"); break;
+ case EXP_TYPEOF: printunary(level, n->a, "(typeof ", ")"); break;
+ case EXP_PREINC: printunary(level, n->a, "(++", ")"); break;
+ case EXP_PREDEC: printunary(level, n->a, "(--", ")"); break;
+ case EXP_POSTINC: printunary(level, n->a, "(", "++)"); break;+ case EXP_POSTDEC: printunary(level, n->a, "(", "--)"); break;+ case EXP_POS: printunary(level, n->a, "(+", ")"); break;
+ case EXP_NEG: printunary(level, n->a, "(-", ")"); break;
+ case EXP_BITNOT: printunary(level, n->a, "(~", ")"); break;
+ case EXP_LOGNOT: printunary(level, n->a, "(!", ")"); break;
+
+ case EXP_COMMA: printbinary(level, n->a, n->b, ","); break;
+ case EXP_LOGOR: printbinary(level, n->a, n->b, "||"); break;
+ case EXP_LOGAND: printbinary(level, n->a, n->b, "&&"); break;
+ case EXP_BITOR: printbinary(level, n->a, n->b, "|"); break;
+ case EXP_BITXOR: printbinary(level, n->a, n->b, "^"); break;
+ case EXP_BITAND: printbinary(level, n->a, n->b, "&"); break;
+ case EXP_EQ: printbinary(level, n->a, n->b, "=="); break;
+ case EXP_NE: printbinary(level, n->a, n->b, "!="); break;
+ case EXP_EQ3: printbinary(level, n->a, n->b, "==="); break;
+ case EXP_NE3: printbinary(level, n->a, n->b, "!=="); break;
+ case EXP_LT: printbinary(level, n->a, n->b, "<"); break;
+ case EXP_GT: printbinary(level, n->a, n->b, ">"); break;
+ case EXP_LE: printbinary(level, n->a, n->b, "<="); break;
+ case EXP_GE: printbinary(level, n->a, n->b, ">="); break;
+ case EXP_INSTANCEOF: printbinary(level, n->a, n->b, "instanceof"); break;
+ case EXP_IN: printbinary(level, n->a, n->b, "in"); break;
+ case EXP_SHL: printbinary(level, n->a, n->b, "<<"); break;
+ case EXP_SHR: printbinary(level, n->a, n->b, ">>"); break;
+ case EXP_USHR: printbinary(level, n->a, n->b, ">>>"); break;
+ case EXP_ADD: printbinary(level, n->a, n->b, "+"); break;
+ case EXP_SUB: printbinary(level, n->a, n->b, "-"); break;
+ case EXP_MUL: printbinary(level, n->a, n->b, "*"); break;
+ case EXP_DIV: printbinary(level, n->a, n->b, "/"); break;
+ case EXP_MOD: printbinary(level, n->a, n->b, "%"); break;
+ case EXP_ASS: printbinary(level, n->a, n->b, "="); break;
+ case EXP_ASS_MUL: printbinary(level, n->a, n->b, "*="); break;
+ case EXP_ASS_DIV: printbinary(level, n->a, n->b, "/="); break;
+ case EXP_ASS_MOD: printbinary(level, n->a, n->b, "%="); break;
+ case EXP_ASS_ADD: printbinary(level, n->a, n->b, "+="); break;
+ case EXP_ASS_SUB: printbinary(level, n->a, n->b, "-="); break;
+ case EXP_ASS_SHL: printbinary(level, n->a, n->b, "<<="); break;
+ case EXP_ASS_SHR: printbinary(level, n->a, n->b, ">>="); break;
+ case EXP_ASS_USHR: printbinary(level, n->a, n->b, ">>>="); break;
+ case EXP_ASS_BITAND: printbinary(level, n->a, n->b, "&="); break;
+ case EXP_ASS_BITXOR: printbinary(level, n->a, n->b, "^="); break;
+ case EXP_ASS_BITOR: printbinary(level, n->a, n->b, "|="); break;
+
default:
printf("(%s", strast(n->type)); if (n->a) { putchar(' '); printast(n->a, level); }--- a/js-ast.h
+++ b/js-ast.h
@@ -122,5 +122,6 @@
void jsP_freeast(js_State *J);
void printast(js_Ast *n, int level);
+void printblock(js_Ast *n, int level);
#endif
--- a/js-parse.c
+++ b/js-parse.c
@@ -836,7 +836,7 @@
}
next(J);
- printast(sourcelist(J), 0);
+ printblock(sourcelist(J)->a, 0);
putchar('\n');// TODO: compile to bytecode
--
⑨