add completion callback facility to the interpreter
[philodendron.git] / runtime / load_grammar.c
blobcbe1d0acac9f0b45a2559566ff1868126c6957c7
2 #include "bc_read_stream.h"
3 #include "interpreter.h"
5 #include <stdlib.h>
6 #include <stdio.h>
8 #define BC_INTFAS 8
9 #define BC_INTFA 9
10 #define BC_STRINGS 10
11 #define BC_RTNS 11
12 #define BC_RTN 12
14 #define BC_INTFA_STATE 0
15 #define BC_INTFA_FINAL_STATE 1
16 #define BC_INTFA_TRANSITION 2
17 #define BC_INTFA_TRANSITION_RANGE 3
19 #define BC_STRING 0
21 #define BC_RTN_INFO 0
22 #define BC_RTN_STATE 1
23 #define BC_RTN_TRANSITION_TERMINAL 2
24 #define BC_RTN_TRANSITION_NONTERM 3
25 #define BC_RTN_DECISION 4
26 #define BC_RTN_IGNORE 5
28 void check_error(struct bc_read_stream *s)
30 if(bc_rs_get_error(s))
32 int err = bc_rs_get_error(s);
33 printf("There were stream errors!\n");
34 if(err & BITCODE_ERR_VALUE_TOO_LARGE)
35 printf(" Value too large.\n");
36 if(err & BITCODE_ERR_NO_SUCH_VALUE)
37 printf(" No such value.\n");
38 if(err & BITCODE_ERR_IO)
39 printf(" IO error.\n");
40 if(err & BITCODE_ERR_CORRUPT_INPUT)
41 printf(" Corrupt input.\n");
42 if(err & BITCODE_ERR_INTERNAL)
43 printf(" Internal error.\n");
47 void unexpected(struct bc_read_stream *s, struct record_info ri)
49 printf("Unexpected. Record is: ");
50 if(ri.record_type == DataRecord)
52 printf("data, id=%d, %d records\n", ri.id, bc_rs_get_record_size(s));
54 else if(ri.record_type == StartBlock)
56 printf("start block, id=%d\n", ri.id);
58 else if(ri.record_type == EndBlock)
60 printf("end block\n");
62 else if(ri.record_type == Eof)
64 printf("eof\n");
66 else if(ri.record_type == Err)
67 printf("error\n");
69 exit(1);
72 char **load_strings(struct bc_read_stream *s)
74 /* first get a count of the strings */
75 int num_strings = 0;
77 while(1)
79 struct record_info ri = bc_rs_next_data_record(s);
80 if(ri.record_type == DataRecord)
81 num_strings++;
82 else if(ri.record_type == EndBlock)
83 break;
84 else
85 unexpected(s, ri);
88 bc_rs_rewind_block(s);
89 char **strings = malloc((num_strings+1) * sizeof(*strings));
90 int string_offset = 0;
92 while(1)
94 struct record_info ri = bc_rs_next_data_record(s);
95 if(ri.record_type == DataRecord && ri.id == BC_STRING)
97 char *str = malloc((bc_rs_get_record_size(s)+1) * sizeof(char));
98 int i;
99 for(i = 0; bc_rs_get_remaining_record_size(s) > 0; i++)
101 str[i] = bc_rs_read_next_32(s);
104 str[i] = '\0';
106 strings[string_offset++] = str;
108 else if(ri.record_type == EndBlock)
110 break;
112 else
113 unexpected(s, ri);
116 strings[string_offset] = NULL;
117 return strings;
120 void load_intfa(struct bc_read_stream *s, struct intfa *intfa, char **strings)
122 /* first get a count of the states and transitions */
123 intfa->num_states = 0;
124 intfa->num_transitions = 0;
126 while(1)
128 struct record_info ri = bc_rs_next_data_record(s);
129 if(ri.record_type == DataRecord)
131 if(ri.id == BC_INTFA_STATE || ri.id == BC_INTFA_FINAL_STATE)
132 intfa->num_states++;
133 else if(ri.id == BC_INTFA_TRANSITION || ri.id == BC_INTFA_TRANSITION_RANGE)
134 intfa->num_transitions++;
136 else if(ri.record_type == EndBlock)
137 break;
138 else
139 unexpected(s, ri);
142 bc_rs_rewind_block(s);
143 intfa->states = malloc(intfa->num_states * sizeof(*intfa->states));
144 intfa->transitions = malloc(intfa->num_transitions * sizeof(*intfa->transitions));
145 int state_offset = 0;
146 int transition_offset = 0;
147 int state_transition_offset = 0;
149 while(1)
151 struct record_info ri = bc_rs_next_data_record(s);
152 if(ri.record_type == DataRecord)
154 if(ri.id == BC_INTFA_STATE || ri.id == BC_INTFA_FINAL_STATE)
156 struct intfa_state *state = &intfa->states[state_offset++];
158 state->num_transitions = bc_rs_read_next_32(s);
159 state->transitions = &intfa->transitions[state_transition_offset];
160 state_transition_offset += state->num_transitions;
162 if(ri.id == BC_INTFA_FINAL_STATE)
163 state->final = strings[bc_rs_read_next_32(s)];
164 else
165 state->final = NULL;
167 else if(ri.id == BC_INTFA_TRANSITION || ri.id == BC_INTFA_TRANSITION_RANGE)
169 struct intfa_transition *transition = &intfa->transitions[transition_offset++];
171 if(ri.id == BC_INTFA_TRANSITION)
173 transition->ch_low = transition->ch_high = bc_rs_read_next_8(s);
175 else if(ri.id == BC_INTFA_TRANSITION_RANGE)
177 transition->ch_low = bc_rs_read_next_8(s);
178 transition->ch_high = bc_rs_read_next_8(s);
181 transition->dest_state = &intfa->states[bc_rs_read_next_8(s)];
184 else if(ri.record_type == EndBlock)
185 break;
186 else
187 unexpected(s, ri);
191 void load_intfas(struct bc_read_stream *s, struct grammar *g)
193 /* first get a count of the intfas */
194 g->num_intfas = 0;
195 while(1)
197 struct record_info ri = bc_rs_next_data_record(s);
198 if(ri.record_type == StartBlock && ri.id == BC_INTFA)
200 g->num_intfas++;
201 bc_rs_skip_block(s);
203 else if(ri.record_type == EndBlock)
204 break;
205 else
206 unexpected(s, ri);
209 bc_rs_rewind_block(s);
210 g->intfas = malloc((g->num_intfas) * sizeof(*g->intfas));
211 int intfa_offset = 0;
213 while(1)
215 struct record_info ri = bc_rs_next_data_record(s);
216 if(ri.record_type == StartBlock && ri.id == BC_INTFA)
218 load_intfa(s, &g->intfas[intfa_offset++], g->strings);
220 else if(ri.record_type == EndBlock)
221 break;
222 else
223 unexpected(s, ri);
227 void load_rtn(struct bc_read_stream *s, struct rtn *rtn, struct grammar *g)
229 /* first get a count of the ignores, states, and transitions */
230 rtn->num_ignore = 0;
231 rtn->num_states = 0;
232 rtn->num_transitions = 0;
234 while(1)
236 struct record_info ri = bc_rs_next_data_record(s);
237 if(ri.record_type == DataRecord)
239 if(ri.id == BC_RTN_IGNORE)
240 rtn->num_ignore++;
241 else if(ri.id == BC_RTN_STATE)
242 rtn->num_states++;
243 else if(ri.id == BC_RTN_TRANSITION_TERMINAL ||
244 ri.id == BC_RTN_TRANSITION_NONTERM ||
245 ri.id == BC_RTN_DECISION)
246 rtn->num_transitions++;
248 else if(ri.record_type == EndBlock)
249 break;
250 else
251 unexpected(s, ri);
254 bc_rs_rewind_block(s);
255 rtn->ignore_terminals = malloc(rtn->num_ignore * sizeof(*rtn->ignore_terminals));
256 rtn->states = malloc(rtn->num_states * sizeof(*rtn->states));
257 rtn->transitions = malloc(rtn->num_transitions * sizeof(*rtn->transitions));
259 int ignore_offset = 0;
260 int state_offset = 0;
261 int transition_offset = 0;
262 int state_transition_offset = 0;
264 while(1)
266 struct record_info ri = bc_rs_next_data_record(s);
267 if(ri.record_type == DataRecord)
269 if(ri.id == BC_RTN_INFO)
271 rtn->name = g->strings[bc_rs_read_next_32(s)];
272 rtn->num_slots = bc_rs_read_next_32(s);
274 else if(ri.id == BC_RTN_IGNORE)
276 rtn->ignore_terminals[ignore_offset++] = g->strings[bc_rs_read_next_32(s)];
278 else if(ri.id == BC_RTN_STATE)
280 struct rtn_state *state = &rtn->states[state_offset++];
282 state->num_transitions = bc_rs_read_next_32(s);
283 state->transitions = &rtn->transitions[state_transition_offset];
284 state_transition_offset += state->num_transitions;
286 state->term_dfa = &g->intfas[bc_rs_read_next_32(s)];
288 if(bc_rs_read_next_8(s))
289 state->is_final = true;
290 else
291 state->is_final = false;
293 else if(ri.id == BC_RTN_TRANSITION_TERMINAL ||
294 ri.id == BC_RTN_TRANSITION_NONTERM ||
295 ri.id == BC_RTN_DECISION)
297 struct rtn_transition *transition = &rtn->transitions[transition_offset++];
299 if(ri.id == BC_RTN_TRANSITION_TERMINAL || ri.id == BC_RTN_TRANSITION_NONTERM)
301 if(ri.id == BC_RTN_TRANSITION_TERMINAL)
303 transition->transition_type = TERMINAL_TRANSITION;
304 transition->edge.terminal_name = g->strings[bc_rs_read_next_32(s)];
306 else if(ri.id == BC_RTN_TRANSITION_NONTERM)
308 transition->transition_type = NONTERM_TRANSITION;
309 transition->edge.nonterminal = &g->rtns[bc_rs_read_next_32(s)];
312 transition->dest_state = &rtn->states[bc_rs_read_next_32(s)];
313 transition->slotname = g->strings[bc_rs_read_next_32(s)];
314 transition->slotnum = bc_rs_read_next_32(s);
316 else if(ri.id == BC_RTN_DECISION)
318 transition->transition_type = DECISION;
319 char *terminal_name = g->strings[bc_rs_read_next_32(s)];
321 transition->edge.decision = malloc(sizeof(struct decision) +
322 (sizeof(struct rtn_transition) * bc_rs_get_remaining_record_size(s)));
324 struct decision *d = transition->edge.decision;
325 d->terminal_name = terminal_name;
326 d->num_actions = bc_rs_get_remaining_record_size(s);
328 for(int action_num = 0; bc_rs_get_remaining_record_size(s) > 0; action_num++)
330 d->actions[action_num] = bc_rs_read_next_32(s);
335 else if(ri.record_type == EndBlock)
336 break;
337 else
338 unexpected(s, ri);
342 void load_rtns(struct bc_read_stream *s, struct grammar *g)
344 /* first get a count of the rtns */
345 g->num_rtns = 0;
346 while(1)
348 struct record_info ri = bc_rs_next_data_record(s);
349 if(ri.record_type == StartBlock && ri.id == BC_RTN)
351 g->num_rtns++;
352 bc_rs_skip_block(s);
354 else if(ri.record_type == EndBlock)
355 break;
356 else
357 unexpected(s, ri);
360 bc_rs_rewind_block(s);
361 g->rtns = malloc(g->num_rtns * sizeof(*g->rtns));
362 int rtn_offset = 0;
364 while(1)
366 struct record_info ri = bc_rs_next_data_record(s);
367 if(ri.record_type == StartBlock && ri.id == BC_RTN)
369 load_rtn(s, &g->rtns[rtn_offset++], g);
371 else if(ri.record_type == EndBlock)
372 break;
373 else
374 unexpected(s, ri);
378 struct grammar *load_grammar(struct bc_read_stream *s)
380 struct grammar *g = malloc(sizeof(*g));
382 while(1)
384 struct record_info ri = bc_rs_next_data_record(s);
385 if(ri.record_type == StartBlock)
387 if(ri.id == BC_STRINGS)
388 g->strings = load_strings(s);
389 else if(ri.id == BC_INTFAS)
390 load_intfas(s, g);
391 else if(ri.id == BC_RTNS)
392 load_rtns(s, g);
393 else
394 bc_rs_skip_block(s);
396 else if(ri.record_type == Eof)
398 if(g->strings == NULL || g->num_intfas == 0 || g->num_rtns == 0)
400 printf("Premature EOF!\n");
401 exit(1);
403 else
405 /* Success -- we finished loading! */
406 break;
411 return g;
414 void free_grammar(struct grammar *g)
416 for(int i = 0; g->strings[i] != NULL; i++)
417 free(g->strings[i]);
418 free(g->strings);
420 for(int i = 0; i < g->num_rtns; i++)
422 struct rtn *rtn = &g->rtns[i];
423 free(rtn->ignore_terminals);
424 free(rtn->states);
426 for(int j = 0; j < rtn->num_transitions; j++)
427 if(rtn->transitions[j].transition_type == DECISION)
428 free(rtn->transitions[j].edge.decision);
429 free(rtn->transitions);
431 free(g->rtns);
433 for(int i = 0; i < g->num_intfas; i++)
435 struct intfa *intfa = &g->intfas[i];
436 free(intfa->states);
437 free(intfa->transitions);
439 free(g->intfas);
441 free(g);
445 * Local Variables:
446 * c-file-style: "bsd"
447 * c-basic-offset: 4
448 * indent-tabs-mode: nil
449 * End:
450 * vim:et:sts=4:sw=4