testing through yyparse
[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_pattern[] = "[" RED " %5i " CLRC "][" CYAN " %-12i " CLRC "]";
95 for (i = 0; i < PASSES; i++)
96 { switch (tok = lexer())
97 #define OFFS 27
98 { case STR:
99 case NAME:
100 tok_pattern[OFFS] = 's';
101 break;
102 case REF:
103 case FPTR:
104 tok_pattern[OFFS] = 'x';
105 break;
106 case NUM:
107 case SS:
108 case SSD:
109 tok_pattern[OFFS] = 'i';
110 break;
111 case CLOPEN:
112 case CLCLOSE:
113 case SOPEN:
114 case SCLOSE:
115 case EOPEN:
116 case ECLOSE:
117 case VOPEN:
118 case VCLOSE:
119 case QOPEN:
120 case QCLOSE:
121 case RT:
122 case HB:
123 tok_pattern[OFFS] = 'i';
124 break;
125 case 0:
126 goto done;
127 default:
128 printf(YELLOW "test_yyparse" CLRC ", unknown token [" RED " %5i " CLRC "]",tok);
129 goto error;
130 }
131 printf(tok_pattern, tok, yylval.val);
132 if (i % 4 == 0 || yylval.val == 1)
133 printf(";\n");
134 }
135 done:
136 printf(";\n" GREEN "Done" CLRC ".\n");
137 return 0;
138 error:
139 printf(";\n" RED "FAILED" CLRC ".\n");
140 return -1;
141 }