2 * FML interpreter. Europagate, 1995
5 * Revision 1.1 1995/02/06 13:48:09 adam
15 static int default_read_func (void)
20 static void default_err_handle (int no)
22 fprintf (stderr, "Error: %d\n", no);
25 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
27 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
30 static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list);
32 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
34 static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
36 static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
38 static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
40 static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
42 static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
44 static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
46 static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
48 static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
51 static int indent = 0;
53 static void pr_indent (int n)
76 struct fml_sym_info *sym_info;
78 Fml fml = malloc (sizeof(*fml));
83 fml->escape_char = '\\';
84 fml->comment_char = '#';
86 fml->white_chars = " \t\f\r\n";
87 fml->read_func = default_read_func;
88 fml->err_handle = default_err_handle;
91 fml->sym_tab = fml_sym_open ();
92 fml->atom_free_list = NULL;
93 fml->node_free_list = NULL;
96 sym_info = fml_sym_add (fml->sym_tab, "func");
97 sym_info->kind = FML_FUNC;
98 sym_info = fml_sym_add (fml->sym_tab, "bin");
99 sym_info->kind = FML_BIN;
100 sym_info = fml_sym_add (fml->sym_tab, "if");
101 sym_info->kind = FML_IF;
102 sym_info = fml_sym_add (fml->sym_tab, "else");
103 sym_info->kind = FML_ELSE;
104 sym_info = fml_sym_add (fml->sym_tab, "foreach");
105 sym_info->kind = FML_FOREACH;
106 sym_info = fml_sym_add (fml->sym_tab, "set");
107 sym_info->kind = FML_SET;
108 sym_info = fml_sym_add (fml->sym_tab, "while");
109 sym_info->kind = FML_WHILE;
110 sym_info = fml_sym_add (fml->sym_tab, "return");
111 sym_info->kind = FML_RETURN;
114 sym_info = fml_sym_add (fml->sym_tab, "and");
115 sym_info->kind = FML_CBINARY;
116 sym_info->binary = fml_exec_and;
117 sym_info = fml_sym_add (fml->sym_tab, "or");
118 sym_info->kind = FML_CBINARY;
119 sym_info->binary = fml_exec_or;
120 sym_info = fml_sym_add (fml->sym_tab, "index");
121 sym_info->kind = FML_CBINARY;
122 sym_info->binary = fml_exec_indx;
124 sym_info = fml_sym_add (fml->sym_tab, "plus");
125 sym_info->kind = FML_CBINARY;
126 sym_info->binary = fml_exec_plus;
127 sym_info = fml_sym_add (fml->sym_tab, "minus");
128 sym_info->kind = FML_CBINARY;
129 sym_info->binary = fml_exec_minus;
131 sym_info = fml_sym_add (fml->sym_tab, "gt");
132 sym_info->kind = FML_CBINARY;
133 sym_info->binary = fml_exec_gt;
134 sym_info = fml_sym_add (fml->sym_tab, "lt");
135 sym_info->kind = FML_CBINARY;
136 sym_info->binary = fml_exec_lt;
137 sym_info = fml_sym_add (fml->sym_tab, "eq");
138 sym_info->kind = FML_CBINARY;
139 sym_info->binary = fml_exec_eq;
141 sym_info = fml_sym_add (fml->sym_tab, "s");
142 sym_info->kind = FML_CPREFIX;
143 sym_info->prefix = fml_exec_space;
144 sym_info = fml_sym_add (fml->sym_tab, " ");
145 sym_info->kind = FML_CPREFIX;
146 sym_info->prefix = fml_exec_space;
147 sym_info = fml_sym_add (fml->sym_tab, "n");
148 sym_info->kind = FML_CPREFIX;
149 sym_info->prefix = fml_exec_nl;
154 static Fml fml_pop_handler = NULL;
155 static void pop_handler (struct fml_sym_info *info)
157 assert (fml_pop_handler);
161 /* fml_node_delete (fml_pop_handler, info->body); */
165 static void fml_do_pop (Fml fml)
167 fml_pop_handler = fml;
168 fml_sym_pop (fml->sym_tab, pop_handler);
171 int fml_preprocess (Fml fml)
173 fml->list = fml_tokenize (fml);
178 static void fml_init_token (struct token *tp, Fml fml)
180 tp->maxbuf = FML_ATOM_BUF*2;
182 tp->atombuf = tp->sbuf;
183 tp->tokenbuf = tp->sbuf + tp->maxbuf;
184 tp->escape_char = fml->escape_char;
187 static void fml_del_token (struct token *tp, Fml fml)
189 if (tp->maxbuf != FML_ATOM_BUF*2)
193 static void fml_cmd_lex (struct fml_node **np, struct token *tp)
206 tp->atom = (*np)->p[0];
208 fml_atom_str (tp->atom, tp->atombuf);
211 int l = fml_atom_str (tp->atom, NULL);
212 if (l >= tp->maxbuf-1)
214 if (tp->maxbuf != FML_ATOM_BUF*2)
217 tp->atombuf = malloc (tp->maxbuf*2);
218 tp->tokenbuf = tp->atombuf + tp->maxbuf;
220 fml_atom_str (tp->atom, tp->atombuf);
225 tp->sub = (*np)->p[0];
231 cp = tp->atombuf + tp->offset;
233 if (*cp == tp->escape_char)
236 tp->after_char = '\0';
249 tp->after_char = ' ';
253 if (*cp == tp->escape_char)
259 tp->after_char = ' ';
269 tp->offset = cp - tp->atombuf;
270 tp->after_char = '\0';
280 static struct fml_node *fml_lex_list (Fml fml, struct token *tp)
286 fn = fml_node_alloc (fml);
292 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml);
294 static void fml_lr_values (struct fml_node *l, int *left_val,
295 struct fml_node *r, int *right_val)
297 static char arg[128];
300 fml_atom_strx (l->p[0], arg, 127);
301 *left_val = atoi (arg);
307 fml_atom_strx (r->p[0], arg, 127);
308 *right_val = atoi (arg);
314 static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
323 static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
331 static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
334 struct fml_node *list = l;
337 if (!l || !r || !r->is_atom)
339 indx = fml_atom_val (r->p[0]);
340 while (--indx >= 0 && list)
346 struct fml_node *fn = fml_node_alloc (fml);
348 fn->p[0] = list->p[0];
355 static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
358 int left_val, right_val;
362 fml_lr_values (l, &left_val, r, &right_val);
363 sprintf (arg, "%d", left_val + right_val);
364 fn = fml_node_alloc (fml);
366 fn->p[0] = fml_atom_alloc (fml, arg);
370 static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
373 int left_val, right_val;
377 fml_lr_values (l, &left_val, r, &right_val);
378 sprintf (arg, "%d", left_val - right_val);
379 fn = fml_node_alloc (fml);
381 fn->p[0] = fml_atom_alloc (fml, arg);
386 static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
389 int left_val, right_val;
391 fml_lr_values (l, &left_val, r, &right_val);
392 if (left_val > right_val)
394 fn = fml_node_alloc (fml);
396 fn->p[0] = fml_atom_alloc (fml, "1");
404 static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
407 int left_val, right_val;
409 fml_lr_values (l, &left_val, r, &right_val);
410 if (left_val < right_val)
412 fn = fml_node_alloc (fml);
414 fn->p[0] = fml_atom_alloc (fml, "1");
421 static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
424 int left_val, right_val;
426 fml_lr_values (l, &left_val, r, &right_val);
427 if (left_val == right_val)
429 fn = fml_node_alloc (fml);
431 fn->p[0] = fml_atom_alloc (fml, "1");
439 static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
445 static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
452 static struct fml_node *fml_exec_prefix (struct fml_sym_info *info, Fml fml,
453 struct fml_node **lp,
457 struct fml_sym_info *arg_info;
458 struct fml_node *return_value;
459 static char arg[128];
464 printf ("exec_prefix ");
466 fml_sym_push (fml->sym_tab);
467 for (fn = info->args; fn; fn = fn->p[1])
469 fml_cmd_lex (lp, tp);
471 assert (fn->is_atom);
472 fml_atom_strx (fn->p[0], arg, 127);
479 arg_info = fml_sym_add_local (fml->sym_tab, arg);
480 arg_info->kind = FML_VAR;
481 arg_info->body = fml_lex_list (fml, tp);
483 arg_info->body = fml_sub0 (fml, arg_info->body);
486 fml_pr_list (arg_info->body);
490 return_value = fml_exec_group (info->body, fml);
501 static void fml_emit (struct fml_node *list)
512 for (a = list->p[0]; a; a=a->next)
513 printf ("%s", a->buf);
516 fml_emit (list->p[0]);
521 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
525 static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
529 struct fml_sym_info *info;
532 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
538 fml_cmd_lex (lp, tp);
541 fn = fml_exec_prefix (info, fml, lp, tp);
542 fml_cmd_lex (lp, tp);
545 fn = (*info->prefix) (fml, lp, tp);
546 fml_cmd_lex (lp, tp);
549 fml_cmd_lex (lp, tp);
553 else if (tp->kind == 'g')
556 fn = fml_sub0 (fml, tp->sub);
559 fml_cmd_lex (lp, tp);
561 else if (tp->kind == 't')
563 fn = fml_node_alloc (fml);
565 fn->p[0] = fml_atom_alloc (fml, tp->tokenbuf);
566 fml_cmd_lex (lp, tp);
573 static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
576 struct fml_node *f1, *f2;
577 struct fml_sym_info *info;
579 f1 = fml_sub2 (fml, lp, tp);
580 while (tp->kind == 'e')
582 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
585 fprintf (stderr, "cannot locate `%s'", tp->tokenbuf);
588 if (info->kind == FML_CBINARY)
590 fml_cmd_lex (lp, tp);
591 f2 = fml_sub2 (fml, lp, tp);
592 f1 = (*info->binary) (fml, f1, f2);
595 else if (info->kind == FML_BINARY)
597 struct fml_sym_info *arg_info;
603 printf ("exec binary %s", tp->tokenbuf);
605 fml_cmd_lex (lp, tp);
606 f2 = fml_sub2 (fml, lp, tp);
607 fml_sym_push (fml->sym_tab);
609 fml_atom_strx (info->args->p[0], arg, 127);
610 arg_info = fml_sym_add_local (fml->sym_tab, arg);
611 arg_info->kind = FML_VAR;
618 fml_atom_strx ( ((struct fml_node *) info->args->p[1])->p[0],
620 arg_info = fml_sym_add_local (fml->sym_tab, arg);
621 arg_info->kind = FML_VAR;
629 f1 = fml_exec_group (info->body, fml);
644 static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list)
647 struct fml_node *fn, *fn1;
649 fml_init_token (&token, fml);
651 fml_cmd_lex (&list, &token);
652 fn = fml_sub1 (fml, &list, &token);
653 if (token.kind == '\0')
655 fml_del_token (&token, fml);
658 fn1 = fml_node_alloc (fml);
661 while (token.kind != '\0')
663 fn1 = fn1->p[1] = fml_node_alloc (fml);
664 fn1->p[0] = fml_sub1 (fml, &list, &token);
666 fml_del_token (&token, fml);
671 static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
674 struct fml_node *fn, *fn1;
676 fml_init_token (&token, fml);
678 fml_cmd_lex (&list, &token);
679 fn1 = fn = fml_sub1 (fml, &list, &token);
681 while (token.kind != '\0')
682 fn1 = fn1->p[1] = fml_sub1 (fml, &list, &token);
683 fml_del_token (&token, fml);
687 static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
688 struct fml_node **lp,
691 struct fml_sym_info *info_var;
692 struct fml_node *fn, *body;
693 struct fml_node *return_value = NULL, *rv;
695 fml_cmd_lex (lp, tp);
696 assert (tp->kind == 't');
698 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
701 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
702 info_var->body = NULL;
703 info_var->kind = FML_VAR;
708 printf ("[foreach %s ", tp->tokenbuf);
710 fml_cmd_lex (lp, tp);
712 fn = fml_lex_list (fml, tp);
714 fn = fml_sub0 (fml, fn);
716 fml_cmd_lex (lp, tp);
718 body = fml_lex_list (fml, tp);
724 struct fml_node *fn1;
725 fn1 = fml_node_alloc (fml);
727 fn1->p[0] = fn->p[0];
728 info_var->body = fn1;
731 info_var->body = fn->p[0];
736 printf ("[foreach loop var=");
737 fml_pr_list (info_var->body);
740 rv = fml_exec_group (body, fml);
750 static struct fml_node *fml_exec_if (struct fml_sym_info *info, Fml fml,
751 struct fml_node **lp, struct token *tp)
753 struct fml_node *fn, *body;
754 struct fml_node *rv, *return_value = NULL;
756 fml_cmd_lex (lp, tp);
757 fn = fml_lex_list (fml, tp);
759 fn = fml_sub0 (fml, fn);
760 fml_cmd_lex (lp, tp);
763 body = fml_lex_list (fml, tp);
764 rv = fml_exec_group (body, fml);
768 fml_cmd_lex (lp, tp);
771 info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
772 if (info->kind == FML_ELSE)
774 fml_cmd_lex (lp, tp);
775 body = fml_lex_list (fml, tp);
776 fml_cmd_lex (lp, tp);
779 rv = fml_exec_group (body, fml);
788 static struct fml_node *fml_exec_while (struct fml_sym_info *info, Fml fml,
789 struct fml_node **lp, struct token *tp)
791 struct fml_node *fn, *body;
792 struct fml_node *return_value = NULL;
794 fml_cmd_lex (lp, tp);
795 fn = fml_lex_list (fml, tp);
797 fml_cmd_lex (lp, tp);
798 body = fml_lex_list (fml, tp);
801 struct fml_node *fn_expr;
805 fn_expr = fml_sub0 (fml, fn);
808 rv = fml_exec_group (body, fml);
815 static void fml_exec_set (struct fml_sym_info *info, Fml fml,
816 struct fml_node **lp, struct token *tp)
819 struct fml_sym_info *info_var;
821 fml_cmd_lex (lp, tp);
822 info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
825 info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
826 info_var->body = NULL;
831 printf ("set %s ", tp->tokenbuf);
833 info_var->kind = FML_VAR;
834 fml_cmd_lex (lp, tp);
835 fn = fml_lex_list (fml, tp);
838 fn = fml_sub0 (fml, fn);
842 fml_pr_list (info_var->body);
847 static void fml_emit_expr (Fml fml, struct fml_node **lp, struct token *tp)
851 fn = fml_sub1 (fml, lp, tp);
854 if (fn && fn->is_atom)
857 fml_atom_strx (fn->p[0], arg, 127);
863 static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
866 struct fml_sym_info *info;
868 struct fml_node *return_value = NULL, *rv;
872 fml_init_token (&token, fml);
873 fml_cmd_lex (&list, &token);
879 rv = fml_exec_group (token.sub, fml);
884 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
892 fml_cmd_lex (&list, &token);
893 assert (token.kind == 't');
894 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
896 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
897 info->kind = FML_PREFIX;
901 fml_cmd_lex (&list, &token);
902 if (token.kind != 't')
906 info->args = fn = fml_node_alloc (fml);
910 for (fn = info->args; fn->p[1]; fn=fn->p[1])
912 fn = fn->p[1] = fml_node_alloc (fml);
914 fn->p[0] = token.atom;
917 assert (token.kind == 'g');
918 info->body = token.sub;
921 fml_cmd_lex (&list, &token);
922 assert (token.kind == 't');
923 info = fml_sym_lookup (fml->sym_tab, token.tokenbuf);
925 info = fml_sym_add (fml->sym_tab, token.tokenbuf);
926 info->kind = FML_BINARY;
928 fml_cmd_lex (&list, &token);
929 assert (token.kind == 't');
930 info->args = fn = fml_node_alloc (fml);
931 fn->p[0] = token.atom;
934 fml_cmd_lex (&list, &token);
935 assert (token.kind == 't');
936 fn = fn->p[1] = fml_node_alloc (fml);
937 fn->p[0] = token.atom;
940 fml_cmd_lex (&list, &token);
941 assert (token.kind == 'g');
942 info->body = token.sub;
946 after_char = token.after_char;
947 fml_exec_prefix (info, fml, &list, &token);
949 putchar (after_char);
952 fml_emit (info->body);
953 if (token.after_char)
954 putchar (token.after_char);
962 if (token.offset == 0)
966 fml_emit_expr (fml, &list, &token);
969 rv = fml_exec_foreach (info, fml, &list, &token);
974 rv = fml_exec_if (info, fml, &list, &token);
979 fml_exec_set (info, fml, &list, &token);
982 rv = fml_exec_while (info, fml, &list, &token);
987 fml_cmd_lex (&list, &token);
988 return_value = fml_lex_list (fml, &token);
990 return_value = fml_sub0 (fml, return_value);
994 printf ("return of:");
995 fml_pr_list (return_value);
1000 printf ("unknown token: `%s'", token.tokenbuf);
1001 fml_cmd_lex (&list, &token);
1006 printf ("<unknown>");
1012 if (token.offset == 0)
1016 fml_emit_expr (fml, &list, &token);
1019 printf ("%s", token.tokenbuf);
1020 if (token.after_char)
1021 putchar (token.after_char);
1024 fml_cmd_lex (&list, &token);
1026 fml_del_token (&token, fml);
1027 return return_value;
1030 void fml_exec (Fml fml)
1032 fml_exec_group (fml->list, fml);