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 words.symbol
6 combinators.short-circuit ;
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 )
27 [ "}];\"" member? not ]
31 : identifier-ends-parser ( -- parser )
39 [ identifier-middle? not ]
43 : identifier-middle-parser ( -- parser )
44 [ identifier-middle? ] satisfy repeat1 ;
46 : identifier-parser ( -- parser )
48 identifier-ends-parser ,
49 identifier-middle-parser ,
50 identifier-ends-parser ,
52 "" concat-as f ast-identifier boa
56 DEFER: expression-parser
58 : effect-name-parser ( -- parser )
65 ] satisfy repeat1 [ >string ] action ;
67 : stack-effect-parser ( -- parser )
70 effect-name-parser sp repeat0 ,
72 effect-name-parser sp repeat0 ,
75 first2 ast-stack-effect boa
78 : define-parser ( -- parser )
81 identifier-parser sp [ value>> ] action ,
82 stack-effect-parser sp optional ,
85 ] seq* [ first3 ast-define boa ] action ;
87 : quotation-parser ( -- parser )
90 expression-parser [ values>> ] action ,
92 ] seq* [ first ast-quotation boa ] action ;
94 : array-parser ( -- parser )
97 expression-parser [ values>> ] action ,
99 ] seq* [ first ast-array boa ] action ;
101 : word-parser ( -- parser )
104 identifier-parser sp ,
105 ] seq* [ first value>> f ast-word boa ] action ;
107 : atom-parser ( -- parser )
110 integer-parser [ ast-number boa ] action ,
111 string-parser [ ast-string boa ] action ,
114 : comment-parser ( -- parser )
118 dup CHAR: \n = swap CHAR: \r = or not
120 ] seq* [ drop ast-comment boa ] action ;
122 : USE-parser ( -- parser )
124 "USE:" token sp hide ,
125 identifier-parser sp ,
126 ] seq* [ first value>> ast-use boa ] action ;
128 : IN-parser ( -- parser )
130 "IN:" token sp hide ,
131 identifier-parser sp ,
132 ] seq* [ first value>> ast-in boa ] action ;
134 : USING-parser ( -- parser )
136 "USING:" token sp hide ,
137 identifier-parser sp [ value>> ] action repeat1 ,
139 ] seq* [ first ast-using boa ] action ;
141 : hashtable-parser ( -- parser )
144 expression-parser [ values>> ] action ,
146 ] seq* [ first ast-hashtable boa ] action ;
148 : parsing-word-parser ( -- parser )
155 : expression-parser ( -- parser )
159 parsing-word-parser sp ,
160 quotation-parser sp ,
163 hashtable-parser sp ,
166 ] choice* repeat0 [ ast-expression boa ] action
169 : statement-parser ( -- 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 [ >string ] [ vocabulary>> ] bi ast-identifier boa ;
313 M: word (parse-factor-quotation) ( object -- ast )
314 [ name>> ] [ vocabulary>> ] bi ast-identifier boa ;
316 M: string (parse-factor-quotation) ( object -- ast )
319 M: quotation (parse-factor-quotation) ( object -- ast )
320 [ (parse-factor-quotation) ] { } map-as ast-quotation boa ;
322 M: array (parse-factor-quotation) ( object -- ast )
323 [ (parse-factor-quotation) ] { } map-as ast-array boa ;
325 M: hashtable (parse-factor-quotation) ( object -- ast )
326 >alist [ (parse-factor-quotation) ] { } map-as ast-hashtable boa ;
328 M: wrapper (parse-factor-quotation) ( object -- ast )
329 wrapped>> [ name>> ] [ vocabulary>> ] bi ast-word boa ;
331 GENERIC: fjsc-parse ( object -- ast )
333 M: string fjsc-parse ( object -- ast )
334 expression-parser parse ;
336 M: quotation fjsc-parse ( object -- ast )
337 [ (parse-factor-quotation) ] { } map-as ast-expression boa ;
339 : fjsc-compile ( ast -- string )
345 ] { } make [ write ] each
346 ] with-string-writer ;
348 : fjsc-compile* ( string -- string )
349 statement-parser parse fjsc-compile ;
353 statement-parser parse values>> do-expressions
354 ] { } make [ write ] each ;
356 : fjsc-literal ( ast -- string )
358 [ (literal) ] { } make [ write ] each
359 ] with-string-writer ;