5 #include "isl_stream.h"
7 static struct isl_token
*isl_token_new(struct isl_ctx
*ctx
,
8 int line
, int col
, unsigned on_new_line
)
10 struct isl_token
*tok
= isl_alloc_type(ctx
, struct isl_token
);
15 tok
->on_new_line
= on_new_line
;
19 void isl_token_free(struct isl_token
*tok
)
23 if (tok
->type
== ISL_TOKEN_VALUE
)
24 isl_int_clear(tok
->u
.v
);
25 else if (tok
->type
== ISL_TOKEN_IDENT
)
30 void isl_stream_error(struct isl_stream
*s
, struct isl_token
*tok
, char *msg
)
32 int line
= tok
? tok
->line
: s
->line
;
33 int col
= tok
? tok
->col
: s
->col
;
34 fprintf(stderr
, "syntax error (%d, %d): %s\n", line
, col
, msg
);
37 fprintf(stderr
, "got '%c'\n", tok
->type
);
39 fprintf(stderr
, "got token type %d\n", tok
->type
);
43 static struct isl_stream
* isl_stream_new(struct isl_ctx
*ctx
)
46 struct isl_stream
*s
= isl_alloc_type(ctx
, struct isl_stream
);
54 s
->buffer
= isl_alloc_array(ctx
, char, s
->size
);
62 for (i
= 0; i
< 5; ++i
)
71 struct isl_stream
* isl_stream_new_file(struct isl_ctx
*ctx
, FILE *file
)
73 struct isl_stream
*s
= isl_stream_new(ctx
);
80 struct isl_stream
* isl_stream_new_str(struct isl_ctx
*ctx
, const char *str
)
82 struct isl_stream
*s
= isl_stream_new(ctx
);
87 static int isl_stream_getc(struct isl_stream
*s
)
112 static void isl_stream_ungetc(struct isl_stream
*s
, int c
)
121 static int isl_stream_push_char(struct isl_stream
*s
, int c
)
123 if (s
->len
>= s
->size
) {
124 s
->size
= (3*s
->size
)/2;
125 s
->buffer
= isl_realloc_array(ctx
, s
->buffer
, char, s
->size
);
129 s
->buffer
[s
->len
++] = c
;
133 void isl_stream_push_token(struct isl_stream
*s
, struct isl_token
*tok
)
135 isl_assert(s
->ctx
, s
->n_token
< 5, return);
136 s
->tokens
[s
->n_token
++] = tok
;
139 struct isl_token
*isl_stream_next_token(struct isl_stream
*s
)
142 struct isl_token
*tok
= NULL
;
144 int old_line
= s
->line
;
147 return s
->tokens
[--s
->n_token
];
152 while ((c
= isl_stream_getc(s
)) != -1 && isspace(c
))
174 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
177 tok
->type
= (enum isl_token_type
)c
;
182 if ((c
= isl_stream_getc(s
)) == '>') {
183 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
186 tok
->type
= ISL_TOKEN_TO
;
190 isl_stream_ungetc(s
, c
);
192 if (c
== '-' || isdigit(c
)) {
193 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
196 tok
->type
= ISL_TOKEN_VALUE
;
197 isl_int_init(tok
->u
.v
);
198 if (isl_stream_push_char(s
, c
))
200 while ((c
= isl_stream_getc(s
)) != -1 && isdigit(c
))
201 if (isl_stream_push_char(s
, c
))
204 isl_stream_ungetc(s
, c
);
205 if (s
->len
== 1 && s
->buffer
[0] == '-')
206 isl_int_set_si(tok
->u
.v
, -1);
208 isl_stream_push_char(s
, '\0');
209 isl_int_read(tok
->u
.v
, s
->buffer
);
214 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
217 isl_stream_push_char(s
, c
);
218 while ((c
= isl_stream_getc(s
)) != -1 && isalnum(c
))
219 isl_stream_push_char(s
, c
);
221 isl_stream_ungetc(s
, c
);
222 isl_stream_push_char(s
, '\0');
223 if (!strcasecmp(s
->buffer
, "exists"))
224 tok
->type
= ISL_TOKEN_EXISTS
;
226 tok
->type
= ISL_TOKEN_IDENT
;
227 tok
->u
.s
= strdup(s
->buffer
);
233 if ((c
= isl_stream_getc(s
)) == '=') {
234 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
237 tok
->type
= ISL_TOKEN_GE
;
241 isl_stream_ungetc(s
, c
);
245 if ((c
= isl_stream_getc(s
)) == '=') {
246 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
249 tok
->type
= ISL_TOKEN_LE
;
253 isl_stream_ungetc(s
, c
);
256 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
259 tok
->type
= ISL_TOKEN_AND
;
260 if ((c
= isl_stream_getc(s
)) != '&' && c
!= -1)
261 isl_stream_ungetc(s
, c
);
265 tok
= isl_token_new(s
->ctx
, line
, col
, old_line
!= line
);
268 tok
->type
= ISL_TOKEN_UNKNOWN
;
275 int isl_stream_eat(struct isl_stream
*s
, int type
)
277 struct isl_token
*tok
;
279 tok
= isl_stream_next_token(s
);
282 if (tok
->type
== type
) {
286 isl_stream_error(s
, tok
, "expecting other token");
287 isl_stream_push_token(s
, tok
);
291 void isl_stream_free(struct isl_stream
*s
)
296 if (s
->n_token
!= 0) {
297 struct isl_token
*tok
= isl_stream_next_token(s
);
298 isl_stream_error(s
, tok
, "unexpected token");
301 isl_ctx_deref(s
->ctx
);