2 * FML interpreter. Europagate, 1995
5 * Revision 1.5 1995/02/09 14:33:36 adam
6 * Split source fml.c and define relevant build-in functions in separate
7 * files. New operators mult, div, not, llen implemented.
9 * Revision 1.4 1995/02/09 13:07:14 adam
10 * Nodes are freed now. Many bugs fixed.
12 * Revision 1.3 1995/02/07 16:09:23 adam
13 * The \ character is no longer INCLUDED when terminating a token.
14 * Major changes in tokenization routines. Bug fixes in expressions
15 * with lists (fml_sub0).
17 * Revision 1.2 1995/02/06 15:23:25 adam
18 * Added some more relational operators (le,ne,ge). Added increment
19 * and decrement operators. Function index changed, so that first
20 * element is 1 - not 0. Function fml_atom_val edited.
22 * Revision 1.1.1.1 1995/02/06 13:48:10 adam
23 * First version of the FML interpreter. It's slow and memory isn't
24 * freed properly. In particular, the FML nodes aren't released yet.
33 static int default_read_func (void)
38 static void default_err_handle (int no)
40 fprintf (stderr, "Error: %d\n", no);
43 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
44 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
46 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
48 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
50 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
53 static int indent = 0;
55 static void pr_indent (int n)
78 struct fml_sym_info *sym_info;
80 Fml fml = malloc (sizeof(*fml));
85 fml->escape_char = '\\';
86 fml->comment_char = '#';
88 fml->white_chars = " \t\f\r\n";
89 fml->read_func = default_read_func;
90 fml->err_handle = default_err_handle;
93 fml->sym_tab = fml_sym_open ();
94 fml->atom_free_list = NULL;
95 fml->node_free_list = NULL;
98 sym_info = fml_sym_add (fml->sym_tab, "func");
99 sym_info->kind = FML_FUNC;
100 sym_info = fml_sym_add (fml->sym_tab, "bin");
101 sym_info->kind = FML_BIN;
102 sym_info = fml_sym_add (fml->sym_tab, "if");
103 sym_info->kind = FML_IF;
104 sym_info = fml_sym_add (fml->sym_tab, "else");
105 sym_info->kind = FML_ELSE;
106 sym_info = fml_sym_add (fml->sym_tab, "foreach");
107 sym_info->kind = FML_FOREACH;
108 sym_info = fml_sym_add (fml->sym_tab, "set");
109 sym_info->kind = FML_SET;
110 sym_info = fml_sym_add (fml->sym_tab, "while");
111 sym_info->kind = FML_WHILE;
112 sym_info = fml_sym_add (fml->sym_tab, "return");
113 sym_info->kind = FML_RETURN;
119 sym_info = fml_sym_add (fml->sym_tab, "s");
120 sym_info->kind = FML_CPREFIX;
121 sym_info->prefix = fml_exec_space;
122 sym_info = fml_sym_add (fml->sym_tab, " ");
123 sym_info->kind = FML_CPREFIX;
124 sym_info->prefix = fml_exec_space;
125 sym_info = fml_sym_add (fml->sym_tab, "n");
126 sym_info->kind = FML_CPREFIX;
127 sym_info->prefix = fml_exec_nl;
132 static Fml fml_pop_handler = NULL;
133 static void pop_handler (struct fml_sym_info *info)
135 assert (fml_pop_handler);
139 fml_node_delete (fml_pop_handler, info->body);
143 static void fml_do_pop (Fml fml)
145 fml_pop_handler = fml;
146 fml_sym_pop (fml->sym_tab, pop_handler);
149 int fml_preprocess (Fml fml)
151 fml->list = fml_tokenize (fml);
156 void fml_init_token (struct token *tp, Fml fml)
158 tp->maxbuf = FML_ATOM_BUF*2;
160 tp->atombuf = tp->sbuf;
161 tp->tokenbuf = tp->sbuf + tp->maxbuf;
162 tp->escape_char = fml->escape_char;
165 void fml_del_token (struct token *tp, Fml fml)
167 if (tp->maxbuf != FML_ATOM_BUF*2)
171 void fml_cmd_lex (struct fml_node **np, struct token *tp)
185 tp->atom = (*np)->p[0];
187 fml_atom_str (tp->atom, tp->atombuf);
190 int l = fml_atom_str (tp->atom, NULL);
191 if (l >= tp->maxbuf-1)
193 if (tp->maxbuf != FML_ATOM_BUF*2)
196 tp->atombuf = malloc (tp->maxbuf*2);
197 tp->tokenbuf = tp->atombuf + tp->maxbuf;
199 fml_atom_str (tp->atom, tp->atombuf);
204 tp->sub = (*np)->p[0];
212 cp = tp->atombuf + tp->offset;
214 if (*cp == tp->escape_char)
232 if (*cp == tp->escape_char)
235 tp->offset = cp - tp->atombuf;
245 struct fml_node *fml_expr_term (Fml fml, struct fml_node **lp,
251 fn = fml_sub0 (fml, tp->sub);
252 fml_cmd_lex (lp, tp);
255 fn = fml_sub2 (fml, lp, tp);
259 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml);
261 void fml_lr_values (Fml fml, struct fml_node *l, int *left_val,
262 struct fml_node *r, int *right_val)
265 *left_val = fml_atom_val (l->p[0]);
269 *right_val = fml_atom_val (r->p[0]);
272 fml_node_delete (fml, l);
273 fml_node_delete (fml, r);
276 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
279 fml_cmd_lex (lp, tp);
284 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
287 fml_cmd_lex (lp, tp);
292 static struct fml_node *fml_exec_prefix (struct fml_sym_info *info, Fml fml,
293 struct fml_node **lp,
297 struct fml_sym_info *arg_info;
298 struct fml_node *return_value;
299 static char arg[128];
304 printf ("exec_prefix ");
306 fml_sym_push (fml->sym_tab);
307 fml_cmd_lex (lp, tp);
308 for (fn = info->args; fn; fn = fn->p[1])
311 assert (fn->is_atom);
312 fml_atom_strx (fn->p[0], arg, 127);
318 arg_info = fml_sym_add_local (fml->sym_tab, arg);
319 arg_info->kind = FML_VAR;
323 arg_info->body = fml_sub0 (fml, tp->sub);
324 fml_cmd_lex (lp, tp);
327 arg_info->body = fml_sub2 (fml, lp, tp);
330 fml_pr_list (arg_info->body);
334 return_value = fml_exec_group (info->body, fml);
345 static void fml_emit (struct fml_node *list)
356 for (a = list->p[0]; a; a=a->next)
357 printf ("%s", a->buf);
360 fml_emit (list->p[0]);
366 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
370 struct fml_sym_info *info;
373 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
378 fn = fml_node_copy (fml, info->body);
379 fml_cmd_lex (lp, tp);
382 fn = fml_exec_prefix (info, fml, lp, tp);
385 fn = (*info->prefix) (fml, lp, tp);
386 fml_cmd_lex (lp, tp);
389 fml_cmd_lex (lp, tp);
393 else if (tp->kind == 'g')
396 fn = fml_sub0 (fml, tp->sub);
399 fml_cmd_lex (lp, tp);
401 else if (tp->kind == 't')
403 fn = fml_node_alloc (fml);
405 fn->p[0] = fml_atom_alloc (fml, tp->tokenbuf);
406 fml_cmd_lex (lp, tp);
413 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
416 struct fml_node *f1, *f2, *fn;
417 struct fml_sym_info *info;
419 f1 = fml_sub2 (fml, lp, tp);
420 while (tp->kind == 'e')
422 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
425 fprintf (stderr, "cannot locate `%s'", tp->tokenbuf);
428 if (info->kind == FML_CBINARY)
430 fml_cmd_lex (lp, tp);
431 f2 = fml_sub2 (fml, lp, tp);
432 fn = (*info->binary) (fml, f1, f2);
436 else if (info->kind == FML_BINARY)
438 struct fml_sym_info *arg_info;
444 printf ("exec binary %s", tp->tokenbuf);
446 fml_cmd_lex (lp, tp);
447 f2 = fml_sub2 (fml, lp, tp);
448 fml_sym_push (fml->sym_tab);
450 fml_atom_strx (info->args->p[0], arg, 127);
451 arg_info = fml_sym_add_local (fml->sym_tab, arg);
452 arg_info->kind = FML_VAR;
459 fml_atom_strx ( ((struct fml_node *) info->args->p[1])->p[0],
461 arg_info = fml_sym_add_local (fml->sym_tab, arg);
462 arg_info->kind = FML_VAR;
470 f1 = fml_exec_group (info->body, fml);
485 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
488 struct fml_node *fn, *fn1;
490 fml_init_token (&token, fml);
492 fml_cmd_lex (&list, &token);
493 fn = fml_sub1 (fml, &list, &token);
494 if (token.kind == '\0')
496 fml_del_token (&token, fml);
499 fn1 = fml_node_alloc (fml);
502 while (token.kind != '\0')
504 fn1 = fn1->p[1] = fml_node_alloc (fml);
505 fn1->p[0] = fml_sub1 (fml, &list, &token);
507 fml_del_token (&token, fml);
511 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
514 struct fml_node *fn, *fn0, *fn1;
518 fml_init_token (&token, fml);
520 fml_cmd_lex (&list, &token);
521 fn1 = fn = fml_sub1 (fml, &list, &token);
522 if (fn->p[1] && token.kind != '\0')
524 fn1 = fml_node_alloc (fml);
528 while (token.kind != '\0')
530 fn = fml_sub1 (fml, &list, &token);
533 fn1 = fn1->p[1] = fml_node_alloc (fml);
538 fn1 = fn1->p[1] = fn;
541 fml_del_token (&token, fml);
546 static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
547 struct fml_node **lp,
550 struct fml_sym_info *info_var;
551 struct fml_node *fn, *body;
552 struct fml_node *return_value = NULL, *rv;
554 fml_cmd_lex (lp, tp);
555 assert (tp->kind == 't');
557 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
560 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
561 info_var->body = NULL;
562 info_var->kind = FML_VAR;
566 fml_node_delete (fml, info->body);
572 printf ("[foreach %s ", tp->tokenbuf);
574 fml_cmd_lex (lp, tp);
575 assert (tp->kind == 'g');
576 fn = fml_sub0 (fml, tp->sub);
578 fml_cmd_lex (lp, tp);
579 assert (tp->kind == 'g');
584 struct fml_node *fn1;
591 info_var->body = fn->p[0];
595 printf ("[foreach loop var=");
596 fml_pr_list (info_var->body);
599 rv = fml_exec_group (body, fml);
602 fml_node_delete (fml, fn);
605 info_var->body = NULL;
611 static struct fml_node *fml_exec_if (struct fml_sym_info *info, Fml fml,
612 struct fml_node **lp, struct token *tp)
614 struct fml_node *fn, *body;
615 struct fml_node *rv, *return_value = NULL;
617 fml_cmd_lex (lp, tp);
618 assert (tp->kind == 'g');
619 fn = fml_sub0 (fml, tp->sub);
620 fml_cmd_lex (lp, tp);
621 assert (tp->kind == 'g');
624 rv = fml_exec_group (tp->sub, fml);
628 fml_cmd_lex (lp, tp);
631 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
632 if (info->kind == FML_ELSE)
634 fml_cmd_lex (lp, tp);
635 assert (tp->kind == 'g');
639 rv = fml_exec_group (body, fml);
643 fml_cmd_lex (lp, tp);
646 fml_node_delete (fml, fn);
650 static struct fml_node *fml_exec_while (struct fml_sym_info *info, Fml fml,
651 struct fml_node **lp, struct token *tp)
653 struct fml_node *fn, *body;
654 struct fml_node *return_value = NULL;
656 fml_cmd_lex (lp, tp);
657 assert (tp->kind == 'g');
660 fml_cmd_lex (lp, tp);
661 assert (tp->kind == 'g');
666 struct fml_node *fn_expr;
670 fn_expr = fml_sub0 (fml, fn);
673 fml_node_delete (fml, fn_expr);
674 rv = fml_exec_group (body, fml);
681 static void fml_exec_set (struct fml_sym_info *info, Fml fml,
682 struct fml_node **lp, struct token *tp)
685 struct fml_sym_info *info_var;
687 fml_cmd_lex (lp, tp);
688 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
691 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
692 info_var->body = NULL;
697 printf ("set %s ", tp->tokenbuf);
699 info_var->kind = FML_VAR;
700 fml_cmd_lex (lp, tp);
704 fn = fml_sub0 (fml, tp->sub);
705 fml_cmd_lex (lp, tp);
708 fn = fml_sub2 (fml, lp, tp);
709 fml_node_delete (fml, info_var->body);
713 fml_pr_list (info_var->body);
718 static void fml_emit_expr (Fml fml, struct fml_node **lp, struct token *tp)
722 fn = fml_sub1 (fml, lp, tp);
724 fml_node_delete (fml, fn);
727 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
730 struct fml_sym_info *info;
732 struct fml_node *return_value = NULL, *rv;
736 fml_init_token (&token, fml);
737 fml_cmd_lex (&list, &token);
743 rv = fml_exec_group (token.sub, fml);
748 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
756 fml_cmd_lex (&list, &token);
757 assert (token.kind == 't');
758 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
760 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
761 info->kind = FML_PREFIX;
765 fml_cmd_lex (&list, &token);
766 if (token.kind != 't')
770 info->args = fn = fml_node_alloc (fml);
774 for (fn = info->args; fn->p[1]; fn=fn->p[1])
776 fn = fn->p[1] = fml_node_alloc (fml);
778 fn->p[0] = token.atom;
781 assert (token.kind == 'g');
782 info->body = token.sub;
785 fml_cmd_lex (&list, &token);
786 assert (token.kind == 't');
787 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
789 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
790 info->kind = FML_BINARY;
792 fml_cmd_lex (&list, &token);
793 assert (token.kind == 't');
794 info->args = fn = fml_node_alloc (fml);
795 fn->p[0] = token.atom;
798 fml_cmd_lex (&list, &token);
799 assert (token.kind == 't');
800 fn = fn->p[1] = fml_node_alloc (fml);
801 fn->p[0] = token.atom;
804 fml_cmd_lex (&list, &token);
805 assert (token.kind == 'g');
806 info->body = token.sub;
811 if (token.separate && !first)
814 fml_emit_expr (fml, &list, &token);
818 rv = fml_exec_foreach (info, fml, &list, &token);
823 rv = fml_exec_if (info, fml, &list, &token);
828 fml_exec_set (info, fml, &list, &token);
832 rv = fml_exec_while (info, fml, &list, &token);
837 fml_cmd_lex (&list, &token);
839 if (token.kind == 'g')
841 return_value = fml_sub0 (fml, token.sub);
842 fml_cmd_lex (&list, &token);
845 return_value = fml_sub2 (fml, &list, &token);
849 printf ("return of:");
850 fml_pr_list (return_value);
855 printf ("unknown token: `%s'", token.tokenbuf);
856 fml_cmd_lex (&list, &token);
861 printf ("<unknown>");
866 printf ("<token.tokenbuf=%s>", token.tokenbuf);
868 if (token.separate && !first)
871 fml_emit_expr (fml, &list, &token);
875 fml_cmd_lex (&list, &token);
877 fml_del_token (&token, fml);
881 void fml_exec (Fml fml)
884 fml_exec_group (fml->list, fml);