]> gitweb.factorcode.org Git - factor.git/commitdiff
Split up huge parser vocabulary
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 25 Jun 2008 08:25:08 +0000 (03:25 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 25 Jun 2008 08:25:08 +0000 (03:25 -0500)
61 files changed:
core/alien/syntax/syntax.factor
core/classes/classes.factor
core/classes/intersection/intersection.factor
core/classes/mixin/mixin.factor
core/classes/parser/parser.factor [new file with mode: 0644]
core/classes/predicate/predicate.factor
core/classes/tuple/parser/parser-docs.factor [new file with mode: 0644]
core/classes/tuple/parser/parser.factor [new file with mode: 0644]
core/classes/tuple/tuple.factor
core/classes/union/union.factor
core/continuations/continuations-docs.factor
core/cpu/x86/assembler/assembler.factor
core/cpu/x86/assembler/syntax/syntax.factor [new file with mode: 0644]
core/effects/parser/parser-docs.factor [new file with mode: 0644]
core/effects/parser/parser.factor [new file with mode: 0644]
core/generic/parser/parser.factor [new file with mode: 0644]
core/lexer/lexer-docs.factor [new file with mode: 0644]
core/lexer/lexer.factor [new file with mode: 0644]
core/listener/listener.factor
core/parser/parser-docs.factor
core/parser/parser-tests.factor
core/parser/parser.factor
core/source-files/source-files.factor
core/strings/parser/parser-docs.factor [new file with mode: 0644]
core/strings/parser/parser.factor [new file with mode: 0644]
core/syntax/syntax.factor
extra/bitfields/bitfields.factor
extra/bootstrap/unicode/unicode.factor
extra/cocoa/cocoa.factor
extra/cpu/8080/emulator/emulator.factor
extra/editors/editors-docs.factor
extra/editors/editors.factor
extra/gesture-logger/gesture-logger.factor
extra/help/handbook/handbook.factor
extra/html/templates/chloe/syntax/syntax.factor
extra/html/templates/fhtml/fhtml.factor
extra/http/http-tests.factor
extra/http/http.factor
extra/io/encodings/8-bit/8-bit-docs.factor
extra/locals/locals.factor
extra/match/match.factor
extra/money/money.factor
extra/mortar/mortar.factor
extra/multiline/multiline.factor
extra/opengl/gl/extensions/extensions.factor
extra/openssl/libssl/libssl.factor
extra/qualified/qualified.factor
extra/regexp/regexp.factor
extra/semantic-db/semantic-db.factor
extra/state-machine/state-machine.factor
extra/symbols/symbols.factor
extra/tools/deploy/shaker/shaker.factor
extra/tuple-syntax/tuple-syntax.factor
extra/ui/tools/interactor/interactor.factor
extra/unicode/syntax/syntax.factor
extra/urls/urls.factor
extra/vars/vars.factor
extra/xml/generator/generator.factor
extra/xml/utilities/utilities.factor
extra/xmode/loader/syntax/syntax.factor
extra/xmode/utilities/utilities.factor

index def5b02ba03f3c05b1d3c0043d1397d38140d13c..a756734f7bd2f196556440eb12afcada4dc46c2b 100755 (executable)
@@ -3,7 +3,8 @@
 USING: arrays alien alien.c-types alien.structs alien.arrays
 alien.strings kernel math namespaces parser sequences words
 quotations math.parser splitting grouping effects prettyprint
-prettyprint.sections prettyprint.backend assocs combinators ;
+prettyprint.sections prettyprint.backend assocs combinators
+lexer strings.parser ;
 IN: alien.syntax
 
 <PRIVATE
index 0fef6de74865a0262426b661fad7e843c766ecad..35ff475abfda0ef56cb3920451eca8acbe8df089 100755 (executable)
@@ -65,6 +65,15 @@ GENERIC: rank-class ( class -- n )
 
 GENERIC: reset-class ( class -- )
 
+M: class reset-class
+    {
+        "class"
+        "metaclass"
+        "superclass"
+        "members"
+        "participants"
+    } reset-props ;
+
 M: word reset-class drop ;
 
 GENERIC: implementors ( class/classes -- seq )
index 7ea8e24f0a45c66039f768478c2e3dad8fe48416..cc24280384bb3f2bd910114fda603de8e65fa835 100644 (file)
@@ -27,7 +27,4 @@ M: intersection-class update-class define-intersection-predicate ;
     [ drop update-classes ]
     2bi ;
 
-M: intersection-class reset-class
-    { "class" "metaclass" "participants" } reset-props ;
-
 M: intersection-class rank-class drop 2 ;
index a2debe55a10b1defb39b29abd3b5cda0e4cc254b..3924eb264cedebae12cfee0e5826d3bb19f3a90a 100755 (executable)
@@ -7,7 +7,7 @@ IN: classes.mixin
 PREDICATE: mixin-class < union-class "mixin" word-prop ;
 
 M: mixin-class reset-class
-    { "class" "metaclass" "members" "mixin" } reset-props ;
+    [ call-next-method ] [ { "mixin" } reset-props ] bi ;
 
 M: mixin-class rank-class drop 3 ;
 
diff --git a/core/classes/parser/parser.factor b/core/classes/parser/parser.factor
new file mode 100644 (file)
index 0000000..17a7b23
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: parser words kernel classes compiler.units lexer ;
+IN: classes.parser
+
+: save-class-location ( class -- )
+    location remember-class ;
+
+: create-class-in ( word -- word )
+    current-vocab create
+    dup save-class-location
+    dup predicate-word dup set-word save-location ;
+
+: CREATE-CLASS ( -- word )
+    scan create-class-in ;
index c8de36582eabfb09a2c67c8bc54b8b2b74275cb9..7ea60149f8adbcdfd63dd9ab5ecba1c53b3daf1c 100755 (executable)
@@ -24,11 +24,8 @@ PREDICATE: predicate-class < class
     ] 3tri ;
 
 M: predicate-class reset-class
-    {
-        "class"
-        "metaclass"
-        "predicate-definition"
-        "superclass"
-    } reset-props ;
+    [ call-next-method ]
+    [ { "predicate-definition" } reset-props ]
+    bi ;
 
 M: predicate-class rank-class drop 1 ;
diff --git a/core/classes/tuple/parser/parser-docs.factor b/core/classes/tuple/parser/parser-docs.factor
new file mode 100644 (file)
index 0000000..f4ecb14
--- /dev/null
@@ -0,0 +1,14 @@
+IN: classes.tuple.parser
+USING: strings help.markup help.syntax ;
+
+HELP: invalid-slot-name
+{ $values { "name" string } }
+{ $description "Throws an " { $link invalid-slot-name } " error." }
+{ $error-description "Thrown by " { $link POSTPONE: TUPLE: } " and " { $link POSTPONE: ERROR: } " if a suspect token appears as a slot name." }
+{ $notes "The suspect tokens are chosen so that the following code raises this parse error, instead of silently greating a tuple with garbage slots:"
+    { $code
+        "TUPLE: my-mistaken-tuple slot-a slot-b"
+        ""
+        ": some-word ( a b c -- ) ... ;"
+    }
+} ;
diff --git a/core/classes/tuple/parser/parser.factor b/core/classes/tuple/parser/parser.factor
new file mode 100644 (file)
index 0000000..ab3be10
--- /dev/null
@@ -0,0 +1,50 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sets namespaces sequences inspector parser
+lexer combinators words classes.parser classes.tuple ;
+IN: classes.tuple.parser
+
+: shadowed-slots ( superclass slots -- shadowed )
+    >r all-slot-names r> intersect ;
+
+: check-slot-shadowing ( class superclass slots -- )
+    shadowed-slots [
+        [
+            "Definition of slot ``" %
+            %
+            "'' in class ``" %
+            word-name %
+            "'' shadows a superclass slot" %
+        ] "" make note.
+    ] with each ;
+
+ERROR: invalid-slot-name name ;
+
+M: invalid-slot-name summary
+    drop
+    "Invalid slot name" ;
+
+: (parse-tuple-slots) ( -- )
+    #! This isn't meant to enforce any kind of policy, just
+    #! to check for mistakes of this form:
+    #!
+    #! TUPLE: blahblah foo bing
+    #!
+    #! : ...
+    scan {
+        { [ dup not ] [ unexpected-eof ] }
+        { [ dup { ":" "(" "<" } member? ] [ invalid-slot-name ] }
+        { [ dup ";" = ] [ drop ] }
+        [ , (parse-tuple-slots) ]
+    } cond ;
+
+: parse-tuple-slots ( -- seq )
+    [ (parse-tuple-slots) ] { } make ;
+
+: parse-tuple-definition ( -- class superclass slots )
+    CREATE-CLASS
+    scan {
+        { ";" [ tuple f ] }
+        { "<" [ scan-word parse-tuple-slots ] }
+        [ >r tuple parse-tuple-slots r> prefix ]
+    } case 3dup check-slot-shadowing ;
index 5ba0b7e69cdf29402ec80a7c6f811ac0039bac84..b4a2302a9e08020fcac0f60f9e4c1ef1373c758a 100755 (executable)
@@ -217,13 +217,9 @@ M: tuple-class reset-class
             [ writer-word method forget ] 2bi
         ] with each
     ] [
-        {
-            "class"
-            "metaclass"
-            "superclass"
-            "layout"
-            "slots"
-        } reset-props
+        [ call-next-method ]
+        [ { "layout" "slots" } reset-props ]
+        bi
     ] bi ;
 
 M: tuple-class rank-class drop 0 ;
index 74e29cfb01b47e974c5d2c03d4367fb058eb232e..819e0ecb0b1de276b098f8f93b93dd2877cbf7eb 100755 (executable)
@@ -28,7 +28,4 @@ M: union-class update-class define-union-predicate ;
 : define-union-class ( class members -- )
     [ (define-union-class) ] [ drop update-classes ] 2bi ;
 
