|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)func.c 1.3 10/19/80"; ! 4: ! 5: #include "whoami.h" ! 6: #ifdef OBJ ! 7: /* ! 8: * the rest of the file ! 9: */ ! 10: #include "0.h" ! 11: #include "tree.h" ! 12: #include "opcode.h" ! 13: ! 14: /* ! 15: * Funccod generates code for ! 16: * built in function calls and calls ! 17: * call to generate calls to user ! 18: * defined functions and procedures. ! 19: */ ! 20: funccod(r) ! 21: int *r; ! 22: { ! 23: struct nl *p; ! 24: register struct nl *p1; ! 25: register int *al; ! 26: register op; ! 27: int argc, *argv; ! 28: int tr[2], tr2[4]; ! 29: ! 30: /* ! 31: * Verify that the given name ! 32: * is defined and the name of ! 33: * a function. ! 34: */ ! 35: p = lookup(r[2]); ! 36: if (p == NIL) { ! 37: rvlist(r[3]); ! 38: return (NIL); ! 39: } ! 40: if (p->class != FUNC && p->class != FFUNC) { ! 41: error("%s is not a function", p->symbol); ! 42: rvlist(r[3]); ! 43: return (NIL); ! 44: } ! 45: argv = r[3]; ! 46: /* ! 47: * Call handles user defined ! 48: * procedures and functions ! 49: */ ! 50: if (bn != 0) ! 51: return (call(p, argv, FUNC, bn)); ! 52: /* ! 53: * Count the arguments ! 54: */ ! 55: argc = 0; ! 56: for (al = argv; al != NIL; al = al[2]) ! 57: argc++; ! 58: /* ! 59: * Built-in functions have ! 60: * their interpreter opcode ! 61: * associated with them. ! 62: */ ! 63: op = p->value[0] &~ NSTAND; ! 64: if (opt('s') && (p->value[0] & NSTAND)) { ! 65: standard(); ! 66: error("%s is a nonstandard function", p->symbol); ! 67: } ! 68: switch (op) { ! 69: /* ! 70: * Parameterless functions ! 71: */ ! 72: case O_CLCK: ! 73: case O_SCLCK: ! 74: case O_WCLCK: ! 75: case O_ARGC: ! 76: if (argc != 0) { ! 77: error("%s takes no arguments", p->symbol); ! 78: rvlist(argv); ! 79: return (NIL); ! 80: } ! 81: put1(op); ! 82: return (nl+T4INT); ! 83: case O_EOF: ! 84: case O_EOLN: ! 85: if (argc == 0) { ! 86: argv = tr; ! 87: tr[1] = tr2; ! 88: tr2[0] = T_VAR; ! 89: tr2[2] = input->symbol; ! 90: tr2[1] = tr2[3] = NIL; ! 91: argc = 1; ! 92: } else if (argc != 1) { ! 93: error("%s takes either zero or one argument", p->symbol); ! 94: rvlist(argv); ! 95: return (NIL); ! 96: } ! 97: } ! 98: /* ! 99: * All other functions take ! 100: * exactly one argument. ! 101: */ ! 102: if (argc != 1) { ! 103: error("%s takes exactly one argument", p->symbol); ! 104: rvlist(argv); ! 105: return (NIL); ! 106: } ! 107: /* ! 108: * Evaluate the argmument ! 109: */ ! 110: p1 = stkrval((int *) argv[1], NLNIL , RREQ ); ! 111: if (p1 == NIL) ! 112: return (NIL); ! 113: switch (op) { ! 114: case O_EXP: ! 115: case O_SIN: ! 116: case O_COS: ! 117: case O_ATAN: ! 118: case O_LN: ! 119: case O_SQRT: ! 120: case O_RANDOM: ! 121: case O_EXPO: ! 122: case O_UNDEF: ! 123: if (isa(p1, "i")) ! 124: convert(p1, nl+TDOUBLE); ! 125: else if (isnta(p1, "d")) { ! 126: error("%s's argument must be integer or real, not %s", p->symbol, nameof(p1)); ! 127: return (NIL); ! 128: } ! 129: put1(op); ! 130: if (op == O_UNDEF) ! 131: return (nl+TBOOL); ! 132: else if (op == O_EXPO) ! 133: return (nl+T4INT); ! 134: else ! 135: return (nl+TDOUBLE); ! 136: case O_SEED: ! 137: if (isnta(p1, "i")) { ! 138: error("seed's argument must be an integer, not %s", nameof(p1)); ! 139: return (NIL); ! 140: } ! 141: put1(op); ! 142: return (nl+T4INT); ! 143: case O_ROUND: ! 144: case O_TRUNC: ! 145: if (isnta(p1, "d")) { ! 146: error("%s's argument must be a real, not %s", p->symbol, nameof(p1)); ! 147: return (NIL); ! 148: } ! 149: put1(op); ! 150: return (nl+T4INT); ! 151: case O_ABS2: ! 152: case O_SQR2: ! 153: if (isa(p1, "d")) { ! 154: put1(op + O_ABS8-O_ABS2); ! 155: return (nl+TDOUBLE); ! 156: } ! 157: if (isa(p1, "i")) { ! 158: put1(op + (width(p1) >> 2)); ! 159: return (nl+T4INT); ! 160: } ! 161: error("%s's argument must be an integer or real, not %s", p->symbol, nameof(p1)); ! 162: return (NIL); ! 163: case O_ORD2: ! 164: if (isa(p1, "bcis") || classify(p1) == TPTR) { ! 165: return (nl+T4INT); ! 166: } ! 167: error("ord's argument must be of scalar type or a pointer, not %s", nameof(p1)); ! 168: return (NIL); ! 169: case O_SUCC2: ! 170: case O_PRED2: ! 171: if (isa(p1, "bcs")) { ! 172: put1(op); ! 173: return (p1); ! 174: } ! 175: if (isa(p1, "i")) { ! 176: if (width(p1) <= 2) ! 177: op += O_PRED24-O_PRED2; ! 178: else ! 179: op++; ! 180: put1(op); ! 181: return (nl+T4INT); ! 182: } ! 183: if (isa(p1, "id")) { ! 184: error("%s is forbidden for reals", p->symbol); ! 185: return (NIL); ! 186: } ! 187: error("%s's argument must be of scalar type, not %s", p->symbol, nameof(p1)); ! 188: return (NIL); ! 189: case O_ODD2: ! 190: if (isnta(p1, "i")) { ! 191: error("odd's argument must be an integer, not %s", nameof(p1)); ! 192: return (NIL); ! 193: } ! 194: put1(op + (width(p1) >> 2)); ! 195: return (nl+TBOOL); ! 196: case O_CHR2: ! 197: if (isnta(p1, "i")) { ! 198: error("chr's argument must be an integer, not %s", nameof(p1)); ! 199: return (NIL); ! 200: } ! 201: put1(op + (width(p1) >> 2)); ! 202: return (nl+TCHAR); ! 203: case O_CARD: ! 204: if (isnta(p1, "t")) { ! 205: error("Argument to card must be a set, not %s", nameof(p1)); ! 206: return (NIL); ! 207: } ! 208: put2(O_CARD, width(p1)); ! 209: return (nl+T2INT); ! 210: case O_EOLN: ! 211: if (!text(p1)) { ! 212: error("Argument to eoln must be a text file, not %s", nameof(p1)); ! 213: return (NIL); ! 214: } ! 215: put1(op); ! 216: return (nl+TBOOL); ! 217: case O_EOF: ! 218: if (p1->class != FILET) { ! 219: error("Argument to eof must be file, not %s", nameof(p1)); ! 220: return (NIL); ! 221: } ! 222: put1(op); ! 223: return (nl+TBOOL); ! 224: case 0: ! 225: error("%s is an unimplemented 6000-3.4 extension", p->symbol); ! 226: default: ! 227: panic("func1"); ! 228: } ! 229: } ! 230: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.