Ticket #13339: trac_13339-headers.patch
File trac_13339-headers.patch, 51.5 KB (added by , 10 years ago) |
---|
-
sage/ext/gen_interpreters.py
# HG changeset patch # User Jean-Pierre Flori <jean-pierre.flori@ssi.gouv.fr> # Date 1344157525 -7200 # Node ID 192526852a00d85b19760045ae32daef50d082a5 # Parent 361d834fbcd60757f8d71f636c4c13d5dac1df6a #13339: generate headers file for interp_*.c diff --git a/sage/ext/gen_interpreters.py b/sage/ext/gen_interpreters.py
a b 129 129 130 130 Indents each line in text by n spaces. 131 131 132 EXAMPLES: 132 EXAMPLES:: 133 133 134 sage: from sage.ext.gen_interpreters import indent_lines 134 135 sage: indent_lines(3, "foo") 135 136 ' foo' … … 159 160 template on each call; don't use it in situations where 160 161 performance is important.) 161 162 162 EXAMPLES: 163 EXAMPLES:: 164 163 165 sage: from sage.ext.gen_interpreters import je 164 166 sage: je("{{ a }} > {{ b }} * {{ c }}", a='"a suffusion of yellow"', b=3, c=7) 165 167 u'"a suffusion of yellow" > 3 * 7' … … 223 225 A string giving variable declarations that must be local variables 224 226 in Cython methods using this storage type. 225 227 226 EXAMPLES: 228 EXAMPLES:: 229 227 230 sage: from sage.ext.gen_interpreters import * 228 231 sage: ty_double.class_member_declarations 229 232 '' … … 259 262 of output locations are passed into the instruction and the 260 263 instruction writes outputs directly in the final location. 261 264 262 EXAMPLES: 265 EXAMPLES:: 266 263 267 sage: from sage.ext.gen_interpreters import * 264 268 sage: ty_double.cheap_copies() 265 269 True … … 280 284 like "generate an incref" and "generate a decref". But as 281 285 long as we only support Python, this way is probably simpler.) 282 286 283 EXAMPLES: 287 EXAMPLES:: 288 284 289 sage: from sage.ext.gen_interpreters import * 285 290 sage: ty_double.python_refcounted() 286 291 False … … 293 298 r""" 294 299 Gives the Cython type for a single value of this type (as a string). 295 300 296 EXAMPLES: 301 EXAMPLES:: 302 297 303 sage: from sage.ext.gen_interpreters import * 298 304 sage: ty_double.cython_decl_type() 299 305 'double' … … 309 315 Gives the Cython type for referring to an array of values of 310 316 this type (as a string). 311 317 312 EXAMPLES: 318 EXAMPLES:: 319 313 320 sage: from sage.ext.gen_interpreters import * 314 321 sage: ty_double.cython_array_type() 315 322 'double*' … … 331 338 generate empty loops, which are ugly and potentially might not 332 339 be optimized away.) 333 340 334 EXAMPLES: 341 EXAMPLES:: 342 335 343 sage: from sage.ext.gen_interpreters import * 336 344 sage: ty_double.needs_cython_init_clear() 337 345 False … … 346 354 r""" 347 355 Gives the C type for a single value of this type (as a string). 348 356 349 EXAMPLES: 357 EXAMPLES:: 358 350 359 sage: from sage.ext.gen_interpreters import * 351 360 sage: ty_double.c_decl_type() 352 361 'double' … … 362 371 Gives the C type for a pointer to this type (as a reference to 363 372 either a single value or an array) (as a string). 364 373 365 EXAMPLES: 374 EXAMPLES:: 375 366 376 sage: from sage.ext.gen_interpreters import * 367 377 sage: ty_double.c_ptr_type() 368 378 'double*' … … 380 390 same as c_decl_type; for auto-reference types, this is the 381 391 pointer type. 382 392 383 EXAMPLES: 393 EXAMPLES:: 394 384 395 sage: from sage.ext.gen_interpreters import * 385 396 sage: ty_double.c_local_type() 386 397 'double' … … 397 408 and a Python expression, generate code to assign to the Cython 398 409 variable from the Python expression. 399 410 400 EXAMPLES: 411 EXAMPLES:: 412 401 413 sage: from sage.ext.gen_interpreters import * 402 414 sage: ty_double.assign_c_from_py('foo', 'bar') 403 415 u'foo = bar' … … 414 426 in a wrapper class for a memory chunk with this storage type 415 427 and the given name. 416 428 417 EXAMPLES: 429 EXAMPLES:: 430 418 431 sage: from sage.ext.gen_interpreters import * 419 432 sage: ty_mpfr.declare_chunk_class_members('args') 420 433 u' cdef int _n_args\n cdef mpfr_t* _args\n' … … 430 443 Returns a string allocating the memory for the class members for 431 444 a memory chunk with this storage type and the given name. 432 445 433 EXAMPLES: 446 EXAMPLES:: 447 434 448 sage: from sage.ext.gen_interpreters import * 435 449 sage: print ty_mpfr.alloc_chunk_data('args', 'MY_LENGTH') 436 450 self._n_args = MY_LENGTH … … 456 470 wrapper class using a memory chunk with this storage type, to 457 471 deallocate the corresponding class members. 458 472 459 EXAMPLES: 473 EXAMPLES:: 474 460 475 sage: from sage.ext.gen_interpreters import * 461 476 sage: print ty_double.dealloc_chunk_data('args') 462 477 if self._args: … … 490 505 as well as the properties described in the documentation for 491 506 StorageType.__init__. 492 507 493 EXAMPLES: 508 EXAMPLES:: 509 494 510 sage: from sage.ext.gen_interpreters import * 495 511 sage: ty_double.class_member_declarations 496 512 '' … … 516 532 Since having cheap copies is essentially the definition of 517 533 StorageTypeAssignable, this always returns True. 518 534 519 EXAMPLES: 535 EXAMPLES:: 536 520 537 sage: from sage.ext.gen_interpreters import * 521 538 sage: ty_double.cheap_copies() 522 539 True … … 529 546 r""" 530 547 Gives the C type for a single value of this type (as a string). 531 548 532 EXAMPLES: 549 EXAMPLES:: 550 533 551 sage: from sage.ext.gen_interpreters import * 534 552 sage: ty_double.c_decl_type() 535 553 'double' … … 545 563 same as c_decl_type; for auto-reference types, this is the 546 564 pointer type. 547 565 548 EXAMPLES: 566 EXAMPLES:: 567 549 568 sage: from sage.ext.gen_interpreters import * 550 569 sage: ty_double.c_local_type() 551 570 'double' … … 617 636 for StorageTypeAssignable.__init__. The type is always 618 637 'PyObject*'. 619 638 620 EXAMPLES: 639 EXAMPLES:: 640 621 641 sage: from sage.ext.gen_interpreters import * 622 642 sage: ty_python.class_member_declarations 623 643 '' … … 637 657 638 658 Returns True. 639 659 640 EXAMPLES: 660 EXAMPLES:: 661 641 662 sage: from sage.ext.gen_interpreters import * 642 663 sage: ty_python.python_refcounted() 643 664 True … … 648 669 r""" 649 670 Gives the Cython type for a single value of this type (as a string). 650 671 651 EXAMPLES: 672 EXAMPLES:: 673 652 674 sage: from sage.ext.gen_interpreters import * 653 675 sage: ty_python.cython_decl_type() 654 676 'object' … … 661 683 in a wrapper class for a memory chunk with this storage type 662 684 and the given name. 663 685 664 EXAMPLES: 686 EXAMPLES:: 687 665 688 sage: from sage.ext.gen_interpreters import * 666 689 sage: ty_python.declare_chunk_class_members('args') 667 690 u' cdef object _list_args\n cdef int _n_args\n cdef PyObject** _args\n' … … 677 700 Returns a string allocating the memory for the class members for 678 701 a memory chunk with this storage type and the given name. 679 702 680 EXAMPLES: 703 EXAMPLES:: 704 681 705 sage: from sage.ext.gen_interpreters import * 682 706 sage: print ty_python.alloc_chunk_data('args', 'MY_LENGTH') 683 707 self._n_args = MY_LENGTH … … 700 724 Our array was allocated as a Python list; this means we actually 701 725 don't need to do anything to deallocate it. 702 726 703 EXAMPLES: 727 EXAMPLES:: 728 704 729 sage: from sage.ext.gen_interpreters import * 705 730 sage: ty_python.dealloc_chunk_data('args') 706 731 '' … … 714 739 715 740 Returns True. 716 741 717 EXAMPLES: 742 EXAMPLES:: 743 718 744 sage: from sage.ext.gen_interpreters import * 719 745 sage: ty_python.needs_cython_init_clear() 720 746 True … … 727 753 and a Python expression, generate code to assign to the Cython 728 754 variable from the Python expression. 729 755 730 EXAMPLES: 756 EXAMPLES:: 757 731 758 sage: from sage.ext.gen_interpreters import * 732 759 sage: ty_python.assign_c_from_py('foo[i]', 'bar[j]') 733 760 u'foo[i] = <PyObject *>bar[j]; Py_INCREF(foo[i])' … … 740 767 Generates code to initialize a variable (or array reference) 741 768 holding a PyObject*. Sets it to NULL. 742 769 743 EXAMPLES: 770 EXAMPLES:: 771 744 772 sage: from sage.ext.gen_interpreters import * 745 773 sage: ty_python.cython_init('foo[i]') 746 774 u'foo[i] = NULL' … … 752 780 Generates code to clear a variable (or array reference) holding 753 781 a PyObject*. 754 782 755 EXAMPLES: 783 EXAMPLES:: 784 756 785 sage: from sage.ext.gen_interpreters import * 757 786 sage: ty_python.cython_clear('foo[i]') 758 787 u'Py_CLEAR(foo[i])' … … 778 807 respectively), as well as the properties described in 779 808 the documentation for StorageType.__init__. 780 809 781 EXAMPLES: 810 EXAMPLES:: 811 782 812 sage: from sage.ext.gen_interpreters import * 783 813 sage: ty_mpfr.class_member_declarations 784 814 'cdef RealField_class domain\n' … … 799 829 r""" 800 830 Gives the C type for a single value of this type (as a string). 801 831 802 EXAMPLES: 832 EXAMPLES:: 833 803 834 sage: from sage.ext.gen_interpreters import * 804 835 sage: ty_mpfr.c_decl_type() 805 836 'mpfr_t' … … 813 844 same as c_decl_type; for auto-reference types, this is the 814 845 pointer type. 815 846 816 EXAMPLES: 847 EXAMPLES:: 848 817 849 sage: from sage.ext.gen_interpreters import * 818 850 sage: ty_mpfr.c_local_type() 819 851 'mpfr_ptr' … … 828 860 All known examples of auto-reference types do need a special 829 861 initialization call, so this always returns True. 830 862 831 EXAMPLES: 863 EXAMPLES:: 864 832 865 sage: from sage.ext.gen_interpreters import * 833 866 sage: ty_mpfr.needs_cython_init_clear() 834 867 True … … 860 893 variable names that don't conflict. (The id system has 861 894 never actually been used, so bugs probably remain.) 862 895 863 EXAMPLES: 896 EXAMPLES:: 897 864 898 sage: from sage.ext.gen_interpreters import * 865 899 sage: ty_mpfr.class_member_declarations 866 900 'cdef RealField_class domain\n' … … 873 907 sage: ty_mpfr.ref_type 874 908 'mpfr_ptr' 875 909 876 TESTS: 910 TESTS:: 911 877 912 sage: ty_mpfr2 = StorageTypeMPFR(id='_the_second') 878 913 sage: ty_mpfr2.class_member_declarations 879 914 'cdef RealField_class domain_the_second\n' … … 894 929 Generates code to initialize an mpfr_t reference (a variable, an 895 930 array reference, etc.) 896 931 897 EXAMPLES: 932 EXAMPLES:: 933 898 934 sage: from sage.ext.gen_interpreters import * 899 935 sage: ty_mpfr.cython_init('foo[i]') 900 936 u'mpfr_init2(foo[i], self.domain.prec())' … … 907 943 Generates code to clear an mpfr_t reference (a variable, an 908 944 array reference, etc.) 909 945 910 EXAMPLES: 946 EXAMPLES:: 947 911 948 sage: from sage.ext.gen_interpreters import * 912 949 sage: ty_mpfr.cython_clear('foo[i]') 913 950 'mpfr_clear(foo[i])' … … 920 957 and a Python expression, generate code to assign to the Cython 921 958 variable from the Python expression. 922 959 923 EXAMPLES: 960 EXAMPLES:: 961 924 962 sage: from sage.ext.gen_interpreters import * 925 963 sage: ty_mpfr.assign_c_from_py('foo[i]', 'bar[j]') 926 964 u'rn = self.domain(bar[j])\nmpfr_set(foo[i], rn.value, GMP_RNDN)' … … 961 999 used in generated variable names, etc.) and "storage_type", 962 1000 which is a StorageType object. 963 1001 964 EXAMPLES: 1002 EXAMPLES:: 1003 965 1004 sage: from sage.ext.gen_interpreters import * 966 1005 sage: mc = MemoryChunkArguments('args', ty_mpfr) 967 1006 sage: mc.name … … 976 1015 r""" 977 1016 Give a string representation of this memory chunk. 978 1017 979 EXAMPLES: 1018 EXAMPLES:: 1019 980 1020 sage: from sage.ext.gen_interpreters import * 981 1021 sage: mc = MemoryChunkArguments('args', ty_mpfr) 982 1022 sage: mc … … 991 1031 Returns a string giving the declarations of the class members 992 1032 in a wrapper class for this memory chunk. 993 1033 994 EXAMPLES: 1034 EXAMPLES:: 1035 995 1036 sage: from sage.ext.gen_interpreters import * 996 1037 sage: mc = MemoryChunkArguments('args', ty_mpfr) 997 1038 sage: mc.declare_class_members() … … 1005 1046 class using this memory chunk, to initialize the corresponding 1006 1047 class members. 1007 1048 1008 EXAMPLES: 1049 EXAMPLES:: 1050 1009 1051 sage: from sage.ext.gen_interpreters import * 1010 1052 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1011 1053 sage: print mc.init_class_members() … … 1025 1067 class using this memory chunk, to deallocate the corresponding 1026 1068 class members. 1027 1069 1028 EXAMPLES: 1070 EXAMPLES:: 1071 1029 1072 sage: from sage.ext.gen_interpreters import * 1030 1073 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1031 1074 sage: print mc.dealloc_class_members() … … 1042 1085 Returns the string to use to declare the interpreter parameter 1043 1086 corresponding to this memory chunk. 1044 1087 1045 EXAMPLES: 1088 EXAMPLES:: 1089 1046 1090 sage: from sage.ext.gen_interpreters import * 1047 1091 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1048 1092 sage: mc.declare_parameter() … … 1055 1099 Returns a string to put in the __call__ method of a wrapper 1056 1100 class using this memory chunk, to allocate local variables. 1057 1101 1058 EXAMPLES: 1102 EXAMPLES:: 1103 1059 1104 sage: from sage.ext.gen_interpreters import * 1060 1105 sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) 1061 1106 sage: mc.declare_call_locals() … … 1068 1113 Returns the string to pass the argument corresponding to this 1069 1114 memory chunk to the interpreter. 1070 1115 1071 EXAMPLES: 1116 EXAMPLES:: 1117 1072 1118 sage: from sage.ext.gen_interpreters import * 1073 1119 sage: mc = MemoryChunkConstants('constants', ty_mpfr) 1074 1120 sage: mc.pass_argument() … … 1082 1128 memory chunk to the interpreter, for use in the call_c method. 1083 1129 Almost always the same as pass_argument. 1084 1130 1085 EXAMPLES: 1131 EXAMPLES:: 1132 1086 1133 sage: from sage.ext.gen_interpreters import * 1087 1134 sage: mc = MemoryChunkConstants('constants', ty_mpfr) 1088 1135 sage: mc.pass_call_c_argument() … … 1101 1148 This method returns True if this memory chunk is modified by the 1102 1149 interpreter and needs some sort of cleanup when an error happens. 1103 1150 1104 EXAMPLES: 1151 EXAMPLES:: 1152 1105 1153 sage: from sage.ext.gen_interpreters import * 1106 1154 sage: mc = MemoryChunkConstants('constants', ty_mpfr) 1107 1155 sage: mc.needs_cleanup_on_error() … … 1123 1171 ... hardcoded non-stack code 1124 1172 but that hasn't been done yet. 1125 1173 1126 EXAMPLES: 1174 EXAMPLES:: 1175 1127 1176 sage: from sage.ext.gen_interpreters import * 1128 1177 sage: mc = MemoryChunkScratch('scratch', ty_mpfr) 1129 1178 sage: mc.is_stack() … … 1144 1193 INCREF/DECREF and didn't have to explicitly test 1145 1194 is_python_refcounted_stack. 1146 1195 1147 EXAMPLES: 1196 EXAMPLES:: 1197 1148 1198 sage: from sage.ext.gen_interpreters import * 1149 1199 sage: mc = MemoryChunkScratch('args', ty_python) 1150 1200 sage: mc.is_python_refcounted_stack() … … 1171 1221 class using this memory chunk, to initialize the corresponding 1172 1222 class members. 1173 1223 1174 EXAMPLES: 1224 EXAMPLES:: 1225 1175 1226 sage: from sage.ext.gen_interpreters import * 1176 1227 sage: mc = MemoryChunkArguments('args', ty_double) 1177 1228 sage: print mc.init_class_members() … … 1192 1243 class using this memory chunk, to deallocate the corresponding 1193 1244 class members. 1194 1245 1195 EXAMPLES: 1246 EXAMPLES:: 1247 1196 1248 sage: from sage.ext.gen_interpreters import * 1197 1249 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1198 1250 sage: print mc.dealloc_class_members() … … 1209 1261 Returns the string to pass the argument corresponding to this 1210 1262 memory chunk to the interpreter. 1211 1263 1212 EXAMPLES: 1264 EXAMPLES:: 1265 1213 1266 sage: from sage.ext.gen_interpreters import * 1214 1267 sage: mc = MemoryChunkConstants('constants', ty_mpfr) 1215 1268 sage: mc.pass_argument() … … 1231 1284 class using this memory chunk, to initialize the corresponding 1232 1285 class members. 1233 1286 1234 EXAMPLES: 1287 EXAMPLES:: 1288 1235 1289 sage: from sage.ext.gen_interpreters import * 1236 1290 sage: mc = MemoryChunkConstants('constants', ty_mpfr) 1237 1291 sage: print mc.init_class_members() … … 1268 1322 Handle the arguments of __call__ -- copy them into a pre-allocated 1269 1323 array, ready to pass to the interpreter. 1270 1324 1271 EXAMPLES: 1325 EXAMPLES:: 1326 1272 1327 sage: from sage.ext.gen_interpreters import * 1273 1328 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1274 1329 sage: print mc.setup_args() … … 1291 1346 Returns the string to pass the argument corresponding to this 1292 1347 memory chunk to the interpreter. 1293 1348 1294 EXAMPLES: 1349 EXAMPLES:: 1350 1295 1351 sage: from sage.ext.gen_interpreters import * 1296 1352 sage: mc = MemoryChunkArguments('args', ty_mpfr) 1297 1353 sage: mc.pass_argument() … … 1316 1372 the properties described in the documentation for 1317 1373 MemoryChunk.__init__. 1318 1374 1319 EXAMPLES: 1375 EXAMPLES:: 1376 1320 1377 sage: from sage.ext.gen_interpreters import * 1321 1378 sage: mc = MemoryChunkScratch('stack', ty_double, is_stack=True) 1322 1379 sage: mc.name … … 1334 1391 Says whether this memory chunk is a stack. This affects code 1335 1392 generation for instructions using this memory chunk. 1336 1393 1337 EXAMPLES: 1394 EXAMPLES:: 1395 1338 1396 sage: from sage.ext.gen_interpreters import * 1339 1397 sage: mc = MemoryChunkScratch('stack', ty_mpfr, is_stack=True) 1340 1398 sage: mc.is_stack() … … 1353 1411 This method returns True if this memory chunk is modified by the 1354 1412 interpreter and needs some sort of cleanup when an error happens. 1355 1413 1356 EXAMPLES: 1414 EXAMPLES:: 1415 1357 1416 sage: from sage.ext.gen_interpreters import * 1358 1417 sage: mc = MemoryChunkScratch('registers', ty_python) 1359 1418 sage: mc.needs_cleanup_on_error() … … 1371 1430 have left values in the chunk, so we need to go through 1372 1431 the chunk and Py_CLEAR it. 1373 1432 1374 EXAMPLES: 1433 EXAMPLES:: 1434 1375 1435 sage: from sage.ext.gen_interpreters import * 1376 1436 sage: mc = MemoryChunkScratch('registers', ty_python) 1377 1437 sage: print mc.handle_cleanup() … … 1397 1457 Returns a string giving the declarations of the class members 1398 1458 in a wrapper class for this memory chunk. 1399 1459 1400 EXAMPLES: 1460 EXAMPLES:: 1461 1401 1462 sage: from sage.ext.gen_interpreters import * 1402 1463 sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) 1403 1464 sage: mc.declare_class_members() … … 1410 1471 Returns a string to put in the __call__ method of a wrapper 1411 1472 class using this memory chunk, to allocate local variables. 1412 1473 1413 EXAMPLES: 1474 EXAMPLES:: 1475 1414 1476 sage: from sage.ext.gen_interpreters import * 1415 1477 sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) 1416 1478 sage: mc.declare_call_locals() … … 1425 1487 Returns the string to pass the argument corresponding to this 1426 1488 memory chunk to the interpreter. 1427 1489 1428 EXAMPLES: 1490 EXAMPLES:: 1491 1429 1492 sage: from sage.ext.gen_interpreters import * 1430 1493 sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) 1431 1494 sage: mc.pass_argument() … … 1438 1501 Returns the string to pass the argument corresponding to this 1439 1502 memory chunk to the interpreter, for use in the call_c method. 1440 1503 1441 EXAMPLES: 1504 EXAMPLES:: 1505 1442 1506 sage: from sage.ext.gen_interpreters import * 1443 1507 sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) 1444 1508 sage: mc.pass_call_c_argument() … … 1459 1523 Returns a string giving the declarations of the class members 1460 1524 in a wrapper class for this memory chunk. 1461 1525 1462 EXAMPLES: 1526 EXAMPLES:: 1527 1463 1528 sage: from sage.ext.gen_interpreters import * 1464 1529 sage: mc = MemoryChunkPythonArguments('args', ty_python) 1465 1530 """ … … 1471 1536 class using this memory chunk, to initialize the corresponding 1472 1537 class members. 1473 1538 1474 EXAMPLES: 1539 EXAMPLES:: 1540 1475 1541 sage: from sage.ext.gen_interpreters import * 1476 1542 sage: mc = MemoryChunkPythonArguments('args', ty_python) 1477 1543 sage: mc.init_class_members() … … 1486 1552 r""" 1487 1553 Handle the arguments of __call__. Nothing to do. 1488 1554 1489 EXAMPLES: 1555 EXAMPLES:: 1556 1490 1557 sage: from sage.ext.gen_interpreters import * 1491 1558 sage: mc = MemoryChunkPythonArguments('args', ty_python) 1492 1559 sage: mc.setup_args() … … 1498 1565 r""" 1499 1566 Pass the innards of the argument tuple to the interpreter. 1500 1567 1501 EXAMPLES: 1568 EXAMPLES:: 1569 1502 1570 sage: from sage.ext.gen_interpreters import * 1503 1571 sage: mc = MemoryChunkPythonArguments('args', ty_python) 1504 1572 sage: mc.pass_argument() … … 1524 1592 Handle the arguments of __call__. Note: This hardcodes 1525 1593 "self._domain". 1526 1594 1527 EXAMPLES: 1595 EXAMPLES:: 1596 1528 1597 sage: from sage.ext.gen_interpreters import * 1529 1598 sage: mc = MemoryChunkElementArguments('args', ty_python) 1530 1599 sage: mc.setup_args() … … 1536 1605 r""" 1537 1606 Pass the innards of the argument tuple to the interpreter. 1538 1607 1539 EXAMPLES: 1608 EXAMPLES:: 1609 1540 1610 sage: from sage.ext.gen_interpreters import * 1541 1611 sage: mc = MemoryChunkElementArguments('args', ty_python) 1542 1612 sage: mc.pass_argument() … … 1556 1626 1557 1627 Always uses the type ty_python. 1558 1628 1559 EXAMPLES: 1629 EXAMPLES:: 1630 1560 1631 sage: from sage.ext.gen_interpreters import * 1561 1632 sage: mc = MemoryChunkPyConstant('domain') 1562 1633 sage: mc.name … … 1571 1642 Returns a string giving the declarations of the class members 1572 1643 in a wrapper class for this memory chunk. 1573 1644 1574 EXAMPLES: 1645 EXAMPLES:: 1646 1575 1647 sage: from sage.ext.gen_interpreters import * 1576 1648 sage: mc = MemoryChunkPyConstant('domain') 1577 1649 sage: mc.declare_class_members() … … 1587 1659 class using this memory chunk, to initialize the corresponding 1588 1660 class members. 1589 1661 1590 EXAMPLES: 1662 EXAMPLES:: 1663 1591 1664 sage: from sage.ext.gen_interpreters import * 1592 1665 sage: mc = MemoryChunkPyConstant('domain') 1593 1666 sage: mc.init_class_members() … … 1602 1675 Returns the string to use to declare the interpreter parameter 1603 1676 corresponding to this memory chunk. 1604 1677 1605 EXAMPLES: 1678 EXAMPLES:: 1679 1606 1680 sage: from sage.ext.gen_interpreters import * 1607 1681 sage: mc = MemoryChunkPyConstant('domain') 1608 1682 sage: mc.declare_parameter() … … 1615 1689 Returns the string to pass the argument corresponding to this 1616 1690 memory chunk to the interpreter. 1617 1691 1618 EXAMPLES: 1692 EXAMPLES:: 1693 1619 1694 sage: from sage.ext.gen_interpreters import * 1620 1695 sage: mc = MemoryChunkPyConstant('domain') 1621 1696 sage: mc.pass_argument() … … 1659 1734 for a number n (meaning to use that many arguments), or '@C', where 1660 1735 C is the code chunk. 1661 1736 1662 EXAMPLES: 1737 EXAMPLES:: 1738 1663 1739 sage: from sage.ext.gen_interpreters import * 1664 1740 sage: mc_stack = MemoryChunkScratch('stack', ty_double, is_stack=True) 1665 1741 sage: mc_args = MemoryChunkArguments('args', ty_double) … … 1729 1805 address or length. (See the docstring for params_gen for more 1730 1806 information on parameter specifications.) 1731 1807 1732 EXAMPLES: 1808 EXAMPLES:: 1809 1733 1810 sage: from sage.ext.gen_interpreters import * 1734 1811 sage: mc_code = MemoryChunkConstants('code', ty_int) 1735 1812 sage: string_of_addr(mc_code) … … 1807 1884 rules are described in the docstring of the PythonInterpreter 1808 1885 class. 1809 1886 1810 EXAMPLES: 1887 EXAMPLES:: 1888 1811 1889 sage: from sage.ext.gen_interpreters import * 1812 1890 sage: pg = RDFInterpreter().pg 1813 1891 sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') … … 1830 1908 objects and includes its own 1831 1909 reference-counting 1832 1910 1833 EXAMPLES: 1911 EXAMPLES:: 1912 1834 1913 sage: from sage.ext.gen_interpreters import * 1835 1914 1836 1915 sage: pg = RDFInterpreter().pg … … 1904 1983 of its name, a brief stack specification, and its code 1905 1984 (possibly abbreviated). 1906 1985 1907 EXAMPLES: 1986 EXAMPLES:: 1987 1908 1988 sage: from sage.ext.gen_interpreters import * 1909 1989 sage: pg = RDFInterpreter().pg 1910 1990 sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') … … 1924 2004 A helper function for creating instructions implemented by 1925 2005 a single infix binary operator. 1926 2006 1927 EXAMPLES: 2007 EXAMPLES:: 2008 1928 2009 sage: from sage.ext.gen_interpreters import * 1929 2010 sage: pg = RDFInterpreter().pg 1930 2011 sage: instr_infix('mul', pg('SS', 'S'), '*') … … 1937 2018 A helper function for creating instructions implemented by 1938 2019 a two-argument function call. 1939 2020 1940 EXAMPLES: 2021 EXAMPLES:: 2022 1941 2023 sage: from sage.ext.gen_interpreters import * 1942 2024 sage: pg = RDFInterpreter().pg 1943 2025 sage: instr_funcall_2args('atan2', pg('SS', 'S'), 'atan2') … … 1950 2032 A helper function for creating instructions with one input 1951 2033 and one output. 1952 2034 1953 EXAMPLES: 2035 EXAMPLES:: 2036 1954 2037 sage: from sage.ext.gen_interpreters import * 1955 2038 sage: pg = RDFInterpreter().pg 1956 2039 sage: instr_unary('sin', pg('S','S'), 'sin(i0)') … … 1965 2048 A helper function for creating MPFR instructions with two inputs 1966 2049 and one output. 1967 2050 1968 EXAMPLES: 2051 EXAMPLES:: 2052 1969 2053 sage: from sage.ext.gen_interpreters import * 1970 2054 sage: pg = RRInterpreter().pg 1971 2055 sage: instr_funcall_2args_mpfr('add', pg('SS','S'), 'mpfr_add') … … 1978 2062 A helper function for creating MPFR instructions with one input 1979 2063 and one output. 1980 2064 1981 EXAMPLES: 2065 EXAMPLES:: 2066 1982 2067 sage: from sage.ext.gen_interpreters import * 1983 2068 sage: pg = RRInterpreter().pg 1984 2069 sage: instr_funcall_1arg_mpfr('exp', pg('S','S'), 'mpfr_exp') … … 1998 2083 1999 2084 Initializes the following fields: 2000 2085 2001 header -- a code snippet to go at the top of the C interpreter 2086 h_header -- a code snippet to go at the top of the C interpreter 2087 header file 2088 2089 c_header -- a code snippet to go at the top of the C interpreter 2002 2090 source file 2003 pxd_header -- a code snippet to go at the top of the wrapper 2091 pxd_header -- a code snippet to go at the top of the wrapper 2004 2092 class .pxd file 2005 pyx_header -- a code snippet to go at the top of the wrapper 2093 pyx_header -- a code snippet to go at the top of the wrapper 2006 2094 class source file 2007 2095 err_return -- a string indicating the value to be returned 2008 2096 in case of a Python exception … … 2011 2099 don't correspond to memory chunks 2012 2100 extra_members_initialize -- Code to initialize extra_class_members 2013 2101 2014 EXAMPLES: 2102 EXAMPLES:: 2103 2015 2104 sage: from sage.ext.gen_interpreters import * 2016 2105 sage: interp = RDFInterpreter() 2017 sage: interp.h eader2106 sage: interp.h_header 2018 2107 '\n#include <gsl/gsl_math.h>\n' 2108 sage: interp.c_header 2109 '' 2019 2110 sage: interp.pxd_header 2020 2111 '' 2021 2112 sage: interp.pyx_header … … 2030 2121 sage: interp.extra_members_initialize 2031 2122 '' 2032 2123 """ 2033 self.header = '' 2124 self.h_header = '' 2125 self.c_header = '' 2034 2126 self.pxd_header = '' 2035 2127 self.pyx_header = '' 2036 2128 self.err_return = 'NULL' … … 2045 2137 Must be called at the end of __init__ by any subclass of 2046 2138 InterpreterSpec. 2047 2139 2048 EXAMPLES: 2140 EXAMPLES:: 2141 2049 2142 sage: from sage.ext.gen_interpreters import * 2050 2143 sage: interp = RDFInterpreter() 2051 2144 sage: interp.instr_descs[5].opcode … … 2087 2180 method (that bypasses the Python call overhead) 2088 2181 (default True) 2089 2182 2090 EXAMPLES: 2183 EXAMPLES:: 2184 2091 2185 sage: from sage.ext.gen_interpreters import * 2092 2186 sage: rdf = RDFInterpreter() 2093 2187 sage: rr = RRInterpreter() … … 2135 2229 r""" 2136 2230 Initialize an RDFInterpreter. 2137 2231 2138 EXAMPLES: 2232 EXAMPLES:: 2233 2139 2234 sage: from sage.ext.gen_interpreters import * 2140 2235 sage: interp = RDFInterpreter() 2141 2236 sage: interp.name … … 2187 2282 pg = params_gen(A=self.mc_args, C=self.mc_constants, D=self.mc_code, 2188 2283 S=self.mc_stack, P=self.mc_py_constants) 2189 2284 self.pg = pg 2190 self.h eader = """2285 self.h_header = """ 2191 2286 #include <gsl/gsl_math.h> 2192 2287 """ 2193 2288 instrs = [ … … 2265 2360 r""" 2266 2361 Initialize a CDFInterpreter. 2267 2362 2268 EXAMPLES: 2363 EXAMPLES:: 2364 2269 2365 sage: from sage.ext.gen_interpreters import * 2270 2366 sage: interp = CDFInterpreter() 2271 2367 sage: interp.name … … 2297 2393 pg = params_gen(A=self.mc_args, C=self.mc_constants, D=self.mc_code, 2298 2394 S=self.mc_stack, P=self.mc_py_constants) 2299 2395 self.pg = pg 2300 self.h eader = """2396 self.h_header = """ 2301 2397 #include <stdlib.h> 2302 2398 #include <complex.h> 2303 2399 2304 2400 typedef double complex double_complex; 2305 2401 2306 2402 extern int cdf_py_call_helper(PyObject*, int, double complex*, double complex*); 2307 2308 2403 """ 2309 2404 self.pxd_header = """ 2310 2405 # This is to work around a header ordering bug in Cython < 0.11 … … 2402 2497 r""" 2403 2498 Initialize an RDFInterpreter. 2404 2499 2405 EXAMPLES: 2500 EXAMPLES:: 2501 2406 2502 sage: from sage.ext.gen_interpreters import * 2407 2503 sage: interp = RRInterpreter() 2408 2504 sage: interp.name … … 2421 2517 2422 2518 That py_call instruction is particularly interesting, and 2423 2519 demonstrates a useful technique to let you use Cython code 2424 in an interpreter. Let's look more closely: 2520 in an interpreter. Let's look more closely:: 2425 2521 2426 2522 sage: print instrs['py_call'].code 2427 2523 if (!rr_py_call_helper(domain, i0, n_i1, i1, o0)) { … … 2429 2525 } 2430 2526 2431 2527 This instruction makes use of the function rr_py_call_helper, 2432 which is declared... 2433 2434 sage: print interp.header 2528 which is declared:: 2529 2530 sage: print interp.h_header 2531 <BLANKLINE> 2435 2532 #include <mpfr.h> 2533 <BLANKLINE> 2436 2534 extern int rr_py_call_helper(PyObject*, PyObject*, int, mpfr_t*, mpfr_t*); 2437 2535 2438 In particular, rr_py_call_helper comes from: 2439 2536 In particular, rr_py_call_helper comes from:: 2537 2440 2538 sage: print interp.pyx_header 2441 2539 cdef public bint rr_py_call_helper(object domain, object fn, 2442 2540 int n_args, … … 2469 2567 S=self.mc_stack, 2470 2568 P=self.mc_py_constants) 2471 2569 self.pg = pg 2472 self.h eader = """2570 self.h_header = """ 2473 2571 #include <mpfr.h> 2572 2474 2573 extern int rr_py_call_helper(PyObject*, PyObject*, int, mpfr_t*, mpfr_t*); 2475 """.strip() 2476 2574 """ 2477 2575 self.pxd_header = """ 2478 2576 from sage.rings.real_mpfr cimport RealField_class, RealNumber 2479 2577 from sage.libs.mpfr cimport * … … 2572 2670 r""" 2573 2671 Initialize a PythonInterpreter. 2574 2672 2575 EXAMPLES: 2673 EXAMPLES:: 2674 2576 2675 sage: from sage.ext.gen_interpreters import * 2577 2676 sage: interp = PythonInterpreter() 2578 2677 sage: interp.name … … 2598 2697 pg = params_gen(A=self.mc_args, C=self.mc_constants, D=self.mc_code, 2599 2698 S=self.mc_stack) 2600 2699 self.pg = pg 2601 self.header = """ 2602 #include <Python.h> 2700 self.h_header = """ 2603 2701 #define CHECK(x) (x != NULL) 2604 2702 """ 2605 2703 instrs = [ … … 2664 2762 r""" 2665 2763 Initialize an ElementInterpreter. 2666 2764 2667 EXAMPLES: 2765 EXAMPLES:: 2766 2668 2767 sage: from sage.ext.gen_interpreters import * 2669 2768 sage: interp = ElementInterpreter() 2670 2769 sage: interp.name … … 2688 2787 self.mc_domain_info = MemoryChunkPyConstant('domain') 2689 2788 self.chunks = [self.mc_args, self.mc_constants, self.mc_stack, 2690 2789 self.mc_domain_info, self.mc_code] 2691 self.header = """ 2692 #include <Python.h> 2693 2790 self.h_header = """ 2694 2791 extern PyObject* el_check_element(PyObject*, PyObject*); 2695 2792 2696 2793 #define CHECK(x) do_check(&(x), domain) … … 2735 2832 INPUTS: 2736 2833 spec -- an InterpreterSpec 2737 2834 2738 EXAMPLES: 2835 EXAMPLES:: 2836 2739 2837 sage: from sage.ext.gen_interpreters import * 2740 2838 sage: interp = RDFInterpreter() 2741 2839 sage: gen = InterpreterGenerator(interp) … … 2763 2861 See the documentation for the get_interpreter method for more 2764 2862 information. 2765 2863 2766 EXAMPLES: 2864 EXAMPLES:: 2865 2767 2866 sage: from sage.ext.gen_interpreters import * 2768 2867 sage: interp = RDFInterpreter() 2769 2868 sage: gen = InterpreterGenerator(interp) … … 2909 3008 wrapper) or the definition (in the C interpreter) of the interpreter 2910 3009 function. 2911 3010 2912 EXAMPLES: 3011 EXAMPLES:: 3012 2913 3013 sage: from sage.ext.gen_interpreters import * 2914 3014 sage: interp = ElementInterpreter() 2915 3015 sage: gen = InterpreterGenerator(interp) … … 2938 3038 {% endif %}{{ ch.declare_parameter() }} 2939 3039 {%- endfor %})""", ret_ty=ret_ty, s=s) 2940 3040 3041 def write_interpreter_header(self, write): 3042 r""" 3043 Generate the header code for the C interpreter. 3044 3045 EXAMPLES:: 3046 3047 sage: from sage.ext.gen_interpreters import * 3048 sage: interp = RDFInterpreter() 3049 sage: gen = InterpreterGenerator(interp) 3050 sage: import cStringIO 3051 sage: buff = cStringIO.StringIO() 3052 sage: gen.write_interpreter_header(buff.write) 3053 sage: print buff.getvalue() 3054 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ ... 3055 """ 3056 s = self._spec 3057 w = write 3058 w(je(""" 3059 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3060 #include <Python.h> 3061 {% print s.h_header %} 3062 3063 {{ myself.func_header() }}; 3064 """, s=s, i=indent_lines, myself=self)) 3065 2941 3066 def write_interpreter(self, write): 2942 3067 r""" 2943 3068 Generate the code for the C interpreter. … … 2949 3074 See the documentation for the get_interpreter method for more 2950 3075 information. 2951 3076 2952 EXAMPLES: 3077 EXAMPLES:: 3078 2953 3079 sage: from sage.ext.gen_interpreters import * 2954 3080 sage: interp = RDFInterpreter() 2955 3081 sage: gen = InterpreterGenerator(interp) … … 2963 3089 w = write 2964 3090 w(je(""" 2965 3091 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 2966 #include <Python.h> 2967 {% print s.header %} 3092 #include "interp_{{ s.name }}.h" 3093 {% print s.c_header %} 3094 2968 3095 {{ myself.func_header() }} { 2969 3096 while (1) { 2970 3097 switch (*code++) { … … 2992 3119 See the documentation for the get_wrapper method for more 2993 3120 information. 2994 3121 2995 EXAMPLES: 3122 EXAMPLES:: 3123 2996 3124 sage: from sage.ext.gen_interpreters import * 2997 3125 sage: interp = RDFInterpreter() 2998 3126 sage: gen = InterpreterGenerator(interp) … … 3057 3185 from sage.ext.fast_callable cimport Wrapper 3058 3186 {% print s.pyx_header %} 3059 3187 3060 cdef extern {{ myself.func_header(cython=true) -}} 3188 cdef extern from "interp_{{ s.name }}.h": 3189 {{ myself.func_header(cython=true) -}} 3061 3190 {% if s.err_return != 'NULL' %} 3062 except? {{ s.err_return -}}3191 except? {{ s.err_return }} 3063 3192 {% endif %} 3064 3193 3065 3194 cdef class Wrapper_{{ s.name }}(Wrapper): … … 3156 3285 See the documentation for the get_pxd method for more 3157 3286 information. 3158 3287 3159 EXAMPLES: 3288 EXAMPLES:: 3289 3160 3290 sage: from sage.ext.gen_interpreters import * 3161 3291 sage: interp = RDFInterpreter() 3162 3292 sage: gen = InterpreterGenerator(interp) … … 3199 3329 {% endif %} 3200 3330 """, s=s, myself=self, types=types, indent_lines=indent_lines, arg_ch=arg_ch)) 3201 3331 3332 def get_interpreter_header(self): 3333 r""" 3334 Returns the header code for the C interpreter. 3335 3336 EXAMPLES: 3337 3338 First we get the InterpreterSpec for several interpreters:: 3339 3340 sage: from sage.ext.gen_interpreters import * 3341 sage: rdf_spec = RDFInterpreter() 3342 sage: rr_spec = RRInterpreter() 3343 sage: cdf_spec = CDFInterpreter() 3344 sage: el_spec = ElementInterpreter() 3345 3346 Then we get the actual interpreter code:: 3347 3348 sage: rdf_interp_h = InterpreterGenerator(rdf_spec).get_interpreter_header() 3349 sage: rr_interp_h = InterpreterGenerator(rr_spec).get_interpreter_header() 3350 sage: cdf_interp_h = InterpreterGenerator(cdf_spec).get_interpreter_header() 3351 sage: el_interp_h = InterpreterGenerator(el_spec).get_interpreter_header() 3352 3353 Each interpreter starts with a file header; this can be 3354 customized on a per-interpreter basis:: 3355 3356 sage: print rdf_interp_h 3357 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3358 #include <Python.h> 3359 <BLANKLINE> 3360 #include <gsl/gsl_math.h> 3361 ... 3362 sage: print rr_interp_h 3363 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3364 #include <Python.h> 3365 <BLANKLINE> 3366 #include <mpfr.h> 3367 ... 3368 sage: print cdf_interp_h 3369 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3370 #include <Python.h> 3371 <BLANKLINE> 3372 #include <stdlib.h> 3373 #include <complex.h> 3374 ... 3375 sage: print el_interp_h 3376 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3377 #include <Python.h> 3378 <BLANKLINE> 3379 extern PyObject* el_check_element(PyObject*, PyObject*); 3380 <BLANKLINE> 3381 #define CHECK(x) do_check(&(x), domain) 3382 ... 3383 """ 3384 import cStringIO 3385 buff = cStringIO.StringIO() 3386 self.write_interpreter_header(buff.write) 3387 return buff.getvalue() 3388 3202 3389 def get_interpreter(self): 3203 3390 r""" 3204 3391 Returns the code for the C interpreter. 3205 3392 3206 3393 EXAMPLES: 3207 3394 3208 First we get the InterpreterSpec for several interpreters: 3395 First we get the InterpreterSpec for several interpreters:: 3396 3209 3397 sage: from sage.ext.gen_interpreters import * 3210 3398 sage: rdf_spec = RDFInterpreter() 3211 3399 sage: rr_spec = RRInterpreter() 3212 3400 sage: el_spec = ElementInterpreter() 3213 3401 3214 Then we get the actual interpreter code: 3402 Then we get the actual interpreter code:: 3403 3215 3404 sage: rdf_interp = InterpreterGenerator(rdf_spec).get_interpreter() 3216 3405 sage: rr_interp = InterpreterGenerator(rr_spec).get_interpreter() 3217 3406 sage: el_interp = InterpreterGenerator(el_spec).get_interpreter() … … 3219 3408 Now we can look through these interpreters. 3220 3409 3221 3410 Each interpreter starts with a file header; this can be 3222 customized on a per-interpreter basis: 3411 customized on a per-interpreter basis:: 3412 3223 3413 sage: print rr_interp 3224 3414 /* Automatically generated by ext/gen_interpreters.py. Do not edit! */ 3225 #include <Python.h> 3226 #include <mpfr.h> 3415 #include "interp_rr.h" 3227 3416 ... 3228 3417 3229 3418 Next is the function header, with one argument per memory chunk 3230 in the interpreter spec. 3419 in the interpreter spec:: 3420 3231 3421 sage: print el_interp 3232 3422 /* ... */ ... 3233 3423 PyObject* interp_el(PyObject** args, … … 3239 3429 3240 3430 Currently, the interpreters have a very simple structure; just 3241 3431 grab the next instruction and execute it, in a switch 3242 statement. 3432 statement:: 3433 3243 3434 sage: print rdf_interp 3244 3435 /* ... */ ... 3245 3436 while (1) { … … 3247 3438 ... 3248 3439 3249 3440 Then comes the code for each instruction. Here is one of the 3250 simplest instructions: 3441 simplest instructions:: 3442 3251 3443 sage: print rdf_interp 3252 3444 /* ... */ ... 3253 3445 case 10: /* neg */ … … 3265 3457 3266 3458 Let's look at the MPFR-based version of this instruction. 3267 3459 This is an example of an interpreter with an auto-reference 3268 type. 3460 type:: 3461 3269 3462 sage: print rr_interp 3270 3463 /* ... */ ... 3271 3464 case 10: /* neg */ … … 3284 3477 mpfr_t variables. 3285 3478 3286 3479 For completeness, let's look at this instruction in the 3287 Python-object element interpreter. 3480 Python-object element interpreter:: 3481 3288 3482 sage: print el_interp 3289 3483 /* ... */ ... 3290 3484 case 10: /* neg */ … … 3321 3515 3322 3516 EXAMPLES: 3323 3517 3324 First we get the InterpreterSpec for several interpreters: 3518 First we get the InterpreterSpec for several interpreters:: 3519 3325 3520 sage: from sage.ext.gen_interpreters import * 3326 3521 sage: rdf_spec = RDFInterpreter() 3327 3522 sage: rr_spec = RRInterpreter() 3328 3523 sage: el_spec = ElementInterpreter() 3329 3524 3330 Then we get the actual wrapper code: 3525 Then we get the actual wrapper code:: 3526 3331 3527 sage: rdf_wrapper = InterpreterGenerator(rdf_spec).get_wrapper() 3332 3528 sage: rr_wrapper = InterpreterGenerator(rr_spec).get_wrapper() 3333 3529 sage: el_wrapper = InterpreterGenerator(el_spec).get_wrapper() … … 3336 3532 3337 3533 Each wrapper starts with a file header; this can be 3338 3534 customized on a per-interpreter basis (some blank lines have been 3339 elided below): 3535 elided below):: 3536 3340 3537 sage: print rdf_wrapper 3341 3538 # Automatically generated by ext/gen_interpreters.py. Do not edit! 3342 3539 include "../stdsage.pxi" … … 3355 3552 from sage.ext.fast_callable cimport Wrapper 3356 3553 ... 3357 3554 3358 Next is the declaration of the C interpreter function. 3555 Next is the declaration of the C interpreter function:: 3556 3359 3557 sage: print rdf_wrapper 3360 3558 # ... 3361 cdef extern double interp_rdf(double* args, 3559 cdef extern from "interp_rdf.h": 3560 double interp_rdf(double* args, 3362 3561 double* constants, 3363 3562 PyObject** py_constants, 3364 3563 double* stack, … … 3375 3574 3376 3575 Next comes the actual wrapper class. The member declarations 3377 3576 are in the corresponding pxd file; see the documentation for 3378 get_pxd to see them. 3577 get_pxd to see them:: 3578 3379 3579 sage: print rdf_wrapper 3380 3580 # ... 3381 3581 cdef class Wrapper_rdf(Wrapper): 3382 3582 # attributes are declared in corresponding .pxd file 3383 3583 ... 3384 3584 3385 Next is the __init__ method, which starts like this: 3585 Next is the __init__ method, which starts like this:: 3586 3386 3587 sage: print rdf_wrapper 3387 3588 # ... 3388 3589 def __init__(self, args): … … 3412 3613 3413 3614 Basically the same code is repeated, with minor variations, for 3414 3615 each memory chunk; for brevity, we'll only show the code 3415 for 'constants' .3616 for 'constants':: 3416 3617 3417 3618 sage: print rdf_wrapper 3418 3619 # ... … … 3428 3629 double*. 3429 3630 3430 3631 The RRInterpreter version is more complicated, because it has to 3431 call mpfr_init. 3632 call mpfr_init:: 3633 3432 3634 sage: print rr_wrapper 3433 3635 # ... 3434 3636 cdef RealNumber rn … … 3446 3648 3447 3649 And as described in the documentation for get_pxd, in 3448 3650 Python-object based interpreters we actually allocate the 3449 memory as a Python list. 3651 memory as a Python list:: 3652 3450 3653 sage: print el_wrapper 3451 3654 # ... 3452 3655 val = args['constants'] … … 3458 3661 ... 3459 3662 3460 3663 Of course, once we've allocated the memory, we eventually have 3461 to free it. (Again, we'll only look at 'constants'.) 3664 to free it. (Again, we'll only look at 'constants'.):: 3665 3462 3666 sage: print rdf_wrapper 3463 3667 # ... 3464 3668 def __dealloc__(self): … … 3468 3672 ... 3469 3673 3470 3674 The RRInterpreter code is more complicated again because it has 3471 to call mpfr_clear. 3675 to call mpfr_clear:: 3676 3472 3677 sage: print rr_wrapper 3473 3678 # ... 3474 3679 def __dealloc__(self): … … 3492 3697 We optionally adjust the return value of the interpreter 3493 3698 (currently only the RDF/float interpreter performs this step; 3494 3699 this is the only place where domain=RDF differs than 3495 domain=float): 3700 domain=float):: 3496 3701 3497 3702 sage: print rdf_wrapper 3498 3703 # ... … … 3518 3723 stack totally clear when the interpreter finishes. However, 3519 3724 this doesn't happen if the C interpreter raises an exception. 3520 3725 In that case, we have to clear out any remnants from the stack 3521 in the wrapper. 3726 in the wrapper:: 3727 3522 3728 sage: print el_wrapper 3523 3729 # ... 3524 3730 try: … … 3536 3742 3537 3743 Finally, we define a cdef call_c method, for quickly calling 3538 3744 this object from Cython. (The method is omitted from 3539 Python-object based interpreters.) 3745 Python-object based interpreters.):: 3540 3746 sage: print rdf_wrapper 3541 3747 # ... 3542 3748 cdef bint call_c(self, … … 3553 3759 3554 3760 The method for the RR interpreter is slightly different, because 3555 3761 the interpreter takes a pointer to a result location instead of 3556 returning the value. 3762 returning the value:: 3763 3557 3764 sage: print rr_wrapper 3558 3765 # ... 3559 3766 cdef bint call_c(self, … … 3586 3793 ipow instruction is defined over. 3587 3794 3588 3795 First the part that maps instruction names to 3589 (CompilerInstrSpec, opcode) pairs .3796 (CompilerInstrSpec, opcode) pairs:: 3590 3797 3591 3798 sage: print rdf_wrapper 3592 3799 # ... … … 3605 3812 }, ...) 3606 3813 3607 3814 There's also a table that maps opcodes to (instruction name, 3608 CompilerInstrSpec) pairs: 3815 CompilerInstrSpec) pairs:: 3816 3609 3817 sage: print rdf_wrapper 3610 3818 # ... 3611 3819 metadata = InterpreterMetadata(..., by_opcode=[ … … 3621 3829 ... 3622 3830 ], ...) 3623 3831 3624 And then the ipow range: 3832 And then the ipow range:: 3833 3625 3834 sage: print rdf_wrapper 3626 3835 # ... 3627 3836 metadata = InterpreterMetadata(..., … … 3641 3850 EXAMPLES: 3642 3851 3643 3852 First we get the InterpreterSpec for several interpreters: 3853 3644 3854 sage: from sage.ext.gen_interpreters import * 3645 3855 sage: rdf_spec = RDFInterpreter() 3646 3856 sage: rr_spec = RRInterpreter() 3647 3857 sage: el_spec = ElementInterpreter() 3648 3858 3649 Then we get the corresponding .pxd: 3859 Then we get the corresponding .pxd:: 3860 3650 3861 sage: rdf_pxd = InterpreterGenerator(rdf_spec).get_pxd() 3651 3862 sage: rr_pxd = InterpreterGenerator(rr_spec).get_pxd() 3652 3863 sage: el_pxd = InterpreterGenerator(el_spec).get_pxd() … … 3655 3866 3656 3867 Each .pxd starts with a file header; this can be 3657 3868 customized on a per-interpreter basis (some blank lines have been 3658 elided below): 3869 elided below):: 3870 3659 3871 sage: print rdf_pxd 3660 3872 # Automatically generated by ext/gen_interpreters.py. Do not edit! 3661 3873 from cpython cimport PyObject … … 3668 3880 ... 3669 3881 3670 3882 Next and last is the declaration of the wrapper class, which 3671 starts off with a list of member declarations. 3883 starts off with a list of member declarations:: 3884 3672 3885 sage: print rdf_pxd 3673 3886 # ... 3674 3887 cdef class Wrapper_rdf(Wrapper): … … 3689 3902 ElementInterpreter version. To simplify our handling of 3690 3903 reference counting and garbage collection, in a Python-object 3691 3904 based interpreter, we allocate arrays as Python lists, 3692 and then pull the array out of the innards of the list. 3905 and then pull the array out of the innards of the list:: 3906 3693 3907 sage: print el_pxd 3694 3908 # ... 3695 3909 cdef object _list_stack … … 3699 3913 3700 3914 Then, at the end of the wrapper class, we declare a cdef method 3701 3915 for quickly calling the wrapper object from Cython. (This method 3702 is omitted from Python-object based interpreters.) 3916 is omitted from Python-object based interpreters.):: 3917 3703 3918 sage: print rdf_pxd 3704 3919 # ... 3705 3920 cdef bint call_c(self, … … 3722 3937 Writes value to the file named fn, if value is different than 3723 3938 the current contents. 3724 3939 3725 EXAMPLES: 3940 EXAMPLES:: 3941 3726 3942 sage: from sage.ext.gen_interpreters import * 3727 3943 sage: def last_modification(fn): return os.stat(fn).st_mtime 3728 3944 sage: fn = tmp_filename('gen_interp') … … 3768 3984 Given an InterpreterSpec, writes the C interpreter and the Cython 3769 3985 wrapper (generates a pyx and a pxd file). 3770 3986 3771 EXAMPLES: 3987 EXAMPLES:: 3988 3772 3989 sage: from sage.ext.gen_interpreters import * 3773 3990 sage: testdir = tmp_filename() 3774 3991 sage: os.mkdir(testdir) … … 3779 3996 """ 3780 3997 ig = InterpreterGenerator(interp_spec) 3781 3998 interp_fn = '%s/interp_%s.c' % (dir, interp_spec.name) 3999 header_fn = '%s/interp_%s.h' % (dir, interp_spec.name) 3782 4000 wrapper_fn = '%s/wrapper_%s.pyx' % (dir, interp_spec.name) 3783 4001 pxd_fn = '%s/wrapper_%s.pxd' % (dir, interp_spec.name) 3784 4002 interp = ig.get_interpreter() 4003 header = ig.get_interpreter_header() 3785 4004 wrapper = ig.get_wrapper() 3786 4005 pxd = ig.get_pxd() 3787 4006 write_if_changed(interp_fn, interp) 4007 write_if_changed(header_fn, header) 3788 4008 write_if_changed(wrapper_fn, wrapper) 3789 4009 write_if_changed(pxd_fn, pxd) 3790 4010 … … 3793 4013 Check whether the interpreter and wrapper sources have been written 3794 4014 since the last time this module was changed. If not, write them. 3795 4015 3796 EXAMPLES: 4016 EXAMPLES:: 4017 3797 4018 sage: from sage.ext.gen_interpreters import * 3798 4019 sage: testdir = tmp_filename() 3799 4020 sage: os.mkdir(testdir)