aboutsummaryrefslogtreecommitdiffstats
path: root/po/tr.po
diff options
context:
space:
mode:
Diffstat (limited to 'po/tr.po')
-rw-r--r--po/tr.po107
1 files changed, 63 insertions, 44 deletions
diff --git a/po/tr.po b/po/tr.po
index 2b61fd6..2b18e20 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: isodumper\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-06-30 17:50+0200\n"
+"POT-Creation-Date: 2014-07-07 00:05+0200\n"
"PO-Revision-Date: 2014-07-02 21:31+0000\n"
"Last-Translator: Atilla Öntaş <tarakbumba@gmail.com>\n"
"Language-Team: Turkish (http://www.transifex.com/projects/p/mageia/language/"
@@ -22,116 +22,120 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: lib/isodumper.py:153
+#: lib/isodumper.py:152
msgid "Mb"
msgstr "Mb"
-#: lib/isodumper.py:162 lib/isodumper.py:289
+#: lib/isodumper.py:161 lib/isodumper.py:299
msgid "Target Device: "
msgstr "Hedef Aygıt: "
-#: lib/isodumper.py:241
+#: lib/isodumper.py:184
+msgid "Backup in: "
+msgstr ""
+
+#: lib/isodumper.py:247
msgid "The device was formatted successfully."
msgstr "Aygıt başarıyla biçimlendirildi."
-#: lib/isodumper.py:245
+#: lib/isodumper.py:251
msgid "An error occured while creating a partition."
msgstr "Bir disk bölümü oluşturulurken hata meydana geldi."
-#: lib/isodumper.py:247
+#: lib/isodumper.py:253
msgid "Authentication error."
msgstr "Yetkilendirme hatası."
-#: lib/isodumper.py:249
+#: lib/isodumper.py:255
msgid "An error occurred."
msgstr "Bir hata oluştu."
-#: lib/isodumper.py:272 share/isodumper/isodumper.glade.h:32
+#: lib/isodumper.py:278 share/isodumper/isodumper.glade.h:32
msgid "Backup in:"
msgstr "Şuraya yedekle:"
-#: lib/isodumper.py:288
+#: lib/isodumper.py:298
msgid "Image: "
msgstr "Kalıp: "
-#: lib/isodumper.py:292
+#: lib/isodumper.py:302
msgid "The device is too small to contain the ISO file."
msgstr "Aygıt ISO dosyasını içermek için çok küçük"
-#: lib/isodumper.py:299
+#: lib/isodumper.py:309
msgid "The device is bigger than 32 Gbytes. Are you sure you want use it?"
msgstr ""
"Aygıt 32 Gbayttan büyük. Bu aygıtı kullanmak istediğinize emin misiniz?"
-#: lib/isodumper.py:326
+#: lib/isodumper.py:336
msgid "Unmounting all partitions of "
msgstr "Tüm bölümlerden çıkart "
-#: lib/isodumper.py:328
+#: lib/isodumper.py:338
msgid "Trying to unmount "
msgstr "Çıkarmaya çalışıyor "
-#: lib/isodumper.py:334
+#: lib/isodumper.py:344
msgid " was terminated by signal "
msgstr " Sinyal tarafından sonlandırıldı"
-#: lib/isodumper.py:334 lib/isodumper.py:340
+#: lib/isodumper.py:344 lib/isodumper.py:350
msgid "Error, umount "
msgstr "Hata, umount "
-#: lib/isodumper.py:338
+#: lib/isodumper.py:348
msgid " successfully unmounted"
msgstr " başarıyla çıkarıldı"
-#: lib/isodumper.py:340
+#: lib/isodumper.py:350
msgid " returned "
msgstr " döndü "
-#: lib/isodumper.py:343
+#: lib/isodumper.py:353
msgid "Execution failed: "
msgstr "Çalıştırma başarısız: "
-#: lib/isodumper.py:351
+#: lib/isodumper.py:361
msgid "Could not read mtab !"
msgstr "mtab okunamadı !"
-#: lib/isodumper.py:360 lib/isodumper.py:384
+#: lib/isodumper.py:370 lib/isodumper.py:394
msgid "Reading error."
msgstr "Okuma hatası."
-#: lib/isodumper.py:366
+#: lib/isodumper.py:376
msgid "You have not the rights for writing on the device"
msgstr "Aygıta yazma hakkına sahip değilsiniz"
-#: lib/isodumper.py:372 lib/isodumper.py:373
+#: lib/isodumper.py:382 lib/isodumper.py:383
msgid " to "
msgstr " şuna "
-#: lib/isodumper.py:372
+#: lib/isodumper.py:382
msgid "Writing "
msgstr "Yazdırıyor "
-#: lib/isodumper.py:373
+#: lib/isodumper.py:383
msgid "Executing copy from "
msgstr "Kalıptan kopyalama çalıştırılıyor"
-#: lib/isodumper.py:389 lib/isodumper.py:402 lib/isodumper.py:411
+#: lib/isodumper.py:399 lib/isodumper.py:412 lib/isodumper.py:421
msgid "Writing error."
msgstr "Yazma hatası."
-#: lib/isodumper.py:394
+#: lib/isodumper.py:404
msgid "Wrote: "
msgstr "Yazıldı: "
-#: lib/isodumper.py:406
+#: lib/isodumper.py:416
msgid " successfully written to "
msgstr " başarıyla aygıta yazıldı "
-#: lib/isodumper.py:406 lib/isodumper.py:495
+#: lib/isodumper.py:416 lib/isodumper.py:507
msgid "Image "
msgstr "İmaj "
-#: lib/isodumper.py:407
+#: lib/isodumper.py:417
msgid "Bytes written: "
msgstr "Yazılan bayt:"
@@ -155,13 +159,10 @@ msgstr ""
#: share/isodumper/isodumper.glade.h:2
msgid ""
-"Writing is in progress. Exiting will occur that the device will be "
-"unusable.\n"
-"Are you sure you want to quit during writing on the device?"
+"Writing is in progress. Exiting during writing will occur that the device or "
+"the backup will be unusable.\n"
+"Are you sure you want to quit during writing?"
msgstr ""
-"Yazma işlemi sürüyor. Uygulamadan çıkmak aygıtı kullanılamaz hale "
-"getirecektir.\n"
-"Aygıta yazma sürerken çıkmak isteğidiğinize emin misiniz?"
#: share/isodumper/isodumper.glade.h:4
msgid ""
@@ -307,17 +308,35 @@ msgstr ""
#: share/isodumper/isodumper.glade.h:46
msgid ""
"<b>Success</b>\n"
-" The image was successfully written to the\n"
-" target device.\n"
+" The operation was successfully performed.\n"
" \n"
" You are free to unplug it now, a log isodumper.log \n"
" of the operation will be saved in your homedir/.isodumper/ when\n"
" you close the application."
msgstr ""
-"<b>Başarı</b>\n"
-" İmaj hedef aygıta başarılı bir şekilde\n"
-" yazıldı.\n"
-" \n"
-" Aygıtı çıkarabilirsiniz. İşleme dair bir isodumper.log kayıt.\n"
-" dosyası uygulama kapandığında kullanıcı dizini/.isodumper/ altına\n"
-" kaydedilecek."
+
+#~ msgid ""
+#~ "Writing is in progress. Exiting will occur that the device will be "
+#~ "unusable.\n"
+#~ "Are you sure you want to quit during writing on the device?"
+#~ msgstr ""
+#~ "Yazma işlemi sürüyor. Uygulamadan çıkmak aygıtı kullanılamaz hale "
+#~ "getirecektir.\n"
+#~ "Aygıta yazma sürerken çıkmak isteğidiğinize emin misiniz?"
+
+#~ msgid ""
+#~ "<b>Success</b>\n"
+#~ " The image was successfully written to the\n"
+#~ " target device.\n"
+#~ " \n"
+#~ " You are free to unplug it now, a log isodumper.log \n"
+#~ " of the operation will be saved in your homedir/.isodumper/ when\n"
+#~ " you close the application."
+#~ msgstr ""
+#~ "<b>Başarı</b>\n"
+#~ " İmaj hedef aygıta başarılı bir şekilde\n"
+#~ " yazıldı.\n"
+#~ " \n"
+#~ " Aygıtı çıkarabilirsiniz. İşleme dair bir isodumper.log kayıt.\n"
+#~ " dosyası uygulama kapandığında kullanıcı dizini/.isodumper/ altına\n"
+#~ " kaydedilecek."
60'>360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656

/* Copyright (c) 1998, 1999, 2001 John E. Davis
 * This file is part of the S-Lang library.
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Perl Artistic License.
 */

#include "slinclud.h"

#include <math.h>

#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif

#include "slang.h"
#include "_slang.h"