-M: union-class reset-class
-    { "class" "metaclass" "members" } reset-props ;
-
 M: union-class rank-class drop 2 ;
index 3cb7d8a71e9ceb755cd8e550a85818a4fa205999..f176e6ee19a95b093edcf0da0e6a5fcc0d55cea8 100755 (executable)
@@ -1,6 +1,6 @@
 USING: help.markup help.syntax kernel kernel.private
-continuations.private parser vectors arrays namespaces
-assocs words quotations ;
+continuations.private vectors arrays namespaces
+assocs words quotations lexer ;
 IN: continuations
 
 ARTICLE: "errors-restartable" "Restartable errors"
@@ -169,8 +169,8 @@ HELP: rethrow
     "This word is intended to be used in conjunction with " { $link recover } " to implement error handlers which perform an action and pass the error to the next outermost error handler."
 }
 { $examples
-    "The " { $link with-parser } " catches errors, annotates them with file name and line number information, and rethrows them:"
-    { $see with-parser }
+    "The " { $link with-lexer } " word catches errors, annotates them with the current line and column number, and rethrows them:"
+    { $see with-lexer }
 } ;
 
 HELP: throw-restarts
index 452a102341ad85f418eab302c8458ec958c34c87..f8e0b0abb03f986b5c93c3e15454109d10bb47a0 100755 (executable)
@@ -1,8 +1,9 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays generator.fixup io.binary kernel
-combinators kernel.private math namespaces parser sequences
-words system layouts math.order accessors ;
+combinators kernel.private math namespaces sequences
+words system layouts math.order accessors
+cpu.x86.assembler.syntax ;
 IN: cpu.x86.assembler
 
 ! A postfix assembler for x86 and AMD64.
@@ -12,21 +13,6 @@ IN: cpu.x86.assembler
 ! Beware!
 
 ! Register operands -- eg, ECX
-<<
-
-: define-register ( name num size -- )
-    >r >r "cpu.x86.assembler" create dup define-symbol r> r>
-    >r dupd "register" set-word-prop r>
-    "register-size" set-word-prop ;
-
-: define-registers ( names size -- )
-    >r dup length r> [ define-register ] curry 2each ;
-
-: REGISTERS: ( -- )
-    scan-word ";" parse-tokens swap define-registers ; parsing
-
->>
-
 REGISTERS: 8 AL CL DL BL ;
 
 REGISTERS: 16 AX CX DX BX SP BP SI DI ;
