Adverbs and Conjunctions
An Implementation of J
An adverb is monadic, applying to a noun or verb argument on its left;
a conjunction is dyadic, applying to noun or verb arguments on its
left and right. The result is usually a verb, but can also
be a noun, adverb, or conjunction.
The conjunction & is used here to illustrate the relationship
between relevant system components.
(The implementation of adverbs is similar.)
& derives a verb depending on whether the arguments are
nouns (m and n) or
verbs (u and v):
m&n gerund join
m&v m&v y is m v y
u&n u&n y is y v n
u&v u&v y is u v y; x u&v y is (v x) u (v y)
A verb defined from & is (internally) an
array of type VERB
whose value is interpreted according to the defined
type V in file jtype.h:
typedef struct {AF f1,f2;A f,g,h;I flag,mr,lr,rr;C id;} V;
|
f1 | monad |
| f2 | dyad |
| f | left conjunction argument or adverb argument |
| g | right conjunction argument |
| h | auxiliary argument |
| flag | bit flags |
| mr | monadic rank |
| lr | left rank |
| rr | right rank |
| id | ID byte |
If fn=: %.&|:, the arrays would be:
k flag m t c n r
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬
fn │ 28│ 0│ 8│ VERB│ 3│ 1│ 0│...
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴
┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
...│ on1│ on2│ %.│ |:│ 0│ 0│ _│ _│ _│& │
┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
f1 f2 f g h flag mr lr rr id
k flag m t c n r
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬
%. │ 28│ 0│ 8│ VERB│ _│ 1│ 0│...
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴
┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
...│ minv│ mdiv│ 0│ 0│ 0│ 0│ 2│ _│ 2│%. │
┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
f1 f2 f g h flag mr lr rr id
k flag m t c n r
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬
|: │ 28│ 0│ 8│ VERB│ _│ 1│ 0│...
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴
┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
...│cant1│cant2│ 0│ 0│ 0│ 0│ _│ 1│ _│|: │
┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
f1 f2 f g h flag mr lr rr id
Access to the parts of fn is by name and by macros defined in files jt.h
and a.h, and never by offsets and indices.
Thus AV(fn) points to the value part of fn.
And if sv=(V*)AV(fn),
then sv->f1 is on1;
sv->f2 is on2;
sv->f is the array for %.;
sv->g is the array for |:
(that is, sv->f and sv->g are
arrays similar to fn);
sv->mr is _ (indicating
that fn has infinite monadic rank); and so on.
The macro VAV(f), defined
as ((V*)AV(f)),
is useful for working with adverbs and conjunctions.
To introduce & into the system, functions which
implement & are added
to file c.c (or one of the c*.c files), and declarations of
global objects are added to file je.h:
File c.c:
static CS1(on1, CALL2(f1,CALL2(g1,w,gs),fs))
static CS2(on2, CALL3(f2,CALL2(g1,a,gs),CALL2(g1,w,gs),fs))
static DF1(withl){DECLFG; R jt->rank?irs2(fs,w,gs,AR(fs),jt->rank[1],g2):CALL3(g2,fs,w,gs);}
static DF1(withr){DECLFG; R jt->rank?irs2(w,gs,fs,jt->rank[1],AR(gs),f2):CALL3(f2,w,gs,fs);}
F2(jtamp){I m;
RZ(a&&w);
switch(CONJCASE(a,w)){
default: ASSERTSYS(0,"amp");
case NN: R gjoin(CAMP,a,w);
case NV: R CDERIV(CAMP,withl,0L,RMAX,RMAX,RMAX);
case VN: R CDERIV(CAMP,withr,0L,RMAX,RMAX,RMAX);
case VV: m=mr(w); R CDERIV(CAMP,ID(a)==CSLASH&&ID(w)==CCOMMA?jtredravel:on1,on2,m,m,m);
}}
File je.h:
extern F2(jtamp);
Corresponding to the four possibilities, amp defines
four cases. (The impossible default case is to
obviate a spurious C compiler warning.)
The functions withl, withr, on1,
and on2 are applied when a verb derived from & is applied.
The VV case also recognizes u/&, as a special case,
whereby redravel is applied instead of on1.
For the example in question, %.&|: m=: ?4 4$100 first
branches to the case VV in amp, and
subsequently applies on1 to m.
Consider a partial macro expansion of on1 and the
values of its local variables:
Macro Expansion:
static A on1(J jt,A w,A self){PROLOG;V*sv=VAV(self);
A fs=sv->f;AF f1=fs?VAV(fs)->f1:0,f2=fs?VAV(fs)->f2:0;
A gs=sv->g;AF g1=gs?VAV(gs)->f1:0,g2=gs?VAV(gs)->f2:0; A z;
PREF1(on1);
z=f1(jt,g1(jt,w,gs),fs);
EPILOG(z);
}
Local Variables:
|
w |
the matrix m |
|
self |
the verb fn |
|
sv |
pointer to the value part of fn as an array |
|
fs |
left argument to &, that is %. |
|
f1 |
monad of %. |
|
f2 |
dyad of %. |
|
gs |
right argument to &, that is |: |
|
g1 |
monad of |: |
|
g2 |
dyad of |: |
The initialization of sv, fs, f1,
and so on are the same
for all adverbs and conjunctions; the details of such
initialization are normally suppressed by the use of macros.
If an argument to & (i.e. fs or gs)
is itself a result
of adverbs and conjunctions, expressions such as g1(jt,w,gs)
or f1(jt,xxx,gs) engender further executions
as occurs in on1.
The macro PREF1 implements
rank,
and the macros PROLOG
and EPILOG manage memory.
The association between & and amp is established in the
table pst
in file t.c, exactly the way such associations are done for verbs.
In particular, CAMP is the ID for &
and ds(CAMP) is & as an array
(that is, ds(CAMP) is &).
The utilities df1
and df2 in file au.c
apply the monad or the dyad
of a verb. For example:
|
ds(CPOUND) |
# |
|
ds(COPE) |
> |
|
amp(ds(CPOUND),ds(COPE)) |
#&> |
| | |
|
df1(w,ds(CPOUND)) |
# w |
|
df1( w,amp(ds(CPOUND),ds(COPE))) |
#&> w |
|
df2(a,w,amp(ds(CPOUND),ds(COPE))) |
a #&> w |
Next
Previous
Index
Table of Contents