/*
 * This file defines binary and unary operations on all integer types.
 * Supported types include:
 *
 *    SLANG_CHAR_TYPE     (char)
 *    SLANG_SHORT_TYPE    (short)
 *    SLANG_INT_TYPE      (int)
 *    SLANG_LONG_TYPE     (long)
 *    SLANG_FLOAT_TYPE    (float)
 *    SLANG_DOUBLE_TYPE   (double)
 *
 * as well as unsigned types.  The result-type of an arithmentic operation
 * will depend upon the data types involved.  I am going to distinguish
 * between the boolean operations such as `and' and `or' from the arithmetic
 * operations such as `plus'.  Since the result of a boolean operation is
 * either 1 or 0, a boolean result will be represented by SLANG_CHAR_TYPE.
 * Ordinarily I would use an integer but for arrays it makes more sense to
 * use a character data type.
 *
 * So, the following will be assumed (`+' is any arithmetic operator)
 *
 *    char + char = int
 *    char|short + short = int
 *    char|short|int + int = int
 *    char|short|int|long + long = long
 *    char|short|int|long|float + float = float
 *    char|short|int|long|float|double + double = double
 *
 * In the actual implementation, a brute force approach is avoided.  Such
 * an approach would mean defining different functions for all possible
 * combinations of types.  Including the unsigned types, and not including
 * the complex number type, there are 10 arithmetic types and 10*10=100
 * different combinations of types.  Clearly this would be too much.
 *
 * One approach would be to define binary functions only between operands of
 * the same type and then convert types as appropriate.  This would require
 * just 6 such functions (int, uint, long, ulong, float, double).
 * However, many conversion functions are going to be required, particularly
 * since we are going to allow typecasting from one arithmetic to another.
 * Since the bit pattern of signed and unsigned types are the same, and only
 * the interpretation differs, there will be no functions to convert between
 * signed and unsigned forms of a given type.
 */

#define MAX_ARITHMETIC_TYPES	10

unsigned char _SLarith_Is_Arith_Type [256];

unsigned char _SLarith_Arith_Types[] =
{
   SLANG_CHAR_TYPE,
   SLANG_UCHAR_TYPE,
   SLANG_SHORT_TYPE,
   SLANG_USHORT_TYPE,
   SLANG_INT_TYPE,
   SLANG_UINT_TYPE,
   SLANG_LONG_TYPE,
   SLANG_ULONG_TYPE,
   SLANG_FLOAT_TYPE,
   SLANG_DOUBLE_TYPE,
   0
};

/* Here are a bunch of functions to convert from one type to another.  To
 * facilitate the process, a macros will be used.
 */

#define DEFUN_1(f,from_type,to_type) \
static void f (to_type *y, from_type *x, unsigned int n) \
{ \
   unsigned int i; \
   for (i = 0; i < n; i++) y[i] = (to_type) x[i]; \
}

#define DEFUN_2(f,from_type,to_type,copy_fun) \
static VOID_STAR f (VOID_STAR xp, unsigned int n) \
{ \
   from_type *x; \
   to_type *y; \
   x = (from_type *) xp; \
   if (NULL == (y = (to_type *) SLmalloc (sizeof (to_type) * n))) return NULL; \
   copy_fun (y, x, n); \
   return (VOID_STAR) y; \
}
typedef VOID_STAR (*Convert_Fun_Type)(VOID_STAR, unsigned int);

DEFUN_1(copy_char_to_char,char,char)
#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_char_to_short,char,short)
DEFUN_1(copy_char_to_ushort,char,unsigned short)
#else
# define copy_char_to_short	copy_char_to_int
# define copy_char_to_ushort	copy_char_to_uint
#endif
DEFUN_1(copy_char_to_int,char,int)
DEFUN_1(copy_char_to_uint,char,unsigned int)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_char_to_long,char,long)
DEFUN_1(copy_char_to_ulong,char,unsigned long)
#else
# define copy_char_to_long	copy_char_to_int
# define copy_char_to_ulong	copy_char_to_uint
#endif
DEFUN_1(copy_char_to_float,char,float)
DEFUN_1(copy_char_to_double,char,double)

#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_uchar_to_short,unsigned char,short)
DEFUN_1(copy_uchar_to_ushort,unsigned char,unsigned short)
#else
# define copy_uchar_to_short	copy_uchar_to_int
# define copy_uchar_to_ushort	copy_uchar_to_uint
#endif
DEFUN_1(copy_uchar_to_int,unsigned char,int)
DEFUN_1(copy_uchar_to_uint,unsigned char,unsigned int)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_uchar_to_long,unsigned char,long)
DEFUN_1(copy_uchar_to_ulong,unsigned char,unsigned long)
#else
# define copy_uchar_to_long	copy_uchar_to_int
# define copy_uchar_to_ulong	copy_uchar_to_uint
#endif
DEFUN_1(copy_uchar_to_float,unsigned char,float)
DEFUN_1(copy_uchar_to_double,unsigned char,double)

#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_short_to_char,short,char)
DEFUN_1(copy_short_to_uchar,short,unsigned char)
DEFUN_1(copy_short_to_short,short,short)
DEFUN_1(copy_short_to_int,short,int)
DEFUN_1(copy_short_to_uint,short,unsigned int)
DEFUN_1(copy_short_to_long,short,long)
DEFUN_1(copy_short_to_ulong,short,unsigned long)
DEFUN_1(copy_short_to_float,short,float)
DEFUN_1(copy_short_to_double,short,double)
DEFUN_1(copy_ushort_to_char,unsigned short,char)
DEFUN_1(copy_ushort_to_uchar,unsigned short,unsigned char)
DEFUN_1(copy_ushort_to_int,unsigned short,int)
DEFUN_1(copy_ushort_to_uint,unsigned short,unsigned int)
DEFUN_1(copy_ushort_to_long,unsigned short,long)
DEFUN_1(copy_ushort_to_ulong,unsigned short,unsigned long)
DEFUN_1(copy_ushort_to_float,unsigned short,float)
DEFUN_1(copy_ushort_to_double,unsigned short,double)
#else
# define copy_short_to_char	copy_int_to_char
# define copy_short_to_uchar	copy_int_to_uchar
# define copy_short_to_short	copy_int_to_int
# define copy_short_to_int	copy_int_to_int
# define copy_short_to_uint	copy_int_to_int
# define copy_short_to_long	copy_int_to_long
# define copy_short_to_ulong	copy_int_to_ulong
# define copy_short_to_float	copy_int_to_float
# define copy_short_to_double	copy_int_to_double
# define copy_ushort_to_char	copy_uint_to_char
# define copy_ushort_to_uchar	copy_uint_to_uchar
# define copy_ushort_to_int	copy_int_to_int
# define copy_ushort_to_uint	copy_int_to_int
# define copy_ushort_to_long	copy_uint_to_long
# define copy_ushort_to_ulong	copy_uint_to_ulong
# define copy_ushort_to_float	copy_uint_to_float
# define copy_ushort_to_double	copy_uint_to_double
#endif

DEFUN_1(copy_int_to_char,int,char)
DEFUN_1(copy_int_to_uchar,int,unsigned char)
DEFUN_1(copy_uint_to_char,unsigned int,char)
DEFUN_1(copy_uint_to_uchar,unsigned int,unsigned char)
#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_int_to_short,int,short)
DEFUN_1(copy_int_to_ushort,int,unsigned short)
DEFUN_1(copy_uint_to_short,unsigned int,short)
DEFUN_1(copy_uint_to_ushort,unsigned int,unsigned short)
#else
# define copy_int_to_short	copy_int_to_int
# define copy_int_to_ushort	copy_int_to_int
# define copy_uint_to_short	copy_int_to_int
# define copy_uint_to_ushort	copy_int_to_int
#endif
DEFUN_1(copy_int_to_int,int,int)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_int_to_long,int,long)
DEFUN_1(copy_int_to_ulong,int,unsigned long)
DEFUN_1(copy_uint_to_long,unsigned int,long)
DEFUN_1(copy_uint_to_ulong,unsigned int,unsigned long)
#else
# define copy_int_to_long	copy_int_to_int
# define copy_int_to_ulong	copy_int_to_int
# define copy_uint_to_long	copy_int_to_int
# define copy_uint_to_ulong	copy_int_to_int
#endif
DEFUN_1(copy_int_to_float,int,float)
DEFUN_1(copy_int_to_double,int,double)
DEFUN_1(copy_uint_to_float,unsigned int,float)
DEFUN_1(copy_uint_to_double,unsigned int,double)

