smallc: remove literal buffer
authorAlan Cox <alan@linux.intel.com>
Wed, 20 Sep 2017 13:04:31 +0000 (14:04 +0100)
committerAlan Cox <alan@linux.intel.com>
Wed, 20 Sep 2017 13:04:31 +0000 (14:04 +0100)
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
Applications/SmallC/data.h
Applications/SmallC/defs.h
Applications/SmallC/error.c
Applications/SmallC/gen.c
Applications/SmallC/initials.c
Applications/SmallC/main.c
Applications/SmallC/primary.c
Applications/SmallC/prototype.h
Applications/SmallC/sym.c
Applications/SmallC/while.c

index 26ead77..ad87384 100644 (file)
@@ -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;
index 799cb71..7e69074 100644 (file)
@@ -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,
index 7c83941..9500358 100644 (file)
@@ -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
index 4de46c3..6cdb6c4 100644 (file)
@@ -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 ();
 }
-
index 5e1bc05..8e0d0ba 100644 (file)
@@ -38,7 +38,6 @@ void print_label(int label) {
 
 /**
  * glabel - generate label
- * not used ?
  * @param lab label number
  */
 void glabel(char *lab) {
index bd39af7..80bfaa5 100644 (file)
@@ -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;
-}
index 800ff44..bc2d1d9 100644 (file)
@@ -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; i<dim; i++) {
-                    if (symbol->type == 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; i<number_of_members; i++) {
-        // i is the index of current member, get type
-        int member_type = member_table[tag_table[symbol->tagidx].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)");
 }
index 1832aac..553ad23 100644 (file)
@@ -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);
 }
 
index 641e9ae..711866d 100644 (file)
@@ -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);
index 1cf2fc3..3985ac7 100644 (file)
@@ -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;
 }
 
 /**
index 84d523e..a2a2c51 100644 (file)
@@ -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);
         }