| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
(defgroup ccl nil |
|---|
| 50 |
"CCL (Code Conversion Language) compiler." |
|---|
| 51 |
:prefix "ccl-" |
|---|
| 52 |
:group 'i18n) |
|---|
| 53 |
|
|---|
| 54 |
(defconst ccl-command-table |
|---|
| 55 |
[if branch loop break repeat write-repeat write-read-repeat |
|---|
| 56 |
read read-if read-branch write call end |
|---|
| 57 |
read-multibyte-character write-multibyte-character |
|---|
| 58 |
translate-character |
|---|
| 59 |
iterate-multiple-map map-multiple map-single lookup-integer |
|---|
| 60 |
lookup-character] |
|---|
| 61 |
"Vector of CCL commands (symbols).") |
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
(let (op (i 0) (len (length ccl-command-table))) |
|---|
| 65 |
(while (< i len) |
|---|
| 66 |
(setq op (aref ccl-command-table i)) |
|---|
| 67 |
(put op 'ccl-compile-function (intern (format "ccl-compile-%s" op))) |
|---|
| 68 |
(setq i (1+ i)))) |
|---|
| 69 |
|
|---|
| 70 |
(defconst ccl-code-table |
|---|
| 71 |
[set-register |
|---|
| 72 |
set-short-const |
|---|
| 73 |
set-const |
|---|
| 74 |
set-array |
|---|
| 75 |
jump |
|---|
| 76 |
jump-cond |
|---|
| 77 |
write-register-jump |
|---|
| 78 |
write-register-read-jump |
|---|
| 79 |
write-const-jump |
|---|
| 80 |
write-const-read-jump |
|---|
| 81 |
write-string-jump |
|---|
| 82 |
write-array-read-jump |
|---|
| 83 |
read-jump |
|---|
| 84 |
branch |
|---|
| 85 |
read-register |
|---|
| 86 |
write-expr-const |
|---|
| 87 |
read-branch |
|---|
| 88 |
write-register |
|---|
| 89 |
write-expr-register |
|---|
| 90 |
call |
|---|
| 91 |
write-const-string |
|---|
| 92 |
write-array |
|---|
| 93 |
end |
|---|
| 94 |
set-assign-expr-const |
|---|
| 95 |
set-assign-expr-register |
|---|
| 96 |
set-expr-const |
|---|
| 97 |
set-expr-register |
|---|
| 98 |
jump-cond-expr-const |
|---|
| 99 |
jump-cond-expr-register |
|---|
| 100 |
read-jump-cond-expr-const |
|---|
| 101 |
read-jump-cond-expr-register |
|---|
| 102 |
ex-cmd |
|---|
| 103 |
] |
|---|
| 104 |
"Vector of CCL compiled codes (symbols).") |
|---|
| 105 |
|
|---|
| 106 |
(defconst ccl-extended-code-table |
|---|
| 107 |
[read-multibyte-character |
|---|
| 108 |
write-multibyte-character |
|---|
| 109 |
translate-character |
|---|
| 110 |
translate-character-const-tbl |
|---|
| 111 |
nil nil nil nil nil nil nil nil nil nil nil nil |
|---|
| 112 |
iterate-multiple-map |
|---|
| 113 |
map-multiple |
|---|
| 114 |
map-single |
|---|
| 115 |
lookup-int-const-tbl |
|---|
| 116 |
lookup-char-const-tbl |
|---|
| 117 |
] |
|---|
| 118 |
"Vector of CCL extended compiled codes (symbols).") |
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
(let (code (i 0) (len (length ccl-code-table))) |
|---|
| 122 |
(while (< i len) |
|---|
| 123 |
(setq code (aref ccl-code-table i)) |
|---|
| 124 |
(put code 'ccl-code i) |
|---|
| 125 |
(put code 'ccl-dump-function (intern (format "ccl-dump-%s" code))) |
|---|
| 126 |
(setq i (1+ i)))) |
|---|
| 127 |
|
|---|
| 128 |
(let (code (i 0) (len (length ccl-extended-code-table))) |
|---|
| 129 |
(while (< i len) |
|---|
| 130 |
(setq code (aref ccl-extended-code-table i)) |
|---|
| 131 |
(if code |
|---|
| 132 |
(progn |
|---|
| 133 |
(put code 'ccl-ex-code i) |
|---|
| 134 |
(put code 'ccl-dump-function (intern (format "ccl-dump-%s" code))))) |
|---|
| 135 |
(setq i (1+ i)))) |
|---|
| 136 |
|
|---|
| 137 |
(defconst ccl-jump-code-list |
|---|
| 138 |
'(jump jump-cond write-register-jump write-register-read-jump |
|---|
| 139 |
write-const-jump write-const-read-jump write-string-jump |
|---|
| 140 |
write-array-read-jump read-jump)) |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
|
|---|
| 144 |
(let ((l ccl-jump-code-list)) |
|---|
| 145 |
(while l |
|---|
| 146 |
(put (car l) 'jump-flag t) |
|---|
| 147 |
(setq l (cdr l)))) |
|---|
| 148 |
|
|---|
| 149 |
(defconst ccl-register-table |
|---|
| 150 |
[r0 r1 r2 r3 r4 r5 r6 r7] |
|---|
| 151 |
"Vector of CCL registers (symbols).") |
|---|
| 152 |
|
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 |
(let (reg (i 0) (len (length ccl-register-table))) |
|---|
| 156 |
(while (< i len) |
|---|
| 157 |
(setq reg (aref ccl-register-table i)) |
|---|
| 158 |
(put reg 'ccl-register-number i) |
|---|
| 159 |
(setq i (1+ i)))) |
|---|
| 160 |
|
|---|
| 161 |
(defconst ccl-arith-table |
|---|
| 162 |
[+ - * / % & | ^ << >> <8 >8 // nil nil nil |
|---|
| 163 |
< > == <= >= != de-sjis en-sjis] |
|---|
| 164 |
"Vector of CCL arithmetic/logical operators (symbols).") |
|---|
| 165 |
|
|---|
| 166 |
|
|---|
| 167 |
(let (arith (i 0) (len (length ccl-arith-table))) |
|---|
| 168 |
(while (< i len) |
|---|
| 169 |
(setq arith (aref ccl-arith-table i)) |
|---|
| 170 |
(if arith (put arith 'ccl-arith-code i)) |
|---|
| 171 |
(setq i (1+ i)))) |
|---|
| 172 |
|
|---|
| 173 |
(defconst ccl-assign-arith-table |
|---|
| 174 |
[+= -= *= /= %= &= |= ^= <<= >>= <8= >8= //=] |
|---|
| 175 |
"Vector of CCL assignment operators (symbols).") |
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 |
(let (arith (i 0) (len (length ccl-assign-arith-table))) |
|---|
| 179 |
(while (< i len) |
|---|
| 180 |
(setq arith (aref ccl-assign-arith-table i)) |
|---|
| 181 |
(put arith 'ccl-self-arith-code i) |
|---|
| 182 |
(setq i (1+ i)))) |
|---|
| 183 |
|
|---|
| 184 |
(defvar ccl-program-vector nil |
|---|
| 185 |
"Working vector of CCL codes produced by CCL compiler.") |
|---|
| 186 |
(defvar ccl-current-ic 0 |
|---|
| 187 |
"The current index for `ccl-program-vector'.") |
|---|
| 188 |
|
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
(defun ccl-embed-data (data &optional ic) |
|---|
| 192 |
(if ic |
|---|
| 193 |
(aset ccl-program-vector ic data) |
|---|
| 194 |
(let ((len (length ccl-program-vector))) |
|---|
| 195 |
(if (>= ccl-current-ic len) |
|---|
| 196 |
(let ((new (make-vector (* len 2) nil))) |
|---|
| 197 |
(while (> len 0) |
|---|
| 198 |
(setq len (1- len)) |
|---|
| 199 |
(aset new len (aref ccl-program-vector len))) |
|---|
| 200 |
(setq ccl-program-vector new)))) |
|---|
| 201 |
(aset ccl-program-vector ccl-current-ic data) |
|---|
| 202 |
(setq ccl-current-ic (1+ ccl-current-ic)))) |
|---|
| 203 |
|
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
|
|---|
| 207 |
|
|---|
| 208 |
(defun ccl-embed-symbol (symbol prop) |
|---|
| 209 |
(ccl-embed-data (cons symbol prop))) |
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 |
(defun ccl-embed-string (len str) |
|---|
| 214 |
(let ((i 0)) |
|---|
| 215 |
(while (< i len) |
|---|
| 216 |
(ccl-embed-data (logior (ash (aref str i) 16) |
|---|
| 217 |
(if (< (1+ i) len) |
|---|
| 218 |
(ash (aref str (1+ i)) 8) |
|---|
| 219 |
0) |
|---|
| 220 |
(if (< (+ i 2) len) |
|---|
| 221 |
(aref str (+ i 2)) |
|---|
| 222 |
0))) |
|---|
| 223 |
(setq i (+ i 3))))) |
|---|
| 224 |
|
|---|
| 225 |
|
|---|
| 226 |
|
|---|
| 227 |
(defun ccl-embed-current-address (ic) |
|---|
| 228 |
(let ((relative (- ccl-current-ic (1+ ic)))) |
|---|
| 229 |
(aset ccl-program-vector ic |
|---|
| 230 |
(logior (aref ccl-program-vector ic) (ash relative 8))))) |
|---|
| 231 |
|
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
|
|---|
| 238 |
|
|---|
| 239 |
|
|---|
| 240 |
|
|---|
| 241 |
|
|---|
| 242 |
|
|---|
| 243 |
|
|---|
| 244 |
|
|---|
| 245 |
(defun ccl-embed-code (op reg data &optional reg2) |
|---|
| 246 |
(if (and (> data 0) (get op 'jump-flag)) |
|---|
| 247 |
|
|---|
| 248 |
|
|---|
| 249 |
(setq data (- data (1+ ccl-current-ic)))) |
|---|
| 250 |
(let ((code (logior (get op 'ccl-code) |
|---|
| 251 |
(ash |
|---|
| 252 |
(if (symbolp reg) (get reg 'ccl-register-number) reg) 5) |
|---|
| 253 |
(if reg2 |
|---|
| 254 |
(logior (ash (get reg2 'ccl-register-number) 8) |
|---|
| 255 |
(ash data 11)) |
|---|
| 256 |
(ash data 8))))) |
|---|
| 257 |
(ccl-embed-data code))) |
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
|
|---|
| 261 |
|
|---|
| 262 |
(defun ccl-embed-extended-command (ex-op reg reg2 reg3) |
|---|
| 263 |
(let ((data (logior (ash (get ex-op 'ccl-ex-code) 3) |
|---|
| 264 |
(if (symbolp reg3) |
|---|
| 265 |
(get reg3 'ccl-register-number) |
|---|
| 266 |
0)))) |
|---|
| 267 |
(ccl-embed-code 'ex-cmd reg data reg2))) |
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 |
(defun ccl-increment-ic (inc) |
|---|
| 271 |
(setq ccl-current-ic (+ ccl-current-ic inc))) |
|---|
| 272 |
|
|---|
| 273 |
|
|---|
| 274 |
(defvar ccl-loop-head nil) |
|---|
| 275 |
|
|---|
| 276 |
|
|---|
| 277 |
(defvar ccl-breaks nil) |
|---|
| 278 |
|
|---|
| 279 |
|
|---|
| 280 |
(defun ccl-compile (ccl-program) |
|---|
| 281 |
"Return the compiled code of CCL-PROGRAM as a vector of integers." |
|---|
| 282 |
(if (or (null (consp ccl-program)) |
|---|
| 283 |
(null (integerp (car ccl-program))) |
|---|
| 284 |
(null (listp (car (cdr ccl-program))))) |
|---|
| 285 |
(error "CCL: Invalid CCL program: %s" ccl-program)) |
|---|
| 286 |
(if (null (vectorp ccl-program-vector)) |
|---|
| 287 |
(setq ccl-program-vector (make-vector 8192 0))) |
|---|
| 288 |
(setq ccl-loop-head nil ccl-breaks nil) |
|---|
| 289 |
(setq ccl-current-ic 0) |
|---|
| 290 |
|
|---|
| 291 |
|
|---|
| 292 |
(ccl-embed-data (car ccl-program)) |
|---|
| 293 |
|
|---|
| 294 |
|
|---|
| 295 |
|
|---|
| 296 |
|
|---|
| 297 |
(ccl-increment-ic 1) |
|---|
| 298 |
|
|---|
| 299 |
|
|---|
| 300 |
(ccl-compile-1 (car (cdr ccl-program))) |
|---|
| 301 |
|
|---|
| 302 |
|
|---|
| 303 |
(ccl-embed-data ccl-current-ic 1) |
|---|
| 304 |
|
|---|
| 305 |
|
|---|
| 306 |
(if (nth 2 ccl-program) |
|---|
| 307 |
(ccl-compile-1 (nth 2 ccl-program))) |
|---|
| 308 |
|
|---|
| 309 |
|
|---|
| 310 |
(ccl-embed-code 'end 0 0) |
|---|
| 311 |
|
|---|
| 312 |
(let ((vec (make-vector ccl-current-ic 0)) |
|---|
| 313 |
(i 0)) |
|---|
| 314 |
(while (< i ccl-current-ic) |
|---|
| 315 |
(aset vec i (aref ccl-program-vector i)) |
|---|
| 316 |
(setq i (1+ i))) |
|---|
| 317 |
vec)) |
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 |
(defun ccl-syntax-error (cmd) |
|---|
| 321 |
(error "CCL: Syntax error: %s" cmd)) |
|---|
| 322 |
|
|---|
| 323 |
|
|---|
| 324 |
(defun ccl-check-register (arg cmd) |
|---|
| 325 |
(if (get arg 'ccl-register-number) |
|---|
| 326 |
arg |
|---|
| 327 |
(error "CCL: Invalid register %s in %s" arg cmd))) |
|---|
| 328 |
|
|---|
| 329 |
|
|---|
| 330 |
(defun ccl-check-compile-function (arg cmd) |
|---|
| 331 |
(or (get arg 'ccl-compile-function) |
|---|
| 332 |
(error "CCL: Invalid command: %s" cmd))) |
|---|
| 333 |
|
|---|
| 334 |
|
|---|
| 335 |
|
|---|
| 336 |
|
|---|
| 337 |
|
|---|
| 338 |
(defun ccl-compile-1 (ccl-block) |
|---|
| 339 |
(let (unconditional-jump |
|---|
| 340 |
cmd) |
|---|
| 341 |
(if (or (integerp ccl-block) |
|---|
| 342 |
(stringp ccl-block) |
|---|
| 343 |
(and ccl-block (symbolp (car ccl-block)))) |
|---|
| 344 |
|
|---|
| 345 |
(setq ccl-block (list ccl-block))) |
|---|
| 346 |
|
|---|
| 347 |
|
|---|
| 348 |
|
|---|
| 349 |
(while ccl-block |
|---|
| 350 |
(setq cmd (car ccl-block)) |
|---|
| 351 |
(setq unconditional-jump |
|---|
| 352 |
(cond ((integerp cmd) |
|---|
| 353 |
|
|---|
| 354 |
(ccl-compile-set (list 'r0 '= cmd))) |
|---|
| 355 |
|
|---|
| 356 |
((stringp cmd) |
|---|
| 357 |
|
|---|
| 358 |
(ccl-compile-write-string cmd)) |
|---|
| 359 |
|
|---|
| 360 |
((listp cmd) |
|---|
| 361 |
|
|---|
| 362 |
(cond ((eq (nth 1 cmd) '=) |
|---|
| 363 |
|
|---|
| 364 |
(ccl-compile-set cmd)) |
|---|
| 365 |
|
|---|
| 366 |
((and (symbolp (nth 1 cmd)) |
|---|
| 367 |
(get (nth 1 cmd) 'ccl-self-arith-code)) |
|---|
| 368 |
|
|---|
| 369 |
(ccl-compile-self-set cmd)) |
|---|
| 370 |
|
|---|
| 371 |
(t |
|---|
| 372 |
(funcall (ccl-check-compile-function (car cmd) cmd) |
|---|
| 373 |
cmd)))) |
|---|
| 374 |
|
|---|
| 375 |
(t |
|---|
| 376 |
(ccl-syntax-error cmd)))) |
|---|
| 377 |
(setq ccl-block (cdr ccl-block))) |
|---|
| 378 |
unconditional-jump)) |
|---|
| 379 |
|
|---|
| 380 |
(defconst ccl-max-short-const (ash 1 19)) |
|---|
| 381 |
(defconst ccl-min-short-const (ash -1 19)) |
|---|
| 382 |
|
|---|
| 383 |
|
|---|
| 384 |
(defun ccl-compile-set (cmd) |
|---|
| 385 |
(let ((rrr (ccl-check-register (car cmd) cmd)) |
|---|
| 386 |
(right (nth 2 cmd))) |
|---|
| 387 |
(cond ((listp right) |
|---|
| 388 |
|
|---|
| 389 |
(ccl-compile-expression rrr right)) |
|---|
| 390 |
|
|---|
| 391 |
((integerp right) |
|---|
| 392 |
|
|---|
| 393 |
(if (and (<= right ccl-max-short-const) |
|---|
| 394 |
(>= right ccl-min-short-const)) |
|---|
| 395 |
(ccl-embed-code 'set-short-const rrr right) |
|---|
| 396 |
(ccl-embed-code 'set-const rrr 0) |
|---|
| 397 |
(ccl-embed-data right))) |
|---|
| 398 |
|
|---|
| 399 |
(t |
|---|
| 400 |
|
|---|
| 401 |
(ccl-check-register right cmd) |
|---|
| 402 |
(let ((ary (nth 3 cmd))) |
|---|
| 403 |
(if (vectorp ary) |
|---|
| 404 |
(let ((i 0) (len (length ary))) |
|---|
| 405 |
(ccl-embed-code 'set-array rrr len right) |
|---|
| 406 |
(while (< i len) |
|---|
| 407 |
(ccl-embed-data (aref ary i)) |
|---|
| 408 |
(setq i (1+ i)))) |
|---|
| 409 |
(ccl-embed-code 'set-register rrr 0 right)))))) |
|---|
| 410 |
nil) |
|---|
| 411 |
|
|---|
| 412 |
|
|---|
| 413 |
(defun ccl-compile-self-set (cmd) |
|---|
| 414 |
(let ((rrr (ccl-check-register (car cmd) cmd)) |
|---|
| 415 |
(right (nth 2 cmd))) |
|---|
| 416 |
(if (listp right) |
|---|
| 417 |
|
|---|
| 418 |
|
|---|
| 419 |
|
|---|
| 420 |
(progn |
|---|
| 421 |
(ccl-compile-expression 'r7 right) |
|---|
| 422 |
(setq right 'r7))) |
|---|
| 423 |
|
|---|
| 424 |
|
|---|
| 425 |
(ccl-compile-expression |
|---|
| 426 |
rrr |
|---|
| 427 |
(list rrr (intern (substring (symbol-name (nth 1 cmd)) 0 -1)) right))) |
|---|
| 428 |
nil) |
|---|
| 429 |
|
|---|
| 430 |
|
|---|
| 431 |
(defun ccl-compile-expression (rrr expr) |
|---|
| 432 |
(let ((left (car expr)) |
|---|
| 433 |
(op (get (nth 1 expr) 'ccl-arith-code)) |
|---|
| 434 |
(right (nth 2 expr))) |
|---|
| 435 |
(if (listp left) |
|---|
| 436 |
(progn |
|---|
| 437 |
|
|---|
| 438 |
|
|---|
| 439 |
(ccl-compile-expression 'r7 left) |
|---|
| 440 |
(setq left 'r7))) |
|---|
| 441 |
|
|---|
| 442 |
|
|---|
| 443 |
(if (and (eq rrr left) |
|---|
| 444 |
(< op (length ccl-assign-arith-table))) |
|---|
| 445 |
|
|---|
| 446 |
(if (integerp right) |
|---|
| 447 |
(progn |
|---|
| 448 |
(ccl-embed-code 'set-assign-expr-const rrr (ash op 3) 'r0) |
|---|
| 449 |
(ccl-embed-data right)) |
|---|
| 450 |
(ccl-check-register right expr) |
|---|
| 451 |
(ccl-embed-code 'set-assign-expr-register rrr (ash op 3) right)) |
|---|
| 452 |
|
|---|
| 453 |
|
|---|
| 454 |
(if (integerp right) |
|---|
| 455 |
(progn |
|---|
| 456 |
(ccl-embed-code 'set-expr-const rrr (ash op 3) left) |
|---|
| 457 |
(ccl-embed-data right)) |
|---|
| 458 |
(ccl-check-register right expr) |
|---|
| 459 |
(ccl-embed-code 'set-expr-register |
|---|
| 460 |
rrr |
|---|
| 461 |
(logior (ash op 3) (get right 'ccl-register-number)) |
|---|
| 462 |
left))))) |
|---|
| 463 |
|
|---|
| 464 |
|
|---|
| 465 |
(defun ccl-compile-write-string (str) |
|---|
| 466 |
(setq str (string-as-unibyte str)) |
|---|
| 467 |
(let ((len (length str))) |
|---|
| 468 |
(ccl-embed-code 'write-const-string 1 len) |
|---|
| 469 |
(ccl-embed-string len str)) |
|---|
| 470 |
nil) |
|---|
| 471 |
|
|---|
| 472 |
|
|---|
| 473 |
|
|---|
| 474 |
|
|---|
| 475 |
(defun ccl-compile-if (cmd &optional read-flag) |
|---|
| 476 |
(if (and (/= (length cmd) 3) (/= (length cmd) 4)) |
|---|
| 477 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 478 |
(let ((condition (nth 1 cmd)) |
|---|
| 479 |
(true-cmds (nth 2 cmd)) |
|---|
| 480 |
(false-cmds (nth 3 cmd)) |
|---|
| 481 |
jump-cond-address |
|---|
| 482 |
false-ic) |
|---|
| 483 |
(if (and (listp condition) |
|---|
| 484 |
(listp (car condition))) |
|---|
| 485 |
|
|---|
| 486 |
|
|---|
| 487 |
|
|---|
| 488 |
|
|---|
| 489 |
(progn |
|---|
| 490 |
(ccl-compile-expression 'r7 (car condition)) |
|---|
| 491 |
(setq condition (cons 'r7 (cdr condition))) |
|---|
| 492 |
(setq cmd (cons (car cmd) |
|---|
| 493 |
(cons condition (cdr (cdr cmd))))))) |
|---|
| 494 |
|
|---|
| 495 |
(setq jump-cond-address ccl-current-ic) |
|---|
| 496 |
|
|---|
| 497 |
(if (symbolp condition) |
|---|
| 498 |
|
|---|
| 499 |
(progn |
|---|
| 500 |
(ccl-check-register condition cmd) |
|---|
| 501 |
(ccl-embed-code 'jump-cond condition 0)) |
|---|
| 502 |
|
|---|
| 503 |
(let ((rrr (car condition)) |
|---|
| 504 |
(op (get (nth 1 condition) 'ccl-arith-code)) |
|---|
| 505 |
(arg (nth 2 condition))) |
|---|
| 506 |
(ccl-check-register rrr cmd) |
|---|
| 507 |
(if (integerp arg) |
|---|
| 508 |
(progn |
|---|
| 509 |
(ccl-embed-code (if read-flag 'read-jump-cond-expr-const |
|---|
| 510 |
'jump-cond-expr-const) |
|---|
| 511 |
rrr 0) |
|---|
| 512 |
(ccl-embed-data op) |
|---|
| 513 |
(ccl-embed-data arg)) |
|---|
| 514 |
(ccl-check-register arg cmd) |
|---|
| 515 |
(ccl-embed-code (if read-flag 'read-jump-cond-expr-register |
|---|
| 516 |
'jump-cond-expr-register) |
|---|
| 517 |
rrr 0) |
|---|
| 518 |
(ccl-embed-data op) |
|---|
| 519 |
(ccl-embed-data (get arg 'ccl-register-number))))) |
|---|
| 520 |
|
|---|
| 521 |
|
|---|
| 522 |
(let ((unconditional-jump (ccl-compile-1 true-cmds))) |
|---|
| 523 |
(if (null false-cmds) |
|---|
| 524 |
|
|---|
| 525 |
(progn |
|---|
| 526 |
(ccl-embed-current-address jump-cond-address) |
|---|
| 527 |
(setq unconditional-jump nil)) |
|---|
| 528 |
(let (end-true-part-address) |
|---|
| 529 |
(if (not unconditional-jump) |
|---|
| 530 |
(progn |
|---|
| 531 |
|
|---|
| 532 |
|
|---|
| 533 |
(setq end-true-part-address ccl-current-ic) |
|---|
| 534 |
(ccl-embed-code 'jump 0 0))) |
|---|
| 535 |
|
|---|
| 536 |
(ccl-embed-current-address jump-cond-address) |
|---|
| 537 |
|
|---|
| 538 |
(setq unconditional-jump |
|---|
| 539 |
(and (ccl-compile-1 false-cmds) unconditional-jump)) |
|---|
| 540 |
(if end-true-part-address |
|---|
| 541 |
|
|---|
| 542 |
(ccl-embed-current-address end-true-part-address)))) |
|---|
| 543 |
unconditional-jump))) |
|---|
| 544 |
|
|---|
| 545 |
|
|---|
| 546 |
(defun ccl-compile-branch (cmd) |
|---|
| 547 |
(if (< (length cmd) 3) |
|---|
| 548 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 549 |
(ccl-compile-branch-blocks 'branch |
|---|
| 550 |
(ccl-compile-branch-expression (nth 1 cmd) cmd) |
|---|
| 551 |
(cdr (cdr cmd)))) |
|---|
| 552 |
|
|---|
| 553 |
|
|---|
| 554 |
(defun ccl-compile-read-branch (cmd) |
|---|
| 555 |
(if (< (length cmd) 3) |
|---|
| 556 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 557 |
(ccl-compile-branch-blocks 'read-branch |
|---|
| 558 |
(ccl-compile-branch-expression (nth 1 cmd) cmd) |
|---|
| 559 |
(cdr (cdr cmd)))) |
|---|
| 560 |
|
|---|
| 561 |
|
|---|
| 562 |
|
|---|
| 563 |
(defun ccl-compile-branch-expression (expr cmd) |
|---|
| 564 |
(if (listp expr) |
|---|
| 565 |
|
|---|
| 566 |
|
|---|
| 567 |
(progn |
|---|
| 568 |
(ccl-compile-expression 'r7 expr) |
|---|
| 569 |
'r7) |
|---|
| 570 |
(ccl-check-register expr cmd))) |
|---|
| 571 |
|
|---|
| 572 |
|
|---|
| 573 |
|
|---|
| 574 |
|
|---|
| 575 |
(defun ccl-compile-branch-blocks (code rrr blocks) |
|---|
| 576 |
(let ((branches (length blocks)) |
|---|
| 577 |
branch-idx |
|---|
| 578 |
jump-table-head-address |
|---|
| 579 |
empty-block-indexes |
|---|
| 580 |
block-tail-addresses |
|---|
| 581 |
block-unconditional-jump) |
|---|
| 582 |
(ccl-embed-code code rrr branches) |
|---|
| 583 |
(setq jump-table-head-address ccl-current-ic) |
|---|
| 584 |
|
|---|
| 585 |
|
|---|
| 586 |
(ccl-increment-ic (1+ branches)) |
|---|
| 587 |
(setq empty-block-indexes (list branches)) |
|---|
| 588 |
|
|---|
| 589 |
(setq branch-idx 0) |
|---|
| 590 |
(while blocks |
|---|
| 591 |
(if (null (car blocks)) |
|---|
| 592 |
|
|---|
| 593 |
(setq empty-block-indexes (cons branch-idx empty-block-indexes) |
|---|
| 594 |
block-unconditional-jump t) |
|---|
| 595 |
|
|---|
| 596 |
(ccl-embed-data (- ccl-current-ic jump-table-head-address) |
|---|
| 597 |
(+ jump-table-head-address branch-idx)) |
|---|
| 598 |
(setq block-unconditional-jump (ccl-compile-1 (car blocks))) |
|---|
| 599 |
(if (not block-unconditional-jump) |
|---|
| 600 |
(progn |
|---|
| 601 |
|
|---|
| 602 |
|
|---|
| 603 |
(setq block-tail-addresses |
|---|
| 604 |
(cons ccl-current-ic block-tail-addresses)) |
|---|
| 605 |
(ccl-embed-code 'jump 0 0)))) |
|---|
| 606 |
(setq branch-idx (1+ branch-idx)) |
|---|
| 607 |
(setq blocks (cdr blocks))) |
|---|
| 608 |
(if (not block-unconditional-jump) |
|---|
| 609 |
|
|---|
| 610 |
(setq block-tail-addresses (cdr block-tail-addresses) |
|---|
| 611 |
ccl-current-ic (1- ccl-current-ic))) |
|---|
| 612 |
|
|---|
| 613 |
(while block-tail-addresses |
|---|
| 614 |
(ccl-embed-current-address (car block-tail-addresses)) |
|---|
| 615 |
(setq block-tail-addresses (cdr block-tail-addresses))) |
|---|
| 616 |
|
|---|
| 617 |
(while empty-block-indexes |
|---|
| 618 |
(ccl-embed-data (- ccl-current-ic jump-table-head-address) |
|---|
| 619 |
(+ jump-table-head-address (car empty-block-indexes))) |
|---|
| 620 |
(setq empty-block-indexes (cdr empty-block-indexes)))) |
|---|
| 621 |
|
|---|
| 622 |
nil) |
|---|
| 623 |
|
|---|
| 624 |
|
|---|
| 625 |
(defun ccl-compile-loop (cmd) |
|---|
| 626 |
(if (< (length cmd) 2) |
|---|
| 627 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 628 |
(let* ((ccl-loop-head ccl-current-ic) |
|---|
| 629 |
(ccl-breaks nil) |
|---|
| 630 |
unconditional-jump) |
|---|
| 631 |
(setq cmd (cdr cmd)) |
|---|
| 632 |
(if cmd |
|---|
| 633 |
(progn |
|---|
| 634 |
(setq unconditional-jump t) |
|---|
| 635 |
(while cmd |
|---|
| 636 |
(setq unconditional-jump |
|---|
| 637 |
(and (ccl-compile-1 (car cmd)) unconditional-jump)) |
|---|
| 638 |
(setq cmd (cdr cmd))) |
|---|
| 639 |
(if (not ccl-breaks) |
|---|
| 640 |
unconditional-jump |
|---|
| 641 |
|
|---|
| 642 |
|
|---|
| 643 |
(while ccl-breaks |
|---|
| 644 |
(ccl-embed-current-address (car ccl-breaks)) |
|---|
| 645 |
(setq ccl-breaks (cdr ccl-breaks)))) |
|---|
| 646 |
nil)))) |
|---|
| 647 |
|
|---|
| 648 |
|
|---|
| 649 |
(defun ccl-compile-break (cmd) |
|---|
| 650 |
(if (/= (length cmd) 1) |
|---|
| 651 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 652 |
(if (null ccl-loop-head) |
|---|
| 653 |
(error "CCL: No outer loop: %s" cmd)) |
|---|
| 654 |
(setq ccl-breaks (cons ccl-current-ic ccl-breaks)) |
|---|
| 655 |
(ccl-embed-code 'jump 0 0) |
|---|
| 656 |
t) |
|---|
| 657 |
|
|---|
| 658 |
|
|---|
| 659 |
(defun ccl-compile-repeat (cmd) |
|---|
| 660 |
(if (/= (length cmd) 1) |
|---|
| 661 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 662 |
(if (null ccl-loop-head) |
|---|
| 663 |
(error "CCL: No outer loop: %s" cmd)) |
|---|
| 664 |
(ccl-embed-code 'jump 0 ccl-loop-head) |
|---|
| 665 |
t) |
|---|
| 666 |
|
|---|
| 667 |
|
|---|
| 668 |
(defun ccl-compile-write-repeat (cmd) |
|---|
| 669 |
(if (/= (length cmd) 2) |
|---|
| 670 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 671 |
(if (null ccl-loop-head) |
|---|
| 672 |
(error "CCL: No outer loop: %s" cmd)) |
|---|
| 673 |
(let ((arg (nth 1 cmd))) |
|---|
| 674 |
(cond ((integerp arg) |
|---|
| 675 |
(ccl-embed-code 'write-const-jump 0 ccl-loop-head) |
|---|
| 676 |
(ccl-embed-data arg)) |
|---|
| 677 |
((stringp arg) |
|---|
| 678 |
(setq arg (string-as-unibyte arg)) |
|---|
| 679 |
(let ((len (length arg)) |
|---|
| 680 |
(i 0)) |
|---|
| 681 |
(ccl-embed-code 'write-string-jump 0 ccl-loop-head) |
|---|
| 682 |
(ccl-embed-data len) |
|---|
| 683 |
(ccl-embed-string len arg))) |
|---|
| 684 |
(t |
|---|
| 685 |
(ccl-check-register arg cmd) |
|---|
| 686 |
(ccl-embed-code 'write-register-jump arg ccl-loop-head)))) |
|---|
| 687 |
t) |
|---|
| 688 |
|
|---|
| 689 |
|
|---|
| 690 |
(defun ccl-compile-write-read-repeat (cmd) |
|---|
| 691 |
(if (or (< (length cmd) 2) (> (length cmd) 3)) |
|---|
| 692 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 693 |
(if (null ccl-loop-head) |
|---|
| 694 |
(error "CCL: No outer loop: %s" cmd)) |
|---|
| 695 |
(let ((rrr (ccl-check-register (nth 1 cmd) cmd)) |
|---|
| 696 |
(arg (nth 2 cmd))) |
|---|
| 697 |
(cond ((null arg) |
|---|
| 698 |
(ccl-embed-code 'write-register-read-jump rrr ccl-loop-head)) |
|---|
| 699 |
((integerp arg) |
|---|
| 700 |
(ccl-embed-code 'write-const-read-jump rrr arg ccl-loop-head)) |
|---|
| 701 |
((vectorp arg) |
|---|
| 702 |
(let ((len (length arg)) |
|---|
| 703 |
(i 0)) |
|---|
| 704 |
(ccl-embed-code 'write-array-read-jump rrr ccl-loop-head) |
|---|
| 705 |
(ccl-embed-data len) |
|---|
| 706 |
(while (< i len) |
|---|
| 707 |
(ccl-embed-data (aref arg i)) |
|---|
| 708 |
(setq i (1+ i))))) |
|---|
| 709 |
(t |
|---|
| 710 |
(error "CCL: Invalid argument %s: %s" arg cmd))) |
|---|
| 711 |
(ccl-embed-code 'read-jump rrr ccl-loop-head)) |
|---|
| 712 |
t) |
|---|
| 713 |
|
|---|
| 714 |
|
|---|
| 715 |
(defun ccl-compile-read (cmd) |
|---|
| 716 |
(if (< (length cmd) 2) |
|---|
| 717 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 718 |
(let* ((args (cdr cmd)) |
|---|
| 719 |
(i (1- (length args)))) |
|---|
| 720 |
(while args |
|---|
| 721 |
(let ((rrr (ccl-check-register (car args) cmd))) |
|---|
| 722 |
(ccl-embed-code 'read-register rrr i) |
|---|
| 723 |
(setq args (cdr args) i (1- i))))) |
|---|
| 724 |
nil) |
|---|
| 725 |
|
|---|
| 726 |
|
|---|
| 727 |
(defun ccl-compile-read-if (cmd) |
|---|
| 728 |
(ccl-compile-if cmd 'read)) |
|---|
| 729 |
|
|---|
| 730 |
|
|---|
| 731 |
(defun ccl-compile-write (cmd) |
|---|
| 732 |
(if (< (length cmd) 2) |
|---|
| 733 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 734 |
(let ((rrr (nth 1 cmd))) |
|---|
| 735 |
(cond ((integerp rrr) |
|---|
| 736 |
(ccl-embed-code 'write-const-string 0 rrr)) |
|---|
| 737 |
((stringp rrr) |
|---|
| 738 |
(ccl-compile-write-string rrr)) |
|---|
| 739 |
((and (symbolp rrr) (vectorp (nth 2 cmd))) |
|---|
| 740 |
(ccl-check-register rrr cmd) |
|---|
| 741 |
|
|---|
| 742 |
(let* ((arg (nth 2 cmd)) |
|---|
| 743 |
(len (length arg)) |
|---|
| 744 |
(i 0)) |
|---|
| 745 |
(ccl-embed-code 'write-array rrr len) |
|---|
| 746 |
(while (< i len) |
|---|
| 747 |
(if (not (integerp (aref arg i))) |
|---|
| 748 |
(error "CCL: Invalid argument %s: %s" arg cmd)) |
|---|
| 749 |
(ccl-embed-data (aref arg i)) |
|---|
| 750 |
(setq i (1+ i))))) |
|---|
| 751 |
|
|---|
| 752 |
((symbolp rrr) |
|---|
| 753 |
|
|---|
| 754 |
(let* ((args (cdr cmd)) |
|---|
| 755 |
(i (1- (length args)))) |
|---|
| 756 |
(while args |
|---|
| 757 |
(setq rrr (ccl-check-register (car args) cmd)) |
|---|
| 758 |
(ccl-embed-code 'write-register rrr i) |
|---|
| 759 |
(setq args (cdr args) i (1- i))))) |
|---|
| 760 |
|
|---|
| 761 |
((listp rrr) |
|---|
| 762 |
|
|---|
| 763 |
(let ((left (car rrr)) |
|---|
| 764 |
(op (get (nth 1 rrr) 'ccl-arith-code)) |
|---|
| 765 |
(right (nth 2 rrr))) |
|---|
| 766 |
(if (listp left) |
|---|
| 767 |
(progn |
|---|
| 768 |
|
|---|
| 769 |
|
|---|
| 770 |
(ccl-compile-expression 'r7 left) |
|---|
| 771 |
(setq left 'r7))) |
|---|
| 772 |
|
|---|
| 773 |
(if (integerp right) |
|---|
| 774 |
(progn |
|---|
| 775 |
(ccl-embed-code 'write-expr-const 0 (ash op 3) left) |
|---|
| 776 |
(ccl-embed-data right)) |
|---|
| 777 |
(ccl-check-register right rrr) |
|---|
| 778 |
(ccl-embed-code 'write-expr-register 0 |
|---|
| 779 |
(logior (ash op 3) |
|---|
| 780 |
(get right 'ccl-register-number)) |
|---|
| 781 |
left)))) |
|---|
| 782 |
|
|---|
| 783 |
(t |
|---|
| 784 |
(error "CCL: Invalid argument: %s" cmd)))) |
|---|
| 785 |
nil) |
|---|
| 786 |
|
|---|
| 787 |
|
|---|
| 788 |
(defun ccl-compile-call (cmd) |
|---|
| 789 |
(if (/= (length cmd) 2) |
|---|
| 790 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 791 |
(if (not (symbolp (nth 1 cmd))) |
|---|
| 792 |
(error "CCL: Subroutine should be a symbol: %s" cmd)) |
|---|
| 793 |
(ccl-embed-code 'call 1 0) |
|---|
| 794 |
(ccl-embed-symbol (nth 1 cmd) 'ccl-program-idx) |
|---|
| 795 |
nil) |
|---|
| 796 |
|
|---|
| 797 |
|
|---|
| 798 |
(defun ccl-compile-end (cmd) |
|---|
| 799 |
(if (/= (length cmd) 1) |
|---|
| 800 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 801 |
(ccl-embed-code 'end 0 0) |
|---|
| 802 |
t) |
|---|
| 803 |
|
|---|
| 804 |
|
|---|
| 805 |
(defun ccl-compile-read-multibyte-character (cmd) |
|---|
| 806 |
(if (/= (length cmd) 3) |
|---|
| 807 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 808 |
(let ((RRR (nth 1 cmd)) |
|---|
| 809 |
(rrr (nth 2 cmd))) |
|---|
| 810 |
(ccl-check-register rrr cmd) |
|---|
| 811 |
(ccl-check-register RRR cmd) |
|---|
| 812 |
(ccl-embed-extended-command 'read-multibyte-character rrr RRR 0)) |
|---|
| 813 |
nil) |
|---|
| 814 |
|
|---|
| 815 |
|
|---|
| 816 |
(defun ccl-compile-write-multibyte-character (cmd) |
|---|
| 817 |
(if (/= (length cmd) 3) |
|---|
| 818 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 819 |
(let ((RRR (nth 1 cmd)) |
|---|
| 820 |
(rrr (nth 2 cmd))) |
|---|
| 821 |
(ccl-check-register rrr cmd) |
|---|
| 822 |
(ccl-check-register RRR cmd) |
|---|
| 823 |
(ccl-embed-extended-command 'write-multibyte-character rrr RRR 0)) |
|---|
| 824 |
nil) |
|---|
| 825 |
|
|---|
| 826 |
|
|---|
| 827 |
(defun ccl-compile-translate-character (cmd) |
|---|
| 828 |
(if (/= (length cmd) 4) |
|---|
| 829 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 830 |
(let ((Rrr (nth 1 cmd)) |
|---|
| 831 |
(RRR (nth 2 cmd)) |
|---|
| 832 |
(rrr (nth 3 cmd))) |
|---|
| 833 |
(ccl-check-register rrr cmd) |
|---|
| 834 |
(ccl-check-register RRR cmd) |
|---|
| 835 |
(cond ((and (symbolp Rrr) (not (get Rrr 'ccl-register-number))) |
|---|
| 836 |
(ccl-embed-extended-command 'translate-character-const-tbl |
|---|
| 837 |
rrr RRR 0) |
|---|
| 838 |
(ccl-embed-symbol Rrr 'translation-table-id)) |
|---|
| 839 |
(t |
|---|
| 840 |
(ccl-check-register Rrr cmd) |
|---|
| 841 |
(ccl-embed-extended-command 'translate-character rrr RRR Rrr)))) |
|---|
| 842 |
nil) |
|---|
| 843 |
|
|---|
| 844 |
|
|---|
| 845 |
(defun ccl-compile-lookup-integer (cmd) |
|---|
| 846 |
(if (/= (length cmd) 4) |
|---|
| 847 |
(error "CCL: Invalid number of arguments: %s" cmd)) |
|---|
| 848 |
(let ((Rrr (nth 1 cmd)) |
|---|
| 849 |
(RRR (nth 2 cmd)) |
|---|
| 850 |
(rrr (nth 3 cmd))) |
|---|
| 851 |
(ccl-check-register RRR cmd) |
|---|
| 852 |
(ccl-check-register rrr cmd) |
|---|
| 853 |
(cond ((and (symbolp Rrr) (not (get Rrr 'ccl-register-number))) |
|---|
| 854 |
(ccl-embed-extended-command 'lookup-int-const-tbl |
|---|
| 855 |
rrr RRR 0) |
|---|
| 856 |
(ccl-embed-symbol Rrr 'translation-hash-table-id)) |
|---|
| 857 |
(t |
|---|
| 858 |
(error "CCL: non-constant table: %s&quo |
|---|