#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_long_to_char,long,char)
DEFUN_1(copy_long_to_uchar,long,unsigned char)
DEFUN_1(copy_long_to_short,long,short)
DEFUN_1(copy_long_to_ushort,long,unsigned short)
DEFUN_1(copy_long_to_int,long,int)
DEFUN_1(copy_long_to_uint,long,unsigned int)
DEFUN_1(copy_long_to_long,long,long)
DEFUN_1(copy_long_to_float,long,float)
DEFUN_1(copy_long_to_double,long,double)
DEFUN_1(copy_ulong_to_char,unsigned long,char)
DEFUN_1(copy_ulong_to_uchar,unsigned long,unsigned char)
DEFUN_1(copy_ulong_to_short,unsigned long,short)
DEFUN_1(copy_ulong_to_ushort,unsigned long,unsigned short)
DEFUN_1(copy_ulong_to_int,unsigned long,int)
DEFUN_1(copy_ulong_to_uint,unsigned long,unsigned int)
DEFUN_1(copy_ulong_to_float,unsigned long,float)
DEFUN_1(copy_ulong_to_double,unsigned long,double)
#else
#define copy_long_to_char	copy_int_to_char
#define copy_long_to_uchar	copy_int_to_uchar
#define copy_long_to_short	copy_int_to_short
#define copy_long_to_ushort	copy_int_to_ushort
#define copy_long_to_int	copy_int_to_int
#define copy_long_to_uint	copy_int_to_int
#define copy_long_to_long	copy_int_to_int
#define copy_long_to_float	copy_int_to_float
#define copy_long_to_double	copy_int_to_double
#define copy_ulong_to_char	copy_uint_to_char
#define copy_ulong_to_uchar	copy_uint_to_uchar
#define copy_ulong_to_short	copy_uint_to_short
#define copy_ulong_to_ushort	copy_uint_to_ushort
#define copy_ulong_to_int	copy_int_to_int
#define copy_ulong_to_uint	copy_int_to_int
#define copy_ulong_to_float	copy_uint_to_float
#define copy_ulong_to_double	copy_uint_to_double
#endif

DEFUN_1(copy_float_to_char,float,char)
DEFUN_1(copy_float_to_uchar,float,unsigned char)
#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_float_to_short,float,short)
DEFUN_1(copy_float_to_ushort,float,unsigned short)
#else
# define copy_float_to_short	copy_float_to_int
# define copy_float_to_ushort	copy_float_to_uint
#endif
DEFUN_1(copy_float_to_int,float,int)
DEFUN_1(copy_float_to_uint,float,unsigned int)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_float_to_long,float,long)
DEFUN_1(copy_float_to_ulong,float,unsigned long)
#else
# define copy_float_to_long	copy_float_to_int
# define copy_float_to_ulong	copy_float_to_uint
#endif
DEFUN_1(copy_float_to_float,float,float)
DEFUN_1(copy_float_to_double,float,double)

DEFUN_1(copy_double_to_char,double,char)
DEFUN_1(copy_double_to_uchar,double,unsigned char)
#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_1(copy_double_to_short,double,short)
DEFUN_1(copy_double_to_ushort,double,unsigned short)
#else
# define copy_double_to_short	copy_double_to_int
# define copy_double_to_ushort	copy_double_to_uint
#endif
DEFUN_1(copy_double_to_int,double,int)
DEFUN_1(copy_double_to_uint,double,unsigned int)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_1(copy_double_to_long,double,long)
DEFUN_1(copy_double_to_ulong,double,unsigned long)
#else
# define copy_double_to_long	copy_double_to_int
# define copy_double_to_ulong	copy_double_to_uint
#endif
DEFUN_1(copy_double_to_float,double,float)
DEFUN_1(copy_double_to_double,double,double)

DEFUN_2(char_to_int,char,int,copy_char_to_int)
DEFUN_2(char_to_uint,char,unsigned int,copy_char_to_uint)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_2(char_to_long,char,long,copy_char_to_long)
DEFUN_2(char_to_ulong,char,unsigned long,copy_char_to_ulong)
#else
# define char_to_long	char_to_int
# define char_to_ulong	char_to_uint
#endif
DEFUN_2(char_to_float,char,float,copy_char_to_float)
DEFUN_2(char_to_double,char,double,copy_char_to_double)

DEFUN_2(uchar_to_int,unsigned char,int,copy_uchar_to_int)
DEFUN_2(uchar_to_uint,unsigned char,unsigned int,copy_uchar_to_uint)
#if SIZEOF_INT != SIZEOF_LONG
DEFUN_2(uchar_to_long,unsigned char,long,copy_uchar_to_long)
DEFUN_2(uchar_to_ulong,unsigned char,unsigned long,copy_uchar_to_ulong)
#else
# define uchar_to_long		uchar_to_int
# define uchar_to_ulong		uchar_to_uint
#endif
DEFUN_2(uchar_to_float,unsigned char,float,copy_uchar_to_float)
DEFUN_2(uchar_to_double,unsigned char,double,copy_uchar_to_double)

#if SIZEOF_INT != SIZEOF_SHORT
DEFUN_2(short_to_int,short,int,copy_short_to_int)
DEFUN_2(short_to_uint,short,unsigned int,copy_short_to_uint)
DEFUN_2(short_to_long,short,long,copy_short_to_long)
DEFUN_2(short_to_ulong,short,unsigned long,copy_short_to_ulong)
DEFUN_2(short_to_float,short,float,copy_short_to_float)
DEFUN_2(short_to_double,short,double,copy_short_to_double)
DEFUN_2(ushort_to_int,unsigned short,int,copy_ushort_to_int)
DEFUN_2(ushort_to_uint,unsigned short,unsigned int,copy_ushort_to_uint)
DEFUN_2(ushort_to_long,unsigned short,long,copy_ushort_to_long)
DEFUN_2(ushort_to_ulong,unsigned short,unsigned long,copy_ushort_to_ulong)
DEFUN_2(ushort_to_float,unsigned short,float,copy_ushort_to_float)
DEFUN_2(ushort_to_double,unsigned short,double,copy_ushort_to_double)
#else
# define short_to_int		NULL
# define short_to_uint		NULL
# define short_to_long		int_to_long
# define short_to_ulong		int_to_ulong
# define short_to_float		int_to_float
# define short_to_double	int_to_double
# define ushort_to_int		NULL
# define ushort_to_uint		NULL
# define ushort_to_long		uint_to_long
# define ushort_to_ulong	uint_to_ulong
# define ushort_to_float	uint_to_float
# define ushort_to_double	uint_to_double
#endif

#if SIZEOF_INT != SIZEOF_LONG
DEFUN_2(int_to_long,int,long,copy_int_to_long)
DEFUN_2(int_to_ulong,int,unsigned long,copy_int_to_ulong)
#else
# define int_to_long		NULL
# define int_to_ulong		NULL
#endif
DEFUN_2(int_to_float,int,float,copy_int_to_float)
DEFUN_2(int_to_double,int,double,copy_int_to_double)

#if SIZEOF_INT != SIZEOF_LONG
DEFUN_2(uint_to_long,unsigned int,long,copy_uint_to_long)
DEFUN_2(uint_to_ulong,unsigned int,unsigned long,copy_uint_to_ulong)
#else
# define uint_to_long		NULL
# define uint_to_ulong		NULL
#endif
DEFUN_2(uint_to_float,unsigned int,float,copy_uint_to_float)
DEFUN_2(uint_to_double,unsigned int,double,copy_uint_to_double)

#if SIZEOF_INT != SIZEOF_LONG
DEFUN_2(long_to_float,long,float,copy_long_to_float)
DEFUN_2(long_to_double,long,double,copy_long_to_double)
DEFUN_2(ulong_to_float,unsigned long,float,copy_ulong_to_float)
DEFUN_2(ulong_to_double,unsigned long,double,copy_ulong_to_double)
#else
# define long_to_float		int_to_float
# define long_to_double		int_to_double
# define ulong_to_float		uint_to_float
# define ulong_to_double	uint_to_double
#endif

DEFUN_2(float_to_double,float,double,copy_float_to_double)

#define TO_DOUBLE_FUN(name,type) \
static double name (VOID_STAR x) { return (double) *(type *) x; }
TO_DOUBLE_FUN(char_to_one_double,char)
TO_DOUBLE_FUN(uchar_to_one_double,unsigned char)
#if SIZEOF_INT != SIZEOF_SHORT
TO_DOUBLE_FUN(short_to_one_double,short)
TO_DOUBLE_FUN(ushort_to_one_double,unsigned short)
#else
# define short_to_one_double	int_to_one_double
# define ushort_to_one_double	uint_to_one_double
#endif
TO_DOUBLE_FUN(int_to_one_double,int)
TO_DOUBLE_FUN(uint_to_one_double,unsigned int)
#if SIZEOF_INT != SIZEOF_LONG
TO_DOUBLE_FUN(long_to_one_double,long)
TO_DOUBLE_FUN(ulong_to_one_double,unsigned long)
#else
# define long_to_one_double	int_to_one_double
# define ulong_to_one_double	uint_to_one_double
#endif
TO_DOUBLE_FUN(float_to_one_double,float)
TO_DOUBLE_FUN(double_to_one_double,double)

