BSD 3 development
authorCharles B. Haley <cbh@research.uucp>
Fri, 9 Nov 1979 10:25:31 +0000 (02:25 -0800)
committerCharles B. Haley <cbh@research.uucp>
Fri, 9 Nov 1979 10:25:31 +0000 (02:25 -0800)
Work on file usr/src/cmd/pi/call.c

Co-Authored-By: Bill Joy <wnj@ucbvax.Berkeley.EDU>
Co-Authored-By: Ken Thompson <ken@research.uucp>
Synthesized-from: 3bsd

usr/src/cmd/pi/call.c [new file with mode: 0644]

diff --git a/usr/src/cmd/pi/call.c b/usr/src/cmd/pi/call.c
new file mode 100644 (file)
index 0000000..7aba9c5
--- /dev/null
@@ -0,0 +1,102 @@
+/* Copyright (c) 1979 Regents of the University of California */
+#
+/*
+ * pi - Pascal interpreter code translator
+ *
+ * Charles Haley, Bill Joy UCB
+ * Version 1.2 November 1978
+ */
+
+#include "whoami"
+#include "0.h"
+#include "tree.h"
+#include "opcode.h"
+
+/*
+ * Call generates code for calls to
+ * user defined procedures and functions
+ * and is called by proc and funccod.
+ * P is the result of the lookup
+ * of the procedure/function symbol,
+ * and porf is PROC or FUNC.
+ * Psbn is the block number of p.
+ */
+struct nl *
+call(p, argv, porf, psbn)
+       struct nl *p;
+       int *argv, porf, psbn;
+{
+       register struct nl *p1, *q;
+       int *r;
+
+       if (porf == FUNC)
+               /*
+                * Push some space
+                * for the function return type
+                */
+               put2(O_PUSH, even(-width(p->type)));
+       /*
+        * Loop and process each of
+        * arguments to the proc/func.
+        */
+       for (p1 = p->chain; p1 != NIL; p1 = p1->chain) {
+               if (argv == NIL) {
+                       error("Not enough arguments to %s", p->symbol);
+                       return (NIL);
+               }
+               switch (p1->class) {
+                       case REF:
+                               /*
+                                * Var parameter
+                                */
+                               r = argv[1];
+                               if (r != NIL && r[0] != T_VAR) {
+                                       error("Expression given (variable required) for var parameter %s of %s", p1->symbol, p->symbol);
+                                       break;
+                               }
+                               q = lvalue( (int *) argv[1], MOD);
+                               if (q == NIL)
+                                       break;
+                               if (q != p1->type) {
+                                       error("Parameter type not identical to type of var parameter %s of %s", p1->symbol, p->symbol);
+                                       break;
+                               }
+                               break;
+                       case VAR:
+                               /*
+                                * Value parameter
+                                */
+                               q = rvalue(argv[1], p1->type);
+                               if (q == NIL)
+                                       break;
+                               if (incompat(q, p1->type, argv[1])) {
+                                       cerror("Expression type clashed with type of value parameter %s of %s", p1->symbol, p->symbol);
+                                       break;
+                               }
+                               if (isa(p1->type, "bcsi"))
+                                       rangechk(p1->type, q);
+                               if (q->class != STR)
+                                       convert(q, p1->type);
+                               break;
+                       default:
+                               panic("call");
+               }
+               argv = argv[2];
+       }
+       if (argv != NIL) {
+               error("Too many arguments to %s", p->symbol);
+               rvlist(argv);
+               return (NIL);
+       }
+       put2(O_CALL | psbn << 9, p->entloc);
+       put2(O_POP, p->value[NL_OFFS]-DPOFF2);
+       return (p->type);
+}
+
+rvlist(al)
+       register int *al;
+{
+
+       for (; al != NIL; al = al[2])
+               rvalue( (int *) al[1], NLNIL);
+}