From c1b601af3c16a3f59e4de55d7c479998f9e329ef Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Sep 2017 14:04:31 +0100 Subject: [PATCH] smallc: remove literal buffer Restructure the code so that literal data is generated inline relying upon the assembler segment functionality to sort out the interleaving. A platform whose assembler isn't good enough can always switch between two files... This saves us about 3K and means that the literal space is no longer limited to 2.5K per compiled file. You stil can't initialize pointers but the framework is now there to do this. --- Applications/SmallC/data.c | 6 +- Applications/SmallC/data.h | 3 - Applications/SmallC/defs.h | 36 +++++++--- Applications/SmallC/error.c | 3 +- Applications/SmallC/gen.c | 1 - Applications/SmallC/initials.c | 78 --------------------- Applications/SmallC/main.c | 118 +------------------------------- Applications/SmallC/primary.c | 54 +++++++++++---- Applications/SmallC/prototype.h | 2 +- Applications/SmallC/sym.c | 64 +++++++++++------ Applications/SmallC/while.c | 27 ++------ 11 files changed, 120 insertions(+), 272 deletions(-) diff --git a/Applications/SmallC/data.c b/Applications/SmallC/data.c index 26ead77b..ad873844 100644 --- a/Applications/SmallC/data.c +++ b/Applications/SmallC/data.c @@ -17,8 +17,6 @@ int while_table_index; int swstcase[SWSTSZ]; int swstlab[SWSTSZ]; int swstp; -char litq[LITABSZ]; -int litptr; char macq[MACQSIZE]; int macptr; char line[LINESIZE]; @@ -33,7 +31,6 @@ int member_table_index; // ptr to next member /* miscellaneous storage */ int nxtlab, - litlab, stkp, argstk, ncmp, @@ -61,5 +58,4 @@ int aflag; int uflag; // undocumented 8085 instructions INITIALS initials_table[NUMBER_OF_GLOBALS]; -char initials_data_table[INITIALS_SIZE]; // 5kB space for initialisation data -int initials_idx = 0, initials_data_idx = 0; +int initials_idx = 0; diff --git a/Applications/SmallC/data.h b/Applications/SmallC/data.h index 799cb71a..7e69074f 100644 --- a/Applications/SmallC/data.h +++ b/Applications/SmallC/data.h @@ -9,8 +9,6 @@ extern int while_table_index; extern int swstcase[]; extern int swstlab[]; extern int swstp; -extern char litq[]; -extern int litptr; extern char macq[]; extern int macptr; extern char line[]; @@ -25,7 +23,6 @@ extern int member_table_index; // ptr to next member< /* miscellaneous storage */ extern int nxtlab, - litlab, stkp, argstk, ncmp, diff --git a/Applications/SmallC/defs.h b/Applications/SmallC/defs.h index 7c83941e..9500358d 100644 --- a/Applications/SmallC/defs.h +++ b/Applications/SmallC/defs.h @@ -71,6 +71,28 @@ struct tag_symbol { * possible entries for "type" * high order 14 bits give length of object * low order 2 bits make type unique within length + * + * + * Proposed new encoding + * 15: const + * 14: volatile + * 13: complex object + * 12-10: ptr depth + * + * complex object + * 9-0: pointer into object table (including function pointers so + * we can one day do type checking) + * + * simple object + * + * 9-8: unused + * 7: unsigned + * 6-5: + * 00 char/short/int/long + * 01 float/double + * 10 void + * 11 spare + * 0-4: size (1-8) not valid for complex objects */ #define UNSIGNED 1 #define STRUCT 2 @@ -80,7 +102,8 @@ struct tag_symbol { #define UINT ((2 << 2) + 1) #define VOID (0 << 2) -// possible entries for storage +/* possible entries for storage: to change */ + #define PUBLIC 1 #define AUTO 2 #define EXTERN 3 @@ -114,14 +137,6 @@ struct while_rec { /* "switch" label stack */ #define SWSTSZ 100 -/* literal pool */ -#ifdef TINY -#define LITABSZ 2500 -#else -#define LITABSZ 5000 -#endif -#define LITMAX LITABSZ-1 - /* input line */ #define LINESIZE 150 #define LINEMAX (LINESIZE-1) @@ -157,6 +172,7 @@ struct while_rec { #define HL_REG 1<<1 #define DE_REG 1<<2 +/* This we can switch to the new encoding when ready */ struct lvalue { SYMBOL *symbol; // symbol table address, or 0 for constant int indirect; // type of indirect object, 0 for static object @@ -207,6 +223,8 @@ void gen_put_memory(SYMBOL *sym); #define INIT_LENGTH NAMESIZE+1 #define INITIALS_SIZE 5*1024 +/* For arrays we need to use the type and point the type at the object + info so we can do multi-dimensional arrays properly */ struct initials_table { char name[NAMESIZE]; // symbol name int type; // type diff --git a/Applications/SmallC/error.c b/Applications/SmallC/error.c index 4de46c39..6cdb6c4e 100644 --- a/Applications/SmallC/error.c +++ b/Applications/SmallC/error.c @@ -7,7 +7,7 @@ #include "defs.h" #include "data.h" -void error (char *ptr) +void error(char *ptr) { int tempfile; @@ -42,4 +42,3 @@ void doerror(char *ptr) output_string (" ******"); newline (); } - diff --git a/Applications/SmallC/gen.c b/Applications/SmallC/gen.c index 5e1bc05c..8e0d0ba0 100644 --- a/Applications/SmallC/gen.c +++ b/Applications/SmallC/gen.c @@ -38,7 +38,6 @@ void print_label(int label) { /** * glabel - generate label - * not used ? * @param lab label number */ void glabel(char *lab) { diff --git a/Applications/SmallC/initials.c b/Applications/SmallC/initials.c index bd39af79..80bfaa5a 100644 --- a/Applications/SmallC/initials.c +++ b/Applications/SmallC/initials.c @@ -36,7 +36,6 @@ void add_symbol_initials(char *symbol_name, char type) { */ int find_symbol_initials(char *symbol_name) { int result = 0; - initials_data_idx = 0; for (initials_idx=0; initials_table[initials_idx].type != 0; initials_idx++) { if (initials_idx >= NUMBER_OF_GLOBALS) { error("initials table overrun"); @@ -44,46 +43,11 @@ int find_symbol_initials(char *symbol_name) { if (astreq (symbol_name, initials_table[initials_idx].name, NAMEMAX) != 0) { result = 1; break; - } else { // move to next symbol - // count position in data array - initials_data_idx += initials_table[initials_idx].data_len; } } return result; } -/** - * add data to table for given symbol - * @param symbol_name - * @param type - * @param value - * @param tag - */ -void add_data_initials(char *symbol_name, int type, int value, TAG_SYMBOL *tag) { - int position; - if (find_symbol_initials(symbol_name) == 0) { - add_symbol_initials(symbol_name, tag == 0 ? type : STRUCT); - } - if (tag != 0) { - // find number of members, dim is total number of values added - int index = initials_table[initials_idx].dim % tag->number_of_members; - int member_type = member_table[tag->member_idx + index].type; - // add it recursively - add_data_initials(symbol_name, member_type, value, 0); - } else { - position = initials_table[initials_idx].data_len; - if (type & CCHAR) { - initials_data_table[initials_data_idx + position] = 0xff & value; - initials_table[initials_idx].data_len += 1; - } else if (type & CINT) { - initials_data_table[initials_data_idx + position] = (0xff00 & value) >> 8; - initials_data_table[initials_data_idx + position + 1] = 0xff & value; - initials_table[initials_idx].data_len += INTSIZE; - } - initials_table[initials_idx].dim += 1; - } -} - /** * get number of data items for given symbol * @param symbol_name @@ -97,45 +61,3 @@ int get_size(char *symbol_name) { return result; } -/** - * get item at position - * @param symbol_name - * @param position - * @param itag index of tag in tag table - * @return - */ -int get_item_at(char *symbol_name, int position, TAG_SYMBOL *tag) { - int result = 0, i, type; - if (find_symbol_initials(symbol_name) != 0) { - if (initials_table[initials_idx].type & CCHAR) { - result = initials_data_table[initials_data_idx + position]; - } else if (initials_table[initials_idx].type & CINT) { - position *= INTSIZE; - result = (initials_data_table[initials_data_idx + position] << 8) + - (unsigned char)initials_data_table[initials_data_idx + position+1]; - } else if (initials_table[initials_idx].type == STRUCT) { - // find number of members - int number_of_members = tag->number_of_members; - // point behind the last full struct - int index = (position / number_of_members) * tag->size; - // move to required member - for (i=0; i < (position % number_of_members); i++) { - type = member_table[tag->member_idx + i].type; - if (type & CCHAR) { - index += 1; - } else { - index += INTSIZE; - } - } - // get value - type = member_table[tag->member_idx + i].type; - if (type & CCHAR) { - result = initials_data_table[initials_data_idx + index]; - } else { - result = (initials_data_table[initials_data_idx + index] << 8) + - (unsigned char)initials_data_table[initials_data_idx + index+1]; - } - } - } - return result; -} diff --git a/Applications/SmallC/main.c b/Applications/SmallC/main.c index 800ff442..bc2d1d9d 100644 --- a/Applications/SmallC/main.c +++ b/Applications/SmallC/main.c @@ -73,7 +73,6 @@ void compile(char *file) { iflevel = skiplevel = swstp = - litptr = stkp = errcnt = ncmp = @@ -85,7 +84,6 @@ void compile(char *file) { cmode = 1; glbflag = 1; nxtlab = 0; - litlab = getlabel(); defmac("end\tmemory"); //add_global("memory", ARRAY, CCHAR, 0, EXTERN); //add_global("stack", ARRAY, CCHAR, 0, EXTERN); @@ -111,7 +109,6 @@ void compile(char *file) { parse(); close(input); data_segment_gdata(); - dumplits(); dumpglbs(); errorsummary(); trailer(); @@ -205,31 +202,6 @@ int do_declarations(int stclass, TAG_SYMBOL *mtag, int is_struct) { return (1); } -/** - * dump the literal pool - */ -void dumplits(void) { - int j, k; - - if (litptr == 0) - return; - print_label(litlab); - output_label_terminator(); - k = 0; - while (k < litptr) { - gen_def_byte(); - j = 8; - while (j--) { - output_number(litq[k++] & 127); - if ((j == 0) | (k >= litptr)) { - newline(); - break; - } - output_byte(','); - } - } -} - /** * dump all static variables */ @@ -240,88 +212,14 @@ void dumpglbs(void) { current_symbol_table_idx = rglobal_table_index; while (current_symbol_table_idx < global_table_index) { SYMBOL *symbol = &symbol_table[current_symbol_table_idx]; - if (symbol->identity != FUNCTION) { + if (symbol->identity != FUNCTION) ppubext(symbol); - if (symbol->storage != EXTERN) { - output_string(symbol->name); - output_label_terminator(); - dim = symbol->offset; - list_size = 0; - line_count = 0; - if (find_symbol_initials(symbol->name)) { // has initials - list_size = get_size(symbol->name); - if (dim == -1) { - dim = list_size; - } - } - for (i=0; itype == STRUCT) { - dump_struct(symbol, i); - } else { - if (line_count % 10 == 0) { - newline(); - if ((symbol->type & CINT) || (symbol->identity == POINTER)) { - gen_def_word(); - } else { - gen_def_byte(); - } - } - if (i < list_size) { - // dump data - value = get_item_at(symbol->name, i, &tag_table[symbol->tagidx]); - output_number(value); - } else { - // dump zero, no more data available - output_number(0); - } - line_count++; - if (line_count % 10 == 0) { - line_count = 0; - } else { - if (i < dim-1) { - output_byte( ',' ); - } - } - } - } - newline(); - } - } else { + else fpubext(symbol); - } current_symbol_table_idx++; } } -/** - * dump struct data - * @param symbol struct variable - * @param position position of the struct in the array, or zero - */ -void dump_struct(SYMBOL *symbol, int position) { - int i, number_of_members, value; - number_of_members = tag_table[symbol->tagidx].number_of_members; - newline(); - for (i=0; itagidx].member_idx + i].type; - if (member_type & CINT) { - gen_def_word(); - } else { - gen_def_byte(); - } - if (position < get_size(symbol->name)) { - // dump data - value = get_item_at(symbol->name, position*number_of_members+i, &tag_table[symbol->tagidx]); - output_number(value); - } else { - // dump zero, no more data available - output_number(0); - } - newline(); - } -} - /** * report errors */ @@ -334,18 +232,6 @@ void errorsummary(void) { if (errcnt) errfile = YES; output_string(" error(s) in compilation"); newline(); - gen_comment(); - output_with_tab("literal pool:"); - output_decimal(litptr); - newline(); - gen_comment(); - output_with_tab("global pool:"); - output_decimal(global_table_index - rglobal_table_index); - newline(); - gen_comment(); - output_with_tab("Macro pool:"); - output_decimal(macptr); - newline(); if (errcnt > 0) pl("Error(s)"); } diff --git a/Applications/SmallC/primary.c b/Applications/SmallC/primary.c index 1832aac4..553ad234 100644 --- a/Applications/SmallC/primary.c +++ b/Applications/SmallC/primary.c @@ -175,10 +175,14 @@ int constant(int val[]) { gen_immediate (); else if (quoted_char (val)) gen_immediate (); - else if (quoted_string (val)) { + /* Quoted strings are constants so we don't need to do any mucking about + with segments - however we move them to data as we'd otherwise put + them mid code stream ! */ + else if (quoted_string (NULL, val)) { gen_immediate (); - print_label (litlab); - output_byte ('+'); + print_label (val[0]); + newline(); + return 1; } else return (0); output_number (val[0]); @@ -249,30 +253,50 @@ int quoted_char(int *value) { /** * Test if we have string enclosed in double quotes. e.g. "abc". * Load the string into literal pool. - * @param position returns beginning of the string + * @param position returns label for this string * @return 1 if such string found, 0 otherwise */ -int quoted_string(int *position) { +int quoted_string(int *len, int *position) { char c; + int x; + int l; if (!match ("\"")) return (0); - *position = litptr; + if (position) { + data_segment_gdata(); + *position = getlabel(); + generate_label(*position); + } + x = 0; while (ch () != '"') { - if (ch () == 0) + if (ch () == 0) { + /* Should error ?? FIXME */ break; - if (litptr >= LITMAX) { - error ("string space exhausted"); - while (!match ("\"")) - if (gch () == 0) - break; - return (1); } c = gch(); - litq[litptr++] = (c == '\\') ? spechar(): c; + c = (c == '\\') ? spechar(): c; + if (x == 0) + gen_def_byte(); + else + output_byte(','); + output_number(c); + if (x++ == 7) { + x = 0; + newline(); + } + l++; } gch (); - litq[litptr++] = 0; + if (x != 0) + newline(); + gen_def_byte(); + output_number(0); + newline(); + if (len) + *len = l + 1; + if (position) + code_segment_gtext(); return (1); } diff --git a/Applications/SmallC/prototype.h b/Applications/SmallC/prototype.h index 641e9ae8..711866da 100644 --- a/Applications/SmallC/prototype.h +++ b/Applications/SmallC/prototype.h @@ -183,7 +183,7 @@ extern void result(LVALUE *lval, LVALUE *lval2); extern int constant(int val[]); extern int number(int val[]); extern int quoted_char(int *value); -extern int quoted_string(int *position); +extern int quoted_string(int *len, int *position); extern int spechar(void); extern void callfunction(char *ptr); extern void needlval(void); diff --git a/Applications/SmallC/sym.c b/Applications/SmallC/sym.c index 1cf2fc32..3985ac70 100644 --- a/Applications/SmallC/sym.c +++ b/Applications/SmallC/sym.c @@ -95,13 +95,16 @@ int declare_global(int type, int storage, TAG_SYMBOL *mtag, int otag, int is_str */ int initials(char *symbol_name, int type, int identity, int dim, int otag) { int dim_unknown = 0; - litptr = 0; + int n; + if(dim == 0) { // allow for xx[] = {..}; declaration dim_unknown = 1; } if (!(type & CCHAR) && !(type & CINT) && !(type == STRUCT)) { error("unsupported storage size"); } + data_segment_gdata(); + glabel(symbol_name); if(match("=")) { // an array or struct if(match("{")) { @@ -131,6 +134,19 @@ int initials(char *symbol_name, int type, int identity, int dim, int otag) { } if(--dim_unknown == 0) identity = POINTER; + else { + /* Pad any missing objects */ + n = dim; + gen_def_storage(); + if (identity != ARRAY && type != STRUCT) { + if (!(type & CCHAR)) + n *= 2; + } else + n = tag_table[otag].size; + + output_number(n); + newline(); + } } needbrack("}"); // single constant @@ -138,6 +154,7 @@ int initials(char *symbol_name, int type, int identity, int dim, int otag) { init(symbol_name, type, identity, &dim, 0); } } + code_segment_gtext(); return identity; } @@ -148,15 +165,19 @@ int initials(char *symbol_name, int type, int identity, int dim, int otag) { void struct_init(TAG_SYMBOL *tag, char *symbol_name) { int dim ; int member_idx; + int size = tag->size; member_idx = tag->member_idx; while (member_idx < tag->member_idx + tag->number_of_members) { - init(symbol_name, member_table[tag->member_idx + member_idx].type, + size -= init(symbol_name, member_table[tag->member_idx + member_idx].type, member_table[tag->member_idx + member_idx].identity, &dim, tag); ++member_idx; + /* FIXME: not an error - zero rest */ if ((match(",") == 0) && (member_idx != (tag->member_idx + tag->number_of_members))) { - error("struct initialisaton out of data"); - break ; + gen_def_storage(); + output_number(size); + newline(); + break; } } } @@ -169,31 +190,32 @@ void struct_init(TAG_SYMBOL *tag, char *symbol_name) { * @param dim * @param tag * @return + * returns size of initializer, or 0 for none (a null string is size 1) + * */ int init(char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL *tag) { - int value, number_of_chars; + int value, n; if(identity == POINTER) { error("cannot assign to pointer"); } - if(quoted_string(&value)) { + /* FIXME: may need to distinguish const string v data in future */ + if(quoted_string(&n, NULL)) { if((identity == VARIABLE) || !(type & CCHAR)) error("found string: must assign to char pointer or array"); - number_of_chars = litptr - value; - *dim = *dim - number_of_chars; - while (number_of_chars > 0) { - add_data_initials(symbol_name, CCHAR, litq[value++], tag); - number_of_chars = number_of_chars - 1; - } - } else if (number(&value)) { - add_data_initials(symbol_name, CINT, value, tag); - *dim = *dim - 1; - } else if(quoted_char(&value)) { - add_data_initials(symbol_name, CCHAR, value, tag); - *dim = *dim - 1; - } else { - return 0; + *dim = *dim - n; /* ??? FIXME arrays of char only */ + return n; } - return 1; + + if (type & CCHAR) + gen_def_byte(); + else + gen_def_word(); + if (!number(&value) && !quoted_char(&value)) + return 0; + *dim = *dim - 1; + output_number(value); + newline(); + return (type & CCHAR) ? 1 : 2; } /** diff --git a/Applications/SmallC/while.c b/Applications/SmallC/while.c index 84d523e7..a2a2c510 100644 --- a/Applications/SmallC/while.c +++ b/Applications/SmallC/while.c @@ -8,62 +8,47 @@ #include "defs.h" #include "data.h" -void addwhile(WHILE *ptr) { -//int ptr[]; - //int k; +char *noactive = "mo active do/for/while/switch"; - //if (wsptr == WSMAX) { +void addwhile(WHILE *ptr) { if (while_table_index == WSTABSZ) { error ("too many active whiles"); return; } - //k = 0; - //while (k < WSSIZ) - // *wsptr++ = ptr[k++]; memcpy(&ws[while_table_index++], ptr, sizeof(WHILE)); } void delwhile(void) { - if (readwhile ()) { - //wsptr = wsptr - WSSIZ; + if (readwhile ()) while_table_index--; - } } WHILE *readwhile(void) { if (while_table_index == 0) { - //if (wsptr == ws) { - error ("no active do/for/while/switch"); + error (noactive); return (0); } else { - //return (wsptr-WSSIZ); return &ws[while_table_index - 1]; } } WHILE *findwhile(void) { - //int *ptr; int while_table_idx; - //for (ptr = wsptr; ptr != ws;) { while_table_idx = while_table_index; for (; while_table_idx != 0;) { - //ptr = ptr - WSSIZ; while_table_idx--; - //if (ptr[WSTYP] != WSSWITCH) - // return (ptr); if (ws[while_table_idx].type != WSSWITCH) return &ws[while_table_idx]; } - error ("no active do/for/while"); + error (noactive); return (0); } WHILE *readswitch(void) { - WHILE *ptr; //int *ptr; + WHILE *ptr; if ((ptr = readwhile ()) != 0) { - //if (ptr[WSTYP] == WSSWITCH) if (ptr->type == WSSWITCH) { return (ptr); } -- 2.34.1