comparison lisp/international/ccl.el @ 30845:dcfcae58d8d6

(declare-ccl-program): Docstring modified. (ccl-execute-with-args): Likewise.
author Kenichi Handa <handa@m17n.org>
date Wed, 16 Aug 2000 10:57:57 +0000
parents b37405134317
children 496f65930f98
comparison
equal deleted inserted replaced
30844:947edf38ac6f 30845:dcfcae58d8d6
35 ;; However, since CCL is designed as a powerful programming language, 35 ;; However, since CCL is designed as a powerful programming language,
36 ;; it can be used for more generic calculation. For instance, 36 ;; it can be used for more generic calculation. For instance,
37 ;; combination of three or more arithmetic operations can be 37 ;; combination of three or more arithmetic operations can be
38 ;; calculated faster than Emacs Lisp. 38 ;; calculated faster than Emacs Lisp.
39 ;; 39 ;;
40 ;; Here's the syntax of CCL program in BNF notation. 40 ;; Syntax and semantics of CCL program is described in the
41 ;; 41 ;; documentation of `define-ccl-program'.
42 ;; CCL_PROGRAM :=
43 ;; (BUFFER_MAGNIFICATION
44 ;; CCL_MAIN_BLOCK
45 ;; [ CCL_EOF_BLOCK ])
46 ;;
47 ;; BUFFER_MAGNIFICATION := integer
48 ;; CCL_MAIN_BLOCK := CCL_BLOCK
49 ;; CCL_EOF_BLOCK := CCL_BLOCK
50 ;;
51 ;; CCL_BLOCK :=
52 ;; STATEMENT | (STATEMENT [STATEMENT ...])
53 ;; STATEMENT :=
54 ;; SET | IF | BRANCH | LOOP | REPEAT | BREAK | READ | WRITE | CALL
55 ;;
56 ;; SET :=
57 ;; (REG = EXPRESSION)
58 ;; | (REG ASSIGNMENT_OPERATOR EXPRESSION)
59 ;; | integer
60 ;;
61 ;; EXPRESSION := ARG | (EXPRESSION OPERATOR ARG)
62 ;;
63 ;; IF := (if EXPRESSION CCL_BLOCK CCL_BLOCK)
64 ;; BRANCH := (branch EXPRESSION CCL_BLOCK [CCL_BLOCK ...])
65 ;; LOOP := (loop STATEMENT [STATEMENT ...])
66 ;; BREAK := (break)
67 ;; REPEAT :=
68 ;; (repeat)
69 ;; | (write-repeat [REG | integer | string])
70 ;; | (write-read-repeat REG [integer | ARRAY])
71 ;; READ :=
72 ;; (read REG ...)
73 ;; | (read-if (REG OPERATOR ARG) CCL_BLOCK CCL_BLOCK)
74 ;; | (read-branch REG CCL_BLOCK [CCL_BLOCK ...])
75 ;; | (read-multibyte-character REG {charset} REG {code-point})
76 ;; WRITE :=
77 ;; (write REG ...)
78 ;; | (write EXPRESSION)
79 ;; | (write integer) | (write string) | (write REG ARRAY)
80 ;; | string
81 ;; | (write-multibyte-character REG(charset) REG(codepoint))
82 ;; TRANSLATE :=
83 ;; (translate-character REG(table) REG(charset) REG(codepoint))
84 ;; | (translate-character SYMBOL REG(charset) REG(codepoint))
85 ;; MAP :=
86 ;; (iterate-multiple-map REG REG MAP-IDs)
87 ;; | (map-multiple REG REG (MAP-SET))
88 ;; | (map-single REG REG MAP-ID)
89 ;; MAP-IDs := MAP-ID ...
90 ;; MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
91 ;; MAP-ID := integer
92 ;;
93 ;; CALL := (call ccl-program-name)
94 ;; END := (end)
95 ;;
96 ;; REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7
97 ;; ARG := REG | integer
98 ;; OPERATOR :=
99 ;; + | - | * | / | % | & | '|' | ^ | << | >> | <8 | >8 | //
100 ;; | < | > | == | <= | >= | != | de-sjis | en-sjis
101 ;; ASSIGNMENT_OPERATOR :=
102 ;; += | -= | *= | /= | %= | &= | '|=' | ^= | <<= | >>=
103 ;; ARRAY := '[' integer ... ']'
104 42
105 ;;; Code: 43 ;;; Code:
106 44
107 (defgroup ccl nil 45 (defgroup ccl nil
108 "CCL (Code Conversion Language) compiler." 46 "CCL (Code Conversion Language) compiler."
1303 `(put ',name 'ccl-program-idx (register-ccl-program ',name ,vector))) 1241 `(put ',name 'ccl-program-idx (register-ccl-program ',name ,vector)))
1304 1242
1305 ;;;###autoload 1243 ;;;###autoload
1306 (defmacro define-ccl-program (name ccl-program &optional doc) 1244 (defmacro define-ccl-program (name ccl-program &optional doc)
1307 "Set NAME the compiled code of CCL-PROGRAM. 1245 "Set NAME the compiled code of CCL-PROGRAM.
1308 CCL-PROGRAM is `eval'ed before being handed to the CCL compiler `ccl-compile'. 1246
1309 The compiled code is a vector of integers." 1247 CCL-PROGRAM is has this form:
1248 (BUFFER_MAGNIFICATION
1249 CCL_MAIN_CODE
1250 [ CCL_EOF_CODE ])
1251
1252 BUFFER_MAGNIFICATION is an integer value specifying the approximate
1253 output buffer magnification size compared with the bytes of input data
1254 text. If the value is zero, the CCL program can't execute `read' and
1255 `write' commands.
1256
1257 CCL_MAIN_CODE and CCL_EOF_CODE are CCL program codes. CCL_MAIN_CODE
1258 executed at first. If there's no more input data when `read' command
1259 is executed in CCL_MAIN_CODE, CCL_EOF_CODE is executed. If
1260 CCL_MAIN_CODE is terminated, CCL_EOF_CODE is not executed.
1261
1262 Here's the syntax of CCL program code in BNF notation. The lines
1263 starting by two semicolons (and optional leading spaces) describe the
1264 semantics.
1265
1266 CCL_MAIN_CODE := CCL_BLOCK
1267
1268 CCL_EOF_CODE := CCL_BLOCK
1269
1270 CCL_BLOCK := STATEMENT | (STATEMENT [STATEMENT ...])
1271
1272 STATEMENT :=
1273 SET | IF | BRANCH | LOOP | REPEAT | BREAK | READ | WRITE | CALL
1274 | TRANSLATE | END
1275
1276 SET := (REG = EXPRESSION)
1277 | (REG ASSIGNMENT_OPERATOR EXPRESSION)
1278 ;; The following form is the same as (r0 = integer).
1279 | integer
1280
1281 EXPRESSION := ARG | (EXPRESSION OPERATOR ARG)
1282
1283 ;; Evaluate EXPRESSION. If the result is nonzeor, execute
1284 ;; CCL_BLOCK_0. Otherwise, execute CCL_BLOCK_1.
1285 IF := (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1)
1286
1287 ;; Evaluate EXPRESSION. Provided that the result is N, execute
1288 ;; CCL_BLOCK_N.
1289 BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...])
1290
1291 ;; Execute STATEMENTs until (break) or (end) is executed.
1292 LOOP := (loop STATEMENT [STATEMENT ...])
1293
1294 ;; Terminate the most inner loop.
1295 BREAK := (break)
1296
1297 REPEAT :=
1298 ;; Jump to the head of the most inner loop.
1299 (repeat)
1300 ;; Same as: ((write [REG | integer | string])
1301 ;; (repeat))
1302 | (write-repeat [REG | integer | string])
1303 ;; Same as: ((write REG [ARRAY])
1304 ;; (read REG)
1305 ;; (repeat))
1306 | (write-read-repeat REG [ARRAY])
1307 ;; Same as: ((write integer)
1308 ;; (read REG)
1309 ;; (repeat))
1310 | (write-read-repeat REG integer)
1311
1312 READ := ;; Set REG_0 to a byte read from the input text, set REG_1
1313 ;; to the next byte read, and so on.
1314 (read REG_0 [REG_1 ...])
1315 ;; Same as: ((read REG)
1316 ;; (if (REG OPERATOR ARG) CCL_BLOCK_0 CCL_BLOCK_1))
1317 | (read-if (REG OPERATOR ARG) CCL_BLOCK_0 CCL_BLOCK_1)
1318 ;; Same as: ((read REG)
1319 ;; (branch REG CCL_BLOCK_0 [CCL_BLOCK_1 ...]))
1320 | (read-branch REG CCL_BLOCK_0 [CCL_BLOCK_1 ...])
1321 ;; Read a character from the input text while parsing
1322 ;; multibyte representation, set REG_0 to the charset ID of
1323 ;; the character, set REG_1 to the code point of the
1324 ;; character. If the dimension of charset is two, set REG_1
1325 ;; to ((CODE0 << 8) | CODE1), where CODE0 is the first code
1326 ;; point and CODE1 is the second code point.
1327 | (read-multibyte-character REG_0 REG_1)
1328
1329 WRITE :=
1330 ;; Write REG_0, REG_1, ... to the output buffer. If REG_N is
1331 ;; a multibyte character, write the corresponding multibyte
1332 ;; representation.
1333 (write REG_0 [REG_1 ...])
1334 ;; Same as: ((r7 = EXPRESSION)
1335 ;; (write r7))
1336 | (write EXPRESSION)
1337 ;; Write the value of `integer' to the output buffer. If it
1338 ;; is a multibyte character, write the corresponding multibyte
1339 ;; representation.
1340 | (write integer)
1341 ;; Write the byte sequence of `string' as is to the output
1342 ;; buffer.
1343 | (write string)
1344 ;; Same as: (write string)
1345 | string
1346 ;; Provided that the value of REG is N, write Nth element of
1347 ;; ARRAY to the output buffer. If it is a multibyte
1348 ;; character, write the corresponding multibyte
1349 ;; representation.
1350 | (write REG ARRAY)
1351 ;; Write a multibyte representation of a character whose
1352 ;; charset ID is REG_0 and code point is REG_1. If the
1353 ;; dimension of the charset is two, REG_1 should be ((CODE0 <<
1354 ;; 8) | CODE1), where CODE0 is the first code point and CODE1
1355 ;; is the second code point of the character.
1356 | (write-multibyte-character REG_0 REG_1)
1357
1358 ;; Call CCL program whose name is ccl-program-name.
1359 CALL := (call ccl-program-name)
1360
1361 ;; Terminate the CCL program.
1362 END := (end)
1363
1364 ;; CCL registers that can contain any integer value. As r7 is also
1365 ;; used by CCL interpreter, its value is changed unexpectedly.
1366 REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7
1367
1368 ARG := REG | integer
1369
1370 OPERATOR :=
1371 ;; Normal arithmethic operators (same meaning as C code).
1372 + | - | * | / | %
1373
1374 ;; Bitwize operators (same meaning as C code)
1375 | & | `|' | ^
1376
1377 ;; Shifting operators (same meaning as C code)
1378 | << | >>
1379
1380 ;; (REG = ARG_0 <8 ARG_1) means:
1381 ;; (REG = ((ARG_0 << 8) | ARG_1))
1382 | <8
1383
1384 ;; (REG = ARG_0 >8 ARG_1) means:
1385 ;; ((REG = (ARG_0 >> 8))
1386 ;; (r7 = (ARG_0 & 255)))
1387 | >8
1388
1389 ;; (REG = ARG_0 // ARG_1) means:
1390 ;; ((REG = (ARG_0 / ARG_1))
1391 ;; (r7 = (ARG_0 % ARG_1)))
1392 | //
1393
1394 ;; Normal comparing operators (same meaning as C code)
1395 | < | > | == | <= | >= | !=
1396
1397 ;; If ARG_0 and ARG_1 are higher and lower byte of Shift-JIS
1398 ;; code, and CHAR is the corresponding JISX0208 character,
1399 ;; (REG = ARG_0 de-sjis ARG_1) means:
1400 ;; ((REG = CODE0)
1401 ;; (r7 = CODE1))
1402 ;; where CODE0 is the first code point of CHAR, CODE1 is the
1403 ;; second code point of CHAR.
1404 | de-sjis
1405
1406 ;; If ARG_0 and ARG_1 are the first and second code point of
1407 ;; JISX0208 character CHAR, and SJIS is the correponding
1408 ;; Shift-JIS code,
1409 ;; (REG = ARG_0 en-sjis ARG_1) means:
1410 ;; ((REG = HIGH)
1411 ;; (r7 = LOW))
1412 ;; where HIGH is the higher byte of SJIS, LOW is the lower
1413 ;; byte of SJIS.
1414 | en-sjis
1415
1416 ASSIGNMENT_OPERATOR :=
1417 ;; Same meaning as C code
1418 += | -= | *= | /= | %= | &= | `|=' | ^= | <<= | >>=
1419
1420 ;; (REG <8= ARG) is the same as:
1421 ;; ((REG <<= 8)
1422 ;; (REG |= ARG))
1423 | <8=
1424
1425 ;; (REG >8= ARG) is the same as:
1426 ;; ((r7 = (REG & 255))
1427 ;; (REG >>= 8))
1428
1429 ;; (REG //= ARG) is the same as:
1430 ;; ((r7 = (REG % ARG))
1431 ;; (REG /= ARG))
1432 | //=
1433
1434 ARRAY := `[' integer ... `]'
1435
1436
1437 TRANSLATE :=
1438 (translate-character REG(table) REG(charset) REG(codepoint))
1439 | (translate-character SYMBOL REG(charset) REG(codepoint))
1440 MAP :=
1441 (iterate-multiple-map REG REG MAP-IDs)
1442 | (map-multiple REG REG (MAP-SET))
1443 | (map-single REG REG MAP-ID)
1444 MAP-IDs := MAP-ID ...
1445 MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
1446 MAP-ID := integer
1447 "
1310 `(let ((prog ,(ccl-compile (eval ccl-program)))) 1448 `(let ((prog ,(ccl-compile (eval ccl-program))))
1311 (defconst ,name prog ,doc) 1449 (defconst ,name prog ,doc)
1312 (put ',name 'ccl-program-idx (register-ccl-program ',name prog)) 1450 (put ',name 'ccl-program-idx (register-ccl-program ',name prog))
1313 nil)) 1451 nil))
1314 1452
1327 ,ccl-program))) 1465 ,ccl-program)))
1328 1466
1329 ;;;###autoload 1467 ;;;###autoload
1330 (defun ccl-execute-with-args (ccl-prog &rest args) 1468 (defun ccl-execute-with-args (ccl-prog &rest args)
1331 "Execute CCL-PROGRAM with registers initialized by the remaining args. 1469 "Execute CCL-PROGRAM with registers initialized by the remaining args.
1332 The return value is a vector of resulting CCL registers." 1470 The return value is a vector of resulting CCL registers.
1471
1472 See the documentation of `define-ccl-program' for the detail of CCL program."
1333 (let ((reg (make-vector 8 0)) 1473 (let ((reg (make-vector 8 0))
1334 (i 0)) 1474 (i 0))
1335 (while (and args (< i 8)) 1475 (while (and args (< i 8))
1336 (if (not (integerp (car args))) 1476 (if (not (integerp (car args)))
1337 (error "Arguments should be integer")) 1477 (error "Arguments should be integer"))