diff options
| author | Kenichi Handa | 2000-08-16 10:57:57 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-08-16 10:57:57 +0000 |
| commit | 07fd074eb839fb01fdc70cfde3d6e59f667917c8 (patch) | |
| tree | f244224d6be1856d8ef7273fe8d23a3144a67f1d | |
| parent | c7c386ad4726a6d31a2ee9ef9392db2da17e9026 (diff) | |
| download | emacs-07fd074eb839fb01fdc70cfde3d6e59f667917c8.tar.gz emacs-07fd074eb839fb01fdc70cfde3d6e59f667917c8.zip | |
(declare-ccl-program): Docstring modified.
(ccl-execute-with-args): Likewise.
| -rw-r--r-- | lisp/international/ccl.el | 274 |
1 files changed, 207 insertions, 67 deletions
diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el index e357e367cf7..e1f0250aa2b 100644 --- a/lisp/international/ccl.el +++ b/lisp/international/ccl.el | |||
| @@ -37,70 +37,8 @@ | |||
| 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 | ||
| @@ -1305,8 +1243,208 @@ Optional arg VECTOR is a compiled CCL code of the CCL program." | |||
| 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)) |
| @@ -1329,7 +1467,9 @@ register CCL-PROGRAM by name NAME, and return NAME." | |||
| 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)) |