factor/basis/xmode/catalog/catalog.factor

120 lines
3.1 KiB
Factor
Raw Normal View History

2007-12-10 02:20:36 -05:00
USING: xmode.loader xmode.utilities xmode.rules namespaces
strings splitting assocs sequences kernel io.files xml memoize
words globs combinators io.encodings.utf8 sorting accessors ;
IN: xmode.catalog
TUPLE: mode file file-name-glob first-line-glob ;
2008-06-15 04:25:41 -04:00
<TAGS: parse-mode-tag ( modes tag -- )
TAG: MODE
2008-12-17 20:17:37 -05:00
"NAME" over at [
mode new {
{ "FILE" f (>>file) }
{ "FILE_NAME_GLOB" f (>>file-name-glob) }
{ "FIRST_LINE_GLOB" f (>>first-line-glob) }
} init-from-tag
] dip
rot set-at ;
TAGS>
: parse-modes-tag ( tag -- modes )
H{ } clone [
2008-01-09 17:36:30 -05:00
swap child-tags [ parse-mode-tag ] with each
] keep ;
2008-05-26 01:47:27 -04:00
MEMO: modes ( -- modes )
2008-09-04 21:11:28 -04:00
"resource:basis/xmode/modes/catalog"
file>xml parse-modes-tag ;
2008-05-26 01:47:27 -04:00
MEMO: mode-names ( -- modes )
modes keys natural-sort ;
: reset-catalog ( -- )
2008-05-26 01:47:27 -04:00
\ modes reset-memoized ;
2007-12-10 02:20:36 -05:00
MEMO: (load-mode) ( name -- rule-sets )
2008-04-15 23:03:40 -04:00
modes at [
file>>
2008-09-04 21:11:28 -04:00
"resource:basis/xmode/modes/" prepend
utf8 <file-reader> parse-mode
2008-04-15 23:03:40 -04:00
] [
"text" (load-mode)
] if* ;
2007-12-10 02:20:36 -05:00
SYMBOL: rule-sets
2008-01-18 02:39:09 -05:00
: no-such-rule-set ( name -- * )
"No such rule set: " prepend throw ;
2008-01-18 02:39:09 -05:00
2007-12-10 03:35:40 -05:00
: get-rule-set ( name -- rule-sets rules )
2008-01-18 02:39:09 -05:00
dup "::" split1 [ swap (load-mode) ] [ rule-sets get ] if*
dup -roll at* [ nip ] [ drop no-such-rule-set ] if ;
2007-12-10 02:20:36 -05:00
: resolve-delegate ( rule -- )
2008-08-30 21:53:59 -04:00
dup delegate>> dup string?
[ get-rule-set nip swap (>>delegate) ] [ 2drop ] if ;
2007-12-10 02:20:36 -05:00
: each-rule ( rule-set quot -- )
2008-12-17 20:17:37 -05:00
[ rules>> values concat ] dip each ; inline
2007-12-10 02:20:36 -05:00
: resolve-delegates ( ruleset -- )
[ resolve-delegate ] each-rule ;
: ?update ( keyword-map/f keyword-map -- keyword-map )
over [ dupd update ] [ nip clone ] if ;
: import-keywords ( parent child -- )
2008-12-17 20:17:37 -05:00
over [ [ keywords>> ] bi@ ?update ] dip (>>keywords) ;
2007-12-10 02:20:36 -05:00
: import-rules ( parent child -- )
swap [ add-rule ] curry each-rule ;
: resolve-imports ( ruleset -- )
dup imports>> [
2008-01-18 02:39:09 -05:00
get-rule-set swap rule-sets [
dup resolve-delegates
2dup import-keywords
import-rules
] with-variable
2008-01-09 17:36:30 -05:00
] with each ;
2007-12-10 02:20:36 -05:00
ERROR: mutually-recursive-rulesets ruleset ;
2007-12-10 02:20:36 -05:00
: finalize-rule-set ( ruleset -- )
dup finalized?>> {
2007-12-10 03:35:40 -05:00
{ f [
2008-08-30 21:37:55 -04:00
{
[ 1 >>finalized? drop ]
[ resolve-imports ]
[ resolve-delegates ]
[ t >>finalized? drop ]
} cleave
2007-12-10 03:35:40 -05:00
] }
{ t [ drop ] }
{ 1 [ mutually-recursive-rulesets ] }
2007-12-10 03:35:40 -05:00
} case ;
: finalize-mode ( rulesets -- )
rule-sets [
2007-12-10 02:20:36 -05:00
dup [ nip finalize-rule-set ] assoc-each
] with-variable ;
2007-12-10 03:35:40 -05:00
: load-mode ( name -- rule-sets )
(load-mode) dup finalize-mode ;
: reset-modes ( -- )
2008-02-05 19:52:16 -05:00
\ (load-mode) reset-memoized ;
: ?glob-matches ( string glob/f -- ? )
dup [ glob-matches? ] [ 2drop f ] if ;
: suitable-mode? ( file-name first-line mode -- ? )
tuck first-line-glob>> ?glob-matches
[ 2drop t ] [ file-name-glob>> ?glob-matches ] if ;
: find-mode ( file-name first-line -- mode )
modes
2008-12-17 20:17:37 -05:00
[ nip [ 2dup ] dip suitable-mode? ] assoc-find
2drop [ 2drop ] dip [ "text" ] unless* ;