(defpackage :igo.unknown
(:use :common-lisp :igo.char-category)
(:nicknames :unk)
(:shadow load
search)
(:export load
unknown
search))
(in-package :igo.unknown)
;;;;;;;;;;
;;; struct
(defstruct (unknown (:conc-name ""))
(categorys nil :type category-set)
(space-id 0 :type fixnum))
;;;;;;;;;;;;;;;;;;;;;
;;; external function
(defun load (root-dir)
(let* ((cts (igo.char-category:load root-dir))
(unk (make-unknown :categorys cts)))
(setf (space-id unk)
(category-trie-id (category (char-code #\Space) cts)))
unk))
(defun search (cs unk wdic result)
(declare #.igo::*optimize-fastest*)
(prog* ((start (code-stream:position cs))
(code (code-stream:read cs))
(categorys (categorys unk))
(ct (category code categorys)))
(when (and result (not (category-invoke? ct))) ; invoke
(go :end))
(let* ((trie-id (category-trie-id ct))
(space? (= trie-id (space-id unk)))
(limit (category-length ct)))
(loop FOR len FROM 1 TO limit DO ; length
(setf result
(dic:search-from-trie-id trie-id start (code-stream:position cs) space? result wdic))
(when (or (code-stream:end? cs)
(not (compatible? code (code-stream:read cs) categorys)))
(go :end)))
(when (and (category-group? ct)) ; group
(loop (when (code-stream:end? cs)
(return))
(unless (compatible? code (code-stream:read cs) categorys)
(code-stream:unread cs)
(return)))
(setf result
(dic:search-from-trie-id trie-id start (code-stream:position cs) space? result wdic))))
:end
(setf (code-stream:position cs) start))
result)