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