/core/parser/parser.factor

http://github.com/abeaumont/factor · Factor · 236 lines · 175 code · 59 blank · 2 comment · 31 complexity · fc3a2a6c5be3f5240c9130144092ca60 MD5 · raw file

  1. ! Copyright (C) 2005, 2010 Slava Pestov.
  2. ! See http://factorcode.org/license.txt for BSD license.
  3. USING: accessors arrays assocs classes combinators
  4. compiler.units continuations definitions effects io
  5. io.encodings.utf8 io.files kernel lexer math.parser namespaces
  6. parser.notes quotations sequences slots source-files vectors
  7. vocabs vocabs.parser words words.symbol ;
  8. IN: parser
  9. : location ( -- loc )
  10. file get lexer get line>> 2dup and
  11. [ [ path>> ] dip 2array ] [ 2drop f ] if ;
  12. : save-location ( definition -- )
  13. location remember-definition ;
  14. M: parsing-word stack-effect drop ( parsed -- parsed ) ;
  15. : create-in ( str -- word )
  16. current-vocab create dup set-word dup save-location ;
  17. SYMBOL: auto-use?
  18. : auto-use ( -- ) auto-use? on ;
  19. : no-word-restarted ( restart-value -- word )
  20. dup word? [
  21. dup vocabulary>>
  22. [ auto-use-vocab ]
  23. [ "Added \"" "\" vocabulary to search path" surround note. ] bi
  24. ] [ create-in ] if ;
  25. : ignore-forwards ( seq -- seq' )
  26. [ forward-reference? not ] filter ;
  27. : private? ( word -- ? ) vocabulary>> ".private" tail? ;
  28. : ignore-privates ( seq -- seq' )
  29. dup [ private? ] all? [ [ private? not ] filter ] unless ;
  30. : no-word ( name -- newword )
  31. dup words-named ignore-forwards
  32. dup ignore-privates dup length 1 = auto-use? get and
  33. [ 2nip first no-word-restarted ]
  34. [ drop <no-word-error> throw-restarts no-word-restarted ]
  35. if ;
  36. : parse-word ( string -- word )
  37. dup search [ ] [ no-word ] ?if ;
  38. ERROR: number-expected ;
  39. : parse-number ( string -- number )
  40. string>number [ number-expected ] unless* ;
  41. : parse-datum ( string -- word/number )
  42. dup search [ ] [
  43. dup string>number [ ] [ no-word ] ?if
  44. ] ?if ;
  45. : (scan-datum) ( -- word/number/f )
  46. (scan-token) dup [ parse-datum ] when ;
  47. : scan-datum ( -- word/number )
  48. (scan-datum) [ \ word unexpected-eof ] unless* ;
  49. : scan-word ( -- word )
  50. (scan-token) parse-word ;
  51. : scan-number ( -- number )
  52. (scan-token) parse-number ;
  53. : scan-word-name ( -- string )
  54. scan-token
  55. dup string>number [
  56. "Word names cannot be numbers" throw
  57. ] when ;
  58. : scan-new ( -- word )
  59. scan-word-name create-in ;
  60. : scan-new-word ( -- word )
  61. scan-new dup reset-generic ;
  62. ERROR: staging-violation word ;
  63. : (execute-parsing) ( accum word -- accum )
  64. dup push-parsing-word
  65. execute( accum -- accum )
  66. pop-parsing-word ; inline
  67. : execute-parsing ( accum word -- accum )
  68. dup changed-definitions get key? [ staging-violation ] when
  69. (execute-parsing) ;
  70. : scan-object ( -- object )
  71. scan-datum
  72. dup parsing-word? [
  73. V{ } clone swap execute-parsing first
  74. ] when ;
  75. : scan-class ( -- class )
  76. scan-object \ f or ;
  77. : parse-until-step ( accum end -- accum ? )
  78. (scan-datum) {
  79. { [ 2dup eq? ] [ 2drop f ] }
  80. { [ dup not ] [ drop unexpected-eof t ] }
  81. { [ dup delimiter? ] [ unexpected t ] }
  82. { [ dup parsing-word? ] [ nip execute-parsing t ] }
  83. [ pick push drop t ]
  84. } cond ;
  85. : (parse-until) ( accum end -- accum )
  86. [ parse-until-step ] keep swap [ (parse-until) ] [ drop ] if ;
  87. : parse-until ( end -- vec )
  88. 100 <vector> swap (parse-until) ;
  89. SYMBOL: quotation-parser
  90. HOOK: parse-quotation quotation-parser ( -- quot )
  91. M: f parse-quotation \ ] parse-until >quotation ;
  92. : (parse-lines) ( lexer -- quot )
  93. [ f parse-until >quotation ] with-lexer ;
  94. : parse-lines ( lines -- quot )
  95. >array <lexer> (parse-lines) ;
  96. : parse-literal ( accum end quot -- accum )
  97. [ parse-until ] dip call suffix! ; inline
  98. : parse-definition ( -- quot )
  99. \ ; parse-until >quotation ;
  100. ERROR: bad-number ;
  101. : scan-base ( base -- n )
  102. scan-token swap base> [ bad-number ] unless* ;
  103. SYMBOL: bootstrap-syntax
  104. : with-file-vocabs ( quot -- )
  105. [
  106. "syntax" use-vocab
  107. bootstrap-syntax get [ use-words ] when*
  108. call
  109. ] with-manifest ; inline
  110. SYMBOL: print-use-hook
  111. print-use-hook [ [ ] ] initialize
  112. : parse-fresh ( lines -- quot )
  113. [
  114. parse-lines
  115. auto-used? [ print-use-hook get call( -- ) ] when
  116. ] with-file-vocabs ;
  117. : parsing-file ( file -- )
  118. parser-quiet? get [ drop ] [ "Loading " write print flush ] if ;
  119. : filter-moved ( assoc1 assoc2 -- seq )
  120. swap assoc-diff keys [
  121. {
  122. { [ dup where dup [ first ] when file get path>> = not ] [ f ] }
  123. { [ dup reader-method? ] [ f ] }
  124. { [ dup writer-method? ] [ f ] }
  125. [ t ]
  126. } cond nip
  127. ] filter ;
  128. : removed-definitions ( -- assoc1 assoc2 )
  129. new-definitions old-definitions
  130. [ get first2 assoc-union ] bi@ ;
  131. : removed-classes ( -- assoc1 assoc2 )
  132. new-definitions old-definitions
  133. [ get second ] bi@ ;
  134. : forget-removed-definitions ( -- )
  135. removed-definitions filter-moved forget-all ;
  136. : reset-removed-classes ( -- )
  137. removed-classes
  138. filter-moved [ class? ] filter [ forget-class ] each ;
  139. : fix-class-words ( -- )
  140. #! If a class word had a compound definition which was
  141. #! removed, it must go back to being a symbol.
  142. new-definitions get first2
  143. filter-moved [ [ reset-generic ] [ define-symbol ] bi ] each ;
  144. : forget-smudged ( -- )
  145. forget-removed-definitions
  146. reset-removed-classes
  147. fix-class-words ;
  148. : finish-parsing ( lines quot -- )
  149. file get
  150. [ record-top-level-form ]
  151. [ record-definitions ]
  152. [ record-checksum ]
  153. tri ;
  154. : parse-stream ( stream name -- quot )
  155. [
  156. [
  157. stream-lines dup parse-fresh
  158. [ nip ] [ finish-parsing ] 2bi
  159. forget-smudged
  160. ] with-source-file
  161. ] with-compilation-unit ;
  162. : parse-file-restarts ( file -- restarts )
  163. "Load " " again" surround t 2array 1array ;
  164. : parse-file ( file -- quot )
  165. [
  166. [ parsing-file ] keep
  167. [ utf8 <file-reader> ] keep
  168. parse-stream
  169. ] [
  170. over parse-file-restarts rethrow-restarts
  171. drop parse-file
  172. ] recover ;
  173. : run-file ( file -- )
  174. parse-file call( -- ) ;
  175. : ?run-file ( path -- )
  176. dup exists? [ run-file ] [ drop ] if ;
  177. ERROR: version-control-merge-conflict ;