! Copyright (C) 2006 Chris Double. All Rights Reserved.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel peg strings sequences math math.parser
-namespaces make words quotations arrays hashtables io
-io.streams.string assocs ascii peg.parsers words.symbol ;
+make words quotations arrays hashtables io
+io.streams.string assocs ascii peg.parsers words.symbol
+combinators.short-circuit ;
IN: fjsc
TUPLE: ast-number value ;
TUPLE: ast-hashtable elements ;
: identifier-middle? ( ch -- bool )
- [ blank? not ] keep
- [ "}];\"" member? not ] keep
- digit? not
- and and ;
-
-: 'identifier-ends' ( -- parser )
- [
- [ blank? not ] keep
- [ CHAR: " = not ] keep
- [ CHAR: ; = not ] keep
- [ LETTER? not ] keep
- [ letter? not ] keep
- identifier-middle? not
- and and and and and
- ] satisfy repeat0 ;
-
-: 'identifier-middle' ( -- parser )
- [ identifier-middle? ] satisfy repeat1 ;
-
-: 'identifier' ( -- parser )
- [
- 'identifier-ends' ,
- 'identifier-middle' ,
- 'identifier-ends' ,
- ] seq* [
- concat >string f ast-identifier boa
- ] action ;
-
-
-DEFER: 'expression'
-
-: 'effect-name' ( -- parser )
- [
- [ blank? not ] keep
- [ CHAR: ) = not ] keep
- CHAR: - = not
- and and
- ] satisfy repeat1 [ >string ] action ;
-
-: 'stack-effect' ( -- parser )
- [
- "(" token hide ,
- 'effect-name' sp repeat0 ,
- "--" token sp hide ,
- 'effect-name' sp repeat0 ,
- ")" token sp hide ,
- ] seq* [
- first2 ast-stack-effect boa
- ] action ;
-
-: 'define' ( -- parser )
- [
- ":" token sp hide ,
- 'identifier' sp [ value>> ] action ,
- 'stack-effect' sp optional ,
- 'expression' ,
- ";" token sp hide ,
- ] seq* [ first3 ast-define boa ] action ;
-
-: 'quotation' ( -- parser )
- [
- "[" token sp hide ,
- 'expression' [ values>> ] action ,
- "]" token sp hide ,
- ] seq* [ first ast-quotation boa ] action ;
-
-: 'array' ( -- parser )
- [
- "{" token sp hide ,
- 'expression' [ values>> ] action ,
- "}" token sp hide ,
- ] seq* [ first ast-array boa ] action ;
-
-: 'word' ( -- parser )
- [
- "\\" token sp hide ,
- 'identifier' sp ,
- ] seq* [ first value>> f ast-word boa ] action ;
-
-: 'atom' ( -- parser )
- [
- 'identifier' ,
- 'integer' [ ast-number boa ] action ,
- 'string' [ ast-string boa ] action ,
- ] choice* ;
-
-: 'comment' ( -- parser )
- [
+ {
+ [ blank? not ]
+ [ "}];\"" member? not ]
+ [ digit? not ]
+ } 1&& ;
+
+: identifier-ends-parser ( -- parser )
+ [
+ {
+ [ blank? not ]
+ [ CHAR: \" = not ]
+ [ CHAR: ; = not ]
+ [ LETTER? not ]
+ [ letter? not ]
+ [ identifier-middle? not ]
+ } 1&&
+ ] satisfy repeat0 ;
+
+: identifier-middle-parser ( -- parser )
+ [ identifier-middle? ] satisfy repeat1 ;
+
+: identifier-parser ( -- parser )
+ [
+ identifier-ends-parser ,
+ identifier-middle-parser ,
+ identifier-ends-parser ,
+ ] seq* [
+ "" concat-as f ast-identifier boa
+ ] action ;
+
+
+DEFER: expression-parser
+
+: effect-name-parser ( -- parser )
+ [
+ {
+ [ blank? not ]
+ [ CHAR: ) = not ]
+ [ CHAR: - = not ]
+ } 1&&
+ ] satisfy repeat1 [ >string ] action ;
+
+: stack-effect-parser ( -- parser )
+ [
+ "(" token hide ,
+ effect-name-parser sp repeat0 ,
+ "--" token sp hide ,
+ effect-name-parser sp repeat0 ,
+ ")" token sp hide ,
+ ] seq* [
+ first2 ast-stack-effect boa
+ ] action ;
+
+: define-parser ( -- parser )
+ [
+ ":" token sp hide ,
+ identifier-parser sp [ value>> ] action ,
+ stack-effect-parser sp optional ,
+ expression-parser ,
+ ";" token sp hide ,
+ ] seq* [ first3 ast-define boa ] action ;
+
+: quotation-parser ( -- parser )
+ [
+ "[" token sp hide ,
+ expression-parser [ values>> ] action ,
+ "]" token sp hide ,
+ ] seq* [ first ast-quotation boa ] action ;
+
+: array-parser ( -- parser )
+ [
+ "{" token sp hide ,
+ expression-parser [ values>> ] action ,
+ "}" token sp hide ,
+ ] seq* [ first ast-array boa ] action ;
+
+: word-parser ( -- parser )
+ [
+ "\\" token sp hide ,
+ identifier-parser sp ,
+ ] seq* [ first value>> f ast-word boa ] action ;
+
+: atom-parser ( -- parser )
+ [
+ identifier-parser ,
+ integer-parser [ ast-number boa ] action ,
+ string-parser [ ast-string boa ] action ,
+ ] choice* ;
+
+: comment-parser ( -- parser )
+ [
+ "!" token hide ,
+ [
+ dup CHAR: \n = swap CHAR: \r = or not
+ ] satisfy repeat0 ,
+ ] seq* [ drop ast-comment boa ] action ;
+
+: USE-parser ( -- parser )
[
- "#!" token sp ,
- "!" token sp ,
- ] choice* hide ,
+ "USE:" token sp hide ,
+ identifier-parser sp ,
+ ] seq* [ first value>> ast-use boa ] action ;
+
+: IN-parser ( -- parser )
+ [
+ "IN:" token sp hide ,
+ identifier-parser sp ,
+ ] seq* [ first value>> ast-in boa ] action ;
+
+: USING-parser ( -- parser )
+ [
+ "USING:" token sp hide ,
+ identifier-parser sp [ value>> ] action repeat1 ,
+ ";" token sp hide ,
+ ] seq* [ first ast-using boa ] action ;
+
+: hashtable-parser ( -- parser )
[
- dup CHAR: \n = swap CHAR: \r = or not
- ] satisfy repeat0 ,
- ] seq* [ drop ast-comment boa ] action ;
-
-: 'USE:' ( -- parser )
- [
- "USE:" token sp hide ,
- 'identifier' sp ,
- ] seq* [ first value>> ast-use boa ] action ;
-
-: 'IN:' ( -- parser )
- [
- "IN:" token sp hide ,
- 'identifier' sp ,
- ] seq* [ first value>> ast-in boa ] action ;
-
-: 'USING:' ( -- parser )
- [
- "USING:" token sp hide ,
- 'identifier' sp [ value>> ] action repeat1 ,
- ";" token sp hide ,
- ] seq* [ first ast-using boa ] action ;
-
-: 'hashtable' ( -- parser )
- [
- "H{" token sp hide ,
- 'expression' [ values>> ] action ,
- "}" token sp hide ,
- ] seq* [ first ast-hashtable boa ] action ;
-
-: 'parsing-word' ( -- parser )
- [
- 'USE:' ,
- 'USING:' ,
- 'IN:' ,
- ] choice* ;
-
-: 'expression' ( -- parser )
- [
+ "H{" token sp hide ,
+ expression-parser [ values>> ] action ,
+ "}" token sp hide ,
+ ] seq* [ first ast-hashtable boa ] action ;
+
+: parsing-word-parser ( -- parser )
+ [
+ USE-parser ,
+ USING-parser ,
+ IN-parser ,
+ ] choice* ;
+
+: expression-parser ( -- parser )
[
- 'comment' ,
- 'parsing-word' sp ,
- 'quotation' sp ,
- 'define' sp ,
- 'array' sp ,
- 'hashtable' sp ,
- 'word' sp ,
- 'atom' sp ,
- ] choice* repeat0 [ ast-expression boa ] action
- ] delay ;
-
-: 'statement' ( -- parser )
- 'expression' ;
+ [
+ comment-parser ,
+ parsing-word-parser sp ,
+ quotation-parser sp ,
+ define-parser sp ,
+ array-parser sp ,
+ hashtable-parser sp ,
+ word-parser sp ,
+ atom-parser sp ,
+ ] choice* repeat0 [ ast-expression boa ] action
+ ] delay ;
+
+: statement-parser ( -- parser )
+ expression-parser ;
GENERIC: (compile) ( ast -- )
GENERIC: (literal) ( ast -- )
M: ast-number (literal)
- value>> number>string , ;
+ value>> number>string , ;
M: ast-number (compile)
- "factor.push_data(" ,
- (literal)
- "," , ;
+ "factor.push_data(" ,
+ (literal)
+ "," , ;
M: ast-string (literal)
- "\"" ,
- value>> ,
- "\"" , ;
+ "\"" ,
+ value>> ,
+ "\"" , ;
M: ast-string (compile)
- "factor.push_data(" ,
- (literal)
- "," , ;
+ "factor.push_data(" ,
+ (literal)
+ "," , ;
M: ast-identifier (literal)
- dup vocab>> [
- "factor.get_word(\"" ,
- dup vocab>> ,
- "\",\"" ,
- value>> ,
- "\")" ,
- ] [
- "factor.find_word(\"" , value>> , "\")" ,
- ] if ;
+ dup vocab>> [
+ "factor.get_word(\"" ,
+ dup vocab>> ,
+ "\",\"" ,
+ value>> ,
+ "\")" ,
+ ] [
+ "factor.find_word(\"" , value>> , "\")" ,
+ ] if ;
M: ast-identifier (compile)
- (literal) ".execute(" , ;
+ (literal) ".execute(" , ;
M: ast-define (compile)
- "factor.define_word(\"" ,
- dup name>> ,
- "\",\"source\"," ,
- expression>> (compile)
- "," , ;
+ "factor.define_word(\"" ,
+ dup name>> ,
+ "\",\"source\"," ,
+ expression>> (compile)
+ "," , ;
: do-expressions ( seq -- )
- dup empty? not [
- unclip
- dup ast-comment? not [
- "function() {" ,
- (compile)
- do-expressions
- ")}" ,
+ dup empty? not [
+ unclip
+ dup ast-comment? not [
+ "function() {" ,
+ (compile)
+ do-expressions
+ ")}" ,
+ ] [
+ drop do-expressions
+ ] if
] [
- drop do-expressions
- ] if
- ] [
- drop "factor.cont.next" ,
- ] if ;
+ drop "factor.cont.next" ,
+ ] if ;
M: ast-quotation (literal)
- "factor.make_quotation(\"source\"," ,
- values>> do-expressions
- ")" , ;
+ "factor.make_quotation(\"source\"," ,
+ values>> do-expressions
+ ")" , ;
M: ast-quotation (compile)
- "factor.push_data(factor.make_quotation(\"source\"," ,
- values>> do-expressions
- ")," , ;
+ "factor.push_data(factor.make_quotation(\"source\"," ,
+ values>> do-expressions
+ ")," , ;
M: ast-array (literal)
- "[" ,
- elements>> [ "," , ] [ (literal) ] interleave
- "]" , ;
+ "[" ,
+ elements>> [ "," , ] [ (literal) ] interleave
+ "]" , ;
M: ast-array (compile)
- "factor.push_data(" , (literal) "," , ;
+ "factor.push_data(" , (literal) "," , ;
M: ast-hashtable (literal)
- "new Hashtable().fromAlist([" ,
- elements>> [ "," , ] [ (literal) ] interleave
- "])" , ;
+ "new Hashtable().fromAlist([" ,
+ elements>> [ "," , ] [ (literal) ] interleave
+ "])" , ;
M: ast-hashtable (compile)
- "factor.push_data(" , (literal) "," , ;
+ "factor.push_data(" , (literal) "," , ;
M: ast-expression (literal)
- values>> [
- (literal)
- ] each ;
+ values>> [
+ (literal)
+ ] each ;
M: ast-expression (compile)
- values>> do-expressions ;
+ values>> do-expressions ;
M: ast-word (literal)
- dup vocab>> [
- "factor.get_word(\"" ,
- dup vocab>> ,
- "\",\"" ,
- value>> ,
- "\")" ,
- ] [
- "factor.find_word(\"" , value>> , "\")" ,
- ] if ;
+ dup vocab>> [
+ "factor.get_word(\"" ,
+ dup vocab>> ,
+ "\",\"" ,
+ value>> ,
+ "\")" ,
+ ] [
+ "factor.find_word(\"" , value>> , "\")" ,
+ ] if ;
M: ast-word (compile)
- "factor.push_data(" ,
- (literal)
- "," , ;
+ "factor.push_data(" ,
+ (literal)
+ "," , ;
M: ast-comment (compile)
- drop ;
+ drop ;
M: ast-stack-effect (compile)
- drop ;
+ drop ;
M: ast-use (compile)
- "factor.use(\"" ,
- name>> ,
- "\"," , ;
+ "factor.use(\"" ,
+ name>> ,
+ "\"," , ;
M: ast-in (compile)
- "factor.set_in(\"" ,
- name>> ,
- "\"," , ;
+ "factor.set_in(\"" ,
+ name>> ,
+ "\"," , ;
M: ast-using (compile)
- "factor.using([" ,
- names>> [
- "," ,
- ] [
- "\"" , , "\"" ,
- ] interleave
- "]," , ;
+ "factor.using([" ,
+ names>> [
+ "," ,
+ ] [
+ "\"" , , "\"" ,
+ ] interleave
+ "]," , ;
GENERIC: (parse-factor-quotation) ( object -- ast )
-M: number (parse-factor-quotation) ( object -- ast )
- ast-number boa ;
+M: number (parse-factor-quotation)
+ ast-number boa ;
-M: symbol (parse-factor-quotation) ( object -- ast )
- dup >string swap vocabulary>> ast-identifier boa ;
+M: symbol (parse-factor-quotation)
+ [ >string ] [ vocabulary>> ] bi ast-identifier boa ;
-M: word (parse-factor-quotation) ( object -- ast )
- dup name>> swap vocabulary>> ast-identifier boa ;
+M: word (parse-factor-quotation)
+ [ name>> ] [ vocabulary>> ] bi ast-identifier boa ;
-M: string (parse-factor-quotation) ( object -- ast )
- ast-string boa ;
+M: string (parse-factor-quotation)
+ ast-string boa ;
-M: quotation (parse-factor-quotation) ( object -- ast )
- [
- [ (parse-factor-quotation) , ] each
- ] { } make ast-quotation boa ;
+M: quotation (parse-factor-quotation)
+ [ (parse-factor-quotation) ] { } map-as ast-quotation boa ;
-M: array (parse-factor-quotation) ( object -- ast )
- [
- [ (parse-factor-quotation) , ] each
- ] { } make ast-array boa ;
+M: array (parse-factor-quotation)
+ [ (parse-factor-quotation) ] { } map-as ast-array boa ;
-M: hashtable (parse-factor-quotation) ( object -- ast )
- >alist [
- [ (parse-factor-quotation) , ] each
- ] { } make ast-hashtable boa ;
+M: hashtable (parse-factor-quotation)
+ >alist [ (parse-factor-quotation) ] { } map-as ast-hashtable boa ;
-M: wrapper (parse-factor-quotation) ( object -- ast )
- wrapped>> dup name>> swap vocabulary>> ast-word boa ;
+M: wrapper (parse-factor-quotation)
+ wrapped>> [ name>> ] [ vocabulary>> ] bi ast-word boa ;
GENERIC: fjsc-parse ( object -- ast )
-M: string fjsc-parse ( object -- ast )
- 'expression' parse ;
+M: string fjsc-parse
+ expression-parser parse ;
-M: quotation fjsc-parse ( object -- ast )
- [
- [ (parse-factor-quotation) , ] each
- ] { } make ast-expression boa ;
+M: quotation fjsc-parse
+ [ (parse-factor-quotation) ] { } map-as ast-expression boa ;
: fjsc-compile ( ast -- string )
- [
[
- "(" ,
- (compile)
- ")" ,
- ] { } make [ write ] each
- ] with-string-writer ;
+ [
+ "(" ,
+ (compile)
+ ")" ,
+ ] { } make [ write ] each
+ ] with-string-writer ;
: fjsc-compile* ( string -- string )
- 'statement' parse fjsc-compile ;
+ statement-parser parse fjsc-compile ;
: fc* ( string -- )
- [
- 'statement' parse values>> do-expressions
- ] { } make [ write ] each ;
-
+ [
+ statement-parser parse values>> do-expressions
+ ] { } make [ write ] each ;
: fjsc-literal ( ast -- string )
- [
- [ (literal) ] { } make [ write ] each
- ] with-string-writer ;
-
+ [
+ [ (literal) ] { } make [ write ] each
+ ] with-string-writer ;