SLang_To_Double_Fun_Type
SLarith_get_to_double_fun (unsigned char type, unsigned int *sizeof_type)
{
   unsigned int da;
   SLang_To_Double_Fun_Type to_double;

   switch (type)
     {
      default:
	return NULL;

      case SLANG_CHAR_TYPE:
	da = sizeof (char); to_double = char_to_one_double;
	break;
      case SLANG_UCHAR_TYPE:
	da = sizeof (unsigned char); to_double = uchar_to_one_double;
	break;
      case SLANG_SHORT_TYPE:
	da = sizeof (short); to_double = short_to_one_double;
	break;
      case SLANG_USHORT_TYPE:
	da = sizeof (unsigned short); to_double = ushort_to_one_double;
	break;
      case SLANG_INT_TYPE:
	da = sizeof (int); to_double = int_to_one_double;
	break;
      case SLANG_UINT_TYPE:
	da = sizeof (unsigned int); to_double = uint_to_one_double;
	break;
      case SLANG_LONG_TYPE:
	da = sizeof (long); to_double = long_to_one_double;
	break;
      case SLANG_ULONG_TYPE:
	da = sizeof (unsigned long); to_double = ulong_to_one_double;
	break;
      case SLANG_FLOAT_TYPE:
	da = sizeof (float); to_double = float_to_one_double;
	break;
     case SLANG_DOUBLE_TYPE:
	da = sizeof (double); to_double = double_to_one_double;
	break;
     }

   if (sizeof_type != NULL) *sizeof_type = da;
   return to_double;
}

/* Each element of the matrix determines how the row maps onto the column.
 * That is, let the matrix be B_ij.  Where the i,j indices refer to
 * precedence of the type.  Then,
 * B_ij->copy_function copies type i to type j.  Similarly,
 * B_ij->convert_function mallocs a new array of type j and copies i to it.
 *
 * Since types are always converted to higher levels of precedence for binary
 * operations, many of the elements are NULL.
 *
 * Is the idea clear?
 */
typedef struct
{
   FVOID_STAR copy_function;
   Convert_Fun_Type convert_function;
}
Binary_Matrix_Type;

static Binary_Matrix_Type Binary_Matrix [MAX_ARITHMETIC_TYPES][MAX_ARITHMETIC_TYPES] =
{
     {
	  {(FVOID_STAR)copy_char_to_char, NULL},
	  {(FVOID_STAR)copy_char_to_char, NULL},
	{(FVOID_STAR) copy_char_to_short, NULL},
	{(FVOID_STAR) copy_char_to_ushort, NULL},
	{(FVOID_STAR) copy_char_to_int, char_to_int},
	{(FVOID_STAR) copy_char_to_uint, char_to_uint},
	{(FVOID_STAR) copy_char_to_long, char_to_long},
	{(FVOID_STAR) copy_char_to_ulong, char_to_ulong},
	{(FVOID_STAR) copy_char_to_float, char_to_float},
	{(FVOID_STAR) copy_char_to_double, char_to_double},
     },

     {
	  {(FVOID_STAR)copy_char_to_char, NULL},
	  {(FVOID_STAR)copy_char_to_char, NULL},
	{(FVOID_STAR) copy_uchar_to_short, NULL},
	{(FVOID_STAR) copy_uchar_to_ushort, NULL},
	{(FVOID_STAR) copy_uchar_to_int, uchar_to_int},
	{(FVOID_STAR) copy_uchar_to_uint, uchar_to_uint},
	{(FVOID_STAR) copy_uchar_to_long, uchar_to_long},
	{(FVOID_STAR) copy_uchar_to_ulong, uchar_to_ulong},
	{(FVOID_STAR) copy_uchar_to_float, uchar_to_float},
	{(FVOID_STAR) copy_uchar_to_double, uchar_to_double},
     },

     {
	{(FVOID_STAR) copy_short_to_char, NULL},
	{(FVOID_STAR) copy_short_to_uchar, NULL},
	{(FVOID_STAR) copy_short_to_short, NULL},
	{(FVOID_STAR) copy_short_to_short, NULL},
	{(FVOID_STAR) copy_short_to_int, short_to_int},
	{(FVOID_STAR) copy_short_to_uint, short_to_uint},
	{(FVOID_STAR) copy_short_to_long, short_to_long},
	{(FVOID_STAR) copy_short_to_ulong, short_to_ulong},
	{(FVOID_STAR) copy_short_to_float, short_to_float},
	{(FVOID_STAR) copy_short_to_double, short_to_double},
     },

     {
	{(FVOID_STAR) copy_ushort_to_char, NULL},
	{(FVOID_STAR) copy_ushort_to_uchar, NULL},
	{(FVOID_STAR) copy_short_to_short, NULL},
	{(FVOID_STAR) copy_short_to_short, NULL},
	{(FVOID_STAR) copy_ushort_to_int, ushort_to_int},
	{(FVOID_STAR) copy_ushort_to_uint, ushort_to_uint},
	{(FVOID_STAR) copy_ushort_to_long, ushort_to_long},
	{(FVOID_STAR) copy_ushort_to_ulong, ushort_to_ulong},
	{(FVOID_STAR) copy_ushort_to_float, ushort_to_float},
	{(FVOID_STAR) copy_ushort_to_double, ushort_to_double},
     },

     {
	{(FVOID_STAR) copy_int_to_char, NULL},
	{(FVOID_STAR) copy_int_to_uchar, NULL},
	{(FVOID_STAR) copy_int_to_short, NULL},
	{(FVOID_STAR) copy_int_to_ushort, NULL},
	{(FVOID_STAR) copy_int_to_int, NULL},
	{(FVOID_STAR) copy_int_to_int, NULL},
	{(FVOID_STAR) copy_int_to_long, int_to_long},
	{(FVOID_STAR) copy_int_to_ulong, int_to_ulong},
	{(FVOID_STAR) copy_int_to_float, int_to_float},
	{(FVOID_STAR) copy_int_to_double, int_to_double},
     },

     {
	{(FVOID_STAR) copy_uint_to_char, NULL},
	{(FVOID_STAR) copy_uint_to_uchar, NULL},
	{(FVOID_STAR) copy_uint_to_short, NULL},
	{(FVOID_STAR) copy_uint_to_ushort, NULL},
	{(FVOID_STAR) copy_int_to_int, NULL},
	{(FVOID_STAR) copy_int_to_int, NULL},
	{(FVOID_STAR) copy_uint_to_long, uint_to_long},
	{(FVOID_STAR) copy_uint_to_ulong, uint_to_ulong},
	{(FVOID_STAR) copy_uint_to_float, uint_to_float},
	{(FVOID_STAR) copy_uint_to_double, uint_to_double},
     },

     {
	{(FVOID_STAR) copy_long_to_char, NULL},
	{(FVOID_STAR) copy_long_to_uchar, NULL},
	{(FVOID_STAR) copy_long_to_short, NULL},
	{(FVOID_STAR) copy_long_to_ushort, NULL},
	{(FVOID_STAR) copy_long_to_int, NULL},
	{(FVOID_STAR) copy_long_to_uint, NULL},
	{(FVOID_STAR) copy_long_to_long, NULL},
	{(FVOID_STAR) copy_long_to_long, NULL},
	{(FVOID_STAR) copy_long_to_float, long_to_float},
	{(FVOID_STAR) copy_long_to_double, long_to_double},
     },

     {
	{(FVOID_STAR) copy_ulong_to_char, NULL},
	{(FVOID_STAR) copy_ulong_to_uchar, NULL},
	{(FVOID_STAR) copy_ulong_to_short, NULL},
	{(FVOID_STAR) copy_ulong_to_ushort, NULL},
	{(FVOID_STAR) copy_ulong_to_int, NULL},
	{(FVOID_STAR) copy_ulong_to_uint, NULL},
	{(FVOID_STAR) copy_long_to_long, NULL},
	{(FVOID_STAR) copy_long_to_long, NULL},
	{(FVOID_STAR) copy_ulong_to_float, ulong_to_float},
	{(FVOID_STAR) copy_ulong_to_double, ulong_to_double},
     },

     {
	{(FVOID_STAR) copy_float_to_char, NULL},
	{(FVOID_STAR) copy_float_to_uchar, NULL},
	{(FVOID_STAR) copy_float_to_short, NULL},
	{(FVOID_STAR) copy_float_to_ushort, NULL},
	{(FVOID_STAR) copy_float_to_int, NULL},
	{(FVOID_STAR) copy_float_to_uint, NULL},
	{(FVOID_STAR) copy_float_to_long, NULL},
	{(FVOID_STAR) copy_float_to_ulong, NULL},
	{(FVOID_STAR) copy_float_to_float, NULL},
	{(FVOID_STAR) copy_float_to_double, float_to_double},
     },

     {
	{(FVOID_STAR) copy_double_to_char, NULL},
	{(FVOID_STAR) copy_double_to_uchar, NULL},
	{(FVOID_STAR) copy_double_to_short, NULL},
	{(FVOID_STAR) copy_double_to_ushort, NULL},
	{(FVOID_STAR) copy_double_to_int, NULL},
	{(FVOID_STAR) copy_double_to_uint, NULL},
	{(FVOID_STAR) copy_double_to_long, NULL},
	{(FVOID_STAR) copy_double_to_ulong, NULL},
	{(FVOID_STAR) copy_double_to_float, NULL},
	{(FVOID_STAR) copy_double_to_double, NULL},
     }
};

