forked from zeotrope/anicca
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnoun.c
114 lines (100 loc) · 2.75 KB
/
noun.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "anicca.h"
#include "error.h"
#include "memory.h"
#include "char.h"
#include "table.h"
#include "convert.h"
#include "util.h"
#include "verb.h"
#include "lexer.h"
#include "noun.h"
#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].
*/
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;
}
);
end_noun:
ra(z, INT, k); AN(z) = k; R z;
}
NPARSE(base) { NPROLOG(pieul);
if (*e=='b') { ; }
R 1;
}
NPARSE(pieul) { NPROLOG(cmpx);
if (*e=='p') { ; }
else if (*e=='x') { NBODY(cmpx,times(p,expntl(q))); }
R 1;
}
NPARSE(cmpx) { NPROLOG(exp);
if (*e=='a') {
if (*e=='d') { NBODY(exp,complex(p,q)); }
else if (*e=='r') { NBODY(exp,complex(p,q)); }
}
else if (*e=='j') { NBODY(exp,complex(p,q)); }
R 1;
}
NPARSE(exp) { NPROLOG(rat);
if (*e=='e') { NBODY(rat,times(p,power(ten,q))); }
R 1;
}
NPARSE(rat) { NPROLOG(num);
if (*e=='r') { ; }
R 1;
}
NPARSE(num) { C c=**sp, *s=*sp, *d=memchr(s,'.',n), *e; A w = *y;
if (n==1&&(c==CZERO||c==CONE)) { *BAV(w)=c-CZERO; e=s+1; }
else if (d) { w=conv(FLT,w); *DAV(w)=a_strtod(n,s,&e); }
else { w=conv(INT,w); *IAV(w)=a_strtoi(n,s,&e); }
*y=w; *sp=e; R 1;
}
A parse_noun(I n, C *s) {
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] = sbool(0);
ASSERT(parse_pieul(wl,&ws,&atm),ERILLNUM);
t=MAX(at=AT(atm),t); nv[i]=atm;
);
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;
}