1 ! Copyright (C) 2006 Chris Double. All Rights Reserved.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors kernel peg strings sequences math math.parser
4 namespaces make words quotations arrays hashtables io
5 io.streams.string assocs ascii peg.parsers accessors
9 TUPLE: ast-number value ;
10 TUPLE: ast-identifier value vocab ;
11 TUPLE: ast-string value ;
12 TUPLE: ast-quotation values ;
13 TUPLE: ast-array elements ;
14 TUPLE: ast-define name stack-effect expression ;
15 TUPLE: ast-expression values ;
16 TUPLE: ast-word value vocab ;
18 TUPLE: ast-stack-effect in out ;
20 TUPLE: ast-using names ;
22 TUPLE: ast-hashtable elements ;
24 : identifier-middle? ( ch -- bool )
26 [ "}];\"" member? not ] keep
30 : 'identifier-ends' ( -- parser )
33 [ CHAR: " = not ] keep
34 [ CHAR: ; = not ] keep
37 identifier-middle? not
41 : 'identifier-middle' ( -- parser )
42 [ identifier-middle? ] satisfy repeat1 ;
44 : 'identifier' ( -- parser )
50 concat >string f ast-identifier boa
56 : 'effect-name' ( -- parser )
59 [ CHAR: ) = not ] keep
62 ] satisfy repeat1 [ >string ] action ;
64 : 'stack-effect' ( -- parser )
67 'effect-name' sp repeat0 ,
69 'effect-name' sp repeat0 ,
72 first2 ast-stack-effect boa
75 : 'define' ( -- parser )
78 'identifier' sp [ value>> ] action ,
79 'stack-effect' sp optional ,
82 ] seq* [ first3 ast-define boa ] action ;
84 : 'quotation' ( -- parser )
87 'expression' [ values>> ] action ,
89 ] seq* [ first ast-quotation boa ] action ;
91 : 'array' ( -- parser )
94 'expression' [ values>> ] action ,
96 ] seq* [ first ast-array boa ] action ;
98 : 'word' ( -- parser )
102 ] seq* [ first value>> f ast-word boa ] action ;
104 : 'atom' ( -- parser )
107 'integer' [ ast-number boa ] action ,
108 'string' [ ast-string boa ] action ,
111 : 'comment' ( -- parser )
118 dup CHAR: \n = swap CHAR: \r = or not
120 ] seq* [ drop ast-comment boa ] action ;
122 : 'USE:' ( -- parser )
124 "USE:" token sp hide ,
126 ] seq* [ first value>> ast-use boa ] action ;
128 : 'IN:' ( -- parser )
130 "IN:" token sp hide ,
132 ] seq* [ first value>> ast-in boa ] action ;
134 : 'USING:' ( -- parser )
136 "USING:" token sp hide ,
137 'identifier' sp [ value>> ] action repeat1 ,
139 ] seq* [ first ast-using boa ] action ;
141 : 'hashtable' ( -- parser )
144 'expression' [ values>> ] action ,
146 ] seq* [ first ast-hashtable boa ] action ;
148 : 'parsing-word' ( -- parser )
155 : 'expression' ( -- parser )
166 ] choice* repeat0 [ ast-expression boa ] action
169 : 'statement' ( -- parser )
172 GENERIC: (compile) ( ast -- )
173 GENERIC: (literal) ( ast -- )
175 M: ast-number (literal)
176 value>> number>string , ;
178 M: ast-number (compile)
179 "factor.push_data(" ,
183 M: ast-string (literal)
188 M: ast-string (compile)
189 "factor.push_data(" ,
193 M: ast-identifier (literal)
195 "factor.get_word(\"" ,
201 "factor.find_word(\"" , value>> , "\")" ,
204 M: ast-identifier (compile)
205 (literal) ".execute(" , ;
207 M: ast-define (compile)
208 "factor.define_word(\"" ,
211 expression>> (compile)
214 : do-expressions ( seq -- )
217 dup ast-comment? not [
226 drop "factor.cont.next" ,
229 M: ast-quotation (literal)
230 "factor.make_quotation(\"source\"," ,
231 values>> do-expressions
234 M: ast-quotation (compile)
235 "factor.push_data(factor.make_quotation(\"source\"," ,
236 values>> do-expressions
239 M: ast-array (literal)
241 elements>> [ "," , ] [ (literal) ] interleave
244 M: ast-array (compile)
245 "factor.push_data(" , (literal) "," , ;
247 M: ast-hashtable (literal)
248 "new Hashtable().fromAlist([" ,
249 elements>> [ "," , ] [ (literal) ] interleave
252 M: ast-hashtable (compile)
253 "factor.push_data(" , (literal) "," , ;
256 M: ast-expression (literal)
261 M: ast-expression (compile)
262 values>> do-expressions ;
264 M: ast-word (literal)
266 "factor.get_word(\"" ,
272 "factor.find_word(\"" , value>> , "\")" ,
275 M: ast-word (compile)
276 "factor.push_data(" ,
280 M: ast-comment (compile)
283 M: ast-stack-effect (compile)
296 M: ast-using (compile)
305 GENERIC: (parse-factor-quotation) ( object -- ast )
307 M: number (parse-factor-quotation) ( object -- ast )
310 M: symbol (parse-factor-quotation) ( object -- ast )
311 dup >string swap vocabulary>> ast-identifier boa ;
313 M: word (parse-factor-quotation) ( object -- ast )
314 dup name>> swap vocabulary>> ast-identifier boa ;
316 M: string (parse-factor-quotation) ( object -- ast )
319 M: quotation (parse-factor-quotation) ( object -- ast )
321 [ (parse-factor-quotation) , ] each
322 ] { } make ast-quotation boa ;
324 M: array (parse-factor-quotation) ( object -- ast )
326 [ (parse-factor-quotation) , ] each
327 ] { } make ast-array boa ;
329 M: hashtable (parse-factor-quotation) ( object -- ast )
331 [ (parse-factor-quotation) , ] each
332 ] { } make ast-hashtable boa ;
334 M: wrapper (parse-factor-quotation) ( object -- ast )
335 wrapped>> dup name>> swap vocabulary>> ast-word boa ;
337 GENERIC: fjsc-parse ( object -- ast )
339 M: string fjsc-parse ( object -- ast )
340 'expression' parse ast>> ;
342 M: quotation fjsc-parse ( object -- ast )
344 [ (parse-factor-quotation) , ] each
345 ] { } make ast-expression boa ;
347 : fjsc-compile ( ast -- string )
353 ] { } make [ write ] each
354 ] with-string-writer ;
356 : fjsc-compile* ( string -- string )
357 'statement' parse ast>> fjsc-compile ;
359 : fc* ( string -- string )
361 'statement' parse ast>> values>> do-expressions
362 ] { } make [ write ] each ;
365 : fjsc-literal ( ast -- string )
367 [ (literal) ] { } make [ write ] each
368 ] with-string-writer ;