diff --git a/core/alien/syntax/syntax.factor b/core/alien/syntax/syntax.factor index def5b02ba0..a756734f7b 100755 --- a/core/alien/syntax/syntax.factor +++ b/core/alien/syntax/syntax.factor @@ -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 diff --git a/core/classes/classes.factor b/core/classes/classes.factor index 0fef6de748..35ff475abf 100755 --- a/core/classes/classes.factor +++ b/core/classes/classes.factor @@ -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 ) diff --git a/core/classes/intersection/intersection.factor b/core/classes/intersection/intersection.factor index 7ea8e24f0a..cc24280384 100644 --- a/core/classes/intersection/intersection.factor +++ b/core/classes/intersection/intersection.factor @@ -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 ; diff --git a/core/classes/mixin/mixin.factor b/core/classes/mixin/mixin.factor index a2debe55a1..3924eb264c 100755 --- a/core/classes/mixin/mixin.factor +++ b/core/classes/mixin/mixin.factor @@ -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 index 0000000000..17a7b23552 --- /dev/null +++ b/core/classes/parser/parser.factor @@ -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 ; diff --git a/core/classes/predicate/predicate.factor b/core/classes/predicate/predicate.factor index c8de36582e..7ea60149f8 100755 --- a/core/classes/predicate/predicate.factor +++ b/core/classes/predicate/predicate.factor @@ -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 index 0000000000..f4ecb1461e --- /dev/null +++ b/core/classes/tuple/parser/parser-docs.factor @@ -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 index 0000000000..ab3be109e1 --- /dev/null +++ b/core/classes/tuple/parser/parser.factor @@ -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 ; diff --git a/core/classes/tuple/tuple-tests.factor b/core/classes/tuple/tuple-tests.factor index 604914bd5c..c93bd11ffe 100755 --- a/core/classes/tuple/tuple-tests.factor +++ b/core/classes/tuple/tuple-tests.factor @@ -4,7 +4,7 @@ namespaces quotations sequences.private classes continuations generic.standard effects classes.tuple classes.tuple.private arrays vectors strings compiler.units accessors classes.algebra calendar prettyprint io.streams.string splitting inspector -columns math.order classes.private ; +columns math.order classes.private slots.private ; IN: classes.tuple.tests TUPLE: rect x y w h ; @@ -94,7 +94,7 @@ TUPLE: size-test a b c d ; [ t ] [ T{ size-test } tuple-size - size-test tuple-size = + size-test tuple-layout layout-size = ] unit-test GENERIC: <yo-momma> @@ -220,7 +220,7 @@ C: <erg's-reshape-problem> erg's-reshape-problem [ "IN: classes.tuple.tests SYMBOL: not-a-class C: <not-a-class> not-a-class" eval -] [ error>> no-tuple-class? ] must-fail-with +] [ error>> not-a-tuple-class? ] must-fail-with ! Inheritance TUPLE: computer cpu ram ; @@ -252,7 +252,7 @@ C: <laptop> laptop test-laptop-slot-values [ laptop ] [ - "laptop" get tuple-layout + "laptop" get 1 slot dup layout-echelon swap layout-superclasses nth ] unit-test @@ -490,7 +490,7 @@ USE: vocabs ] with-compilation-unit ] unit-test -[ "USE: words T{ word }" eval ] [ error>> no-method? ] must-fail-with +[ "USE: words T{ word }" eval ] [ error>> not-a-tuple-class? ] must-fail-with ! Accessors not being forgotten... [ [ ] ] [ @@ -595,3 +595,6 @@ GENERIC: break-me ( obj -- ) [ ] [ "IN: classes.tuple.tests USE: math USE: kernel M: integer break-me drop ;" eval ] unit-test [ f ] [ \ break-me "methods" word-prop assoc-empty? ] unit-test + +! Insufficient type checking +[ \ vocab tuple>array drop ] must-fail diff --git a/core/classes/tuple/tuple.factor b/core/classes/tuple/tuple.factor index 5ba0b7e69c..df59f34ff4 100755 --- a/core/classes/tuple/tuple.factor +++ b/core/classes/tuple/tuple.factor @@ -9,32 +9,32 @@ IN: classes.tuple M: tuple class 1 slot 2 slot { word } declare ; -ERROR: no-tuple-class class ; +ERROR: not-a-tuple object ; + +: check-tuple ( object -- tuple ) + dup tuple? [ not-a-tuple ] unless ; inline + +ERROR: not-a-tuple-class class ; + +: check-tuple-class ( class -- class ) + dup tuple-class? [ not-a-tuple-class ] unless ; inline <PRIVATE -GENERIC: tuple-layout ( object -- layout ) +: tuple-layout ( class -- layout ) + check-tuple-class "layout" word-prop ; -M: tuple-class tuple-layout "layout" word-prop ; - -M: tuple tuple-layout 1 slot ; - -M: tuple-layout tuple-layout ; - -: tuple-size tuple-layout layout-size ; inline +: tuple-size ( tuple -- size ) + 1 slot layout-size ; inline : prepare-tuple>array ( tuple -- n tuple layout ) - [ tuple-size ] [ ] [ tuple-layout ] tri ; + check-tuple [ tuple-size ] [ ] [ 1 slot ] tri ; : copy-tuple-slots ( n tuple -- array ) [ array-nth ] curry map ; PRIVATE> -: check-tuple ( class -- ) - dup tuple-class? - [ drop ] [ no-tuple-class ] if ; - : tuple>array ( tuple -- array ) prepare-tuple>array >r copy-tuple-slots r> @@ -63,7 +63,7 @@ ERROR: bad-superclass class ; <PRIVATE : tuple= ( tuple1 tuple2 -- ? ) - 2dup [ tuple-layout ] bi@ eq? [ + 2dup [ 1 slot ] bi@ eq? [ [ drop tuple-size ] [ [ [ drop array-nth ] [ nip array-nth ] 3bi = ] 2curry ] 2bi all-integers? @@ -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 ; diff --git a/core/classes/union/union.factor b/core/classes/union/union.factor index 74e29cfb01..819e0ecb0b 100755 --- a/core/classes/union/union.factor +++ b/core/classes/union/union.factor @@ -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 ; diff --git a/core/compiler/compiler.factor b/core/compiler/compiler.factor index 4ee2fd5cdf..093b215013 100755 --- a/core/compiler/compiler.factor +++ b/core/compiler/compiler.factor @@ -46,7 +46,6 @@ SYMBOL: +failed+ ] tri ; : (compile) ( word -- ) - dup dup "compile-count" word-prop 0 or 1 + "compile-count" set-word-prop [ H{ } clone dependencies set diff --git a/core/continuations/continuations-docs.factor b/core/continuations/continuations-docs.factor index 3cb7d8a71e..f176e6ee19 100755 --- a/core/continuations/continuations-docs.factor +++ b/core/continuations/continuations-docs.factor @@ -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 diff --git a/core/cpu/x86/assembler/assembler.factor b/core/cpu/x86/assembler/assembler.factor index 452a102341..f8e0b0abb0 100755 --- a/core/cpu/x86/assembler/assembler.factor +++ b/core/cpu/x86/assembler/assembler.factor @@ -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 index 0000000000..5940663d42 --- /dev/null +++ b/core/cpu/x86/assembler/syntax/syntax.factor @@ -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/debugger/debugger.factor b/core/debugger/debugger.factor index cfad144737..2ac903a39b 100755 --- a/core/debugger/debugger.factor +++ b/core/debugger/debugger.factor @@ -209,8 +209,11 @@ M: inconsistent-next-method summary M: check-method summary drop "Invalid parameters for create-method" ; -M: no-tuple-class summary - drop "BOA constructors can only be defined for tuple classes" ; +M: not-a-tuple summary + drop "Not a tuple" ; + +M: not-a-tuple-class summary + drop "Not a tuple class" ; M: bad-superclass summary drop "Tuple classes can only inherit from other tuple classes" ; diff --git a/core/effects/effects.factor b/core/effects/effects.factor index 099260f111..d7923ad595 100755 --- a/core/effects/effects.factor +++ b/core/effects/effects.factor @@ -42,14 +42,14 @@ M: integer (stack-picture) drop "object" ; GENERIC: stack-effect ( word -- effect/f ) -M: symbol stack-effect drop 0 1 <effect> ; +M: symbol stack-effect drop (( -- symbol )) ; M: word stack-effect { "declared-effect" "inferred-effect" } swap word-props [ at ] curry map [ ] find nip ; M: effect clone - [ in>> clone ] keep effect-out clone <effect> ; + [ in>> clone ] [ out>> clone ] bi <effect> ; : split-shuffle ( stack shuffle -- stack1 stack2 ) in>> length cut* ; diff --git a/core/effects/parser/parser-docs.factor b/core/effects/parser/parser-docs.factor new file mode 100644 index 0000000000..6cb39d208d --- /dev/null +++ b/core/effects/parser/parser-docs.factor @@ -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 index 0000000000..8f28450de7 --- /dev/null +++ b/core/effects/parser/parser.factor @@ -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 index 0000000000..ba9cd5244c --- /dev/null +++ b/core/generic/parser/parser.factor @@ -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/inference/backend/backend.factor b/core/inference/backend/backend.factor index f8b071e803..59fbd289db 100755 --- a/core/inference/backend/backend.factor +++ b/core/inference/backend/backend.factor @@ -228,7 +228,7 @@ M: object constructor drop f ; 1 infer->r peek-d reify-curry 1 infer-r> - 2 1 <effect> swap #call consume/produce + (( obj quot -- curry )) swap #call consume/produce ] when* ; : reify-curries ( n -- ) diff --git a/core/inference/transforms/transforms-tests.factor b/core/inference/transforms/transforms-tests.factor index f90dd2350c..7f5f8035fb 100755 --- a/core/inference/transforms/transforms-tests.factor +++ b/core/inference/transforms/transforms-tests.factor @@ -1,7 +1,7 @@ IN: inference.transforms.tests USING: sequences inference.transforms tools.test math kernel quotations inference accessors combinators words arrays -classes ; +classes classes.tuple ; : compose-n-quot ( word -- quot' ) <repetition> >quotation ; : compose-n ( quot -- ) compose-n-quot call ; @@ -46,3 +46,9 @@ C: <color> color [ 16 -3 1/6 ] [ 4 3 6 \ spread-test word-def call ] unit-test [ fixnum instance? ] must-infer + +: bad-new-test ( -- obj ) V{ } new ; + +[ bad-new-test ] must-infer + +[ bad-new-test ] [ T{ not-a-tuple-class f V{ } } = ] must-fail-with diff --git a/core/inference/transforms/transforms.factor b/core/inference/transforms/transforms.factor index 5ca10c7545..8fc72b0f09 100755 --- a/core/inference/transforms/transforms.factor +++ b/core/inference/transforms/transforms.factor @@ -2,8 +2,9 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel words sequences generic math namespaces quotations assocs combinators math.bitfields inference.backend -inference.dataflow inference.state classes.tuple.private effects -inspector hashtables classes generic sets definitions ; +inference.dataflow inference.state classes.tuple +classes.tuple.private effects inspector hashtables classes +generic sets definitions ; IN: inference.transforms : pop-literals ( n -- rstate seq ) @@ -83,19 +84,26 @@ M: duplicated-slots-error summary ] 1 define-transform \ boa [ - dup +inlined+ depends-on - tuple-layout [ <tuple-boa> ] curry + dup tuple-class? [ + dup +inlined+ depends-on + tuple-layout [ <tuple-boa> ] curry + ] [ + [ not-a-tuple-class ] curry time-bomb + ] if ] 1 define-transform \ new [ 1 ensure-values peek-d value? [ - pop-literal - dup +inlined+ depends-on - tuple-layout [ <tuple> ] curry - swap infer-quot + pop-literal dup tuple-class? [ + dup +inlined+ depends-on + tuple-layout [ <tuple> ] curry + swap infer-quot + ] [ + \ not-a-tuple-class boa time-bomb drop + ] if ] [ - \ new 1 1 <effect> make-call-node + \ new (( class -- tuple )) make-call-node ] if ] "infer" set-word-prop diff --git a/core/inspector/inspector-tests.factor b/core/inspector/inspector-tests.factor index 72c1a9a6bf..c230364342 100644 --- a/core/inspector/inspector-tests.factor +++ b/core/inspector/inspector-tests.factor @@ -9,3 +9,29 @@ H{ } describe H{ } describe [ "fixnum instance\n" ] [ [ 3 describe ] with-string-writer ] unit-test + +[ ] [ inspector-hook get-global inspector-hook set ] unit-test + +[ ] [ H{ } clone inspect ] unit-test + +[ ] [ "a" "b" &add ] unit-test + +[ H{ { "b" "a" } } ] [ me get ] unit-test + +[ ] [ "x" 0 &put ] unit-test + +[ H{ { "b" "x" } } ] [ me get ] unit-test + +[ ] [ 0 &at ] unit-test + +[ "x" ] [ me get ] unit-test + +[ ] [ &back ] unit-test + +[ ] [ "y" 0 &rename ] unit-test + +[ H{ { "y" "x" } } ] [ me get ] unit-test + +[ ] [ 0 &delete ] unit-test + +[ H{ } ] [ me get ] unit-test diff --git a/core/inspector/inspector.factor b/core/inspector/inspector.factor index fd4e11901a..d32f1c90cf 100755 --- a/core/inspector/inspector.factor +++ b/core/inspector/inspector.factor @@ -3,7 +3,7 @@ USING: arrays generic hashtables io kernel assocs math namespaces prettyprint sequences strings io.styles vectors words quotations mirrors splitting math.parser classes vocabs refs -sets ; +sets sorting ; IN: inspector GENERIC: summary ( object -- string ) @@ -78,10 +78,17 @@ SYMBOL: +editable+ : summary. ( obj -- ) [ summary ] keep write-object nl ; +: sorted-keys ( assoc -- alist ) + dup mirror? [ keys ] [ + keys + [ [ unparse-short ] keep ] { } map>assoc + sort-keys values + ] if ; + : describe* ( obj flags -- ) clone [ dup summary. - make-mirror dup keys dup empty? [ + make-mirror dup sorted-keys dup empty? [ 2drop ] [ dup enum? [ +sequence+ on ] when diff --git a/core/kernel/kernel-tests.factor b/core/kernel/kernel-tests.factor index 4b129ad59d..c5bd0615a7 100755 --- a/core/kernel/kernel-tests.factor +++ b/core/kernel/kernel-tests.factor @@ -117,3 +117,8 @@ IN: kernel.tests : total-failure-2 [ ] (call) unimplemented ; [ total-failure-2 ] must-fail + +! From combinators.lib +[ 1 1 2 2 3 3 ] [ 1 2 3 [ dup ] tri@ ] unit-test +[ 1 4 9 ] [ 1 2 3 [ sq ] tri@ ] unit-test +[ [ sq ] tri@ ] must-infer diff --git a/core/lexer/lexer-docs.factor b/core/lexer/lexer-docs.factor new file mode 100644 index 0000000000..a7dcb161e5 --- /dev/null +++ b/core/lexer/lexer-docs.factor @@ -0,0 +1,109 @@ +IN: lexer +USING: help.markup help.syntax kernel math sequences strings +words quotations ; + +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 index 0000000000..3d65fb95ca --- /dev/null +++ b/core/lexer/lexer.factor @@ -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 diff --git a/core/listener/listener.factor b/core/listener/listener.factor index e00e64f4bc..4e2a8c768e 100755 --- a/core/listener/listener.factor +++ b/core/listener/listener.factor @@ -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 diff --git a/core/mirrors/mirrors.factor b/core/mirrors/mirrors.factor index 0a49163075..607ba1542f 100755 --- a/core/mirrors/mirrors.factor +++ b/core/mirrors/mirrors.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: assocs hashtables kernel sequences generic words arrays classes slots slots.private classes.tuple math vectors -quotations sorting prettyprint accessors ; +quotations accessors ; IN: mirrors : all-slots ( class -- slots ) @@ -47,13 +47,8 @@ M: mirror assoc-size mirror-slots length ; INSTANCE: mirror assoc -: sort-assoc ( assoc -- alist ) - >alist - [ [ first unparse-short ] keep ] { } map>assoc - sort-keys values ; - GENERIC: make-mirror ( obj -- assoc ) -M: hashtable make-mirror sort-assoc ; +M: hashtable make-mirror ; M: integer make-mirror drop f ; M: array make-mirror <enum> ; M: vector make-mirror <enum> ; diff --git a/core/optimizer/math/partial/partial.factor b/core/optimizer/math/partial/partial.factor index 8b5e25deb1..30a726e022 100644 --- a/core/optimizer/math/partial/partial.factor +++ b/core/optimizer/math/partial/partial.factor @@ -59,7 +59,7 @@ PREDICATE: math-partial < word : define-integer-op-word ( word fix-word big-word -- ) [ [ integer-op-word ] [ integer-op-quot ] 3bi - 2 1 <effect> define-declared + (( x y -- z )) define-declared ] [ [ integer-op-word ] [ 2drop ] 3bi diff --git a/core/parser/parser-docs.factor b/core/parser/parser-docs.factor index 2ec9f2de54..1aecfbd60d 100755 --- a/core/parser/parser-docs.factor +++ b/core/parser/parser-docs.factor @@ -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 } } diff --git a/core/parser/parser-tests.factor b/core/parser/parser-tests.factor index 555c6eb32c..074b3738ac 100755 --- a/core/parser/parser-tests.factor +++ b/core/parser/parser-tests.factor @@ -198,7 +198,7 @@ IN: parser.tests [ "IN: parser.tests : x ; : y 3 throw ; this is an error" <string-reader> "a" parse-stream - ] [ parse-error? ] must-fail-with + ] [ source-file-error? ] must-fail-with [ t ] [ "y" "parser.tests" lookup >boolean @@ -298,12 +298,12 @@ IN: parser.tests [ "IN: parser.tests TUPLE: another-pred-test ; GENERIC: another-pred-test?" <string-reader> "removing-the-predicate" parse-stream - ] [ error>> error>> redefine-error? ] must-fail-with + ] [ error>> error>> error>> redefine-error? ] must-fail-with [ "IN: parser.tests TUPLE: class-redef-test ; TUPLE: class-redef-test ;" <string-reader> "redefining-a-class-1" parse-stream - ] [ error>> error>> redefine-error? ] must-fail-with + ] [ error>> error>> error>> redefine-error? ] must-fail-with [ ] [ "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test" @@ -313,7 +313,7 @@ IN: parser.tests [ "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test : class-redef-test ;" <string-reader> "redefining-a-class-3" parse-stream drop - ] [ error>> error>> redefine-error? ] must-fail-with + ] [ error>> error>> error>> redefine-error? ] must-fail-with [ ] [ "IN: parser.tests TUPLE: class-fwd-test ;" @@ -323,7 +323,7 @@ IN: parser.tests [ "IN: parser.tests \\ class-fwd-test" <string-reader> "redefining-a-class-3" parse-stream drop - ] [ error>> error>> no-word-error? ] must-fail-with + ] [ error>> error>> error>> no-word-error? ] must-fail-with [ ] [ "IN: parser.tests TUPLE: class-fwd-test ; SYMBOL: class-fwd-test" @@ -333,12 +333,12 @@ IN: parser.tests [ "IN: parser.tests \\ class-fwd-test" <string-reader> "redefining-a-class-3" parse-stream drop - ] [ error>> error>> no-word-error? ] must-fail-with + ] [ error>> error>> error>> no-word-error? ] must-fail-with [ "IN: parser.tests : foo ; TUPLE: foo ;" <string-reader> "redefining-a-class-4" parse-stream drop - ] [ error>> error>> redefine-error? ] must-fail-with + ] [ error>> error>> error>> redefine-error? ] must-fail-with [ ] [ "IN: parser.tests : foo ( x y -- z ) 1 2 ; : bar ( a -- b ) ;" eval @@ -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 diff --git a/core/parser/parser.factor b/core/parser/parser.factor index 129d5ef2ee..601245c463 100755 --- a/core/parser/parser.factor +++ b/core/parser/parser.factor @@ -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,161 +22,16 @@ 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. - lexer get [ - lexer-line number>string print - ] [ - nl - ] if* + file get [ file. ] when* + lexer get line>> number>string write ": " write "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 +50,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 +65,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 +103,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 +113,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 +134,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 +148,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 -- ) diff --git a/core/prettyprint/prettyprint-tests.factor b/core/prettyprint/prettyprint-tests.factor index d5f4dd5906..9e11611f5b 100755 --- a/core/prettyprint/prettyprint-tests.factor +++ b/core/prettyprint/prettyprint-tests.factor @@ -167,9 +167,11 @@ unit-test "another-retain-layout" another-retain-layout-test check-see ] unit-test +DEFER: parse-error-file + : another-soft-break-test { - "USING: namespaces parser sequences ;" + "USING: namespaces sequences ;" "IN: prettyprint.tests" ": another-soft-break-layout ( node -- quot )" " parse-error-file" @@ -183,7 +185,7 @@ unit-test : string-layout { - "USING: io kernel parser ;" + "USING: io kernel lexer ;" "IN: prettyprint.tests" ": string-layout-test ( error -- )" " \"Expected \" write dup unexpected-want expected>string write" diff --git a/core/sequences/sequences.factor b/core/sequences/sequences.factor index 02a7191f0a..2d05d3c2ef 100755 --- a/core/sequences/sequences.factor +++ b/core/sequences/sequences.factor @@ -206,6 +206,8 @@ M: slice virtual@ [ slice-from + ] [ slice-seq ] bi ; M: slice length dup slice-to swap slice-from - ; +: short ( seq n -- seq n' ) over length min ; inline + : head-slice ( seq n -- slice ) (head) <slice> ; : tail-slice ( seq n -- slice ) (tail) <slice> ; diff --git a/core/source-files/source-files.factor b/core/source-files/source-files.factor index 454f148974..2c5c19708e 100755 --- a/core/source-files/source-files.factor +++ b/core/source-files/source-files.factor @@ -75,11 +75,35 @@ 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> . ; + +M: source-file-error error. + [ file>> file. ] [ 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 index 0000000000..e1c53cd87a --- /dev/null +++ b/core/strings/parser/parser-docs.factor @@ -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 prettyprint strings.parser ;" "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 index 0000000000..08421b4a20 --- /dev/null +++ b/core/strings/parser/parser.factor @@ -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 ; diff --git a/core/syntax/syntax.factor b/core/syntax/syntax.factor index 91a453408d..4d4b81d00e 100755 --- a/core/syntax/syntax.factor +++ b/core/syntax/syntax.factor @@ -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 @@ -167,7 +168,7 @@ IN: bootstrap.syntax "C:" [ CREATE-WORD - scan-word dup check-tuple + scan-word check-tuple-class [ boa ] curry define-inline ] define-syntax diff --git a/core/vocabs/loader/loader-tests.factor b/core/vocabs/loader/loader-tests.factor index 45b0d6b019..5ed0b0a34c 100755 --- a/core/vocabs/loader/loader-tests.factor +++ b/core/vocabs/loader/loader-tests.factor @@ -68,7 +68,7 @@ IN: vocabs.loader.tests <string-reader> "resource:core/vocabs/loader/test/a/a.factor" parse-stream -] [ error>> error>> no-word-error? ] must-fail-with +] [ error>> error>> error>> no-word-error? ] must-fail-with 0 "count-me" set-global diff --git a/extra/bitfields/bitfields.factor b/extra/bitfields/bitfields.factor index 7d3ef89759..c83d4b5152 100644 --- a/extra/bitfields/bitfields.factor +++ b/extra/bitfields/bitfields.factor @@ -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 diff --git a/extra/boids/boids.factor b/extra/boids/boids.factor index 4151b44cfb..e6c97b90dd 100644 --- a/extra/boids/boids.factor +++ b/extra/boids/boids.factor @@ -1,5 +1,5 @@ -USING: kernel namespaces +USING: combinators.short-circuit kernel namespaces math math.constants math.functions diff --git a/extra/boids/ui/ui.factor b/extra/boids/ui/ui.factor index a1feac381d..e3c54e0744 100755 --- a/extra/boids/ui/ui.factor +++ b/extra/boids/ui/ui.factor @@ -1,5 +1,5 @@ -USING: kernel namespaces +USING: combinators.short-circuit kernel namespaces math math.functions math.vectors @@ -104,11 +104,11 @@ VARS: population-label cohesion-label alignment-label separation-label ; C[ [ run ] in-thread ] slate> set-slate-graft C[ loop off ] slate> set-slate-ungraft - "" <label> dup reverse-video-theme >population-label update-population-label + "" <label> reverse-video-theme >population-label update-population-label - "" <label> dup reverse-video-theme >cohesion-label update-cohesion-label - "" <label> dup reverse-video-theme >alignment-label update-alignment-label - "" <label> dup reverse-video-theme >separation-label update-separation-label + "" <label> reverse-video-theme >cohesion-label update-cohesion-label + "" <label> reverse-video-theme >alignment-label update-alignment-label + "" <label> reverse-video-theme >separation-label update-separation-label <frame> diff --git a/extra/bootstrap/unicode/unicode.factor b/extra/bootstrap/unicode/unicode.factor index 0476cbf18b..b46e322d7b 100755 --- a/extra/bootstrap/unicode/unicode.factor +++ b/extra/bootstrap/unicode/unicode.factor @@ -1,4 +1,4 @@ -USING: parser kernel namespaces ; +USING: strings.parser kernel namespaces ; USE: unicode.breaks USE: unicode.case diff --git a/extra/bunny/deploy.factor b/extra/bunny/deploy.factor index 643737b23c..22e97b455e 100755 --- a/extra/bunny/deploy.factor +++ b/extra/bunny/deploy.factor @@ -1,15 +1,15 @@ USING: tools.deploy.config ; H{ - { deploy-word-defs? f } + { deploy-math? t } + { deploy-reflection 2 } + { deploy-io 3 } + { deploy-c-types? f } { deploy-random? f } + { deploy-ui? t } { deploy-name "Bunny" } + { deploy-word-defs? f } + { "stop-after-last-window?" t } { deploy-threads? t } { deploy-compiler? t } - { deploy-math? t } - { deploy-c-types? f } - { deploy-io 3 } - { deploy-reflection 1 } - { deploy-ui? t } - { "stop-after-last-window?" t } { deploy-word-props? f } } diff --git a/extra/cocoa/cocoa.factor b/extra/cocoa/cocoa.factor index f4cfb20591..1dd1e0a264 100755 --- a/extra/cocoa/cocoa.factor +++ b/extra/cocoa/cocoa.factor @@ -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 -- ) diff --git a/extra/combinators/lib/lib-tests.factor b/extra/combinators/lib/lib-tests.factor index 78916bb027..e511e88fcc 100755 --- a/extra/combinators/lib/lib-tests.factor +++ b/extra/combinators/lib/lib-tests.factor @@ -10,9 +10,6 @@ IN: combinators.lib.tests [ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] must-infer { 2 1 2 3 4 5 } [ 1 2 3 4 5 [ drop drop drop drop drop 2 ] 5 nkeep ] unit-test [ [ 1 2 3 + ] ] [ 1 2 3 [ + ] 3 ncurry ] unit-test -[ 1 1 2 2 3 3 ] [ 1 2 3 [ dup ] 3apply ] unit-test -[ 1 4 9 ] [ 1 2 3 [ sq ] 3apply ] unit-test -[ [ sq ] 3apply ] must-infer [ { 1 2 } { 2 4 } { 3 8 } { 4 16 } { 5 32 } ] [ 1 2 3 4 5 [ dup 2^ 2array ] 5 napply ] unit-test [ [ dup 2^ 2array ] 5 napply ] must-infer @@ -23,35 +20,6 @@ IN: combinators.lib.tests { "oof" "bar" } { [ reverse ] [ "x" swap "x" 3append ] } parallel-call ] unit-test -! && - -[ t ] [ - 3 { - [ dup number? ] [ dup odd? ] [ dup 0 > ] - } 0&& nip -] unit-test - -[ f ] [ - 3 { - [ dup number? ] [ dup even? ] [ dup 0 > ] - } 0&& nip -] unit-test - -! || - -[ t ] [ - 4 { - [ dup array? ] [ dup number? ] [ 3 throw ] - } 0|| nip -] unit-test - -[ f ] [ - 4 { - [ dup array? ] [ dup vector? ] [ dup float? ] - } 0|| nip -] unit-test - - { 1 1 } [ [ even? ] [ drop 1 ] [ drop 2 ] ifte ] must-infer-as diff --git a/extra/combinators/lib/lib.factor b/extra/combinators/lib/lib.factor index fe6b68638b..3fab4f62ae 100755 --- a/extra/combinators/lib/lib.factor +++ b/extra/combinators/lib/lib.factor @@ -36,8 +36,6 @@ MACRO: napply ( n -- ) '[ , ntuck , nslip ] ] map concat >quotation [ call ] append ; -: 3apply ( obj obj obj quot -- ) 3 napply ; inline - : 2with ( param1 param2 obj quot -- obj curry ) with with ; inline @@ -59,47 +57,6 @@ MACRO: napply ( n -- ) : assoc-map-with ( obj assoc quot -- assoc ) with* assoc-map ; inline -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! short circuiting words -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -: short-circuit ( quots quot default -- quot ) - 1quotation -rot { } map>assoc <reversed> alist>quot ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -MACRO: 0&& ( quots -- quot ) - [ '[ drop @ dup not ] [ drop f ] 2array ] map - { [ t ] [ ] } suffix - '[ f , cond ] ; - -MACRO: 1&& ( quots -- quot ) - [ '[ drop dup @ dup not ] [ drop drop f ] 2array ] map - { [ t ] [ nip ] } suffix - '[ f , cond ] ; - -MACRO: 2&& ( quots -- quot ) - [ '[ drop 2dup @ dup not ] [ drop 2drop f ] 2array ] map - { [ t ] [ 2nip ] } suffix - '[ f , cond ] ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -MACRO: 0|| ( quots -- quot ) - [ '[ drop @ dup ] [ ] 2array ] map - { [ drop t ] [ f ] } suffix - '[ f , cond ] ; - -MACRO: 1|| ( quots -- quot ) - [ '[ drop dup @ dup ] [ nip ] 2array ] map - { [ drop drop t ] [ f ] } suffix - '[ f , cond ] ; - -MACRO: 2|| ( quots -- quot ) - [ '[ drop 2dup @ dup ] [ 2nip ] 2array ] map - { [ drop 2drop t ] [ f ] } suffix - '[ f , cond ] ; - ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ifte ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/extra/combinators/short-circuit/short-circuit-tests.factor b/extra/combinators/short-circuit/short-circuit-tests.factor new file mode 100644 index 0000000000..e392d67d2a --- /dev/null +++ b/extra/combinators/short-circuit/short-circuit-tests.factor @@ -0,0 +1,32 @@ + +USING: kernel math tools.test combinators.short-circuit ; + +IN: combinators.short-circuit.tests + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: must-be-t ( in -- ) [ t ] swap unit-test ; +: must-be-f ( in -- ) [ f ] swap unit-test ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +[ { [ 1 ] [ 2 ] [ 3 ] } 0&& 3 = ] must-be-t +[ 3 { [ 0 > ] [ odd? ] [ 2 + ] } 1&& 5 = ] must-be-t +[ 10 20 { [ + 0 > ] [ - even? ] [ + ] } 2&& 30 = ] must-be-t + +[ { [ 1 ] [ f ] [ 3 ] } 0&& 3 = ] must-be-f +[ 3 { [ 0 > ] [ even? ] [ 2 + ] } 1&& ] must-be-f +[ 10 20 { [ + 0 > ] [ - odd? ] [ + ] } 2&& 30 = ] must-be-f + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +[ { [ 10 0 < ] [ f ] [ "factor" ] } 0|| "factor" = ] must-be-t + +[ 10 { [ odd? ] [ 100 > ] [ 1 + ] } 1|| 11 = ] must-be-t + +[ 10 20 { [ + odd? ] [ + 100 > ] [ + ] } 2|| 30 = ] must-be-t + +[ { [ 10 0 < ] [ f ] [ 0 1 = ] } 0|| ] must-be-f + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + diff --git a/extra/combinators/short-circuit/short-circuit.factor b/extra/combinators/short-circuit/short-circuit.factor new file mode 100644 index 0000000000..3301633d7d --- /dev/null +++ b/extra/combinators/short-circuit/short-circuit.factor @@ -0,0 +1,33 @@ + +USING: kernel combinators quotations arrays sequences assocs + locals shuffle macros fry ; + +IN: combinators.short-circuit + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +:: n&&-rewrite ( quots N -- quot ) + quots + [ '[ drop N ndup @ dup not ] [ drop N ndrop f ] 2array ] + map + [ t ] [ N nnip ] 2array suffix + '[ f , cond ] ; + +MACRO: 0&& ( quots -- quot ) 0 n&&-rewrite ; +MACRO: 1&& ( quots -- quot ) 1 n&&-rewrite ; +MACRO: 2&& ( quots -- quot ) 2 n&&-rewrite ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +:: n||-rewrite ( quots N -- quot ) + quots + [ '[ drop N ndup @ dup ] [ N nnip ] 2array ] + map + [ drop N ndrop t ] [ f ] 2array suffix + '[ f , cond ] ; + +MACRO: 0|| ( quots -- quot ) 0 n||-rewrite ; +MACRO: 1|| ( quots -- quot ) 1 n||-rewrite ; +MACRO: 2|| ( quots -- quot ) 2 n||-rewrite ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/extra/combinators/short-circuit/smart/smart-tests.factor b/extra/combinators/short-circuit/smart/smart-tests.factor new file mode 100644 index 0000000000..7ec4a0e657 --- /dev/null +++ b/extra/combinators/short-circuit/smart/smart-tests.factor @@ -0,0 +1,32 @@ + +USING: kernel math tools.test combinators.short-circuit.smart ; + +IN: combinators.short-circuit.smart.tests + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +: must-be-t ( in -- ) [ t ] swap unit-test ; +: must-be-f ( in -- ) [ f ] swap unit-test ; + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +[ { [ 1 ] [ 2 ] [ 3 ] } && 3 = ] must-be-t +[ 3 { [ 0 > ] [ odd? ] [ 2 + ] } && 5 = ] must-be-t +[ 10 20 { [ + 0 > ] [ - even? ] [ + ] } && 30 = ] must-be-t + +[ { [ 1 ] [ f ] [ 3 ] } && 3 = ] must-be-f +[ 3 { [ 0 > ] [ even? ] [ 2 + ] } && ] must-be-f +[ 10 20 { [ + 0 > ] [ - odd? ] [ + ] } && 30 = ] must-be-f + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +[ { [ 10 0 < ] [ f ] [ "factor" ] } || "factor" = ] must-be-t + +[ 10 { [ odd? ] [ 100 > ] [ 1 + ] } || 11 = ] must-be-t + +[ 10 20 { [ + odd? ] [ + 100 > ] [ + ] } || 30 = ] must-be-t + +[ { [ 10 0 < ] [ f ] [ 0 1 = ] } || ] must-be-f + +! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + diff --git a/extra/combinators/short-circuit/smart/smart.factor b/extra/combinators/short-circuit/smart/smart.factor new file mode 100644 index 0000000000..2cef957a6f --- /dev/null +++ b/extra/combinators/short-circuit/smart/smart.factor @@ -0,0 +1,11 @@ + +USING: kernel sequences math inference accessors macros + combinators.short-circuit ; + +IN: combinators.short-circuit.smart + +MACRO: && ( quots -- quot ) + dup first infer [ in>> ] [ out>> ] bi - 1+ n&&-rewrite ; + +MACRO: || ( quots -- quot ) + dup first infer [ in>> ] [ out>> ] bi - 1+ n||-rewrite ; diff --git a/extra/concurrency/distributed/distributed-tests.factor b/extra/concurrency/distributed/distributed-tests.factor index dc20e7ad5c..528e1956b8 100755 --- a/extra/concurrency/distributed/distributed-tests.factor +++ b/extra/concurrency/distributed/distributed-tests.factor @@ -13,8 +13,6 @@ concurrency.messaging continuations accessors prettyprint ; [ ] [ test-node dup (start-node) ] unit-test -[ ] [ 1000 sleep ] unit-test - [ ] [ [ receive first2 >r 3 + r> send @@ -30,6 +28,4 @@ concurrency.messaging continuations accessors prettyprint ; receive ] unit-test -[ ] [ 1000 sleep ] unit-test - [ ] [ test-node stop-node ] unit-test diff --git a/extra/concurrency/distributed/distributed.factor b/extra/concurrency/distributed/distributed.factor index 9ae2627505..4da079e812 100755 --- a/extra/concurrency/distributed/distributed.factor +++ b/extra/concurrency/distributed/distributed.factor @@ -12,16 +12,15 @@ SYMBOL: local-node deserialize [ first2 get-process send ] [ stop-server ] if* ; +: <node-server> ( addrspec -- threaded-server ) + <threaded-server> + swap >>insecure + binary >>encoding + "concurrency.distributed" >>name + [ handle-node-client ] >>handler ; + : (start-node) ( addrspec addrspec -- ) - local-node set-global - [ - <threaded-server> - swap >>insecure - binary >>encoding - "concurrency.distributed" >>name - [ handle-node-client ] >>handler - start-server - ] curry "Distributed concurrency server" spawn drop ; + local-node set-global <node-server> start-server* ; : start-node ( port -- ) host-name over <inet> (start-node) ; diff --git a/extra/cpu/8080/emulator/emulator.factor b/extra/cpu/8080/emulator/emulator.factor index b0ffb6ae54..aa8dc4f9cf 100755 --- a/extra/cpu/8080/emulator/emulator.factor +++ b/extra/cpu/8080/emulator/emulator.factor @@ -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 diff --git a/extra/dns/forwarding/forwarding.factor b/extra/dns/forwarding/forwarding.factor index 039b969ddd..87f9821153 100644 --- a/extra/dns/forwarding/forwarding.factor +++ b/extra/dns/forwarding/forwarding.factor @@ -1,5 +1,5 @@ -USING: kernel +USING: combinators.short-circuit kernel combinators vectors sequences diff --git a/extra/dns/server/server.factor b/extra/dns/server/server.factor index 04b3ecfbee..16677d8761 100644 --- a/extra/dns/server/server.factor +++ b/extra/dns/server/server.factor @@ -1,7 +1,7 @@ USING: kernel combinators sequences sets math threads namespaces continuations debugger io io.sockets unicode.case accessors destructors - combinators.cleave combinators.lib + combinators.cleave combinators.lib combinators.short-circuit newfx fry dns dns.util dns.misc ; diff --git a/extra/editors/editors-docs.factor b/extra/editors/editors-docs.factor index 2b9e4cc021..0f50e40eb4 100644 --- a/extra/editors/editors-docs.factor +++ b/extra/editors/editors-docs.factor @@ -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" } "." } ; diff --git a/extra/editors/editors.factor b/extra/editors/editors.factor index ec8313363e..78f6caf965 100755 --- a/extra/editors/editors.factor +++ b/extra/editors/editors.factor @@ -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,37 @@ 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-file + error>> error-file ; -M: object find-parse-error +M: lexer-error error-line + [ error>> error-line ] [ line>> ] bi or ; + +M: source-file-error error-file + [ error>> error-file ] [ file>> path>> ] bi or ; + +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 -- ) [ diff --git a/extra/ftp/server/server.factor b/extra/ftp/server/server.factor index c71eadb72f..c5a5449b25 100644 --- a/extra/ftp/server/server.factor +++ b/extra/ftp/server/server.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors combinators io io.encodings.8-bit +USING: combinators.short-circuit accessors combinators io io.encodings.8-bit io.encodings io.encodings.binary io.encodings.utf8 io.files io.sockets kernel math.parser namespaces sequences ftp io.unix.launcher.parser unicode.case splitting assocs diff --git a/extra/furnace/auth/login/permits/permits.factor b/extra/furnace/auth/login/permits/permits.factor index 49cf98e0e3..ae9458f4ac 100644 --- a/extra/furnace/auth/login/permits/permits.factor +++ b/extra/furnace/auth/login/permits/permits.factor @@ -1,6 +1,8 @@ USING: accessors namespaces combinators.lib kernel db.tuples db.types -furnace.auth furnace.sessions furnace.cache ; +furnace.auth furnace.sessions furnace.cache +combinators.short-circuit ; + IN: furnace.auth.login.permits TUPLE: permit < server-state session uid ; diff --git a/extra/furnace/boilerplate/boilerplate.factor b/extra/furnace/boilerplate/boilerplate.factor index 0e2a673d9b..2bb97e7c14 100644 --- a/extra/furnace/boilerplate/boilerplate.factor +++ b/extra/furnace/boilerplate/boilerplate.factor @@ -7,7 +7,7 @@ html.templates.chloe locals http.server http.server.filters -furnace ; +furnace combinators.short-circuit ; IN: furnace.boilerplate TUPLE: boilerplate < filter-responder template init ; diff --git a/extra/furnace/sessions/sessions.factor b/extra/furnace/sessions/sessions.factor index 6e50417ea1..0ec9648a67 100755 --- a/extra/furnace/sessions/sessions.factor +++ b/extra/furnace/sessions/sessions.factor @@ -7,7 +7,7 @@ io.servers.connection db db.tuples db.types http http.server http.server.dispatchers http.server.filters html.elements -furnace furnace.cache ; +furnace furnace.cache combinators.short-circuit ; IN: furnace.sessions TUPLE: session < server-state namespace user-agent client changed? ; diff --git a/extra/gesture-logger/gesture-logger.factor b/extra/gesture-logger/gesture-logger.factor index b9de7c1b74..ba0ff5bedd 100644 --- a/extra/gesture-logger/gesture-logger.factor +++ b/extra/gesture-logger/gesture-logger.factor @@ -1,16 +1,17 @@ ! 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 ; : <gesture-logger> ( stream -- gadget ) \ gesture-logger construct-gadget - [ set-gesture-logger-stream ] keep - { 100 100 } over set-rect-dim - dup black solid-interior ; + swap >>stream + { 100 100 } >>dim + black solid-interior ; M: gesture-logger handle-gesture* drop diff --git a/extra/graph-theory/authors.txt b/extra/graph-theory/authors.txt new file mode 100644 index 0000000000..93667236de --- /dev/null +++ b/extra/graph-theory/authors.txt @@ -0,0 +1 @@ +William Schlieper diff --git a/extra/graph-theory/graph-theory-docs.factor b/extra/graph-theory/graph-theory-docs.factor new file mode 100644 index 0000000000..82d8b9adf6 --- /dev/null +++ b/extra/graph-theory/graph-theory-docs.factor @@ -0,0 +1,135 @@ +! See http://factorcode.org/license.txt for BSD licence. +USING: help.markup help.syntax ; + +IN: graph-theory + +ARTICLE: "graph-protocol" "Graph protocol" +"All graphs must be instances of the graph mixin:" +{ $subsection graph } +"All graphs must implement a method on the following generic word:" +{ $subsection vertices } +"At least one of the following two generic words must have a method; the " { $link graph } " mixin has default definitions which are mutually recursive:" +{ $subsection adjlist } +{ $subsection adj? } +"All mutable graphs must implement a method on the following generic word:" +{ $subsection add-blank-vertex } +"All mutable undirected graphs must implement a method on the following generic word:" +{ $subsection add-edge } +"Mutable directed graphs should not implement the above word, as it has a default definition defined in terms of the following generic word:" +{ $subsection add-edge* } +"The following two words have default definitions, but are available as generics to allow implementations to optimize them:" +{ $subsection num-vertices } +{ $subsection num-edges } ; + +HELP: graph +{ $class-description "A mixin class whose instances are graphs. Custom implementations of the graph protocol should be declared as instances of this mixin for all graph functionality to work correctly:" + { $code "INSTANCE: hex-board graph" } +} ; + +{ vertices num-vertices num-edges } related-words + +HELP: vertices +{ $values { "graph" graph } { "seq" "The vertices" } } +{ $description "Returns the vertices of the graph." } ; + +HELP: num-vertices +{ $values { "graph" graph } { "n" "The number of vertices" } } +{ $description "Returns the number of vertices in the graph." } ; + +HELP: num-edges +{ $values { "graph" "A graph" } { "n" "The number of edges" } } +{ $description "Returns the number of edges in the graph." } ; + +{ adjlist adj? } related-words + +HELP: adjlist +{ $values + { "from" "The index of a vertex" } + { "graph" "The graph to be examined" } + { "seq" "The adjacency list" } } +{ $description "Returns a sequence of vertices that this vertex links to" } ; + +HELP: adj? +{ $values + { "from" "The index of a vertex" } + { "to" "The index of a vertex" } + { "graph" "A graph" } + { "?" "A boolean" } } +{ $description "Returns a boolean describing whether there is an edge in the graph between from and to." } ; + +{ add-blank-vertex add-blank-vertices add-edge add-edge* } related-words + +HELP: add-blank-vertex +{ $values + { "index" "A vertex index" } + { "graph" "A graph" } } +{ $description "Adds a vertex to the graph." } ; + +HELP: add-blank-vertices +{ $values + { "seq" "A sequence of vertex indices" } + { "graph" "A graph" } } +{ $description "Adds vertices with indices in seq to the graph." } ; + +HELP: add-edge* +{ $values + { "from" "The index of a vertex" } + { "to" "The index of another vertex" } + { "graph" "A graph" } } +{ $description "Adds a one-way edge to the graph, between from and to." + $nl + "If you want to add a two-way edge, use " { $link add-edge } " instead." } ; + +HELP: add-edge +{ $values + { "m" "The index of a vertex" } + { "n" "The index of another vertex" } + { "graph" "A graph" } } +{ $description "Adds a two-way edge to the graph, between m and n." + $nl + "If you want to add a one-way edge, use " { $link add-edge* } " instead." } ; + +{ depth-first full-depth-first dag? topological-sort } related-words + +HELP: depth-first +{ $values + { "v" "The vertex to start the search at" } + { "graph" "The graph to search" } + { "pre" "A quotation of the form ( n -- )" } + { "post" "A quotation of the form ( n -- )" } + { "?list" "A list of booleans describing the vertices visited in the search" } + { "?" "A boolean describing whether or not the end-search error was thrown" } } +{ $description "Performs a depth-first search on " { $emphasis "graph" } ". The variable " { $emphasis "graph" } " can be accessed in both quotations." + $nl + "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first." + $nl + "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first." + $nl + { $emphasis "?list" } " is a list of booleans, " { $link t } " for every vertex visted during the search, and " { $link f } " for every vertex not visited." } ; + +HELP: full-depth-first +{ $values + { "graph" "The graph to search" } + { "pre" "A quotation of the form ( n -- )" } + { "post" "A quotation of the form ( n -- )" } + { "tail" "A quotation of the form ( -- )" } + { "?" "A boolean describing whether or not the end-search error was thrown" } } +{ $description "Performs a depth-first search on " { $emphasis "graph" } ". The variable " { $emphasis "graph" } "can be accessed in both quotations." + $nl + "The " { $emphasis "pre" } " quotation is run before the recursive application of depth-first." + $nl + "The " { $emphasis "post" } " quotation is run after the recursive application of depth-first." + $nl + "The " { $emphasis "tail" } " quotation is run after each time the depth-first search runs out of nodes. On an undirected graph this will be each connected subgroup but on a directed graph it can be more complex." } ; + +HELP: dag? +{ $values + { "graph" graph } + { "?" "A boolean indicating if the graph is acyclic" } } +{ $description "Using a depth-first search, determines if the specified directed graph is a directed acyclic graph. An undirected graph will produce a false result, as the algorithm does not eliminate cycles of length 2, which will include any edge that goes both ways." } ; + +HELP: topological-sort +{ $values + { "graph" graph } + { "seq/f" "Either a sequence of values or f" } } +{ $description "Using a depth-first search, topologically sorts the specified directed graph. Returns f if the graph contains any cycles, and a topologically sorted sequence otherwise." } ; diff --git a/extra/graph-theory/graph-theory.factor b/extra/graph-theory/graph-theory.factor new file mode 100644 index 0000000000..322f17d2dd --- /dev/null +++ b/extra/graph-theory/graph-theory.factor @@ -0,0 +1,92 @@ +! Copyright (C) 2008 William Schlieper <schlieper@unc.edu> +! See http://factorcode.org/license.txt for BSD license. + +USING: kernel combinators fry continuations sequences arrays vectors assocs hashtables heaps namespaces ; + +IN: graph-theory + +MIXIN: graph +SYMBOL: visited? +ERROR: end-search ; + +GENERIC: vertices ( graph -- seq ) flushable + +GENERIC: num-vertices ( graph -- n ) flushable + +GENERIC: num-edges ( graph -- n ) flushable + +GENERIC: adjlist ( from graph -- seq ) flushable + +GENERIC: adj? ( from to graph -- ? ) flushable + +GENERIC: add-blank-vertex ( index graph -- ) + +GENERIC: delete-blank-vertex ( index graph -- ) + +GENERIC: add-edge* ( from to graph -- ) + +GENERIC: add-edge ( u v graph -- ) + +GENERIC: delete-edge* ( from to graph -- ) + +GENERIC: delete-edge ( u v graph -- ) + +M: graph num-vertices + vertices length ; + +M: graph num-edges + [ vertices ] [ '[ , adjlist length ] map sum ] bi ; + +M: graph adjlist + [ vertices ] [ swapd '[ , swap , adj? ] filter ] bi ; + +M: graph adj? + swapd adjlist index >boolean ; + +M: graph add-edge + [ add-edge* ] [ swapd add-edge* ] 3bi ; + +M: graph delete-edge + [ delete-edge* ] [ swapd delete-edge* ] 3bi ; + +: add-blank-vertices ( seq graph -- ) + '[ , add-blank-vertex ] each ; + +: delete-vertex ( index graph -- ) + [ adjlist ] + [ '[ , , 3dup adj? [ delete-edge* ] [ 3drop ] if ] each ] + [ delete-blank-vertex ] 2tri ; + +<PRIVATE + +: search-wrap ( quot graph -- ? ) + [ [ graph set ] [ vertices [ f 2array ] map >hashtable visited? set ] bi + [ t ] compose [ dup end-search? [ drop f ] [ rethrow ] if ] recover ] with-scope ; inline + +: (depth-first) ( v pre post -- ) + { [ 2drop visited? get t -rot set-at ] + [ drop call ] + [ [ graph get adjlist ] 2dip + '[ dup visited? get at [ drop ] [ , , (depth-first) ] if ] each ] + [ nip call ] } 3cleave ; inline + +PRIVATE> + +: depth-first ( v graph pre post -- ?list ? ) + '[ , , (depth-first) visited? get ] swap search-wrap ; inline + +: full-depth-first ( graph pre post tail -- ? ) + '[ [ visited? get [ nip not ] assoc-find ] + [ drop , , (depth-first) @ ] + [ 2drop ] while ] swap search-wrap ; inline + +: dag? ( graph -- ? ) + V{ } clone swap [ 2dup swap push dupd + '[ , swap graph get adj? not ] all? + [ end-search ] unless ] + [ drop dup pop* ] [ ] full-depth-first nip ; + +: topological-sort ( graph -- seq/f ) + dup dag? + [ V{ } swap [ drop ] [ prefix ] [ ] full-depth-first drop ] + [ drop f ] if ; diff --git a/extra/graph-theory/reversals/reversals.factor b/extra/graph-theory/reversals/reversals.factor new file mode 100644 index 0000000000..1ea1a3fbf5 --- /dev/null +++ b/extra/graph-theory/reversals/reversals.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2008 William Schlieper <schlieper@unc.edu> +! See http://factorcode.org/license.txt for BSD license. + +USING: accessors kernel graph-theory ; + +IN: graph-theory.reversals + +TUPLE: reversal graph ; + +GENERIC: reverse-graph ( graph -- reversal ) + +M: graph reverse-graph reversal boa ; + +M: reversal reverse-graph graph>> ; + +INSTANCE: reversal graph + +M: reversal vertices + graph>> vertices ; + +M: reversal adj? + swapd graph>> adj? ; diff --git a/extra/graph-theory/sparse/sparse.factor b/extra/graph-theory/sparse/sparse.factor new file mode 100644 index 0000000000..33c5505f0a --- /dev/null +++ b/extra/graph-theory/sparse/sparse.factor @@ -0,0 +1,35 @@ +! Copyright (C) 2008 William Schlieper <schlieper@unc.edu> +! See http://factorcode.org/license.txt for BSD license. + +USING: accessors kernel sequences arrays vectors sets assocs hashtables graph-theory namespaces fry ; + +IN: graph-theory.sparse + +TUPLE: sparse-graph alist ; + +: <sparse-graph> ( -- sparse-graph ) + H{ } clone sparse-graph boa ; + +: >sparse-graph ( graph -- sparse-graph ) + [ vertices ] keep + '[ dup , adjlist 2array ] map >hashtable sparse-graph boa ; + +INSTANCE: sparse-graph graph + +M: sparse-graph vertices + alist>> keys ; + +M: sparse-graph adjlist + alist>> at ; + +M: sparse-graph add-blank-vertex + alist>> V{ } clone -rot set-at ; + +M: sparse-graph delete-blank-vertex + alist>> delete-at ; + +M: sparse-graph add-edge* + alist>> swapd at adjoin ; + +M: sparse-graph delete-edge* + alist>> swapd at delete ; diff --git a/extra/graph-theory/summary.txt b/extra/graph-theory/summary.txt new file mode 100644 index 0000000000..3e1d791ab1 --- /dev/null +++ b/extra/graph-theory/summary.txt @@ -0,0 +1 @@ +Graph-theoretic algorithms diff --git a/extra/graph-theory/tags.txt b/extra/graph-theory/tags.txt new file mode 100644 index 0000000000..42d711b32b --- /dev/null +++ b/extra/graph-theory/tags.txt @@ -0,0 +1 @@ +collections diff --git a/extra/help/handbook/handbook.factor b/extra/help/handbook/handbook.factor index dfbb7a12b8..246ad56e51 100755 --- a/extra/help/handbook/handbook.factor +++ b/extra/help/handbook/handbook.factor @@ -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" diff --git a/extra/help/markup/markup.factor b/extra/help/markup/markup.factor index 32e4084150..150a66ec92 100755 --- a/extra/help/markup/markup.factor +++ b/extra/help/markup/markup.factor @@ -290,6 +290,11 @@ M: string ($instance) : $values-x/y ( children -- ) drop { { "x" number } { "y" number } } $values ; +: $parsing-note ( children -- ) + drop + "This word should only be called from parsing words." + $notes ; + : $io-error ( children -- ) drop "Throws an error if the I/O operation fails." $errors ; diff --git a/extra/html/templates/chloe/syntax/syntax.factor b/extra/html/templates/chloe/syntax/syntax.factor index 7eeb756a39..cfa576d56f 100644 --- a/extra/html/templates/chloe/syntax/syntax.factor +++ b/extra/html/templates/chloe/syntax/syntax.factor @@ -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 diff --git a/extra/html/templates/fhtml/fhtml.factor b/extra/html/templates/fhtml/fhtml.factor index 74e5c37ef1..e435fdce5f 100755 --- a/extra/html/templates/fhtml/fhtml.factor +++ b/extra/html/templates/fhtml/fhtml.factor @@ -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 ) [ diff --git a/extra/http/http-tests.factor b/extra/http/http-tests.factor index 522d0c1845..7ddf6cf3aa 100755 --- a/extra/http/http-tests.factor +++ b/extra/http/http-tests.factor @@ -1,10 +1,16 @@ -USING: http tools.test multiline tuple-syntax -io.streams.string io.encodings.utf8 io.encodings.string -kernel arrays splitting sequences -assocs io.sockets db db.sqlite continuations urls hashtables -accessors ; +USING: http tools.test multiline tuple-syntax io.streams.string +io.encodings.utf8 io.encodings.8-bit io.encodings.binary +io.encodings.string kernel arrays splitting sequences 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 @@ -184,6 +190,13 @@ test-db [ init-furnace-tables ] with-db +: test-httpd ( -- ) + #! Return as soon as server is running. + <http-server> + 1237 >>insecure + f >>secure + start-server* ; + [ ] [ [ <dispatcher> @@ -196,15 +209,13 @@ test-db [ "redirect-loop" add-responder main-responder set - [ 1237 httpd ] "HTTPD test" spawn drop + test-httpd ] with-scope ] unit-test -[ ] [ 100 sleep ] unit-test - [ t ] [ "resource:extra/http/test/foo.html" ascii file-contents - "http://localhost:1237/nested/foo.html" http-get nip ascii decode = + "http://localhost:1237/nested/foo.html" http-get nip = ] unit-test [ "http://localhost:1237/redirect-loop" http-get nip ] @@ -229,12 +240,10 @@ test-db [ test-db <db-persistence> main-responder set - [ 1237 httpd ] "HTTPD test" spawn drop + test-httpd ] with-scope ] unit-test -[ ] [ 100 sleep ] unit-test - : 404? [ download-failed? ] [ response>> code>> 404 = ] bi and ; ! This should give a 404 not an infinite redirect loop @@ -256,12 +265,10 @@ test-db [ test-db <db-persistence> main-responder set - [ 1237 httpd ] "HTTPD test" spawn drop + test-httpd ] with-scope ] unit-test -[ ] [ 100 sleep ] unit-test - [ "Hi" ] [ "http://localhost:1237/" http-get nip ] unit-test [ "Goodbye" ] [ "http://localhost:1237/quit" http-get nip ] unit-test @@ -287,12 +294,10 @@ SYMBOL: a test-db <db-persistence> main-responder set - [ 1237 httpd ] "HTTPD test" spawn drop + test-httpd ] with-scope ] unit-test -[ ] [ 100 sleep ] unit-test - 3 a set-global : test-a string>xml "input" tag-named "value" swap at ; diff --git a/extra/http/http.factor b/extra/http/http.factor index 4001301cb1..d5712d5bab 100755 --- a/extra/http/http.factor +++ b/extra/http/http.factor @@ -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 ) diff --git a/extra/http/parsers/parsers.factor b/extra/http/parsers/parsers.factor index 33bfa4b202..bc6e1148c3 100644 --- a/extra/http/parsers/parsers.factor +++ b/extra/http/parsers/parsers.factor @@ -1,4 +1,4 @@ -USING: math math.order math.parser kernel combinators.lib +USING: combinators.short-circuit math math.order math.parser kernel combinators.lib sequences sequences.deep peg peg.parsers assocs arrays hashtables strings unicode.case namespaces ascii ; IN: http.parsers diff --git a/extra/inverse/inverse.factor b/extra/inverse/inverse.factor index ef1f575972..43507046d6 100755 --- a/extra/inverse/inverse.factor +++ b/extra/inverse/inverse.factor @@ -2,7 +2,7 @@ USING: kernel words inspector slots quotations sequences assocs math arrays inference effects shuffle continuations debugger classes.tuple namespaces vectors bit-arrays byte-arrays strings sbufs math.functions macros sequences.private combinators -mirrors combinators.lib ; +mirrors combinators.lib combinators.short-circuit ; IN: inverse TUPLE: fail ; diff --git a/extra/io/encodings/8-bit/8-bit-docs.factor b/extra/io/encodings/8-bit/8-bit-docs.factor index 33d629b105..8f5e955998 100644 --- a/extra/io/encodings/8-bit/8-bit-docs.factor +++ b/extra/io/encodings/8-bit/8-bit-docs.factor @@ -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" } ; diff --git a/extra/io/encodings/8-bit/8-bit.factor b/extra/io/encodings/8-bit/8-bit.factor index 71c57ef68c..16fe052867 100755 --- a/extra/io/encodings/8-bit/8-bit.factor +++ b/extra/io/encodings/8-bit/8-bit.factor @@ -30,15 +30,12 @@ IN: io.encodings.8-bit } ; : encoding-file ( file-name -- stream ) - "resource:extra/io/encodings/8-bit/" ".TXT" - swapd 3append ascii <file-reader> ; - -: tail-if ( seq n -- newseq ) - 2dup swap length <= [ tail ] [ drop ] if ; + "resource:extra/io/encodings/8-bit/" swap ".TXT" + 3append ascii <file-reader> ; : process-contents ( lines -- assoc ) [ "#" split1 drop ] map harvest - [ "\t" split 2 head [ 2 tail-if hex> ] map ] map ; + [ "\t" split 2 head [ 2 short tail hex> ] map ] map ; : byte>ch ( assoc -- array ) 256 replacement-char <array> @@ -51,39 +48,40 @@ IN: io.encodings.8-bit lines process-contents [ byte>ch ] [ ch>byte ] bi ; -TUPLE: 8-bit name decode encode ; +SYMBOL: 8-bit-encodings + +TUPLE: 8-bit decode encode ; : encode-8-bit ( char stream assoc -- ) - swapd at* [ encode-error ] unless swap stream-write1 ; + swap >r at* + [ r> stream-write1 ] [ r> drop encode-error ] if ; inline -M: 8-bit encode-char - encode>> encode-8-bit ; +M: 8-bit encode-char encode>> encode-8-bit ; : decode-8-bit ( stream array -- char/f ) - swap stream-read1 dup - [ swap nth [ replacement-char ] unless* ] - [ nip ] if ; + >r stream-read1 dup + [ r> nth [ replacement-char ] unless* ] [ r> 2drop f ] if ; inline -M: 8-bit decode-char - decode>> decode-8-bit ; - -: make-8-bit ( word byte>ch ch>byte -- ) - [ 2drop ] [ 8-bit boa ] 3bi [ ] curry define ; - -: define-8-bit-encoding ( name stream -- ) - >r in get create r> parse-file make-8-bit ; +M: 8-bit decode-char decode>> decode-8-bit ; PREDICATE: 8-bit-encoding < word - word-def dup length 1 = [ first 8-bit? ] [ drop f ] if ; + 8-bit-encodings get-global key? ; -M: 8-bit-encoding <encoder> word-def first <encoder> ; +M: 8-bit-encoding <encoder> + 8-bit-encodings get-global at <encoder> ; -M: 8-bit-encoding <decoder> word-def first <decoder> ; +M: 8-bit-encoding <decoder> + 8-bit-encodings get-global at <decoder> ; PRIVATE> [ - "io.encodings.8-bit" in [ - mappings [ encoding-file define-8-bit-encoding ] assoc-each - ] with-variable + mappings [ + [ "io.encodings.8-bit" create ] + [ encoding-file parse-file 8-bit boa ] + bi* + ] assoc-map + [ keys [ define-symbol ] each ] + [ 8-bit-encodings set-global ] + bi ] with-compilation-unit diff --git a/extra/io/servers/connection/connection-tests.factor b/extra/io/servers/connection/connection-tests.factor index bb87d67917..84e0d684ac 100755 --- a/extra/io/servers/connection/connection-tests.factor +++ b/extra/io/servers/connection/connection-tests.factor @@ -29,18 +29,22 @@ concurrency.promises io.encodings.ascii io threads calendar ; [ ] [ <promise> "p" set ] unit-test +[ ] [ + <threaded-server> + 5 >>max-connections + 1237 >>insecure + [ "Hello world." write stop-server ] >>handler + "server" set +] unit-test + [ ] [ [ - <threaded-server> - 5 >>max-connections - 1237 >>insecure - [ "Hello world." write stop-server ] >>handler - start-server + "server" get start-server t "p" get fulfill ] in-thread ] unit-test -[ ] [ 100 sleep ] unit-test +[ ] [ "server" get wait-for-server ] unit-test [ "Hello world." ] [ "localhost" 1237 <inet> ascii <client> drop contents ] unit-test diff --git a/extra/io/servers/connection/connection.factor b/extra/io/servers/connection/connection.factor index b062322142..fa0e2f515d 100755 --- a/extra/io/servers/connection/connection.factor +++ b/extra/io/servers/connection/connection.factor @@ -2,11 +2,12 @@ ! See http://factorcode.org/license.txt for BSD license. USING: continuations destructors kernel math math.parser namespaces parser sequences strings prettyprint debugger -quotations combinators combinators.lib logging calendar assocs +quotations combinators logging calendar assocs fry accessors arrays io io.sockets io.encodings.ascii io.sockets.secure io.files io.streams.duplex io.timeouts io.encodings threads concurrency.combinators -concurrency.semaphores ; +concurrency.semaphores concurrency.flags +combinators.short-circuit ; IN: io.servers.connection TUPLE: threaded-server @@ -18,7 +19,8 @@ max-connections semaphore timeout encoding -handler ; +handler +ready ; : local-server ( port -- addrspec ) "localhost" swap <inet> ; @@ -31,7 +33,8 @@ handler ; 1 minutes >>timeout V{ } clone >>sockets <secure-config> >>secure-config - [ "No handler quotation" throw ] >>handler ; inline + [ "No handler quotation" throw ] >>handler + <flag> >>ready ; inline : <threaded-server> ( -- threaded-server ) threaded-server new-threaded-server ; @@ -86,11 +89,13 @@ M: threaded-server handle-client* handler>> call ; if* ] [ accept-loop ] bi ; inline -: start-accept-loop ( server -- ) +: started-accept-loop ( server -- ) + threaded-server get + [ sockets>> push ] [ ready>> raise-flag ] bi ; + +: start-accept-loop ( addrspec -- ) threaded-server get encoding>> <server> - [ threaded-server get sockets>> push ] - [ [ accept-loop ] with-disposal ] - bi ; + [ started-accept-loop ] [ [ accept-loop ] with-disposal ] bi ; \ start-accept-loop ERROR add-error-logging @@ -115,6 +120,14 @@ PRIVATE> ] with-variable ] with-secure-context ; +: wait-for-server ( threaded-server -- ) + ready>> wait-for-flag ; + +: start-server* ( threaded-server -- ) + [ [ start-server ] curry "Threaded server" spawn drop ] + [ wait-for-server ] + bi ; + : stop-server ( -- ) threaded-server get [ f ] change-sockets drop dispose-each ; diff --git a/extra/io/sockets/secure/secure-tests.factor b/extra/io/sockets/secure/secure-tests.factor old mode 100644 new mode 100755 index 78de43d379..311127e333 --- a/extra/io/sockets/secure/secure-tests.factor +++ b/extra/io/sockets/secure/secure-tests.factor @@ -2,3 +2,11 @@ IN: io.sockets.secure.tests USING: accessors kernel io.sockets io.sockets.secure tools.test ; [ "hello" 24 ] [ "hello" 24 <inet> <secure> [ host>> ] [ port>> ] bi ] unit-test + +[ ] [ + <secure-config> + "resource:extra/openssl/test/server.pem" >>key-file + "resource:extra/openssl/test/dh1024.pem" >>dh-file + "password" >>password + [ ] with-secure-context +] unit-test diff --git a/extra/io/windows/files/files.factor b/extra/io/windows/files/files.factor index 6787936f96..419509f124 100755 --- a/extra/io/windows/files/files.factor +++ b/extra/io/windows/files/files.factor @@ -4,13 +4,13 @@ USING: alien.c-types io.binary io.backend io.files io.buffers io.windows kernel math splitting windows windows.kernel32 windows.time calendar combinators math.functions sequences namespaces words symbols system -combinators.lib io.ports destructors accessors +io.ports destructors accessors math.bitfields math.bitfields.lib ; IN: io.windows.files : open-file ( path access-mode create-mode flags -- handle ) [ - >r >r share-mode security-attributes-inherit r> r> + >r >r share-mode default-security-attributes r> r> CreateFile-flags f CreateFile opened-file ] with-destructors ; @@ -216,11 +216,11 @@ M: winnt link-info ( path -- info ) "FILETIME" <c-object> "FILETIME" <c-object> [ GetFileTime win32-error=0/f ] 3keep - [ FILETIME>timestamp >local-time ] 3apply + [ FILETIME>timestamp >local-time ] tri@ ] with-destructors ; : (set-file-times) ( handle timestamp/f timestamp/f timestamp/f -- ) - [ timestamp>FILETIME ] 3apply + [ timestamp>FILETIME ] tri@ SetFileTime win32-error=0/f ; : set-file-times ( path timestamp/f timestamp/f timestamp/f -- ) diff --git a/extra/io/windows/nt/backend/backend.factor b/extra/io/windows/nt/backend/backend.factor index 1a7462f304..786275c736 100755 --- a/extra/io/windows/nt/backend/backend.factor +++ b/extra/io/windows/nt/backend/backend.factor @@ -3,7 +3,7 @@ continuations destructors io io.backend io.ports io.timeouts io.windows io.windows.files libc kernel math namespaces sequences threads classes.tuple.lib windows windows.errors windows.kernel32 strings splitting io.files -io.buffers qualified ascii combinators.lib system +io.buffers qualified ascii system accessors locals ; QUALIFIED: windows.winsock IN: io.windows.nt.backend diff --git a/extra/io/windows/nt/files/files.factor b/extra/io/windows/nt/files/files.factor index e8bdd8e4ec..2a39cea479 100755 --- a/extra/io/windows/nt/files/files.factor +++ b/extra/io/windows/nt/files/files.factor @@ -3,7 +3,7 @@ io.timeouts io.ports io.windows io.windows.files io.windows.nt.backend windows windows.kernel32 kernel libc math threads system alien.c-types alien.arrays alien.strings sequences combinators -combinators.lib sequences.lib ascii splitting alien strings +combinators.short-circuit ascii splitting alien strings assocs namespaces io.files.private accessors ; IN: io.windows.nt.files @@ -22,21 +22,18 @@ M: winnt root-directory? ( path -- ? ) { { [ dup empty? ] [ f ] } { [ dup [ path-separator? ] all? ] [ t ] } - { [ dup right-trim-separators - { [ dup length 2 = ] [ dup second CHAR: : = ] } 0&& nip ] [ - t - ] } + { [ dup right-trim-separators { [ length 2 = ] [ second CHAR: : = ] } 1&& ] [ t ] } [ f ] } cond nip ; ERROR: not-absolute-path ; : root-directory ( string -- string' ) - { - [ dup length 2 >= ] - [ dup second CHAR: : = ] - [ dup first Letter? ] - } 0&& [ 2 head ] [ not-absolute-path ] if ; + dup { + [ length 2 >= ] + [ second CHAR: : = ] + [ first Letter? ] + } 1&& [ 2 head ] [ not-absolute-path ] if ; : prepend-prefix ( string -- string' ) dup unicode-prefix head? [ diff --git a/extra/io/windows/nt/launcher/launcher.factor b/extra/io/windows/nt/launcher/launcher.factor index 6c86b53049..ff11c456ca 100755 --- a/extra/io/windows/nt/launcher/launcher.factor +++ b/extra/io/windows/nt/launcher/launcher.factor @@ -46,7 +46,7 @@ IN: io.windows.nt.launcher path normalize-path access-mode share-mode - security-attributes-inherit + default-security-attributes create-mode FILE_ATTRIBUTE_NORMAL ! flags and attributes f ! template file @@ -58,11 +58,8 @@ IN: io.windows.nt.launcher redirect-file dup 0 FILE_END set-file-pointer ; -: set-inherit ( handle ? -- ) - >r HANDLE_FLAG_INHERIT r> >BOOLEAN SetHandleInformation win32-error=0/f ; - : redirect-handle ( handle access-mode create-mode -- handle ) - 2drop handle>> duplicate-handle dup t set-inherit ; + 2drop handle>> duplicate-handle ; : redirect-stream ( stream access-mode create-mode -- handle ) >r >r underlying-handle handle>> r> r> redirect-handle ; @@ -75,7 +72,8 @@ IN: io.windows.nt.launcher { [ pick appender? ] [ redirect-append ] } { [ pick win32-file? ] [ redirect-handle ] } [ redirect-stream ] - } cond ; + } cond + dup [ dup t set-inherit ] when ; : redirect-stdout ( process args -- handle ) drop diff --git a/extra/io/windows/nt/nt.factor b/extra/io/windows/nt/nt.factor index 8e59a4d555..d79af52c5e 100755 --- a/extra/io/windows/nt/nt.factor +++ b/extra/io/windows/nt/nt.factor @@ -12,6 +12,7 @@ USE: io.windows.nt.sockets USE: io.windows.mmap USE: io.windows.files USE: io.backend +USE: openssl USE: system winnt set-io-backend diff --git a/extra/io/windows/nt/pipes/pipes.factor b/extra/io/windows/nt/pipes/pipes.factor index 97c2e49627..dc0d7cf1e5 100755 --- a/extra/io/windows/nt/pipes/pipes.factor +++ b/extra/io/windows/nt/pipes/pipes.factor @@ -16,13 +16,13 @@ IN: io.windows.nt.pipes 4096 4096 0 - security-attributes-inherit + default-security-attributes CreateNamedPipe opened-file ; : open-other-end ( name -- handle ) GENERIC_WRITE { FILE_SHARE_READ FILE_SHARE_WRITE } flags - security-attributes-inherit + default-security-attributes OPEN_EXISTING FILE_FLAG_OVERLAPPED f diff --git a/extra/io/windows/sockets/sockets.factor b/extra/io/windows/sockets/sockets.factor index 359776d639..d9ab10d5e3 100755 --- a/extra/io/windows/sockets/sockets.factor +++ b/extra/io/windows/sockets/sockets.factor @@ -7,8 +7,7 @@ HOOK: WSASocket-flags io-backend ( -- DWORD ) TUPLE: win32-socket < win32-file ; : <win32-socket> ( handle -- win32-socket ) - win32-socket new - swap >>handle ; + win32-socket new-win32-handle ; M: win32-socket dispose ( stream -- ) handle>> closesocket drop ; diff --git a/extra/io/windows/windows.factor b/extra/io/windows/windows.factor index 5e10389c44..0892563a02 100755 --- a/extra/io/windows/windows.factor +++ b/extra/io/windows/windows.factor @@ -8,10 +8,13 @@ windows.shell32 windows.types windows.winsock splitting continuations math.bitfields system accessors ; IN: io.windows +: set-inherit ( handle ? -- ) + >r HANDLE_FLAG_INHERIT r> >BOOLEAN SetHandleInformation win32-error=0/f ; + TUPLE: win32-handle handle disposed ; : new-win32-handle ( handle class -- win32-handle ) - new swap >>handle ; + new swap [ >>handle ] [ f set-inherit ] bi ; : <win32-handle> ( handle -- win32-handle ) win32-handle new-win32-handle ; diff --git a/extra/lcs/lcs.factor b/extra/lcs/lcs.factor index 4b0fb53f5e..2fa0b6cc71 100755 --- a/extra/lcs/lcs.factor +++ b/extra/lcs/lcs.factor @@ -1,5 +1,6 @@ USING: sequences kernel math locals math.order math.ranges -accessors combinators.lib arrays namespaces combinators ; +accessors combinators.lib arrays namespaces combinators +combinators.short-circuit ; IN: lcs <PRIVATE diff --git a/extra/lisp/lisp.factor b/extra/lisp/lisp.factor index e3d942d390..109083de37 100644 --- a/extra/lisp/lisp.factor +++ b/extra/lisp/lisp.factor @@ -3,7 +3,7 @@ USING: kernel peg sequences arrays strings combinators.lib namespaces combinators math locals locals.private locals.backend accessors vectors syntax lisp.parser assocs parser sequences.lib words -quotations fry lists inspector ; +quotations fry lists inspector combinators.short-circuit ; IN: lisp DEFER: convert-form diff --git a/extra/lisp/parser/parser.factor b/extra/lisp/parser/parser.factor index 8fadb00e65..428e1221da 100644 --- a/extra/lisp/parser/parser.factor +++ b/extra/lisp/parser/parser.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 James Cash ! See http://factorcode.org/license.txt for BSD license. USING: kernel peg peg.ebnf peg.expr math.parser sequences arrays strings -combinators.lib math fry accessors lists ; +combinators.lib math fry accessors lists combinators.short-circuit ; IN: lisp.parser diff --git a/extra/locals/locals-tests.factor b/extra/locals/locals-tests.factor index 4e670cdac0..025e175bc2 100755 --- a/extra/locals/locals-tests.factor +++ b/extra/locals/locals-tests.factor @@ -1,6 +1,6 @@ USING: locals math sequences tools.test hashtables words kernel namespaces arrays strings prettyprint io.streams.string parser -accessors ; +accessors generic ; IN: locals.tests :: foo ( a b -- a a ) a a ; @@ -265,3 +265,14 @@ M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ; [ \ a-word-with-locals see ] with-string-writer new-definition = ] unit-test + +: method-definition "USING: locals locals.tests sequences ;\nM:: sequence method-with-locals ( a -- y ) a reverse ;\n" ; + +GENERIC: method-with-locals ( x -- y ) + +M:: sequence method-with-locals ( a -- y ) a reverse ; + +[ t ] [ + [ \ sequence \ method-with-locals method see ] with-string-writer + method-definition = +] unit-test diff --git a/extra/locals/locals.factor b/extra/locals/locals.factor index 028502560f..49eec6d652 100755 --- a/extra/locals/locals.factor +++ b/extra/locals/locals.factor @@ -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 @@ -405,8 +405,8 @@ M: lambda-memoized reset-word M: lambda-method synopsis* dup dup dup definer. - "method-specializer" word-prop pprint* - "method-generic" word-prop pprint* + "method-class" word-prop pprint-word + "method-generic" word-prop pprint-word method-stack-effect effect>string comment. ; PRIVATE> diff --git a/extra/lsys/strings/interpret/interpret.factor b/extra/lsys/strings/interpret/interpret.factor index bcd87ca137..1d992cc1e2 100644 --- a/extra/lsys/strings/interpret/interpret.factor +++ b/extra/lsys/strings/interpret/interpret.factor @@ -1,6 +1,6 @@ USING: kernel sequences quotations assocs math math.parser - combinators.lib vars lsys.strings ; + combinators.lib vars lsys.strings combinators.short-circuit ; IN: lsys.strings.interpret diff --git a/extra/lsys/strings/rewrite/rewrite.factor b/extra/lsys/strings/rewrite/rewrite.factor index eb76dbd751..622a86c425 100644 --- a/extra/lsys/strings/rewrite/rewrite.factor +++ b/extra/lsys/strings/rewrite/rewrite.factor @@ -1,6 +1,6 @@ USING: kernel sbufs strings sequences assocs math - combinators.lib vars lsys.strings ; + combinators.lib vars lsys.strings combinators.short-circuit ; IN: lsys.strings.rewrite diff --git a/extra/lsys/strings/strings.factor b/extra/lsys/strings/strings.factor index f184ca5dfc..603c6cc630 100644 --- a/extra/lsys/strings/strings.factor +++ b/extra/lsys/strings/strings.factor @@ -1,5 +1,5 @@ -USING: kernel sequences math combinators.lib ; +USING: kernel sequences math combinators.lib combinators.short-circuit ; IN: lsys.strings diff --git a/extra/lsys/tortoise/graphics/graphics.factor b/extra/lsys/tortoise/graphics/graphics.factor index d75915ae8e..ab679c8369 100644 --- a/extra/lsys/tortoise/graphics/graphics.factor +++ b/extra/lsys/tortoise/graphics/graphics.factor @@ -2,7 +2,7 @@ USING: kernel math vectors sequences opengl.gl math.vectors math.order math.matrices vars opengl self pos ori turtle lsys.tortoise - lsys.strings.interpret ; + lsys.strings.interpret combinators.short-circuit ; ! lsys.strings diff --git a/extra/lsys/ui/ui.factor b/extra/lsys/ui/ui.factor index c3b9190c3c..8f9513ff2a 100644 --- a/extra/lsys/ui/ui.factor +++ b/extra/lsys/ui/ui.factor @@ -16,7 +16,8 @@ USING: kernel namespaces threads math math.order math.vectors vars rewrite-closures self pos ori turtle opengl.camera lsys.tortoise lsys.tortoise.graphics - lsys.strings.rewrite lsys.strings.interpret ; + lsys.strings.rewrite lsys.strings.interpret + combinators.short-circuit ; ! lsys.strings ! lsys.strings.rewrite @@ -100,17 +101,17 @@ DEFER: empty-model { -[ "Load" <label> dup reverse-video-theme ] +[ "Load" <label> reverse-video-theme ] [ "Models" <label> [ drop model-chooser ] closed-quot <bevel-button> ] [ "Scenes" <label> [ drop scene-chooser ] closed-quot <bevel-button> ] -[ "Model" <label> dup reverse-video-theme ] +[ "Model" <label> reverse-video-theme ] [ "Iterate" <label> [ drop iterate build-model ] closed-quot <bevel-button> ] [ "Build model" <label> [ drop build-model ] closed-quot <bevel-button> ] -[ "Camera" <label> dup reverse-video-theme ] +[ "Camera" <label> reverse-video-theme ] [ "Turn left" <label> [ 5 turn-left ] camera-action <bevel-button> ] [ "Turn right" <label> [ 5 turn-right ] camera-action <bevel-button> ] diff --git a/extra/match/match.factor b/extra/match/match.factor index 8a174034ba..0ae285d20d 100755 --- a/extra/match/match.factor +++ b/extra/match/match.factor @@ -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 diff --git a/extra/math/text/english/english.factor b/extra/math/text/english/english.factor index 500e08f79d..b8256533bf 100755 --- a/extra/math/text/english/english.factor +++ b/extra/math/text/english/english.factor @@ -1,7 +1,8 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math math.functions math.parser namespaces - sequences splitting grouping sequences.lib ; + sequences splitting grouping sequences.lib + combinators.short-circuit ; IN: math.text.english <PRIVATE diff --git a/extra/money/money.factor b/extra/money/money.factor index 54c53e9bec..ba7a0ae04f 100644 --- a/extra/money/money.factor +++ b/extra/money/money.factor @@ -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 diff --git a/extra/mortar/mortar.factor b/extra/mortar/mortar.factor index 3a4dc6fefb..1b5b6f2393 100644 --- a/extra/mortar/mortar.factor +++ b/extra/mortar/mortar.factor @@ -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 diff --git a/extra/multiline/multiline.factor b/extra/multiline/multiline.factor index ce79bdaf5f..cf671c5609 100755 --- a/extra/multiline/multiline.factor +++ b/extra/multiline/multiline.factor @@ -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 ) diff --git a/extra/opengl/demo-support/demo-support.factor b/extra/opengl/demo-support/demo-support.factor index 88531a70bc..6596948f45 100755 --- a/extra/opengl/demo-support/demo-support.factor +++ b/extra/opengl/demo-support/demo-support.factor @@ -1,4 +1,4 @@ -USING: arrays combinators.lib kernel math math.functions +USING: arrays kernel math math.functions math.order math.vectors namespaces opengl opengl.gl sequences ui ui.gadgets ui.gestures ui.render accessors ; IN: opengl.demo-support diff --git a/extra/opengl/gl/extensions/extensions.factor b/extra/opengl/gl/extensions/extensions.factor index 8f2eee9459..fd547c8b5a 100644 --- a/extra/opengl/gl/extensions/extensions.factor +++ b/extra/opengl/gl/extensions/extensions.factor @@ -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 ; diff --git a/extra/openssl/libssl/libssl.factor b/extra/openssl/libssl/libssl.factor index dced2e5c0c..e951ad8858 100755 --- a/extra/openssl/libssl/libssl.factor +++ b/extra/openssl/libssl/libssl.factor @@ -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 diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 4725534178..3d48665c8c 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -2,9 +2,10 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel compiler.units words arrays strings math.parser sequences quotations vectors namespaces math assocs continuations peg - peg.parsers unicode.categories multiline combinators combinators.lib - splitting accessors effects sequences.deep peg.search inference - io.streams.string io prettyprint parser ; + peg.parsers unicode.categories multiline combinators.lib + splitting accessors effects sequences.deep peg.search + combinators.short-circuit lexer io.streams.string inference io + prettyprint combinators parser ; IN: peg.ebnf : rule ( name word -- parser ) @@ -22,7 +23,7 @@ TUPLE: tokenizer any one many ; : parser-tokenizer ( parser -- tokenizer ) [ 1quotation ] keep - [ swap [ = ] curry semantic ] curry dup tokenizer boa ; + [ swap [ = ] curry semantic ] curry dup \ tokenizer boa ; : rule-tokenizer ( name word -- tokenizer ) rule parser-tokenizer ; diff --git a/extra/peg/javascript/parser/parser.factor b/extra/peg/javascript/parser/parser.factor index 5eb42daa31..b7df9908da 100644 --- a/extra/peg/javascript/parser/parser.factor +++ b/extra/peg/javascript/parser/parser.factor @@ -60,9 +60,9 @@ RelExpr = RelExpr:x ">" AddExpr:y => [[ x y ">" ast-binop AddExpr = AddExpr:x "+" MulExpr:y => [[ x y "+" ast-binop boa ]] | AddExpr:x "-" MulExpr:y => [[ x y "-" ast-binop boa ]] | MulExpr -MulExpr = MulExpr:x "*" MulExpr:y => [[ x y "*" ast-binop boa ]] - | MulExpr:x "/" MulExpr:y => [[ x y "/" ast-binop boa ]] - | MulExpr:x "%" MulExpr:y => [[ x y "%" ast-binop boa ]] +MulExpr = MulExpr:x "*" Unary:y => [[ x y "*" ast-binop boa ]] + | MulExpr:x "/" Unary:y => [[ x y "/" ast-binop boa ]] + | MulExpr:x "%" Unary:y => [[ x y "%" ast-binop boa ]] | Unary Unary = "-" Postfix:p => [[ p "-" ast-unop boa ]] | "+" Postfix:p => [[ p ]] @@ -89,7 +89,8 @@ PrimExprHd = "(" Expr:e ")" => [[ e ]] | String => [[ ast-string boa ]] | RegExp => [[ ast-regexp boa ]] | "function" FuncRest:fr => [[ fr ]] - | "new" Name:n "(" Args:as ")" => [[ n as ast-new boa ]] + | "new" PrimExpr:n "(" Args:as ")" => [[ n as ast-new boa ]] + | "new" PrimExpr:n => [[ n f ast-new boa ]] | "[" Args:es "]" => [[ es ast-array boa ]] | Json JsonBindings = (JsonBinding ("," JsonBinding => [[ second ]])* => [[ first2 swap prefix ]])? diff --git a/extra/persistent-vectors/persistent-vectors-tests.factor b/extra/persistent-vectors/persistent-vectors-tests.factor index a4e4ad33fe..45eb894e67 100644 --- a/extra/persistent-vectors/persistent-vectors-tests.factor +++ b/extra/persistent-vectors/persistent-vectors-tests.factor @@ -48,6 +48,10 @@ random namespaces vectors math math.order ; [ ] [ PV{ } "1" set ] unit-test [ ] [ V{ } clone "2" set ] unit-test +: push/pop-test ( vec -- vec' ) 3 swap ppush 3 swap ppush ppop ; + +[ ] [ PV{ } 10000 [ push/pop-test ] times drop ] unit-test + [ t ] [ 100 [ drop diff --git a/extra/persistent-vectors/persistent-vectors.factor b/extra/persistent-vectors/persistent-vectors.factor index f9f4b68933..691ebfcf4d 100644 --- a/extra/persistent-vectors/persistent-vectors.factor +++ b/extra/persistent-vectors/persistent-vectors.factor @@ -1,7 +1,7 @@ ! Based on Clojure's PersistentVector by Rich Hickey. USING: math accessors kernel sequences.private sequences arrays -combinators parser prettyprint.backend ; +combinators combinators.short-circuit parser prettyprint.backend ; IN: persistent-vectors ERROR: empty-error pvec ; @@ -123,30 +123,39 @@ M: persistent-vector new-nth ( obj i pvec -- pvec' ) ] if ] if ; +: ppop-tail ( pvec -- pvec' ) + [ clone [ ppop ] change-children ] change-tail ; + : (ppop-contraction) ( node -- node' tail' ) clone [ unclip-last swap ] change-children swap ; : ppop-contraction ( node -- node' tail' ) - [ (ppop-contraction) ] [ level>> 1 = ] bi swap and ; + dup children>> length 1 = + [ children>> peek f swap ] + [ (ppop-contraction) ] + if ; : (ppop-new-tail) ( root -- root' tail' ) dup level>> 1 > [ - dup children>> peek (ppop-new-tail) over children>> empty? - [ 2drop ppop-contraction ] [ [ swap node-set-last ] dip ] if + dup children>> peek (ppop-new-tail) over + [ [ swap node-set-last ] dip ] + [ 2drop ppop-contraction ] + if ] [ ppop-contraction ] if ; -: ppop-tail ( pvec -- pvec' ) - [ clone [ ppop ] change-children ] change-tail ; +: trivial? ( node -- ? ) + { [ level>> 1 > ] [ children>> length 1 = ] } 1&& ; : ppop-new-tail ( pvec -- pvec' ) - dup root>> (ppop-new-tail) - [ - dup [ level>> 1 > ] [ children>> length 1 = ] bi and - [ children>> first ] when - ] dip - [ >>root ] [ >>tail ] bi* ; + dup root>> (ppop-new-tail) [ + { + { [ dup not ] [ drop T{ node f { } 1 } ] } + { [ dup trivial? ] [ children>> first ] } + [ ] + } cond + ] dip [ >>root ] [ >>tail ] bi* ; PRIVATE> diff --git a/extra/project-euler/014/014.factor b/extra/project-euler/014/014.factor index ef8ef8c0f7..b99e34d36f 100644 --- a/extra/project-euler/014/014.factor +++ b/extra/project-euler/014/014.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: arrays combinators.lib kernel math math.ranges namespaces sequences - sorting ; + sorting combinators.short-circuit ; IN: project-euler.014 ! http://projecteuler.net/index.php?section=problems&id=14 diff --git a/extra/project-euler/017/017.factor b/extra/project-euler/017/017.factor index ffff10d4fe..cf58e88ffe 100644 --- a/extra/project-euler/017/017.factor +++ b/extra/project-euler/017/017.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: kernel math.ranges math.text.english sequences sequences.lib strings - ascii ; + ascii combinators.short-circuit ; IN: project-euler.017 ! http://projecteuler.net/index.php?section=problems&id=17 diff --git a/extra/project-euler/021/021.factor b/extra/project-euler/021/021.factor index e6eadba264..f09b0c0b42 100644 --- a/extra/project-euler/021/021.factor +++ b/extra/project-euler/021/021.factor @@ -1,7 +1,8 @@ ! Copyright (c) 2007 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math math.functions math.ranges namespaces - project-euler.common sequences sequences.lib ; + project-euler.common sequences sequences.lib + combinators.short-circuit ; IN: project-euler.021 ! http://projecteuler.net/index.php?section=problems&id=21 diff --git a/extra/project-euler/032/032.factor b/extra/project-euler/032/032.factor index 68b42ca442..8a54c595a9 100755 --- a/extra/project-euler/032/032.factor +++ b/extra/project-euler/032/032.factor @@ -31,11 +31,11 @@ IN: project-euler.032 : 1and4 ( n -- ? ) number>string 1 cut-slice 4 cut-slice - [ string>number ] 3apply [ * ] dip = ; + [ string>number ] tri@ [ * ] dip = ; : 2and3 ( n -- ? ) number>string 2 cut-slice 3 cut-slice - [ string>number ] 3apply [ * ] dip = ; + [ string>number ] tri@ [ * ] dip = ; : valid? ( n -- ? ) dup 1and4 swap 2and3 or ; @@ -65,7 +65,7 @@ PRIVATE> ! multiplicand/multiplier/product : mmp ( pair -- n ) - first2 2dup * [ number>string ] 3apply 3append string>number ; + first2 2dup * [ number>string ] tri@ 3append string>number ; PRIVATE> diff --git a/extra/project-euler/036/036.factor b/extra/project-euler/036/036.factor index fbf6376eb3..4a4f906467 100644 --- a/extra/project-euler/036/036.factor +++ b/extra/project-euler/036/036.factor @@ -1,7 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib kernel math.parser math.ranges project-euler.common - sequences ; + sequences combinators.short-circuit ; IN: project-euler.036 ! http://projecteuler.net/index.php?section=problems&id=36 diff --git a/extra/project-euler/039/039.factor b/extra/project-euler/039/039.factor old mode 100644 new mode 100755 index 9075b19324..7a9f51f1d3 --- a/extra/project-euler/039/039.factor +++ b/extra/project-euler/039/039.factor @@ -44,7 +44,7 @@ SYMBOL: p-count dup sum max-p < [ dup sum adjust-p-count [ u-transform ] [ a-transform ] [ d-transform ] tri - [ (count-perimeters) ] 3apply + [ (count-perimeters) ] tri@ ] [ drop ] if ; diff --git a/extra/project-euler/043/043.factor b/extra/project-euler/043/043.factor index 0c51146656..e095d94ead 100644 --- a/extra/project-euler/043/043.factor +++ b/extra/project-euler/043/043.factor @@ -1,7 +1,8 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. USING: combinators.lib hashtables kernel math math.combinatorics math.parser - math.ranges project-euler.common sequences sequences.lib sorting sets ; + math.ranges project-euler.common sequences sequences.lib sorting + sets combinators.short-circuit ; IN: project-euler.043 ! http://projecteuler.net/index.php?section=problems&id=43 diff --git a/extra/project-euler/052/052.factor b/extra/project-euler/052/052.factor index 6c4b605bd9..194530ea78 100644 --- a/extra/project-euler/052/052.factor +++ b/extra/project-euler/052/052.factor @@ -1,6 +1,7 @@ ! Copyright (c) 2008 Aaron Schaefer. ! See http://factorcode.org/license.txt for BSD license. -USING: combinators.lib kernel math project-euler.common sequences sorting ; +USING: combinators.lib kernel math project-euler.common sequences +sorting combinators.short-circuit ; IN: project-euler.052 ! http://projecteuler.net/index.php?section=problems&id=52 diff --git a/extra/project-euler/075/075.factor b/extra/project-euler/075/075.factor old mode 100644 new mode 100755 index 453ebfa129..8e5b849de5 --- a/extra/project-euler/075/075.factor +++ b/extra/project-euler/075/075.factor @@ -57,7 +57,7 @@ SYMBOL: p-count dup sum max-p < [ dup sum adjust-p-count [ u-transform ] [ a-transform ] [ d-transform ] tri - [ (count-perimeters) ] 3apply + [ (count-perimeters) ] tri@ ] [ drop ] if ; diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 9325e74d93..3101c900e3 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -17,7 +17,7 @@ USING: definitions io io.files kernel math math.parser project-euler.ave-time project-euler.052 project-euler.053 project-euler.056 project-euler.059 project-euler.067 project-euler.075 project-euler.079 project-euler.092 project-euler.097 project-euler.134 project-euler.169 project-euler.173 - project-euler.175 ; + project-euler.175 combinators.short-circuit ; IN: project-euler <PRIVATE diff --git a/extra/qualified/qualified.factor b/extra/qualified/qualified.factor index 5810a03f80..d636cc0152 100644 --- a/extra/qualified/qualified.factor +++ b/extra/qualified/qualified.factor @@ -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 -- ) diff --git a/extra/regexp/regexp.factor b/extra/regexp/regexp.factor index 99e6b887c8..c329977875 100755 --- a/extra/regexp/regexp.factor +++ b/extra/regexp/regexp.factor @@ -1,7 +1,8 @@ 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 ; +assocs prettyprint.backend memoize unicode.case unicode.categories +combinators.short-circuit ; USE: io IN: regexp @@ -20,9 +21,6 @@ SYMBOL: ignore-case? [ [ between? ] ] if 2curry ; -: or-predicates ( quots -- quot ) - [ \ dup prefix ] map [ [ t ] ] f short-circuit \ nip suffix ; - : <@literal ( parser obj -- action ) [ nip ] curry <@ ; : <@delay ( parser quot -- action ) [ curry ] curry <@ ; @@ -179,7 +177,7 @@ C: <group-result> group-result : 'positive-character-class' ( -- parser ) "]" token [ CHAR: ] = ] <@literal 'character-class-term' <*> <&:> 'character-class-term' <+> <|> - [ or-predicates ] <@ ; + [ [ 1|| ] curry ] <@ ; : 'negative-character-class' ( -- parser ) "^" token 'positive-character-class' &> diff --git a/extra/reports/noise/noise.factor b/extra/reports/noise/noise.factor index 3537d2e719..fc8ba9821c 100755 --- a/extra/reports/noise/noise.factor +++ b/extra/reports/noise/noise.factor @@ -20,7 +20,6 @@ IN: reports.noise { 2swap 3 } { 2with 2 } { 2with* 3 } - { 3apply 1/2 } { 3curry 2 } { 3drop 1 } { 3dup 2 } diff --git a/extra/semantic-db/semantic-db.factor b/extra/semantic-db/semantic-db.factor index 7d50d384e2..89ad6fe2d0 100755 --- a/extra/semantic-db/semantic-db.factor +++ b/extra/semantic-db/semantic-db.factor @@ -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 @@ -36,10 +36,10 @@ TUPLE: arc id subject object relation ; : delete-arc ( arc -- ) delete-tuples ; : create-arc ( subject object relation -- ) - [ id>> ] 3apply <arc> insert-tuple ; + [ id>> ] tri@ <arc> insert-tuple ; : nodes>arc ( subject object relation -- arc ) - [ [ id>> ] [ f ] if* ] 3apply <arc> ; + [ [ id>> ] [ f ] if* ] tri@ <arc> ; : select-arcs ( subject object relation -- arcs ) nodes>arc select-tuples ; diff --git a/extra/sequences/lib/lib.factor b/extra/sequences/lib/lib.factor index 324b8d166d..feb3793098 100755 --- a/extra/sequences/lib/lib.factor +++ b/extra/sequences/lib/lib.factor @@ -238,9 +238,6 @@ PRIVATE> : remove-nth ( seq n -- seq' ) cut-slice rest-slice append ; -: short ( seq n -- seq n' ) - over length min ; inline - : if-seq ( seq quot1 quot2 -- ) [ f like ] 2dip if* ; inline diff --git a/extra/shell/shell.factor b/extra/shell/shell.factor index 8ba5b66d5a..45c6f1fb4d 100644 --- a/extra/shell/shell.factor +++ b/extra/shell/shell.factor @@ -2,7 +2,8 @@ USING: kernel parser words continuations namespaces debugger sequences combinators splitting prettyprint system io io.files io.launcher io.encodings.utf8 io.pipes sequences.deep - accessors multi-methods newfx shell.parser ; + accessors multi-methods newfx shell.parser + combinators.short-circuit ; IN: shell diff --git a/extra/state-machine/state-machine.factor b/extra/state-machine/state-machine.factor index 4c83c64641..b5e8c16b02 100755 --- a/extra/state-machine/state-machine.factor +++ b/extra/state-machine/state-machine.factor @@ -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 diff --git a/extra/symbols/symbols.factor b/extra/symbols/symbols.factor index 20cf16e640..6cf8eac6fb 100755 --- a/extra/symbols/symbols.factor +++ b/extra/symbols/symbols.factor @@ -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: diff --git a/extra/syndication/syndication.factor b/extra/syndication/syndication.factor index 32b3c925f3..8d4c91177a 100644 --- a/extra/syndication/syndication.factor +++ b/extra/syndication/syndication.factor @@ -53,7 +53,7 @@ TUPLE: entry title url description date ; swap { [ "title" tag-named children>string >>title ] [ { "link" "guid" } any-tag-named children>string >url >>url ] - [ "description" tag-named children>string >>description ] + [ { "description" "encoded" } any-tag-named children>string >>description ] [ { "date" "pubDate" } any-tag-named children>string try-parsing-timestamp >>date diff --git a/extra/tools/deploy/deploy-tests.factor b/extra/tools/deploy/deploy-tests.factor index 8ff22fb1ad..ed22902af2 100755 --- a/extra/tools/deploy/deploy-tests.factor +++ b/extra/tools/deploy/deploy-tests.factor @@ -49,12 +49,51 @@ namespaces continuations layouts accessors ; cell 8 = 50 30 ? 100000 * small-enough? ] unit-test +{ + "tools.deploy.test.1" + "tools.deploy.test.2" + "tools.deploy.test.3" + "tools.deploy.test.4" +} [ + [ ] swap [ + shake-and-bake + vm + "-i=" "test.image" temp-file append + 2array try-process + ] curry unit-test +] each + +USING: http.client furnace.actions http.server http.server.dispatchers +http.server.responses http.server.static io.servers.connection ; + +: add-quit-action + <action> + [ stop-server "Goodbye" "text/html" <content> ] >>display + "quit" add-responder ; + +: test-httpd ( -- ) + #! Return as soon as server is running. + <http-server> + 1237 >>insecure + f >>secure + start-server* ; + [ ] [ - "tools.deploy.test.1" shake-and-bake - vm "-i=" "test.image" temp-file append 2array try-process + [ + <dispatcher> + add-quit-action + "resource:extra/http/test" <static> >>default + main-responder set + + test-httpd + ] with-scope ] unit-test [ ] [ - "tools.deploy.test.2" shake-and-bake - vm "-i=" "test.image" temp-file append 2array try-process + "tools.deploy.test.5" shake-and-bake + vm + "-i=" "test.image" temp-file append + 2array try-process ] unit-test + +[ ] [ "http://localhost:1237/quit" http-get 2drop ] unit-test diff --git a/extra/tools/deploy/shaker/shaker.factor b/extra/tools/deploy/shaker/shaker.factor index db0f478709..5a20dd8911 100755 --- a/extra/tools/deploy/shaker/shaker.factor +++ b/extra/tools/deploy/shaker/shaker.factor @@ -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 @@ -66,28 +66,72 @@ IN: tools.deploy.shaker : strip-word-defs ( words -- ) "Stripping symbolic word definitions" show + [ "no-def-strip" word-prop not ] filter [ [ ] swap set-word-def ] each ; -: strip-word-props ( retain-props words -- ) +: strip-word-props ( stripped-props words -- ) "Stripping word properties" show [ [ word-props swap - '[ , nip member? ] assoc-filter + '[ , nip member? not ] assoc-filter f assoc-like ] keep set-word-props ] with each ; -: retained-props ( -- seq ) +: stripped-word-props ( -- seq ) [ - "class" , - "metaclass" , - "layout" , - deploy-ui? get [ - "gestures" , - "commands" , - { "+nullary+" "+listener+" "+description+" } - [ "ui.commands" lookup , ] each + strip-dictionary? [ + { + "coercer" + "compiled-effect" + "compiled-uses" + "constraints" + "declared-effect" + "default-output-classes" + "identities" + "if-intrinsics" + "infer" + "inferred-effect" + "interval" + "intrinsics" + "loc" + "members" + "methods" + "combination" + "cannot-infer" + "default-method" + "optimizer-hooks" + "output-classes" + "participants" + "predicate" + "predicate-definition" + "predicating" + "slots" + "slot-names" + "specializer" + "step-into" + "step-into?" + "superclass" + "reading" + "writing" + "type" + "engines" + } % + ] when + + strip-prettyprint? [ + { + "delimiter" + "flushable" + "foldable" + "inline" + "lambda" + "macro" + "memo-quot" + "parsing" + "word-style" + } % ] when ] { } make ; @@ -133,11 +177,11 @@ IN: tools.deploy.shaker strip-io? [ io.backend:io-backend , ] when - [ - io.backend:io-backend , - "default-buffer-size" "io.ports" lookup , - ] { } make - { "alarms" "io" "tools" } strip-vocab-globals % + { } { + "alarms" + "tools" + "io.launcher" + } strip-vocab-globals % strip-dictionary? [ { } { "cpu" } strip-vocab-globals % @@ -242,7 +286,7 @@ SYMBOL: deploy-vocab strip-recompile-hook strip-init-hooks deploy-vocab get vocab-main set-boot-quot* - retained-props >r + stripped-word-props >r stripped-globals strip-globals r> strip-words ; diff --git a/extra/tools/deploy/test/3/3.factor b/extra/tools/deploy/test/3/3.factor index 69287db4e2..5919fa15db 100755 --- a/extra/tools/deploy/test/3/3.factor +++ b/extra/tools/deploy/test/3/3.factor @@ -1,8 +1,7 @@ IN: tools.deploy.test.3 -USING: io.encodings.ascii io.files kernel ; +USING: io.encodings.ascii io.encodings.string system kernel ; : deploy-test-3 ( -- ) - "resource:extra/tools/deploy/test/3/3.factor" - ascii file-contents drop ; + "xyzthg" ascii encode drop ; MAIN: deploy-test-3 diff --git a/extra/tools/deploy/test/4/4.factor b/extra/tools/deploy/test/4/4.factor new file mode 100644 index 0000000000..a9ee71131c --- /dev/null +++ b/extra/tools/deploy/test/4/4.factor @@ -0,0 +1,7 @@ +IN: tools.deploy.test.4 +USING: io.encodings.8-bit io.encodings.string kernel ; + +: deploy-test-4 ( -- ) + "xyzthg" \ latin7 encode drop ; + +MAIN: deploy-test-4 diff --git a/extra/tools/deploy/test/4/deploy.factor b/extra/tools/deploy/test/4/deploy.factor new file mode 100644 index 0000000000..894d6aa62e --- /dev/null +++ b/extra/tools/deploy/test/4/deploy.factor @@ -0,0 +1,15 @@ +USING: tools.deploy.config ; +H{ + { deploy-math? f } + { deploy-reflection 1 } + { deploy-io 2 } + { deploy-c-types? f } + { deploy-random? f } + { deploy-ui? f } + { deploy-name "tools.deploy.test.4" } + { deploy-word-defs? f } + { "stop-after-last-window?" t } + { deploy-threads? t } + { deploy-compiler? t } + { deploy-word-props? f } +} diff --git a/extra/tools/deploy/test/5/5.factor b/extra/tools/deploy/test/5/5.factor new file mode 100644 index 0000000000..debc020d49 --- /dev/null +++ b/extra/tools/deploy/test/5/5.factor @@ -0,0 +1,7 @@ +IN: tools.deploy.test.5 +USING: http.client kernel ; + +: deploy-test-5 ( -- ) + "http://localhost:1237/foo.html" http-get 2drop ; + +MAIN: deploy-test-5 diff --git a/extra/tools/deploy/test/5/deploy.factor b/extra/tools/deploy/test/5/deploy.factor new file mode 100644 index 0000000000..87536457b0 --- /dev/null +++ b/extra/tools/deploy/test/5/deploy.factor @@ -0,0 +1,15 @@ +USING: tools.deploy.config ; +H{ + { deploy-math? t } + { deploy-reflection 2 } + { deploy-io 3 } + { deploy-c-types? f } + { deploy-random? t } + { deploy-ui? f } + { deploy-name "tools.deploy.test.5" } + { deploy-word-defs? f } + { "stop-after-last-window?" t } + { deploy-threads? t } + { deploy-compiler? t } + { deploy-word-props? f } +} diff --git a/extra/tuple-syntax/tuple-syntax.factor b/extra/tuple-syntax/tuple-syntax.factor index cf439f6407..ce717f4211 100755 --- a/extra/tuple-syntax/tuple-syntax.factor +++ b/extra/tuple-syntax/tuple-syntax.factor @@ -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 diff --git a/extra/ui/cocoa/cocoa.factor b/extra/ui/cocoa/cocoa.factor index 0db38e5eca..b0653ffa39 100755 --- a/extra/ui/cocoa/cocoa.factor +++ b/extra/ui/cocoa/cocoa.factor @@ -110,7 +110,6 @@ M: cocoa-ui-backend ui "UI" assert.app [ [ init-clipboard - stop-after-last-window? off cocoa-init-hook get [ call ] when* start-ui finish-launching diff --git a/extra/ui/gadgets/buttons/buttons.factor b/extra/ui/gadgets/buttons/buttons.factor index e452e6c455..c36d2050c9 100755 --- a/extra/ui/gadgets/buttons/buttons.factor +++ b/extra/ui/gadgets/buttons/buttons.factor @@ -41,7 +41,7 @@ button H{ : <button> ( gadget quot -- button ) button new - [ set-button-quot ] keep + swap >>quot [ set-gadget-delegate ] keep ; TUPLE: button-paint plain rollover pressed selected ; @@ -53,10 +53,10 @@ C: <button-paint> button-paint : button-paint ( button paint -- button paint ) over find-button { - { [ dup button-pressed? ] [ drop button-paint-pressed ] } - { [ dup button-selected? ] [ drop button-paint-selected ] } - { [ dup button-rollover? ] [ drop button-paint-rollover ] } - [ drop button-paint-plain ] + { [ dup pressed?>> ] [ drop pressed>> ] } + { [ dup selected?>> ] [ drop selected>> ] } + { [ dup button-rollover? ] [ drop rollover>> ] } + [ drop plain>> ] } cond ; M: button-paint draw-interior @@ -65,25 +65,26 @@ M: button-paint draw-interior M: button-paint draw-boundary button-paint draw-boundary ; -: roll-button-theme ( button -- ) - f black <solid> dup f <button-paint> - swap set-gadget-boundary ; +: roll-button-theme ( button -- button ) + f black <solid> dup f <button-paint> >>boundary ; inline : <roll-button> ( label quot -- button ) - >r >label r> - <button> dup roll-button-theme ; + >r >label r> <button> roll-button-theme ; -: bevel-button-theme ( gadget -- ) +: <bevel-button-paint> ( -- paint ) plain-gradient rollover-gradient pressed-gradient selected-gradient - <button-paint> over set-gadget-interior - faint-boundary ; + <button-paint> ; + +: bevel-button-theme ( gadget -- gadget ) + <bevel-button-paint> >>interior + faint-boundary ; inline : <bevel-button> ( label quot -- button ) >r >label 5 <border> r> - <button> dup bevel-button-theme ; + <button> bevel-button-theme ; TUPLE: repeat-button ; diff --git a/extra/ui/gadgets/canvas/canvas.factor b/extra/ui/gadgets/canvas/canvas.factor index 15df44fda4..0a9f07ed6e 100644 --- a/extra/ui/gadgets/canvas/canvas.factor +++ b/extra/ui/gadgets/canvas/canvas.factor @@ -9,7 +9,7 @@ TUPLE: canvas dlist ; : <canvas> ( -- canvas ) canvas construct-gadget - dup black solid-interior ; + black solid-interior ; : delete-canvas-dlist ( canvas -- ) dup find-gl-context diff --git a/extra/ui/gadgets/labelled/labelled.factor b/extra/ui/gadgets/labelled/labelled.factor index 63ab2f1d6f..3013dcd0bd 100755 --- a/extra/ui/gadgets/labelled/labelled.factor +++ b/extra/ui/gadgets/labelled/labelled.factor @@ -13,7 +13,7 @@ TUPLE: labelled-gadget content ; : <labelled-gadget> ( gadget title -- newgadget ) labelled-gadget new [ - <label> dup reverse-video-theme f track, + <label> reverse-video-theme f track, g-> set-labelled-gadget-content 1 track, ] { 0 1 } build-track ; diff --git a/extra/ui/gadgets/labels/labels.factor b/extra/ui/gadgets/labels/labels.factor index 167aa26084..f800b12120 100755 --- a/extra/ui/gadgets/labels/labels.factor +++ b/extra/ui/gadgets/labels/labels.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2005, 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays hashtables io kernel math namespaces +USING: accessors arrays hashtables io kernel math namespaces opengl sequences strings splitting ui.gadgets ui.gadgets.tracks ui.gadgets.theme ui.render colors models ; @@ -10,7 +10,7 @@ IN: ui.gadgets.labels TUPLE: label text font color ; : label-string ( label -- string ) - label-text dup string? [ "\n" join ] unless ; inline + text>> dup string? [ "\n" join ] unless ; inline : set-label-string ( string label -- ) CHAR: \n pick memq? [ @@ -19,21 +19,21 @@ TUPLE: label text font color ; set-label-text ] if ; inline -: label-theme ( gadget -- ) - black over set-label-color - sans-serif-font swap set-label-font ; +: label-theme ( gadget -- gadget ) + sans-serif-font >>font + black >>color ; inline : <label> ( string -- label ) label construct-gadget [ set-label-string ] keep - dup label-theme ; + label-theme ; M: label pref-dim* - dup label-font open-font swap label-text text-dim ; + [ font>> open-font ] [ text>> ] bi text-dim ; M: label draw-gadget* - dup label-color gl-color - dup label-font swap label-text origin get draw-text ; + [ color>> gl-color ] + [ [ font>> ] [ text>> ] bi origin get draw-text ] bi ; M: label gadget-text* label-string % ; @@ -45,12 +45,12 @@ M: label-control model-changed : <label-control> ( model -- gadget ) "" <label> label-control construct-control ; -: text-theme ( gadget -- ) - black over set-label-color - monospace-font swap set-label-font ; +: text-theme ( gadget -- gadget ) + black >>color + monospace-font >>font ; -: reverse-video-theme ( label -- ) - white over set-label-color +: reverse-video-theme ( label -- label ) + white >>color black solid-interior ; GENERIC: >label ( obj -- gadget ) diff --git a/extra/ui/gadgets/lists/lists.factor b/extra/ui/gadgets/lists/lists.factor index fd5234ab03..43c0539e91 100755 --- a/extra/ui/gadgets/lists/lists.factor +++ b/extra/ui/gadgets/lists/lists.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2006, 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: ui.commands ui.gestures ui.render ui.gadgets +USING: accessors ui.commands ui.gestures ui.render ui.gadgets ui.gadgets.labels ui.gadgets.scrollers kernel sequences models opengl math math.order namespaces ui.gadgets.presentations ui.gadgets.viewports ui.gadgets.packs @@ -27,17 +27,18 @@ TUPLE: list index presenter color hook ; swap set-list-index ; : list-presentation-hook ( list -- quot ) - list-hook [ [ [ list? ] is? ] find-parent ] prepend ; + hook>> [ [ [ list? ] is? ] find-parent ] prepend ; : <list-presentation> ( hook elt presenter -- gadget ) keep <presentation> - [ set-presentation-hook ] keep - [ text-theme ] keep ; + swap >>hook + text-theme ; inline : <list-items> ( list -- seq ) - dup list-presentation-hook - over list-presenter - rot control-value [ + [ list-presentation-hook ] + [ presenter>> ] + [ control-value ] + tri [ >r 2dup r> swap <list-presentation> ] map 2nip ; diff --git a/extra/ui/gadgets/menus/menus.factor b/extra/ui/gadgets/menus/menus.factor index 34051eaac0..153b4aeb6e 100644 --- a/extra/ui/gadgets/menus/menus.factor +++ b/extra/ui/gadgets/menus/menus.factor @@ -42,11 +42,11 @@ M: menu-glass layout* gadget-child prefer ; [ hand-clicked get find-world hide-glass ] 3append <roll-button> ; -: menu-theme ( gadget -- ) - dup light-gray solid-interior +: menu-theme ( gadget -- gadget ) + light-gray solid-interior faint-boundary ; : <commands-menu> ( hook target commands -- gadget ) [ [ >r 2dup r> <menu-item> gadget, ] each 2drop - ] make-filled-pile 5 <border> dup menu-theme ; + ] make-filled-pile 5 <border> menu-theme ; diff --git a/extra/ui/gadgets/panes/panes.factor b/extra/ui/gadgets/panes/panes.factor index 880fb4450e..86d95e8ad0 100755 --- a/extra/ui/gadgets/panes/panes.factor +++ b/extra/ui/gadgets/panes/panes.factor @@ -182,7 +182,7 @@ M: pane-stream make-span-stream foreground [ over set-label-color ] apply-style ; : apply-background-style ( style gadget -- style gadget ) - background [ dupd solid-interior ] apply-style ; + background [ solid-interior ] apply-style ; : specified-font ( style -- font ) [ font swap at "monospace" or ] keep @@ -207,15 +207,15 @@ M: pane-stream make-span-stream : apply-wrap-style ( style pane -- style pane ) wrap-margin [ - 2dup <paragraph> swap set-pane-prototype - <paragraph> over set-pane-current + 2dup <paragraph> >>prototype drop + <paragraph> >>current ] apply-style ; : apply-border-color-style ( style gadget -- style gadget ) - border-color [ dupd solid-boundary ] apply-style ; + border-color [ solid-boundary ] apply-style ; : apply-page-color-style ( style gadget -- style gadget ) - page-color [ dupd solid-interior ] apply-style ; + page-color [ solid-interior ] apply-style ; : apply-path-style ( style gadget -- style gadget ) presented-path [ <editable-slot> ] apply-style ; @@ -224,9 +224,7 @@ M: pane-stream make-span-stream border-width [ <border> ] apply-style ; : apply-printer-style ( style gadget -- style gadget ) - presented-printer [ - [ make-pane ] curry over set-editable-slot-printer - ] apply-style ; + presented-printer [ [ make-pane ] curry >>printer ] apply-style ; : style-pane ( style pane -- pane ) apply-border-width-style @@ -294,11 +292,8 @@ M: pack dispose drop ; M: paragraph dispose drop ; : gadget-write ( string gadget -- ) - over empty? [ - 2drop - ] [ - >r <label> dup text-theme r> add-gadget - ] if ; + over empty? + [ 2drop ] [ >r <label> text-theme r> add-gadget ] if ; M: pack stream-write gadget-write ; @@ -372,11 +367,11 @@ M: f sloppy-pick-up* : extend-selection ( pane -- ) hand-moved? [ - dup pane-selecting? [ + dup selecting?>> [ dup move-caret ] [ dup hand-clicked get child? [ - t over set-pane-selecting? + t >>selecting? dup hand-clicked set-global dup move-caret dup caret>mark @@ -386,10 +381,9 @@ M: f sloppy-pick-up* ] when drop ; : end-selection ( pane -- ) - f over set-pane-selecting? + f >>selecting? hand-moved? [ - dup com-copy-selection - request-focus + [ com-copy-selection ] [ request-focus ] bi ] [ relayout-1 ] if ; diff --git a/extra/ui/gadgets/scrollers/scrollers.factor b/extra/ui/gadgets/scrollers/scrollers.factor index e513853d27..e58fbc5925 100755 --- a/extra/ui/gadgets/scrollers/scrollers.factor +++ b/extra/ui/gadgets/scrollers/scrollers.factor @@ -46,7 +46,7 @@ scroller H{ y-model <y-slider> g-> set-scroller-y @right frame, viewport, ] with-gadget - ] keep t over set-gadget-root? dup faint-boundary ; + ] keep t >>root? faint-boundary ; : scroll ( value scroller -- ) [ diff --git a/extra/ui/gadgets/sliders/sliders.factor b/extra/ui/gadgets/sliders/sliders.factor index c781a9167d..eb22a5a823 100755 --- a/extra/ui/gadgets/sliders/sliders.factor +++ b/extra/ui/gadgets/sliders/sliders.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2005, 2007 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays ui.gestures ui.gadgets ui.gadgets.buttons +USING: accessors arrays ui.gestures ui.gadgets ui.gadgets.buttons ui.gadgets.frames ui.gadgets.grids math.order ui.gadgets.theme ui.render kernel math namespaces sequences vectors models math.vectors math.functions quotations colors ; @@ -65,14 +65,15 @@ thumb H{ { T{ drag } [ do-drag ] } } set-gestures -: thumb-theme ( thumb -- ) - plain-gradient over set-gadget-interior faint-boundary ; +: thumb-theme ( thumb -- thumb ) + plain-gradient >>interior + faint-boundary ; inline : <thumb> ( vector -- thumb ) thumb construct-gadget - t over set-gadget-root? - dup thumb-theme - [ set-gadget-orientation ] keep ; + swap >>orientation + t >>root? + thumb-theme ; : slide-by ( amount slider -- ) gadget-model move-by ; diff --git a/extra/ui/gadgets/status-bar/status-bar.factor b/extra/ui/gadgets/status-bar/status-bar.factor index b528d6739c..417826a680 100755 --- a/extra/ui/gadgets/status-bar/status-bar.factor +++ b/extra/ui/gadgets/status-bar/status-bar.factor @@ -1,14 +1,14 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: models sequences ui.gadgets.labels ui.gadgets.theme -ui.gadgets.tracks ui.gadgets.worlds ui.gadgets ui kernel -calendar ; +USING: accessors models sequences ui.gadgets.labels +ui.gadgets.theme ui.gadgets.tracks ui.gadgets.worlds ui.gadgets +ui kernel calendar ; IN: ui.gadgets.status-bar : <status-bar> ( model -- gadget ) 1/10 seconds <delay> [ "" like ] <filter> <label-control> - dup reverse-video-theme - t over set-gadget-root? ; + reverse-video-theme + t >>root? ; : open-status-window ( gadget title -- ) >r [ diff --git a/extra/ui/gadgets/theme/theme.factor b/extra/ui/gadgets/theme/theme.factor index f0884f9486..68bd3b201a 100644 --- a/extra/ui/gadgets/theme/theme.factor +++ b/extra/ui/gadgets/theme/theme.factor @@ -2,17 +2,17 @@ ! Copyright (C) 2006, 2007 Alex Chapman. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel sequences io.styles ui.gadgets ui.render -colors ; +colors accessors ; IN: ui.gadgets.theme -: solid-interior ( gadget color -- ) - <solid> swap set-gadget-interior ; +: solid-interior ( gadget color -- gadget ) + <solid> >>interior ; inline -: solid-boundary ( gadget color -- ) - <solid> swap set-gadget-boundary ; +: solid-boundary ( gadget color -- gadget ) + <solid> >>boundary ; inline -: faint-boundary ( gadget -- ) - gray solid-boundary ; +: faint-boundary ( gadget -- gadget ) + gray solid-boundary ; inline : selection-color ( -- color ) light-purple ; diff --git a/extra/ui/gadgets/worlds/worlds.factor b/extra/ui/gadgets/worlds/worlds.factor index 2895dd07cc..4d2f31cda5 100755 --- a/extra/ui/gadgets/worlds/worlds.factor +++ b/extra/ui/gadgets/worlds/worlds.factor @@ -1,8 +1,9 @@ -! Copyright (C) 2005, 2007 Slava Pestov. +! Copyright (C) 2005, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays assocs continuations kernel math models namespaces opengl sequences io combinators math.vectors -ui.gadgets ui.gestures ui.render ui.backend inspector ; +ui.gadgets ui.gestures ui.render ui.backend inspector +debugger ; IN: ui.gadgets.worlds TUPLE: world < identity-tuple @@ -78,7 +79,8 @@ TUPLE: world-error world ; SYMBOL: ui-error-hook -: ui-error ( error -- ) ui-error-hook get call ; +: ui-error ( error -- ) + ui-error-hook get [ call ] [ print-error ] if* ; [ rethrow ] ui-error-hook set-global diff --git a/extra/ui/tools/interactor/interactor-tests.factor b/extra/ui/tools/interactor/interactor-tests.factor index f8d5e33df9..37f43faa8b 100755 --- a/extra/ui/tools/interactor/interactor-tests.factor +++ b/extra/ui/tools/interactor/interactor-tests.factor @@ -1,7 +1,7 @@ IN: ui.tools.interactor.tests USING: ui.tools.interactor ui.gadgets.panes namespaces ui.gadgets.editors concurrency.promises threads listener -tools.test kernel calendar parser accessors ; +tools.test kernel calendar parser accessors calendar io ; \ <interactor> must-infer @@ -41,3 +41,47 @@ tools.test kernel calendar parser accessors ; [ ] [ 1000 sleep ] unit-test [ ] [ "interactor" get interactor-eof ] unit-test + +[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test + +: text "Hello world.\nThis is a test." ; + +[ ] [ text "interactor" get set-editor-string ] unit-test + +[ ] [ <promise> "promise" set ] unit-test + +[ ] [ + [ + "interactor" get register-self + "interactor" get contents "promise" get fulfill + ] in-thread +] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get evaluate-input ] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get interactor-eof ] unit-test + +[ t ] [ "promise" get 2 seconds ?promise-timeout text = ] unit-test + +[ ] [ <pane> <pane-stream> <interactor> "interactor" set ] unit-test + +[ ] [ text "interactor" get set-editor-string ] unit-test + +[ ] [ <promise> "promise" set ] unit-test + +[ ] [ + [ + "interactor" get register-self + "interactor" get stream-read1 "promise" get fulfill + ] in-thread +] unit-test + +[ ] [ 100 sleep ] unit-test + +[ ] [ "interactor" get evaluate-input ] unit-test + +[ CHAR: H ] [ "promise" get 2 seconds ?promise-timeout ] unit-test diff --git a/extra/ui/tools/interactor/interactor.factor b/extra/ui/tools/interactor/interactor.factor index 400169908b..fcd3f9ab22 100755 --- a/extra/ui/tools/interactor/interactor.factor +++ b/extra/ui/tools/interactor/interactor.factor @@ -2,11 +2,12 @@ ! 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 -concurrency.mailboxes ui.tools.workspace accessors sets ; +concurrency.mailboxes ui.tools.workspace accessors sets +destructors ; IN: ui.tools.interactor ! If waiting is t, we're waiting for user input, and invoking @@ -110,9 +111,11 @@ M: interactor model-changed } cleave ] [ drop f ] if ; +: interactor-read ( interactor -- lines ) + [ interactor-yield ] [ interactor-finish ] bi ; + M: interactor stream-readln - [ interactor-yield ] [ interactor-finish ] bi - dup [ first ] when ; + interactor-read dup [ first ] when ; : interactor-call ( quot interactor -- ) dup interactor-busy? [ @@ -124,19 +127,29 @@ M: interactor stream-read swap dup zero? [ 2drop "" ] [ - >r stream-readln dup length r> min head + >r interactor-read dup [ "\n" join ] when r> short head ] if ; M: interactor stream-read-partial stream-read ; +M: interactor stream-read1 + dup interactor-read { + { [ dup not ] [ 2drop f ] } + { [ dup empty? ] [ drop stream-read1 ] } + { [ dup first empty? ] [ 2drop CHAR: \n ] } + [ nip first first ] + } cond ; + +M: interactor dispose drop ; + : go-to-error ( interactor error -- ) [ line>> 1- ] [ column>> ] bi 2array over set-caret 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 ) @@ -144,7 +157,7 @@ M: interactor stream-read-partial drop parse-lines-interactive ] [ 2nip - dup parse-error? [ + dup lexer-error? [ dup error>> unexpected-eof? [ drop f ] when ] when ] recover ; diff --git a/extra/unicode/breaks/breaks.factor b/extra/unicode/breaks/breaks.factor index b70d79b872..fe19685b53 100755 --- a/extra/unicode/breaks/breaks.factor +++ b/extra/unicode/breaks/breaks.factor @@ -1,8 +1,7 @@ -USING: unicode.categories kernel math combinators splitting +USING: combinators.short-circuit unicode.categories kernel math combinators splitting sequences math.parser io.files io assocs arrays namespaces math.ranges unicode.normalize values io.encodings.ascii -unicode.syntax unicode.data compiler.units alien.syntax sets -combinators.lib ; +unicode.syntax unicode.data compiler.units alien.syntax sets ; IN: unicode.breaks C-ENUM: Any L V T Extend Control CR LF graphemes ; diff --git a/extra/unicode/collation/collation-tests.factor b/extra/unicode/collation/collation-tests.factor index 5de90d238d..d523a15ada 100755 --- a/extra/unicode/collation/collation-tests.factor +++ b/extra/unicode/collation/collation-tests.factor @@ -1,6 +1,6 @@ USING: io io.files splitting grouping unicode.collation sequences kernel io.encodings.utf8 math.parser math.order -tools.test assocs io.streams.null words combinators.lib ; +tools.test assocs io.streams.null words ; IN: unicode.collation.tests : parse-test ( -- strings ) @@ -17,7 +17,7 @@ IN: unicode.collation.tests : test-equality { primary= secondary= tertiary= quaternary= } - [ execute ] 2with each ; + [ execute ] with with each ; [ f f f f ] [ "hello" "hi" test-equality ] unit-test [ t f f f ] [ "hello" "h\u0000e9llo" test-equality ] unit-test diff --git a/extra/unicode/collation/collation.factor b/extra/unicode/collation/collation.factor index 216f80c79d..3e239430d4 100755 --- a/extra/unicode/collation/collation.factor +++ b/extra/unicode/collation/collation.factor @@ -1,7 +1,7 @@ -USING: sequences io.files io.encodings.ascii kernel values -splitting accessors math.parser ascii io assocs strings math -namespaces sorting combinators math.order arrays -unicode.normalize unicode.data combinators.lib locals +USING: combinators.short-circuit sequences io.files +io.encodings.ascii kernel values splitting accessors math.parser +ascii io assocs strings math namespaces sorting combinators +math.order arrays unicode.normalize unicode.data locals unicode.syntax macros sequences.deep words unicode.breaks quotations ; IN: unicode.collation @@ -86,7 +86,7 @@ ducet insert-helpers : add ( char -- ) dup blocked? [ 1string , ] [ dup possible-bases dup length - [ ?combine ] 2with contains? + [ ?combine ] with with contains? [ drop ] [ 1string , ] if ] if ; diff --git a/extra/unicode/data/data.factor b/extra/unicode/data/data.factor index 5fb769e499..f74e2e0473 100755 --- a/extra/unicode/data/data.factor +++ b/extra/unicode/data/data.factor @@ -1,8 +1,8 @@ -USING: assocs math kernel sequences io.files hashtables -quotations splitting grouping arrays math.parser hash2 math.order -byte-arrays words namespaces words compiler.units parser -io.encodings.ascii values interval-maps ascii sets -combinators.lib combinators locals math.ranges sorting ; +USING: combinators.short-circuit assocs math kernel sequences +io.files hashtables quotations splitting grouping arrays +math.parser hash2 math.order byte-arrays words namespaces words +compiler.units parser io.encodings.ascii values interval-maps +ascii sets combinators locals math.ranges sorting ; IN: unicode.data VALUE: simple-lower diff --git a/extra/unicode/normalize/normalize.factor b/extra/unicode/normalize/normalize.factor index 3b64cf577f..124840a7fb 100755 --- a/extra/unicode/normalize/normalize.factor +++ b/extra/unicode/normalize/normalize.factor @@ -1,5 +1,5 @@ USING: sequences namespaces unicode.data kernel math arrays -locals combinators.lib sorting.insertion combinators.lib ; +locals sorting.insertion ; IN: unicode.normalize ! Conjoining Jamo behavior diff --git a/extra/unicode/syntax/syntax.factor b/extra/unicode/syntax/syntax.factor index b5ba25db4e..2410779804 100755 --- a/extra/unicode/syntax/syntax.factor +++ b/extra/unicode/syntax/syntax.factor @@ -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 diff --git a/extra/urls/urls.factor b/extra/urls/urls.factor index 38511de8e8..4c45164815 100644 --- a/extra/urls/urls.factor +++ b/extra/urls/urls.factor @@ -1,22 +1,22 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel unicode.categories combinators sequences splitting -fry namespaces assocs arrays strings io.sockets -io.sockets.secure io.encodings.string io.encodings.utf8 -math math.parser accessors mirrors parser -prettyprint.backend hashtables present ; +USING: kernel unicode.categories combinators +combinators.short-circuit sequences splitting fry namespaces +assocs arrays strings io.sockets io.sockets.secure +io.encodings.string io.encodings.utf8 math math.parser accessors +mirrors parser strings.parser lexer prettyprint.backend +hashtables present ; IN: urls : url-quotable? ( ch -- ? ) #! 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 diff --git a/extra/vars/vars.factor b/extra/vars/vars.factor index 5942215a69..e3e13be3a9 100644 --- a/extra/vars/vars.factor +++ b/extra/vars/vars.factor @@ -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 diff --git a/extra/windows/com/syntax/syntax.factor b/extra/windows/com/syntax/syntax.factor index 80a4a040c4..e0ea65e8be 100755 --- a/extra/windows/com/syntax/syntax.factor +++ b/extra/windows/com/syntax/syntax.factor @@ -1,5 +1,5 @@ -USING: alien alien.c-types effects kernel windows.ole32 combinators.lib -parser splitting grouping sequences.lib sequences namespaces +USING: alien alien.c-types effects kernel windows.ole32 +parser lexer splitting grouping sequences.lib sequences namespaces assocs quotations shuffle accessors words macros alien.syntax fry arrays ; IN: windows.com.syntax diff --git a/extra/windows/com/wrapper/wrapper.factor b/extra/windows/com/wrapper/wrapper.factor index 6d6aa078e8..266439ad79 100755 --- a/extra/windows/com/wrapper/wrapper.factor +++ b/extra/windows/com/wrapper/wrapper.factor @@ -2,8 +2,8 @@ USING: alien alien.c-types windows.com.syntax windows.com.syntax.private windows.com continuations kernel sequences.lib namespaces windows.ole32 libc vocabs assocs accessors arrays sequences quotations combinators -math combinators.lib words compiler.units destructors fry -math.parser ; +math words compiler.units destructors fry +math.parser combinators.lib ; IN: windows.com.wrapper TUPLE: com-wrapper vtbls disposed ; @@ -84,7 +84,7 @@ unless swap append ; : compile-alien-callback ( word return parameters abi quot -- alien ) - [ alien-callback ] 4 ncurry + '[ , , , , alien-callback ] [ [ (( -- alien )) define-declared ] pick slip ] with-compilation-unit execute ; diff --git a/extra/windows/kernel32/kernel32.factor b/extra/windows/kernel32/kernel32.factor index 0ac41a18ea..108e02cb46 100755 --- a/extra/windows/kernel32/kernel32.factor +++ b/extra/windows/kernel32/kernel32.factor @@ -1182,7 +1182,8 @@ FUNCTION: BOOL IsProcessorFeaturePresent ( DWORD ProcessorFeature ) ; ! FUNCTION: LeaveCriticalSection ! FUNCTION: LoadLibraryA ! FUNCTION: LoadLibraryExA -! FUNCTION: LoadLibraryExW +FUNCTION: HMODULE LoadLibraryExW ( LPCTSTR lpFile, HANDLE hFile, DWORD flags ) ; +ALIAS: LoadLibraryEx LoadLibraryExW ! FUNCTION: LoadLibraryW ! FUNCTION: LoadModule ! FUNCTION: LoadResource diff --git a/extra/windows/ole32/ole32.factor b/extra/windows/ole32/ole32.factor old mode 100644 new mode 100755 index a71a569f16..7daba37063 --- a/extra/windows/ole32/ole32.factor +++ b/extra/windows/ole32/ole32.factor @@ -1,5 +1,5 @@ USING: alien alien.syntax alien.c-types alien.strings math -kernel sequences windows windows.types combinators.lib +kernel sequences windows windows.types math.order ; IN: windows.ole32 @@ -132,5 +132,5 @@ FUNCTION: void ReleaseStgMedium ( LPSTGMEDIUM pmedium ) ; utf16n string>alien "GUID" <c-object> [ CLSIDFromString ole32-error ] keep ; : guid>string ( guid -- string ) GUID-STRING-LENGTH 1+ [ "ushort" <c-array> ] keep - [ StringFromGUID2 drop ] { 2 } multikeep utf16n alien>string ; + [ StringFromGUID2 drop ] 2keep drop utf16n alien>string ; diff --git a/extra/xml/generator/generator.factor b/extra/xml/generator/generator.factor index 44bd1934f8..bf4bd618b7 100644 --- a/extra/xml/generator/generator.factor +++ b/extra/xml/generator/generator.factor @@ -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: >> diff --git a/extra/xml/utilities/utilities-tests.factor b/extra/xml/utilities/utilities-tests.factor new file mode 100644 index 0000000000..c150c7133d --- /dev/null +++ b/extra/xml/utilities/utilities-tests.factor @@ -0,0 +1,8 @@ +IN: xml.utilities.tests +USING: xml xml.utilities tools.test ; + +[ "bar" ] [ "<foo>bar</foo>" string>xml children>string ] unit-test + +[ "" ] [ "<foo></foo>" string>xml children>string ] unit-test + +[ "" ] [ "<foo/>" string>xml children>string ] unit-test diff --git a/extra/xml/utilities/utilities.factor b/extra/xml/utilities/utilities.factor index 87a0242412..e1875bd0c1 100755 --- a/extra/xml/utilities/utilities.factor +++ b/extra/xml/utilities/utilities.factor @@ -1,8 +1,8 @@ ! 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 -splitting vectors sequences.deep ; +quotations strings parser lexer arrays xml.data xml.writer debugger +splitting vectors sequences.deep combinators ; IN: xml.utilities ! * System for words specialized on tag names @@ -48,10 +48,11 @@ M: process-missing error. standard-prolog { } rot { } <xml> ; : children>string ( tag -- string ) - tag-children - dup [ string? ] all? - [ "XML tag unexpectedly contains non-text children" throw ] unless - concat ; + tag-children { + { [ dup empty? ] [ drop "" ] } + { [ dup [ string? not ] contains? ] [ "XML tag unexpectedly contains non-text children" throw ] } + [ concat ] + } cond ; : children-tags ( tag -- sequence ) tag-children [ tag? ] filter ; diff --git a/extra/xmode/loader/syntax/syntax.factor b/extra/xmode/loader/syntax/syntax.factor index b3adf5cb60..4c95a45832 100644 --- a/extra/xmode/loader/syntax/syntax.factor +++ b/extra/xmode/loader/syntax/syntax.factor @@ -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? diff --git a/extra/xmode/marker/marker.factor b/extra/xmode/marker/marker.factor index 7d82842327..911397cc20 100755 --- a/extra/xmode/marker/marker.factor +++ b/extra/xmode/marker/marker.factor @@ -2,7 +2,8 @@ IN: xmode.marker USING: kernel namespaces xmode.rules xmode.tokens xmode.marker.state xmode.marker.context xmode.utilities xmode.catalog sequences math assocs combinators combinators.lib -strings regexp splitting parser-combinators ascii unicode.case ; +strings regexp splitting parser-combinators ascii unicode.case +combinators.short-circuit ; ! Based on org.gjt.sp.jedit.syntax.TokenMarker diff --git a/extra/xmode/utilities/utilities.factor b/extra/xmode/utilities/utilities.factor index 2e1d0a2872..d6f9c42799 100644 --- a/extra/xmode/utilities/utilities.factor +++ b/extra/xmode/utilities/utilities.factor @@ -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