meth Obj == self eq: a meth Obj != self ne: a meth Obj < self lt: a meth Obj <= self le: a meth Obj > self gt: a meth Obj >= self ge: a equals 23 1 + 22 equals 'hello' ('h' ap: 'e') ap: ('l' ap: 'lo') equals 'hello' 'he' ap: 'l' $ ap: 'lo' equals 25 3 * 3 + 4 * 4 equals 142 m= Dict new. m at: 10 put: 100. (m at: 10) + 42 equals 142 m= Dict new. m at: 4 + 6 put: 10 * 10. (m at: 10) + 42 equals 'ok' 3 < 5 y::[ 'ok' ] n:: [ 'oops' ] equals 'oops' 8 < 0 y::[ 'ok' ] n:: [ 'oops' ] equals 'ok' 2 < 3 y::[ 'ok' ] equals nil 8 < 0 y::[ 'ok' ] equals nil -8 < 0 n::[ 'ok' ] equals 'Vec' Vec name equals 4, 7, 9 2 * 2; 7; 3 * 3; equals 'Vec' () cls name equals 0 () len equals 'Vec' (8;) cls name equals 1 (8;) len equals 'Vec' (8,) cls name equals 1 (8,) len equals 25 x, y = Vec(3, 4). x * x + y * y. equals 26 x, y = 3; 4. x * x + y * y $ + 1. equals 26 x; y = 3, 4. x * x + y * y $ + 1. meth Vec eq: (a cls name equals: 'Vec') n: ['Vec.== expected Vec argument, but got' err: VEC(a, a cls, a cls name, a cls name equals: 'Vec') ] y: [ self len == a len n: ['Vec.== got different length Vecs' err: VEC(self, a)] y: [ z= Vec new. self len do: [i : z append: ((self at: i) == (a at: i)). ]. z ] ]. equals 1, 1, 0 Vec('foo', 100, 'z') == Vec('foo'; 100; 'zoo') meth Vec collect: "Goldberg & Robson, 1989. p215" z= self cls new. self do: [x : z ap: ( a value: x ) ] . z equals VEC( 100, 400, 900. ) VEC( 10, 20, 30. ) collect: [x : x * x] meth Vec select: "Goldberg & Robson, 1989. p216" z= self cls new . self do: [x : . ( a value: x ) y: [ z ap: x ] ] . z equals 10, 20 ( 10, 20, 30. ) select: [x: x < 25] equals 'once-upon-a-time' ('once', 'upon', 'a', 'time') join: '-' class App Usr class Home App meth HomeCls footerButtons Vec( '|link|/RESET|[RESET]|'; '|link|/Home|[Home]|'; '|link|/Browse|[Browse]|'; '|link|/FormDoit|[Doit]|'; '|link|/DrawLife|[DrawLife]|'; '|link|/DrawLine|[DrawLine]|'; '|link|/DrawRect|[DrawRect]|'; '|link|/DrawStar|[DrawStar]|'; '|link|/DemoHt|[DemoHt]|'; '|link|/SwitchWorld|[SwitchWorld]|'; '|link|/ListUnicodePages|[ListUnicodePages]|'; ) meth Home handle:query: "Default class for handling ':'." Dict new at: 'type' put: 'list' $ at: 'title' put: a $ at: 'value' put: ( '|link|/Home|Home|', 'Go Home.'; '|link|/Reset|Reset|', 'Reset Interpreter.'; '|link|/Browse|browse|', 'Browse Classes.'; '|link|/FormDoit|doit|', 'Evaluate code'; '|link|/DrawLife|[DrawLife]|', 'Conway''s Life'; '|link|/DrawLine|[DrawLine]|', 'Draw Line'; '|link|/DrawRect|[DrawRect]|', 'Draw Rect'; '|link|/DrawStar|[DrawStar]|', 'Draw Star'; '|link|/SwitchWorld|[SwitchWorld]|', 'SwitchWorld '; '|link|/ListUnicodePages|[ListUnicodePages]|', 'List Unicode Pages'; ). class Browse App meth Browse handle:query: ww= a split: '.' . wl= ww len . clss= Cls all . "Start the list V with an UP link." v= Vec('|link|/Home|[Home]|', 'Go Home.';). v len == 1 $must: (v, '#1'). v at: 0 $len == 2 $must: (v, '#2'). ( wl == 1 ) y: [ "gk are Good Keys, those that are classes." gk= clss dir select: [i: AND( clss at: i $ cls name ends: 'Cls'; OR( clss at: i $ name ends: 'Cls' $ not; clss at: i $ cls name == 'ClsCls' ) ) ]. gk do: [k: kc= clss at: k . kn= kc name . tmp = ('|link|/Browse.', kn, '|', kn, '|') jam, kc meths dir join: ' '. tmp len == 2 $must: (tmp, '#3'). v ap: tmp. v do: [each: each len == 2 $must: (v, each, '#4')]. ]. z= Dict new $ at: 'type' put: 'list' $ at: 'title' put: 'Browsing All Classes' "$ at: 'extra' put: ( clss )" "$ at: 'extraKeys' put: ( clss dir )" "$ at: 'extraCollect' put: ( clss dir collect: [i: ( clss at: i ) cls cls name ] )" "$ at: 'extraSelect' put: gk" $ at: 'value' put: v . ] . ( wl == 2 ) y: [ cn= ww at: 1 . "class name" co= clss at: cn toLower . "class object" d= co cls meths . d dir do: [x: "For each class method" v ap: ( ( '|link|/EditMethod.', cn, 'Cls.', x, '|class ', x, '|' ) jam, d at: x $ str ) . ] . d= co meths . d dir do: [x: "For each instance method" v ap: ( ( '|link|/EditMethod.', cn, '.', x, '|', x, '|' ) jam, d at: x $ str ) . ] . z= Dict new at: 'type' put: 'list' $ at: 'title' put: ( 'Browsing Class' ap: cn ) $ at: 'value' put: v . ] . z . class EditMethod App meth EditMethod handle:query: ww= a split: '.' . wl= ww len . clss= Cls all . ( wl ne: 3 ) y: [ Zork foo ] . cn= ww at: 1 . "class name" mn= ww at: 2 . "method name" co= clss at: cn toLower . "class object" mo= co meths at: mn . "method object" z= Dict new at: 'type' p: 'edit' $ at: 'title' p: ( 'Editing Class' ap: cn $ ap: ' Method ' $ ap: mn ) $ at: 'value' p: ( mo str ) $ at: 'action' p: ( '/SubmitMethod' ) $ at: 'field1' p: 'ClassName' $ at: 'value1' p: cn $ at: 'field2' p: 'MethodName' $ at: 'value2' p: mn . z . class SubmitMethod App meth SubmitMethod handle:query: clss= Cls all . cname= b at: 'ClassName' . mname= b at: 'MethodName' . co= clss at: cname tolower . z= co definemethod: mname abbrev: '' doc: '' code: ( b at: 'text' ) . DICT( 'type', 'list'; 'title', ( 'Submitted Class', cname, ' Method ', mname ) join; 'value', Vec( Vec('|link|/Home|Home|'; 'Home.'; ) ); 'URL', a; 'QUERY', b; 'Z', z; ). class FormDoit App meth FormDoit handle:query: DICT( 'type', 'edit'; 'title', 'Doit Form'; 'value', ''; 'action', '/SubmitDoit'; ). class SubmitDoit App meth SubmitDoit handle:query: z= Tmp new eval: ( b at: 'text' ). DICT( 'type', 'text'; 'title', 'doit: ' ap: (b at: 'text'); 'value', z str; ). class DrawLine App meth DrawLine handle:query: DICT( 'type', 'draw'; 'title', 'Drawing a line'; 'value', Vec( VEC( 'line', 10, 400, 50, 300, 2 ); ); 'width', 300; 'height', 500; ) class DrawStar App meth DrawStar handle:query: "Event Location." ex, ey = b at: 'ex', b at: 'ey'. "Default Location." ex = IF( ex equals: nil )THEN( 300 )ELSE( ex num ). ey = IF( ey equals: nil )THEN( 300 )ELSE( ey num ). v = 100 range collect: [i: theta = i fdiv: 10 . x= theta sin * 290 $+ 300. y= theta cos * 290 $+ 300. VEC('line', ex, ey, x, y). ] . DICT( 'type', 'draw'; 'title', 'Drawing a line'; 'value', v; 'width', 600; 'height', 600; ). class DrawLife App meth DrawLife canX 900 meth DrawLife canY 500 meth DrawLife numX 27 meth DrawLife numY 15 meth DrawLife delX self canX idiv: self numX meth DrawLife delY self canY idiv: self numY meth DrawLife initP self numX range collect: [x: self numY range collect: [y: t = x + y * 13 . OR((t imod: 4) == 0, (t imod: 5) == 0, (t imod: 7) == 0). ] ]. meth DrawLife draw IF(p is: nil) THEN(p = self initP). nextP = self numX range collect: [x: self numY range collect: [y: nei = 0. 3 do: [i: i = i - 1 + x. 3 do: [j: j = j - 1 + y. nei = nei + ((p at: i) at: j). ]. ]. "Notice cell x,y can count as a nei." IF((p at: x) at: y) THEN( OR(nei == 3; nei == 4;) ) ELSE( nei == 3 ). ]. ]. p = nextP. v = Vec new. self numX do: [x: self numY do: [y: (p at: x) at: y $ y: [ xx = x * self delX + (self delX idiv: 2). yy = y * self delY + (self delY idiv: 2). v ap: VEC( 'rect', xx - 6, yy - 6, 12, 12,). ] n: [ xx = x * self delX + (self delX idiv: 2). yy = y * self delY + (self delY idiv: 2). v ap: VEC( 'line', xx - 2, yy - 2, xx + 2, yy + 2,). ]. ]. ]. v. meth DrawLife handle:query: DICT( 'type', 'draw'; 'width', self canX; 'height', self canY; 'value', self draw; 'url', ( '/', self cls name, '.', self docId str ) jam; ). class DrawRect App meth DrawRect handle:query: v = Vec new. FOR(x : 10) DO( FOR(y : 10) DO( v append: VEC('rect', 80 * x, 70 * y, 20, 15, 2, 'green'). v append: VEC('text', 80 * x + 25, 70 * y + 30, (x str, ',', y str) jam ). ). ). DICT( 'type', 'draw'; 'title', 'Drawing 100 Rectangles'; 'value', v; 'width', 300; 'height', 500; ). ( 1234 class DemoForm App ) 1234 ( 1235 meth DemoForm handle:query: br = Tag('br'). i1 = Tag('input'; 'name', 'one'; 'value', 'uno'). i2 = Tag('input'; 'name', 'two'; 'value', 'dos'). i3 = Tag('input'; 'name', 'three'; 'value', 'tres'). s = Tag('input'; 'type', 'submit'; 'value', '250 OK'). body = Tag('form'; 'method', 'post'; 'action', '/DemoFormSubmit'; Ht entity: 'alpha'; i1; br; Ht entity: 'beta'; i2; br; Ht entity: 'gamma'; i3; br; s). DICT( 'type', 'html'; 'value', Tag('html', Tag('body', body))). ) 1235 ( 1236 class DemoFormSubmit App ) 1236 ( 1237 meth DemoFormSubmit handle:query: br = Tag('br'). body = Ht( Ht entity: 'alpha', ' == ', b at: 'one', br, Ht entity: 'beta', ' == ', b at: 'two', br, Ht entity: 'gamma', ' == ', b at: 'three', br, ). DICT( 'type', 'html'; 'value', Tag('html', Tag('body', body))). ) 1237 class DemoHt App meth DemoHt handle:query: guts = Ht( Tag('li', 'Test.'), Tag('li', TAG('span'; 'style', 'color:yellow'; 'Hello')), Tag('li', TAG('span'; 'style', 'background-color:brown'; 'World!')), Tag('li', '[', TAG('a'; 'href', '/Home'; 'GO HOME'), ']'), ). guts append: Ht( FOR(i:100)MAP( Tag('li', i))). page = TAG('html', TAG('body'; 'bgcolor', '#222222'; 'text', '#DDDDDD'; TAG('big', TAG('big', TAG('ul', guts))))). DICT('type', 'html'; 'title', 'DemoHt Title'; 'value', page). class ListUnicodePages App meth ListUnicodePages handle:query: ww= a split: '.' . IF( ww len == 2 ) THEN( self drawPage: (ww at: 1) num ) ELSE( self listPages ). meth ListUnicodePages listPages v = FOR(i : 256) MAP( link = ('|link|/ListUnicodePages.', i str, '|Page ', i str, '|') jam. label = ( 'Page ', i str ) jam. (link, label). ). DICT( 'type', 'list'; 'title', 'Unicode Pages.'; 'value', v; ). meth ListUnicodePages drawPage: txt = FOR(i : 256) MAP( i = i + a*256. (i str, ' [', i, '] '). ) implode. DICT( 'type', 'text'; 'title', 'Unicode Page ' append: a str; 'value', txt; ). class SwitchWorld App meth SwitchWorld handle:query: r = Rex new: 'w_([a-z0-9]+).txt'. worlds = Vec new. 'sys files ==' say: Sys files. FOR(f : Sys files) DO( 'r==' say: r. 'f0==' say: (f at: 0). m = r match: (f at: 0). 'm==' say: m. IF(m) THEN( worlds append: (m at: 1). 'worlds' say: worlds. ). ). links = Ht( FOR(w : worlds) MAP ( Ht( Tag('a'; 'href', '/SwitchWorldSubmit?world=' ap: w; w) say, ' | ' ) say ) say ) say. 'links' say: links. br = Tag('br'). i1 = Tag('input'; 'name', 'world'; 'value', ''). s = Tag('input'; 'type', 'submit'; 'value', 'SwitchWorld'). form = Tag( 'form'; 'method', 'post'; 'action', '/SwitchWorldSubmit'; 'Switch to a differnt world: '; i1; br; s). body = Ht( 'Worlds: ', links, br, form ). DICT( 'type', 'html'; 'value', Tag('html', Tag('body', body))). class SwitchWorldSubmit App meth SwitchWorldSubmit handle:query: DICT( 'type', 'world'; 'value', b at: 'world'; ).