BSD 4_4_Lite2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 5 Jan 1987 01:23:23 +0000 (17:23 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 5 Jan 1987 01:23:23 +0000 (17:23 -0800)
Work on file usr/src/contrib/xns/compiler/constantcode.c
Work on file usr/src/contrib/xns/compiler/constants.c

Synthesized-from: CSRG/cd3/4.4BSD-Lite2

usr/src/contrib/xns/compiler/constantcode.c [new file with mode: 0644]
usr/src/contrib/xns/compiler/constants.c [new file with mode: 0644]

diff --git a/usr/src/contrib/xns/compiler/constantcode.c b/usr/src/contrib/xns/compiler/constantcode.c
new file mode 100644 (file)
index 0000000..d05a2ef
--- /dev/null
@@ -0,0 +1,370 @@
+#ifndef lint
+static char RCSid[] = "$Header: constantcode.c,v 2.0 85/11/21 07:21:32 jqj Exp $";
+#endif
+
+/* $Log:       constantcode.c,v $
+ * Revision 2.0  85/11/21  07:21:32  jqj
+ * 4.3BSD standard release
+ * 
+ * Revision 1.4  85/05/23  06:19:32  jqj
+ * *** empty log message ***
+ * 
+ * Revision 1.4  85/05/23  06:19:32  jqj
+ * Public Beta-test version, released 24 May 1985
+ * 
+ * Revision 1.3  85/03/26  06:09:41  jqj
+ * Revised public alpha-test version, released 26 March 1985
+ * 
+ * Revision 1.2  85/03/11  16:38:56  jqj
+ * Public alpha-test version, released 11 March 1985
+ * 
+ * Revision 1.1  85/02/15  13:55:18  jqj
+ * Initial revision
+ * 
+ */
+
+/*
+ * Generate code for constant declarations.
+ */
+
+#include "compiler.h"
+
+/*
+ * Generate code for constant declarations
+ */
+define_constant(name, typtr, value)
+       struct object *name;
+       struct type *typtr;
+       struct constant *value;
+{
+       char *fullname;
+
+       name->o_class = O_CONSTANT;
+       name->o_constant = value;
+       fullname = make_full_name( name->o_module,
+                               name->o_modversion, name_of(name));
+       /*
+        * Check for simple case of Foo: TypeBaz = Mumble;
+        * where Mumble is another constant.  In this case,
+        * just use the existing declaration
+        */
+       if (value->cn_name != NULL) {
+               if (!recursive_flag) {
+                       fprintf(header,"#define %s %s\n",
+                               fullname, value->cn_name);
+                       /* open scope */
+                       fprintf(header1,"#define %s %s\n",
+                               name_of(name), value->cn_name);
+               }
+               return;
+       }
+       /*
+        * We have to generate some code for this one.  We'll generate
+        * the declaration in the header file of a static variable
+        * initialized to the appropriate values.
+        */
+       value->cn_name = fullname;
+       if (recursive_flag)
+               return;         /* it's already been expanded elsewhere */
+       /* open scope */
+       fprintf(header1,"#define %s %s\n", name_of(name), fullname);
+       /* make sure the type is defined */
+       if (typename(typtr) == NULL) {
+               /* create an anonymous (not in symboltable) type and subtypes */
+               char * typenam;
+               typenam = gensym("T_cn");
+               code_type(typenam, typtr);
+               typename(typtr) = typenam;
+               }
+       /* depending on the type, generate appropriate initializer */
+       switch (typtr->type_constr) {
+       case C_PROCEDURE:
+               define_procedure_constant(name, typtr, value);
+               break;
+       case C_ERROR:
+               define_error_constant(name, typtr, value);
+               break;
+       case C_NUMERIC:
+       case C_BOOLEAN:
+       case C_STRING:
+       case C_ENUMERATION:
+               /* these are simple, since they can't include sequences */
+               fprintf(header, "\nstatic %s %s = {%s};\n",
+                       typename(typtr), value->cn_name, value->cn_value);
+               break;
+       default:
+               /* the general case */
+               scan_for_sequences(typtr, value);       /* kludge */
+               fprintf(header, "\nstatic %s %s = ",
+                               typename(typtr), value->cn_name);
+               code_constant(typtr, value);
+               fprintf(header,";\n");
+               break;
+       }
+       return;
+}
+
+
+/*
+ * Generate client and server code for error constants
+ */
+define_error_constant(symbol,typtr,value)
+       struct object *symbol;
+       struct type *typtr;
+       struct constant *value;
+{
+       char *errvalue;
+
+       if (recursive_flag)
+               return;         /* can't happen */
+       if (typtr->type_constr != C_ERROR)
+               error(FATAL, "internal error (define_error_constant): not an error");
+       if (value->cn_constr != C_NUMERIC) {
+               error(ERROR,"Values of ERRORs must be numeric");
+               errvalue = "-1";
+       }
+       else
+               errvalue = value->cn_value;
+       fprintf(header,"\n#define %s (ERROR_OFFSET+%s)\n\
+#define %sArgs %s\n",
+                       value->cn_name, errvalue,
+                       value->cn_name, typename(typtr));
+       fprintf(header1,"#define %sArgs %sArgs\n",
+                       symbol->o_name, value->cn_name);
+       value->cn_constr = C_ERROR;
+       /* put this error in the constant's data structure */
+       /* also store this error on the global list */
+       if (typtr->type_list == NIL) {
+               value->cn_list = cons((list) errvalue, NIL);
+               Errors = cons( cons((list) value, NIL), Errors);
+       }
+       else {
+               value->cn_list = cons((list) errvalue, (list) typtr);
+               Errors = cons( cons((list) value, (list) typtr), Errors);
+       }
+}
+
+/*
+ * recursively generate the code for a constant
+ */
+code_constant(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       switch (typtr->type_constr) {
+       case C_NUMERIC:
+       case C_BOOLEAN:
+       case C_STRING:
+       case C_ENUMERATION:
+               if (value == (struct constant*) 0)
+                 fprintf(header, "0");
+               else
+                 fprintf(header, "%s", value->cn_value);
+               break;
+       case C_ARRAY:
+               code_array_constant(typtr,value);
+               break;
+       case C_SEQUENCE:
+               code_sequence_constant(typtr,value);
+               break;
+       case C_RECORD:
+               code_record_constant(typtr,value);
+               break;
+       case C_CHOICE:
+               code_choice_constant(typtr,value);
+               break;
+       case C_ERROR:
+               error(ERROR,"Error constants may not be part of a structure");
+               break;
+       case C_PROCEDURE:
+               error(ERROR,"Procedures may not be part of a structure");
+       }
+}
+
+/*
+ * Given the name of a record field and a record constant, return
+ * the corresponding component of the record constant.
+ */
+static struct constant *
+findcomponent(name,recvalue)
+       char *name;
+       struct constant *recvalue;
+{
+       list p;
+
+       if (recvalue->cn_constr != C_RECORD)
+               error(FATAL,"internal error (findcomponent): constant is of type %d",
+                       recvalue->cn_constr);
+       for (p = recvalue->cn_list; p != NIL; p = cdr(p))
+               if (streq((char *) caar(p), name))
+                       return((struct constant *) cdar(p));
+       return((struct constant *) 0);
+}
+
+\f
+/*
+ * kludge since PCC doesn't like initializations of the form
+ *   struct {int length; Seqtype *sequence} seq = {3,{1,2,3}};
+ * instead, use:
+ *   Seqtype anonymous[3] = {1,2,3};
+ *   struct {int length; Seqtype *sequence} seq = {3,anonymous};
+ * We have to generate the sequence value before we walk the constant.
+ */
+scan_for_sequences(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p;
+
+       switch (typtr->type_constr) {
+       case C_ARRAY:
+               for (p = value->cn_list; p != NIL; p = cdr(p))
+                       scan_for_sequences(typtr->type_basetype, 
+                                          (struct constant *) car(p));
+               break;
+       case C_RECORD:
+               scan_record_for_sequences(typtr, value);
+               break;
+       case C_CHOICE:
+               scan_choice_for_sequences(typtr, value);
+               break;
+       case C_SEQUENCE:
+               for (p = value->cn_list; p != NIL; p = cdr(p))
+                       scan_for_sequences(typtr->type_basetype, 
+                                          (struct constant *) car(p));
+               value->cn_seqvalname = gensym("S_v");
+               fprintf(header,"\nstatic %s %s[%d] = {\n\t",
+                       typename(typtr->type_basetype), value->cn_seqvalname,
+                       length(value->cn_list));
+               for (p = value->cn_list ; p != NIL ; p = cdr(p)) {
+                       code_constant(typtr->type_basetype,
+                                     (struct constant *) car(p));
+                       if (cdr(p) != NIL)
+                               fprintf(header,",\n\t");
+               }
+               fprintf(header,"\n};\n");
+               break;
+       default:        /* other types don't have embedded sequences */
+               break;
+       }
+}
+
+scan_record_for_sequences(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p, q;
+       struct constant *component;
+
+       for (p = typtr->type_list; p != NIL; p = cdr(p)) {
+               q = car(p);
+               component = findcomponent((char *) caar(q),value);
+               if (component != (struct constant *) 0)
+                       scan_for_sequences((struct type *) cdr(q), component);
+       }
+}
+
+/*ARGSUSED*/
+scan_choice_for_sequences(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       /* constants of type CHOICE are not implemented */
+}
+
+\f
+code_array_constant(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p;
+       int i;
+
+       if (value == (struct constant *) 0) {
+               fprintf(header,"{0");
+               for (i = 1; i < typtr->type_size; i++)
+                 fprintf(header,",0");
+               fprintf(header,"}");
+               return;
+       }
+       if (typtr->type_size != length(value->cn_list))
+               error(WARNING,"wrong number of constant elements specified for array");
+       fprintf(header,"\n\t{");
+       for (p = value->cn_list; p != NIL; p = cdr(p)) {
+               code_constant(typtr->type_basetype,(struct constant *) car(p));
+               if (cdr(p) != NIL)
+                       fprintf(header,",");
+       }
+       fprintf(header,"}");
+}
+
+code_choice_constant(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p,q;
+       struct type *bt;
+       char *desigval;
+       struct object *name;
+
+       if (value == (struct constant *)0)
+         desigval = "?";       /* caar(typtr->type_designator->type_list); */
+       else
+         desigval = (char *) car(value->cn_list);
+       fprintf(header,"\n\t{ %s", desigval);
+       /* find the corresponding arm of the choice */
+       bt = TNIL;
+       for (p = typtr->type_candidates; bt==TNIL && p!=NIL; p = cdr(p)) {
+               for (q = caar(p); bt==TNIL && q!=NIL; q = cdr(q)) {
+                       name = (struct object *) caar(q);
+                       if (streq(name->o_enum->en_name,desigval))
+                               bt = (struct type *) cdar(p);
+               }
+       }
+       if (bt == TNIL)
+               error(WARNING,"CHOICE designator %s is invalid here",desigval);
+       else if (bt != NilRecord_type)
+               error(WARNING,"Constants of type CHOICE are not supported");
+
+       fprintf(header,"\n\t}");
+}
+
+code_sequence_constant(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p;
+       int l;
+
+       if (value == (struct constant *)0 ||
+           (p = value->cn_list) == NIL) {
+               fprintf(header,"{0, 0}");
+               return;
+       }
+       l = length(p);
+       if (typtr->type_size < l)
+               error(WARNING,"too many constant elements specified for sequence");
+       fprintf(header,"{%d, %s}",l,value->cn_seqvalname);
+}
+
+code_record_constant(typtr, value)
+       struct type *typtr;
+       struct constant *value;
+{
+       list p, q;
+       struct constant *component;
+
+       fprintf(header,"{");
+       for (p = typtr->type_list; p != NIL; p = cdr(p)) {
+               q = car(p);
+               if (value == (struct constant *) 0)
+                 component = value;
+               else
+                 component = findcomponent((char *) caar(q), value);
+               code_constant((struct type *) cdr(q), component);
+               if (cdr(p) != NIL)
+                       fprintf(header,",");
+       }
+       fprintf(header,"\n\t}");
+}
+
diff --git a/usr/src/contrib/xns/compiler/constants.c b/usr/src/contrib/xns/compiler/constants.c
new file mode 100644 (file)
index 0000000..546b2e2
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef lint
+static char RCSid[] = "$Header: constants.c,v 2.0 85/11/21 07:21:34 jqj Exp $";
+#endif
+
+/* $Log:       constants.c,v $
+ * Revision 2.0  85/11/21  07:21:34  jqj
+ * 4.3BSD standard release
+ * 
+ * Revision 1.3  85/03/11  16:39:09  jqj
+ * *** empty log message ***
+ * 
+ * Revision 1.3  85/03/11  16:39:09  jqj
+ * Public alpha-test version, released 11 March 1985
+ * 
+ * Revision 1.2  85/02/21  11:05:02  jqj
+ * alpha test version
+ * 
+ * Revision 1.1  85/02/15  13:55:22  jqj
+ * Initial revision
+ * 
+ */
+
+/*
+ * Generate build symbol tables, etc. for constant declarations.
+ */
+
+#include "compiler.h"
+
+/*
+ * Allocate storage for constants
+ */
+struct constant *
+make_constant(constr)
+       enum constr constr;
+{
+       struct constant *c;
+
+       c = New(struct constant);
+       c->cn_constr = constr;
+       return(c);
+}
+
+
+/*
+ * Generate parse tree for simple constants -- Booleans
+ */
+struct constant *
+Boolean_constant(value)
+       char *value;
+{
+       struct constant *c;
+
+       c = make_constant(C_BOOLEAN);
+       c->cn_value = value;
+       return(c);
+}
+
+/*
+ * Generate parse tree for simple constants -- strings
+ */
+struct constant *
+String_constant(value)
+       char *value;
+{
+       struct constant *c;
+
+       c = make_constant(C_STRING);
+       c->cn_value = value;
+       return(c);
+}
+
+/*
+ * Generate parse tree for simple constants -- numeric values
+ * Note that we don't know the actual type of such constants;
+ * they are type-compatible with any numeric type.
+ */
+struct constant *
+Numeric_constant(value)
+       char *value;
+{
+       struct constant *c;
+
+       c = make_constant(C_NUMERIC);
+       c->cn_value = value;
+       return(c);
+}
+/*
+ * Generate parse tree for simple constants -- enumerations
+ * Note that we don't know the actual type of such constants;
+ * they are type-compatible with any numeric type.
+ */
+struct constant *
+enumeration_constant(value)
+       char *value;
+{
+       struct constant *c;
+
+       c = make_constant(C_ENUMERATION);
+       c->cn_value = value;
+       return(c);
+}
+
+/*
+ * Generate parse tree for complex constants -- arrays and sequences
+ * Note that we treat them all as arrays, and allow sequences to
+ * be type-compatible with arrays at declaration time.
+ */
+struct constant *
+array_constant(values)
+       list values;
+{
+       struct constant *c;
+
+       c = make_constant(C_ARRAY);
+       c->cn_list = values;
+       return(c);
+}
+
+/*
+ * Generate parse tree for complex constants -- records
+ * As a special case, NIL record constants are also type-compatible
+ * with some arrays and all sequences.
+ */
+struct constant *
+record_constant(values)
+       list values;
+{
+       struct constant *c;
+
+       c = make_constant(C_RECORD);
+       c->cn_list = values;
+       return(c);
+}
+
+/*
+ * Generate parse tree for complex constants -- choices
+ */
+struct constant *
+choice_constant(values)
+       list values;
+{
+       struct constant *c;
+
+       c = make_constant(C_CHOICE);
+       c->cn_list = values;
+       return(c);
+}