commit e267264d253dd0cecd0a3bd87b881b10df2a14cd
parent 03817ea82122c65ed529a36d448bebd3812e20be
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Wed, 27 Sep 2017 06:11:14 +0200
Merge remote-tracking branch 'origin/master'
Diffstat:
11 files changed, 123 insertions(+), 72 deletions(-)
diff --git a/as/as.h b/as/as.h
@@ -107,7 +107,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);
/* proc.c */
diff --git a/as/expr.c b/as/expr.c
@@ -11,6 +11,7 @@ static char sccsid[] = "@(#) ./as/node.c";
#define NNODES 10
enum tokens {
+ EOS = -1,
IDEN = 1,
NUMBER,
REG,
@@ -124,8 +125,10 @@ binary(int op, Node *l, Node *r)
default:
abort();
}
+ deltree(l);
+ deltree(r);
- np = node(NUMBER, l, r);
+ np = node(NUMBER, NULL, NULL);
np->sym = tmpsym(val);
return np;
@@ -175,8 +178,8 @@ iden(void)
int c;
char *p;
- for (endp = textp; isalnum(c = *endp) || c == '_' || c == '.'; ++endp)
- /* nothing */;
+ while (isalnum(c = *endp) || c == '_' || c == '.')
+ ++endp;
tok2str();
yylval.sym = lookup(yytext);
@@ -189,8 +192,8 @@ number(void)
int c;
char *p;
- for (endp = textp; isxdigit(*endp); ++endp)
- /* nothing */;
+ while (isxdigit(*endp))
+ ++endp;
tok2str();
yylval.sym = tmpsym(atoi(yytext)); /* TODO: parse the string */
@@ -203,8 +206,8 @@ character(void)
int c;
char *p;
- for (endp = textp+1; *endp != '\''; ++endp)
- /* nothing */;
+ while (*endp != '\'')
+ ++endp;
return NUMBER;
}
@@ -214,34 +217,52 @@ 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;
- if (isalpha(c) || c == '_' || c == '.')
+
+ endp = textp;
+ if ((c = *textp) == '\0') {
+ strcpy(yytext, "EOS");
+ yylen = 3;
+ c = EOS;
+ } else if (isalpha(c) || c == '_' || c == '.') {
c = iden();
- else if (isdigit(c))
+ } 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 == '\"')
+ } else if (c == '\"') {
c = string();
- tok2str();
+ } else if (c == '\'') {
+ c = character();
+ } else {
+ c = operator();
+ }
- return c;
+ return yytoken = c;
}
static void
@@ -277,6 +298,12 @@ primary(void)
np->sym = yylval.sym;
next();
break;
+ case '[':
+ next();
+ np = or();
+ expect(']');
+ np = node('@', np, NULL);
+ break;
case '(':
next();
np = or();
@@ -399,15 +426,20 @@ or(void)
}
Node *
-expr(char *s)
+expr(char **s)
{
Node *np;
- textp = s;
+ textp = *s;
+ if (*textp == '\0')
+ return NULL;
+
next();
np = or();
- if (*textp != '\0')
+ if (yytoken != ',' && yytoken != EOS)
error("trailing characters in expression '%s'", textp);
+ *s = endp;
+
return np;
}
diff --git a/as/main.c b/as/main.c
@@ -1,5 +1,6 @@
static char sccsid[] = "@(#) ./as/main.c";
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -11,8 +12,14 @@ static int
cmp(const void *f1, const void *f2)
{
const Ins *ins = f2;
+ const char *s = f1;
+ int d;
- return strcmp(f1, ins->str);
+ d = toupper(*ins->str) - toupper(*s);
+ if (d != 0)
+ return d;
+
+ return casecmp(s, ins->str);
}
static void
diff --git a/as/parser.c b/as/parser.c
@@ -35,32 +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 */;
- *s++ = '\0';
- len = t - s;
- 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 *
@@ -92,9 +77,6 @@ field(char **oldp)
if (c == '\0')
error("unterminated string");
break;
- default:
- *s = toupper(*s);
- break;
}
}
@@ -106,9 +88,14 @@ static int
extract(char *s, struct line *lp)
{
int r = 0;
+ size_t len;
- if (lp->label = field(&s))
+ if (lp->label = field(&s)) {
+ len = strlen(lp->label);
+ if (lp->label[len-1] == ':')
+ lp->label[len-1] = '\0';
r++;
+ }
if (lp->op = field(&s))
r++;
if (lp->args = field(&s))
diff --git a/as/symbol.c b/as/symbol.c
@@ -1,5 +1,6 @@
static char sccsid[] = "@(#) ./as/symbol.c";
+#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -55,11 +56,11 @@ lookup(char *name)
h = h*33 ^ c;
h &= HASHSIZ-1;
- c = *name;
+ c = toupper(*name);
list = &hashtbl[h];
for (sym = *list; sym; sym = sym->next) {
t = sym->name;
- if (c == *t && !strcmp(t, name))
+ if (c == toupper(*t) && !casecmp(t, name))
return sym;
}
diff --git a/as/target/x86/gen.awk b/as/target/x86/gen.awk
@@ -40,24 +40,29 @@ END {
print "struct op optab[] = {"
for (i = 0; i < nvar; i++) {
printf "\t{\n" \
- "\t\t.bytes = (char []) {%s},\n"\
"\t\t.size = %d,\n"\
- "\t\t.format = %s,\n"\
- "\t\t.args = (char []) {%s}\n"\
- "\t},\n",
- opbytes[i], opsize[i], opformat[i], str2args(opargs[i])
+ "\t\t.format = %s,\n",
+ opsize[i], opformat[i]
+
+ if (opbytes[i] != "")
+ printf "\t\t.bytes = (char []) {%s},\n", opbytes[i]
+
+ a = str2args(opargs[i])
+ if (a != "")
+ printf "\t\t.args = (char []) {%s}\n", a
+
+ print "\t},"
}
print "};"
}
function str2args(s, args, i, out)
{
- split(s, args, /,/)
+ if (split(s, args, /,/) == 0 || args[1] == "none")
+ return ""
for (i in args) {
a = args[i]
- if (a == "none") {
- break
- } else if (match(a, /^imm8/)) {
+ if (match(a, /^imm8/)) {
out = "AIMM8"
} else if (match(a, /^imm16/)) {
out = "AIMM16"
diff --git a/inc/scc.h b/inc/scc.h
@@ -44,3 +44,4 @@ extern Alloc *alloc(size_t size, size_t nmemb);
extern void dealloc(Alloc *allocp);
extern void *new(Alloc *allocp);
extern void delete(Alloc *allocp, void *p);
+extern int casecmp(const char *s1, const char *s2);
diff --git a/lib/c/include/ctype.h b/lib/c/include/ctype.h
@@ -28,18 +28,22 @@ extern int toupper(int c);
#define _SP 0x80 /* hard space (0x20) */
extern unsigned char __ctype[];
-
-#define isalnum(c) ((__ctype+1)[(c)] & (_U|_L|_D))
-#define isalpha(c) ((__ctype+1)[(c)] & (_U|_L))
-#define iscntrl(c) ((__ctype+1)[(c)] & (_C))
-#define isdigit(c) ((__ctype+1)[(c)] & (_D))
-#define isgraph(c) ((__ctype+1)[(c)] & (_P|_U|_L|_D))
-#define islower(c) ((__ctype+1)[(c)] & (_L))
-#define isprint(c) ((__ctype+1)[(c)] & (_P|_U|_L|_D|_SP))
-#define ispunct(c) ((__ctype+1)[(c)] & (_P))
-#define isspace(c) ((__ctype+1)[(c)] & (_S))
-#define isupper(c) ((__ctype+1)[(c)] & (_U))
-#define isxdigit(c) ((__ctype+1)[(c)] & (_D|_X))
+extern int __ctmp;
+
+#define isalnum(c) ((__ctype+1)[c] & (_U|_L|_D))
+#define isalpha(c) ((__ctype+1)[c] & (_U|_L))
+#define iscntrl(c) ((__ctype+1)[c] & (_C))
+#define isdigit(c) ((__ctype+1)[c] & (_D))
+#define isgraph(c) ((__ctype+1)[c] & (_P|_U|_L|_D))
+#define islower(c) ((__ctype+1)[c] & (_L))
+#define isprint(c) ((__ctype+1)[c] & (_P|_U|_L|_D|_SP))
+#define ispunct(c) ((__ctype+1)[c] & (_P))
+#define isspace(c) ((__ctype+1)[c] & (_S))
+#define isupper(c) ((__ctype+1)[c] & (_U))
+#define isxdigit(c) ((__ctype+1)[c] & (_D|_X))
+
+#define tolower(c) ((__ctmp=c, isupper(__ctmp) ? __ctmp | 0x20 : __ctmp))
+#define toupper(c) ((__ctmp=c, islower(__ctmp) ? __ctmp & ~0x20 : __ctmp))
#define isascii(c) ((unsigned)(c)<=0x7f)
diff --git a/lib/c/src/ctype.c b/lib/c/src/ctype.c
@@ -2,6 +2,8 @@
#include <ctype.h>
#undef ctype
+int __ctmp;
+
/* __ctype is shifted by one to match EOF */
unsigned char __ctype[257] = {
0, /* EOF */
diff --git a/lib/scc/casecmp.c b/lib/scc/casecmp.c
@@ -0,0 +1,11 @@
+static char sccsid[] = "@(#) ./lib/scc/casecmp.c";
+#include <ctype.h>
+#include "../../inc/scc.h"
+
+int
+casecmp(const char *s1, const char *s2)
+{
+ while (*s1 && toupper(*s1) == toupper(*s2))
+ ++s1, ++s2;
+ return *s1 - *s2;
+}
diff --git a/lib/scc/libdep.mk b/lib/scc/libdep.mk
@@ -6,3 +6,4 @@ LIB-OBJ = $(LIBDIR)/debug.o \
$(LIBDIR)/xrealloc.o \
$(LIBDIR)/xstrdup.o \
$(LIBDIR)/alloc.o \
+ $(LIBDIR)/casecmp.o \