Mercurial > hg > xemacs-beta
comparison lisp/mule/mule-ccl.el @ 444:576fb035e263 r21-2-37
Import from CVS: tag r21-2-37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:36:19 +0200 |
parents | abe6d1db359e |
children | 98528da0b7fc |
comparison
equal
deleted
inserted
replaced
443:a8296e22da4e | 444:576fb035e263 |
---|---|
20 ;; You should have received a copy of the GNU General Public License | 20 ;; You should have received a copy of the GNU General Public License |
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 21 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
23 ;; Boston, MA 02111-1307, USA. | 23 ;; Boston, MA 02111-1307, USA. |
24 | 24 |
25 ;; Synched up with: FSF 20.2 | 25 ;; Synched up with: FSF 21.0.90 |
26 | 26 |
27 ;;; Commentary: | 27 ;;; Commentary: |
28 | 28 |
29 ;; CCL (Code Conversion Language) is a simple programming language to | 29 ;; CCL (Code Conversion Language) is a simple programming language to |
30 ;; be used for various kind of code conversion. CCL program is | 30 ;; be used for various kind of code conversion. CCL program is |
37 ;; However, since CCL is designed as a powerful programming language, | 37 ;; However, since CCL is designed as a powerful programming language, |
38 ;; it can be used for more generic calculation. For instance, | 38 ;; it can be used for more generic calculation. For instance, |
39 ;; combination of three or more arithmetic operations can be | 39 ;; combination of three or more arithmetic operations can be |
40 ;; calculated faster than Emacs Lisp. | 40 ;; calculated faster than Emacs Lisp. |
41 ;; | 41 ;; |
42 ;; Here's the syntax of CCL program in BNF notation. | 42 ;; Syntax and semantics of CCL program is described in the |
43 ;; | 43 ;; documentation of `define-ccl-program'. |
44 ;; CCL_PROGRAM := | |
45 ;; (BUFFER_MAGNIFICATION | |
46 ;; CCL_MAIN_BLOCK | |
47 ;; [ CCL_EOF_BLOCK ]) | |
48 ;; | |
49 ;; BUFFER_MAGNIFICATION := integer | |
50 ;; CCL_MAIN_BLOCK := CCL_BLOCK | |
51 ;; CCL_EOF_BLOCK := CCL_BLOCK | |
52 ;; | |
53 ;; CCL_BLOCK := | |
54 ;; STATEMENT | (STATEMENT [STATEMENT ...]) | |
55 ;; STATEMENT := | |
56 ;; SET | IF | BRANCH | LOOP | REPEAT | BREAK | READ | WRITE | CALL | |
57 ;; | |
58 ;; SET := | |
59 ;; (REG = EXPRESSION) | |
60 ;; | (REG ASSIGNMENT_OPERATOR EXPRESSION) | |
61 ;; | integer | |
62 ;; | |
63 ;; EXPRESSION := ARG | (EXPRESSION OPERATOR ARG) | |
64 ;; | |
65 ;; IF := (if EXPRESSION CCL_BLOCK CCL_BLOCK) | |
66 ;; BRANCH := (branch EXPRESSION CCL_BLOCK [CCL_BLOCK ...]) | |
67 ;; LOOP := (loop STATEMENT [STATEMENT ...]) | |
68 ;; BREAK := (break) | |
69 ;; REPEAT := | |
70 ;; (repeat) | |
71 ;; | (write-repeat [REG | integer | string]) | |
72 ;; | (write-read-repeat REG [integer | ARRAY]) | |
73 ;; READ := | |
74 ;; (read REG ...) | |
75 ;; | (read-if (REG OPERATOR ARG) CCL_BLOCK CCL_BLOCK) | |
76 ;; | (read-branch REG CCL_BLOCK [CCL_BLOCK ...]) | |
77 ;; | (read-multibyte-character REG {charset} REG {code-point}) | |
78 ;; WRITE := | |
79 ;; (write REG ...) | |
80 ;; | (write EXPRESSION) | |
81 ;; | (write integer) | (write string) | (write REG ARRAY) | |
82 ;; | string | |
83 ;; | (write-multibyte-character REG(charset) REG(codepoint)) | |
84 ;; CALL := (call ccl-program-name) | |
85 ;; END := (end) | |
86 ;; | |
87 ;; REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | |
88 ;; ARG := REG | integer | |
89 ;; OPERATOR := | |
90 ;; + | - | * | / | % | & | '|' | ^ | << | >> | <8 | >8 | // | |
91 ;; | < | > | == | <= | >= | != | de-sjis | en-sjis | |
92 ;; ASSIGNMENT_OPERATOR := | |
93 ;; += | -= | *= | /= | %= | &= | '|=' | ^= | <<= | >>= | |
94 ;; ARRAY := '[' integer ... ']' | |
95 | 44 |
96 ;;; Code: | 45 ;;; Code: |
97 | 46 |
98 (defconst ccl-command-table | 47 (defconst ccl-command-table |
99 [if branch loop break repeat write-repeat write-read-repeat | 48 [if branch loop break repeat write-repeat write-read-repeat |
100 read read-if read-branch write call end | 49 read read-if read-branch write call end |
101 read-multibyte-character write-multibyte-character] | 50 read-multibyte-character write-multibyte-character |
51 translate-character | |
52 iterate-multiple-map map-multiple map-single] | |
102 "Vector of CCL commands (symbols).") | 53 "Vector of CCL commands (symbols).") |
103 | 54 |
104 ;; Put a property to each symbol of CCL commands for the compiler. | 55 ;; Put a property to each symbol of CCL commands for the compiler. |
105 (let (op (i 0) (len (length ccl-command-table))) | 56 (let (op (i 0) (len (length ccl-command-table))) |
106 (while (< i len) | 57 (while (< i len) |
226 "The current index for `ccl-program-vector'.") | 177 "The current index for `ccl-program-vector'.") |
227 | 178 |
228 ;; Embed integer DATA in `ccl-program-vector' at `ccl-current-ic' and | 179 ;; Embed integer DATA in `ccl-program-vector' at `ccl-current-ic' and |
229 ;; increment it. If IC is specified, embed DATA at IC. | 180 ;; increment it. If IC is specified, embed DATA at IC. |
230 (defun ccl-embed-data (data &optional ic) | 181 (defun ccl-embed-data (data &optional ic) |
231 (let ((val (if (characterp data) (char-int data) data))) | 182 (if (characterp data) |
232 (if ic | 183 (setq data (char-int data))) |
233 (aset ccl-program-vector ic val) | 184 (if ic |
234 (aset ccl-program-vector ccl-current-ic val) | 185 (aset ccl-program-vector ic data) |
235 (setq ccl-current-ic (1+ ccl-current-ic))))) | 186 (let ((len (length ccl-program-vector))) |
187 (if (>= ccl-current-ic len) | |
188 (let ((new (make-vector (* len 2) nil))) | |
189 (while (> len 0) | |
190 (setq len (1- len)) | |
191 (aset new len (aref ccl-program-vector len))) | |
192 (setq ccl-program-vector new)))) | |
193 (aset ccl-program-vector ccl-current-ic data) | |
194 (setq ccl-current-ic (1+ ccl-current-ic)))) | |
195 | |
196 ;; Embed pair of SYMBOL and PROP where (get SYMBOL PROP) should give | |
197 ;; proper index number for SYMBOL. PROP should be | |
198 ;; `translation-table-id', `code-conversion-map-id', or | |
199 ;; `ccl-program-idx'. | |
200 (defun ccl-embed-symbol (symbol prop) | |
201 (ccl-embed-data (cons symbol prop))) | |
236 | 202 |
237 ;; Embed string STR of length LEN in `ccl-program-vector' at | 203 ;; Embed string STR of length LEN in `ccl-program-vector' at |
238 ;; `ccl-current-ic'. | 204 ;; `ccl-current-ic'. |
239 (defun ccl-embed-string (len str) | 205 (defun ccl-embed-string (len str) |
240 (let ((i 0)) | 206 (let ((i 0)) |
278 (if (symbolp reg) (get reg 'ccl-register-number) reg) 5) | 244 (if (symbolp reg) (get reg 'ccl-register-number) reg) 5) |
279 (if reg2 | 245 (if reg2 |
280 (logior (ash (get reg2 'ccl-register-number) 8) | 246 (logior (ash (get reg2 'ccl-register-number) 8) |
281 (ash data 11)) | 247 (ash data 11)) |
282 (ash data 8))))) | 248 (ash data 8))))) |
283 (aset ccl-program-vector ccl-current-ic code) | 249 (ccl-embed-data code))) |
284 (setq ccl-current-ic (1+ ccl-current-ic)))) | |
285 | 250 |
286 ;; extended ccl command format | 251 ;; extended ccl command format |
287 ;; |- 14-bit -|- 3-bit --|- 3-bit --|- 3-bit --|- 5-bit -| | 252 ;; |- 14-bit -|- 3-bit --|- 3-bit --|- 3-bit --|- 5-bit -| |
288 ;; |- EX-OP --|-- REG3 --|-- REG2 --|-- REG ---|-- OP ---| | 253 ;; |- EX-OP --|-- REG3 --|-- REG2 --|-- REG ---|-- OP ---| |
289 (defun ccl-embed-extended-command (ex-op reg reg2 reg3) | 254 (defun ccl-embed-extended-command (ex-op reg reg2 reg3) |
295 | 260 |
296 ;; Just advance `ccl-current-ic' by INC. | 261 ;; Just advance `ccl-current-ic' by INC. |
297 (defun ccl-increment-ic (inc) | 262 (defun ccl-increment-ic (inc) |
298 (setq ccl-current-ic (+ ccl-current-ic inc))) | 263 (setq ccl-current-ic (+ ccl-current-ic inc))) |
299 | 264 |
300 ;;;###autoload | |
301 (defun ccl-program-p (obj) | |
302 "Return t if OBJECT is a valid CCL compiled code." | |
303 (and (vectorp obj) | |
304 (let ((i 0) (len (length obj)) (flag t)) | |
305 (if (> len 1) | |
306 (progn | |
307 (while (and flag (< i len)) | |
308 (setq flag (integerp (aref obj i))) | |
309 (setq i (1+ i))) | |
310 flag))))) | |
311 | |
312 ;; If non-nil, index of the start of the current loop. | 265 ;; If non-nil, index of the start of the current loop. |
313 (defvar ccl-loop-head nil) | 266 (defvar ccl-loop-head nil) |
314 ;; If non-nil, list of absolute addresses of the breaking points of | 267 ;; If non-nil, list of absolute addresses of the breaking points of |
315 ;; the current loop. | 268 ;; the current loop. |
316 (defvar ccl-breaks nil) | 269 (defvar ccl-breaks nil) |
317 | 270 |
318 ;;;###autoload | 271 ;;;###autoload |
319 (defun ccl-compile (ccl-program) | 272 (defun ccl-compile (ccl-program) |
320 "Return a compiled code of CCL-PROGRAM as a vector of integer." | 273 "Return a compiled code of CCL-PROGRAM as a vector of integer." |
321 (if (or (null (consp ccl-program)) | 274 (if (or (null (consp ccl-program)) |
322 (null (integer-or-char-p (car ccl-program))) | 275 (null (integerp (car ccl-program))) |
323 (null (listp (car (cdr ccl-program))))) | 276 (null (listp (car (cdr ccl-program))))) |
324 (error "CCL: Invalid CCL program: %s" ccl-program)) | 277 (error "CCL: Invalid CCL program: %s" ccl-program)) |
325 (if (null (vectorp ccl-program-vector)) | 278 (if (null (vectorp ccl-program-vector)) |
326 (setq ccl-program-vector (make-vector 8192 0))) | 279 (setq ccl-program-vector (make-vector 8192 0))) |
327 (setq ccl-loop-head nil ccl-breaks nil) | 280 (setq ccl-loop-head nil ccl-breaks nil) |
477 ;; the first term as `(r7 = (EXPR2 OP2 ARG)).' | 430 ;; the first term as `(r7 = (EXPR2 OP2 ARG)).' |
478 (ccl-compile-expression 'r7 left) | 431 (ccl-compile-expression 'r7 left) |
479 (setq left 'r7))) | 432 (setq left 'r7))) |
480 | 433 |
481 ;; Now EXPR has the form (LEFT OP RIGHT). | 434 ;; Now EXPR has the form (LEFT OP RIGHT). |
482 (if (eq rrr left) | 435 (if (and (eq rrr left) |
436 (< op (length ccl-assign-arith-table))) | |
483 ;; Compile this SET statement as `(RRR OP= RIGHT)'. | 437 ;; Compile this SET statement as `(RRR OP= RIGHT)'. |
484 (if (integer-or-char-p right) | 438 (if (integer-or-char-p right) |
485 (progn | 439 (progn |
486 (ccl-embed-code 'set-assign-expr-const rrr (ash op 3) 'r0) | 440 (ccl-embed-code 'set-assign-expr-const rrr (ash op 3) 'r0) |
487 (ccl-embed-data right)) | 441 (ccl-embed-data right)) |
499 (logior (ash op 3) (get right 'ccl-register-number)) | 453 (logior (ash op 3) (get right 'ccl-register-number)) |
500 left))))) | 454 left))))) |
501 | 455 |
502 ;; Compile WRITE statement with string argument. | 456 ;; Compile WRITE statement with string argument. |
503 (defun ccl-compile-write-string (str) | 457 (defun ccl-compile-write-string (str) |
458 (setq str (encode-coding-string str 'binary)) | |
504 (let ((len (length str))) | 459 (let ((len (length str))) |
505 (ccl-embed-code 'write-const-string 1 len) | 460 (ccl-embed-code 'write-const-string 1 len) |
506 (ccl-embed-string len str)) | 461 (ccl-embed-string len str)) |
507 nil) | 462 nil) |
508 | 463 |
710 (let ((arg (nth 1 cmd))) | 665 (let ((arg (nth 1 cmd))) |
711 (cond ((integer-or-char-p arg) | 666 (cond ((integer-or-char-p arg) |
712 (ccl-embed-code 'write-const-jump 0 ccl-loop-head) | 667 (ccl-embed-code 'write-const-jump 0 ccl-loop-head) |
713 (ccl-embed-data arg)) | 668 (ccl-embed-data arg)) |
714 ((stringp arg) | 669 ((stringp arg) |
670 (setq arg (encode-coding-string arg 'binary)) | |
715 (let ((len (length arg)) | 671 (let ((len (length arg)) |
716 (i 0)) | 672 (i 0)) |
717 (ccl-embed-code 'write-string-jump 0 ccl-loop-head) | 673 (ccl-embed-code 'write-string-jump 0 ccl-loop-head) |
718 (ccl-embed-data len) | 674 (ccl-embed-data len) |
719 (ccl-embed-string len arg))) | 675 (ccl-embed-string len arg))) |
823 (defun ccl-compile-call (cmd) | 779 (defun ccl-compile-call (cmd) |
824 (if (/= (length cmd) 2) | 780 (if (/= (length cmd) 2) |
825 (error "CCL: Invalid number of arguments: %s" cmd)) | 781 (error "CCL: Invalid number of arguments: %s" cmd)) |
826 (if (not (symbolp (nth 1 cmd))) | 782 (if (not (symbolp (nth 1 cmd))) |
827 (error "CCL: Subroutine should be a symbol: %s" cmd)) | 783 (error "CCL: Subroutine should be a symbol: %s" cmd)) |
828 (let* ((name (nth 1 cmd)) | 784 (ccl-embed-code 'call 1 0) |
829 (idx (get name 'ccl-program-idx))) | 785 (ccl-embed-symbol (nth 1 cmd) 'ccl-program-idx) |
830 (if (not idx) | |
831 (error "CCL: Unknown subroutine name: %s" name)) | |
832 (ccl-embed-code 'call 0 idx)) | |
833 nil) | 786 nil) |
834 | 787 |
835 ;; Compile END statement. | 788 ;; Compile END statement. |
836 (defun ccl-compile-end (cmd) | 789 (defun ccl-compile-end (cmd) |
837 (if (/= (length cmd) 1) | 790 (if (/= (length cmd) 1) |
860 (ccl-check-register RRR cmd) | 813 (ccl-check-register RRR cmd) |
861 (ccl-embed-extended-command 'write-multibyte-character rrr RRR 0)) | 814 (ccl-embed-extended-command 'write-multibyte-character rrr RRR 0)) |
862 nil) | 815 nil) |
863 | 816 |
864 ;; Compile translate-character | 817 ;; Compile translate-character |
865 ;; (defun ccl-compile-translate-character (cmd) | 818 (defun ccl-compile-translate-character (cmd) |
866 ;; (if (/= (length cmd) 4) | 819 (if (/= (length cmd) 4) |
867 ;; (error "CCL: Invalid number of arguments: %s" cmd)) | 820 (error "CCL: Invalid number of arguments: %s" cmd)) |
868 ;; (let ((Rrr (nth 1 cmd)) | 821 (let ((Rrr (nth 1 cmd)) |
869 ;; (RRR (nth 2 cmd)) | 822 (RRR (nth 2 cmd)) |
870 ;; (rrr (nth 3 cmd))) | 823 (rrr (nth 3 cmd))) |
871 ;; (ccl-check-register rrr cmd) | 824 (ccl-check-register rrr cmd) |
872 ;; (ccl-check-register RRR cmd) | 825 (ccl-check-register RRR cmd) |
873 ;; (cond ((and (symbolp Rrr) (not (get Rrr 'ccl-register-number))) | 826 (cond ((and (symbolp Rrr) (not (get Rrr 'ccl-register-number))) |
874 ;; (if (not (get Rrr 'translation-table)) | 827 (ccl-embed-extended-command 'translate-character-const-tbl |
875 ;; (error "CCL: Invalid translation table %s in %s" Rrr cmd)) | 828 rrr RRR 0) |
876 ;; (ccl-embed-extended-command 'translate-character-const-tbl | 829 (ccl-embed-symbol Rrr 'translation-table-id)) |
877 ;; rrr RRR 0) | 830 (t |
878 ;; (ccl-embed-data Rrr)) | 831 (ccl-check-register Rrr cmd) |
879 ;; (t | 832 (ccl-embed-extended-command 'translate-character rrr RRR Rrr)))) |
880 ;; (ccl-check-register Rrr cmd) | 833 nil) |
881 ;; (ccl-embed-extended-command 'translate-character rrr RRR Rrr)))) | 834 |
882 ;; nil) | 835 (defun ccl-compile-iterate-multiple-map (cmd) |
883 | 836 (ccl-compile-multiple-map-function 'iterate-multiple-map cmd) |
884 ;; (defun ccl-compile-iterate-multiple-map (cmd) | 837 nil) |
885 ;; (ccl-compile-multiple-map-function 'iterate-multiple-map cmd) | 838 |
886 ;; nil) | 839 (defun ccl-compile-map-multiple (cmd) |
887 | 840 (if (/= (length cmd) 4) |
888 ;; (defun ccl-compile-map-multiple (cmd) | 841 (error "CCL: Invalid number of arguments: %s" cmd)) |
889 ;; (if (/= (length cmd) 4) | 842 (let (func arg) |
890 ;; (error "CCL: Invalid number of arguments: %s" cmd)) | 843 (setq func |
891 ;; (let ((func '(lambda (arg mp) | 844 (lambda (arg mp) |
892 ;; (let ((len 0) result add) | 845 (let ((len 0) result add) |
893 ;; (while arg | 846 (while arg |
894 ;; (if (consp (car arg)) | 847 (if (consp (car arg)) |
895 ;; (setq add (funcall func (car arg) t) | 848 (setq add (funcall func (car arg) t) |
896 ;; result (append result add) | 849 result (append result add) |
897 ;; add (+ (-(car add)) 1)) | 850 add (+ (- (car add)) 1)) |
898 ;; (setq result | 851 (setq result |
899 ;; (append result | 852 (append result |
900 ;; (list (car arg))) | 853 (list (car arg))) |
901 ;; add 1)) | 854 add 1)) |
902 ;; (setq arg (cdr arg) | 855 (setq arg (cdr arg) |
903 ;; len (+ len add))) | 856 len (+ len add))) |
904 ;; (if mp | 857 (if mp |
905 ;; (cons (- len) result) | 858 (cons (- len) result) |
906 ;; result)))) | 859 result)))) |
907 ;; arg) | 860 (setq arg (append (list (nth 0 cmd) (nth 1 cmd) (nth 2 cmd)) |
908 ;; (setq arg (append (list (nth 0 cmd) (nth 1 cmd) (nth 2 cmd)) | 861 (funcall func (nth 3 cmd) nil))) |
909 ;; (funcall func (nth 3 cmd) nil))) | 862 (ccl-compile-multiple-map-function 'map-multiple arg)) |
910 ;; (ccl-compile-multiple-map-function 'map-multiple arg)) | 863 nil) |
911 ;; nil) | 864 |
912 | 865 (defun ccl-compile-map-single (cmd) |
913 ;; (defun ccl-compile-map-single (cmd) | 866 (if (/= (length cmd) 4) |
914 ;; (if (/= (length cmd) 4) | 867 (error "CCL: Invalid number of arguments: %s" cmd)) |
915 ;; (error "CCL: Invalid number of arguments: %s" cmd)) | 868 (let ((RRR (nth 1 cmd)) |
916 ;; (let ((RRR (nth 1 cmd)) | 869 (rrr (nth 2 cmd)) |
917 ;; (rrr (nth 2 cmd)) | 870 (map (nth 3 cmd)) |
918 ;; (map (nth 3 cmd)) | 871 id) |
919 ;; id) | 872 (ccl-check-register rrr cmd) |
920 ;; (ccl-check-register rrr cmd) | 873 (ccl-check-register RRR cmd) |
921 ;; (ccl-check-register RRR cmd) | 874 (ccl-embed-extended-command 'map-single rrr RRR 0) |
922 ;; (ccl-embed-extended-command 'map-single rrr RRR 0) | 875 (cond ((symbolp map) |
923 ;; (cond ((symbolp map) | 876 (if (get map 'code-conversion-map) |
924 ;; (if (get map 'code-conversion-map) | 877 (ccl-embed-symbol map 'code-conversion-map-id) |
925 ;; (ccl-embed-data map) | 878 (error "CCL: Invalid map: %s" map))) |
926 ;; (error "CCL: Invalid map: %s" map))) | 879 (t |
927 ;; (t | 880 (error "CCL: Invalid type of arguments: %s" cmd)))) |
928 ;; (error "CCL: Invalid type of arguments: %s" cmd)))) | 881 nil) |
929 ;; nil) | 882 |
930 | 883 (defun ccl-compile-multiple-map-function (command cmd) |
931 ;; (defun ccl-compile-multiple-map-function (command cmd) | 884 (if (< (length cmd) 4) |
932 ;; (if (< (length cmd) 4) | 885 (error "CCL: Invalid number of arguments: %s" cmd)) |
933 ;; (error "CCL: Invalid number of arguments: %s" cmd)) | 886 (let ((RRR (nth 1 cmd)) |
934 ;; (let ((RRR (nth 1 cmd)) | 887 (rrr (nth 2 cmd)) |
935 ;; (rrr (nth 2 cmd)) | 888 (args (nthcdr 3 cmd)) |
936 ;; (args (nthcdr 3 cmd)) | 889 map) |
937 ;; map) | 890 (ccl-check-register rrr cmd) |
938 ;; (ccl-check-register rrr cmd) | 891 (ccl-check-register RRR cmd) |
939 ;; (ccl-check-register RRR cmd) | 892 (ccl-embed-extended-command command rrr RRR 0) |
940 ;; (ccl-embed-extended-command command rrr RRR 0) | 893 (ccl-embed-data (length args)) |
941 ;; (ccl-embed-data (length args)) | 894 (while args |
942 ;; (while args | 895 (setq map (car args)) |
943 ;; (setq map (car args)) | 896 (cond ((symbolp map) |
944 ;; (cond ((symbolp map) | 897 (if (get map 'code-conversion-map) |
945 ;; (if (get map 'code-conversion-map) | 898 (ccl-embed-symbol map 'code-conversion-map-id) |
946 ;; (ccl-embed-data map) | 899 (error "CCL: Invalid map: %s" map))) |
947 ;; (error "CCL: Invalid map: %s" map))) | 900 ((numberp map) |
948 ;; ((numberp map) | 901 (ccl-embed-data map)) |
949 ;; (ccl-embed-data map)) | 902 (t |
950 ;; (t | 903 (error "CCL: Invalid type of arguments: %s" cmd))) |
951 ;; (error "CCL: Invalid type of arguments: %s" cmd))) | 904 (setq args (cdr args))))) |
952 ;; (setq args (cdr args))))) | |
953 | 905 |
954 | 906 |
955 ;;; CCL dump stuff | 907 ;;; CCL dump staffs |
908 | |
909 ;; To avoid byte-compiler warning. | |
910 (defvar ccl-code) | |
956 | 911 |
957 ;;;###autoload | 912 ;;;###autoload |
958 (defun ccl-dump (ccl-code) | 913 (defun ccl-dump (ccl-code) |
959 "Disassemble compiled CCL-CODE." | 914 "Disassemble compiled CCL-CODE." |
960 (let ((len (length ccl-code)) | 915 (let ((len (length ccl-code)) |
978 (ccl-dump-1)) | 933 (ccl-dump-1)) |
979 )) | 934 )) |
980 | 935 |
981 ;; Return a CCL code in `ccl-code' at `ccl-current-ic'. | 936 ;; Return a CCL code in `ccl-code' at `ccl-current-ic'. |
982 (defun ccl-get-next-code () | 937 (defun ccl-get-next-code () |
983 (declare (special ccl-code)) | |
984 (prog1 | 938 (prog1 |
985 (aref ccl-code ccl-current-ic) | 939 (aref ccl-code ccl-current-ic) |
986 (setq ccl-current-ic (1+ ccl-current-ic)))) | 940 (setq ccl-current-ic (1+ ccl-current-ic)))) |
987 | 941 |
988 (defun ccl-dump-1 () | 942 (defun ccl-dump-1 () |
1228 (insert (format "read-multibyte-character r%d r%d\n" RRR rrr))) | 1182 (insert (format "read-multibyte-character r%d r%d\n" RRR rrr))) |
1229 | 1183 |
1230 (defun ccl-dump-write-multibyte-character (rrr RRR Rrr) | 1184 (defun ccl-dump-write-multibyte-character (rrr RRR Rrr) |
1231 (insert (format "write-multibyte-character r%d r%d\n" RRR rrr))) | 1185 (insert (format "write-multibyte-character r%d r%d\n" RRR rrr))) |
1232 | 1186 |
1233 ;; (defun ccl-dump-translate-character (rrr RRR Rrr) | 1187 (defun ccl-dump-translate-character (rrr RRR Rrr) |
1234 ;; (insert (format "translation table(r%d) r%d r%d\n" Rrr RRR rrr))) | 1188 (insert (format "translation table(r%d) r%d r%d\n" Rrr RRR rrr))) |
1235 | 1189 |
1236 ;; (defun ccl-dump-translate-character-const-tbl (rrr RRR Rrr) | 1190 (defun ccl-dump-translate-character-const-tbl (rrr RRR Rrr) |
1237 ;; (let ((tbl (ccl-get-next-code))) | 1191 (let ((tbl (ccl-get-next-code))) |
1238 ;; (insert (format "translation table(%S) r%d r%d\n" tbl RRR rrr)))) | 1192 (insert (format "translation table(%S) r%d r%d\n" tbl RRR rrr)))) |
1239 | 1193 |
1240 ;; (defun ccl-dump-iterate-multiple-map (rrr RRR Rrr) | 1194 (defun ccl-dump-iterate-multiple-map (rrr RRR Rrr) |
1241 ;; (let ((notbl (ccl-get-next-code)) | 1195 (let ((notbl (ccl-get-next-code)) |
1242 ;; (i 0) id) | 1196 (i 0) id) |
1243 ;; (insert (format "iterate-multiple-map r%d r%d\n" RRR rrr)) | 1197 (insert (format "iterate-multiple-map r%d r%d\n" RRR rrr)) |
1244 ;; (insert (format "\tnumber of maps is %d .\n\t [" notbl)) | 1198 (insert (format "\tnumber of maps is %d .\n\t [" notbl)) |
1245 ;; (while (< i notbl) | 1199 (while (< i notbl) |
1246 ;; (setq id (ccl-get-next-code)) | 1200 (setq id (ccl-get-next-code)) |
1247 ;; (insert (format "%S" id)) | 1201 (insert (format "%S" id)) |
1248 ;; (setq i (1+ i))) | 1202 (setq i (1+ i))) |
1249 ;; (insert "]\n"))) | 1203 (insert "]\n"))) |
1250 | 1204 |
1251 ;; (defun ccl-dump-map-multiple (rrr RRR Rrr) | 1205 (defun ccl-dump-map-multiple (rrr RRR Rrr) |
1252 ;; (let ((notbl (ccl-get-next-code)) | 1206 (let ((notbl (ccl-get-next-code)) |
1253 ;; (i 0) id) | 1207 (i 0) id) |
1254 ;; (insert (format "map-multiple r%d r%d\n" RRR rrr)) | 1208 (insert (format "map-multiple r%d r%d\n" RRR rrr)) |
1255 ;; (insert (format "\tnumber of maps and separators is %d\n\t [" notbl)) | 1209 (insert (format "\tnumber of maps and separators is %d\n\t [" notbl)) |
1256 ;; (while (< i notbl) | 1210 (while (< i notbl) |
1257 ;; (setq id (ccl-get-next-code)) | 1211 (setq id (ccl-get-next-code)) |
1258 ;; (if (= id -1) | 1212 (if (= id -1) |
1259 ;; (insert "]\n\t [") | 1213 (insert "]\n\t [") |
1260 ;; (insert (format "%S " id))) | 1214 (insert (format "%S " id))) |
1261 ;; (setq i (1+ i))) | 1215 (setq i (1+ i))) |
1262 ;; (insert "]\n"))) | 1216 (insert "]\n"))) |
1263 | 1217 |
1264 ;; (defun ccl-dump-map-single (rrr RRR Rrr) | 1218 (defun ccl-dump-map-single (rrr RRR Rrr) |
1265 ;; (let ((id (ccl-get-next-code))) | 1219 (let ((id (ccl-get-next-code))) |
1266 ;; (insert (format "map-single r%d r%d map(%S)\n" RRR rrr id)))) | 1220 (insert (format "map-single r%d r%d map(%S)\n" RRR rrr id)))) |
1267 | 1221 |
1268 | 1222 |
1269 ;; CCL emulation staffs | 1223 ;; CCL emulation staffs |
1270 | 1224 |
1271 ;; Not yet implemented. | 1225 ;; Not yet implemented. |
1274 | 1228 |
1275 ;;;###autoload | 1229 ;;;###autoload |
1276 (defmacro declare-ccl-program (name &optional vector) | 1230 (defmacro declare-ccl-program (name &optional vector) |
1277 "Declare NAME as a name of CCL program. | 1231 "Declare NAME as a name of CCL program. |
1278 | 1232 |
1279 To compile a CCL program which calls another CCL program not yet | 1233 This macro exists for backward compatibility. In the old version of |
1280 defined, it must be declared as a CCL program in advance. | 1234 Emacs, to compile a CCL program which calls another CCL program not |
1235 yet defined, it must be declared as a CCL program in advance. But, | |
1236 now CCL program names are resolved not at compile time but before | |
1237 execution. | |
1238 | |
1281 Optional arg VECTOR is a compiled CCL code of the CCL program." | 1239 Optional arg VECTOR is a compiled CCL code of the CCL program." |
1282 `(put ',name 'ccl-program-idx (register-ccl-program ',name ,vector))) | 1240 `(put ',name 'ccl-program-idx (register-ccl-program ',name ,vector))) |
1283 | 1241 |
1284 ;;;###autoload | 1242 ;;;###autoload |
1285 (defmacro define-ccl-program (name ccl-program &optional doc) | 1243 (defmacro define-ccl-program (name ccl-program &optional doc) |
1286 "Set NAME the compiled code of CCL-PROGRAM. | 1244 "Set NAME the compiled code of CCL-PROGRAM. |
1287 CCL-PROGRAM is `eval'ed before being handed to the CCL compiler `ccl-compile'. | 1245 |
1288 The compiled code is a vector of integers." | 1246 CCL-PROGRAM has this form: |
1247 (BUFFER_MAGNIFICATION | |
1248 CCL_MAIN_CODE | |
1249 [ CCL_EOF_CODE ]) | |
1250 | |
1251 BUFFER_MAGNIFICATION is an integer value specifying the approximate | |
1252 output buffer magnification size compared with the bytes of input data | |
1253 text. If the value is zero, the CCL program can't execute `read' and | |
1254 `write' commands. | |
1255 | |
1256 CCL_MAIN_CODE and CCL_EOF_CODE are CCL program codes. CCL_MAIN_CODE | |
1257 executed at first. If there's no more input data when `read' command | |
1258 is executed in CCL_MAIN_CODE, CCL_EOF_CODE is executed. If | |
1259 CCL_MAIN_CODE is terminated, CCL_EOF_CODE is not executed. | |
1260 | |
1261 Here's the syntax of CCL program code in BNF notation. The lines | |
1262 starting by two semicolons (and optional leading spaces) describe the | |
1263 semantics. | |
1264 | |
1265 CCL_MAIN_CODE := CCL_BLOCK | |
1266 | |
1267 CCL_EOF_CODE := CCL_BLOCK | |
1268 | |
1269 CCL_BLOCK := STATEMENT | (STATEMENT [STATEMENT ...]) | |
1270 | |
1271 STATEMENT := | |
1272 SET | IF | BRANCH | LOOP | REPEAT | BREAK | READ | WRITE | CALL | |
1273 | TRANSLATE | END | |
1274 | |
1275 SET := (REG = EXPRESSION) | |
1276 | (REG ASSIGNMENT_OPERATOR EXPRESSION) | |
1277 ;; The following form is the same as (r0 = integer). | |
1278 | integer | |
1279 | |
1280 EXPRESSION := ARG | (EXPRESSION OPERATOR ARG) | |
1281 | |
1282 ;; Evaluate EXPRESSION. If the result is nonzeor, execute | |
1283 ;; CCL_BLOCK_0. Otherwise, execute CCL_BLOCK_1. | |
1284 IF := (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1) | |
1285 | |
1286 ;; Evaluate EXPRESSION. Provided that the result is N, execute | |
1287 ;; CCL_BLOCK_N. | |
1288 BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...]) | |
1289 | |
1290 ;; Execute STATEMENTs until (break) or (end) is executed. | |
1291 LOOP := (loop STATEMENT [STATEMENT ...]) | |
1292 | |
1293 ;; Terminate the most inner loop. | |
1294 BREAK := (break) | |
1295 | |
1296 REPEAT := | |
1297 ;; Jump to the head of the most inner loop. | |
1298 (repeat) | |
1299 ;; Same as: ((write [REG | integer | string]) | |
1300 ;; (repeat)) | |
1301 | (write-repeat [REG | integer | string]) | |
1302 ;; Same as: ((write REG [ARRAY]) | |
1303 ;; (read REG) | |
1304 ;; (repeat)) | |
1305 | (write-read-repeat REG [ARRAY]) | |
1306 ;; Same as: ((write integer) | |
1307 ;; (read REG) | |
1308 ;; (repeat)) | |
1309 | (write-read-repeat REG integer) | |
1310 | |
1311 READ := ;; Set REG_0 to a byte read from the input text, set REG_1 | |
1312 ;; to the next byte read, and so on. | |
1313 (read REG_0 [REG_1 ...]) | |
1314 ;; Same as: ((read REG) | |
1315 ;; (if (REG OPERATOR ARG) CCL_BLOCK_0 CCL_BLOCK_1)) | |
1316 | (read-if (REG OPERATOR ARG) CCL_BLOCK_0 CCL_BLOCK_1) | |
1317 ;; Same as: ((read REG) | |
1318 ;; (branch REG CCL_BLOCK_0 [CCL_BLOCK_1 ...])) | |
1319 | (read-branch REG CCL_BLOCK_0 [CCL_BLOCK_1 ...]) | |
1320 ;; Read a character from the input text while parsing | |
1321 ;; multibyte representation, set REG_0 to the charset ID of | |
1322 ;; the character, set REG_1 to the code point of the | |
1323 ;; character. If the dimension of charset is two, set REG_1 | |
1324 ;; to ((CODE0 << 8) | CODE1), where CODE0 is the first code | |
1325 ;; point and CODE1 is the second code point. | |
1326 | (read-multibyte-character REG_0 REG_1) | |
1327 | |
1328 WRITE := | |
1329 ;; Write REG_0, REG_1, ... to the output buffer. If REG_N is | |
1330 ;; a multibyte character, write the corresponding multibyte | |
1331 ;; representation. | |
1332 (write REG_0 [REG_1 ...]) | |
1333 ;; Same as: ((r7 = EXPRESSION) | |
1334 ;; (write r7)) | |
1335 | (write EXPRESSION) | |
1336 ;; Write the value of `integer' to the output buffer. If it | |
1337 ;; is a multibyte character, write the corresponding multibyte | |
1338 ;; representation. | |
1339 | (write integer) | |
1340 ;; Write the byte sequence of `string' as is to the output | |
1341 ;; buffer. It is encoded by binary coding system, thus, | |
1342 ;; by this operation, you cannot write multibyte string | |
1343 ;; as it is. | |
1344 | (write string) | |
1345 ;; Same as: (write string) | |
1346 | string | |
1347 ;; Provided that the value of REG is N, write Nth element of | |
1348 ;; ARRAY to the output buffer. If it is a multibyte | |
1349 ;; character, write the corresponding multibyte | |
1350 ;; representation. | |
1351 | (write REG ARRAY) | |
1352 ;; Write a multibyte representation of a character whose | |
1353 ;; charset ID is REG_0 and code point is REG_1. If the | |
1354 ;; dimension of the charset is two, REG_1 should be ((CODE0 << | |
1355 ;; 8) | CODE1), where CODE0 is the first code point and CODE1 | |
1356 ;; is the second code point of the character. | |
1357 | (write-multibyte-character REG_0 REG_1) | |
1358 | |
1359 ;; Call CCL program whose name is ccl-program-name. | |
1360 CALL := (call ccl-program-name) | |
1361 | |
1362 ;; Terminate the CCL program. | |
1363 END := (end) | |
1364 | |
1365 ;; CCL registers that can contain any integer value. As r7 is also | |
1366 ;; used by CCL interpreter, its value is changed unexpectedly. | |
1367 REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | |
1368 | |
1369 ARG := REG | integer | |
1370 | |
1371 OPERATOR := | |
1372 ;; Normal arithmethic operators (same meaning as C code). | |
1373 + | - | * | / | % | |
1374 | |
1375 ;; Bitwize operators (same meaning as C code) | |
1376 | & | `|' | ^ | |
1377 | |
1378 ;; Shifting operators (same meaning as C code) | |
1379 | << | >> | |
1380 | |
1381 ;; (REG = ARG_0 <8 ARG_1) means: | |
1382 ;; (REG = ((ARG_0 << 8) | ARG_1)) | |
1383 | <8 | |
1384 | |
1385 ;; (REG = ARG_0 >8 ARG_1) means: | |
1386 ;; ((REG = (ARG_0 >> 8)) | |
1387 ;; (r7 = (ARG_0 & 255))) | |
1388 | >8 | |
1389 | |
1390 ;; (REG = ARG_0 // ARG_1) means: | |
1391 ;; ((REG = (ARG_0 / ARG_1)) | |
1392 ;; (r7 = (ARG_0 % ARG_1))) | |
1393 | // | |
1394 | |
1395 ;; Normal comparing operators (same meaning as C code) | |
1396 | < | > | == | <= | >= | != | |
1397 | |
1398 ;; If ARG_0 and ARG_1 are higher and lower byte of Shift-JIS | |
1399 ;; code, and CHAR is the corresponding JISX0208 character, | |
1400 ;; (REG = ARG_0 de-sjis ARG_1) means: | |
1401 ;; ((REG = CODE0) | |
1402 ;; (r7 = CODE1)) | |
1403 ;; where CODE0 is the first code point of CHAR, CODE1 is the | |
1404 ;; second code point of CHAR. | |
1405 | de-sjis | |
1406 | |
1407 ;; If ARG_0 and ARG_1 are the first and second code point of | |
1408 ;; JISX0208 character CHAR, and SJIS is the correponding | |
1409 ;; Shift-JIS code, | |
1410 ;; (REG = ARG_0 en-sjis ARG_1) means: | |
1411 ;; ((REG = HIGH) | |
1412 ;; (r7 = LOW)) | |
1413 ;; where HIGH is the higher byte of SJIS, LOW is the lower | |
1414 ;; byte of SJIS. | |
1415 | en-sjis | |
1416 | |
1417 ASSIGNMENT_OPERATOR := | |
1418 ;; Same meaning as C code | |
1419 += | -= | *= | /= | %= | &= | `|=' | ^= | <<= | >>= | |
1420 | |
1421 ;; (REG <8= ARG) is the same as: | |
1422 ;; ((REG <<= 8) | |
1423 ;; (REG |= ARG)) | |
1424 | <8= | |
1425 | |
1426 ;; (REG >8= ARG) is the same as: | |
1427 ;; ((r7 = (REG & 255)) | |
1428 ;; (REG >>= 8)) | |
1429 | |
1430 ;; (REG //= ARG) is the same as: | |
1431 ;; ((r7 = (REG % ARG)) | |
1432 ;; (REG /= ARG)) | |
1433 | //= | |
1434 | |
1435 ARRAY := `[' integer ... `]' | |
1436 | |
1437 | |
1438 TRANSLATE := | |
1439 (translate-character REG(table) REG(charset) REG(codepoint)) | |
1440 | (translate-character SYMBOL REG(charset) REG(codepoint)) | |
1441 MAP := | |
1442 (iterate-multiple-map REG REG MAP-IDs) | |
1443 | (map-multiple REG REG (MAP-SET)) | |
1444 | (map-single REG REG MAP-ID) | |
1445 MAP-IDs := MAP-ID ... | |
1446 MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET | |
1447 MAP-ID := integer | |
1448 " | |
1289 `(let ((prog ,(ccl-compile (eval ccl-program)))) | 1449 `(let ((prog ,(ccl-compile (eval ccl-program)))) |
1290 (defconst ,name prog ,doc) | 1450 (defconst ,name prog ,doc) |
1291 (put ',name 'ccl-program-idx (register-ccl-program ',name prog)) | 1451 (put ',name 'ccl-program-idx (register-ccl-program ',name prog)) |
1292 nil)) | 1452 nil)) |
1293 | 1453 |
1294 ;;;###autoload | 1454 ;;;###autoload |
1295 (defmacro check-ccl-program (ccl-program &optional name) | 1455 (defmacro check-ccl-program (ccl-program &optional name) |
1296 "Check validity of CCL-PROGRAM. | 1456 "Check validity of CCL-PROGRAM. |
1297 If CCL-PROGRAM is a symbol denoting a valid CCL program, return | 1457 If CCL-PROGRAM is a symbol denoting a CCL program, return |
1298 CCL-PROGRAM, else return nil. | 1458 CCL-PROGRAM, else return nil. |
1299 If CCL-PROGRAM is a vector and optional arg NAME (symbol) is supplied, | 1459 If CCL-PROGRAM is a vector and optional arg NAME (symbol) is supplied, |
1300 register CCL-PROGRAM by name NAME, and return NAME." | 1460 register CCL-PROGRAM by name NAME, and return NAME." |
1301 `(let ((result ,ccl-program)) | 1461 `(if (ccl-program-p ,ccl-program) |
1302 (cond ((symbolp ,ccl-program) | 1462 (if (vectorp ,ccl-program) |
1303 (or (numberp (get ,ccl-program 'ccl-program-idx)) | 1463 (progn |
1304 (setq result nil))) | 1464 (register-ccl-program ,name ,ccl-program) |
1305 ((vectorp ,ccl-program) | 1465 ,name) |
1306 (setq result ,name) | 1466 ,ccl-program))) |
1307 (register-ccl-program result ,ccl-program)) | |
1308 (t | |
1309 (setq result nil))) | |
1310 result)) | |
1311 | 1467 |
1312 ;;;###autoload | 1468 ;;;###autoload |
1313 (defun ccl-execute-with-args (ccl-prog &rest args) | 1469 (defun ccl-execute-with-args (ccl-prog &rest args) |
1314 "Execute CCL-PROGRAM with registers initialized by the remaining args. | 1470 "Execute CCL-PROGRAM with registers initialized by the remaining args. |
1315 The return value is a vector of resulting CCL registers." | 1471 The return value is a vector of resulting CCL registers. |
1472 | |
1473 See the documentation of `define-ccl-program' for the detail of CCL program." | |
1316 (let ((reg (make-vector 8 0)) | 1474 (let ((reg (make-vector 8 0)) |
1317 (i 0)) | 1475 (i 0)) |
1318 (while (and args (< i 8)) | 1476 (while (and args (< i 8)) |
1319 (if (not (integerp (car args))) | 1477 (if (not (integerp (car args))) |
1320 (error "Arguments should be integer")) | 1478 (error "Arguments should be integer")) |