#define GENERIC_BINARY_FUNCTION int_int_bin_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE int
#define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
#define POW_RESULT_TYPE double
#define ABS_FUNCTION abs
#define MOD_FUNCTION(a,b) ((a) % (b))
#define GENERIC_UNARY_FUNCTION int_unary_op
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define SCALAR_BINARY_FUNCTION int_int_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_int_obj(SLANG_INT_TYPE,(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
#define CMP_FUNCTION int_cmp_function
#include "slarith.inc"

#define GENERIC_BINARY_FUNCTION uint_uint_bin_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE unsigned int
#define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
#define POW_RESULT_TYPE double
#define MOD_FUNCTION(a,b) ((a) % (b))
#define GENERIC_UNARY_FUNCTION uint_unary_op
#define ABS_FUNCTION(a) (a)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
#define SCALAR_BINARY_FUNCTION uint_uint_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_int_obj(SLANG_UINT_TYPE,(int)(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
#define CMP_FUNCTION uint_cmp_function
#include "slarith.inc"

#if SIZEOF_LONG != SIZEOF_INT
#define GENERIC_BINARY_FUNCTION long_long_bin_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE long
#define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
#define POW_RESULT_TYPE double
#define MOD_FUNCTION(a,b) ((a) % (b))
#define GENERIC_UNARY_FUNCTION long_unary_op
#define ABS_FUNCTION(a) (((a) >= 0) ? (a) : -(a))
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define SCALAR_BINARY_FUNCTION long_long_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_long_obj(SLANG_LONG_TYPE,(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
#define CMP_FUNCTION long_cmp_function
#include "slarith.inc"

#define GENERIC_BINARY_FUNCTION ulong_ulong_bin_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE unsigned long
#define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
#define POW_RESULT_TYPE double
#define MOD_FUNCTION(a,b) ((a) % (b))
#define GENERIC_UNARY_FUNCTION ulong_unary_op
#define ABS_FUNCTION(a) (a)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
#define SCALAR_BINARY_FUNCTION ulong_ulong_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_long_obj(SLANG_ULONG_TYPE,(long)(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
#define CMP_FUNCTION ulong_cmp_function
#include "slarith.inc"
#else
#define long_long_bin_op	int_int_bin_op
#define ulong_ulong_bin_op	uint_uint_bin_op
#define long_unary_op		int_unary_op
#define ulong_unary_op		uint_unary_op
#define long_cmp_function	int_cmp_function
#define ulong_cmp_function	uint_cmp_function
#endif				       /* SIZEOF_INT != SIZEOF_LONG */

#define GENERIC_BINARY_FUNCTION float_float_bin_op
#define GENERIC_TYPE float
#define POW_FUNCTION(a,b) (float)pow((double)(a),(double)(b))
#define POW_RESULT_TYPE float
#define MOD_FUNCTION(a,b) (float)fmod((a),(b))
#define GENERIC_UNARY_FUNCTION float_unary_op
#define ABS_FUNCTION(a) (float)fabs((double) a)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define SCALAR_BINARY_FUNCTION float_float_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_float_obj(SLANG_FLOAT_TYPE,(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_float_obj(SLANG_FLOAT_TYPE, (x))
#define CMP_FUNCTION float_cmp_function
#include "slarith.inc"

#define GENERIC_BINARY_FUNCTION double_double_bin_op
#define GENERIC_TYPE double
#define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
#define POW_RESULT_TYPE double
#define MOD_FUNCTION(a,b) (float)fmod((a),(b))
#define GENERIC_UNARY_FUNCTION double_unary_op
#define ABS_FUNCTION(a) fabs(a)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define SCALAR_BINARY_FUNCTION double_double_scalar_bin_op
#define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE,(x))
#define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
#define CMP_FUNCTION double_cmp_function
#include "slarith.inc"

#define GENERIC_UNARY_FUNCTION char_unary_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE signed char
#define ABS_FUNCTION abs
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define CMP_FUNCTION char_cmp_function
#include "slarith.inc"

#define GENERIC_UNARY_FUNCTION uchar_unary_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE unsigned char
#define ABS_FUNCTION(x) (x)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
#define CMP_FUNCTION uchar_cmp_function
#include "slarith.inc"

#if SIZEOF_SHORT != SIZEOF_INT
#define GENERIC_UNARY_FUNCTION short_unary_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE short
#define ABS_FUNCTION abs
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
#define CMP_FUNCTION short_cmp_function
#include "slarith.inc"

#define GENERIC_UNARY_FUNCTION ushort_unary_op
#define GENERIC_BIT_OPERATIONS
#define GENERIC_TYPE unsigned short
#define ABS_FUNCTION(x) (x)
#define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
#define CMP_FUNCTION ushort_cmp_function
#include "slarith.inc"
#endif				       /* SIZEOF_INT != SIZEOF_SHORT */

/* Unfortunately, the numbers that were assigned to the data-types were
 * not well thought out.  So, I need to use the following table.
 */
#define MAXIMUM_ARITH_TYPE_VALUE	SLANG_FLOAT_TYPE
#define IS_INTEGER_TYPE(x) \
  (((x) <= MAXIMUM_ARITH_TYPE_VALUE) \
      && (Type_Precedence_Table[x] < 8) && (Type_Precedence_Table[x] != -1))
#define IS_ARITHMETIC_TYPE(x) \
  (((x) <= MAXIMUM_ARITH_TYPE_VALUE) && (Type_Precedence_Table[x] != -1))

#define LONG_PRECEDENCE_VALUE	6
#define FLOAT_PRECEDENCE_VALUE	8

static signed char Type_Precedence_Table [MAXIMUM_ARITH_TYPE_VALUE + 1] =
{
   -1,				       /* SLANG_UNDEFINED_TYPE */
   -1,				       /* SLANG_VOID_TYPE */
   4,				       /* SLANG_INT_TYPE */
   9,				       /* SLANG_DOUBLE_TYPE */
   0,				       /* SLANG_CHAR_TYPE */
   -1,				       /* SLANG_INTP_TYPE */
   -1,				       /* SLANG_REF_TYPE */
   -1,				       /* SLANG_COMPLEX_TYPE */
   -1,				       /* SLANG_NULL_TYPE */
   1,				       /* SLANG_UCHAR_TYPE */
   2,				       /* SLANG_SHORT_TYPE */
   3,				       /* SLANG_USHORT_TYPE */
   5,				       /* SLANG_UINT_TYPE */
   6,				       /* SLANG_LONG_TYPE */
   7,				       /* SLANG_ULONG_TYPE */
   -1,				       /* SLANG_STRING_TYPE */
   8				       /* SLANG_FLOAT_TYPE */
};

int _SLarith_get_precedence (unsigned char type)
{
   if (type > MAXIMUM_ARITH_TYPE_VALUE)
     return -1;

   return Type_Precedence_Table[type];
}

unsigned char _SLarith_promote_type (unsigned char t)
{
   switch (t)
     {
      case SLANG_FLOAT_TYPE:
      case SLANG_DOUBLE_TYPE:
      case SLANG_LONG_TYPE:
      case SLANG_ULONG_TYPE:
      case SLANG_INT_TYPE:
      case SLANG_UINT_TYPE:
	break;

      case SLANG_USHORT_TYPE:
#if SIZEOF_INT == SIZEOF_SHORT
	t = SLANG_UINT_TYPE;
	break;
#endif
	/* drop */
      case SLANG_CHAR_TYPE:
      case SLANG_UCHAR_TYPE:
      case SLANG_SHORT_TYPE:
      default:
	t = SLANG_INT_TYPE;
     }

   return t;
}

static unsigned char promote_to_common_type (unsigned char a, unsigned char b)
{
   a = _SLarith_promote_type (a);
   b = _SLarith_promote_type (b);

   return (Type_Precedence_Table[a] > Type_Precedence_Table[b]) ? a : b;
}

static int arith_bin_op_result (int op, unsigned char a_type, unsigned char b_type,
				unsigned char *c_type)
{
   switch (op)
     {
      case SLANG_EQ:
      case SLANG_NE:
      case SLANG_GT:
      case SLANG_GE:
      case SLANG_LT:
      case SLANG_LE:
      case SLANG_OR:
      case SLANG_AND:
	*c_type = SLANG_CHAR_TYPE;
	return 1;

      case SLANG_POW:
	if (SLANG_FLOAT_TYPE == promote_to_common_type (a_type, b_type))
	  *c_type = SLANG_FLOAT_TYPE;
	else
	  *c_type = SLANG_DOUBLE_TYPE;
	return 1;

      case SLANG_BAND:
      case SLANG_BXOR:
      case SLANG_BOR:
      case SLANG_SHL:
      case SLANG_SHR:
	/* The bit-level operations are defined just for integer types */
	if ((0 == IS_INTEGER_TYPE (a_type))
	    || (0 == IS_INTEGER_TYPE(b_type)))
	  return 0;
	break;

      default:
	break;
     }

   *c_type = promote_to_common_type (a_type, b_type);
   return 1;
}

typedef int (*Bin_Fun_Type) (int,
			     unsigned char, VOID_STAR, unsigned int,
			     unsigned char, VOID_STAR, unsigned int,
			     VOID_STAR);

/* This array of functions must be indexed by precedence after arithmetic
 * promotions.
 */
static Bin_Fun_Type Bin_Fun_Map [MAX_ARITHMETIC_TYPES] =
{
   NULL,
   NULL,
   NULL,
   NULL,
   int_int_bin_op,
   uint_uint_bin_op,
   long_long_bin_op,
   ulong_ulong_bin_op,
   float_float_bin_op,
   double_double_bin_op
};

static int arith_bin_op (int op,
			 unsigned char a_type, VOID_STAR ap, unsigned int na,
			 unsigned char b_type, VOID_STAR bp, unsigned int nb,
			 VOID_STAR cp)
{
   Convert_Fun_Type af, bf;
   Bin_Fun_Type binfun;
   int a_indx, b_indx, c_indx;
   unsigned char c_type;
   int ret;

   c_type = promote_to_common_type (a_type, b_type);

   a_indx = Type_Precedence_Table [a_type];
   b_indx = Type_Precedence_Table [b_type];
   c_indx = Type_Precedence_Table [c_type];

   af = Binary_Matrix[a_indx][c_indx].convert_function;
   bf = Binary_Matrix[b_indx][c_indx].convert_function;
   binfun = Bin_Fun_Map[c_indx];

   if ((af != NULL)
       && (NULL == (ap = (VOID_STAR) (*af) (ap, na))))
     return -1;

   if ((bf != NULL)
       && (NULL == (bp = (VOID_STAR) (*bf) (bp, nb))))
     {
	if (af != NULL) SLfree ((char *) ap);
	return -1;
     }

   ret = (*binfun) (op, a_type, ap, na, b_type, bp, nb, cp);
   if (af != NULL) SLfree ((char *) ap);
   if (bf != NULL) SLfree ((char *) bp);

   return ret;
}

static int arith_unary_op_result (int op, unsigned char a, unsigned char *b)
{
   (void) a;
   switch (op)
     {
      default:
	return 0;

      case SLANG_SQR:
      case SLANG_MUL2:
      case SLANG_PLUSPLUS:
      case SLANG_MINUSMINUS:
      case SLANG_CHS:
      case SLANG_ABS:
	*b = a;
	break;

      case SLANG_NOT:
      case SLANG_BNOT:
	if (0 == IS_INTEGER_TYPE(a))
	  return 0;
	*b = a;
	break;

      case SLANG_SIGN:
	*b = SLANG_INT_TYPE;
	break;
     }
   return 1;
}

static int integer_pop (unsigned char type, VOID_STAR ptr)
{
   SLang_Object_Type obj;
   int i, j;
   void (*f)(VOID_STAR, VOID_STAR, unsigned int);

   if (-1 == SLang_pop (&obj))
     return -1;

   if ((obj.data_type > MAXIMUM_ARITH_TYPE_VALUE)
       || ((j = Type_Precedence_Table[obj.data_type]) == -1)
       || (j >= FLOAT_PRECEDENCE_VALUE))
     {
	_SLclass_type_mismatch_error (type, obj.data_type);
       	SLang_free_object (&obj);
	return -1;
     }

   i = Type_Precedence_Table[type];
   f = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
     Binary_Matrix[j][i].copy_function;

   (*f) (ptr, (VOID_STAR)&obj.v, 1);

   return 0;
}

static int integer_push (unsigned char type, VOID_STAR ptr)
{
   SLang_Object_Type obj;
   int i;
   void (*f)(VOID_STAR, VOID_STAR, unsigned int);

   i = Type_Precedence_Table[type];
   f = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
     Binary_Matrix[i][i].copy_function;

   obj.data_type = type;

   (*f) ((VOID_STAR)&obj.v, ptr, 1);

   return SLang_push (&obj);
}

int SLang_pop_char (char *i)
{
   return integer_pop (SLANG_CHAR_TYPE, (VOID_STAR) i);
}

int SLang_pop_uchar (unsigned char *i)
{
   return integer_pop (SLANG_UCHAR_TYPE, (VOID_STAR) i);
}

int SLang_pop_short (short *i)
{
   return integer_pop (SLANG_SHORT_TYPE, (VOID_STAR) i);
}

int SLang_pop_ushort (unsigned short *i)
{
   return integer_pop (SLANG_USHORT_TYPE, (VOID_STAR) i);
}

int SLang_pop_long (long *i)
{
   return integer_pop (SLANG_LONG_TYPE, (VOID_STAR) i);
}

int SLang_pop_ulong (unsigned long *i)
{
   return integer_pop (SLANG_ULONG_TYPE, (VOID_STAR) i);
}

int SLang_pop_integer (int *i)
{
#if _SLANG_OPTIMIZE_FOR_SPEED
   SLang_Object_Type obj;

   if (-1 == _SLang_pop_object_of_type (SLANG_INT_TYPE, &obj, 0))
     return -1;
   *i = obj.v.int_val;
   return 0;
#else
  return integer_pop (SLANG_INT_TYPE, (VOID_STAR) i);
#endif
}

int SLang_pop_uinteger (unsigned int *i)
{
   return integer_pop (SLANG_UINT_TYPE, (VOID_STAR) i);
}

int SLang_push_integer (int i)
{
   return SLclass_push_int_obj (SLANG_INT_TYPE, i);
}
int SLang_push_uinteger (unsigned int i)
{
   return SLclass_push_int_obj (SLANG_UINT_TYPE, (int) i);
}
int SLang_push_char (char i)
{
   return SLclass_push_char_obj (SLANG_CHAR_TYPE, i);
}
int SLang_push_uchar (unsigned char i)
{
   return SLclass_push_char_obj (SLANG_UCHAR_TYPE, (char) i);
}
int SLang_push_short (short i)
{
   return SLclass_push_short_obj (SLANG_SHORT_TYPE, i);
}
int SLang_push_ushort (unsigned short i)
{
   return SLclass_push_short_obj (SLANG_USHORT_TYPE, (unsigned short) i);
}
int SLang_push_long (long i)
{
   return SLclass_push_long_obj (SLANG_LONG_TYPE, i);
}
int SLang_push_ulong (unsigned long i)
{
   return SLclass_push_long_obj (SLANG_ULONG_TYPE, (long) i);
}

_INLINE_
int _SLarith_typecast (unsigned char a_type, VOID_STAR ap, unsigned int na,
		       unsigned char b_type, VOID_STAR bp)
{
   int i, j;

   void (*copy)(VOID_STAR, VOID_STAR, unsigned int);

   i = Type_Precedence_Table[a_type];
   j = Type_Precedence_Table[b_type];

   copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
     Binary_Matrix[i][j].copy_function;

   (*copy) (bp, ap, na);
   return 1;
}

#if SLANG_HAS_FLOAT

int SLang_pop_double(double *x, int *convertp, int *ip)
{
   SLang_Object_Type obj;
   int i, convert;

   if (0 != SLang_pop (&obj))
     return -1;

   i = 0;
   convert = 0;

   switch (obj.data_type)
     {
      case SLANG_FLOAT_TYPE:
	*x = (double) obj.v.float_val;
	break;

      case SLANG_DOUBLE_TYPE:
	*x = obj.v.double_val;
	break;

      case SLANG_INT_TYPE:
	i = (int) obj.v.long_val;
	*x = (double) i;
	convert = 1;
	break;

      case SLANG_CHAR_TYPE: *x = (double) obj.v.char_val; break;
      case SLANG_UCHAR_TYPE: *x = (double) obj.v.uchar_val; break;
      case SLANG_SHORT_TYPE: *x = (double) obj.v.short_val; break;
      case SLANG_USHORT_TYPE: *x = (double) obj.v.ushort_val; break;
      case SLANG_UINT_TYPE: *x = (double) obj.v.uint_val; break;
      case SLANG_LONG_TYPE: *x = (double) obj.v.long_val; break;
      case SLANG_ULONG_TYPE: *x = (double) obj.v.ulong_val; break;
	
      default:
	_SLclass_type_mismatch_error (SLANG_DOUBLE_TYPE, obj.data_type);
	SLang_free_object (&obj);
	return -1;
     }

   if (convertp != NULL) *convertp = convert;
   if (ip != NULL) *ip = i;

   return 0;
}

int SLang_push_double (double x)
{
   return SLclass_push_double_obj (SLANG_DOUBLE_TYPE, x);
}

int SLang_pop_float (float *x)
{
   double d;

   /* Pop it as a double and let the double function do all the typcasting */
   if (-1 == SLang_pop_double (&d, NULL, NULL))
     return -1;

   *x = (float) d;
   return 0;
}

int SLang_push_float (float f)
{
   return SLclass_push_float_obj (SLANG_FLOAT_TYPE, (double) f);
}

/* Double */
static int double_push (unsigned char unused, VOID_STAR ptr)
{
   (void) unused;
   SLang_push_double (*(double *) ptr);
   return 0;
}

static int double_push_literal (unsigned char type, VOID_STAR ptr)
{
   (void) type;
   return SLang_push_double (**(double **)ptr);
}

static int double_pop (unsigned char unused, VOID_STAR ptr)
{
   (void) unused;
   return SLang_pop_double ((double *) ptr, NULL, NULL);
}

static void double_byte_code_destroy (unsigned char unused, VOID_STAR ptr)
{
   (void) unused;
   SLfree (*(char **) ptr);
}

static int float_push (unsigned char unused, VOID_STAR ptr)
{
   (void) unused;
   SLang_push_float (*(float *) ptr);
   return 0;
}

static int float_pop (unsigned char unused, VOID_STAR ptr)
{
   (void) unused;
   return SLang_pop_float ((float *) ptr);
}

#endif				       /* SLANG_HAS_FLOAT */

#if SLANG_HAS_FLOAT
static char Double_Format[16] = "%g";

void _SLset_double_format (char *s)
{
   strncpy (Double_Format, s, 15);
   Double_Format[15] = 0;
}
#endif

static char *arith_string (unsigned char type, VOID_STAR v)
{
   char buf [256];
   char *s;

   s = buf;

   switch (type)
     {
      default:
	s = SLclass_get_datatype_name (type);
	break;

      case SLANG_CHAR_TYPE:
	sprintf (s, "%d", *(char *) v);
	break;
      case SLANG_UCHAR_TYPE:
	sprintf (s, "%u", *(unsigned char *) v);
	break;
      case SLANG_SHORT_TYPE:
	sprintf (s, "%d", *(short *) v);
	break;
      case SLANG_USHORT_TYPE:
	sprintf (s, "%u", *(unsigned short *) v);
	break;
      case SLANG_INT_TYPE:
	sprintf (s, "%d", *(int *) v);
	break;
      case SLANG_UINT_TYPE:
	sprintf (s, "%u", *(unsigned int *) v);
	break;
      case SLANG_LONG_TYPE:
	sprintf (s, "%ld", *(long *) v);
	break;
      case SLANG_ULONG_TYPE:
	sprintf (s, "%lu", *(unsigned long *) v);
	break;
#if SLANG_HAS_FLOAT
      case SLANG_FLOAT_TYPE:
	if (EOF == _SLsnprintf (buf, sizeof (buf), Double_Format, *(float *) v))
	  sprintf (s, "%e", *(float *) v);
	break;
      case SLANG_DOUBLE_TYPE:
	if (EOF == _SLsnprintf (buf, sizeof (buf), Double_Format, *(double *) v))
	  sprintf (s, "%e", *(double *) v);
	break;
#endif
     }

   return SLmake_string (s);
}

static int integer_to_bool (unsigned char type, int *t)
{
   (void) type;
   return SLang_pop_integer (t);
}

static int push_int_literal (unsigned char type, VOID_STAR ptr)
{
   return SLclass_push_int_obj (type, (int) *(long *) ptr);
}

static int push_char_literal (unsigned char type, VOID_STAR ptr)
{
   return SLclass_push_char_obj (type, (char) *(long *) ptr);
}

#if SIZEOF_SHORT != SIZEOF_INT
static int push_short_literal (unsigned char type, VOID_STAR ptr)
{
   return SLclass_push_short_obj (type, (short) *(long *) ptr);
}
#endif

#if SIZEOF_INT != SIZEOF_LONG
static int push_long_literal (unsigned char type, VOID_STAR ptr)
{
   return SLclass_push_long_obj (type, *(long *) ptr);
}
#endif

typedef struct
{
   char *name;
   unsigned char data_type;
   unsigned int sizeof_type;
   int (*unary_fun)(int, unsigned char, VOID_STAR, unsigned int, VOID_STAR);
   int (*push_literal) (unsigned char, VOID_STAR);
   int (*cmp_fun) (unsigned char, VOID_STAR, VOID_STAR, int *);
}
Integer_Info_Type;

static Integer_Info_Type Integer_Types [8] =
{
     {"Char_Type", SLANG_CHAR_TYPE, sizeof (char), char_unary_op, push_char_literal, char_cmp_function},
     {"UChar_Type", SLANG_UCHAR_TYPE, sizeof (unsigned char), uchar_unary_op, push_char_literal, uchar_cmp_function},
#if SIZEOF_INT != SIZEOF_SHORT
     {"Short_Type", SLANG_SHORT_TYPE, sizeof (short), short_unary_op, push_short_literal, short_cmp_function},
     {"UShort_Type", SLANG_USHORT_TYPE, sizeof (unsigned short), ushort_unary_op, push_short_literal, ushort_cmp_function},
#else
     {NULL, SLANG_SHORT_TYPE},
     {NULL, SLANG_USHORT_TYPE},
#endif

     {"Integer_Type", SLANG_INT_TYPE, sizeof (int), int_unary_op, push_int_literal, int_cmp_function},
     {"UInteger_Type", SLANG_UINT_TYPE, sizeof (unsigned int), uint_unary_op, push_int_literal, uint_cmp_function},

#if SIZEOF_INT != SIZEOF_LONG
     {"Long_Type", SLANG_LONG_TYPE, sizeof (long), long_unary_op, push_long_literal, long_cmp_function},
     {"ULong_Type", SLANG_ULONG_TYPE, sizeof (unsigned long), ulong_unary_op, push_long_literal, ulong_cmp_function}
#else
     {NULL, SLANG_LONG_TYPE, 0, NULL, NULL, NULL},
     {NULL, SLANG_ULONG_TYPE, 0, NULL, NULL, NULL}
#endif
};

static int create_synonyms (void)
{
   static char *names[8] =
     {
	"Int16_Type", "UInt16_Type", "Int32_Type", "UInt32_Type",
	"Int64_Type", "UInt64_Type",
	"Float32_Type", "Float64_Type"
     };
   int types[8];
   unsigned int i;

   memset ((char *) types, 0, sizeof (types));

   /* The assumption is that sizeof(unsigned X) == sizeof (X) */
#if SIZEOF_INT == 2
   types[0] = SLANG_INT_TYPE;
   types[1] = SLANG_UINT_TYPE;
#else
# if SIZEOF_SHORT == 2
   types[0] = SLANG_SHORT_TYPE;
   types[1] = SLANG_USHORT_TYPE;
# else
#  if SIZEOF_LONG == 2
   types[0] = SLANG_LONG_TYPE;
   types[1] = SLANG_ULONG_TYPE;
#  endif
# endif
#endif

#if SIZEOF_INT == 4
   types[2] = SLANG_INT_TYPE;
   types[3] = SLANG_UINT_TYPE;
#else
# if SIZEOF_SHORT == 4
   types[2] = SLANG_SHORT_TYPE;
   types[3] = SLANG_USHORT_TYPE;
# else
#  if SIZEOF_LONG == 4
   types[2] = SLANG_LONG_TYPE;
   types[3] = SLANG_ULONG_TYPE;
#  endif
# endif
#endif

#if SIZEOF_INT == 8
   types[4] = SLANG_INT_TYPE;
   types[5] = SLANG_UINT_TYPE;
#else
# if SIZEOF_SHORT == 8
   types[4] = SLANG_SHORT_TYPE;
   types[5] = SLANG_USHORT_TYPE;
# else
#  if SIZEOF_LONG == 8
   types[4] = SLANG_LONG_TYPE;
   types[5] = SLANG_ULONG_TYPE;
#  endif
# endif
#endif

#if SLANG_HAS_FLOAT

#if SIZEOF_FLOAT == 4
   types[6] = SLANG_FLOAT_TYPE;
#else
# if SIZEOF_DOUBLE == 4
   types[6] = SLANG_DOUBLE_TYPE;
# endif
#endif
#if SIZEOF_FLOAT == 8
   types[7] = SLANG_FLOAT_TYPE;
#else
# if SIZEOF_DOUBLE == 8
   types[7] = SLANG_DOUBLE_TYPE;
# endif
#endif

#endif

   if ((-1 == SLclass_create_synonym ("Int_Type", SLANG_INT_TYPE))
       || (-1 == SLclass_create_synonym ("UInt_Type", SLANG_UINT_TYPE)))
     return -1;

   for (i = 0; i < 8; i++)
     {
	if (types[i] == 0) continue;

	if (-1 == SLclass_create_synonym (names[i], types[i]))
	  return -1;
     }

#if SIZEOF_INT == SIZEOF_SHORT
   if ((-1 == SLclass_create_synonym ("Short_Type", SLANG_INT_TYPE))
       || (-1 == SLclass_create_synonym ("UShort_Type", SLANG_UINT_TYPE))
       || (-1 == _SLclass_copy_class (SLANG_SHORT_TYPE, SLANG_INT_TYPE))
       || (-1 == _SLclass_copy_class (SLANG_USHORT_TYPE, SLANG_UINT_TYPE)))
     return -1;
#endif
#if SIZEOF_INT == SIZEOF_LONG
   if ((-1 == SLclass_create_synonym ("Long_Type", SLANG_INT_TYPE))
       || (-1 == SLclass_create_synonym ("ULong_Type", SLANG_UINT_TYPE))
       || (-1 == _SLclass_copy_class (SLANG_LONG_TYPE, SLANG_INT_TYPE))
       || (-1 == _SLclass_copy_class (SLANG_ULONG_TYPE, SLANG_UINT_TYPE)))
     return -1;
#endif
   return 0;
}

int _SLarith_register_types (void)
{
   SLang_Class_Type *cl;
   int a_type, b_type;
   int i, j;

#if defined(HAVE_SETLOCALE) && defined(LC_NUMERIC)
   /* make sure decimal point it used --- the parser requires it */
   (void) setlocale (LC_NUMERIC, "C"); 
#endif

   for (i = 0; i < 8; i++)
     {
	Integer_Info_Type *info;

	info = Integer_Types + i;

	if (info->name == NULL)
	  {
	     /* This happens when the object is the same size as an integer
	      * For this case, we really want to copy the integer class.
	      * We will handle that when the synonym is created.
	      */
	     continue;
	  }

	if (NULL == (cl = SLclass_allocate_class (info->name)))
	  return -1;

	(void) SLclass_set_string_function (cl, arith_string);
	(void) SLclass_set_push_function (cl, integer_push);
	(void) SLclass_set_pop_function (cl, integer_pop);
	cl->cl_push_literal = info->push_literal;
	cl->cl_to_bool = integer_to_bool;

	cl->cl_cmp = info->cmp_fun;

	if (-1 == SLclass_register_class (cl, info->data_type, info->sizeof_type,
					  SLANG_CLASS_TYPE_SCALAR))
	  return -1;
	if (-1 == SLclass_add_unary_op (info->data_type, info->unary_fun, arith_unary_op_result))
	  return -1;
	
	_SLarith_Is_Arith_Type [info->data_type] = 1;
     }

#if SLANG_HAS_FLOAT
   if (NULL == (cl = SLclass_allocate_class ("Double_Type")))
     return -1;
   (void) SLclass_set_push_function (cl, double_push);
   (void) SLclass_set_pop_function (cl, double_pop);
   (void) SLclass_set_string_function (cl, arith_string);
   cl->cl_byte_code_destroy = double_byte_code_destroy;
   cl->cl_push_literal = double_push_literal;
   cl->cl_cmp = double_cmp_function;

   if (-1 == SLclass_register_class (cl, SLANG_DOUBLE_TYPE, sizeof (double),
				     SLANG_CLASS_TYPE_SCALAR))
     return -1;
   if (-1 == SLclass_add_unary_op (SLANG_DOUBLE_TYPE, double_unary_op, arith_unary_op_result))
     return -1;
   _SLarith_Is_Arith_Type [SLANG_DOUBLE_TYPE] = 2;

   if (NULL == (cl = SLclass_allocate_class ("Float_Type")))
     return -1;
   (void) SLclass_set_string_function (cl, arith_string);
   (void) SLclass_set_push_function (cl, float_push);
   (void) SLclass_set_pop_function (cl, float_pop);
   cl->cl_cmp = float_cmp_function;

   if (-1 == SLclass_register_class (cl, SLANG_FLOAT_TYPE, sizeof (float),
				     SLANG_CLASS_TYPE_SCALAR))
     return -1;
   if (-1 == SLclass_add_unary_op (SLANG_FLOAT_TYPE, float_unary_op, arith_unary_op_result))
     return -1;
   _SLarith_Is_Arith_Type [SLANG_FLOAT_TYPE] = 2;
#endif

   if (-1 == create_synonyms ())
     return -1;

   for (a_type = 0; a_type <= MAXIMUM_ARITH_TYPE_VALUE; a_type++)
     {
	if (-1 == (i = Type_Precedence_Table [a_type]))
	  continue;

	for (b_type = 0; b_type <= MAXIMUM_ARITH_TYPE_VALUE; b_type++)
	  {
	     int implicit_ok;

	     if (-1 == (j = Type_Precedence_Table [b_type]))
	       continue;

	     /* Allow implicit typecast, except from into to float */
	     implicit_ok = ((j >= FLOAT_PRECEDENCE_VALUE)
			    || (i < FLOAT_PRECEDENCE_VALUE));

	     if (-1 == SLclass_add_binary_op (a_type, b_type, arith_bin_op, arith_bin_op_result))
	       return -1;

	     if (i != j)
	       if (-1 == SLclass_add_typecast (a_type, b_type, _SLarith_typecast, implicit_ok))
		 return -1;
	  }
     }

   return 0;
}

#if _SLANG_OPTIMIZE_FOR_SPEED

static void promote_objs (SLang_Object_Type *a, SLang_Object_Type *b,
			  SLang_Object_Type *c, SLang_Object_Type *d)
{
   unsigned char ia, ib, ic, id;
   int i, j;
   void (*copy)(VOID_STAR, VOID_STAR, unsigned int);

   ia = a->data_type;
   ib = b->data_type;
   
   ic = _SLarith_promote_type (ia);

   if (ic == ib) id = ic;	       /* already promoted */
   else id = _SLarith_promote_type (ib);

   i = Type_Precedence_Table[ic];
   j = Type_Precedence_Table[id];
   if (i > j)
     {
	id = ic;
	j = i;
     }

   c->data_type = d->data_type = id;

   i = Type_Precedence_Table[ia];
   copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
     Binary_Matrix[i][j].copy_function;
   (*copy) ((VOID_STAR) &c->v, (VOID_STAR)&a->v, 1);

   i = Type_Precedence_Table[ib];
   copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
     Binary_Matrix[i][j].copy_function;
   (*copy) ((VOID_STAR) &d->v, (VOID_STAR)&b->v, 1);
}

int _SLarith_bin_op (SLang_Object_Type *oa, SLang_Object_Type *ob, int op)
{
   unsigned char a_type, b_type;

   a_type = oa->data_type;
   b_type = ob->data_type;

   if (a_type != b_type)
     {
	SLang_Object_Type obj_a, obj_b;
	
	/* Handle common cases */
	if ((a_type == SLANG_INT_TYPE)
	    && (b_type == SLANG_DOUBLE_TYPE))
	  return double_double_scalar_bin_op (oa->v.int_val, ob->v.double_val, op);

	if ((a_type == SLANG_DOUBLE_TYPE)
	    && (b_type == SLANG_INT_TYPE))
	  return double_double_scalar_bin_op (oa->v.double_val, ob->v.int_val, op);

	/* Otherwise do it the hard way */
	promote_objs (oa, ob, &obj_a, &obj_b);
	oa = &obj_a;
	ob = &obj_b;
	
	a_type = oa->data_type;
	b_type = ob->data_type;
     }
   
	  
   switch (a_type)
     {
      case SLANG_CHAR_TYPE:
	return int_int_scalar_bin_op (oa->v.char_val, ob->v.char_val, op);

      case SLANG_UCHAR_TYPE:
	return int_int_scalar_bin_op (oa->v.uchar_val, ob->v.uchar_val, op);

      case SLANG_SHORT_TYPE:
	return int_int_scalar_bin_op (oa->v.short_val, ob->v.short_val, op);

      case SLANG_USHORT_TYPE:
# if SIZEOF_INT == SIZEOF_SHORT
	return uint_uint_scalar_bin_op (oa->v.ushort_val, ob->v.ushort_val, op);
# else
	return int_int_scalar_bin_op ((int)oa->v.ushort_val, (int)ob->v.ushort_val, op);
# endif

#if SIZEOF_LONG == SIZEOF_INT
      case SLANG_LONG_TYPE:
#endif
      case SLANG_INT_TYPE:
	return int_int_scalar_bin_op (oa->v.int_val, ob->v.int_val, op);

#if SIZEOF_LONG == SIZEOF_INT
      case SLANG_ULONG_TYPE:
#endif
      case SLANG_UINT_TYPE:
	return uint_uint_scalar_bin_op (oa->v.uint_val, ob->v.uint_val, op);
	
#if SIZEOF_LONG != SIZEOF_INT
      case SLANG_LONG_TYPE:
	return long_long_scalar_bin_op (oa->v.long_val, ob->v.long_val, op);
      case SLANG_ULONG_TYPE:
	return ulong_ulong_scalar_bin_op (oa->v.ulong_val, ob->v.ulong_val, op);
#endif
      case SLANG_FLOAT_TYPE:
	return float_float_scalar_bin_op (oa->v.float_val, ob->v.float_val, op);
      case SLANG_DOUBLE_TYPE:
	return double_double_scalar_bin_op (oa->v.double_val, ob->v.double_val, op);
     }
   
   return 1;
}
#endif