shithub: scc

Download patch

ref: 1bc054f7b7f8cd2fa8eea85929bf6d06f8bf787f
parent: 4fc15c50d106acfee86968ebe9d97757a0012483
parent: db6a88b11ded5bd3de7c6898e6ad08c6be74a45d
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Sep 27 02:11:14 EDT 2017

Merge remote-tracking branch 'origin/master'

--- a/as/as.h
+++ b/as/as.h
@@ -107,7 +107,7 @@
 #endif
 
 /* expr.c */
-extern Node *expr(char *s);
+extern Node *expr(char **s);
 extern void deltree(Node *np);
 
 /* proc.c */
--- a/as/expr.c
+++ b/as/expr.c
@@ -11,6 +11,7 @@
 #define NNODES   10
 
 enum tokens {
+	EOS = -1,
 	IDEN = 1,
 	NUMBER,
 	REG,
@@ -124,8 +125,10 @@
 	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 @@
 	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 @@
 	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 @@
 	int c;
 	char *p;
 
-	for (endp = textp+1; *endp != '\''; ++endp)
-		/* nothing */;
+	while (*endp != '\'')
+		++endp;
 	return NUMBER;
 }
 
@@ -214,12 +217,27 @@
 	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;
@@ -226,22 +244,25 @@
 
 	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 @@
 		np->sym = yylval.sym;
 		next();
 		break;
+	case '[':
+		next();
+		np = or();
+		expect(']');
+		np = node('@', np, NULL);
+		break;
 	case '(':
 		next();
 		np = or();
@@ -399,15 +426,20 @@
 }
 
 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;
 }
--- 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 @@
 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
--- a/as/parser.c
+++ b/as/parser.c
@@ -35,8 +35,6 @@
 Node **
 getargs(char *s)
 {
-	char *t;
-	int ch, len;
 	Node **ap;
 	static Node *args[NARGS];
 
@@ -43,24 +41,11 @@
 	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 @@
 			if (c == '\0')
 				error("unterminated string");
 			break;
-		default:
-			*s = toupper(*s);
-			break;
 		}
 	}
 
@@ -106,9 +88,14 @@
 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))
--- 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 @@
 		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;
 	}
 
--- a/as/target/x86/gen.awk
+++ b/as/target/x86/gen.awk
@@ -40,12 +40,18 @@
 	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 "};"
 }
@@ -52,12 +58,11 @@
 
 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"
--- a/inc/scc.h
+++ b/inc/scc.h
@@ -44,3 +44,4 @@
 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);
--- a/lib/c/include/ctype.h
+++ b/lib/c/include/ctype.h
@@ -28,18 +28,22 @@
 #define _SP	0x80	/* hard space (0x20) */
 
 extern unsigned char __ctype[];
+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 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)
 
--- 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 */
--- /dev/null
+++ b/lib/scc/casecmp.c
@@ -1,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;
+}
--- a/lib/scc/libdep.mk
+++ b/lib/scc/libdep.mk
@@ -6,3 +6,4 @@
           $(LIBDIR)/xrealloc.o \
           $(LIBDIR)/xstrdup.o \
           $(LIBDIR)/alloc.o \
+          $(LIBDIR)/casecmp.o \