NB. Evaluation in Slow Motion rev: 7 sep 01 NB. This script defines an adverb EVM which evaluates an expression. NB. The argument of EVM is an expression as character-string, NB. for example '2+2' EVM . NB. EVM also produces global variables which, when displayed, NB. show the stages in the evaluation process. NB. The main function: EVM =: 1 : 0 setup x. done =: 0 while. not done do. r =: inspect '' NB. look for applicable rule update (<Q),(<S), <<r NB. update history if. not r -: 'none' NB. some rule applies do. execute r , ' 0' NB. execute the rule elseif. (#Q) > 0 NB. no rule, some Q do. transfer '' NB. get a word from Q elseif. 1 do. done =: 1 end. end. ". 'zz =: ', ; }. S ((5 !: 1) <'zz') (5 !: 0) NB. deliver the result ) NB. Utility Functions and Constants wordform =: ;: unwordfm =: ;: ^: _1 print =: (1 !: 2 ) & 2 First =: {. Last =: {: Most =: }: jclass =: 4 !: 0 T1 =: 1 & {. NB. Take 1 (first) T2 =: 2 & {. T3 =: 3 & {. NB. Take 3 T4 =: 4 & {. NB. Take 4 D3 =: 3 & }. NB. Drop 3 D4 =: 4 & }. NB. Drop 4 and =: *. or =: +. not =: -. rep =: 5 !: 6 NB. representation-function execute =: ". mark =: 'mark' letters =: ((65 + i. 26), (97 + i. 26)) { a. digits =: (48 + i. 10) { a. nchars =: letters,digits,'_' NB. A scheme for classifying the objects of the stack. We assign a number NB. for each kind of object. Following the built-in J classification scheme, NB. nouns are class-0 objects, adverbs are class-1 objects and so on. Noun =: 0 Adv =: 1 Conj =: 2 Verb =: 3 Name =: _1 NB. a name with no assigned value NB. Also in the stack will be objects which are punctuation rather NB. than values. We have the "mark" (marking the beginning of the expression), left and right NB. parentheses and the symbol for assignment, ([=:] or [=.]). We give arbitrary numbers NB. to encode these classes. Mark =: 99 Rpar =: 98 Lpar =: 97 Asgn =: 96 NB. Next some larger classes, represented by lists. VN =: Verb, Noun AVN =: Adv, Verb, Noun CAVN =: Conj, Adv, Verb, Noun EDGE =: Mark, Asgn, Lpar EAVN =: EDGE, AVN NN =: Noun, Name NB. A pattern is a sequence of classes. Here is a verb to match the stack NB. against a pattern and identify the corresponding rule. inspect =: 3 : 0 if. S match EDGE; Verb; Noun do. 'monad' elseif. S match EAVN; Verb; Verb; Noun do. 'monad2' elseif. S match EAVN; Noun; Verb; Noun do. 'dyad' elseif. S match EAVN; VN; Adv do. 'adv' elseif. S match EAVN; VN; Conj; VN do. 'conj' elseif. S match EAVN; Verb; Verb; Verb do. 'fork' elseif. S match EDGE; CAVN; CAVN; CAVN do. 'trident' elseif. S match EDGE; CAVN; CAVN do. 'bident' elseif. S match NN; Asgn; CAVN do. 'assign' elseif. S match Lpar; CAVN; Rpar do. 'paren' elseif. 1 do. 'none' end. ) setup =: 3 : 0 NB. set up global variables Q =: mark ; wordform y. NB. a list of boxed strings S =: 0 $ < ' ' NB. a list of boxed strings Qh =: (0 , (#Q)) $ Q NB. Q history Sh =: 0 1 $ Q NB. Stack history Rh =: (0,1) $ < ' ' NB. Rule history ) NB. verb to transfer a word from end of Q to front of S, NB. evaluating names which are nouns and not about to be assigned-to transfer =: 3 : 0 a =. > Last Q if. isname a do. if. (classify a) = Noun do. if. 1 - S match < Asgn do. a =. > Eval < a end. end. end. S =: (<a) , S Q =: Most Q ) NB. A verb to test whether the stack matches a pattern of object-classes. NB. The left argument x. is the stack, and the right argument y. NB. is a pattern, a list of (sets of) classes. match =: 4 : 0 if. (# x.) < (# y.) do. 0 NB. stack too short else. x. =. (# y.) {. x. *. / x. (match1 &: > " 0 0) y. end. ) NB. a verb to match a single stack item against a classification. NB. case [q] catches reassigning to existing name NB. case [r] embodies the assumption that an unassigned name denotes a verb match1 =: 4 : 0 c =. classify x. p =. c e. y. q =. (y. -: NN) and (isname x.) r =. (Verb e. y.) and (c -: Name) or/p,q,r ) NB. A verb which tests whether a string is a name , that is, NB. begins with a letter and contains only letters or digits or underscores. isname =: 3 : '((0 { y.) e. letters) and (*./ y. e. " 0 1 nchars)' NB. A verb to classify a stack-item (a string). classify =: 3 : 0 if. y. -: mark do. Mark elseif. y. -: 1 $ ')' do. Rpar elseif. y. -: 1 $ '(' do. Lpar elseif. y. -: '=:' do. Asgn elseif. y. -: '=:' do. Asgn elseif. Name = jclass < y. do. Name NB. an unused name ! elseif. 1 do. ". 'x =. ' , y. jclass < 'x' end. ) NB. Now the functions for the rules. Each computes a new value of S. monad =: 3 : 'S =: (T1 S), (Eval 1 2 { S), (D3 S) ' monad2 =: 3 : 'S =: (T2 S), (Eval 2 3 { S), (D4 S) ' bident =: 3 : 'S =: (T1 S), (Eval 1 2 { S), (D3 S) ' trident=: 3 : 'S =: (T1 S), (Eval 1 2 3 { S), (D4 S) ' dyad =: 3 : 'S =: (T1 S), (Eval 1 2 3 { S), (D4 S) ' adv =: 3 : 'S =: (T1 S), (Eval 1 2 { S), (D3 S) ' conj =: 3 : 'S =: (T1 S), (Eval 1 2 3 { S), (D4 S) ' fork =: 3 : 'S =: (T1 S), (Eval 1 2 3 { S), (D4 S) ' assign =: 3 : 'S =: (Is 0 1 2 { S), (D3 S) ' paren =: 3 : 'S =: (1&{ , D3) S ' NB. Each of these rule-functions needs to perform some actual computation. NB. The computations are done by the Eval verb, or in case NB. of assignments, by the Is verb. NB. The argument of Eval is a sequence of stack items. NB. After parenthesizing each item they are run together NB. to form a single string. This string is executed. NB. The resulting value (of whatever kind) is turned back into a string with NB. the representation-function and boxed to give a single NB. stack-item, which is the result of Eval. Paren =: (('('&,) @ (, & ')')) &. > Eval =: 3 : 0 execute 'z=. ' , ; Paren y. < rep < 'z' ) NB. The Is verb executes assignments. NB. Note that, for the purpose of the modelling, it is convenient NB. to force the assignment to be global. Otherwise, a local assignment would be NB. buried inside the model itself. Is =: 3 : 0 execute 'z=. ', (> 0 { y.), '=:', (> 2} y.) < rep < 'z' ) NB. function to record one stage, adding it to the history update =: 3 : 0 'Q S R' =. y. Qh =: Qh,Q Sh =: Sh,S if. R -: <'none' do. R =. <' ' end. Rh =: Rh,R '' ) NB. End of definition of modelling-adverb EVM. NB. display of history: functions to generate an HTML table NB. from the global variables Qh, Sh, Rh td =: 3 : '''<TD>'', y. , ''</TD>''' TD =: td @: ('<TT>' & ,) b =: ' ' bl =: td b show =: 3 : 0 print '<TABLE BORDER=1 CELLPADDING=4>' print '<TR>' print bl,bl,(td 'queue'),bl, ('<TD COLSPAN='),(": # 0{Sh), '> stack </TD>',bl ,(td 'rule') i =. _1 while. (i =. i+1) < # Sh do. showrow i end. print '</TABLE> <BR>' '' ) showrow =: 3 : 0 i =. y. NB. row-number print '<TR>' print TD ": i NB. stage print bl, TD b, rmark unwordfm i { Qh NB. queue print bl s =. i { Sh j =. _1 while. (j =. j+1) < # s do. print TD b, rmark > j { s NB. stack item end. r =. i { Rh print bl, TD b, > r NB. rule '' ) NB. replace mark with HTML symbol in string y. HTMLmark =: 38 35 49 54 55 59 { a. rmark =: 3 : 'if. (T4 y.) -: mark do. HTMLmark, D4 y. else. y. end.' NB. ------- e n d ---------- last updated 7 sep 01#
last updated 7 Sep 01