/
scanner.re
230 lines (194 loc) · 5.39 KB
/
scanner.re
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
* Milkymist SoC (Software)
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "symtab.h"
#include "scanner.h"
#define YYCTYPE unsigned char
#define YYCURSOR s->cursor
#define YYLIMIT s->limit
/* refilling not supported */
#define YYMARKER s->marker
#define YYFILL(n)
#define YYCONDTYPE enum scanner_cond
#define YYGETCONDITION() s->cond
#define YYSETCONDITION(c) s->cond = (c)
struct scanner *new_scanner(unsigned char *input)
{
struct scanner *s;
s = malloc(sizeof(struct scanner));
if(s == NULL) return NULL;
s->cond = yycN;
s->marker = input;
s->old_cursor = input;
s->cursor = input;
s->limit = input + strlen((char *)input);
s->lineno = 1;
return s;
}
void delete_scanner(struct scanner *s)
{
free(s);
}
static int nls(const unsigned char *s, const unsigned char *end)
{
int n = 0;
while(s != end)
if(*s++ == '\n')
n++;
return n;
}
/*
* Regular expression for C-style comments by Stephen Ostermiller, from
* http://ostermiller.org/findcomment.html
*/
int scan(struct scanner *s)
{
std:
if(s->cursor == s->limit) return TOK_EOF;
s->old_cursor = s->cursor;
/*!re2c
<*>[\x00] { abort(); }
<*>[\x20\r\t] { goto std; }
<*>"\n" { s->lineno++;
YYSETCONDITION(yycN);
goto std; }
<N>"//"[^\n\x00]* { goto std; }
<N>"/*"([^*\x00]|("*"+([^*/\x00])))*"*"+"/"
{ s->lineno += nls(s->old_cursor,
s->cursor);
goto std; }
<N>"[preset00]" { goto std; }
<N>[0-9]+ { return TOK_CONSTANT; }
<N>[0-9]+ "." [0-9]* { return TOK_CONSTANT; }
<N>[0-9]* "." [0-9]+ { return TOK_CONSTANT; }
<N>"above" { return TOK_ABOVE; }
<N>"abs" { return TOK_ABS; }
<N>"band" { return TOK_BAND; }
<N>"below" { return TOK_BELOW; }
<N>"bnot" { return TOK_BNOT; }
<N>"bor" { return TOK_BOR; }
<N>"cos" { return TOK_COS; }
<N>"equal" { return TOK_EQUAL; }
<N>"f2i" { return TOK_F2I; }
<N>"icos" { return TOK_ICOS; }
<N>"i2f" { return TOK_I2F; }
<N>"if" { return TOK_IF; }
<N>"int" { return TOK_INT; }
<N>"invsqrt" { return TOK_INVSQRT; }
<N>"isin" { return TOK_ISIN; }
<N>"max" { return TOK_MAX; }
<N>"min" { return TOK_MIN; }
<N>"quake" { return TOK_QUAKE; }
<N>"sin" { return TOK_SIN; }
<N>"sqr" { return TOK_SQR; }
<N>"sqrt" { return TOK_SQRT; }
<N>"tsign" { return TOK_TSIGN; }
<N>"per_frame" { return TOK_PER_FRAME; }
<N>"per_vertex" { return TOK_PER_VERTEX; }
<N>"per_frame"[a-z_0-9]+
{ return TOK_PER_FRAME_UGLY; }
<N>"per_vertex"[a-z_0-9]+
{ return TOK_PER_VERTEX_UGLY; }
<N>"per_pixel"[a-z_0-9]*
{ return TOK_PER_PIXEL_UGLY; }
<N>"midi" { return TOK_MIDI; }
<N>"range" { return TOK_RANGE; }
<N>"differential" { return TOK_DIFF; }
<N>"button" { return TOK_BUTTON; }
<N>"toggle" { return TOK_TOGGLE; }
<N>"cyclic" { return TOK_CYCLIC; }
<N>"unbounded" { return TOK_UNBOUNDED; }
<N>"imagefile"[1-9] { YYSETCONDITION(yycFNAME1);
return TOK_IMAGEFILE; }
<N>[a-zA-Z_0-9]+ { return TOK_IDENT; }
<N>'"'[^"\x00\n\r]*'"' { return TOK_STRING; }
<N>"+" { return TOK_PLUS; }
<N>"-" { return TOK_MINUS; }
<N>"*" { return TOK_MULTIPLY; }
<N>"/" { return TOK_DIVIDE; }
<N>"%" { return TOK_PERCENT; }
<N>"(" { return TOK_LPAREN; }
<N>")" { return TOK_RPAREN; }
<N>"," { return TOK_COMMA; }
<N>"?" { return TOK_QUESTION; }
<N>":" { return TOK_COLON; }
<N>"!" { return TOK_NOT; }
<N>"==" { return TOK_EQ; }
<N>"!=" { return TOK_NE; }
<N>"<" { return TOK_LT; }
<N>">" { return TOK_GT; }
<N>"<=" { return TOK_LE; }
<N>">=" { return TOK_GE; }
<N>"&&" { return TOK_ANDAND; }
<N>"||" { return TOK_OROR; }
<N>"{" { return TOK_LBRACE; }
<N>"}" { return TOK_RBRACE; }
<N,FNAME1>"=" { if (YYGETCONDITION() == yycFNAME1)
YYSETCONDITION(yycFNAME2);
return TOK_ASSIGN; }
<N>";" { return TOK_SEMI; }
<FNAME2>[^ \x00\n\r\t]|[^ \x00\n\r\t][^\n\x00]*[^ \x00\n\r\t]
{ return TOK_FNAME; }
<*>[\x01-\xff] { return TOK_ERROR; }
*/
}
struct sym *get_symbol(struct scanner *s)
{
return unique_n((const char *) s->old_cursor,
s->cursor - s->old_cursor);
}
const char *get_name(struct scanner *s)
{
char *buf;
int n;
n = s->cursor - s->old_cursor;
buf = malloc(n+1);
memcpy(buf, s->old_cursor, n);
buf[n] = 0;
return buf;
}
const char *get_string(struct scanner *s)
{
char *buf;
int n;
n = s->cursor - s->old_cursor;
buf = malloc(n-1);
memcpy(buf, s->old_cursor+1, n-2);
buf[n-2] = 0;
return buf;
}
float get_constant(struct scanner *s)
{
const unsigned char *p;
float v = 0;
float m = 1;
for(p = s->old_cursor; p != s->cursor; p++) {
if(*p == '.')
goto dot;
v = v*10+(*p-'0');
}
return v;
dot:
for(p++; p != s->cursor; p++) {
m /= 10;
v += m*(*p-'0');
}
return v;
}