* FML interpreter. Europagate, 1995
*
* $Log: fml.c,v $
- * Revision 1.14 1995/02/23 08:32:04 adam
+ * Revision 1.15 1995/02/27 09:01:20 adam
+ * Regular expression support. Argument passing by name option. New FML
+ * function strlen.
+ *
+ * Revision 1.14 1995/02/23 08:32:04 adam
* Changed header.
*
* Revision 1.12 1995/02/22 15:20:13 adam
void fml_cmd_lex (struct fml_node **np, struct token *tp)
{
+ fml_cmd_lex_s (np, tp, 1);
+}
+
+void fml_cmd_lex_s (struct fml_node **np, struct token *tp, int esc_stop)
+{
char *cp;
char *dst;
if (!*np)
}
while (*cp)
{
- if (*cp == tp->escape_char)
+ if (*cp == tp->escape_char && esc_stop)
{
*dst = '\0';
tp->offset = cp - tp->atombuf;
(*fml->write_func) ('_');
else
(*fml->write_func) (' ');
- putchar (' ');
return NULL;
}
struct fml_node *fn;
struct fml_sym_info *arg_info;
struct fml_node *return_value;
- static char arg[128];
+ static char arg_name[128];
if (fml->debug & 1)
{
fml_cmd_lex (lp, tp);
for (fn = info->args; fn; fn = fn->p[1])
{
-
assert (fn->is_atom);
- fml_atom_strx (fn->p[0], arg, 127);
+ fml_atom_strx (fn->p[0], arg_name, 127);
if (fml->debug & 1)
{
pr_indent (1);
- printf ("%s=", arg);
+ printf ("%s=", arg_name);
}
- arg_info = fml_sym_add_local (fml->sym_tab, arg);
- arg_info->kind = FML_VAR;
-
- if (tp->kind == 'g')
+ if (*arg_name == fml->escape_char)
{
- arg_info->body = fml_sub0 (fml, tp->sub);
+ arg_info = fml_sym_add_local (fml->sym_tab, 1+arg_name);
+ arg_info->kind = FML_CODE;
+
+ if (tp->kind == 'g')
+ arg_info->body = tp->sub;
+ else
+ arg_info->body = NULL;
+ if (fml->debug & 1)
+ {
+ fml_pr_list (arg_info->body);
+ pr_indent (-1);
+ }
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);
+ arg_info = fml_sym_add_local (fml->sym_tab, arg_name);
+ arg_info->kind = FML_VAR;
+
+ 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 (tp->kind == 'e')
{
info = fml_sym_lookup (fml->sym_tab, tp->tokenbuf);
- assert (info);
+ if (!info)
+ {
+ printf ("<<unknown %s in expression>>", tp->tokenbuf);
+ getchar ();
+ return NULL;
+ }
switch (info->kind)
{
case FML_VAR:
fn = fml_node_copy (fml, info->body);
fml_cmd_lex (lp, tp);
break;
+ case FML_CODE:
+ fn = fml_node_copy (fml, info->body);
+ fml_cmd_lex (lp, tp);
+ break;
case FML_PREFIX:
fn = fml_exec_prefix (info, fml, lp, tp);
break;
while (1)
{
fml_cmd_lex (&list, &token);
- if (token.kind != 't')
+ if (token.kind != 't' && token.kind != 'e')
break;
if (!info->args)
{
pr_indent (-1);
}
continue;
+ case FML_CODE:
+ fml_exec_group (info->body, fml);
+ break;
default:
- printf ("unknown token: `%s'", token.tokenbuf);
+ printf ("<unknown token: `%s'>", token.tokenbuf);
fml_cmd_lex (&list, &token);
}
}
else
{
- printf ("<unknown>");
+ printf ("<unknown %s>", token.tokenbuf);
}
break;
case 't':