aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2000-08-16 10:57:57 +0000
committerKenichi Handa2000-08-16 10:57:57 +0000
commit07fd074eb839fb01fdc70cfde3d6e59f667917c8 (patch)
treef244224d6be1856d8ef7273fe8d23a3144a67f1d
parentc7c386ad4726a6d31a2ee9ef9392db2da17e9026 (diff)
downloademacs-07fd074eb839fb01fdc70cfde3d6e59f667917c8.tar.gz
emacs-07fd074eb839fb01fdc70cfde3d6e59f667917c8.zip
(declare-ccl-program): Docstring modified.
(ccl-execute-with-args): Likewise.
-rw-r--r--lisp/international/ccl.el274
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.
1308CCL-PROGRAM is `eval'ed before being handed to the CCL compiler `ccl-compile'. 1246
1309The compiled code is a vector of integers." 1247CCL-PROGRAM is has this form:
1248 (BUFFER_MAGNIFICATION
1249 CCL_MAIN_CODE
1250 [ CCL_EOF_CODE ])
1251
1252BUFFER_MAGNIFICATION is an integer value specifying the approximate
1253output buffer magnification size compared with the bytes of input data
1254text. If the value is zero, the CCL program can't execute `read' and
1255`write' commands.
1256
1257CCL_MAIN_CODE and CCL_EOF_CODE are CCL program codes. CCL_MAIN_CODE
1258executed at first. If there's no more input data when `read' command
1259is executed in CCL_MAIN_CODE, CCL_EOF_CODE is executed. If
1260CCL_MAIN_CODE is terminated, CCL_EOF_CODE is not executed.
1261
1262Here's the syntax of CCL program code in BNF notation. The lines
1263starting by two semicolons (and optional leading spaces) describe the
1264semantics.
1265
1266CCL_MAIN_CODE := CCL_BLOCK
1267
1268CCL_EOF_CODE := CCL_BLOCK
1269
1270CCL_BLOCK := STATEMENT | (STATEMENT [STATEMENT ...])
1271
1272STATEMENT :=
1273 SET | IF | BRANCH | LOOP | REPEAT | BREAK | READ | WRITE | CALL
1274 | TRANSLATE | END
1275
1276SET := (REG = EXPRESSION)
1277 | (REG ASSIGNMENT_OPERATOR EXPRESSION)
1278 ;; The following form is the same as (r0 = integer).
1279 | integer
1280
1281EXPRESSION := ARG | (EXPRESSION OPERATOR ARG)
1282
1283;; Evaluate EXPRESSION. If the result is nonzeor, execute
1284;; CCL_BLOCK_0. Otherwise, execute CCL_BLOCK_1.
1285IF := (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1)
1286
1287;; Evaluate EXPRESSION. Provided that the result is N, execute
1288;; CCL_BLOCK_N.
1289BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...])
1290
1291;; Execute STATEMENTs until (break) or (end) is executed.
1292LOOP := (loop STATEMENT [STATEMENT ...])
1293
1294;; Terminate the most inner loop.
1295BREAK := (break)
1296
1297REPEAT :=
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
1312READ := ;; 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
1329WRITE :=
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.
1359CALL := (call ccl-program-name)
1360
1361;; Terminate the CCL program.
1362END := (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.
1366REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7
1367
1368ARG := REG | integer
1369
1370OPERATOR :=
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
1416ASSIGNMENT_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
1434ARRAY := `[' integer ... `]'
1435
1436
1437TRANSLATE :=
1438 (translate-character REG(table) REG(charset) REG(codepoint))
1439 | (translate-character SYMBOL REG(charset) REG(codepoint))
1440MAP :=
1441 (iterate-multiple-map REG REG MAP-IDs)
1442 | (map-multiple REG REG (MAP-SET))
1443 | (map-single REG REG MAP-ID)
1444MAP-IDs := MAP-ID ...
1445MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
1446MAP-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.
1332The return value is a vector of resulting CCL registers." 1470The return value is a vector of resulting CCL registers.
1471
1472See 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))