scc

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

commit 6124426ed00d4e0802766a6100b8032155f0bb44
parent a62bbf6a5d79b1428f3a8016644daf4b44614d95
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 25 Jan 2016 21:39:19 +0100

Simplify definitions in the IR

Having the definition of initializers in the nex line was causing
that was impossible to be able to emit variables until parsing
the next element, which forced us to deal with a lastsym variable
and several cases. It is better to know in the same line if
the symbol is initialized or not.

Diffstat:
cc1/cc1.h | 3++-
cc1/code.c | 5+++--
cc1/expr.c | 1+
cc1/init.c | 4+++-
cc1/tests/test001.c | 3+--
cc1/tests/test026.c | 5++---
cc1/tests/test027.c | 3+--
cc1/tests/test028.c | 3+--
cc1/tests/test032.c | 3+--
cc1/tests/test038.c | 2+-
cc1/tests/test045.c | 3+--
cc1/tests/test046.c | 3+--
cc1/tests/test047.c | 3+--
cc1/tests/test048.c | 3+--
cc1/tests/test049.c | 6++----
cc1/tests/test051.c | 3+--
cc1/tests/test052.c | 3+--
cc1/tests/test053.c | 3+--
cc1/tests/test056.c | 6++----
cc1/tests/test057.c | 6++----
cc1/tests/test058.c | 3+--
cc2/parser.c | 68+++++++++++++++++++++++++++++++++++++++-----------------------------
22 files changed, 69 insertions(+), 73 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -187,7 +187,8 @@ enum { ISDEFINED = 2048, ISSTRING = 4096, ISTYPEDEF = 8192, - ISINITLST = 16384 + ISINITLST = 16384, + ISINIT = 32768 }; /* lexer mode, compiler or preprocessor directive */ diff --git a/cc1/code.c b/cc1/code.c @@ -365,7 +365,7 @@ emitinit(unsigned op, void *arg) { Node *np = arg; - puts("("); + puts("\t("); emitdesig(np, np->type); puts(")"); } @@ -384,8 +384,9 @@ emitdcl(unsigned op, void *arg) printf("\t\"%s", (sym->name) ? sym->name : ""); if (sym->flags & ISFIELD) printf("\t#%c%llX", sizettype->letter, sym->u.i); - putchar('\n'); sym->flags |= ISEMITTED; + if ((sym->flags & ISINIT) == 0) + putchar('\n'); } static void diff --git a/cc1/expr.c b/cc1/expr.c @@ -619,6 +619,7 @@ primary(void) switch (yytoken) { case STRING: np = constnode(sym); + sym->flags |= ISINIT; emit(ODECL, sym); emit(OINIT, np); np = decay(varnode(sym)); diff --git a/cc1/init.c b/cc1/init.c @@ -300,7 +300,6 @@ initializer(Symbol *sym, Type *tp) } np = initialize(tp); - emit(ODECL, sym); if (flags & ISDEFINED) { errorp("redeclaration of '%s'", sym->name); } else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) { @@ -308,12 +307,15 @@ initializer(Symbol *sym, Type *tp) errorp("initializer element is not constant"); return; } + sym->flags |= ISINIT; + emit(ODECL, sym); emit(OINIT, np); sym->flags |= ISDEFINED; } else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) { errorp("'%s' has both '%s' and initializer", sym->name, (flags&ISEXTERN) ? "extern" : "typedef"); } else { + emit(ODECL, sym); np = node(OASSIGN, tp, varnode(sym), np); emit(OEXPR, np); } diff --git a/cc1/tests/test001.c b/cc1/tests/test001.c @@ -7,8 +7,7 @@ G6 F "main { \ V8 K #N13 -Y7 V8 " -( +Y7 V8 " ( #"hello world #K0A #K00 diff --git a/cc1/tests/test026.c b/cc1/tests/test026.c @@ -10,13 +10,12 @@ G3 F "main A4 I "y A6 P "p V8 K #N10 -Y7 V8 " -( +Y7 V8 " ( #"test026.c #K00 ) A6 Y7 'P :P - A4 #I24 :I + A4 #I23 :I A4 #I1 :I A4 #I1 :I A4 #I1 :I diff --git a/cc1/tests/test027.c b/cc1/tests/test027.c @@ -9,8 +9,7 @@ G3 F "main \ A5 P "p V7 K #N25 -Y6 V7 " -( +Y6 V7 " ( #"hello is better than bye #K00 ) diff --git a/cc1/tests/test028.c b/cc1/tests/test028.c @@ -8,8 +8,7 @@ G6 F "foo { \ V8 K #N3 -Y10 V8 " -( +Y10 V8 " ( #"hi #K00 ) diff --git a/cc1/tests/test032.c b/cc1/tests/test032.c @@ -8,8 +8,7 @@ G5 F "main { \ V9 K #N44 -Y8 V9 " -( +Y8 V9 " ( #"This is a string $ or # or ##and it is ok ! #K00 ) diff --git a/cc1/tests/test038.c b/cc1/tests/test038.c @@ -6,7 +6,7 @@ error: test038.c:43: error: redeclaration of 'x' output: G1 I "x -( + ( #I0 ) G5 F "foo diff --git a/cc1/tests/test045.c b/cc1/tests/test045.c @@ -3,8 +3,7 @@ name: TEST045 description: Basic test of initializers error: output: -G1 I "x -( +G1 I "x ( #I5 ) G3 F "main diff --git a/cc1/tests/test046.c b/cc1/tests/test046.c @@ -4,8 +4,7 @@ description: Basic test for initializators error: output: V1 I #N3 -G2 V1 "x -( +G2 V1 "x ( #I1 #I2 #I3 diff --git a/cc1/tests/test047.c b/cc1/tests/test047.c @@ -7,8 +7,7 @@ S2 "S #N6 #N1 M3 I "a #N0 M4 I "b #N2 M5 I "c #N4 -G6 S2 "x -( +G6 S2 "x ( #I1 #I2 #I3 diff --git a/cc1/tests/test048.c b/cc1/tests/test048.c @@ -7,8 +7,7 @@ S2 "S #N4 #N1 M3 I "a #N0 M4 I "b #N2 V5 S2 #N1 -G6 V5 "x -( +G6 V5 "x ( #I1 #I2 ) diff --git a/cc1/tests/test049.c b/cc1/tests/test049.c @@ -3,12 +3,10 @@ name: TEST049 description: Basic test for initializer error: output: -G1 I "x -( +G1 I "x ( #I5 ) -G3 P "p -( +G3 P "p ( G1 'P ) G5 F "main diff --git a/cc1/tests/test051.c b/cc1/tests/test051.c @@ -4,8 +4,7 @@ description: Basic test for initializer error: output: V1 I #N3 -G2 V1 "arr -( +G2 V1 "arr ( #I0 #I1 #I2 diff --git a/cc1/tests/test052.c b/cc1/tests/test052.c @@ -7,8 +7,7 @@ S2 "S #N4 #N1 M3 I "a #N0 M4 I "b #N2 V5 S2 #N2 -G6 V5 "arr -( +G6 V5 "arr ( #I1 #I2 #I3 diff --git a/cc1/tests/test053.c b/cc1/tests/test053.c @@ -6,8 +6,7 @@ output: S2 "S #N4 #N1 M3 I "a #N0 M4 I "b #N2 -G5 S2 "s -( +G5 S2 "s ( #I1 #I2 ) diff --git a/cc1/tests/test056.c b/cc1/tests/test056.c @@ -10,8 +10,7 @@ M4 I "b #N2 M5 I "c #N4 M7 V6 "d #N6 M8 I "e #N9 -G9 S2 "s -( +G9 S2 "s ( #I1 #I2 #I0 @@ -21,8 +20,7 @@ G9 S2 "s #I0 ) V10 K #N0 -G11 V10 "m -( +G11 V10 "m ( ) G13 F "main { diff --git a/cc1/tests/test057.c b/cc1/tests/test057.c @@ -6,8 +6,7 @@ error: output: V1 I #N3 V2 V1 #N2 -G3 V2 "arr1 -( +G3 V2 "arr1 ( #I2 #I7 #I5 @@ -15,8 +14,7 @@ G3 V2 "arr1 #I1 #I2 ) -G4 V2 "arr2 -( +G4 V2 "arr2 ( #I2 #I7 #I5 diff --git a/cc1/tests/test058.c b/cc1/tests/test058.c @@ -6,8 +6,7 @@ output: V1 I #N5 V2 V1 #N3 V3 V2 #N2 -G4 V3 "arr -( +G4 V3 "arr ( #I0 #I0 #I3 diff --git a/cc2/parser.c b/cc2/parser.c @@ -32,11 +32,11 @@ union tokenop { typedef void parsefun(char *, union tokenop); static parsefun type, symbol, getname, unary, binary, ternary, call, - parameter, constant, composed; + parameter, constant, composed, begininit, endinit; typedef void evalfun(void); -static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, - endinit, array, aggregate, flddecl; +static evalfun vardecl, beginfun, endfun, endpars, stmt, + array, aggregate, flddecl; static struct decoc { void (*eval)(void); @@ -76,8 +76,8 @@ static struct decoc { [ONAME] = {NULL, getname}, ['{'] = {beginfun}, ['}'] = {endfun}, - ['('] = {begininit}, - [')'] = {endinit}, + ['('] = {NULL, begininit}, + [')'] = {NULL, endinit}, [OEPARS] = {endpars}, [OSTMT] = {stmt}, @@ -280,15 +280,13 @@ binary(char *token, union tokenop u) } static void -begininit(void) +begininit(char *token, union tokenop u) { ininit = 1; - lastsym->type.flags |= INITF; - label(lastsym); } static void -endinit(void) +endinit(char *token, union tokenop u) { ininit = 0; } @@ -368,6 +366,32 @@ array(void) } static void +decl(Symbol *sym) +{ + switch (sym->kind) { + case EXTRN: + label(sym); + break; + case GLOB: + case PRIVAT: + case LOCAL: + label(sym); + if (!ininit) + allocdata(&sym->type); + break; + case AUTO: + case REG: + if (funpars >= 0) { + if (funpars == NR_FUNPARAM) + error(EOUTPAR); + params[funpars++] = sym; + break; + } + break; + } +} + +static void vardecl(void) { Type *tp; @@ -375,20 +399,6 @@ vardecl(void) Symbol *sym; char *name; - if (lastsym && (lastsym->type.flags & INITF) == 0) { - switch (lastsym->kind) { - case EXTRN: - label(lastsym); - break; - case GLOB: - case PRIVAT: - case LOCAL: - label(lastsym); - allocdata(&lastsym->type); - break; - } - } - name = pop(); tp = pop(); np = pop(); @@ -397,13 +407,11 @@ vardecl(void) sym->name = name; sym->type = *tp; sym->kind = sclass; + if (ininit) + sym->type.flags |= INITF; lastsym = sym; + decl(sym); - if (funpars >= 0) { - if (funpars == NR_FUNPARAM) - error(EOUTPAR); - params[funpars++] = sym; - } delnode(np); } @@ -457,6 +465,7 @@ parse(void) size_t len; int c; struct decoc *dp; + void (*fun)(void); for (;;) { if (!fgets(line, sizeof(line), stdin)) @@ -475,7 +484,8 @@ parse(void) (*dp->parse)(t, dp->u); } - (*optbl[c].eval)(); + if ((fun = *optbl[c].eval) != NULL) + (*fun)(); if (sp != stack) error(ESTACKA); if (c == '}')