ref: 3cb05279b1ab7d3b2a97d4aa427a44a1598ec839
parent: e55a366ab763ffa5706625ad27271384eee6e857
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Apr 23 10:52:23 EDT 2014
Add STRING constants These are the common C strings ended with a 0.
--- a/cc1.h
+++ b/cc1.h
@@ -103,6 +103,7 @@
} s;
union {
int i;
+ char *s;
struct symbol *sym;
uint8_t ns, token;
} u;
@@ -169,7 +170,7 @@
LE, GE, EQ, NE, AND, OR,
MUL_EQ, DIV_EQ, MOD_EQ, ADD_EQ, SUB_EQ, AND_EQ,
XOR_EQ, OR_EQ, SHL_EQ, SHR_EQ,
- ELLIPSIS,
+ ELLIPSIS, STRING,
CASE, DEFAULT, IF, ELSE, SWITCH, WHILE, DO, FOR, GOTO,
CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
};
--- a/code.c
+++ b/code.c
@@ -79,7 +79,16 @@
static void
emitconst(Node *np)
{
- printf("#%x", np->u.sym->u.i);
+ register char *bp, c;
+ Symbol *sym = np->u.sym;
+
+ if (np->type == inttype) {
+ printf("#%x", sym->u.i);
+ } else {
+ putchar('"');
+ for (bp = sym->u.s; c = *bp; ++bp)
+ printf("%02x", (unsigned) c);
+ }
}
void
--- a/expr.c
+++ b/expr.c
@@ -422,7 +422,7 @@
Symbol *sym;
switch (yytoken) {
- case CONSTANT: case IDEN:
+ case STRING: case CONSTANT: case IDEN:
if ((sym = yylval.sym) == NULL)
error("'%s' undeclared", yytext);
np = symcode(yylval.sym);
@@ -432,7 +432,6 @@
}
next();
break;
- /* TODO: case STRING: */
case '(':
next();
np = expr();
--- a/lex.c
+++ b/lex.c
@@ -98,7 +98,8 @@
}
}
-end: if (bp == &yybuf[IDENTSIZ])
+end:
+ if (bp == &yybuf[IDENTSIZ])
error("identifier too long %s", yybuf);
*bp = '\0';
ungetc(ch, yyin);
@@ -105,6 +106,71 @@
return integer(yybuf, base);
}
+static char *
+escape(char *s)
+{
+ char c;
+
+ switch (getc(yyin)) {
+ case '\\': c = '\''; break;
+ case 'a': c = '\a'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
+ case '\'': c = '\\'; break;
+ case '"': c ='"'; break;
+ case 'x': /* TODO: */
+ case '0': /* TODO: */
+ case 'u': /* TODO: */
+ case '\n':
+ ++linenum, columnum = 1;
+ return s;
+ default:
+ warn(1, "unknown escape sequence");
+ return s;
+ }
+
+ *s = c;
+ return ++s;
+}
+
+static uint8_t
+string(void)
+{
+ static char buf[STRINGSIZ+1];
+ register char *bp;
+ register int c;
+ static Symbol *sym;
+
+ getc(yyin); /* discard the initial " */
+
+ for (bp = buf; bp < &buf[STRINGSIZ]; ) {
+ switch (c = getc(yyin)) {
+ case EOF:
+ error("found EOF while parsing");
+ case '"':
+ goto end_string;
+ case '\\':
+ bp = escape(bp);
+ break;
+ default:
+ *bp++ = c;
+ }
+ }
+
+end_string:
+ if (bp == &buf[IDENTSIZ])
+ error("string too long");
+ *bp = '\0';
+ sym = install("", NS_IDEN);
+ sym->u.s = xstrdup(buf);
+ sym->type = mktype(chartype, PTR, NULL, 0);
+ yynlval.sym = sym;
+ return STRING;
+}
+
void
init_keywords(void)
{
@@ -322,6 +388,8 @@
yyntoken = iden();
else if (isdigit(c) || c == '-' || c == '+')
yyntoken = number();
+ else if (c == '"')
+ yyntoken = string();
else
yyntoken = operator();