2 * FML interpreter. Europagate, 1995
5 * Revision 1.1.1.1 1995/02/06 13:48:10 adam
6 * First version of the FML interpreter. It's slow and memory isn't
7 * freed properly. In particular, the FML nodes aren't released yet.
16 static int default_read_func (void)
21 static void default_err_handle (int no)
23 fprintf (stderr, "Error: %d\n", no);
26 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
28 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
31 static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list);
33 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
35 static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
37 static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
39 static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
41 static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
43 static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
45 static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
47 static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
49 static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
52 static int indent = 0;
54 static void pr_indent (int n)
77 struct fml_sym_info *sym_info;
79 Fml fml = malloc (sizeof(*fml));
84 fml->escape_char = '\\';
85 fml->comment_char = '#';
87 fml->white_chars = " \t\f\r\n";
88 fml->read_func = default_read_func;
89 fml->err_handle = default_err_handle;
92 fml->sym_tab = fml_sym_open ();
93 fml->atom_free_list = NULL;
94 fml->node_free_list = NULL;
97 sym_info = fml_sym_add (fml->sym_tab, "func");
98 sym_info->kind = FML_FUNC;
99 sym_info = fml_sym_add (fml->sym_tab, "bin");
100 sym_info->kind = FML_BIN;
101 sym_info = fml_sym_add (fml->sym_tab, "if");
102 sym_info->kind = FML_IF;
103 sym_info = fml_sym_add (fml->sym_tab, "else");
104 sym_info->kind = FML_ELSE;
105 sym_info = fml_sym_add (fml->sym_tab, "foreach");
106 sym_info->kind = FML_FOREACH;
107 sym_info = fml_sym_add (fml->sym_tab, "set");
108 sym_info->kind = FML_SET;
109 sym_info = fml_sym_add (fml->sym_tab, "while");
110 sym_info->kind = FML_WHILE;
111 sym_info = fml_sym_add (fml->sym_tab, "return");
112 sym_info->kind = FML_RETURN;
115 sym_info = fml_sym_add (fml->sym_tab, "and");
116 sym_info->kind = FML_CBINARY;
117 sym_info->binary = fml_exec_and;
118 sym_info = fml_sym_add (fml->sym_tab, "or");
119 sym_info->kind = FML_CBINARY;
120 sym_info->binary = fml_exec_or;
121 sym_info = fml_sym_add (fml->sym_tab, "index");
122 sym_info->kind = FML_CBINARY;
123 sym_info->binary = fml_exec_indx;
125 sym_info = fml_sym_add (fml->sym_tab, "plus");
126 sym_info->kind = FML_CBINARY;
127 sym_info->binary = fml_exec_plus;
128 sym_info = fml_sym_add (fml->sym_tab, "minus");
129 sym_info->kind = FML_CBINARY;
130 sym_info->binary = fml_exec_minus;
132 sym_info = fml_sym_add (fml->sym_tab, "gt");
133 sym_info->kind = FML_CBINARY;
134 sym_info->binary = fml_exec_gt;
135 sym_info = fml_sym_add (fml->sym_tab, "lt");
136 sym_info->kind = FML_CBINARY;
137 sym_info->binary = fml_exec_lt;
138 sym_info = fml_sym_add (fml->sym_tab, "eq");
139 sym_info->kind = FML_CBINARY;
140 sym_info->binary = fml_exec_eq;
142 sym_info = fml_sym_add (fml->sym_tab, "s");
143 sym_info->kind = FML_CPREFIX;
144 sym_info->prefix = fml_exec_space;
145 sym_info = fml_sym_add (fml->sym_tab, " ");
146 sym_info->kind = FML_CPREFIX;
147 sym_info->prefix = fml_exec_space;
148 sym_info = fml_sym_add (fml->sym_tab, "n");
149 sym_info->kind = FML_CPREFIX;
150 sym_info->prefix = fml_exec_nl;
155 static Fml fml_pop_handler = NULL;
156 static void pop_handler (struct fml_sym_info *info)
158 assert (fml_pop_handler);
162 /* fml_node_delete (fml_pop_handler, info->body); */
166 static void fml_do_pop (Fml fml)
168 fml_pop_handler = fml;
169 fml_sym_pop (fml->sym_tab, pop_handler);
172 int fml_preprocess (Fml fml)
174 fml->list = fml_tokenize (fml);
179 static void fml_init_token (struct token *tp, Fml fml)
181 tp->maxbuf = FML_ATOM_BUF*2;
183 tp->atombuf = tp->sbuf;
184 tp->tokenbuf = tp->sbuf + tp->maxbuf;
185 tp->escape_char = fml->escape_char;
188 static void fml_del_token (struct token *tp, Fml fml)
190 if (tp->maxbuf != FML_ATOM_BUF*2)
194 static void fml_cmd_lex (struct fml_node **np, struct token *tp)
207 tp->atom = (*np)->p[0];
209 fml_atom_str (tp->atom, tp->atombuf);
212 int l = fml_atom_str (tp->atom, NULL);
213 if (l >= tp->maxbuf-1)
215 if (tp->maxbuf != FML_ATOM_BUF*2)
218 tp->atombuf = malloc (tp->maxbuf*2);
219 tp->tokenbuf = tp->atombuf + tp->maxbuf;
221 fml_atom_str (tp->atom, tp->atombuf);
226 tp->sub = (*np)->p[0];
232 cp = tp->atombuf + tp->offset;
234 if (*cp == tp->escape_char)
237 tp->after_char = '\0';
250 tp->after_char = ' ';
254 if (*cp == tp->escape_char)
260 tp->after_char = ' ';
270 tp->offset = cp - tp->atombuf;
271 tp->after_char = '\0';
281 static struct fml_node *fml_lex_list (Fml fml, struct token *tp)
287 fn = fml_node_alloc (fml);
293 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml);
295 static void fml_lr_values (struct fml_node *l, int *left_val,
296 struct fml_node *r, int *right_val)
298 static char arg[128];
301 fml_atom_strx (l->p[0], arg, 127);
302 *left_val = atoi (arg);
308 fml_atom_strx (r->p[0], arg, 127);
309 *right_val = atoi (arg);
315 static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
324 static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
332 static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
335 struct fml_node *list = l;
338 if (!l || !r || !r->is_atom)
340 indx = fml_atom_val (r->p[0]);
341 while (--indx >= 0 && list)
347 struct fml_node *fn = fml_node_alloc (fml);
349 fn->p[0] = list->p[0];
356 static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
359 int left_val, right_val;
363 fml_lr_values (l, &left_val, r, &right_val);
364 sprintf (arg, "%d", left_val + right_val);
365 fn = fml_node_alloc (fml);
367 fn->p[0] = fml_atom_alloc (fml, arg);
371 static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
374 int left_val, right_val;
378 fml_lr_values (l, &left_val, r, &right_val);
379 sprintf (arg, "%d", left_val - right_val);
380 fn = fml_node_alloc (fml);
382 fn->p[0] = fml_atom_alloc (fml, arg);
387 static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
390 int left_val, right_val;
392 fml_lr_values (l, &left_val, r, &right_val);
393 if (left_val > right_val)
395 fn = fml_node_alloc (fml);
397 fn->p[0] = fml_atom_alloc (fml, "1");
405 static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
408 int left_val, right_val;
410 fml_lr_values (l, &left_val, r, &right_val);
411 if (left_val < right_val)
413 fn = fml_node_alloc (fml);
415 fn->p[0] = fml_atom_alloc (fml, "1");
422 static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
425 int left_val, right_val;
427 fml_lr_values (l, &left_val, r, &right_val);
428 if (left_val == right_val)
430 fn = fml_node_alloc (fml);
432 fn->p[0] = fml_atom_alloc (fml, "1");
440 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
446 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
453 static struct fml_node *fml_exec_prefix (struct fml_sym_info *info, Fml fml,
454 struct fml_node **lp,
458 struct fml_sym_info *arg_info;
459 struct fml_node *return_value;
460 static char arg[128];
465 printf ("exec_prefix ");
467 fml_sym_push (fml->sym_tab);
468 for (fn = info->args; fn; fn = fn->p[1])
470 fml_cmd_lex (lp, tp);
472 assert (fn->is_atom);
473 fml_atom_strx (fn->p[0], arg, 127);
480 arg_info = fml_sym_add_local (fml->sym_tab, arg);
481 arg_info->kind = FML_VAR;
482 arg_info->body = fml_lex_list (fml, tp);
484 arg_info->body = fml_sub0 (fml, arg_info->body);
487 fml_pr_list (arg_info->body);
491 return_value = fml_exec_group (info->body, fml);
502 static void fml_emit (struct fml_node *list)
513 for (a = list->p[0]; a; a=a->next)
514 printf ("%s", a->buf);
517 fml_emit (list->p[0]);
522 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
526 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
530 struct fml_sym_info *info;
533 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
539 fml_cmd_lex (lp, tp);
542 fn = fml_exec_prefix (info, fml, lp, tp);
543 fml_cmd_lex (lp, tp);
546 fn = (*info->prefix) (fml, lp, tp);
547 fml_cmd_lex (lp, tp);
550 fml_cmd_lex (lp, tp);
554 else if (tp->kind == 'g')
557 fn = fml_sub0 (fml, tp->sub);
560 fml_cmd_lex (lp, tp);
562 else if (tp->kind == 't')
564 fn = fml_node_alloc (fml);
566 fn->p[0] = fml_atom_alloc (fml, tp->tokenbuf);
567 fml_cmd_lex (lp, tp);
574 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
577 struct fml_node *f1, *f2;
578 struct fml_sym_info *info;
580 f1 = fml_sub2 (fml, lp, tp);
581 while (tp->kind == 'e')
583 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
586 fprintf (stderr, "cannot locate `%s'", tp->tokenbuf);
589 if (info->kind == FML_CBINARY)
591 fml_cmd_lex (lp, tp);
592 f2 = fml_sub2 (fml, lp, tp);
593 f1 = (*info->binary) (fml, f1, f2);
596 else if (info->kind == FML_BINARY)
598 struct fml_sym_info *arg_info;
604 printf ("exec binary %s", tp->tokenbuf);
606 fml_cmd_lex (lp, tp);
607 f2 = fml_sub2 (fml, lp, tp);
608 fml_sym_push (fml->sym_tab);
610 fml_atom_strx (info->args->p[0], arg, 127);
611 arg_info = fml_sym_add_local (fml->sym_tab, arg);
612 arg_info->kind = FML_VAR;
619 fml_atom_strx ( ((struct fml_node *) info->args->p[1])->p[0],
621 arg_info = fml_sym_add_local (fml->sym_tab, arg);
622 arg_info->kind = FML_VAR;
630 f1 = fml_exec_group (info->body, fml);
645 static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list)
648 struct fml_node *fn, *fn1;
650 fml_init_token (&token, fml);
652 fml_cmd_lex (&list, &token);
653 fn = fml_sub1 (fml, &list, &token);
654 if (token.kind == '\0')
656 fml_del_token (&token, fml);
659 fn1 = fml_node_alloc (fml);
662 while (token.kind != '\0')
664 fn1 = fn1->p[1] = fml_node_alloc (fml);
665 fn1->p[0] = fml_sub1 (fml, &list, &token);
667 fml_del_token (&token, fml);
672 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
675 struct fml_node *fn, *fn1;
677 fml_init_token (&token, fml);
679 fml_cmd_lex (&list, &token);
680 fn1 = fn = fml_sub1 (fml, &list, &token);
682 while (token.kind != '\0')
683 fn1 = fn1->p[1] = fml_sub1 (fml, &list, &token);
684 fml_del_token (&token, fml);
688 static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
689 struct fml_node **lp,
692 struct fml_sym_info *info_var;
693 struct fml_node *fn, *body;
694 struct fml_node *return_value = NULL, *rv;
696 fml_cmd_lex (lp, tp);
697 assert (tp->kind == 't');
699 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
702 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
703 info_var->body = NULL;
704 info_var->kind = FML_VAR;
709 printf ("[foreach %s ", tp->tokenbuf);
711 fml_cmd_lex (lp, tp);
713 fn = fml_lex_list (fml, tp);
715 fn = fml_sub0 (fml, fn);
717 fml_cmd_lex (lp, tp);
719 body = fml_lex_list (fml, tp);
725 struct fml_node *fn1;
726 fn1 = fml_node_alloc (fml);
728 fn1->p[0] = fn->p[0];
729 info_var->body = fn1;
732 info_var->body = fn->p[0];
737 printf ("[foreach loop var=");
738 fml_pr_list (info_var->body);
741 rv = fml_exec_group (body, fml);
751 static struct fml_node *fml_exec_if (struct fml_sym_info *info, Fml fml,
752 struct fml_node **lp, struct token *tp)
754 struct fml_node *fn, *body;
755 struct fml_node *rv, *return_value = NULL;
757 fml_cmd_lex (lp, tp);
758 fn = fml_lex_list (fml, tp);
760 fn = fml_sub0 (fml, fn);
761 fml_cmd_lex (lp, tp);
764 body = fml_lex_list (fml, tp);
765 rv = fml_exec_group (body, fml);
769 fml_cmd_lex (lp, tp);
772 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
773 if (info->kind == FML_ELSE)
775 fml_cmd_lex (lp, tp);
776 body = fml_lex_list (fml, tp);
777 fml_cmd_lex (lp, tp);
780 rv = fml_exec_group (body, fml);
789 static struct fml_node *fml_exec_while (struct fml_sym_info *info, Fml fml,
790 struct fml_node **lp, struct token *tp)
792 struct fml_node *fn, *body;
793 struct fml_node *return_value = NULL;
795 fml_cmd_lex (lp, tp);
796 fn = fml_lex_list (fml, tp);
798 fml_cmd_lex (lp, tp);
799 body = fml_lex_list (fml, tp);
802 struct fml_node *fn_expr;
806 fn_expr = fml_sub0 (fml, fn);
809 rv = fml_exec_group (body, fml);
816 static void fml_exec_set (struct fml_sym_info *info, Fml fml,
817 struct fml_node **lp, struct token *tp)
820 struct fml_sym_info *info_var;
822 fml_cmd_lex (lp, tp);
823 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
826 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
827 info_var->body = NULL;
832 printf ("set %s ", tp->tokenbuf);
834 info_var->kind = FML_VAR;
835 fml_cmd_lex (lp, tp);
836 fn = fml_lex_list (fml, tp);
839 fn = fml_sub0 (fml, fn);
843 fml_pr_list (info_var->body);
848 static void fml_emit_expr (Fml fml, struct fml_node **lp, struct token *tp)
852 fn = fml_sub1 (fml, lp, tp);
855 if (fn && fn->is_atom)
858 fml_atom_strx (fn->p[0], arg, 127);
864 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
867 struct fml_sym_info *info;
869 struct fml_node *return_value = NULL, *rv;
873 fml_init_token (&token, fml);
874 fml_cmd_lex (&list, &token);
880 rv = fml_exec_group (token.sub, fml);
885 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
893 fml_cmd_lex (&list, &token);
894 assert (token.kind == 't');
895 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
897 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
898 info->kind = FML_PREFIX;
902 fml_cmd_lex (&list, &token);
903 if (token.kind != 't')
907 info->args = fn = fml_node_alloc (fml);
911 for (fn = info->args; fn->p[1]; fn=fn->p[1])
913 fn = fn->p[1] = fml_node_alloc (fml);
915 fn->p[0] = token.atom;
918 assert (token.kind == 'g');
919 info->body = token.sub;
922 fml_cmd_lex (&list, &token);
923 assert (token.kind == 't');
924 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
926 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
927 info->kind = FML_BINARY;
929 fml_cmd_lex (&list, &token);
930 assert (token.kind == 't');
931 info->args = fn = fml_node_alloc (fml);
932 fn->p[0] = token.atom;
935 fml_cmd_lex (&list, &token);
936 assert (token.kind == 't');
937 fn = fn->p[1] = fml_node_alloc (fml);
938 fn->p[0] = token.atom;
941 fml_cmd_lex (&list, &token);
942 assert (token.kind == 'g');
943 info->body = token.sub;
947 after_char = token.after_char;
948 fml_exec_prefix (info, fml, &list, &token);
950 putchar (after_char);
953 fml_emit (info->body);
954 if (token.after_char)
955 putchar (token.after_char);
963 if (token.offset == 0)
967 fml_emit_expr (fml, &list, &token);
970 rv = fml_exec_foreach (info, fml, &list, &token);
975 rv = fml_exec_if (info, fml, &list, &token);
980 fml_exec_set (info, fml, &list, &token);
983 rv = fml_exec_while (info, fml, &list, &token);
988 fml_cmd_lex (&list, &token);
989 return_value = fml_lex_list (fml, &token);
991 return_value = fml_sub0 (fml, return_value);
995 printf ("return of:");
996 fml_pr_list (return_value);
1001 printf ("unknown token: `%s'", token.tokenbuf);
1002 fml_cmd_lex (&list, &token);
1007 printf ("<unknown>");
1013 if (token.offset == 0)
1017 fml_emit_expr (fml, &list, &token);
1020 printf ("%s", token.tokenbuf);
1021 if (token.after_char)
1022 putchar (token.after_char);
1025 fml_cmd_lex (&list, &token);
1027 fml_del_token (&token, fml);
1028 return return_value;
1031 void fml_exec (Fml fml)
1033 fml_exec_group (fml->list, fml);