* FML interpreter. Europagate, 1995
*
* $Log: fml.c,v $
- * Revision 1.2 1995/02/06 15:23:25 adam
+ * Revision 1.6 1995/02/09 16:06:06 adam
+ * FML can be called from the outside multiple times by the functions:
+ * fml_exec_call and fml_exec_call_str.
+ * An interactive parameter (-i) to fmltest starts a shell-like
+ * interface to FML by using the fml_exec_call_str function.
+ *
+ * Revision 1.5 1995/02/09 14:33:36 adam
+ * Split source fml.c and define relevant build-in functions in separate
+ * files. New operators mult, div, not, llen implemented.
+ *
+ * Revision 1.4 1995/02/09 13:07:14 adam
+ * Nodes are freed now. Many bugs fixed.
+ *
+ * Revision 1.3 1995/02/07 16:09:23 adam
+ * The \ character is no longer INCLUDED when terminating a token.
+ * Major changes in tokenization routines. Bug fixes in expressions
+ * with lists (fml_sub0).
+ *
+ * Revision 1.2 1995/02/06 15:23:25 adam
* Added some more relational operators (le,ne,ge). Added increment
* and decrement operators. Function index changed, so that first
* element is 1 - not 0. Function fml_atom_val edited.
fprintf (stderr, "Error: %d\n", no);
}
+static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
+static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
+ struct token *tp);
+static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
+ struct token *tp);
static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
struct token *tp);
static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
struct token *tp);
-static struct fml_node *fml_exec_incr (Fml fml, struct fml_node **lp,
- struct token *tp);
-static struct fml_node *fml_exec_decr (Fml fml, struct fml_node **lp,
- struct token *tp);
-#if 0
-static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list);
-#endif
-static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list);
-
-static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_ge (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_le (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_ne (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
- struct fml_node *r);
-static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
- struct fml_node *r);
static int indent = 0;
{
int i = indent;
while (--i >= 0)
- putchar (' ');
+ putchar(' ');
}
if (n > 0)
{
sym_info = fml_sym_add (fml->sym_tab, "return");
sym_info->kind = FML_RETURN;
-
- sym_info = fml_sym_add (fml->sym_tab, "and");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_and;
- sym_info = fml_sym_add (fml->sym_tab, "or");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_or;
- sym_info = fml_sym_add (fml->sym_tab, "index");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_indx;
-
- sym_info = fml_sym_add (fml->sym_tab, "plus");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_plus;
- sym_info = fml_sym_add (fml->sym_tab, "minus");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_minus;
-
- sym_info = fml_sym_add (fml->sym_tab, "gt");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_gt;
- sym_info = fml_sym_add (fml->sym_tab, "lt");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_lt;
- sym_info = fml_sym_add (fml->sym_tab, "eq");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_eq;
-
- sym_info = fml_sym_add (fml->sym_tab, "ge");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_ge;
- sym_info = fml_sym_add (fml->sym_tab, "le");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_le;
- sym_info = fml_sym_add (fml->sym_tab, "ne");
- sym_info->kind = FML_CBINARY;
- sym_info->binary = fml_exec_ne;
-
- sym_info = fml_sym_add (fml->sym_tab, "incr");
- sym_info->kind = FML_CPREFIX;
- sym_info->prefix = fml_exec_incr;
- sym_info = fml_sym_add (fml->sym_tab, "decr");
- sym_info->kind = FML_CPREFIX;
- sym_info->prefix = fml_exec_decr;
+ fml_list_init (fml);
+ fml_arit_init (fml);
+ fml_rel_init (fml);
sym_info = fml_sym_add (fml->sym_tab, "s");
sym_info->kind = FML_CPREFIX;
switch (info->kind)
{
case FML_VAR:
-/* fml_node_delete (fml_pop_handler, info->body); */
+ fml_node_delete (fml_pop_handler, info->body);
break;
}
}
}
-static void fml_init_token (struct token *tp, Fml fml)
+void fml_init_token (struct token *tp, Fml fml)
{
tp->maxbuf = FML_ATOM_BUF*2;
tp->offset = 0;
tp->escape_char = fml->escape_char;
}
-static void fml_del_token (struct token *tp, Fml fml)
+void fml_del_token (struct token *tp, Fml fml)
{
if (tp->maxbuf != FML_ATOM_BUF*2)
free (tp->atombuf);
}
-static void fml_cmd_lex (struct fml_node **np, struct token *tp)
+void fml_cmd_lex (struct fml_node **np, struct token *tp)
{
char *cp;
char *dst;
}
if (tp->offset == 0)
{
+ tp->separate = 1;
if ((*np)->is_atom)
{
tp->atom = (*np)->p[0];
return ;
}
}
+ else
+ tp->separate = 0;
cp = tp->atombuf + tp->offset;
dst = tp->tokenbuf;
if (*cp == tp->escape_char)
{
tp->kind = 'e';
- tp->after_char = '\0';
cp++;
if (*cp == '\0')
{
else
{
tp->kind = 't';
- tp->after_char = ' ';
}
while (*cp)
{
if (*cp == tp->escape_char)
{
*dst = '\0';
-#if 0
- if (cp[1] == '\0')
- {
- tp->after_char = ' ';
- break;
- }
-#endif
- if (tp->kind == 'e')
- {
- cp++;
- if (! *cp)
- break;
- }
tp->offset = cp - tp->atombuf;
- tp->after_char = '\0';
return ;
}
*dst++ = *cp++;
*np = (*np)->p[1];
}
-static struct fml_node *fml_lex_list (Fml fml, struct token *tp)
+struct fml_node *fml_expr_term (Fml fml, struct fml_node **lp,
+ struct token *tp)
{
struct fml_node *fn;
-
if (tp->kind == 'g')
- return tp->sub;
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = tp->atom;
+ {
+ fn = fml_sub0 (fml, tp->sub);
+ fml_cmd_lex (lp, tp);
+ }
+ else
+ fn = fml_sub2 (fml, lp, tp);
return fn;
}
-static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml);
-
-static void fml_lr_values (struct fml_node *l, int *left_val,
+void fml_lr_values (Fml fml, struct fml_node *l, int *left_val,
struct fml_node *r, int *right_val)
{
- if (l->is_atom)
+ if (l && l->is_atom)
*left_val = fml_atom_val (l->p[0]);
else
*left_val = 0;
- if (r->is_atom)
+ if (r && r->is_atom)
*right_val = fml_atom_val (r->p[0]);
else
*right_val = 0;
+ fml_node_delete (fml, l);
+ fml_node_delete (fml, r);
}
-static struct fml_node *fml_exec_and (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- if (l && r)
- return r;
- else
- return NULL;
-}
-
-static struct fml_node *fml_exec_or (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- if (l)
- return l;
- return r;
-}
-
-static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- struct fml_node *list = l;
- int indx;
-
- if (!l || !r || !r->is_atom)
- return NULL;
- indx = fml_atom_val (r->p[0]);
- while (--indx >= 1 && list)
- list = list->p[1];
- if (!list)
- return NULL;
- if (list->is_atom)
- {
- struct fml_node *fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = list->p[0];
- return fn;
- }
- else
- return list->p[0];
-}
-
-static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- char arg[20];
- struct fml_node *fn;
-
- fml_lr_values (l, &left_val, r, &right_val);
- sprintf (arg, "%d", left_val + right_val);
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, arg);
- return fn;
-}
-
-static struct fml_node *fml_exec_minus (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- char arg[20];
- struct fml_node *fn;
-
- fml_lr_values (l, &left_val, r, &right_val);
- sprintf (arg, "%d", left_val - right_val);
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, arg);
- return fn;
-}
-
-
-static struct fml_node *fml_exec_gt (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val > right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-
-static struct fml_node *fml_exec_lt (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val < right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-static struct fml_node *fml_exec_eq (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val == right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-static struct fml_node *fml_exec_ne (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val != right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-static struct fml_node *fml_exec_le (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val <= right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-static struct fml_node *fml_exec_ge (Fml fml, struct fml_node *l,
- struct fml_node *r)
-{
- int left_val, right_val;
- struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
- if (left_val >= right_val)
- {
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, "1");
- }
- else
- fn = NULL;
- return fn;
-}
-
-
static struct fml_node *fml_exec_space (Fml fml, struct fml_node **lp,
struct token *tp)
{
+ fml_cmd_lex (lp, tp);
+ putchar ('_');
return NULL;
}
static struct fml_node *fml_exec_nl (Fml fml, struct fml_node **lp,
struct token *tp)
{
- putchar ('\n');
- return NULL;
-}
-
-static struct fml_node *fml_exec_incr (Fml fml, struct fml_node **lp,
- struct token *tp)
-{
- struct fml_node *fn = NULL;
- struct fml_sym_info *info;
- fml_cmd_lex (lp, tp);
- if (tp->kind == 'e')
- {
- info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
- assert (info);
- if (info->kind == FML_VAR && info->body && info->body->is_atom)
- {
- char arg[128];
- int val;
-
- val = fml_atom_val (info->body->p[0]);
- fml_node_delete (fml, info->body);
- sprintf (arg, "%d", val+1);
- info->body = fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, arg);
- }
- }
- return NULL;
-}
-
-static struct fml_node *fml_exec_decr (Fml fml, struct fml_node **lp,
- struct token *tp)
-{
- struct fml_node *fn = NULL;
- struct fml_sym_info *info;
fml_cmd_lex (lp, tp);
- if (tp->kind == 'e')
- {
- info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
- assert (info);
- if (info->kind == FML_VAR && info->body && info->body->is_atom)
- {
- char arg[128];
- int val;
-
- val = fml_atom_val (info->body->p[0]);
- sprintf (arg, "%d", val-1);
- info->body = fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = fml_atom_alloc (fml, arg);
- }
- }
+ putchar ('\n');
return NULL;
}
struct fml_node *return_value;
static char arg[128];
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("exec_prefix ");
}
fml_sym_push (fml->sym_tab);
+ fml_cmd_lex (lp, tp);
for (fn = info->args; fn; fn = fn->p[1])
{
- fml_cmd_lex (lp, tp);
assert (fn->is_atom);
fml_atom_strx (fn->p[0], arg, 127);
- if (fml->debug)
+ if (fml->debug & 1)
{
-
pr_indent (1);
printf ("%s=", arg);
}
arg_info = fml_sym_add_local (fml->sym_tab, arg);
arg_info->kind = FML_VAR;
- arg_info->body = fml_lex_list (fml, tp);
- if (arg_info->body)
- arg_info->body = fml_sub0 (fml, arg_info->body);
- if (fml->debug)
+
+ if (tp->kind == 'g')
+ {
+ arg_info->body = fml_sub0 (fml, tp->sub);
+ fml_cmd_lex (lp, tp);
+ }
+ else
+ arg_info->body = fml_sub2 (fml, lp, tp);
+ if (fml->debug & 1)
{
fml_pr_list (arg_info->body);
pr_indent (-1);
}
}
return_value = fml_exec_group (info->body, fml);
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent(0);
pr_indent (-1);
}
}
-static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
- struct token *tp);
-
static struct fml_node *fml_sub2 (Fml fml, struct fml_node **lp,
struct token *tp)
switch (info->kind)
{
case FML_VAR:
- fn = info->body;
+ fn = fml_node_copy (fml, info->body);
fml_cmd_lex (lp, tp);
break;
case FML_PREFIX:
fn = fml_exec_prefix (info, fml, lp, tp);
- fml_cmd_lex (lp, tp);
break;
case FML_CPREFIX:
fn = (*info->prefix) (fml, lp, tp);
static struct fml_node *fml_sub1 (Fml fml, struct fml_node **lp,
struct token *tp)
{
- struct fml_node *f1, *f2;
+ struct fml_node *f1, *f2, *fn;
struct fml_sym_info *info;
f1 = fml_sub2 (fml, lp, tp);
{
fml_cmd_lex (lp, tp);
f2 = fml_sub2 (fml, lp, tp);
- f1 = (*info->binary) (fml, f1, f2);
+ fn = (*info->binary) (fml, f1, f2);
+ f1 = fn;
continue;
}
else if (info->kind == FML_BINARY)
struct fml_sym_info *arg_info;
char arg[127];
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("exec binary %s", tp->tokenbuf);
arg_info = fml_sym_add_local (fml->sym_tab, arg);
arg_info->kind = FML_VAR;
arg_info->body = f1;
- if (fml->debug)
+ if (fml->debug & 1)
{
printf (" left=");
fml_pr_list (f1);
arg_info = fml_sym_add_local (fml->sym_tab, arg);
arg_info->kind = FML_VAR;
arg_info->body = f2;
- if (fml->debug)
+ if (fml->debug & 1)
{
printf (" right=");
fml_pr_list (f2);
}
f1 = fml_exec_group (info->body, fml);
fml_do_pop (fml);
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent (0);
pr_indent (-1);
}
#if 0
-static struct fml_node *fml_sub_bad (Fml fml, struct fml_node *list)
+static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
{
struct token token;
struct fml_node *fn, *fn1;
fml_del_token (&token, fml);
return fn;
}
-#endif
-
+#else
static struct fml_node *fml_sub0 (Fml fml, struct fml_node *list)
{
struct token token;
- struct fml_node *fn, *fn1;
+ struct fml_node *fn, *fn0, *fn1;
+ if (!list)
+ return NULL;
fml_init_token (&token, fml);
assert (list);
fml_cmd_lex (&list, &token);
fn1 = fn = fml_sub1 (fml, &list, &token);
-
+ if (fn->p[1] && token.kind != '\0')
+ {
+ fn1 = fml_node_alloc (fml);
+ fn1->p[0] = fn;
+ }
+ fn0 = fn1;
while (token.kind != '\0')
- fn1 = fn1->p[1] = fml_sub1 (fml, &list, &token);
+ {
+ fn = fml_sub1 (fml, &list, &token);
+ if (fn->p[1])
+ {
+ fn1 = fn1->p[1] = fml_node_alloc (fml);
+ fn1->p[0] = fn;
+ }
+ else
+ {
+ fn1 = fn1->p[1] = fn;
+ }
+ }
fml_del_token (&token, fml);
- return fn;
+ return fn0;
}
+#endif
static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
struct fml_node **lp,
info_var->body = NULL;
info_var->kind = FML_VAR;
}
- if (fml->debug)
+ else
+ {
+ fml_node_delete (fml, info->body);
+ info->body = NULL;
+ }
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("[foreach %s ", tp->tokenbuf);
}
fml_cmd_lex (lp, tp);
-
- fn = fml_lex_list (fml, tp);
- if (fn)
- fn = fml_sub0 (fml, fn);
+ assert (tp->kind == 'g');
+ fn = fml_sub0 (fml, tp->sub);
fml_cmd_lex (lp, tp);
-
- body = fml_lex_list (fml, tp);
+ assert (tp->kind == 'g');
+ body = tp->sub;
while (fn)
{
+ struct fml_node *fn1;
+
+ fn1 = fn->p[1];
+ fn->p[1] = NULL;
if (fn->is_atom)
- {
- struct fml_node *fn1;
- fn1 = fml_node_alloc (fml);
- fn1->is_atom=1;
- fn1->p[0] = fn->p[0];
- info_var->body = fn1;
- }
+ info_var->body = fn;
else
info_var->body = fn->p[0];
-
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("[foreach loop var=");
rv = fml_exec_group (body, fml);
if (rv)
return_value = rv;
- fn = fn->p[1];
+ fml_node_delete (fml, fn);
+ fn = fn1;
}
- if (fml->debug)
+ info_var->body = NULL;
+ if (fml->debug & 1)
pr_indent (-1);
return return_value;
}
struct fml_node *rv, *return_value = NULL;
fml_cmd_lex (lp, tp);
- fn = fml_lex_list (fml, tp);
- if (fn)
- fn = fml_sub0 (fml, fn);
+ assert (tp->kind == 'g');
+ fn = fml_sub0 (fml, tp->sub);
fml_cmd_lex (lp, tp);
+ assert (tp->kind == 'g');
if (fn)
{
- body = fml_lex_list (fml, tp);
- rv = fml_exec_group (body, fml);
+ rv = fml_exec_group (tp->sub, fml);
if (rv)
return_value = rv;
}
if (info->kind == FML_ELSE)
{
fml_cmd_lex (lp, tp);
- body = fml_lex_list (fml, tp);
- fml_cmd_lex (lp, tp);
+ assert (tp->kind == 'g');
+ body = tp->sub;
if (!fn)
{
rv = fml_exec_group (body, fml);
if (rv)
return_value = rv;
}
+ fml_cmd_lex (lp, tp);
}
}
+ fml_node_delete (fml, fn);
return return_value;
}
struct fml_node *return_value = NULL;
fml_cmd_lex (lp, tp);
- fn = fml_lex_list (fml, tp);
+ assert (tp->kind == 'g');
+ fn = tp->sub;
fml_cmd_lex (lp, tp);
- body = fml_lex_list (fml, tp);
+ assert (tp->kind == 'g');
+ body = tp->sub;
+ assert (tp->sub);
while (1)
{
struct fml_node *fn_expr;
fn_expr = fml_sub0 (fml, fn);
if (!fn_expr)
break;
+ fml_node_delete (fml, fn_expr);
rv = fml_exec_group (body, fml);
if (rv)
return_value = rv;
{
struct fml_node *fn;
struct fml_sym_info *info_var;
-
+
fml_cmd_lex (lp, tp);
info_var = fml_sym_lookup_local (fml->sym_tab, tp->tokenbuf);
if (!info_var)
info_var = fml_sym_add_local (fml->sym_tab, tp->tokenbuf);
info_var->body = NULL;
}
- if (fml->debug)
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("set %s ", tp->tokenbuf);
}
info_var->kind = FML_VAR;
fml_cmd_lex (lp, tp);
- fn = fml_lex_list (fml, tp);
- assert (fn);
- if (fn)
- fn = fml_sub0 (fml, fn);
+
+ if (tp->kind == 'g')
+ {
+ fn = fml_sub0 (fml, tp->sub);
+ fml_cmd_lex (lp, tp);
+ }
+ else
+ fn = fml_sub2 (fml, lp, tp);
+ fml_node_delete (fml, info_var->body);
info_var->body = fn;
- if (fml->debug)
+ if (fml->debug & 1)
{
fml_pr_list (info_var->body);
pr_indent (-1);
fn = fml_sub1 (fml, lp, tp);
fml_emit (fn);
+ fml_node_delete (fml, fn);
}
-static struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
+struct fml_node *fml_exec_group (struct fml_node *list, Fml fml)
{
struct token token;
struct fml_sym_info *info;
- int separate = 0;
+ int first = 1;
struct fml_node *return_value = NULL, *rv;
if (!list)
assert (token.kind == 'g');
info->body = token.sub;
break;
-#if 0
- case FML_PREFIX:
- after_char = token.after_char;
- fml_exec_prefix (info, fml, &list, &token);
- if (after_char)
- putchar (after_char);
- break;
- case FML_VAR:
- fml_emit (info->body);
- if (token.after_char)
- putchar (token.after_char);
- break;
-#endif
case FML_VAR:
case FML_PREFIX:
case FML_CPREFIX:
- if (separate)
+ if (token.separate && !first)
putchar (' ');
- if (token.offset == 0)
- separate = ' ';
- else
- separate = 0;
+ first = 1;
fml_emit_expr (fml, &list, &token);
+ fml_node_stat (fml);
continue;
case FML_FOREACH:
rv = fml_exec_foreach (info, fml, &list, &token);
rv = fml_exec_if (info, fml, &list, &token);
if (rv)
return_value = rv;
- break;
+ continue;
case FML_SET:
fml_exec_set (info, fml, &list, &token);
- break;
+ fml_node_stat (fml);
+ continue;
case FML_WHILE:
rv = fml_exec_while (info, fml, &list, &token);
if (rv)
break;
case FML_RETURN:
fml_cmd_lex (&list, &token);
- return_value = fml_lex_list (fml, &token);
- if (return_value)
- return_value = fml_sub0 (fml, return_value);
- if (fml->debug)
+
+ if (token.kind == 'g')
+ {
+ return_value = fml_sub0 (fml, token.sub);
+ fml_cmd_lex (&list, &token);
+ }
+ else
+ return_value = fml_sub2 (fml, &list, &token);
+ if (fml->debug & 1)
{
pr_indent (1);
printf ("return of:");
fml_pr_list (return_value);
pr_indent (-1);
}
- break;
+ continue;
default:
printf ("unknown token: `%s'", token.tokenbuf);
fml_cmd_lex (&list, &token);
}
break;
case 't':
- if (separate)
+ if (token.separate && !first)
putchar (' ');
- if (token.offset == 0)
- separate = ' ';
- else
- separate = 0;
+ first = 0;
fml_emit_expr (fml, &list, &token);
+ fml_node_stat (fml);
continue;
-#if 0
- printf ("%s", token.tokenbuf);
- if (token.after_char)
- putchar (token.after_char);
-#endif
}
fml_cmd_lex (&list, &token);
}
void fml_exec (Fml fml)
{
+ fml_node_stat (fml);
fml_exec_group (fml->list, fml);
- if (fml->debug)
- printf ("\n");
+ if (fml->debug & 1)
+ putchar ('\n');
}
-
-