Annotation of 43BSD/contrib/xns/compiler/procedures.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char RCSid[] = "$Header: procedures.c,v 2.0 85/11/21 07:21:43 jqj Exp $";
        !             3: #endif
        !             4: 
        !             5: /* $Log:       procedures.c,v $
        !             6:  * Revision 2.0  85/11/21  07:21:43  jqj
        !             7:  * 4.3BSD standard release
        !             8:  * 
        !             9:  * Revision 1.5  85/05/06  08:13:31  jqj
        !            10:  * *** empty log message ***
        !            11:  * 
        !            12:  * Revision 1.5  85/05/06  08:13:31  jqj
        !            13:  * Almost Beta-test version.
        !            14:  * 
        !            15:  * Revision 1.4  85/03/26  06:10:21  jqj
        !            16:  * Revised public alpha-test version, released 26 March 1985
        !            17:  * 
        !            18:  * Revision 1.3  85/03/11  16:39:55  jqj
        !            19:  * Public alpha-test version, released 11 March 1985
        !            20:  * 
        !            21:  * Revision 1.2  85/02/21  11:05:39  jqj
        !            22:  * alpha test version
        !            23:  * 
        !            24:  * Revision 1.1  85/02/15  13:55:36  jqj
        !            25:  * Initial revision
        !            26:  * 
        !            27:  */
        !            28: 
        !            29: #define argname(p)     ((char *) car(caar(p)))
        !            30: #define argtype(p)     ((struct type *) cdar(p))
        !            31: 
        !            32: /*
        !            33:  * routines for generating procedures and errors
        !            34:  */
        !            35: 
        !            36: #include "compiler.h"
        !            37: 
        !            38: /*
        !            39:  * Generate client and server functions for procedure declarations.
        !            40:  */
        !            41: define_procedure_constant(symbol,typtr,value)
        !            42:        struct object *symbol;
        !            43:        struct type *typtr;
        !            44:        struct constant *value;
        !            45: {
        !            46:        struct type *resulttype;
        !            47:        char *procvalue;
        !            48:        char * resultname;
        !            49:        char buf[MAXSTR];
        !            50:        list p, q;
        !            51: 
        !            52:        if (recursive_flag)     /* don't bother to do anything for procs */
        !            53:                return;         /* in DEPENDS UPON modules */
        !            54:        if (typtr->type_constr != C_PROCEDURE)
        !            55:                error(FATAL, "internal error (define_procedure): not a procedure");
        !            56:        if (value->cn_constr != C_NUMERIC) {
        !            57:                error(ERROR,"Values of procedure constants must be numeric");
        !            58:                procvalue = "-1";
        !            59:        }
        !            60:        else
        !            61:                procvalue = value->cn_value;
        !            62:        /*
        !            63:         * RETURNS stuff:  coerce the result to be a single record
        !            64:         */
        !            65:        if (length(typtr->type_results) > 0) {
        !            66:                struct object *resultobj;
        !            67: 
        !            68:                resulttype = record_type(typtr->type_results);
        !            69:                sprintf(buf,"%sResults",name_of(symbol));
        !            70:                resultname = copy(buf);
        !            71:                resultobj = make_symbol(resultname,CurrentProgram);
        !            72:                define_type(resultobj, resulttype);
        !            73:                /* replaces define_record_type(resulttype); */
        !            74:                typtr->type_results = cons( cons( cons((list)resultname, NIL),
        !            75:                                                  (list)resulttype), 
        !            76:                                            NIL);
        !            77:        }
        !            78:        /*
        !            79:         * REPORTS stuff:  check here to make sure the errors are all defined
        !            80:         */
        !            81:        for (p = typtr->type_errors, q = NIL; p != NIL; q = p, p = cdr(p)) {
        !            82:                struct object *sym;
        !            83:                sym = check_def((char *)car(p),CurrentProgram);
        !            84:                if (sym == (struct object *)0) {
        !            85:                        error(ERROR,"Error constant %s not defined",
        !            86:                                (char*)car(p));
        !            87:                        if (q == NIL) typtr->type_errors = cdr(p);
        !            88:                        else cdr(q) = cdr(p);
        !            89:                }
        !            90:                else if (sym->o_class != O_CONSTANT
        !            91:                    || sym->o_constant->cn_constr != C_ERROR) {
        !            92:                        error(ERROR,"Symbol %s is not of appropriate type",
        !            93:                                name_of(sym));
        !            94:                        if (q == NIL) typtr->type_errors = cdr(p);
        !            95:                        else cdr(q) = cdr(p);
        !            96:                }
        !            97:        }
        !            98:        /*
        !            99:         * Argument stuff:  make sure all the argument types are defined
        !           100:         */
        !           101:        for (p = typtr->type_args; p != NIL; p = cdr(p)) {
        !           102:                if (typename(argtype(p)) == NULL) {
        !           103:                        struct object *name;
        !           104:                        name = make_symbol(gensym("T_p"),CurrentProgram);
        !           105:                        define_type(name,argtype(p));
        !           106:                }
        !           107:        }
        !           108:        /*
        !           109:         * Actually generate code for this procedure
        !           110:         */
        !           111:        proc_functions(symbol->o_constant->cn_name, typtr, procvalue);
        !           112:        /*
        !           113:         * Save this procedure on the global procs for wrapup (server 
        !           114:         * dispatch code)
        !           115:         */
        !           116:        Procedures = cons(cons( (list)symbol->o_constant->cn_name,
        !           117:                                (list)procvalue ),
        !           118:                          Procedures);
        !           119: }
        !           120: 
        !           121: 
        !           122: /*
        !           123:  * Generate funcions for client and server calls to a procedure.
        !           124:  */
        !           125: proc_functions(proc_name, type, proc_number)
        !           126:        char *proc_name;
        !           127:        struct type *type;
        !           128:        char *proc_number;
        !           129: {
        !           130:        list p;
        !           131:        int nresults, fixed_size, variable_size;
        !           132:        struct type *t, *bt, *result_type;
        !           133:        char *result_name, *ref, *rtname;
        !           134: 
        !           135:        /*
        !           136:         * Make sure there is at most one result returned.
        !           137:         */
        !           138:        nresults = length(type->type_results);
        !           139:        if (nresults > 1) {
        !           140:                error(ERROR, "procedures that return multiple results are not supported");
        !           141:                return;
        !           142:        }
        !           143:        if (nresults) {
        !           144:                result_name = "_Results";
        !           145:                result_type = argtype(type->type_results);
        !           146:                rtname = typename(result_type);
        !           147:        } else {
        !           148:                rtname = "void";
        !           149:        }
        !           150: 
        !           151:        /*
        !           152:         * Server routine.
        !           153:         */
        !           154: 
        !           155:        fprintf(server, "\nextern %s %s();\n", rtname, proc_name);
        !           156:        fprintf(server,
        !           157: "\nserver_%s(_buf)\n\
        !           158: \tregister Unspecified *_buf;\n\
        !           159: {\n\
        !           160: \tregister Unspecified *_bp = _buf;\n\
        !           161: \tregister LongCardinal _n;\n",
        !           162:                proc_name);
        !           163:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           164:                t = argtype(p);
        !           165:                fprintf(server, "\t%s %s;\n", typename(t), argname(p));
        !           166:        }
        !           167:        if (nresults)
        !           168:                fprintf(server, "\t%s %s;\n", rtname, result_name);
        !           169:        fprintf(server, "\n");
        !           170:        /*
        !           171:         * Generate code to internalize the arguments.
        !           172:         */
        !           173:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           174:                t = argtype(p);
        !           175:                ref = refstr(t);
        !           176:                fprintf(server, "\t_bp += %s(%s%s, _bp);\n",
        !           177:                        xfn(INTERNALIZE, t), ref, argname(p));
        !           178:        }
        !           179:        /*
        !           180:         * Generate code to call the procedure.
        !           181:         */
        !           182:        if (nresults)
        !           183:                fprintf(server, "\t%s = %s(_serverConnection, 0",
        !           184:                        result_name, proc_name);
        !           185:        else
        !           186:                fprintf(server, "\t%s(_serverConnection, 0", proc_name);
        !           187:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           188:                fprintf(server, ", %s", argname(p));
        !           189:        }
        !           190:        fprintf(server, ");\n");
        !           191:        /*
        !           192:         * Generate code to externalize the result.
        !           193:         */
        !           194:        if (nresults) {
        !           195:                ref = refstr(result_type);
        !           196:                fprintf(server,
        !           197: "\t_n = sizeof_%s(%s%s);\n\
        !           198: \t_bp = Allocate(_n);\n\
        !           199: \t%s(%s%s, _bp);\n\
        !           200: \tSendReturnMessage(_n, _bp);\n\
        !           201: \tDeallocate(_bp);\n\
        !           202: }\n",
        !           203:                        rtname, ref, result_name,
        !           204:                        xfn(EXTERNALIZE, result_type), ref, result_name);
        !           205:        } else
        !           206:                fprintf(server,"}\n"    );
        !           207: 
        !           208:        /*
        !           209:         * Stub routine for client.
        !           210:         */
        !           211: 
        !           212:        fprintf(header, "\nextern %s %s();\n",
        !           213:                rtname, proc_name);
        !           214:        fprintf(client,
        !           215: "\n\
        !           216: %s\n\
        !           217: %s(_Connection, _BDTprocptr",
        !           218:                rtname, proc_name);
        !           219:        for (p = type->type_args; p != NIL; p = cdr(p))
        !           220:                fprintf(client, ", %s", argname(p));
        !           221:        fprintf(client, ")\n\
        !           222: \tCourierConnection *_Connection;\n\
        !           223: \tint (*_BDTprocptr)();\n\
        !           224: "
        !           225:                );
        !           226:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           227:                t = argtype(p);
        !           228:                fprintf(client, "\t%s %s;\n", typename(t), argname(p));
        !           229:        }
        !           230:        fprintf(client, "{\n");
        !           231:        if (nresults)
        !           232:                fprintf(client, "\t%s %s;\n", rtname, result_name);
        !           233:        fprintf(client,
        !           234: "\tregister Unspecified *_buf, *_bp;\n\
        !           235: \tBoolean _errorflag;\n\
        !           236: \tCardinal _errtype;\n"
        !           237:                );
        !           238:        /*
        !           239:         * Determine the size of the arguments.
        !           240:         * This is like the code in record_type().
        !           241:         */
        !           242:        fixed_size = 0;
        !           243:        variable_size = 0;
        !           244:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           245:                bt = argtype(p);
        !           246:                if (bt->type_xsize == -1) {
        !           247:                        variable_size = 1;
        !           248:                } else {
        !           249:                        fixed_size += bt->type_xsize;
        !           250:                }
        !           251:        }
        !           252:        if (!variable_size) {
        !           253:                /*
        !           254:                 * The argument list is fixed-size.
        !           255:                 */
        !           256:                fprintf(client,
        !           257: "\n\
        !           258: \t_buf = Allocate(%d);\n",
        !           259:                        fixed_size);
        !           260:        } else {
        !           261:                /*
        !           262:                 * There are some variable-size arguments.
        !           263:                 */
        !           264:                fprintf(client,
        !           265: "\tregister LongCardinal _n = %d;\n\
        !           266: \n",
        !           267:                        fixed_size);
        !           268:                for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           269:                        t = argtype(p);
        !           270:                        bt = t;
        !           271:                        if (bt->type_xsize != -1)
        !           272:                                continue;
        !           273:                        ref = refstr(bt);
        !           274:                        fprintf(client,
        !           275: "\t_n += sizeof_%s(%s%s);\n",
        !           276:                                typename(t), ref, argname(p));
        !           277:                }
        !           278:                fprintf(client,
        !           279: "\t_buf = Allocate(_n);\n"
        !           280:                        );
        !           281:        }
        !           282:        fprintf(client,
        !           283: "\t_bp = _buf;\n"
        !           284:                );
        !           285:        /*
        !           286:         * Generate code to externalize the arguments.
        !           287:         */
        !           288:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           289:                t = argtype(p);
        !           290:                ref = refstr(t);
        !           291:                fprintf(client, "\t_bp += %s(%s%s, _bp);\n",
        !           292:                        xfn(EXTERNALIZE, t), ref, argname(p));
        !           293:        }
        !           294:        if (!variable_size) {
        !           295:                fprintf(client,
        !           296: "\tSendCallMessage(_Connection, %d, %d, %s, %d, _buf);\n",
        !           297:                        CurrentNumber, CurrentVersion,
        !           298:                        proc_number, fixed_size);
        !           299:        } else {
        !           300:                fprintf(client,
        !           301: "\tSendCallMessage(_Connection, %d, %d, %s, _n, _buf);\n",
        !           302:                        CurrentNumber, CurrentVersion,
        !           303:                        proc_number);
        !           304:        }
        !           305:        fprintf(client,
        !           306: "\tDeallocate(_buf);\n\
        !           307: \tMaybeCallBDTHandler(_Connection, _BDTprocptr);\n"
        !           308:                );
        !           309:        /*
        !           310:         * Generate code to receive the results and interpret them
        !           311:         * as errors
        !           312:         */
        !           313:        fprintf(client,
        !           314: "\t_bp = ReceiveReturnMessage(_Connection, &_errorflag);\n\
        !           315: \t_buf = _bp;\n\
        !           316: \tif (_errorflag) {\n\
        !           317: \t\t_bp += %s(&_errtype, _bp);\n\
        !           318: \t\tswitch (ERROR_OFFSET+_errtype) {\n",
        !           319:                xfn(INTERNALIZE, Cardinal_type)
        !           320:                        );
        !           321:        for (p = type->type_errors; p != NIL; p = cdr(p)) {
        !           322:                struct constant *errconst;
        !           323:                struct type *errtype;
        !           324:                errconst = (check_def((char *)car(p),CurrentProgram))->o_constant;
        !           325:                errtype = (struct type *) cdr(errconst->cn_list);
        !           326:                if (errtype == TNIL)
        !           327:                        fprintf(client,
        !           328: "\t\tcase %s:\n\
        !           329: \t\t\traise(ERROR_OFFSET+_errtype, 0);\n\
        !           330: \t\t\t/*NOTREACHED*/\n",
        !           331:                                errconst->cn_name);
        !           332:                else
        !           333:                        fprintf(client,
        !           334: "\t\tcase %s: {\n\
        !           335: \t\t\tstatic %s _result;\n\
        !           336: \t\t\t_bp += %s(%s_result, _bp);\n\
        !           337: \t\t\traise(ERROR_OFFSET+_errtype, (char *) &_result);\n\
        !           338: \t\t\t/*NOTREACHED*/\n\
        !           339: \t\t\t}\n",
        !           340:                                errconst->cn_name,
        !           341:                                typename(errtype),
        !           342:                                xfn(INTERNALIZE, errtype), refstr(errtype)
        !           343:                                );
        !           344:        }
        !           345:        fprintf(client,
        !           346: "\t\tdefault:\n\
        !           347: \t\t\t/* don't know how to unpack this */\n\
        !           348: \t\t\traise(ERROR_OFFSET+_errtype, 0);\n\
        !           349: \t\t\t/*NOTREACHED*/\n\
        !           350: \t\t}\n"
        !           351:                );
        !           352:        /*
        !           353:         * Code to unpack results and return
        !           354:         */
        !           355:        if (nresults)
        !           356:                fprintf(client,
        !           357: "\t} else\n\
        !           358: \t\t_bp += %s(%s%s, _bp);\n\
        !           359: \tDeallocate(_buf);\n\
        !           360: \treturn (%s);\n\
        !           361: }\n",
        !           362:                        xfn(INTERNALIZE, result_type),
        !           363:                        refstr(result_type), result_name, result_name);
        !           364:        else
        !           365:                fprintf(client,
        !           366: "\t}\n\
        !           367: \tDeallocate(_buf);\n\
        !           368: }\n");
        !           369: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.