History

Add pretty-printing command line tool.

Tor Andersson committed 8 years ago

Commit d04cbf31 parent 25821e64 files · +300 −126Browse files

Unified · Split

4 files
  1. Makefile +21 −15
  2. jsdump.c +163 −110
  3. jsparse.h +1 −1
  4. pp.c +115 −0
Makefile+21−15
@@ -8,9 +8,9 @@ incdir ?= $(prefix)/include · 7 unmodified lines
8libdir ?= $(prefix)/lib8libdir ?= $(prefix)/lib
9 9
10ifeq "$(wildcard .git)" ".git"10ifeq "$(wildcard .git)" ".git"
11VERSION := $(shell git describe --tags --always)11 VERSION := $(shell git describe --tags --always)
12else12else
13VERSION := $(shell basename $$PWD | sed -e s,^mujs-,,)13 VERSION := $(shell basename $$PWD | sed -e s,^mujs-,,)
14endif14endif
15 15
16# Compiler flags for various configurations:16# Compiler flags for various configurations:
@@ -18,22 +18,22 @@ endif · 1 unmodified line
18CFLAGS := -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter18CFLAGS := -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter
19 19
20ifeq "$(CC)" "clang"20ifeq "$(CC)" "clang"
21CFLAGS += -Wunreachable-code21 CFLAGS += -Wunreachable-code
22endif22endif
23 23
24ifeq "$(shell uname)" "Linux"24ifeq "$(shell uname)" "Linux"
25CFLAGS += -ffunction-sections -fdata-sections25 CFLAGS += -ffunction-sections -fdata-sections
26LDFLAGS += -Wl,--gc-sections26 LDFLAGS += -Wl,--gc-sections
27endif27endif
28 28
29ifeq "$(build)" "debug"29ifeq "$(build)" "debug"
30CFLAGS += -g30 CFLAGS += -g
31else ifeq "$(build)" "sanitize"31else ifeq "$(build)" "sanitize"
32CFLAGS += -pipe -g -fsanitize=address -fno-omit-frame-pointer32 CFLAGS += -pipe -g -fsanitize=address -fno-omit-frame-pointer
33LDFLAGS += -fsanitize=address33 LDFLAGS += -fsanitize=address
34else34else
35CFLAGS += -Os35 CFLAGS += -Os
36LDFLAGS += -Wl,-s36 LDFLAGS += -Wl,-s
37endif37endif
38 38
39CFLAGS += $(XCFLAGS)39CFLAGS += $(XCFLAGS)
@@ -46,7 +46,7 @@ SRCS := $(wildcard js*.c utf*.c regexp.c) · 6 unmodified lines
46HDRS := $(wildcard js*.h mujs.h utf.h regexp.h)46HDRS := $(wildcard js*.h mujs.h utf.h regexp.h)
47 47
48default: static48default: static
49static: $(OUT) $(OUT)/mujs $(OUT)/libmujs.a $(OUT)/mujs.pc49static: $(OUT)/mujs-pp $(OUT)/mujs $(OUT)/libmujs.a $(OUT)/mujs.pc
50shared: static $(OUT)/libmujs.so50shared: static $(OUT)/libmujs.so
51 51
52astnames.h: jsparse.h52astnames.h: jsparse.h
@@ -60,22 +60,28 @@ one.c: $(SRCS) · 7 unmodified lines
60 60
61jsdump.c: astnames.h opnames.h61jsdump.c: astnames.h opnames.h
62 62
63$(OUT):63$(OUT)/%.o: %.c $(HDRS)
64 mkdir -p $(OUT)64 @ mkdir -p $(dir $@)
65
66$(OUT)/main.o: main.c $(HDRS)
67 $(CC) $(CFLAGS) -o $@ -c $<65 $(CC) $(CFLAGS) -o $@ -c $<
68 66
69$(OUT)/libmujs.o: one.c $(HDRS)67$(OUT)/libmujs.o: one.c $(HDRS)
68 @ mkdir -p $(dir $@)
70 $(CC) $(CFLAGS) -o $@ -c $<69 $(CC) $(CFLAGS) -o $@ -c $<
71 70
72$(OUT)/libmujs.a: $(OUT)/libmujs.o71$(OUT)/libmujs.a: $(OUT)/libmujs.o
72 @ mkdir -p $(dir $@)
73 $(AR) cru $@ $^73 $(AR) cru $@ $^
74 74
75$(OUT)/libmujs.so: one.c $(HDRS)75$(OUT)/libmujs.so: one.c $(HDRS)
76 @ mkdir -p $(dir $@)
76 $(CC) $(CFLAGS) -fPIC -shared -o $@ $< -lm77 $(CC) $(CFLAGS) -fPIC -shared -o $@ $< -lm
77 78
78$(OUT)/mujs: $(OUT)/libmujs.o $(OUT)/main.o79$(OUT)/mujs: $(OUT)/libmujs.o $(OUT)/main.o
80 @ mkdir -p $(dir $@)
81 $(CC) $(LDFLAGS) -o $@ $^ -lm
82
83$(OUT)/mujs-pp: $(OUT)/libmujs.o $(OUT)/pp.o
84 @ mkdir -p $(dir $@)
79 $(CC) $(LDFLAGS) -o $@ $^ -lm85 $(CC) $(LDFLAGS) -o $@ $^ -lm
80 86
81$(OUT)/mujs.pc:87$(OUT)/mujs.pc:
jsdump.c+163−110
@@ -17,6 +17,8 @@ static const char *opname[] = { · 16 unmodified lines
17NULL17NULL
18};18};
19 19
20static int minify = 0;
21
20const char *jsP_aststring(enum js_AstType type)22const char *jsP_aststring(enum js_AstType type)
21{23{
22 if (type < nelem(astname)-1)24 if (type < nelem(astname)-1)
@@ -34,6 +36,7 @@ const char *jsC_opcodestring(enum js_OpCode opcode) · 11 unmodified lines
34static int prec(enum js_AstType type)36static int prec(enum js_AstType type)
35{37{
36 switch (type) {38 switch (type) {
39 case AST_IDENTIFIER:
37 case EXP_IDENTIFIER:40 case EXP_IDENTIFIER:
38 case EXP_NUMBER:41 case EXP_NUMBER:
39 case EXP_STRING:42 case EXP_STRING:
@@ -142,13 +145,27 @@ static void ps(const char *s) · 102 unmodified lines
142 145
143static void in(int d)146static void in(int d)
144{147{
145 while (d-- > 0)148 if (minify < 1)
146 putchar('\t');149 while (d-- > 0)
150 putchar('\t');
147}151}
148 152
149static void nl(void)153static void nl(void)
150{154{
151 putchar('\n');155 if (minify < 2)
156 putchar('\n');
157}
158
159static void sp(void)
160{
161 if (minify < 1)
162 putchar(' ');
163}
164
165static void comma(void)
166{
167 putchar(',');
168 sp();
152}169}
153 170
154/* Pretty-printed Javascript syntax */171/* Pretty-printed Javascript syntax */
@@ -166,68 +183,79 @@ static void pargs(int d, js_Ast *list) · 11 unmodified lines
166 pexpi(d, COMMA, list->a);183 pexpi(d, COMMA, list->a);
167 list = list->b;184 list = list->b;
168 if (list)185 if (list)
169 ps(", ");186 comma();
170 }187 }
171}188}
172 189
173static void parray(int d, js_Ast *list)190static void parray(int d, js_Ast *list)
174{191{
175 ps("[");192 pc('[');
176 while (list) {193 while (list) {
177 assert(list->type == AST_LIST);194 assert(list->type == AST_LIST);
178 pexpi(d, COMMA, list->a);195 pexpi(d, COMMA, list->a);
179 list = list->b;196 list = list->b;
180 if (list)197 if (list)
181 ps(", ");198 comma();
182 }199 }
183 ps("]");200 pc(']');
184}201}
185 202
186static void pobject(int d, js_Ast *list)203static void pobject(int d, js_Ast *list)
187{204{
188 ps("{");205 pc('{');
206 if (list) {
207 nl();
208 in(d+1);
209 }
189 while (list) {210 while (list) {
190 js_Ast *kv = list->a;211 js_Ast *kv = list->a;
191 assert(list->type == AST_LIST);212 assert(list->type == AST_LIST);
192 switch (kv->type) {213 switch (kv->type) {
193 default: break;214 default: break;
194 case EXP_PROP_VAL:215 case EXP_PROP_VAL:
195 pexpi(d, COMMA, kv->a);216 pexpi(d+1, COMMA, kv->a);
196 ps(": ");217 pc(':'); sp();
197 pexpi(d, COMMA, kv->b);218 pexpi(d+1, COMMA, kv->b);
198 break;219 break;
199 case EXP_PROP_GET:220 case EXP_PROP_GET:
200 ps("get ");221 ps("get ");
201 pexpi(d, COMMA, kv->a);222 pexpi(d+1, COMMA, kv->a);
202 ps("() {\n");223 ps("()"); sp(); pc('{'); nl();
203 pstmlist(d, kv->c);224 pstmlist(d+1, kv->c);
204 in(d); ps("}");225 in(d+1); pc('}');
205 break;226 break;
206 case EXP_PROP_SET:227 case EXP_PROP_SET:
207 ps("set ");228 ps("set ");
208 pexpi(d, COMMA, kv->a);229 pexpi(d+1, COMMA, kv->a);
209 ps("(");230 pc('(');
210 pargs(d, kv->b);231 pargs(d+1, kv->b);
211 ps(") {\n");232 pc(')'); sp(); pc('{'); nl();
212 pstmlist(d, kv->c);233 pstmlist(d+1, kv->c);
213 in(d); ps("}");234 in(d+1); pc('}');
214 break;235 break;
215 }236 }
216 list = list->b;237 list = list->b;
217 if (list)238 if (list) {
218 ps(", ");239 pc(',');
240 nl();
241 in(d+1);
242 } else {
243 nl();
244 in(d);
245 }
219 }246 }
220 ps("}");247 pc('}');
221}248}
222 249
223static void pstr(const char *s)250static void pstr(const char *s)
224{251{
225 static const char *HEX = "0123456789ABCDEF";252 static const char *HEX = "0123456789ABCDEF";
226 Rune c;253 Rune c;
227 pc('"');254 pc(minify ? '\'' : '"');
228 while (*s) {255 while (*s) {
229 s += chartorune(&c, s);256 s += chartorune(&c, s);
230 switch (c) {257 switch (c) {
258 case '\'': ps("\\'"); break;
231 case '"': ps("\\\""); break;259 case '"': ps("\\\""); break;
232 case '\\': ps("\\\\"); break;260 case '\\': ps("\\\\"); break;
233 case '\b': ps("\\b"); break;261 case '\b': ps("\\b"); break;
@@ -247,7 +275,7 @@ static void pstr(const char *s) · 13 unmodified lines
247 }275 }
248 }276 }
249 }277 }
250 pc('"');278 pc(minify ? '\'' : '"');
251}279}
252 280
253static void pregexp(const char *prog, int flags)281static void pregexp(const char *prog, int flags)
@@ -263,7 +291,9 @@ static void pregexp(const char *prog, int flags) · 9 unmodified lines
263static void pbin(int d, int p, js_Ast *exp, const char *op)291static void pbin(int d, int p, js_Ast *exp, const char *op)
264{292{
265 pexpi(d, p, exp->a);293 pexpi(d, p, exp->a);
294 sp();
266 ps(op);295 ps(op);
296 sp();
267 pexpi(d, p, exp->b);297 pexpi(d, p, exp->b);
268}298}
269 299
@@ -316,49 +346,58 @@ static void pexpi(int d, int p, js_Ast *exp) · 46 unmodified lines
316 case EXP_BITNOT: puna(d, p, exp, "~", ""); break;346 case EXP_BITNOT: puna(d, p, exp, "~", ""); break;
317 case EXP_LOGNOT: puna(d, p, exp, "!", ""); break;347 case EXP_LOGNOT: puna(d, p, exp, "!", ""); break;
318 348
319 case EXP_LOGOR: pbin(d, p, exp, " || "); break;349 case EXP_LOGOR: pbin(d, p, exp, "||"); break;
320 case EXP_LOGAND: pbin(d, p, exp, " && "); break;350 case EXP_LOGAND: pbin(d, p, exp, "&&"); break;
321 case EXP_BITOR: pbin(d, p, exp, " | "); break;351 case EXP_BITOR: pbin(d, p, exp, "|"); break;
322 case EXP_BITXOR: pbin(d, p, exp, " ^ "); break;352 case EXP_BITXOR: pbin(d, p, exp, "^"); break;
323 case EXP_BITAND: pbin(d, p, exp, " & "); break;353 case EXP_BITAND: pbin(d, p, exp, "&"); break;
324 case EXP_EQ: pbin(d, p, exp, " == "); break;354 case EXP_EQ: pbin(d, p, exp, "=="); break;
325 case EXP_NE: pbin(d, p, exp, " != "); break;355 case EXP_NE: pbin(d, p, exp, "!="); break;
326 case EXP_STRICTEQ: pbin(d, p, exp, " === "); break;356 case EXP_STRICTEQ: pbin(d, p, exp, "==="); break;
327 case EXP_STRICTNE: pbin(d, p, exp, " !== "); break;357 case EXP_STRICTNE: pbin(d, p, exp, "!=="); break;
328 case EXP_LT: pbin(d, p, exp, " < "); break;358 case EXP_LT: pbin(d, p, exp, "<"); break;
329 case EXP_GT: pbin(d, p, exp, " > "); break;359 case EXP_GT: pbin(d, p, exp, ">"); break;
330 case EXP_LE: pbin(d, p, exp, " <= "); break;360 case EXP_LE: pbin(d, p, exp, "<="); break;
331 case EXP_GE: pbin(d, p, exp, " >= "); break;361 case EXP_GE: pbin(d, p, exp, ">="); break;
332 case EXP_INSTANCEOF: pbin(d, p, exp, " instanceof "); break;362 case EXP_IN: pbin(d, p, exp, "in"); break;
333 case EXP_IN: pbin(d, p, exp, " in "); break;363 case EXP_SHL: pbin(d, p, exp, "<<"); break;
334 case EXP_SHL: pbin(d, p, exp, " << "); break;364 case EXP_SHR: pbin(d, p, exp, ">>"); break;
335 case EXP_SHR: pbin(d, p, exp, " >> "); break;365 case EXP_USHR: pbin(d, p, exp, ">>>"); break;
336 case EXP_USHR: pbin(d, p, exp, " >>> "); break;366 case EXP_ADD: pbin(d, p, exp, "+"); break;
337 case EXP_ADD: pbin(d, p, exp, " + "); break;367 case EXP_SUB: pbin(d, p, exp, "-"); break;
338 case EXP_SUB: pbin(d, p, exp, " - "); break;368 case EXP_MUL: pbin(d, p, exp, "*"); break;
339 case EXP_MUL: pbin(d, p, exp, " * "); break;369 case EXP_DIV: pbin(d, p, exp, "/"); break;
340 case EXP_DIV: pbin(d, p, exp, " / "); break;370 case EXP_MOD: pbin(d, p, exp, "%"); break;
341 case EXP_MOD: pbin(d, p, exp, " % "); break;371 case EXP_ASS: pbin(d, p, exp, "="); break;
342 case EXP_ASS: pbin(d, p, exp, " = "); break;372 case EXP_ASS_MUL: pbin(d, p, exp, "*="); break;
343 case EXP_ASS_MUL: pbin(d, p, exp, " *= "); break;373 case EXP_ASS_DIV: pbin(d, p, exp, "/="); break;
344 case EXP_ASS_DIV: pbin(d, p, exp, " /= "); break;374 case EXP_ASS_MOD: pbin(d, p, exp, "%="); break;
345 case EXP_ASS_MOD: pbin(d, p, exp, " %= "); break;375 case EXP_ASS_ADD: pbin(d, p, exp, "+="); break;
346 case EXP_ASS_ADD: pbin(d, p, exp, " += "); break;376 case EXP_ASS_SUB: pbin(d, p, exp, "-="); break;
347 case EXP_ASS_SUB: pbin(d, p, exp, " -= "); break;377 case EXP_ASS_SHL: pbin(d, p, exp, "<<="); break;
348 case EXP_ASS_SHL: pbin(d, p, exp, " <<= "); break;378 case EXP_ASS_SHR: pbin(d, p, exp, ">>="); break;
349 case EXP_ASS_SHR: pbin(d, p, exp, " >>= "); break;379 case EXP_ASS_USHR: pbin(d, p, exp, ">>>="); break;
350 case EXP_ASS_USHR: pbin(d, p, exp, " >>>= "); break;380 case EXP_ASS_BITAND: pbin(d, p, exp, "&="); break;
351 case EXP_ASS_BITAND: pbin(d, p, exp, " &= "); break;381 case EXP_ASS_BITXOR: pbin(d, p, exp, "^="); break;
352 case EXP_ASS_BITXOR: pbin(d, p, exp, " ^= "); break;382 case EXP_ASS_BITOR: pbin(d, p, exp, "|="); break;
353 case EXP_ASS_BITOR: pbin(d, p, exp, " |= "); break;383
354 384 case EXP_INSTANCEOF:
355 case EXP_COMMA: pbin(d, p, exp, ", "); break;385 pexpi(d, p, exp->a);
386 ps(" instanceof ");
387 pexpi(d, p, exp->b);
388 break;
389
390 case EXP_COMMA:
391 pexpi(d, p, exp->a);
392 pc(','); sp();
393 pexpi(d, p, exp->b);
394 break;
356 395
357 case EXP_COND:396 case EXP_COND:
358 pexpi(d, p, exp->a);397 pexpi(d, p, exp->a);
359 ps(" ? ");398 sp(); pc('?'); sp();
360 pexpi(d, p, exp->b);399 pexpi(d, p, exp->b);
361 ps(" : ");400 sp(); pc(':'); sp();
362 pexpi(d, p, exp->c);401 pexpi(d, p, exp->c);
363 break;402 break;
364 403
@@ -396,7 +435,7 @@ static void pexpi(int d, int p, js_Ast *exp) · 31 unmodified lines
396 pexpi(d, 0, exp->a);435 pexpi(d, 0, exp->a);
397 pc('(');436 pc('(');
398 pargs(d, exp->b);437 pargs(d, exp->b);
399 ps(") {\n");438 pc(')'); sp(); pc('{'); nl();
400 pstmlist(d, exp->c);439 pstmlist(d, exp->c);
401 in(d); pc('}');440 in(d); pc('}');
402 if (p == 0) pc(')');441 if (p == 0) pc(')');
@@ -420,7 +459,7 @@ static void pvar(int d, js_Ast *var) · 17 unmodified lines
420 assert(var->type == EXP_VAR);459 assert(var->type == EXP_VAR);
421 pexp(d, var->a);460 pexp(d, var->a);
422 if (var->b) {461 if (var->b) {
423 ps(" = ");462 sp(); pc('='); sp();
424 pexp(d, var->b);463 pexp(d, var->b);
425 }464 }
426}465}
@@ -432,23 +471,24 @@ static void pvarlist(int d, js_Ast *list) · 5 unmodified lines
432 pvar(d, list->a);471 pvar(d, list->a);
433 list = list->b;472 list = list->b;
434 if (list)473 if (list)
435 ps(", ");474 comma();
436 }475 }
437}476}
438 477
439static void pblock(int d, js_Ast *block)478static void pblock(int d, js_Ast *block)
440{479{
441 assert(block->type == STM_BLOCK);480 assert(block->type == STM_BLOCK);
442 ps(" {\n");481 pc('{'); nl();
443 pstmlist(d, block->a);482 pstmlist(d, block->a);
444 in(d); pc('}');483 in(d); pc('}');
445}484}
446 485
447static void pstmh(int d, js_Ast *stm)486static void pstmh(int d, js_Ast *stm)
448{487{
449 if (stm->type == STM_BLOCK)488 if (stm->type == STM_BLOCK) {
489 sp();
450 pblock(d, stm);490 pblock(d, stm);
451 else {491 } else {
452 nl();492 nl();
453 pstm(d+1, stm);493 pstm(d+1, stm);
454 }494 }
@@ -459,11 +499,11 @@ static void pcaselist(int d, js_Ast *list) · 4 unmodified lines
459 while (list) {499 while (list) {
460 js_Ast *stm = list->a;500 js_Ast *stm = list->a;
461 if (stm->type == STM_CASE) {501 if (stm->type == STM_CASE) {
462 in(d); ps("case "); pexp(d, stm->a); ps(":\n");502 in(d); ps("case "); pexp(d, stm->a); pc(':'); nl();
463 pstmlist(d, stm->b);503 pstmlist(d, stm->b);
464 }504 }
465 if (stm->type == STM_DEFAULT) {505 if (stm->type == STM_DEFAULT) {
466 in(d); ps("default:\n");506 in(d); ps("default:"); nl();
467 pstmlist(d, stm->a);507 pstmlist(d, stm->a);
468 }508 }
469 list = list->b;509 list = list->b;
@@ -485,9 +525,9 @@ static void pstm(int d, js_Ast *stm) · 15 unmodified lines
485 pexp(d, stm->a);525 pexp(d, stm->a);
486 pc('(');526 pc('(');
487 pargs(d, stm->b);527 pargs(d, stm->b);
488 ps(") {\n");528 pc(')'); sp(); pc('{'); nl();
489 pstmlist(d, stm->c);529 pstmlist(d, stm->c);
490 in(d); ps("}");530 in(d); pc('}');
491 break;531 break;
492 532
493 case STM_EMPTY:533 case STM_EMPTY:
@@ -497,11 +537,11 @@ static void pstm(int d, js_Ast *stm) · 3 unmodified lines
497 case STM_VAR:537 case STM_VAR:
498 ps("var ");538 ps("var ");
499 pvarlist(d, stm->a);539 pvarlist(d, stm->a);
500 ps(";");540 pc(';');
501 break;541 break;
502 542
503 case STM_IF:543 case STM_IF:
504 ps("if ("); pexp(d, stm->a); ps(")");544 ps("if"); sp(); pc('('); pexp(d, stm->a); pc(')');
505 pstmh(d, stm->b);545 pstmh(d, stm->b);
506 if (stm->c) {546 if (stm->c) {
507 nl(); in(d); ps("else");547 nl(); in(d); ps("else");
@@ -513,87 +553,89 @@ static void pstm(int d, js_Ast *stm) · 5 unmodified lines
513 ps("do");553 ps("do");
514 pstmh(d, stm->a);554 pstmh(d, stm->a);
515 nl();555 nl();
516 in(d); ps("while ("); pexp(d, stm->b); ps(");");556 in(d); ps("while"); sp(); pc('('); pexp(d, stm->b); pc(')'); pc(';');
517 break;557 break;
518 558
519 case STM_WHILE:559 case STM_WHILE:
520 ps("while ("); pexp(d, stm->a); ps(")");560 ps("while"); sp(); pc('('); pexp(d, stm->a); pc(')');
521 pstmh(d, stm->b);561 pstmh(d, stm->b);
522 break;562 break;
523 563
524 case STM_FOR:564 case STM_FOR:
525 ps("for (");565 ps("for"); sp(); pc('(');
526 pexp(d, stm->a); ps("; ");566 pexp(d, stm->a); pc(';'); sp();
527 pexp(d, stm->b); ps("; ");567 pexp(d, stm->b); pc(';'); sp();
528 pexp(d, stm->c); ps(")");568 pexp(d, stm->c); pc(')');
529 pstmh(d, stm->d);569 pstmh(d, stm->d);
530 break;570 break;
531 case STM_FOR_VAR:571 case STM_FOR_VAR:
532 ps("for (var ");572 ps("for"); sp(); ps("(var ");
533 pvarlist(d, stm->a); ps("; ");573 pvarlist(d, stm->a); pc(';'); sp();
534 pexp(d, stm->b); ps("; ");574 pexp(d, stm->b); pc(';'); sp();
535 pexp(d, stm->c); ps(")");575 pexp(d, stm->c); pc(')');
536 pstmh(d, stm->d);576 pstmh(d, stm->d);
537 break;577 break;
538 case STM_FOR_IN:578 case STM_FOR_IN:
539 ps("for (");579 ps("for"); sp(); pc('(');
540 pexp(d, stm->a); ps(" in ");580 pexp(d, stm->a); ps(" in ");
541 pexp(d, stm->b); ps(")");581 pexp(d, stm->b); pc(')');
542 pstmh(d, stm->c);582 pstmh(d, stm->c);
543 break;583 break;
544 case STM_FOR_IN_VAR:584 case STM_FOR_IN_VAR:
545 ps("for (var ");585 ps("for"); sp(); ps("(var ");
546 pvarlist(d, stm->a); ps(" in ");586 pvarlist(d, stm->a); ps(" in ");
547 pexp(d, stm->b); ps(")");587 pexp(d, stm->b); pc(')');
548 pstmh(d, stm->c);588 pstmh(d, stm->c);
549 break;589 break;
550 590
551 case STM_CONTINUE:591 case STM_CONTINUE:
592 ps("continue");
552 if (stm->a) {593 if (stm->a) {
553 ps("continue "); pexp(d, stm->a); ps(";");594 pc(' '); pexp(d, stm->a);
554 } else {
555 ps("continue;");
556 }595 }
596 pc(';');
557 break;597 break;
558 598
559 case STM_BREAK:599 case STM_BREAK:
600 ps("break");
560 if (stm->a) {601 if (stm->a) {
561 ps("break "); pexp(d, stm->a); ps(";");602 pc(' '); pexp(d, stm->a);
562 } else {
563 ps("break;");
564 }603 }
604 pc(';');
565 break;605 break;
566 606
567 case STM_RETURN:607 case STM_RETURN:
608 ps("return");
568 if (stm->a) {609 if (stm->a) {
569 ps("return "); pexp(d, stm->a); ps(";");610 pc(' '); pexp(d, stm->a);
570 } else {
571 ps("return;");
572 }611 }
612 pc(';');
573 break;613 break;
574 614
575 case STM_WITH:615 case STM_WITH:
576 ps("with ("); pexp(d, stm->a); ps(")");616 ps("with"); sp(); pc('('); pexp(d, stm->a); pc(')');
577 pstmh(d, stm->b);617 pstmh(d, stm->b);
578 break;618 break;
579 619
580 case STM_SWITCH:620 case STM_SWITCH:
581 ps("switch (");621 ps("switch"); sp(); pc('(');
582 pexp(d, stm->a);622 pexp(d, stm->a);
583 ps(") {\n");623 pc(')'); sp(); pc('{'); nl();
584 pcaselist(d, stm->b);624 pcaselist(d, stm->b);
585 in(d); ps("}");625 in(d); pc('}');
586 break;626 break;
587 627
588 case STM_THROW:628 case STM_THROW:
589 ps("throw "); pexp(d, stm->a); ps(";");629 ps("throw "); pexp(d, stm->a); pc(';');
590 break;630 break;
591 631
592 case STM_TRY:632 case STM_TRY:
593 ps("try");633 ps("try");
634 if (minify && stm->a->type != STM_BLOCK)
635 pc(' ');
594 pstmh(d, stm->a);636 pstmh(d, stm->a);
595 if (stm->b && stm->c) {637 if (stm->b && stm->c) {
596 nl(); in(d); ps("catch ("); pexp(d, stm->b); ps(")");638 nl(); in(d); ps("catch"); sp(); pc('('); pexp(d, stm->b); pc(')');
597 pstmh(d, stm->c);639 pstmh(d, stm->c);
598 }640 }
599 if (stm->d) {641 if (stm->d) {
@@ -603,15 +645,17 @@ static void pstm(int d, js_Ast *stm) · 3 unmodified lines
603 break;645 break;
604 646
605 case STM_LABEL:647 case STM_LABEL:
606 pexp(d, stm->a); ps(": "); pstm(d, stm->b);648 pexp(d, stm->a); pc(':'); sp(); pstm(d, stm->b);
607 break;649 break;
608 650
609 case STM_DEBUGGER:651 case STM_DEBUGGER:
610 ps("debugger;");652 ps("debugger");
653 pc(';');
611 break;654 break;
612 655
613 default:656 default:
614 pexp(d, stm); pc(';');657 pexp(d, stm);
658 pc(';');
615 }659 }
616}660}
617 661
@@ -625,14 +669,17 @@ static void pstmlist(int d, js_Ast *list) · 7 unmodified lines
625 }669 }
626}670}
627 671
628void jsP_dumpsyntax(js_State *J, js_Ast *prog)672void jsP_dumpsyntax(js_State *J, js_Ast *prog, int dominify)
629{673{
674 minify = dominify;
630 if (prog->type == AST_LIST)675 if (prog->type == AST_LIST)
631 pstmlist(-1, prog);676 pstmlist(-1, prog);
632 else {677 else {
633 pstm(0, prog);678 pstm(0, prog);
634 nl();679 nl();
635 }680 }
681 if (minify > 1)
682 putchar('\n');
636}683}
637 684
638/* S-expression list representation */685/* S-expression list representation */
@@ -708,6 +755,7 @@ static void sblock(int d, js_Ast *list) · 69 unmodified lines
708 755
709void jsP_dumplist(js_State *J, js_Ast *prog)756void jsP_dumplist(js_State *J, js_Ast *prog)
710{757{
758 minify = 0;
711 if (prog->type == AST_LIST)759 if (prog->type == AST_LIST)
712 sblock(0, prog);760 sblock(0, prog);
713 else761 else
@@ -723,6 +771,8 @@ void jsC_dumpfunction(js_State *J, js_Function *F) · 9 unmodified lines
723 js_Instruction *end = F->code + F->codelen;771 js_Instruction *end = F->code + F->codelen;
724 int i;772 int i;
725 773
774 minify = 0;
775
726 printf("%s(%d)\n", F->name, F->numparams);776 printf("%s(%d)\n", F->name, F->numparams);
727 if (F->lightweight) printf("\tlightweight\n");777 if (F->lightweight) printf("\tlightweight\n");
728 if (F->arguments) printf("\targuments\n");778 if (F->arguments) printf("\targuments\n");
@@ -802,6 +852,7 @@ void jsC_dumpfunction(js_State *J, js_Function *F) · 73 unmodified lines
802 852
803void js_dumpvalue(js_State *J, js_Value v)853void js_dumpvalue(js_State *J, js_Value v)
804{854{
855 minify = 0;
805 switch (v.type) {856 switch (v.type) {
806 case JS_TUNDEFINED: printf("undefined"); break;857 case JS_TUNDEFINED: printf("undefined"); break;
807 case JS_TNULL: printf("null"); break;858 case JS_TNULL: printf("null"); break;
@@ -843,6 +894,7 @@ void js_dumpvalue(js_State *J, js_Value v) · 35 unmodified lines
843 894
844static void js_dumpproperty(js_State *J, js_Property *node)895static void js_dumpproperty(js_State *J, js_Property *node)
845{896{
897 minify = 0;
846 if (node->left->level)898 if (node->left->level)
847 js_dumpproperty(J, node->left);899 js_dumpproperty(J, node->left);
848 printf("\t%s: ", node->name);900 printf("\t%s: ", node->name);
@@ -854,6 +906,7 @@ static void js_dumpproperty(js_State *J, js_Property *node) · 5 unmodified lines
854 906
855void js_dumpobject(js_State *J, js_Object *obj)907void js_dumpobject(js_State *J, js_Object *obj)
856{908{
909 minify = 0;
857 printf("{\n");910 printf("{\n");
858 if (obj->properties->level)911 if (obj->properties->level)
859 js_dumpproperty(J, obj->properties);912 js_dumpproperty(J, obj->properties);
jsparse.h+1−1
@@ -140,7 +140,7 @@ js_Ast *jsP_parse(js_State *J, const char *filename, const char *source); · 139 unmodified lines
140void jsP_freeparse(js_State *J);140void jsP_freeparse(js_State *J);
141 141
142const char *jsP_aststring(enum js_AstType type);142const char *jsP_aststring(enum js_AstType type);
143void jsP_dumpsyntax(js_State *J, js_Ast *prog);143void jsP_dumpsyntax(js_State *J, js_Ast *prog, int minify);
144void jsP_dumplist(js_State *J, js_Ast *prog);144void jsP_dumplist(js_State *J, js_Ast *prog);
145 145
146#endif146#endif
pp.c+115−0
@@ -0,0 +1,115 @@
1/* Pretty-print input source by emitting parse tree back as syntax.
2 * with no flags: pretty-printed source
3 * with -m: minified source with line breaks
4 * with -mm: minified source without line breaks
5 * with -s: s-expression syntax tree
6 */
7
8#include <stdio.h>
9
10#include "jsi.h"
11#include "jsparse.h"
12
13static void js_ppstring(js_State *J, const char *filename, const char *source, int minify)
14{
15 js_Ast *P;
16 if (js_try(J)) {
17 jsP_freeparse(J);
18 js_throw(J);
19 }
20 P = jsP_parse(J, filename, source);
21 if (minify > 2)
22 jsP_dumplist(J, P);
23 else
24 jsP_dumpsyntax(J, P, minify);
25 jsP_freeparse(J);
26 js_endtry(J);
27}
28
29void js_ppfile(js_State *J, const char *filename, int minify)
30{
31 FILE *f;
32 char *s;
33 int n, t;
34
35 f = fopen(filename, "rb");
36 if (!f) {
37 js_error(J, "cannot open file: '%s'", filename);
38 }
39
40 if (fseek(f, 0, SEEK_END) < 0) {
41 fclose(f);
42 js_error(J, "cannot seek in file: '%s'", filename);
43 }
44
45 n = ftell(f);
46 if (n < 0) {
47 fclose(f);
48 js_error(J, "cannot tell in file: '%s'", filename);
49 }
50
51 if (fseek(f, 0, SEEK_SET) < 0) {
52 fclose(f);
53 js_error(J, "cannot seek in file: '%s'", filename);
54 }
55
56 s = js_malloc(J, n + 1); /* add space for string terminator */
57 if (!s) {
58 fclose(f);
59 js_error(J, "cannot allocate storage for file contents: '%s'", filename);
60 }
61
62 t = fread(s, 1, (size_t)n, f);
63 if (t != n) {
64 js_free(J, s);
65 fclose(f);
66 js_error(J, "cannot read data from file: '%s'", filename);
67 }
68
69 s[n] = 0; /* zero-terminate string containing file data */
70
71 if (js_try(J)) {
72 js_free(J, s);
73 fclose(f);
74 js_throw(J);
75 }
76
77 js_ppstring(J, filename, s, minify);
78
79 js_free(J, s);
80 fclose(f);
81 js_endtry(J);
82}
83
84int
85main(int argc, char **argv)
86{
87 js_State *J;
88 int minify = 0;
89 int i;
90
91 J = js_newstate(NULL, NULL, 0);
92
93 for (i = 1; i < argc; ++i) {
94 if (!strcmp(argv[i], "-m"))
95 minify = 1;
96 else if (!strcmp(argv[i], "-mm"))
97 minify = 2;
98 else if (!strcmp(argv[i], "-s"))
99 minify = 3;
100 else {
101 if (js_try(J)) {
102 js_report(J, js_trystring(J, -1, "Error"));
103 js_pop(J, 1);
104 continue;
105 }
106 js_ppfile(J, argv[i], minify);
107 js_endtry(J);
108 }
109 }
110
111 js_gc(J, 0);
112 js_freestate(J);
113
114 return 0;
115}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t