commit 69a0a3e07aee3304446942c49527d65ebc5f7c85
parent b390c994ee75e9c45616cfc91bf89d869d228310
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 22 Sep 2017 14:24:03 +0100
[as] Rewrite getargs()
Getargs() has not to do parsing anymore since this task is
done in expr() now.
Diffstat:
M | as/as.h | | | 2 | +- |
M | as/expr.c | | | 63 | ++++++++++++++++++++++++++++++++++++++++++++------------------- |
M | as/parser.c | | | 24 | ++++-------------------- |
3 files changed, 49 insertions(+), 40 deletions(-)
diff --git a/as/as.h b/as/as.h
@@ -112,7 +112,7 @@ extern int nextline(FILE *fp, struct line *linep);
#endif
/* expr.c */
-extern Node *expr(char *s);
+extern Node *expr(char **s);
extern void deltree(Node *np);
/*
diff --git a/as/expr.c b/as/expr.c
@@ -175,8 +175,8 @@ iden(void)
int c;
char *p;
- for (endp = textp+1; isalnum(c = *endp) || c == '_' || c == '.'; ++endp)
- /* nothing */;
+ while (isalnum(c = *endp) || c == '_' || c == '.')
+ ++endp;
tok2str();
yylval.sym = lookup(yytext);
@@ -189,8 +189,8 @@ number(void)
int c;
char *p;
- for (endp = textp+1; isxdigit(*endp); ++endp)
- /* nothing */;
+ while (isxdigit(*endp))
+ ++endp;
tok2str();
yylval.sym = tmpsym(atoi(yytext)); /* TODO: parse the string */
@@ -203,8 +203,8 @@ character(void)
int c;
char *p;
- for (endp = textp+1; *endp != '\''; ++endp)
- /* nothing */;
+ while (*endp != '\'')
+ ++endp;
return NUMBER;
}
@@ -214,31 +214,51 @@ string(void)
int c;
char *p;
- for (endp = textp+1; *endp != '"'; ++endp)
- /* nothing */;
+ while (*endp != '"')
+ ++endp;
return STRING;
}
static int
+operator(void)
+{
+ int c;
+
+ ++endp;
+ if ((c = *textp) == '>')
+ c = follow('=', '>', LE, SHL, '>');
+ else if (c == '<')
+ c = follow('=', '<', GE, SHR, '>');
+ tok2str();
+
+ return c;
+}
+
+static int
next(void)
{
int c;
while (isspace(*textp))
++textp;
- c = *textp;
+
+ endp = textp;
+ if ((c = *textp) == '\0') {
+ strcpy(yytext, "EOF");
+ yylen = 3;
+ return EOF;
+ }
+
if (isalpha(c) || c == '_' || c == '.')
c = iden();
else if (isdigit(c))
c = number();
- else if (c == '>')
- c = follow('=', '>', LE, SHL, '>');
- else if (c == '<')
- c = follow('=', '<', GE, SHR, '>');
- else if (c == '\'')
- c = character();
else if (c == '\"')
c = string();
+ else if (c == '\'')
+ c = character();
+ else
+ c = operator();
return yytoken = c;
}
@@ -398,15 +418,20 @@ or(void)
}
Node *
-expr(char *s)
+expr(char **s)
{
Node *np;
- textp = s;
+ if (*s == '\0')
+ return NULL;
+
+ textp = *s;
next();
np = or();
- if (*textp != '\0')
- error("trailing characters in expression '%s'", textp);
+ if (yytoken != ',' && yytoken != EOF)
+ error("trailing characters in expression '%s:%s'", *s, textp);
+ *s = endp;
+
return np;
}
diff --git a/as/parser.c b/as/parser.c
@@ -35,33 +35,17 @@ error(char *msg, ...)
Node **
getargs(char *s)
{
- char *t;
- int ch, len;
Node **ap;
static Node *args[NARGS];
if (!s)
return NULL;
- for (ap = args; ; *ap++ = expr(t)) {
- while (isspace(*s))
- ++s;
- if (*s == '\0')
- break;
- if (ap == &args[NARGS-1])
- error("too many arguments in one instruction");
-
- for (t = s; *s && *s != ','; s++)
- /* nothing */;
- len = t - s;
- if (*s != '\0')
- *s++ = '\0';
- if (len == 0)
- error("wrong operand '%s'", t);
+ for (ap = args; ap < &args[NARGS-1]; ++ap) {
+ if ((*ap = expr(&s)) == NULL)
+ return args;
}
- *ap = NULL;
-
- return args;
+ error("too many arguments in one instruction");
}
static char *