/* itest.c * Copyright 1984-2017 Cisco Systems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define r_EOF 0 #define r_LPAREN 1 #define r_RPAREN 2 #define r_CONST 3 static INT digit_value(ICHAR c, INT r) { switch (r) { case 2: if ('0' <= c && c <= '1') return c - '0'; break; case 8: if ('0' <= c && c <= '8') return c - '0'; break; case 10: if ('0' <= c && c <= '9') return c - '0'; break; case 16: if ('0' <= c && c <= '9') return c - '0'; if ('a' <= c && c <= 'f') return c - 'a'; if ('A' <= c && c <= 'F') return c - 'A'; default: break; } return -1; } static INT read_int(ptr *v, ptr n, INT r, IBOOL sign) { INT i, c; for (;;) { if ((i = digit_value((c = getchar()), r)) == -1) { ungetc(c, stdin); break; } n = S_add(S_mul(n, FIX(r)), FIX(i)); } *v = sign ? S_sub(FIX(0), n) : n; return r_CONST; } static INT read_token(ptr *v) { ICHAR c = getchar(); switch (c) { case SEOF: return r_EOF; case '\n': case ' ': return read_token(v); case ';': for (;;) { switch (getchar()) { case SEOF: return r_EOF; case '\n': return read_token(v); default: break; } } case '(': return r_LPAREN; case ')': return r_RPAREN; case '#': { ICHAR c = getchar(); INT r = 10; switch (c) { case 'x': r = 16; case 'o': if (r == 0) r = 8; case 'b': if (r == 10) r = 2; case 'd': { INT i; IBOOL sign = 0; c = getchar(); if (c == '+') c = getchar(); else if (c == '-') { sign = 1; c = getchar(); } if ((i = digit_value(c, r)) != -1) return read_int(v, FIX(i), r, sign); } default: printf("malformed hash prefix ignored\n"); return read_token(v); } } case '+': case '-': { INT i, c2; if ((i = digit_value((c2 = getchar()), 10)) == -1) { ungetc(c2, stdin); } else { return read_int(v, FIX(i), 10, c == '-'); } } case '*': case '/': case 'q': case 'r': case 'g': case '=': case '<': case 'f': case 'c': case 'd': *v = Schar(c); return r_CONST; default: { INT i; if ((i = digit_value(c, 10)) != -1) return read_int(v, FIX(i), 10, 0); } break; } printf("invalid character %d ignored\n", c); return read_token(v); } static ptr readx(INT t, ptr v); static ptr read_list(void) { INT t; ptr v, x; t = read_token(&v); if (t == r_RPAREN) return Snil; x = readx(t, v); return Scons(x, read_list()); } static ptr readx(INT t, ptr v) { switch (t) { case r_EOF: printf("unexpected EOF\n"); exit(1); case r_LPAREN: return read_list(); case r_RPAREN: printf("unexpected right paren ignored\n"); t = read_token(&v); return readx(t, v); case r_CONST: return v; default: printf("invalid token %d\n", t); exit(1); } } static ptr read_top(void) { INT t; ptr v; t = read_token(&v); switch (t) { case r_EOF: return Seof_object; case r_RPAREN: return read_top(); default: return readx(t, v); } } static ptr eval(ptr x); #define First(x) eval(Scar(Scdr(x))) #define Second(x) eval(Scar(Scdr(Scdr(x)))) static ptr eval(ptr x) { if (Spairp(x)) { switch (Schar_value(Scar(x))) { case '+': return S_add(First(x), Second(x)); case '-': return S_sub(First(x), Second(x)); case '*': return S_mul(First(x), Second(x)); case '/': return S_div(First(x), Second(x)); case 'q': return S_trunc(First(x), Second(x)); case 'r': return S_rem(First(x), Second(x)); case 'g': return S_gcd(First(x), Second(x)); case '=': { ptr x1 = First(x), x2 = Second(x); if (Sfixnump(x1) && Sfixnump(x2)) return Sboolean(x1 == x2); else if (Sbignump(x1) && Sbignump(x2)) return Sboolean(S_big_eq(x1, x2)); else return Sfalse; } case '<': { ptr x1 = First(x), x2 = Second(x); if (Sfixnump(x1)) if (Sfixnump(x2)) return Sboolean(x1 < x2); else return Sboolean(!BIGSIGN(x2)); else if (Sfixnump(x2)) return Sboolean(BIGSIGN(x1)); else return Sboolean(S_big_lt(x1, x2)); } case 'f': return Sflonum(S_floatify(First(x))); case 'c': S_gc(get_thread_context(), UNFIX(First(x)),UNFIX(Second(x))); return Svoid; case 'd': return S_decode_float(Sflonum_value(First(x))); default: S_prin1(x); putchar('\n'); printf("unrecognized operator, returning zero\n"); return FIX(0); } } else return x; } #undef PROMPT #undef NOISY static void bignum_test(void) { ptr x; for (;;) { #ifdef PROMPT putchar('*'); putchar(' '); #endif x = read_top(); if (x == Seof_object) { putchar('\n'); exit(0); } #ifdef NOISY S_prin1(x); putchar('\n'); #endif x = eval(x); S_prin1(x); putchar('\n'); } }