4db0b86e0f5eae5366f9c7d0f22ed8167544891e
[henge/webcc.git] / src / bin / tools / testapc.c
1 /*!@file
2 \brief APC test driver
3 \details This driver does what APC does, but in staggered stages with
4 additional debugging information
5 \author Jordan Lavatai
6 \date Aug 2016
7 ----------------------------------------------------------------------------*/
8 /* Standard */
9 #include <stdio.h> //print
10 #include <errno.h> //errors
11 #include <string.h> //strnlen
12 /* Posix */
13 #include <stdlib.h> //exit
14 #include <unistd.h> //getopt
15 /* Internal */
16 #include <apc/parser.tab.h> //bison
17 #include <apc/ir.h> //ir
18
19 /* Import apc.c but redefine its primary symbols for jumping */
20 #define main apc_main
21 #define yyparse testapc_yyparse
22 #include <bin/tools/apc.c>
23 #undef yyparse
24 #undef main
25
26 int main(int, char*[]);
27 int testapc_yyparse(void);
28 int test_yyparse(void);
29
30 extern //bison
31 int yyparse(void);
32 extern //lexer.c
33 int lexer_init(void);
34 extern //apc.c
35 const char* cargs['Z'];
36
37 extern //apc/parser.tab.c
38 YYSTYPE yylval;
39 extern //lexer.c
40 int lexer(void);
41
42 /* Ansi Term Colors */
43 #define RED "\x1b[31m"
44 #define GREEN "\x1b[32m"
45 #define YELLOW "\x1b[33m"
46 #define BLUE "\x1b[34m"
47 #define MAGENTA "\x1b[35m"
48 #define CYAN "\x1b[36m"
49 #define CLRC "\x1b[0m" //clear current color
50
51 /* Main entry from terminal
52 parses debugging options for testing apc, and calls apc_main
53 */
54 int main
55 ( int argc,
56 char* argv[]
57 )
58 { apc_main(argc, argv);
59 printf(GREEN "PASS" CLRC "\n");
60 exit(EXIT_SUCCESS);
61 }
62
63 #define MAX_TOK 1024
64 char tok_lval[MAX_TOK];
65
66 /* yyparse intercept
67 tests yyparse internally, then resets the scanner and runs bison's 'yyparse'
68 implementation after validating it with 'test_yyparse'.
69 */
70 int testapc_yyparse
71 #ifndef YYABORT
72 #define YYABORT 1
73 #endif
74 ()
75 { static char bPassedTest = 'f';
76 if (bPassedTest == 'f')
77 { if (test_yyparse())
78 { printf("Parse test aborted\n");
79 return YYABORT;
80 }
81 bPassedTest = 't';
82 apc_main(0,NULL);
83 }
84 return yyparse();
85 }
86
87 /* test_yyparse
88 runs 'lexer' 'PASSES' times, or until finished
89 */
90 int test_yyparse
91 #define PASSES 1000
92 ()
93 { int i, tok;
94 static char* tok_string;
95 static char tok_pattern[] = "[" RED " %9s " CLRC "][" CYAN " %-12i " CLRC "]";
96 for (i = 0; i < PASSES; i++)
97 { switch (tok = lexer())
98 #define TOFFS 9
99 #define LOFFS 27
100 #define $($)#$
101 #define TOK_CASE(T,C) \
102 case T: \
103 tok_string = $(T); \
104 tok_pattern[LOFFS] = C; \
105 break
106 { TOK_CASE(STR,'s');
107 TOK_CASE(NAME,'s');
108 TOK_CASE(REF,'x');
109 TOK_CASE(FPTR,'x');
110 TOK_CASE(NUM,'i');
111 TOK_CASE(SS,'i');
112 TOK_CASE(SSD,'i');
113 TOK_CASE(CLOPEN,'i');
114 TOK_CASE(CLCLOSE,'i');
115 default:
116 tok_string = 0;
117 tok_pattern[LOFFS] = 'i';
118 break;
119 case 0:
120 goto done;
121 }
122 if (tok_string == NULL)
123 { tok_pattern[TOFFS] = 'i';
124 printf(tok_pattern, tok, yylval.val);
125 }
126 else
127 { tok_pattern[TOFFS] = 's';
128 printf(tok_pattern, tok_string, yylval.val);
129 }
130 if (i % 4 == 0 || yylval.val == 0)
131 printf(";\n");
132 }
133 done:
134 printf(";\n" GREEN "Done" CLRC ".\n");
135 return 0;
136 error:
137 printf(";\n" RED "FAILED" CLRC ".\n");
138 return -1;
139 }