* FML interpreter. Europagate, 1995
*
* $Log: fml.c,v $
- * Revision 1.3 1995/02/07 16:09:23 adam
+ * 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).
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_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);
switch (info->kind)
{
case FML_VAR:
-/* fml_node_delete (fml_pop_handler, info->body); */
+ fml_node_delete (fml_pop_handler, info->body);
break;
}
}
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 0
- if (tp->kind == 'e')
- {
- cp++;
- if (! *cp)
- break;
- }
-#endif
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 *fn;
-
- if (tp->kind == 'g')
- return tp->sub;
- fn = fml_node_alloc (fml);
- fn->is_atom = 1;
- fn->p[0] = tp->atom;
- 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,
+static 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)
+ {
+ fml_node_delete (fml, l);
return r;
- else
- return NULL;
+ }
+ fml_node_delete (fml, l);
+ fml_node_delete (fml, r);
+ 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;
+ if (r)
+ {
+ fml_node_delete (fml, l);
+ return r;
+ }
+ return l;
}
static struct fml_node *fml_exec_indx (Fml fml, struct fml_node *l,
struct fml_node *r)
{
struct fml_node *list = l;
+ struct fml_node *fn;
int indx;
if (!l || !r || !r->is_atom)
+ {
+ fml_node_delete (fml, l);
+ fml_node_delete (fml, r);
return NULL;
+ }
indx = fml_atom_val (r->p[0]);
+ fml_node_delete (fml, r);
while (--indx >= 1 && list)
list = list->p[1];
if (!list)
- return NULL;
- if (list->is_atom)
+ fn = NULL;
+ else if (list->is_atom)
{
- struct fml_node *fn = fml_node_alloc (fml);
+ fn = fml_node_alloc (fml);
fn->is_atom = 1;
fn->p[0] = list->p[0];
- return fn;
+ list->is_atom = 0;
+ list->p[0] = NULL;
}
else
- return list->p[0];
+ {
+ fn = list->p[0];
+ list->p[0] = NULL;
+ }
+ fml_node_delete (fml, l);
+ return fn;
}
static struct fml_node *fml_exec_plus (Fml fml, struct fml_node *l,
char arg[20];
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
sprintf (arg, "%d", left_val + right_val);
fn = fml_node_alloc (fml);
fn->is_atom = 1;
char arg[20];
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
sprintf (arg, "%d", left_val - right_val);
fn = fml_node_alloc (fml);
fn->is_atom = 1;
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val > right_val)
{
fn = fml_node_alloc (fml);
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val < right_val)
{
fn = fml_node_alloc (fml);
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val == right_val)
{
fn = fml_node_alloc (fml);
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val != right_val)
{
fn = fml_node_alloc (fml);
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val <= right_val)
{
fn = fml_node_alloc (fml);
{
int left_val, right_val;
struct fml_node *fn;
- fml_lr_values (l, &left_val, r, &right_val);
+ fml_lr_values (fml, l, &left_val, r, &right_val);
if (left_val >= right_val)
{
fn = fml_node_alloc (fml);
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);
struct token token;
struct fml_node *fn, *fn0, *fn1;
+ if (!list)
+ return NULL;
fml_init_token (&token, fml);
assert (list);
fml_cmd_lex (&list, &token);
}
#endif
-
static struct fml_node *fml_exec_foreach (struct fml_sym_info *info, Fml fml,
struct fml_node **lp,
struct token *tp)
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)
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 (token.separate && !first)
- {
putchar (' ');
- }
first = 1;
fml_emit_expr (fml, &list, &token);
+ fml_node_stat (fml);
continue;
case FML_FOREACH:
rv = fml_exec_foreach (info, fml, &list, &token);
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);
putchar (' ');
first = 0;
fml_emit_expr (fml, &list, &token);
+ fml_node_stat (fml);
continue;
}
fml_cmd_lex (&list, &token);
void fml_exec (Fml fml)
{
+ fml_node_stat (fml);
fml_exec_group (fml->list, fml);
- if (fml->debug)
+ if (fml->debug & 1)
printf ("\n");
}