2 * FML interpreter. Europagate, 1995
5 * Revision 1.6 1995/02/09 16:06:06 adam
6 * FML can be called from the outside multiple times by the functions:
7 * fml_exec_call and fml_exec_call_str.
8 * An interactive parameter (-i) to fmltest starts a shell-like
9 * interface to FML by using the fml_exec_call_str function.
11 * Revision 1.5 1995/02/09 14:33:36 adam
12 * Split source fml.c and define relevant build-in functions in separate
13 * files. New operators mult, div, not, llen implemented.
15 * Revision 1.4 1995/02/09 13:07:14 adam
16 * Nodes are freed now. Many bugs fixed.
18 * Revision 1.3 1995/02/07 16:09:23 adam
19 * The \ character is no longer INCLUDED when terminating a token.
20 * Major changes in tokenization routines. Bug fixes in expressions
21 * with lists (fml_sub0).
23 * Revision 1.2 1995/02/06 15:23:25 adam
24 * Added some more relational operators (le,ne,ge). Added increment
25 * and decrement operators. Function index changed, so that first
26 * element is 1 - not 0. Function fml_atom_val edited.
28 * Revision 1.1.1.1 1995/02/06 13:48:10 adam
29 * First version of the FML interpreter. It's slow and memory isn't
30 * freed properly. In particular, the FML nodes aren't released yet.
39 static int default_read_func (void)
44 static void default_err_handle (int no)
46 fprintf (stderr, "Error: %d\n", no);
49 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
50 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
52 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
54 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
56 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
59 static int indent = 0;
61 static void pr_indent (int n)
84 struct fml_sym_info *sym_info;
86 Fml fml = malloc (sizeof(*fml));
91 fml->escape_char = '\\';
92 fml->comment_char = '#';
94 fml->white_chars = " \t\f\r\n";
95 fml->read_func = default_read_func;
96 fml->err_handle = default_err_handle;
99 fml->sym_tab = fml_sym_open ();
100 fml->atom_free_list = NULL;
101 fml->node_free_list = NULL;
104 sym_info = fml_sym_add (fml->sym_tab, "func");
105 sym_info->kind = FML_FUNC;
106 sym_info = fml_sym_add (fml->sym_tab, "bin");
107 sym_info->kind = FML_BIN;
108 sym_info = fml_sym_add (fml->sym_tab, "if");
109 sym_info->kind = FML_IF;
110 sym_info = fml_sym_add (fml->sym_tab, "else");
111 sym_info->kind = FML_ELSE;
112 sym_info = fml_sym_add (fml->sym_tab, "foreach");
113 sym_info->kind = FML_FOREACH;
114 sym_info = fml_sym_add (fml->sym_tab, "set");
115 sym_info->kind = FML_SET;
116 sym_info = fml_sym_add (fml->sym_tab, "while");
117 sym_info->kind = FML_WHILE;
118 sym_info = fml_sym_add (fml->sym_tab, "return");
119 sym_info->kind = FML_RETURN;
125 sym_info = fml_sym_add (fml->sym_tab, "s");
126 sym_info->kind = FML_CPREFIX;
127 sym_info->prefix = fml_exec_space;
128 sym_info = fml_sym_add (fml->sym_tab, " ");
129 sym_info->kind = FML_CPREFIX;
130 sym_info->prefix = fml_exec_space;
131 sym_info = fml_sym_add (fml->sym_tab, "n");
132 sym_info->kind = FML_CPREFIX;
133 sym_info->prefix = fml_exec_nl;
138 static Fml fml_pop_handler = NULL;
139 static void pop_handler (struct fml_sym_info *info)
141 assert (fml_pop_handler);
145 fml_node_delete (fml_pop_handler, info->body);
149 static void fml_do_pop (Fml fml)
151 fml_pop_handler = fml;
152 fml_sym_pop (fml->sym_tab, pop_handler);
155 int fml_preprocess (Fml fml)
157 fml->list = fml_tokenize (fml);
162 void fml_init_token (struct token *tp, Fml fml)
164 tp->maxbuf = FML_ATOM_BUF*2;
166 tp->atombuf = tp->sbuf;
167 tp->tokenbuf = tp->sbuf + tp->maxbuf;
168 tp->escape_char = fml->escape_char;
171 void fml_del_token (struct token *tp, Fml fml)
173 if (tp->maxbuf != FML_ATOM_BUF*2)
177 void fml_cmd_lex (struct fml_node **np, struct token *tp)
191 tp->atom = (*np)->p[0];
193 fml_atom_str (tp->atom, tp->atombuf);
196 int l = fml_atom_str (tp->atom, NULL);
197 if (l >= tp->maxbuf-1)
199 if (tp->maxbuf != FML_ATOM_BUF*2)
202 tp->atombuf = malloc (tp->maxbuf*2);
203 tp->tokenbuf = tp->atombuf + tp->maxbuf;
205 fml_atom_str (tp->atom, tp->atombuf);
210 tp->sub = (*np)->p[0];
218 cp = tp->atombuf + tp->offset;
220 if (*cp == tp->escape_char)
238 if (*cp == tp->escape_char)
241 tp->offset = cp - tp->atombuf;
251 struct fml_node *fml_expr_term (Fml fml, struct fml_node **lp,
257 fn = fml_sub0 (fml, tp->sub);
258 fml_cmd_lex (lp, tp);
261 fn = fml_sub2 (fml, lp, tp);
265 void fml_lr_values (Fml fml, struct fml_node *l, int *left_val,
266 struct fml_node *r, int *right_val)
269 *left_val = fml_atom_val (l->p[0]);
273 *right_val = fml_atom_val (r->p[0]);
276 fml_node_delete (fml, l);
277 fml_node_delete (fml, r);
280 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
283 fml_cmd_lex (lp, tp);
288 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
291 fml_cmd_lex (lp, tp);
296 static struct fml_node *fml_exec_prefix (struct fml_sym_info *info, Fml fml,
297 struct fml_node **lp,
301 struct fml_sym_info *arg_info;
302 struct fml_node *return_value;
303 static char arg[128];
308 printf ("exec_prefix ");
310 fml_sym_push (fml->sym_tab);
311 fml_cmd_lex (lp, tp);
312 for (fn = info->args; fn; fn = fn->p[1])
315 assert (fn->is_atom);
316 fml_atom_strx (fn->p[0], arg, 127);
322 arg_info = fml_sym_add_local (fml->sym_tab, arg);
323 arg_info->kind = FML_VAR;
327 arg_info->body = fml_sub0 (fml, tp->sub);
328 fml_cmd_lex (lp, tp);
331 arg_info->body = fml_sub2 (fml, lp, tp);
334 fml_pr_list (arg_info->body);
338 return_value = fml_exec_group (info->body, fml);
349 static void fml_emit (struct fml_node *list)
360 for (a = list->p[0]; a; a=a->next)
361 printf ("%s", a->buf);
364 fml_emit (list->p[0]);
370 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
374 struct fml_sym_info *info;
377 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
382 fn = fml_node_copy (fml, info->body);
383 fml_cmd_lex (lp, tp);
386 fn = fml_exec_prefix (info, fml, lp, tp);
389 fn = (*info->prefix) (fml, lp, tp);
390 fml_cmd_lex (lp, tp);
393 fml_cmd_lex (lp, tp);
397 else if (tp->kind == 'g')
400 fn = fml_sub0 (fml, tp->sub);
403 fml_cmd_lex (lp, tp);
405 else if (tp->kind == 't')
407 fn = fml_node_alloc (fml);
409 fn->p[0] = fml_atom_alloc (fml, tp->tokenbuf);
410 fml_cmd_lex (lp, tp);
417 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
420 struct fml_node *f1, *f2, *fn;
421 struct fml_sym_info *info;
423 f1 = fml_sub2 (fml, lp, tp);
424 while (tp->kind == 'e')
426 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
429 fprintf (stderr, "cannot locate `%s'", tp->tokenbuf);
432 if (info->kind == FML_CBINARY)
434 fml_cmd_lex (lp, tp);
435 f2 = fml_sub2 (fml, lp, tp);
436 fn = (*info->binary) (fml, f1, f2);
440 else if (info->kind == FML_BINARY)
442 struct fml_sym_info *arg_info;
448 printf ("exec binary %s", tp->tokenbuf);
450 fml_cmd_lex (lp, tp);
451 f2 = fml_sub2 (fml, lp, tp);
452 fml_sym_push (fml->sym_tab);
454 fml_atom_strx (info->args->p[0], arg, 127);
455 arg_info = fml_sym_add_local (fml->sym_tab, arg);
456 arg_info->kind = FML_VAR;
463 fml_atom_strx ( ((struct fml_node *) info->args->p[1])->p[0],
465 arg_info = fml_sym_add_local (fml->sym_tab, arg);
466 arg_info->kind = FML_VAR;
474 f1 = fml_exec_group (info->body, fml);
489 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
492 struct fml_node *fn, *fn1;
494 fml_init_token (&token, fml);
496 fml_cmd_lex (&list, &token);
497 fn = fml_sub1 (fml, &list, &token);
498 if (token.kind == '\0')
500 fml_del_token (&token, fml);
503 fn1 = fml_node_alloc (fml);
506 while (token.kind != '\0')
508 fn1 = fn1->p[1] = fml_node_alloc (fml);
509 fn1->p[0] = fml_sub1 (fml, &list, &token);
511 fml_del_token (&token, fml);
515 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
518 struct fml_node *fn, *fn0, *fn1;
522 fml_init_token (&token, fml);
524 fml_cmd_lex (&list, &token);
525 fn1 = fn = fml_sub1 (fml, &list, &token);
526 if (fn->p[1] && token.kind != '\0')
528 fn1 = fml_node_alloc (fml);
532 while (token.kind != '\0')
534 fn = fml_sub1 (fml, &list, &token);
537 fn1 = fn1->p[1] = fml_node_alloc (fml);
542 fn1 = fn1->p[1] = fn;
545 fml_del_token (&token, fml);
550 static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
551 struct fml_node **lp,
554 struct fml_sym_info *info_var;
555 struct fml_node *fn, *body;
556 struct fml_node *return_value = NULL, *rv;
558 fml_cmd_lex (lp, tp);
559 assert (tp->kind == 't');
561 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
564 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
565 info_var->body = NULL;
566 info_var->kind = FML_VAR;
570 fml_node_delete (fml, info->body);
576 printf ("[foreach %s ", tp->tokenbuf);
578 fml_cmd_lex (lp, tp);
579 assert (tp->kind == 'g');
580 fn = fml_sub0 (fml, tp->sub);
582 fml_cmd_lex (lp, tp);
583 assert (tp->kind == 'g');
588 struct fml_node *fn1;
595 info_var->body = fn->p[0];
599 printf ("[foreach loop var=");
600 fml_pr_list (info_var->body);
603 rv = fml_exec_group (body, fml);
606 fml_node_delete (fml, fn);
609 info_var->body = NULL;
615 static struct fml_node *fml_exec_if (struct fml_sym_info *info, Fml fml,
616 struct fml_node **lp, struct token *tp)
618 struct fml_node *fn, *body;
619 struct fml_node *rv, *return_value = NULL;
621 fml_cmd_lex (lp, tp);
622 assert (tp->kind == 'g');
623 fn = fml_sub0 (fml, tp->sub);
624 fml_cmd_lex (lp, tp);
625 assert (tp->kind == 'g');
628 rv = fml_exec_group (tp->sub, fml);
632 fml_cmd_lex (lp, tp);
635 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
636 if (info->kind == FML_ELSE)
638 fml_cmd_lex (lp, tp);
639 assert (tp->kind == 'g');
643 rv = fml_exec_group (body, fml);
647 fml_cmd_lex (lp, tp);
650 fml_node_delete (fml, fn);
654 static struct fml_node *fml_exec_while (struct fml_sym_info *info, Fml fml,
655 struct fml_node **lp, struct token *tp)
657 struct fml_node *fn, *body;
658 struct fml_node *return_value = NULL;
660 fml_cmd_lex (lp, tp);
661 assert (tp->kind == 'g');
664 fml_cmd_lex (lp, tp);
665 assert (tp->kind == 'g');
670 struct fml_node *fn_expr;
674 fn_expr = fml_sub0 (fml, fn);
677 fml_node_delete (fml, fn_expr);
678 rv = fml_exec_group (body, fml);
685 static void fml_exec_set (struct fml_sym_info *info, Fml fml,
686 struct fml_node **lp, struct token *tp)
689 struct fml_sym_info *info_var;
691 fml_cmd_lex (lp, tp);
692 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
695 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
696 info_var->body = NULL;
701 printf ("set %s ", tp->tokenbuf);
703 info_var->kind = FML_VAR;
704 fml_cmd_lex (lp, tp);
708 fn = fml_sub0 (fml, tp->sub);
709 fml_cmd_lex (lp, tp);
712 fn = fml_sub2 (fml, lp, tp);
713 fml_node_delete (fml, info_var->body);
717 fml_pr_list (info_var->body);
722 static void fml_emit_expr (Fml fml, struct fml_node **lp, struct token *tp)
726 fn = fml_sub1 (fml, lp, tp);
728 fml_node_delete (fml, fn);
731 struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
734 struct fml_sym_info *info;
736 struct fml_node *return_value = NULL, *rv;
740 fml_init_token (&token, fml);
741 fml_cmd_lex (&list, &token);
747 rv = fml_exec_group (token.sub, fml);
752 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
760 fml_cmd_lex (&list, &token);
761 assert (token.kind == 't');
762 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
764 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
765 info->kind = FML_PREFIX;
769 fml_cmd_lex (&list, &token);
770 if (token.kind != 't')
774 info->args = fn = fml_node_alloc (fml);
778 for (fn = info->args; fn->p[1]; fn=fn->p[1])
780 fn = fn->p[1] = fml_node_alloc (fml);
782 fn->p[0] = token.atom;
785 assert (token.kind == 'g');
786 info->body = token.sub;
789 fml_cmd_lex (&list, &token);
790 assert (token.kind == 't');
791 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
793 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
794 info->kind = FML_BINARY;
796 fml_cmd_lex (&list, &token);
797 assert (token.kind == 't');
798 info->args = fn = fml_node_alloc (fml);
799 fn->p[0] = token.atom;
802 fml_cmd_lex (&list, &token);
803 assert (token.kind == 't');
804 fn = fn->p[1] = fml_node_alloc (fml);
805 fn->p[0] = token.atom;
808 fml_cmd_lex (&list, &token);
809 assert (token.kind == 'g');
810 info->body = token.sub;
815 if (token.separate && !first)
818 fml_emit_expr (fml, &list, &token);
822 rv = fml_exec_foreach (info, fml, &list, &token);
827 rv = fml_exec_if (info, fml, &list, &token);
832 fml_exec_set (info, fml, &list, &token);
836 rv = fml_exec_while (info, fml, &list, &token);
841 fml_cmd_lex (&list, &token);
843 if (token.kind == 'g')
845 return_value = fml_sub0 (fml, token.sub);
846 fml_cmd_lex (&list, &token);
849 return_value = fml_sub2 (fml, &list, &token);
853 printf ("return of:");
854 fml_pr_list (return_value);
859 printf ("unknown token: `%s'", token.tokenbuf);
860 fml_cmd_lex (&list, &token);
865 printf ("<unknown>");
869 if (token.separate && !first)
872 fml_emit_expr (fml, &list, &token);
876 fml_cmd_lex (&list, &token);
878 fml_del_token (&token, fml);
882 void fml_exec (Fml fml)
885 fml_exec_group (fml->list, fml);