flush
[m6w6/ext-psi] / idl / lexer.re
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <assert.h>
6
7 #include "lexer.h"
8
9 #if INTERFACE
10 /*!max:re2c*/
11 #define BSIZE 256
12
13 typedef struct PSI_Lexer {
14 decl_typedefs *defs;
15 decls *decls;
16 impls *impls;
17 char *lib;
18 char *fn;
19 FILE *fp;
20 size_t line;
21 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
22 } PSI_Lexer;
23 #endif
24
25 #if BSIZE < YYMAXFILL
26 # error BSIZE must be greater than YYMAXFILL
27 #endif
28
29 PSI_Token *PSI_TokenAlloc(PSI_Lexer *L, token_t t)
30 {
31 PSI_Token *T;
32 size_t token_len;
33
34 if (L->cur <= L->tok) {
35 return NULL;
36 }
37
38 token_len = L->cur - L->tok;
39
40 T = malloc(sizeof(*T) + token_len);
41 T->type = t;
42 T->line = L->line;
43 T->size = token_len;
44 T->text[token_len] = 0;
45 memcpy(T->text, L->tok, token_len);
46
47 return T;
48 }
49
50 size_t PSI_LexerFill(PSI_Lexer *L, size_t n)
51 {
52 // printf("+ Fill: n=%zu\n", n);
53 if (!n) {
54 L->cur = L->tok = L->lim = L->mrk = L->buf;
55 L->eof = NULL;
56 }
57
58 if (!L->eof) {
59 size_t consumed = L->tok - L->buf;
60 size_t reserved = L->lim - L->tok;
61 size_t available = BSIZE - reserved;
62 size_t didread;
63
64 if (consumed) {
65 memmove(L->buf, L->tok, reserved);
66 L->tok -= consumed;
67 L->cur -= consumed;
68 L->lim -= consumed;
69 L->mrk -= consumed;
70 }
71
72 didread = fread(L->lim, 1, available, L->fp);
73 L->lim += didread;
74 if (didread < available) {
75 L->eof = L->lim;
76 }
77
78 // printf("+ Fill: consumed=%zu reserved=%zu available=%zu didread=%zu\n",
79 // consumed, reserved, available, didread);
80 }
81 // printf("+ Fill: avail=%zu\n", L->lim - L->cur);
82 return L->lim - L->cur;
83 }
84
85 void PSI_LexerDtor(PSI_Lexer *L)
86 {
87 if (L->fp) {
88 fclose(L->fp);
89 }
90 if (L->fn) {
91 free(L->fn);
92 }
93 if (L->lib) {
94 free(L->lib);
95 }
96 if (L->defs) {
97 free_decl_typedefs(L->defs);
98 }
99 if (L->decls) {
100 free_decls(L->decls);
101 }
102 if (L->impls) {
103 free_impls(L->impls);
104 }
105 memset(L, 0, sizeof(*L));
106 }
107
108 void PSI_LexerFree(PSI_Lexer **L)
109 {
110 if (*L) {
111 PSI_LexerDtor(*L);
112 free(*L);
113 *L = NULL;
114 }
115 }
116
117 PSI_Lexer *PSI_LexerInit(PSI_Lexer *L, const char *filename)
118 {
119 FILE *fp = fopen(filename, "r");
120
121 if (!fp) {
122 perror(filename);
123 return NULL;
124 }
125
126 if (!L) {
127 L = malloc(sizeof(*L));
128 }
129 memset(L, 0, sizeof(*L));
130
131 L->fp = fp;
132 L->fn = strdup(filename);
133 L->line = 1;
134
135 PSI_LexerFill(L, 0);
136
137 return L;
138 }
139
140
141 token_t PSI_LexerScan(PSI_Lexer *L)
142 {
143 for (;;) {
144 L->tok = L->cur;
145 /*!re2c
146 re2c:indent:top = 2;
147 re2c:define:YYCTYPE = "unsigned char";
148 re2c:define:YYCURSOR = L->cur;
149 re2c:define:YYLIMIT = L->lim;
150 re2c:define:YYMARKER = L->mrk;
151 re2c:define:YYFILL = "{ if (!PSI_LexerFill(L,@@)) return -1; }";
152 re2c:yyfill:parameter = 0;
153
154 B = [^a-zA-Z0-9_];
155 W = [a-zA-Z0-9_];
156 NAME = W+;
157 NSNAME = (NAME)? ("\\" NAME)+;
158 QUOTED_STRING = "\"" ([^\"])+ "\"";
159 NULL = 'NULL';
160 MIXED = 'mixed';
161 VOID = 'void';
162 BOOL = 'bool';
163 INT = 'int';
164 FLOAT = 'float';
165 DOUBLE = 'double';
166 SINT8 = 'sint8';
167 UINT8 = 'uint8';
168 SINT16 = 'sint16';
169 UINT16 = 'uint16';
170 SINT32 = 'sint32';
171 UINT32 = 'uint32';
172 SINT64 = 'sint64';
173 UINT64 = 'uint64';
174 STRING = 'string';
175 ARRAY = 'array';
176 FUNCTION = 'function';
177 TYPEDEF = 'typedef';
178 LIB = 'lib';
179 LET = 'let';
180 SET = 'set';
181 RET = 'ret';
182 STRVAL = 'strval';
183 INTVAL = 'intval';
184 FLOATVAL = 'floatval';
185 BOOLVAL = 'boolval';
186 TO_STRING = 'to_string';
187 TO_INT = 'to_int';
188 TO_FLOAT = 'to_float';
189 TO_BOOL = 'to_bool';
190
191 "#" .* "\n" { ++L->line; return PSI_T_COMMENT;}
192 "(" {return PSI_T_LPAREN;}
193 ")" {return PSI_T_RPAREN;}
194 ";" {return PSI_T_EOS;}
195 "," {return PSI_T_COMMA;}
196 ":" {return PSI_T_COLON;}
197 "{" {return PSI_T_LBRACE;}
198 "}" {return PSI_T_RBRACE;}
199 "." {return PSI_T_DOT;}
200 "=" {return PSI_T_EQUALS;}
201 "$" {return PSI_T_DOLLAR;}
202 "*" {return PSI_T_POINTER;}
203 "&" {return PSI_T_REFERENCE;}
204 [\r\n] { ++L->line; continue; }
205 [\t ]+ { continue; }
206 NULL {return PSI_T_NULL;}
207 MIXED {return PSI_T_MIXED;}
208 VOID {return PSI_T_VOID;}
209 BOOL {return PSI_T_BOOL;}
210 INT {return PSI_T_INT;}
211 FLOAT {return PSI_T_FLOAT;}
212 DOUBLE {return PSI_T_DOUBLE;}
213 SINT8 {return PSI_T_SINT8;}
214 UINT8 {return PSI_T_UINT8;}
215 SINT16 {return PSI_T_SINT16;}
216 UINT16 {return PSI_T_UINT16;}
217 SINT32 {return PSI_T_SINT32;}
218 UINT32 {return PSI_T_UINT32;}
219 SINT64 {return PSI_T_SINT64;}
220 UINT64 {return PSI_T_UINT64;}
221 STRING {return PSI_T_STRING;}
222 ARRAY {return PSI_T_ARRAY;}
223 FUNCTION {return PSI_T_FUNCTION;}
224 TYPEDEF {return PSI_T_TYPEDEF;}
225 LIB {return PSI_T_LIB;}
226 LET {return PSI_T_LET;}
227 SET {return PSI_T_SET;}
228 RET {return PSI_T_RET;}
229 STRVAL {return PSI_T_STRVAL;}
230 INTVAL {return PSI_T_INTVAL;}
231 FLOATVAL {return PSI_T_FLOATVAL;}
232 BOOLVAL {return PSI_T_BOOLVAL;}
233 TO_STRING {return PSI_T_TO_STRING;}
234 TO_INT {return PSI_T_TO_INT;}
235 TO_FLOAT {return PSI_T_TO_FLOAT;}
236 TO_BOOL {return PSI_T_TO_BOOL;}
237 [0-9] {return PSI_T_DIGIT;}
238 NAME {return PSI_T_NAME;}
239 NSNAME {return PSI_T_NSNAME;}
240 QUOTED_STRING {return PSI_T_QUOTED_STRING;}
241 */
242 }
243 return -1;
244 }