diff --git a/core/cpu/x86/assembler/syntax/syntax.factor b/core/cpu/x86/assembler/syntax/syntax.factor
new file mode 100644 (file)
index 0000000..5940663
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel words sequences lexer parser ;
+IN: cpu.x86.assembler.syntax
+
+: define-register ( name num size -- )
+    >r >r "cpu.x86.assembler" create dup define-symbol r> r>
+    >r dupd "register" set-word-prop r>
+    "register-size" set-word-prop ;
+
+: define-registers ( names size -- )
+    >r dup length r> [ define-register ] curry 2each ;
+
+: REGISTERS: ( -- )
+    scan-word ";" parse-tokens swap define-registers ; parsing
diff --git a/core/effects/parser/parser-docs.factor b/core/effects/parser/parser-docs.factor
new file mode 100644 (file)
index 0000000..6cb39d2
--- /dev/null
@@ -0,0 +1,9 @@
+IN: effects.parser
+USING: strings effects help.markup help.syntax ;
+
+HELP: parse-effect
+{ $values { "end" string } { "effect" "an instance of " { $link effect } } }
+{ $description "Parses a stack effect from the current input line." }
+{ $examples "This word is used by " { $link POSTPONE: ( } " and " { $link POSTPONE: (( } " to parse stack effect declarations." }
+$parsing-note ;
+
diff --git a/core/effects/parser/parser.factor b/core/effects/parser/parser.factor
new file mode 100644 (file)
index 0000000..8f28450
--- /dev/null
@@ -0,0 +1,15 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: lexer sets sequences kernel splitting effects ;
+IN: effects.parser
+
+: parse-effect ( end -- effect )
+    parse-tokens dup { "(" "((" } intersect empty? [
+        { "--" } split1 dup [
+            <effect>
+        ] [
+            "Stack effect declaration must contain --" throw
+        ] if
+    ] [
+        "Stack effect declaration must not contain ( or ((" throw
+    ] if ;
diff --git a/core/generic/parser/parser.factor b/core/generic/parser/parser.factor
new file mode 100644 (file)
index 0000000..ba9cd52
--- /dev/null
@@ -0,0 +1,33 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: parser kernel words generic namespaces inspector ;
+IN: generic.parser
+
+ERROR: not-in-a-method-error ;
+
+M: not-in-a-method-error summary
+    drop "call-next-method can only be called in a method definition" ;
+
+: CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
+
+: create-method-in ( class generic -- method )
+    create-method f set-word dup save-location ;
+
+: CREATE-METHOD ( -- method )
+    scan-word bootstrap-word scan-word create-method-in ;
+
+SYMBOL: current-class
+SYMBOL: current-generic
+
+: with-method-definition ( quot -- parsed )
+    [
+        >r
+        [ "method-class" word-prop current-class set ]
+        [ "method-generic" word-prop current-generic set ]
+        [ ] tri
+        r> call
+    ] with-scope ; inline
+
+: (M:) ( method def -- )
+    CREATE-METHOD [ parse-definition ] with-method-definition ;
+
diff --git a/core/lexer/lexer-docs.factor b/core/lexer/lexer-docs.factor
new file mode 100644 (file)
index 0000000..b61fc82
--- /dev/null
@@ -0,0 +1,114 @@
+IN: lexer
+USING: help.markup help.syntax kernel math sequences strings
+words quotations ;
+
+: $parsing-note ( children -- )
+    drop
+    "This word should only be called from parsing words."
+    $notes ;
+
+HELP: lexer
+{ $var-description "Stores the current " { $link lexer } " instance." }
+{ $class-description "An object for tokenizing parser input. It has the following slots:"
+    { $list
+        { { $snippet "text" } " - the lines being parsed; an array of strings" }
+        { { $snippet "line" } " - the line number being parsed; unlike most indices this is 1-based for friendlier error reporting and integration with text editors" }
+        { { $snippet "column" } " - the current column position, zero-based" }
+    }
+"Custom lexing can be implemented by delegating a tuple to an instance of this class and implementing the " { $link skip-word } " and " { $link skip-blank } " generic words." } ;
+
+HELP: <lexer>
+{ $values { "text" "a sequence of strings" } { "lexer" lexer } }
+{ $description "Creates a new lexer for tokenizing the given sequence of lines." } ;
+
+HELP: next-line
+{ $values { "lexer" lexer } }
+{ $description "Advances the lexer to the next input line, discarding the remainder of the current line." } ;
+
+HELP: lexer-error
+{ $error-description "Thrown when the lexer encounters invalid input. A lexer error wraps an underlying error together with line and column numbers." } ;
+
+HELP: <lexer-error>
+{ $values { "msg" "an error" } { "error" lexer-error } }
+{ $description "Creates a new " { $link lexer-error } ", filling in the location information from the current " { $link lexer } "." } ;
+
+HELP: skip
+{ $values { "i" "a starting index" } { "seq" sequence } { "?" "a boolean" } { "n" integer } }
+{ $description "Skips to the first space character (if " { $snippet "boolean" } " is " { $link f } ") or the first non-space character (otherwise)." } ;
+
+HELP: change-lexer-column
+{ $values { "lexer" lexer } { "quot" "a quotation with stack effect " { $snippet "( col line -- newcol )" } } }
+{ $description "Applies a quotation to the current column and line text to produce a new column, and moves the lexer position." } ;
+
+HELP: skip-blank
+{ $values { "lexer" lexer } }
+{ $contract "Skips whitespace characters." }
+{ $notes "Custom lexers can implement this generic word." } ;
+
+HELP: skip-word
+{ $values { "lexer" lexer } }
+{ $contract
+    "Skips until the end of the current token."
+    $nl
+    "The default implementation treats a single " { $snippet "\"" } " as a word by itself; otherwise it searches forward until a whitespace character or the end of the line."
+}
+{ $notes "Custom lexers can implement this generic word." } ;
+
+HELP: still-parsing-line?
+{ $values { "lexer" lexer } { "?" "a boolean" } }
+{ $description "Outputs " { $link f } " if the end of the current line has been reached, " { $link t } " otherwise." } ;
+
+HELP: parse-token
+{ $values { "lexer" lexer } { "str/f" "a " { $link string } " or " { $link f } } }
+{ $description "Reads the next token from the lexer. Tokens are delimited by whitespace, with the exception that " { $snippet "\"" } " is treated like a single token even when not followed by whitespace." } ;
+
+HELP: scan
+{ $values { "str/f" "a " { $link string } " or " { $link f } } }
+{ $description "Reads the next token from the lexer. See " { $link parse-token } " for details." }
+$parsing-note ;
+
+HELP: still-parsing?
+{ $values { "lexer" lexer } { "?" "a boolean" } }
+{ $description "Outputs " { $link f } " if end of input has been reached, " { $link t } " otherwise." } ;
+
+HELP: parse-tokens
+{ $values { "end" string } { "seq" "a new sequence of strings" } }
+{ $description "Reads a sequence of tokens until the first occurrence of " { $snippet "end" } ". The tokens remain as strings and are not processed in any way." }
+{ $examples "This word is used to implement " { $link POSTPONE: USING: } "." }
+$parsing-note ;
+
+HELP: unexpected
+{ $values { "want" "a " { $link word } " or " { $link f } } { "got" word } }
+{ $description "Throws an " { $link unexpected } " error." }
+{ $error-description "Thrown by the parser if an unmatched closing delimiter is encountered." }
+{ $examples
+    "Parsing the following snippet will throw this error:"
+    { $code "[ 1 2 3 }" }
+} ;
+
+HELP: unexpected-eof
+{ $values { "word" "a " { $link word } } }
+{ $description "Throws an " { $link unexpected } " error indicating the parser was looking for an occurrence of " { $snippet "word" } " but encountered end of file." } ;
+
+HELP: with-lexer
+{ $values { "lexer" lexer } { "quot" quotation } }
+{ $description "Calls the quotation with the " { $link lexer } " variable set to the given lexer. The quotation can make use of words such as " { $link scan } ". Any errors thrown by the quotation are wrapped in " { $link lexer-error } " instances." } ;
+
+HELP: lexer-factory
+{ $var-description "A variable holding a quotation with stack effect " { $snippet "( lines -- lexer )" } ". This quotation is called by the parser to create " { $link lexer } " instances. This variable can be rebound to a quotation which outputs a custom tuple delegating to " { $link lexer } " to customize syntax." } ;
+
+
+ARTICLE: "parser-lexer" "The lexer"
+"A variable that encapsulate internal parser state:"
+{ $subsection lexer }
+"Creating a default lexer:"
+{ $subsection <lexer> }
+"A word to test of the end of input has been reached:"
+{ $subsection still-parsing? }
+"A word to advance the lexer to the next line:"
+{ $subsection next-line }
+"Two generic words to override the lexer's token boundary detection:"
+{ $subsection skip-blank }
+{ $subsection skip-word }
+"Utility combinator:"
+{ $subsection with-lexer } ;
diff --git a/core/lexer/lexer.factor b/core/lexer/lexer.factor
new file mode 100644 (file)
index 0000000..3d65fb9
--- /dev/null
@@ -0,0 +1,133 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences accessors namespaces math words strings
+debugger io vectors arrays math.parser combinators inspector
+continuations ;
+IN: lexer
+
+TUPLE: lexer text line line-text line-length column ;
+
+: next-line ( lexer -- )
+    dup [ line>> ] [ text>> ] bi ?nth >>line-text
+    dup line-text>> length >>line-length
+    [ 1+ ] change-line
+    0 >>column
+    drop ;
+
+: new-lexer ( text class -- lexer )
+    new
+        0 >>line
+        swap >>text
+    dup next-line ; inline
+
+: <lexer> ( text -- lexer )
+    lexer new-lexer ;
+
+: skip ( i seq ? -- n )
+    over >r
+    [ swap CHAR: \s eq? xor ] curry find-from drop
+    [ r> drop ] [ r> length ] if* ;
+
+: change-lexer-column ( lexer quot -- )
+    swap
+    [ dup lexer-column swap lexer-line-text rot call ] keep
+    set-lexer-column ; inline
+
+GENERIC: skip-blank ( lexer -- )
+
+M: lexer skip-blank ( lexer -- )
+    [ t skip ] change-lexer-column ;
+
+GENERIC: skip-word ( lexer -- )
+
+M: lexer skip-word ( lexer -- )
+    [
+        2dup nth CHAR: " eq? [ drop 1+ ] [ f skip ] if
+    ] change-lexer-column ;
+
+: still-parsing? ( lexer -- ? )
+    dup lexer-line swap lexer-text length <= ;
+
+: still-parsing-line? ( lexer -- ? )
+    dup lexer-column swap lexer-line-length < ;
+
+: (parse-token) ( lexer -- str )
+    [ lexer-column ] keep
+    [ skip-word ] keep
+    [ lexer-column ] keep
+    lexer-line-text subseq ;
+
+:  parse-token ( lexer -- str/f )
+    dup still-parsing? [
+        dup skip-blank
+        dup still-parsing-line?
+        [ (parse-token) ] [ dup next-line parse-token ] if
+    ] [ drop f ] if ;
+
+: scan ( -- str/f ) lexer get parse-token ;
+
+ERROR: unexpected want got ;
+
+GENERIC: expected>string ( obj -- str )
+
+M: f expected>string drop "end of input" ;
+M: word expected>string word-name ;
+M: string expected>string ;
+
+M: unexpected error.
+    "Expected " write
+    dup unexpected-want expected>string write
+    " but got " write
+    unexpected-got expected>string print ;
+
+PREDICATE: unexpected-eof < unexpected
+    unexpected-got not ;
+
+: unexpected-eof ( word -- * ) f unexpected ;
+
+: (parse-tokens) ( accum end -- accum )
+    scan 2dup = [
+        2drop
+    ] [
+        [ pick push (parse-tokens) ] [ unexpected-eof ] if*
+    ] if ;
+
+: parse-tokens ( end -- seq )
+    100 <vector> swap (parse-tokens) >array ;
+
+TUPLE: lexer-error line column line-text error ;
+
+: <lexer-error> ( msg -- error )
+    \ lexer-error new
+        lexer get
+        [ line>> >>line ]
+        [ column>> >>column ]
+        [ line-text>> >>line-text ]
+        tri
+        swap >>error ;
+
+: lexer-dump ( error -- )
+    [ line>> number>string ": " append ]
+    [ line-text>> dup string? [ drop "" ] unless ]
+    [ column>> 0 or ] tri
+    pick length + CHAR: \s <string>
+    [ write ] [ print ] [ write "^" print ] tri* ;
+
+M: lexer-error error.
+    [ lexer-dump ] [ error>> error. ] bi ;
+
+M: lexer-error summary
+    error>> summary ;
+
+M: lexer-error compute-restarts
+    error>> compute-restarts ;
+
+M: lexer-error error-help
+    error>> error-help ;
+
+: with-lexer ( lexer quot -- newquot )
+    [ lexer set ] dip [ <lexer-error> rethrow ] recover ; inline
+
+SYMBOL: lexer-factory
+
+[ <lexer> ] lexer-factory set-global
index e00e64f4bcfc7e0f0d656747760bb687071eb86e..4e2a8c768e347d18c3606b4cd0000c5e69f3bd20 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2003, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays hashtables io kernel math math.parser memory
-namespaces parser sequences strings io.styles
+namespaces parser lexer sequences strings io.styles
 vectors words generic system combinators continuations debugger
 definitions compiler.units accessors ;
 IN: listener
@@ -51,7 +51,7 @@ SYMBOL: error-hook
     listener-hook get call prompt.
     [ read-quot [ [ error-hook get call ] recover ] [ bye ] if* ]
     [
-        dup parse-error? [
+        dup lexer-error? [
             error-hook get call
         ] [
             rethrow
index 2ec9f2de544aa86b8bc065cbac5b87ebf32e06d5..1aecfbd60d9182a8575001df4f6c2445391533e4 100755 (executable)
@@ -1,7 +1,7 @@
 USING: help.markup help.syntax kernel sequences words
 math strings vectors quotations generic effects classes
 vocabs.loader definitions io vocabs source-files
-quotations namespaces compiler.units assocs ;
+quotations namespaces compiler.units assocs lexer ;
 IN: parser
 
 ARTICLE: "vocabulary-search-shadow" "Shadowing word names"
@@ -135,25 +135,6 @@ $nl
 { $subsection "defining-words" }
 { $subsection "parsing-tokens" } ;
 
-ARTICLE: "parser-lexer" "The lexer"
-"Two variables that encapsulate internal parser state:"
-{ $subsection file }
-{ $subsection lexer }
-"Creating a default lexer:"
-{ $subsection <lexer> }
-"A word to test of the end of input has been reached:"
-{ $subsection still-parsing? }
-"A word to advance the lexer to the next line:"
-{ $subsection next-line }
-"Two generic words to override the lexer's token boundary detection:"
-{ $subsection skip-blank }
-{ $subsection skip-word }
-"A utility used when parsing string literals:"
-{ $subsection parse-string }
-"The parser can be invoked with a custom lexer:"
-{ $subsection (parse-lines) }
-{ $subsection with-parser } ;
-
 ARTICLE: "parser-files" "Parsing source files"
 "The parser can run source files:"
 { $subsection run-file }
@@ -192,25 +173,6 @@ $nl
 
 ABOUT: "parser"
 
-: $parsing-note ( children -- )
-    drop
-    "This word should only be called from parsing words."
-    $notes ;
-
-HELP: lexer
-{ $var-description "Stores the current " { $link lexer } " instance." }
-{ $class-description "An object for tokenizing parser input. It has the following slots:"
-    { $list
-        { { $link lexer-text } " - the lines being parsed; an array of strings" }
-        { { $link lexer-line } " - the line number being parsed; unlike most indices this is 1-based for friendlier error reporting and integration with text editors" }
-        { { $link lexer-column } " - the current column position, zero-based" }
-    }
-"Custom lexing can be implemented by delegating a tuple to an instance of this class and implementing the " { $link skip-word } " and " { $link skip-blank } " generic words." } ;
-
-HELP: <lexer>
-{ $values { "text" "a sequence of strings" } { "lexer" lexer } }
-{ $description "Creates a new lexer for tokenizing the given sequence of lines." } ;
-
 HELP: location
 { $values { "loc" "a " { $snippet "{ path line# }" } " pair" } }
 { $description "Outputs the current parser location. This value can be passed to " { $link set-where } " or " { $link remember-definition } "." } ;
@@ -226,73 +188,9 @@ HELP: parser-notes?
 { $values { "?" "a boolean" } }
 { $description "Tests if the parser will print various notes and warnings. To disable parser notes, either set " { $link parser-notes } " to " { $link f } ", or pass the " { $snippet "-quiet" } " command line switch." } ;
 
-HELP: next-line
-{ $values { "lexer" lexer } }
-{ $description "Advances the lexer to the next input line, discarding the remainder of the current line." } ;
-
-HELP: parse-error
-{ $error-description "Thrown when the parser encounters invalid input. A parse error wraps an underlying error and holds the file being parsed, line number, and column number." } ;
-
-HELP: <parse-error>
-{ $values { "msg" "an error" } { "error" parse-error } }
-{ $description "Creates a new " { $link parse-error } ", filling in the location information from the current " { $link lexer } "." } ;
-
-HELP: skip
-{ $values { "i" "a starting index" } { "seq" sequence } { "?" "a boolean" } { "n" integer } }
-{ $description "Skips to the first space character (if " { $snippet "boolean" } " is " { $link f } ") or the first non-space character (otherwise)." } ;
-
-HELP: change-lexer-column
-{ $values { "lexer" lexer } { "quot" "a quotation with stack effect " { $snippet "( col line -- newcol )" } } }
-{ $description "Applies a quotation to the current column and line text to produce a new column, and moves the lexer position." } ;
-
-HELP: skip-blank
-{ $values { "lexer" lexer } }
-{ $contract "Skips whitespace characters." }
-{ $notes "Custom lexers can implement this generic word." } ;
-
-HELP: skip-word
-{ $values { "lexer" lexer } }
-{ $contract
-    "Skips until the end of the current token."
-    $nl
-    "The default implementation treats a single " { $snippet "\"" } " as a word by itself; otherwise it searches forward until a whitespace character or the end of the line."
-}
-{ $notes "Custom lexers can implement this generic word." } ;
-
-HELP: still-parsing-line?
-{ $values { "lexer" lexer } { "?" "a boolean" } }
-{ $description "Outputs " { $link f } " if the end of the current line has been reached, " { $link t } " otherwise." } ;
-
-HELP: parse-token
-{ $values { "lexer" lexer } { "str/f" "a " { $link string } " or " { $link f } } }
-{ $description "Reads the next token from the lexer. Tokens are delimited by whitespace, with the exception that " { $snippet "\"" } " is treated like a single token even when not followed by whitespace." } ;
-
-HELP: scan
-{ $values { "str/f" "a " { $link string } " or " { $link f } } }
-{ $description "Reads the next token from the lexer. See " { $link parse-token } " for details." }
-$parsing-note ;
-
-HELP: bad-escape
-{ $error-description "Indicates the parser encountered an invalid escape code following a backslash (" { $snippet "\\" } ") in a string literal. See " { $link "escape" } " for a list of valid escape codes." } ;
-
 HELP: bad-number
 { $error-description "Indicates the parser encountered an invalid numeric literal." } ;
 
-HELP: escape
-{ $values { "escape" "a single-character escape" } { "ch" "a character" } }
-{ $description "Converts from a single-character escape code and the corresponding character." }
-{ $examples { $example "USING: kernel parser prettyprint ;" "CHAR: n escape CHAR: \\n = ." "t" } } ;
-
-HELP: parse-string
-{ $values { "str" "a new " { $link string } } }
-{ $description "Parses the line until a quote (\"), interpreting escape codes along the way." }
-{ $errors "Throws an error if the string contains an invalid escape sequence." }
-$parsing-note ;
-
-HELP: still-parsing?
-{ $values { "lexer" lexer } { "?" "a boolean" } }
-{ $description "Outputs " { $link f } " if end of input has been reached, " { $link t } " otherwise." } ;
-
 HELP: use
 { $var-description "A variable holding the current vocabulary search path as a sequence of assocs." } ;
 
@@ -338,12 +236,6 @@ HELP: create-in
 { $description "Creates a word in the current vocabulary. Until re-defined, the word throws an error when invoked." }
 $parsing-note ;
 
-HELP: parse-tokens
-{ $values { "end" string } { "seq" "a new sequence of strings" } }
-{ $description "Reads a sequence of tokens until the first occurrence of " { $snippet "end" } ". The tokens remain as strings and are not processed in any way." }
-{ $examples "This word is used to implement " { $link POSTPONE: USING: } "." }
-$parsing-note ;
-
 HELP: CREATE
 { $values { "word" word } }
 { $description "Reads the next token from the line currently being parsed, and creates a word with that name in the current vocabulary." }
@@ -369,31 +261,6 @@ HELP: scan-word
 { $errors "Throws an error if the token does not name a word, and does not parse as a number." }
 $parsing-note ;
 
-HELP: invalid-slot-name
-{ $values { "name" string } }
-{ $description "Throws an " { $link invalid-slot-name } " error." }
-{ $error-description "Thrown by " { $link POSTPONE: TUPLE: } " and " { $link POSTPONE: ERROR: } " if a suspect token appears as a slot name." }
-{ $notes "The suspect tokens are chosen so that the following code raises this parse error, instead of silently greating a tuple with garbage slots:"
-    { $code
-        "TUPLE: my-mistaken-tuple slot-a slot-b"
-        ""
-        ": some-word ( a b c -- ) ... ;"
-    }
-} ;
-
-HELP: unexpected
-{ $values { "want" "a " { $link word } " or " { $link f } } { "got" word } }
-{ $description "Throws an " { $link unexpected } " error." }
-{ $error-description "Thrown by the parser if an unmatched closing delimiter is encountered." }
-{ $examples
-    "Parsing the following snippet will throw this error:"
-    { $code "[ 1 2 3 }" }
-} ;
-
-HELP: unexpected-eof
-{ $values { "word" "a " { $link word } } }
-{ $description "Throws an " { $link unexpected } " error indicating the parser was looking for an occurrence of " { $snippet "word" } " but encountered end of file." } ;
-
 HELP: parse-step
 { $values { "accum" vector } { "end" word } { "?" "a boolean" } }
 { $description "Parses a token. If the token is a number or an ordinary word, it is added to the accumulator. If it is a parsing word, calls the parsing word with the accumulator on the stack. Outputs " { $link f } " if " { $snippet "end" } " is encountered, " { $link t } " otherwise." }
@@ -417,28 +284,15 @@ HELP: parsed
 { $description "Convenience word for parsing words. It behaves exactly the same as " { $link push } ", except the accumulator remains on the stack." }
 $parsing-note ;
 
-HELP: with-parser
-{ $values { "lexer" lexer } { "quot" "a quotation with stack effect " { $snippet "( -- accum )" } } { "newquot" "a new " { $link quotation } } }
-{ $description "Sets up the parser and calls the quotation. The quotation can make use of parsing words such as " { $link scan } " and " { $link parse-until } ". It must yield a sequence, which is converted to a quotation and output. Any errors thrown by the quotation are wrapped in parse errors." } ;
-
 HELP: (parse-lines)
 { $values { "lexer" lexer } { "quot" "a new " { $link quotation } } }
 { $description "Parses Factor source code using a custom lexer. The vocabulary search path is taken from the current scope." }
-{ $errors "Throws a " { $link parse-error } " if the input is malformed." } ;
+{ $errors "Throws a " { $link lexer-error } " if the input is malformed." } ;
 
 HELP: parse-lines
 { $values { "lines" "a sequence of strings" } { "quot" "a new " { $link quotation } } }
 { $description "Parses Factor source code which has been tokenized into lines. The vocabulary search path is taken from the current scope." }
-{ $errors "Throws a " { $link parse-error } " if the input is malformed." } ;
-
-HELP: lexer-factory
-{ $var-description "A variable holding a quotation with stack effect " { $snippet "( lines -- lexer )" } ". This quotation is called by the parser to create " { $link lexer } " instances. This variable can be rebound to a quotation which outputs a custom tuple delegating to " { $link lexer } " to customize syntax." } ;
-
-HELP: parse-effect
-{ $values { "end" string } { "effect" "an instance of " { $link effect } } }
-{ $description "Parses a stack effect from the current input line." }
-{ $examples "This word is used by " { $link POSTPONE: ( } " and " { $link POSTPONE: (( } " to parse stack effect declarations." }
-$parsing-note ;
+{ $errors "Throws a " { $link lexer-error } " if the input is malformed." } ;
 
 HELP: parse-base
 { $values { "base" "an integer between 2 and 36" } { "parsed" integer } }
index 555c6eb32c9a73b3a3724f52e77eafd74d7fda67..eb37d556d032208772aa28906151a6a4b615efc7 100755 (executable)
@@ -485,3 +485,9 @@ must-fail-with
 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
 
 [ "DEFER: blah" eval ] [ error>> no-current-vocab? ] must-fail-with
+
+[
+    "IN: parser.tests : blah ; parsing FORGET: blah" eval
+] [
+    error>> staging-violation?
+] must-fail-with
index 129d5ef2ee77ed479c7c9a8c5df5eff5d5e1542b..44708f11f369ea323be2dbe18b1cd9bb8bcc2606 100755 (executable)
@@ -4,38 +4,17 @@ USING: arrays definitions generic assocs kernel math namespaces
 prettyprint sequences strings vectors words quotations inspector
 io.styles io combinators sorting splitting math.parser effects
 continuations debugger io.files io.streams.string vocabs
-io.encodings.utf8 source-files classes classes.tuple hashtables
-compiler.errors compiler.units accessors sets ;
+io.encodings.utf8 source-files classes hashtables
+compiler.errors compiler.units accessors sets lexer ;
 IN: parser
 
-TUPLE: lexer text line line-text line-length column ;
-
-: next-line ( lexer -- )
-    dup [ line>> ] [ text>> ] bi ?nth >>line-text
-    dup line-text>> length >>line-length
-    [ 1+ ] change-line
-    0 >>column
-    drop ;
-
-: new-lexer ( text class -- lexer )
-    new
-        0 >>line
-        swap >>text
-    dup next-line ; inline
-
-: <lexer> ( text -- lexer )
-    lexer new-lexer ;
-
 : location ( -- loc )
-    file get lexer get lexer-line 2dup and
-    [ >r source-file-path r> 2array ] [ 2drop f ] if ;
+    file get lexer get line>> 2dup and
+    [ >r path>> r> 2array ] [ 2drop f ] if ;
 
 : save-location ( definition -- )
     location remember-definition ;
 
-: save-class-location ( class -- )
-    location remember-class ;
-
 SYMBOL: parser-notes
 
 t parser-notes set-global
@@ -43,13 +22,6 @@ t parser-notes set-global
 : parser-notes? ( -- ? )
     parser-notes get "quiet" get not and ;
 
-: file. ( file -- )
-    [
-        source-file-path <pathname> pprint
-    ] [
-        "<interactive>" write
-    ] if* ":" write ;
-
 : note. ( str -- )
     parser-notes? [
         file get file.
@@ -61,143 +33,9 @@ t parser-notes set-global
         "Note: " write dup print
     ] when drop ;
 
-: skip ( i seq ? -- n )
-    over >r
-    [ swap CHAR: \s eq? xor ] curry find-from drop
-    [ r> drop ] [ r> length ] if* ;
-
-: change-lexer-column ( lexer quot -- )
-    swap
-    [ dup lexer-column swap lexer-line-text rot call ] keep
-    set-lexer-column ; inline
-
-GENERIC: skip-blank ( lexer -- )
-
-M: lexer skip-blank ( lexer -- )
-    [ t skip ] change-lexer-column ;
-
-GENERIC: skip-word ( lexer -- )
-
-M: lexer skip-word ( lexer -- )
-    [
-        2dup nth CHAR: " eq? [ drop 1+ ] [ f skip ] if
-    ] change-lexer-column ;
-
-: still-parsing? ( lexer -- ? )
-    dup lexer-line swap lexer-text length <= ;
-
-: still-parsing-line? ( lexer -- ? )
-    dup lexer-column swap lexer-line-length < ;
-
-: (parse-token) ( lexer -- str )
-    [ lexer-column ] keep
-    [ skip-word ] keep
-    [ lexer-column ] keep
-    lexer-line-text subseq ;
-
-:  parse-token ( lexer -- str/f )
-    dup still-parsing? [
-        dup skip-blank
-        dup still-parsing-line?
-        [ (parse-token) ] [ dup next-line parse-token ] if
-    ] [ drop f ] if ;
-
-: scan ( -- str/f ) lexer get parse-token ;
-
-ERROR: bad-escape ;
-
-M: bad-escape summary drop "Bad escape code" ;
-
-: escape ( escape -- ch )
-    H{
-        { CHAR: a  CHAR: \a }
-        { CHAR: e  CHAR: \e }
-        { CHAR: n  CHAR: \n }
-        { CHAR: r  CHAR: \r }
-        { CHAR: t  CHAR: \t }
-        { CHAR: s  CHAR: \s }
-        { CHAR: \s CHAR: \s }
-        { CHAR: 0  CHAR: \0 }
-        { CHAR: \\ CHAR: \\ }
-        { CHAR: \" CHAR: \" }
-    } at [ bad-escape ] unless* ;
-
-SYMBOL: name>char-hook
-
-name>char-hook global [
-    [ "Unicode support not available" throw ] or
-] change-at
-
-: unicode-escape ( str -- ch str' )
-    "{" ?head-slice [
-        CHAR: } over index cut-slice
-        >r >string name>char-hook get call r>
-        rest-slice
-    ] [
-        6 cut-slice >r hex> r>
-    ] if ;
-
-: next-escape ( str -- ch str' )
-    "u" ?head-slice [
-        unicode-escape
-    ] [
-        unclip-slice escape swap
-    ] if ;
-
-: (parse-string) ( str -- m )
-    dup [ "\"\\" member? ] find dup [
-        >r cut-slice >r % r> rest-slice r>
-        dup CHAR: " = [
-            drop slice-from
-        ] [
-            drop next-escape >r , r> (parse-string)
-        ] if
-    ] [
-        "Unterminated string" throw
-    ] if ;
-
-: parse-string ( -- str )
-    lexer get [
-        [ swap tail-slice (parse-string) ] "" make swap
-    ] change-lexer-column ;
-
-TUPLE: parse-error file line column line-text error ;
-
-: <parse-error> ( msg -- error )
-    \ parse-error new
-        file get >>file
-        lexer get line>> >>line
-        lexer get column>> >>column
-        lexer get line-text>> >>line-text
-        swap >>error ;
-
-: parse-dump ( error -- )
-    {
-        [ file>> file. ]
-        [ line>> number>string print ]
-        [ line-text>> dup string? [ print ] [ drop ] if ]
-        [ column>> 0 or CHAR: \s <string> write ]
-    } cleave
-    "^" print ;
-
-M: parse-error error.
-    [ parse-dump ] [ error>> error. ] bi ;
-
-M: parse-error summary
-    error>> summary ;
-
-M: parse-error compute-restarts
-    error>> compute-restarts ;
-
-M: parse-error error-help
-    error>> error-help ;
-
 SYMBOL: use
 SYMBOL: in
 
-: word/vocab% ( word -- )
-    "(" % dup word-vocabulary % " " % word-name % ")" % ;
-
 : (use+) ( vocab -- )
     vocab-words use get push ;
 
@@ -216,25 +54,8 @@ SYMBOL: in
 : set-in ( name -- )
     check-vocab-string dup in set create-vocab (use+) ;
 
-ERROR: unexpected want got ;
-
-PREDICATE: unexpected-eof < unexpected
-    unexpected-got not ;
-
 M: parsing-word stack-effect drop (( parsed -- parsed )) ;
 
-: unexpected-eof ( word -- * ) f unexpected ;
-
-: (parse-tokens) ( accum end -- accum )
-    scan 2dup = [
-        2drop
-    ] [
-        [ pick push (parse-tokens) ] [ unexpected-eof ] if*
-    ] if ;
-
-: parse-tokens ( end -- seq )
-    100 <vector> swap (parse-tokens) >array ;
-
 ERROR: no-current-vocab ;
 
 M: no-current-vocab summary ( obj -- )
@@ -248,18 +69,8 @@ M: no-current-vocab summary ( obj -- )
 
 : CREATE ( -- word ) scan create-in ;
 
-: CREATE-GENERIC ( -- word ) CREATE dup reset-word ;
-
 : CREATE-WORD ( -- word ) CREATE dup reset-generic ;
 
-: create-class-in ( word -- word )
-    current-vocab create
-    dup save-class-location
-    dup predicate-word dup set-word save-location ;
-
-: CREATE-CLASS ( -- word )
-    scan create-class-in ;
-
 : word-restarts ( possibilities -- restarts )
     natural-sort [
         [ "Use the word " swap summary append ] keep
@@ -296,62 +107,6 @@ M: no-word-error summary
         ] ?if
     ] when ;
 
-: create-method-in ( class generic -- method )
-    create-method f set-word dup save-location ;
-
-: CREATE-METHOD ( -- method )
-    scan-word bootstrap-word scan-word create-method-in ;
-
-: shadowed-slots ( superclass slots -- shadowed )
-    >r all-slot-names r> intersect ;
-
-: check-slot-shadowing ( class superclass slots -- )
-    shadowed-slots [
-        [
-            "Definition of slot ``" %
-            %
-            "'' in class ``" %
-            word-name %
-            "'' shadows a superclass slot" %
-        ] "" make note.
-    ] with each ;
-
-ERROR: invalid-slot-name name ;
-
-M: invalid-slot-name summary
-    drop
-    "Invalid slot name" ;
-
-: (parse-tuple-slots) ( -- )
-    #! This isn't meant to enforce any kind of policy, just
-    #! to check for mistakes of this form:
-    #!
-    #! TUPLE: blahblah foo bing
-    #!
-    #! : ...
-    scan {
-        { [ dup not ] [ unexpected-eof ] }
-        { [ dup { ":" "(" "<" } member? ] [ invalid-slot-name ] }
-        { [ dup ";" = ] [ drop ] }
-        [ , (parse-tuple-slots) ]
-    } cond ;
-
-: parse-tuple-slots ( -- seq )
-    [ (parse-tuple-slots) ] { } make ;
-
-: parse-tuple-definition ( -- class superclass slots )
-    CREATE-CLASS
-    scan {
-        { ";" [ tuple f ] }
-        { "<" [ scan-word parse-tuple-slots ] }
-        [ >r tuple parse-tuple-slots r> prefix ]
-    } case 3dup check-slot-shadowing ;
-
-ERROR: not-in-a-method-error ;
-
-M: not-in-a-method-error summary
-    drop "call-next-method can only be called in a method definition" ;
-
 ERROR: staging-violation word ;
 
 M: staging-violation summary
@@ -362,6 +117,10 @@ M: staging-violation summary
     dup changed-definitions get key? [ staging-violation ] when
     execute ;
 
+: scan-object ( -- object )
+    scan-word dup parsing-word?
+    [ V{ } clone swap execute-parsing first ] when ;
+
 : parse-step ( accum end -- accum ? )
     scan-word {
         { [ 2dup eq? ] [ 2drop f ] }
@@ -379,37 +138,12 @@ M: staging-violation summary
 
 : parsed ( accum obj -- accum ) over push ;
 
-: with-parser ( lexer quot -- newquot )
-    swap lexer set
-    [ call >quotation ] [ <parse-error> rethrow ] recover ;
-
 : (parse-lines) ( lexer -- quot )
-    [ f parse-until ] with-parser ;
-
-SYMBOL: lexer-factory
-
-[ <lexer> ] lexer-factory set-global
+    [ f parse-until >quotation ] with-lexer ;
 
 : parse-lines ( lines -- quot )
     lexer-factory get call (parse-lines) ;
 
-! Parsing word utilities
-: parse-effect ( end -- effect )
-    parse-tokens dup { "(" "((" } intersect empty? [
-        { "--" } split1 dup [
-            <effect>
-        ] [
-            "Stack effect declaration must contain --" throw
-        ] if
-    ] [
-        "Stack effect declaration must not contain ( or ((" throw
-    ] if ;
-
-ERROR: bad-number ;
-
-: parse-base ( parsed base -- parsed )
-    scan swap base> [ bad-number ] unless* parsed ;
-
 : parse-literal ( accum end quot -- accum )
     >r parse-until r> call parsed ; inline
 
@@ -418,40 +152,14 @@ ERROR: bad-number ;
 
 : (:) ( -- word def ) CREATE-WORD parse-definition ;
 
-SYMBOL: current-class
-SYMBOL: current-generic
-
-: with-method-definition ( quot -- parsed )
-    [
-        >r
-        [ "method-class" word-prop current-class set ]
-        [ "method-generic" word-prop current-generic set ]
-        [ ] tri
-        r> call
-    ] with-scope ; inline
-
-: (M:) ( method def -- )
-    CREATE-METHOD [ parse-definition ] with-method-definition ;
-
-: scan-object ( -- object )
-    scan-word dup parsing-word?
-    [ V{ } clone swap execute first ] when ;
-
-GENERIC: expected>string ( obj -- str )
-
-M: f expected>string drop "end of input" ;
-M: word expected>string word-name ;
-M: string expected>string ;
-
-M: unexpected error.
-    "Expected " write
-    dup unexpected-want expected>string write
-    " but got " write
-    unexpected-got expected>string print ;
+ERROR: bad-number ;
 
 M: bad-number summary
     drop "Bad number literal" ;
 
+: parse-base ( parsed base -- parsed )
+    scan swap base> [ bad-number ] unless* parsed ;
+
 SYMBOL: bootstrap-syntax
 
 : with-file-vocabs ( quot -- )
index 454f1489741d04e1e05ff0a0d516c03c1fae01a0..0577dacc8529d6ebd0785df39d8d51c06f8d2375 100755 (executable)
@@ -75,11 +75,36 @@ M: pathname forget*
 
 SYMBOL: file
 
+TUPLE: source-file-error file error ;
+
+: <source-file-error> ( msg -- error )
+    \ source-file-error new
+        file get >>file
+        swap >>error ;
+
+: file. ( file -- ) path>> <pathname> pprint ;
+
+M: source-file-error error.
+    "Error while parsing " write
+    [ file>> file. nl ] [ error>> error. ] bi ;
+
+M: source-file-error summary
+    error>> summary ;
+
+M: source-file-error compute-restarts
+    error>> compute-restarts ;
+
+M: source-file-error error-help
+    error>> error-help ;
+
 : with-source-file ( name quot -- )
     #! Should be called from inside with-compilation-unit.
     [
         swap source-file
         dup file set
         source-file-definitions old-definitions set
-        [ ] [ file get rollback-source-file ] cleanup
+        [
+            file get rollback-source-file
+            <source-file-error> rethrow
+        ] recover
     ] with-scope ; inline
diff --git a/core/strings/parser/parser-docs.factor b/core/strings/parser/parser-docs.factor
new file mode 100644 (file)
index 0000000..0aa6d48
--- /dev/null
@@ -0,0 +1,16 @@
+USING: help.markup help.syntax strings lexer ;
+IN: strings.parser
+
+HELP: bad-escape
+{ $error-description "Indicates the parser encountered an invalid escape code following a backslash (" { $snippet "\\" } ") in a string literal. See " { $link "escape" } " for a list of valid escape codes." } ;
+
+HELP: escape
+{ $values { "escape" "a single-character escape" } { "ch" "a character" } }
+{ $description "Converts from a single-character escape code and the corresponding character." }
+{ $examples { $example "USING: kernel parser prettyprint ;" "CHAR: n escape CHAR: \\n = ." "t" } } ;
+
+HELP: parse-string
+{ $values { "str" "a new " { $link string } } }
+{ $description "Parses the line until a quote (\"), interpreting escape codes along the way." }
+{ $errors "Throws an error if the string contains an invalid escape sequence." }
+$parsing-note ;
diff --git a/core/strings/parser/parser.factor b/core/strings/parser/parser.factor
new file mode 100644 (file)
index 0000000..08421b4
--- /dev/null
@@ -0,0 +1,62 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel inspector assocs namespaces splitting sequences
+strings math.parser lexer ;
+IN: strings.parser
+
+ERROR: bad-escape ;
+
+M: bad-escape summary drop "Bad escape code" ;
+
+: escape ( escape -- ch )
+    H{
+        { CHAR: a  CHAR: \a }
+        { CHAR: e  CHAR: \e }
+        { CHAR: n  CHAR: \n }
+        { CHAR: r  CHAR: \r }
+        { CHAR: t  CHAR: \t }
+        { CHAR: s  CHAR: \s }
+        { CHAR: \s CHAR: \s }
+        { CHAR: 0  CHAR: \0 }
+        { CHAR: \\ CHAR: \\ }
+        { CHAR: \" CHAR: \" }
+    } at [ bad-escape ] unless* ;
+
+SYMBOL: name>char-hook
+
+name>char-hook global [
+    [ "Unicode support not available" throw ] or
+] change-at
+
+: unicode-escape ( str -- ch str' )
+    "{" ?head-slice [
+        CHAR: } over index cut-slice
+        >r >string name>char-hook get call r>
+        rest-slice
+    ] [
+        6 cut-slice >r hex> r>
+    ] if ;
+
+: next-escape ( str -- ch str' )
+    "u" ?head-slice [
+        unicode-escape
+    ] [
+        unclip-slice escape swap
+    ] if ;
+
+: (parse-string) ( str -- m )
+    dup [ "\"\\" member? ] find dup [
+        >r cut-slice >r % r> rest-slice r>
+        dup CHAR: " = [
+            drop slice-from
+        ] [
+            drop next-escape >r , r> (parse-string)
+        ] if
+    ] [
+        "Unterminated string" throw
+    ] if ;
+
+: parse-string ( -- str )
+    lexer get [
+        [ swap tail-slice (parse-string) ] "" make swap
+    ] change-lexer-column ;
index 91a453408dd8a811d84e4a45b699b2eb1671e9b6..dfba35f71ac99a9723d7957aaea86516a1067c1e 100755 (executable)
@@ -1,13 +1,14 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien arrays bit-arrays byte-arrays byte-vectors
-definitions generic hashtables kernel math
-namespaces parser sequences strings sbufs vectors words
-quotations io assocs splitting classes.tuple generic.standard
-generic.math classes io.files vocabs float-arrays
-classes.union classes.intersection classes.mixin
-classes.predicate classes.singleton compiler.units
-combinators debugger ;
+definitions generic hashtables kernel math namespaces parser
+lexer sequences strings strings.parser sbufs vectors
+words quotations io assocs splitting classes.tuple
+generic.standard generic.math generic.parser classes io.files
+vocabs float-arrays classes.parser classes.union
+classes.intersection classes.mixin classes.predicate
+classes.singleton classes.tuple.parser compiler.units
+combinators debugger effects.parser ;
 IN: bootstrap.syntax
 
 ! These words are defined as a top-level form, instead of with
index 7d3ef8975942e10369cb7870046eaf94a45b21c1..c83d4b5152b41e685f86846edaf15ed905b98dd3 100644 (file)
@@ -1,4 +1,4 @@
-USING: parser kernel math sequences namespaces assocs inspector
+USING: parser lexer kernel math sequences namespaces assocs inspector
 words splitting math.parser arrays sequences.next mirrors
 shuffle compiler.units ;
 IN: bitfields
index 0476cbf18b6dfcb9f2e42fb65e18f6f0d08f25be..b46e322d7bc01b4a1ec05527691186d1de6fe9dc 100755 (executable)
@@ -1,4 +1,4 @@
-USING: parser kernel namespaces ;
+USING: strings.parser kernel namespaces ;
 
 USE: unicode.breaks
 USE: unicode.case
index f4cfb2059174dc5d88d6748a42e3e1866d05700c..1dd1e0a26460cf7bccf996085761d7233a945c5b 100755 (executable)
@@ -2,7 +2,8 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: compiler io kernel cocoa.runtime cocoa.subclassing
 cocoa.messages cocoa.types sequences words vocabs parser
-core-foundation namespaces assocs hashtables compiler.units ;
+core-foundation namespaces assocs hashtables compiler.units
+lexer ;
 IN: cocoa
 
 : (remember-send) ( selector variable -- )
index b0ffb6ae544f56174e0878ac3202cb76555453dd..aa8dc4f9cfd53741877759118a3eff9eddd49970 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 USING: kernel math sequences words arrays io io.files namespaces
-math.parser assocs quotations parser parser-combinators
+math.parser assocs quotations parser lexer parser-combinators
 tools.time io.encodings.binary sequences.deep symbols combinators ;
 IN: cpu.8080.emulator
 
index 2b9e4cc021a598290296e7e784a9a36d5dcaee3f..0f50e40eb404f25d65061abd0a10c7710ba7d94d 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax parser vocabs.loader ;
+USING: help.markup help.syntax parser source-files vocabs.loader ;
 IN: editors
 
 ARTICLE: "editor" "Editor integration"
@@ -35,4 +35,4 @@ HELP: no-edit-hook
 { $error-description "Thrown when " { $link edit } " is called when the " { $link edit-hook } " variable is not set. See " { $link "editor" } "." } ;
 
 HELP: :edit
-{ $description "If the most recent error was a " { $link parse-error } " thrown while parsing a source file, opens the source file at the failing line in the default editor using the " { $link edit-hook } ". See " { $link "editor" } "." } ;
+{ $description "If the most recent error was a " { $link source-file-error } " thrown while parsing a source file, opens the source file at the failing line in the default editor using the " { $link edit-hook } ". See " { $link "editor" } "." } ;
index ec8313363e0e1d97c20fc329bf857f96aa1d1d90..29cbbca90e22d97f3a389e7382566892968ab280 100755 (executable)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser kernel namespaces sequences definitions io.files
-inspector continuations tools.crossref tools.vocabs 
-io prettyprint source-files assocs vocabs vocabs.loader
-io.backend splitting accessors ;
+USING: parser lexer kernel namespaces sequences definitions
+io.files inspector continuations tools.crossref tools.vocabs io
+prettyprint source-files assocs vocabs vocabs.loader io.backend
+splitting accessors ;
 IN: editors
 
 TUPLE: no-edit-hook ;
@@ -35,21 +35,27 @@ SYMBOL: edit-hook
 : edit-vocab ( name -- )
     vocab-source-path 1 edit-location ;
 
-GENERIC: find-parse-error ( error -- error' )
+GENERIC: error-file ( error -- file )
 
-M: parse-error find-parse-error
-    dup error>> find-parse-error [ ] [ ] ?if ;
+GENERIC: error-line ( error -- line )
 
-M: condition find-parse-error
-    error>> find-parse-error ;
+M: lexer-error error-line line>> ;
 
-M: object find-parse-error
-    drop f ;
+M: source-file-error error-file file>> path>> ;
+
+M: source-file-error error-line error>> error-line ;
+
+M: condition error-file error>> error-file ;
+
+M: condition error-line error>> error-line ;
+
+M: object error-file drop f ;
+
+M: object error-line drop f ;
 
 : :edit ( -- )
-    error get find-parse-error [
-        [ file>> path>> ] [ line>> ] bi edit-location
-    ] when* ;
+    error get [ error-file ] [ error-line ] bi
+    2dup and [ edit-location ] [ 2drop ] if ;
 
 : edit-each ( seq -- )
     [
index 76615a3de5ab8ac8dc66a23477045f2819836c8c..ba0ff5bedd6b43a586170a2b2e70c4fd0bb43967 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2007 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: io kernel prettyprint ui ui.gadgets ui.gadgets.panes
-ui.gadgets.scrollers ui.gadgets.theme ui.gestures colors ;
+ui.gadgets.scrollers ui.gadgets.theme ui.gestures colors
+accessors ;
 IN: gesture-logger
 
 TUPLE: gesture-logger stream ;
index dfbb7a12b8e14d219f7980903510bfc7b5696f29..246ad56e519e92b00573af23fe19534b6380738f 100755 (executable)
@@ -3,7 +3,7 @@ namespaces words sequences classes assocs vocabs kernel arrays
 prettyprint.backend kernel.private io generic math system
 strings sbufs vectors byte-arrays bit-arrays float-arrays
 quotations io.streams.byte-array io.encodings.string
-classes.builtin parser ;
+classes.builtin parser lexer ;
 IN: help.handbook
 
 ARTICLE: "conventions" "Conventions"
index 7eeb756a3979f061ab40146750743f6283b65782..cfa576d56fcd254de90e385d53fffa25cfa3df99 100644 (file)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 IN: html.templates.chloe.syntax
 USING: accessors kernel sequences combinators kernel namespaces
-classes.tuple assocs splitting words arrays memoize parser
+classes.tuple assocs splitting words arrays memoize parser lexer
 io io.files io.encodings.utf8 io.streams.string
 unicode.case tuple-syntax mirrors fry math urls
 multiline xml xml.data xml.writer xml.utilities
index 74e5c37ef1ae887827b7bc05536977021c3febab..e435fdce5f0b93987b29e51e0a7e5dfe58b765b0 100755 (executable)
@@ -4,7 +4,7 @@
 USING: continuations sequences kernel namespaces debugger
 combinators math quotations generic strings splitting
 accessors assocs fry
-parser io io.files io.streams.string io.encodings.utf8
+parser lexer io io.files io.streams.string io.encodings.utf8
 html.elements
 html.templates ;
 IN: html.templates.fhtml
@@ -55,8 +55,8 @@ DEFER: <% delimiter
 
 : parse-template-lines ( lines -- quot )
     <template-lexer> [
-        V{ } clone lexer get parse-%> f (parse-until)
-    ] with-parser ;
+        V{ } clone lexer get parse-%> f (parse-until) >quotation
+    ] with-lexer ;
 
 : parse-template ( string -- quot )
     [
index 522d0c1845fd4341c6a828bb8a1857a3ff04da80..a920d4e67a71f73f397e911c531500c834d033b5 100755 (executable)
@@ -5,6 +5,12 @@ assocs io.sockets db db.sqlite continuations urls hashtables
 accessors ;
 IN: http.tests
 
+[ "text/plain" latin1 ] [ "text/plain" parse-content-type ] unit-test
+
+[ "text/html" utf8 ] [ "text/html;  charset=UTF-8" parse-content-type ] unit-test
+
+[ "application/octet-stream" binary ] [ "application/octet-stream" parse-content-type ] unit-test
+
 : lf>crlf "\n" split "\r\n" join ;
 
 STRING: read-request-test-1
index 4001301cb1065a909dc25a43d9fb046c6a221737..d5712d5bab823f655b70c5bcc16596fa11d5bef8 100755 (executable)
@@ -211,7 +211,8 @@ TUPLE: post-data raw content content-type ;
     " " split harvest [ "=" split1 [ >lower ] dip ] { } map>assoc ;
 
 : parse-content-type ( content-type -- type encoding )
-    ";" split1 parse-content-type-attributes "charset" swap at ;
+    ";" split1 parse-content-type-attributes "charset" swap at
+    name>encoding over "text/" head? latin1 binary ? or ;
 
 : read-request ( -- request )
     <request>
@@ -310,7 +311,7 @@ M: response clone
     dup "content-type" header [
         parse-content-type
         [ >>content-type ]
-        [ name>encoding binary or >>content-charset ] bi*
+        [ >>content-charset ] bi*
     ] when* ;
 
 : read-response ( -- response )
index 33d629b10541f4b507d208c75cd71300beaf89fe..8f5e955998ec929a3f8c0afd496da3df975b5a77 100644 (file)
@@ -24,20 +24,13 @@ ARTICLE: "io.encodings.8-bit" "8-bit encodings"
 { $subsection koi8-r }
 { $subsection windows-1252 }
 { $subsection ebcdic }
-{ $subsection mac-roman }
-"Words used in defining these"
-{ $subsection 8-bit }
-{ $subsection define-8-bit-encoding } ;
+{ $subsection mac-roman } ;
 
 ABOUT: "io.encodings.8-bit"
 
 HELP: 8-bit
 { $class-description "Describes an 8-bit encoding, including its name (a symbol) and a table used for encoding and decoding." } ;
 
-HELP: define-8-bit-encoding
-{ $values { "name" string } { "stream" "an input stream" } }
-{ $description "Creates a new encoding. The stream should be in a similar format to those at " { $url "ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/" } } ;
-
 HELP: latin1
 { $description "This is the ISO-8859-1 encoding, also called Latin-1: Western European. It is an 8-bit superset of ASCII which is the default for a mimetype starting with 'text' and provides the characters necessary for most western European languages." } 
 { $see-also "encodings-introduction" } ;
index cc6a7d093e640f228f2d9c6fdb07eae25f306cd6..49eec6d65287944c4aabff54be9aa1ac5c3c6476 100755 (executable)
@@ -4,8 +4,8 @@ USING: kernel namespaces sequences sequences.private assocs math
 inference.transforms parser words quotations debugger macros
 arrays macros splitting combinators prettyprint.backend
 definitions prettyprint hashtables prettyprint.sections sets
-sequences.private effects generic compiler.units accessors
-locals.backend memoize ;
+sequences.private effects effects.parser generic generic.parser
+compiler.units accessors locals.backend memoize lexer ;
 IN: locals
 
 ! Inspired by
index 8a174034baa0bdd6b4dda21574e709c8bc3c06ac..0ae285d20d47d469ffccfbda8e9bcbfa44ec5ab4 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 !
 ! Based on pattern matching code from Paul Graham's book 'On Lisp'.
-USING: parser kernel words namespaces sequences classes.tuple
+USING: parser lexer kernel words namespaces sequences classes.tuple
 combinators macros assocs math effects ;
 IN: match
 
index 54c53e9bec2656a6eef1267b02b6b43e143d8b34..ba7a0ae04fc964d353bebae0f718bab1d07e457a 100644 (file)
@@ -1,4 +1,4 @@
-USING: io kernel math math.functions math.parser parser
+USING: io kernel math math.functions math.parser parser lexer
 namespaces sequences splitting grouping combinators
 continuations sequences.lib ;
 IN: money
index 3a4dc6fefb746f10fe55ecc3a475252ad23feff1..1b5b6f2393503f4bab19dae286c1a7f4e8a3b7de 100644 (file)
@@ -1,5 +1,5 @@
 
-USING: kernel io parser words namespaces quotations arrays assocs sequences
+USING: kernel io parser lexer words namespaces quotations arrays assocs sequences
        splitting grouping math shuffle ;
 
 IN: mortar
index ce79bdaf5f8f88ef150776edaad939c67b1500ae..cf671c5609c60d0e8e4b3575f333780060bfab05 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2007 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: namespaces parser kernel sequences words quotations math ;
+USING: namespaces parser lexer kernel sequences words quotations math ;
 IN: multiline
 
 : next-line-text ( -- str )
index 8f2eee9459d1cc7ac88d3f5ad4460d20aca5432c..fd547c8b5a3d3f9ae377b3efdd987423d2a4905d 100644 (file)
@@ -1,6 +1,6 @@
 USING: alien alien.syntax combinators kernel parser sequences
 system words namespaces hashtables init math arrays assocs
-continuations ;
+continuations lexer ;
 IN: opengl.gl.extensions
 
 ERROR: unknown-gl-platform ;
index dced2e5c0cec5cdac805fb6ef3ace370b6563c18..e951ad88581c1454914e41b93e796f491474ac7a 100755 (executable)
@@ -2,7 +2,7 @@
 ! Portions copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.syntax combinators kernel system namespaces
-assocs parser sequences words quotations math.bitfields ;
+assocs parser lexer sequences words quotations math.bitfields ;
 
 IN: openssl.libssl
 
index 5810a03f80f6be65438e703f6e39857080389b52..d636cc01526d8069e3a74936e3ac426458952b16 100644 (file)
@@ -1,5 +1,7 @@
-USING: kernel sequences assocs hashtables parser vocabs words namespaces
-vocabs.loader debugger sets ;
+! Copyright (C) 2007, 2008 Daniel Ehrenberg.
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel sequences assocs hashtables parser lexer
+vocabs words namespaces vocabs.loader debugger sets ;
 IN: qualified
 
 : define-qualified ( vocab-name prefix-name -- )
index 99e6b887c8706d35c1c00fcf315ec595c7916ba7..8872338f5d1159a3aa10039a5a2c26406c4feae2 100755 (executable)
@@ -1,5 +1,5 @@
 USING: arrays combinators kernel lists math math.parser
-namespaces parser parser-combinators parser-combinators.simple
+namespaces parser lexer parser-combinators parser-combinators.simple
 promises quotations sequences combinators.lib strings math.order
 assocs prettyprint.backend memoize unicode.case unicode.categories ;
 USE: io
index 7d50d384e25892436cbf19ea84bc629689065a5d..27e8cf1d9030df56b6df9e2b4abc3e6bdc30b785 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors arrays combinators combinators.cleave combinators.lib
 continuations db db.tuples db.types db.sqlite kernel math
-math.parser namespaces parser sets sequences sequences.deep
+math.parser namespaces parser lexer sets sequences sequences.deep
 sequences.lib strings words destructors ;
 IN: semantic-db
 
index 4c83c646416fced30f47fa64de190707baa7a40f..b5e8c16b022fd006808f858bed9a7d73f68b2192 100755 (executable)
@@ -1,4 +1,4 @@
-USING: kernel parser strings math namespaces sequences words io
+USING: kernel parser lexer strings math namespaces sequences words io
 arrays quotations debugger kernel.private sequences.private ;
 IN: state-machine
 
index 20cf16e640b5d5c8eb57cc724c80a4855547db08..6cf8eac6fbf37b11c76e5549ba3db3837a3ce9ea 100755 (executable)
@@ -1,6 +1,7 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: parser sequences words kernel classes.singleton ;
+USING: parser lexer sequences words kernel classes.singleton
+classes.parser ;
 IN: symbols
 
 : SYMBOLS:
index 3df5485f4e52f259c5b76fbeae1f2e5159326469..f9b56a1d8d0404651f1454ad204c48aa2aa223e5 100755 (executable)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: qualified io.streams.c init fry namespaces assocs kernel
-parser tools.deploy.config vocabs sequences words words.private
-memory kernel.private continuations io prettyprint
-vocabs.loader debugger system strings sets ;
+parser lexer strings.parser tools.deploy.config vocabs sequences
+words words.private memory kernel.private continuations io
+prettyprint vocabs.loader debugger system strings sets ;
 QUALIFIED: bootstrap.stage2
 QUALIFIED: classes
 QUALIFIED: command-line
index cf439f6407ca8f704db51dcd90f6b918694e3330..ce717f4211dfdeb7f98400ebfad6b8a13adbb711 100755 (executable)
@@ -1,4 +1,4 @@
-USING: kernel sequences slots parser words classes
+USING: kernel sequences slots parser lexer words classes
 slots.private mirrors ;
 IN: tuple-syntax
 
index 72bd4e43a328f61fd117aad4f077ee610e574f92..fcd3f9ab224c7933b6fed19e09b6f214546ae932 100755 (executable)
@@ -2,7 +2,7 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: arrays assocs combinators continuations documents
 hashtables io io.styles kernel math math.order math.vectors
-models namespaces parser prettyprint quotations sequences
+models namespaces parser lexer prettyprint quotations sequences
 strings threads listener classes.tuple ui.commands ui.gadgets
 ui.gadgets.editors ui.gadgets.presentations ui.gadgets.worlds
 ui.gestures definitions calendar concurrency.flags
@@ -149,7 +149,7 @@ M: interactor dispose drop ;
     mark>caret ;
 
 : handle-parse-error ( interactor error -- )
-    dup parse-error? [ 2dup go-to-error error>> ] when
+    dup lexer-error? [ 2dup go-to-error error>> ] when
     swap find-workspace debugger-popup ;
 
 : try-parse ( lines interactor -- quot/error/f )
@@ -157,7 +157,7 @@ M: interactor dispose drop ;
         drop parse-lines-interactive
     ] [
         2nip
-        dup parse-error? [
+        dup lexer-error? [
             dup error>> unexpected-eof? [ drop f ] when
         ] when
     ] recover ;
index b5ba25db4e27214264d67b1b1787330349f1ab6c..24107798045d1b49aa2bf2446c8508642bf0f806 100755 (executable)
@@ -1,4 +1,4 @@
-USING: unicode.data kernel math sequences parser bit-arrays
+USING: unicode.data kernel math sequences parser lexer bit-arrays
 namespaces sequences.private arrays quotations assocs
 classes.predicate math.order ;
 IN: unicode.syntax
index 38511de8e87641c458b926b837a057e3dc147436..de661bdd9da9d19a0a750753cb1268a0438ca0e2 100644 (file)
@@ -1,9 +1,10 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel unicode.categories combinators sequences splitting
+USING: kernel unicode.categories combinators combinators.lib
+sequences splitting
 fry namespaces assocs arrays strings io.sockets
 io.sockets.secure io.encodings.string io.encodings.utf8
-math math.parser accessors mirrors parser
+math math.parser accessors mirrors parser strings.parser lexer
 prettyprint.backend hashtables present ;
 IN: urls
 
@@ -11,12 +12,11 @@ IN: urls
     #! In a URL, can this character be used without
     #! URL-encoding?
     {
-        { [ dup letter? ] [ t ] }
-        { [ dup LETTER? ] [ t ] }
-        { [ dup digit? ] [ t ] }
-        { [ dup "/_-." member? ] [ t ] }
-        [ f ]
-    } cond nip ; foldable
+        [ letter? ]
+        [ LETTER? ]
+        [ digit? ]
+        [ "/_-." member? ]
+    } 1|| ; foldable
 
 <PRIVATE
 
index 5942215a699b6473735d5288236b7a633a37a637..e3e13be3a9666f873dc4a00e29be469145cf36a2 100644 (file)
@@ -2,7 +2,7 @@
 
 ! Thanks to Mackenzie Straight for the idea
 
-USING: kernel parser words namespaces sequences quotations ;
+USING: kernel parser lexer words namespaces sequences quotations ;
 
 IN: vars
 
index 44bd1934f8a7127eadbb88114d7be68100fdba91..bf4bd618b76d83f72b63d89ced4387ba87d9bfa4 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2006, 2007 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
 USING: namespaces kernel xml.data xml.utilities assocs splitting
-sequences parser quotations sequences.lib xml.utilities ;
+sequences parser lexer quotations sequences.lib xml.utilities ;
 IN: xml.generator
 
 : comment, ( string -- ) <comment> , ;
@@ -36,7 +36,7 @@ IN: xml.generator
     [ \ contained*, parsed ] [
         scan-word \ [ =
         [ POSTPONE: [ \ tag*, parsed ]
-        [ "Expected [ missing" <parse-error> throw ] if
+        [ "Expected [ missing" throw ] if
     ] if ;
 
 DEFER: >>
index 87a0242412b45081b46e1cd40fb2fa7a80f6a502..c53bbf3b0f2589226107db773e5425c32c30d2e8 100755 (executable)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel namespaces sequences words io assocs
-quotations strings parser arrays xml.data xml.writer debugger
+quotations strings parser lexer arrays xml.data xml.writer debugger
 splitting vectors sequences.deep ;
 IN: xml.utilities
 
index b3adf5cb605b2b3cf0d42d0f6d818e7b759bff3e..4c95a45832e45382fd924c3ce468d199460b163e 100644 (file)
@@ -1,6 +1,6 @@
 USING: xmode.tokens xmode.rules xmode.keyword-map xml.data
 xml.utilities xml assocs kernel combinators sequences
-math.parser namespaces parser xmode.utilities regexp io.files ;
+math.parser namespaces parser lexer xmode.utilities regexp io.files ;
 IN: xmode.loader.syntax
 
 SYMBOL: ignore-case?
index 2e1d0a2872d216b684a9615e75912fe663eb594f..d6f9c427997f1618259f622e696588d586ff4153 100644 (file)
@@ -1,5 +1,5 @@
 USING: sequences assocs kernel quotations namespaces xml.data
-xml.utilities combinators macros parser words ;
+xml.utilities combinators macros parser lexer words ;
 IN: xmode.utilities
 
 : implies >r not r> or ; inline