From 4ea811e970a0c0e7aec55d58f120616ffc9b07b4 Mon Sep 17 00:00:00 2001 From: Sami Abdin Date: Sat, 14 Aug 2010 18:04:35 -0400 Subject: [PATCH] Refactored noun parsing to use conversion functions. TODO + Numeric atom functions --- adverb.h | 4 +- anicca.c | 11 +-- anicca.h | 2 + atom.c | 11 ++- conjunction.h | 4 +- convert.c | 27 ++++-- convert.h | 16 +++- function.c | 24 +++-- function.h | 6 +- lexer.c | 105 +++++---------------- lexer.h | 8 +- memory.c | 60 ++++++------ memory.h | 24 ++--- noun.c | 247 ++++++++++++++++++++------------------------------ noun.h | 54 ++--------- parser.c | 10 +- primitive.c | 2 +- test.c | 4 +- util.c | 27 ++++-- util.h | 3 +- verb-atomic.c | 2 +- verb.c | 39 ++++---- 22 files changed, 283 insertions(+), 407 deletions(-) diff --git a/adverb.h b/adverb.h index cac41ff..9e84bd7 100644 --- a/adverb.h +++ b/adverb.h @@ -2,10 +2,10 @@ #define _ADVERB_H #define ADEF(id, f1, f2, f, l, m, r) \ - func_def(id, ADV, f1, f2, f, NULL, NULL, l, m, r, 0) + fdef(id, ADV, f1, f2, f, NULL, NULL, l, m, r, 0) #define ADERV(id, df1, df2, f, l, m, r) \ - derv_def(id, VERB, df1, df2, f, NULL, NULL, l, m, r, 0) + ddef(id, VERB, df1, df2, f, NULL, NULL, l, m, r, 0) MONAD(slash); DMONAD(insert); diff --git a/anicca.c b/anicca.c index e529b8e..013f2fa 100755 --- a/anicca.c +++ b/anicca.c @@ -15,17 +15,8 @@ #include "parser.h" #include "util.h" - I main(I argc, C *argv[]) { - C *v, str[100]; - A x, y, z; - a_init(); - while (1) { - printf(" "); - fgets(str, 100, stdin); - v = strndup(str, strlen(str)-1); /* remove carriage return */ - println(z = eval(v)); - } + a_repl(" "); return 0; } diff --git a/anicca.h b/anicca.h index 653e95a..2f84f02 100755 --- a/anicca.h +++ b/anicca.h @@ -8,6 +8,8 @@ } \ } while(0) +#define R return + typedef int I; typedef unsigned int UI; typedef char B; diff --git a/atom.c b/atom.c index cbdc573..818935f 100644 --- a/atom.c +++ b/atom.c @@ -1,5 +1,5 @@ #include - +/* #include "anicca.h" #include "noun.h" #include "atom.h" @@ -28,10 +28,11 @@ ATOMFUNC(angd) { return 1; } -ATOMFUNC(exp) { - D d = noun_dval(a); /* TODO: it could be an integer */ - DO(noun_ival(&b), d *= 10); /* TODO: negative exponents */ - a->t = FLT; +ATOMFUNC(exp) { */ +/* D d = noun_dval(a); */ /* TODO: it could be an integer */ +/* DO(noun_ival(&b), d *= 10); */ /* TODO: negative exponents */ +/* a->t = FLT; a->val.d = d; return 1; } +*/ diff --git a/conjunction.h b/conjunction.h index 987344b..f505039 100644 --- a/conjunction.h +++ b/conjunction.h @@ -2,10 +2,10 @@ #define _CONJUNCTION_H #define CDEF(id, f1, f2, f, g, l, r, m) \ - func_def(id, CONJ, f1, f2, f, g, NULL, l, r, m, 0) + fdef(id, CONJ, f1, f2, f, g, NULL, l, r, m, 0) #define CDERV(id, df1, df2, f, g, l, r, m) \ - derv_def(id, VERB, df1, df2, f, g, NULL, l, r, m, 0) + ddef(id, VERB, df1, df2, f, g, NULL, l, r, m, 0) DYAD(amper); DMONAD(bond); diff --git a/convert.c b/convert.c index 1730929..b6e3923 100644 --- a/convert.c +++ b/convert.c @@ -1,18 +1,27 @@ #include #include "anicca.h" +#include "error.h" #include "memory.h" #include "convert.h" -A convert(I t, A y) { - I yt = AT(y), yr = AR(y), yn = AN(y), *ys = AS(y); - I k = type_size(t), *iv; B *bv; D *dv; - A z = gen_array(t, yr, yn, ys); +B cbTi(I n, I *iv, B *bv) { DO(n, iv[i] = (I)bv[i]); R 1; } +B cbTd(I n, D *dv, B *bv) { DO(n, dv[i] = (D)bv[i]); R 1; } +B ciTd(I n, D *dv, I *iv) { DO(n, dv[i] = (D)iv[i]); R 1; } - switch(k = CNVCASE(yt, t)) { - case BtI: bv=BAV(y); iv=IAV(z); DO(yn, iv[i] = (I)bv[i]); break; - case BtD: bv=BAV(y); dv=DAV(z); DO(yn, dv[i] = (D)bv[i]); break; - case ItD: iv=IAV(y); dv=DAV(z); DO(yn, dv[i] = (D)iv[i]); break; +B aconv(I cv, I n, VP z, VP y) { + B *bv; I *iv; D *dv; + switch(cv) { + case BtI: bv=(B*)y; iv=(I*)z; cbTi(n,iv,bv); break; + case BtD: bv=(B*)y; dv=(D*)z; cbTd(n,dv,bv); break; + case ItD: iv=(I*)y; dv=(D*)z; ciTd(n,dv,iv); break; } - return z; + R 1; +} + +A conv(I t, A y) { + I yt = AT(y), yr = AR(y), yn = AN(y), *ys = AS(y); + A z = ga(t, yr, yn, ys); + ASSERT(aconv(CNVCASE(yt,t),yn,AV(z),AV(y)),ERDOM); + R z; } diff --git a/convert.h b/convert.h index 420538f..357c411 100644 --- a/convert.h +++ b/convert.h @@ -16,6 +16,20 @@ #define ItZ CNVCASE(INT, CMPX) #define DtZ CNVCASE(FLT, CMPX) -A convert(I t, A y); +/* + Atomic conversions + c(Argument)T(Result) + input: + n: number of elements. + v1: result. + v2: argument. + output: error code. +*/ +B cbTi(I n, I *iv, B *bv); +B cbTd(I n, D *dv, B *bv); +B ciTd(I n, D *dv, I *iv); + +B aconv(I cv, I n, VP z, VP y); +A conv(I t, A y); #endif diff --git a/function.c b/function.c index f344ec7..8044699 100644 --- a/function.c +++ b/function.c @@ -20,18 +20,16 @@ DDYAD(df2) { DMONAD(dhk) { V *v = VAV(y); - return derv_def(CHOOK, VERB, hook, hook2, y, self, NULL, VLR(v), VMR(v), \ - VRR(v), 0); + return ddef(CHOOK,VERB,hook,hook2,y,self,NULL,VLR(v),VMR(v),VRR(v),0); } DDYAD(dfrk) { V *v = VAV(x); - return derv_def(CFORK, VERB, forrk, forrk2, x, y, self, VLR(v), VMR(v), \ - VRR(v), 0); + return ddef(CFORK,VERB,forrk,forrk2,x,y,self,VLR(v),VMR(v),VRR(v),0); } /* - ado: Execute a dyadic scalar function on elements of the arguments. + ado: Execute a dyadic atomic function on elements of the arguments. input: b: xr <= yr m: minimum number of elements. @@ -65,8 +63,8 @@ VO ado(I b, I m, I n, I k, I zk, C *zv, C *xv, C *yv, SF f2) { */ A sex1(A y, I zt, SF f1) { I yt = AT(y), yr = AR(y), yn = AN(y), *ys = AS(y); - I zk = type_size(zt), k = type_size(yt); - A z = gen_array(zt, yr, yn, ys); + I zk = ts(zt), k = ts(yt); + A z = ga(zt, yr, yn, ys); C *yv = CAV(y), *zv = CAV(z); zv -= zk; yv -= k; DO(yn, f1(zv+=zk, yv+=k)); @@ -86,16 +84,16 @@ A sex1(A y, I zt, SF f1) { A sex2(A x, A y, I zt, SF f2) { I xt = AT(x), yt = AT(y), *xs = AS(x), *ys = AS(y); I xn = AN(x), yn = AN(y), xr = AR(x), yr = AR(y); - I zk = type_size(zt), k = type_size(xt); + I zk = ts(zt), k = ts(xt); I b = xr <= yr, m = b ? xn : yn, n = m ? (b ? yn : xn)/m : 0; - A z = gen_array(zt, b ? yr : xr, m*n, b ? ys : xs); + A z = ga(zt, b ? yr : xr, m*n, b ? ys : xs); C *xv = CAV(x), *yv = CAV(y), *zv = CAV(z); ado(b, m, n, k, zk, zv, xv, yv, f2); return z; } -A func_def(UC id, I t, AF1 f1, AF2 f2, A f, A g, A h, I lr, I mr, I rr, I inv) { - A z = gen_array(t, 0, 1, NULL); +A fdef(UC id, I t, AF1 f1, AF2 f2, A f, A g, A h, I lr, I mr, I rr, I inv) { + A z = ga(t, 0, 1, NULL); V *v = VAV(z); VF1(v) = f1; VF2(v) = f2; VDF1(v) = NULL; VDF2(v) = NULL; @@ -106,8 +104,8 @@ A func_def(UC id, I t, AF1 f1, AF2 f2, A f, A g, A h, I lr, I mr, I rr, I inv) { return z; } -A derv_def(UC id, I t, AF2 df1, AF3 df2, A f, A g, A h, I lr, I mr, I rr, I inv) { - A z = func_def(id, t, NULL, NULL, f, g, h, lr, mr, rr, inv); +A ddef(UC id, I t, AF2 df1, AF3 df2, A f, A g, A h, I lr, I mr, I rr, I inv) { + A z = fdef(id, t, NULL, NULL, f, g, h, lr, mr, rr, inv); V *v = VAV(z); VDF1(v) = df1; VDF2(v) = df2; return z; diff --git a/function.h b/function.h index 7156d39..055c662 100644 --- a/function.h +++ b/function.h @@ -34,7 +34,7 @@ typedef struct _verb { V *v = VAV(self); A f = VF(v), g = VG(v), h = VH(v), z; #define VDEF(id, f1, f2, l, m, r, i) \ - func_def(id, VERB, f1, f2, NULL, NULL, NULL. l, m, r, i) + fdef(id, VERB, f1, f2, NULL, NULL, NULL. l, m, r, i) DMONAD(df1); DDYAD(df2); @@ -44,7 +44,7 @@ DDYAD(dfrk); static VO ado(I b, I m, I n, I k, I zk, C *zv, C *xv, C *yv, SF f2); A sex1(A y, I zt, SF f1); A sex2(A x, A y, I zt, SF f2); -A func_def(UC id, I t, AF1 f1, AF2 f2, A f, A g, A h, I lr, I mr, I rr, I inv); -A derv_def(UC id, I t, AF2 df1, AF3 df2, A f, A g, A h, I lr, I mr, I rr, I inv); +A fdef(UC id, I t, AF1 f1, AF2 f2, A f, A g, A h, I lr, I mr, I rr, I inv); +A ddef(UC id, I t, AF2 df1, AF3 df2, A f, A g, A h, I lr, I mr, I rr, I inv); #endif diff --git a/lexer.c b/lexer.c index 9a8a758..b0f01f9 100755 --- a/lexer.c +++ b/lexer.c @@ -20,56 +20,9 @@ input: Length of string, Pointer to string. output: Array of type string with length (n-2). */ -A parse_literal(I n, C *s) { - A z = gen_array(CHAR, 1, n-=2, NULL); C *v = CAV(z); - if (n > 0) { s++; strncpy(v, s, n); } - return z; -} - -#define NCOL 3 -#define NROW 5 - -/* Noun Transition Table */ -static ST noun[NROW][NCOL] = { - /*SS*/ {{SM,ES},{SS,EO},{SX,EN}}, - /*SX*/ {{SM,EW},{SN,EW},{SA,EO}}, - /*SA*/ {{SM,EW},{SN,EW},{SA,EO}}, - /*SN*/ {{SM,ES},{SS,EO},{SX,EN}}, - /*SM*/ {{SS,ES},{SS,ES},{SS,ES}} - /* CX CS CA */ -}; - -/* - noun_start - input: Length of noun, String of noun. - output: Array of size 2n, in the form: - [start index token 1, length token 1, start index token 2, - length token 2, ..., start index token n, length token n]. -*/ -A noun_index(I n, C *s) { - C e, t, st = SS; - I i, m = 1+n, j = 0, k = 0, *v; - ST pr; - A z = gen_array(INT, 1, m, NULL); - v = IAV(z); - - DO(n, - t = nountype[s[i]]; - pr = noun[st][t]; - e = pr.effect; - st = pr.new; - - switch (e) { - case EO: break; - case EN: j = i; break; - case EW: v[k++] = j; v[k++] = i-j; break; - case ES: goto end_noun; break; - } - ); - end_noun: - resize_array(z, INT, k); - AN(z) = k; - return z; +static A parse_literal(I n, C *s) { + A z = gstr(n-=2, s++); + R z; } #define DCOL 9 @@ -96,11 +49,11 @@ static ST dfa[DROW][DCOL] = { [start index token 1, length token 1, start index token 2, length token 2, ..., start index token n, length token n]. */ -MONAD(token_index) { +static MONAD(token_index) { C e, sn, t, s = SS, vec = 0, *str = CAV(y); I i, jv, j = 0, k = 0, n = AN(y), *v; ST pr; - A z = gen_array(INT, 1, n+n, NULL); + A z = ga(INT, 1, n+n, NULL); v = IAV(z); DO(n, @@ -112,20 +65,18 @@ MONAD(token_index) { switch (e) { case EO: break; case EN: { j = i; break; } - case EW: { v[k++] = j; v[k++] = i-j; j = i; break; } + case EW: { v[k++] = j; v[k++] = i-j; j = i; break; } case EY: { v[k++] = j; v[k++] = i-j; j = -1; break; } case EV: { if (!vec) { v[k++] = j; v[k] = i-j; jv = j; } else { v[k] = i-jv; } - j = i; - vec = 1; + j = i; vec = 1; break; } case EZ: { if (!vec) { v[k++] = j; v[k] = i-j; jv = j; } else { v[k] = i-jv; } - j = -1; - vec = 1; + j = -1; vec = 1; break; } case ES: goto end; break; @@ -135,45 +86,33 @@ MONAD(token_index) { s = sn; ); end: - resize_array(z, INT, k); + ra(z, INT, k); AN(z) = k; - return z; + R z; } /* tokens input: - x: Output of token_index. y: Boxed string to be tokenized. output: Array of boxed tokens. */ -DYAD(tokens) { - C c, vn, *s, *str = CAV(y); - I j, ws, wl, t, n = AN(x)/2, *indx = IAV(x); - A v, z = gen_array(BOX, 1, n+5, NULL), *av = AAV(z); - *av++ = mark; +MONAD(tokens) { + C c, vn, *str=CAV(y), *s; + A x=token_index(y), z, v, *av; + I n=AN(x)/2, *indx=IAV(x), j, ws, wl, t; - DO(n, - j = i+i; - ws = indx[j]; - wl = indx[j+1]; - s = &str[ws]; - c = *s; - t = chartype[c]; - vn = verb_name(wl, s); - v = primitive_lookup(vn); + z = ga(BOX, 1, n+5, NULL); av = AAV(z); *av++ = mark; + + DO(n, j=i+i; ws=indx[j]; wl=indx[j+1]; + s=&str[ws]; c=*s; t=chartype[c]; + vn=verb_name(wl,s); v=primitive_lookup(vn); if (AT(v)&MARK) { switch (t) { case CS: - case C9: { - *av++ = parse_noun(wl, s); - break; - } - case CQ: { - *av++ = parse_literal(wl, s); - break; - } + case C9: { *av++ = parse_noun(wl, s); break; } + case CQ: { *av++ = parse_literal(wl, s); break; } default: break; /* error */ } } @@ -181,5 +120,5 @@ DYAD(tokens) { ); DO(4, *av++ = mark); - return z; + R z; } diff --git a/lexer.h b/lexer.h index d1f4cdd..0a327d0 100755 --- a/lexer.h +++ b/lexer.h @@ -29,10 +29,8 @@ typedef struct _state { C effect; } ST; -A parse_literal(I n, C *s); -A parse_verb(I n, C *s); -A noun_index(I n, C *s); -MONAD(token_index); -DYAD(tokens); +static A parse_literal(I n, C *s); +static MONAD(token_index); +MONAD(tokens); #endif diff --git a/memory.c b/memory.c index e6fd423..d435547 100755 --- a/memory.c +++ b/memory.c @@ -19,7 +19,7 @@ VO a_free(A y) { free(y); } -I type_size(I type) { +I ts(I type) { switch (type) { case BOOL: case CHAR: return sizeof(C); break; @@ -34,63 +34,59 @@ I type_size(I type) { return sizeof(int); } -A scalar_char(C c) { - A z; z = gen_array(CHAR, 0, 1, NULL); *CAV(z) = c; return z; -} +A schar(C c) { A z; z = ga(CHAR, 0, 1, NULL); *CAV(z) = c; R z; } -A scalar_int(I i) { - A z; z = gen_array(INT, 0, 1, NULL); *IAV(z) = i; return z; -} +A sint(I i) { A z; z = ga(INT, 0, 1, NULL); *IAV(z) = i; R z; } -A scalar_flt(D d) { - A z; z = gen_array(FLT, 0, 1, NULL); *DAV(z) = d; return z; -} +A sflt(D d) { A z; z = ga(FLT, 0, 1, NULL); *DAV(z) = d; R z; } -A gen_array(I t, I r, I n, I *s) { +A ga(I t, I r, I n, I *s) { A z = (A)a_malloc(sizeof(struct _array)); AT(z) = t; AC(z) = 1; AR(z) = r; AN(z) = n; AS(z) = s; - if (n > 0) { AV(z) = a_malloc(type_size(t)*n); } - return z; + if (n > 0) { AV(z) = a_malloc(ts(t)*n); } + R z; } -A gen_str(I n, const C *str) { - A z = gen_array(CHAR, 1, n, NULL); - memcpy(AV(z), str, n); - return z; +A gstr(I n, const C *str) { + A z; + ASSERT(n<=0,ERDOM); + if (n==1) { z = schar(*str); } + else { z = ga(CHAR, 1, n, NULL); strncpy(CAV(z), str, n); } + R z; } -A gen_iarray(I *ints, I n) { - A z = gen_array(INT, 1, n, NULL); I *zv = IAV(z); +A giarray(I *ints, I n) { + A z = ga(INT, 1, n, NULL); I *zv = IAV(z); DO(n, zv[i] = ints[i]); - return z; + R z; } -A gen_farray(D *d, I n) { +A gfarray(D *d, I n) { A z; D *zv; - z = gen_array(FLT, 1, n, NULL); + z = ga(FLT, 1, n, NULL); zv = AV(z); DO(n, zv[i] = d[i]); - return z; + R z; } -A gen_test_array(I n, ...) { +A gtest_array(I n, ...) { va_list ap; - A z = gen_array(BOX, 1, n+ 5, NULL), *zv = AAV(z); + A z = ga(BOX, 1, n+ 5, NULL), *zv = AAV(z); *zv++ = mark; va_start(ap, n); DO(n, zv[i] = va_arg(ap, A)); DO(4, zv[n+i] = mark); va_end(ap); - return z; + R z; } -A copy_array(A y) { - A z = gen_array(AT(y), AR(y), AN(y), AS(y)); - memcpy(AV(z), AV(y), AN(y)*type_size(AT(y))); - return z; +A ca(A y) { + A z = ga(AT(y), AR(y), AN(y), AS(y)); + memcpy(AV(z), AV(y), AN(y)*ts(AT(y))); + R z; } -VO resize_array(A y, I t, I n) { - AN(y) = n; AV(y) = realloc(AV(y), type_size(t)*n); +VO ra(A y, I t, I n) { + AN(y) = n; AV(y) = realloc(AV(y), ts(t)*n); } diff --git a/memory.h b/memory.h index 1b43a24..23b23f0 100755 --- a/memory.h +++ b/memory.h @@ -3,21 +3,21 @@ VP a_malloc(I n); VO a_free(A); -I type_size(I t); +I ts(I t); -A scalar_char(C c); -A scalar_int(I i); -A scalar_flt(D d); +A schar(C c); +A sint(I i); +A sflt(D d); -A gen_scalar(I t, I v); -A gen_array(I t, I r, I n, I *s); -A gen_str(I n, const C *); -A gen_iarray(I *ints, I n); -A gen_farray(D *d, I n); -A gen_test_array(I n, ...); +A gs(I t, I v); +A ga(I t, I r, I n, I *s); +A gstr(I n, const C *); +A giarray(I *ints, I n); +A gfarray(D *d, I n); +A gtest_array(I n, ...); -A copy_array(A y); -VO resize_array(A y, I t, I n); +A ca(A y); +VO ra(A y, I t, I n); #endif diff --git a/noun.c b/noun.c index 5a8e7e0..987399e 100644 --- a/noun.c +++ b/noun.c @@ -3,182 +3,127 @@ #include #include "anicca.h" -#include "char.h" #include "error.h" #include "memory.h" -#include "noun.h" -#include "atom.h" +#include "char.h" +#include "table.h" +#include "convert.h" #include "util.h" +#include "verb.h" +/*#include "atom.h"*/ +#include "lexer.h" +#include "noun.h" -NVAL(bval, B) { - NUMERIC_SWITCH(NT(a), - return NB(a), - return (B)(NI(a) != 0), - /* FIXME: floating point tolerance */ - return (B)(ND(a) != 0), - return (B)(NZ(a).real != 0) - ); - return 1; -} -NVAL(ival, I) { - NUMERIC_SWITCH(NT(a), - return (I)NB(a), - return NI(a), - return (I)ND(a), - return (I)NZ(a).real - ); - return 1; -} +#define NCOL 3 +#define NROW 5 -NVAL(dval, D) { - NUMERIC_SWITCH(NT(a), - return (D)NB(a), - return (D)NI(a), - return ND(a), - return NZ(a).real - ); - return 1; -} +/* Noun Transition Table */ +static ST noun[NROW][NCOL] = { + /*SS*/ {{SM,ES},{SS,EO},{SX,EN}}, + /*SX*/ {{SM,EW},{SN,EW},{SA,EO}}, + /*SA*/ {{SM,EW},{SN,EW},{SA,EO}}, + /*SN*/ {{SM,ES},{SS,EO},{SX,EN}}, + /*SM*/ {{SS,ES},{SS,ES},{SS,ES}} + /* CX CS CA */ +}; -NVAL(zval, Z) { - Z z = {0, 0}; - NUMERIC_SWITCH(NT(a), - z.real = (D)NB(a); break, - z.real = (D)NI(a); break, - z.real = ND(a); break, - return NZ(a) +/* + noun_start + input: Length of noun, String of noun. + output: Array of size 2n, in the form: + [start index token 1, length token 1, start index token 2, + length token 2, ..., start index token n, length token n]. +*/ +static A noun_index(I n, C *s) { + C e, t, st = SS; + I i, m = 1+n, j = 0, k = 0, *v; + ST pr; A z = ga(INT, 1, m, NULL); + v = IAV(z); + + DO(n, + t = nountype[s[i]]; + pr = noun[st][t]; + e = pr.effect; + st = pr.new; + + switch (e) { + case EO: break; + case EN: j = i; break; + case EW: v[k++] = j; v[k++] = i-j; break; + case ES: goto end_noun; break; + } ); - return z; + end_noun: + ra(z, INT, k); + AN(z) = k; + R z; } -PARSE(atom) { - N res; C *se; - se = parse_exp(n, s, &res); - *a = res; - return se; +NPARSE(base) { + parse_pieul(n,s,y); + if (*s=='b') { parse_pieul(n,s,y); } + R 1; } -PARSE(base) { - C *se; N b; B good = 1; - - se = parse_pi(n, s, a); - if (!se) return NULL; - n -= (se+1) - s; - - if (se[0]=='b') { - se = parse_pi(n, se+1, &b); - if (!se) return NULL; - good = abase(a, b); - } - return good ? se : NULL; +NPARSE(pieul) { + parse_cmpx(n,s,y); + if (*s=='p') { parse_cmpx(n,s,y); } + else if (*s=='x') { parse_cmpx(n,s,y); } + R 1; } -PARSE(pi) { - C *p, *x, *se; N b; B good = 1; - - se = parse_cmpx(n, s, a); - if (!se) return NULL; - n -= (se+1) - s; - - if (se[0]=='p') { - se = parse_cmpx(n, se+1, &b); - if (!se) return NULL; - good = apitime(a, b); +NPARSE(cmpx) { + parse_exp(n,s,y); + if (*s=='a') { s++; + if (*s=='d') { parse_exp(n,s,y); } + else if (*s=='r') { parse_exp(n,s,y); } } - else if (se[0]=='x') { - se = parse_cmpx(n, se+1, &b); - if (!se) return NULL; - good = aeuler(a, b); - } - return good ? se : NULL; + else if (*s=='j') { parse_exp(n,s,y); } + R 1; } -PARSE(cmpx) { - C *j, *r, *se; N b; B good = 1; - - se = parse_exp(n, s, a); - if (!se) return NULL; - n -= se - s; - - if (s[0]=='j') { - se = parse_exp(n-1, se+1, &b); - if (!se) return NULL; - good = acmpx(a, b); - } - else if (s[0]=='a') { - if (s[1]=='d') { - se = parse_exp(n-2, se+2, &b); - if (!se) return NULL; - good = aangd(a, b); - } - else if (s[1]=='r') { - se = parse_exp(n-2, se+2, &b); - if (!se) return NULL; - good = aangr(a, b); - } +NPARSE(exp) { + parse_rat(n,s,y); + if (*s=='e') { + ASSERT(parse_rat(n,s++,y),ERILLNUM); } - return good ? se : NULL; + R 1; } -PARSE(exp) { - C *se; N b; B good = 1; - - se = parse_num(n, s, a); - if (!se) return NULL; - n -= se - s; - - if (se[0]=='e') { - se = parse_num(n-1, se+1, &b); - if (b.t>INT) { - a_signal(ERLEXER); - return NULL; - } - good = aexp(a, b); - } - return good ? se : NULL; +NPARSE(rat) { + parse_num(n,s,y); + if (*s=='r') { parse_num(n,s,y); } + R 1; } -PARSE(num) { - C si = 0, c = *s, *d = memchr(s, '.', n), *e; - I iv; D dv; - if (c==CUNDS) { si = 1; s++; } - if (d) { - dv = strtod(s, &e); - ND(a) = si ? -dv : dv; - NT(a) = FLT; } - else { - iv = strtol(s, &e, 10); - if (!si && (iv==0 || ABS(iv)==1)) { NB(a) = (B)iv; NT(a) = BOOL; } - else { NI(a) = si ? -iv : iv; NT(a) = INT; } - } - return e; +NPARSE(num) { + C c = *s, *d=memchr(s,'.',n), *e; + I si = (*s==CUNDS) ? 1 : 0, iv; D dv; A w = *y; + if (n==1&&(c==CZERO||c==CONE)) { *BAV(w)=c-CZERO; e=s+1; } + else if (d) { w=conv(FLT,w); dv=strtod(s,&e); *DAV(w)=si ? -(dv) : dv; } + else { w=conv(INT,w); iv=strtol(s,&e,10); *IAV(w)=si ? -(iv) : iv; } + *y=w; s=e; R 1; } -/* - parse_numeric - input: Length of numeric string, Pointer to string. - output: Numeric array. -*/ A parse_noun(I n, C *s) { - I al, as, m = AN(y)/2, j, k = 0, t = 0, *indx = IAV(y), *iv; - B *bv; D *dv; Z *zv; - A y = noun_index(n+1, s), z; - N *atm, *nouns = (N *)a_malloc(sizeof(N)*m); - - DO(m, - j = i+i; as = indx[j]; al = indx[j+1]; atm = &nouns[i]; - ASSERT(parse_atom(al, &s[as], atm), ERLEXER); - t = MAX(t, NT(atm)); + B *bv; C *av, *zv, *ws; D *dv; + A y=noun_index(n+1,s), nouns, z, atm, *nv; + I m=AN(y)/2, t=0, ak, at, j, wi, wl, zk, *indx=IAV(y), *iv; + nouns = ga(BOX, 1, m, NULL); nv = AAV(nouns); + DO(m, j=i+i; wi=indx[j]; wl=indx[j+1]; ws=&s[wi]; + atm = nv[i] = ga(BOOL, 0, 1, NULL); + ASSERT(parse_num(wl,ws,&atm),ERILLNUM); + t=MAX(at=AT(atm),t); nv[i]=atm; ); - z = gen_array(t, m!=1, m, NULL); - NUMERIC_SWITCH(t, - bv = BAV(z); DO(m, bv[i] = noun_bval(&nouns[i])); break, - iv = IAV(z); DO(m, iv[i] = noun_ival(&nouns[i])); break, - dv = DAV(z); DO(m, dv[i] = noun_dval(&nouns[i])); break, - zv = ZAV(z); DO(m, zv[i] = noun_zval(&nouns[i])); break - ); - - return z; + if (m==1) { z = ca(atm); } + else { + z = ga(t, 1, m, NULL); zk = ts(t); zv = CAV(z)-zk; + DO(m, atm=nv[i]; at=AT(atm); av=CAV(atm); + if (at==t) { memcpy(zv+=zk, av, zk); } + else { aconv(CNVCASE(at,t), 1, zv+=zk, av); } + ); + } + R z; } diff --git a/noun.h b/noun.h index 6a5ac55..332bfa4 100644 --- a/noun.h +++ b/noun.h @@ -1,50 +1,16 @@ #ifndef _NOUN_H #define _NOUN_H -typedef struct _noun { - I t; - union val { - B b; - I i; - D d; - Z z; - } val; -} N; - -#define NT(n) (n->t) -#define NV(n) (n->val) -#define NB(n) (NV(n).b) -#define NI(n) (NV(n).i) -#define ND(n) (NV(n).d) -#define NZ(n) (NV(n).z) - -#define NVAL(name, t) t noun_ ## name(const N *a) - -NVAL(bval, B); -NVAL(ival, I); -NVAL(dval, D); -NVAL(zval, Z); - -/* - parse_*() functions - input: - n: length of string - s: string - output: - a: noun result of parsing - returns pointer to character after last used in parsing, - or NULL if parsing fails. -*/ -#define PARSE(name) static C* parse_ ## name(I n, C *s, N *a) - -PARSE(atom); -PARSE(base); -PARSE(pi); -PARSE(cmpx); -PARSE(exp); -PARSE(num); - +#define NPARSE(name) static B parse_ ## name(I n, C *s, A *y) + +static A noun_index(I n, C *s); +NPARSE(atom); +NPARSE(base); +NPARSE(pieul); +NPARSE(cmpx); +NPARSE(exp); +NPARSE(rat); +NPARSE(num); A parse_noun(I n, C *s); -extern A noun_index(I n, C *s); #endif diff --git a/parser.c b/parser.c index 9f16880..b147fcb 100644 --- a/parser.c +++ b/parser.c @@ -42,7 +42,7 @@ A parse(A tokens) { do { top = &stack[j]; - /* printf("m: %d j: %d ", m, j); print(tokens); */ + /*printf("m: %d j: %d ", m, j); print(tokens);*/ for (c=0; c=0 && m>2); - /* printf("m: %d j: %d\n", m, j); */ - /* println(tokens); */ + /*printf("m: %d j: %d\n", m, j); + println(tokens);*/ if (m>2) { a_signal(ERSYNTX); }; z = stack[j]; diff --git a/primitive.c b/primitive.c index d76165c..6043684 100644 --- a/primitive.c +++ b/primitive.c @@ -206,7 +206,7 @@ A primitive_lookup(UC id) { case NOUN: break; case ADV: case VERB: - case CONJ: return func_def(id, t, p->f1, p->f2, NULL, NULL, NULL, \ + case CONJ: return fdef(id, t, p->f1, p->f2, NULL, NULL, NULL, \ p->lr, p->mr, p->rr, p->inv); case LPAR: return lpar; case RPAR: return rpar; diff --git a/test.c b/test.c index bc54f72..b86a98c 100644 --- a/test.c +++ b/test.c @@ -59,6 +59,6 @@ VO testcases_init(VO) { D e0[] = { 1.5, 900, 3 }; I e1[] = { 1 }; - testcases[0].expected = gen_test_array(3, lpar, gen_farray(e0, LENGTHOF(e0)), rpar); - testcases[1].expected = gen_test_array(1, gen_iarray(e1, LENGTHOF(e1))); + testcases[0].expected = gtest_array(3, lpar, gfarray(e0, LENGTHOF(e0)), rpar); + testcases[1].expected = gtest_array(1, giarray(e1, LENGTHOF(e1))); } diff --git a/util.c b/util.c index d51b78a..cc30af8 100644 --- a/util.c +++ b/util.c @@ -52,18 +52,27 @@ VO println(A y) { } VO a_init(VO) { - zero = scalar_int(0); one = scalar_int(1); - mark = gen_array(MARK, 0, 0, NULL); - lpar = gen_array(LPAR, 0, 0, NULL); - rpar = gen_array(RPAR, 0, 0, NULL); + zero = sint(0); one = sint(1); + mark = ga(MARK, 0, 0, NULL); + lpar = ga(LPAR, 0, 0, NULL); + rpar = ga(RPAR, 0, 0, NULL); } A eval(const C *str) { - A w, x, y, z; - w = gen_str(strlen(str)+1, str); - x = token_index(w); - y = tokens(x, w); + A w, y, z; + w = gstr(strlen(str)+1, str); + y = tokens(w); z = parse(y); - a_free(w); a_free(x); a_free(y); + a_free(w); a_free(y); return z; } + +VO a_repl(const C *s) { + C *v, str[100]; A z; + while (1) { + printf(s, "%s\n"); + fgets(str, 100, stdin); + v = strndup(str, strlen(str)-1); /* remove carriage return */ + println(z = eval(v)); + } +} diff --git a/util.h b/util.h index 5095604..82b869c 100644 --- a/util.h +++ b/util.h @@ -28,7 +28,7 @@ case LPAR: { lpar; break; } \ case RPAR: { rpar; break; } \ default: { def; break; } \ - } +} #define LENGTHOF(array) (sizeof(array)/sizeof(*array)) @@ -37,5 +37,6 @@ VO println(A y); VO a_init(VO); C *strndup(const C *s, UI n); A eval(const C *str); +VO a_repl(const C *str); #endif diff --git a/verb-atomic.c b/verb-atomic.c index 80c3e33..882b2b3 100644 --- a/verb-atomic.c +++ b/verb-atomic.c @@ -72,6 +72,6 @@ A va2(C id, A x, A y) { SF f2 = vd->f; A z; ASSERT(xt&NUMERIC&&yt&NUMERIC, ERDOM); cv = vd->cv; at = atype(cv); rt = rtype(cv); - z = sex2(xt==at ? x : convert(at, x), yt==at ? y : convert(at, y), rt, f2); + z = sex2(xt==at ? x : conv(at, x), yt==at ? y : conv(at, y), rt, f2); return z; } diff --git a/verb.c b/verb.c index 9e94b8d..daf76bd 100755 --- a/verb.c +++ b/verb.c @@ -7,6 +7,7 @@ #include "char.h" #include "error.h" #include "memory.h" +#include "convert.h" #include "function.h" #include "verb.h" #include "verb-scalar1.h" @@ -16,7 +17,7 @@ MONAD(fact) { MONAD_PROLOG; I temp, r; ASSERT(AT(y)&INT, ERDOM); - z = gen_array(INT, AR(y), yn, AS(y)); + z = ga(INT, AR(y), yn, AS(y)); v = IAV(z); DO(yn, r = 1; temp = yv[i]; DO(temp, r *= temp--); @@ -30,13 +31,13 @@ DYAD(outof) { A z; return z; } -MONAD(tally) { A z; z = scalar_int(AN(y)); return z; } +MONAD(tally) { A z; z = sint(AN(y)); return z; } DYAD(copy) { DYAD_PROLOG; I n = 0, itm, cnt; ASSERT(xn==yn, ERLEN ); DO(xn, n += xv[i]); - z = gen_array(INT, AR(y), n, AS(y)); + z = ga(INT, AR(y), n, AS(y)); v = IAV(z); DO(xn, cnt = xv[i]; itm = yv[i]; if (cnt>0) { DO(cnt, *v++ = itm); } @@ -50,7 +51,7 @@ DYAD(divide) { A z = va2(CPERC, x, y); return z; } MONAD(signum) { A z; switch (AT(y)) { - case BOOL: z = copy_array(y); break; + case BOOL: z = ca(y); break; case INT: z = sex1(y, INT, isignum); break; case FLT: z = sex1(y, INT, dsignum); break; } @@ -70,12 +71,18 @@ DYAD(plus) { A z = va2(CPLUS, x, y); return z; } MONAD(duble) { A z = plus(y, y); return z; } DYAD(append) { - I xt = AT(x), yt = AT(y), xn = AN(x), yn = AN(y), zn = yn + xn, k; - C *xv = CAV(x), *yv = CAV(y), *v; - A z; + I xt=AT(x), yt=AT(y), xr=AR(x), yr=AR(y); + I xn=AN(x), yn=AN(y), *xs=AS(x), *ys=AS(y); + I t=MAX(xt,yt), r=MAX(xr,yr), zn=yn+xn, k; + C *xv, *yv, *v; A p=x, q=y, z; + if (xt&NUMERIC&&yt&NUMERIC && (xt!=yt)) { + if (xt>yt) { q=conv(t, y); yt=t; } + else { p=conv(t, x); xt=t; } + } + xv=CAV(p); yv=CAV(q); if (xt==yt) { - z = gen_array(yt, AR(y), zn, AS(y)); - v = CAV(z); k = type_size(yt); + z = ga(t, r=(r!=0?r:1), zn, xr>yr ? xs : ys); + v=CAV(z); k=ts(t); memcpy(v, xv, k*xn); v += k*xn; memcpy(v, yv, k*yn); @@ -93,7 +100,7 @@ DYAD(link) { A z; return z; } -MONAD(box) { A z = gen_array(BOX, 0, 1, NULL); *AAV(z) = y; return z; } +MONAD(box) { A z = ga(BOX, 0, 1, NULL); *AAV(z) = y; return z; } DYAD(lthan) { A z = va2(CLT, x, y); return z; } @@ -118,31 +125,31 @@ DYAD(deal) { } MONAD(indices) { MONAD_PROLOG; - z = gen_array(INT, AR(y), yn, AS(y)); + z = ga(INT, AR(y), yn, AS(y)); v = IAV(z); return z; } MONAD(expntl) { I yn = AN(y), *yv = IAV(y); - A z = gen_array(FLT, AR(y), yn, AS(y)); D *v = DAV(z); + A z = ga(FLT, AR(y), yn, AS(y)); D *v = DAV(z); DO(yn, v[i] = exp((D)yv[i])); return z; } MONAD(iota) { A z; I yr = AR(y), n = *IAV(y), *v; - z = gen_array(INT, 1, n, AS(y)); + z = ga(INT, 1, n, AS(y)); v = IAV(z); DO(n, v[i] = i); return z; } -MONAD(same) { A z = copy_array(y); return z; } +MONAD(same) { A z = ca(y); return z; } -DYAD(left) { A z = copy_array(x); return z; } +DYAD(left) { A z = ca(x); return z; } -DYAD(right) { A z = copy_array(y); return z; } +DYAD(right) { A z = ca(y); return z; } DYAD(residue) { A z; return z;