scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 47c4f8aebf11f33fa841c25d85ab33410668ea24
parent e56b22693ff12207d5106ed3c9aab1ba77cbb096
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 19 Jan 2016 14:06:30 +0100

Add initializators from strings

There are two cases of initializators in this case,
iniitializator of array of char, and initializators of
pointers to char. In this case we are dealing with array
initializators.

Diffstat:
cc1/cc1.h | 1+
cc1/init.c | 34++++++++++++++++++++++++++++------
cc1/lex.c | 5+----
cc1/symbol.c | 12++++++++++++
4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -341,6 +341,7 @@ extern void pushctx(void), popctx(void); extern void killsym(Symbol *sym); extern Symbol *newlabel(void); extern void keywords(struct keyword *key, int ns); +extern Symbol *newstring(char *s, size_t len); /* stmt.c */ extern void compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch); diff --git a/cc1/init.c b/cc1/init.c @@ -91,14 +91,36 @@ static Node *initlist(Type *tp); static Node * initialize(Type *tp) { - Node *np; + Node *np, *aux; + Symbol *sym; + Type *btp; + size_t len; + + np = (accept('{')) ? initlist(tp) : assign(); + sym = np->sym; + if (sym && (sym->flags & ISSTRING) != 0 && tp->op == ARY) { + btp = tp->type; + if (btp != chartype && btp != uchartype && btp != schartype) { + errorp("array of inappropriate type initialized from string constant"); + goto return_zero; + } + len = strlen(sym->u.s); + if (!tp->defined) { + tp->defined = 1; + tp->n.elem = len; + } else if (tp->n.elem < len) { + warn("initializer-string for array of chars is too long"); + np->sym = newstring(sym->u.s, tp->n.elem); + } - np = (accept('{')) ? initlist(tp) : decay(assign()); - if ((np = convert(np, tp, 0)) == NULL) { - errorp("incorrect initializer"); - np = constnode(zero); + return np; } - return np; + if ((aux = convert(decay(np), tp, 0)) != NULL) + return aux; + + errorp("incorrect initializer"); +return_zero: + return constnode(zero); } static Node * diff --git a/cc1/lex.c b/cc1/lex.c @@ -483,10 +483,7 @@ repeat: *bp = '\0'; yylen = bp - yytext + 1; - yylval.sym = newsym(NS_IDEN); - yylval.sym->flags |= ISSTRING | ISCONSTANT; - yylval.sym->u.s = xstrdup(yytext+1); - yylval.sym->type = mktype(chartype, ARY, yylen - 2, NULL); + yylval.sym = newstring(yytext+1, yylen-2); *bp++ = '"'; *bp = '\0'; return CONSTANT; diff --git a/cc1/symbol.c b/cc1/symbol.c @@ -226,6 +226,18 @@ newsym(int ns) } Symbol * +newstring(char *s, size_t len) +{ + Symbol *sym = newsym(NS_IDEN); + + sym->flags |= ISSTRING | ISCONSTANT; + sym->u.s = xmalloc(len); + memcpy(sym->u.s, s, len); + sym->type = mktype(chartype, ARY, len, NULL); + return sym; +} + +Symbol * newlabel(void) { Symbol *sym = newsym(NS_LABEL);