Merge remote-tracking branch 'upstream/master' into list_index
This commit is contained in:
commit
7e73a8fd09
97
logo/FONT-LICENSE.txt
Normal file
97
logo/FONT-LICENSE.txt
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
The font used for the Micro Python logo is "Exo",
|
||||||
|
http://www.google.com/fonts/specimen/Exo.
|
||||||
|
|
||||||
|
Copyright (c) 2013, Natanael Gama (https://plus.google.com/u/0/+NatanaelGama),
|
||||||
|
with Reserved Font Name Exo.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
9888
logo/vector-text-R2000.dxf
Normal file
9888
logo/vector-text-R2000.dxf
Normal file
File diff suppressed because it is too large
Load Diff
137
logo/vector-text.svg
Normal file
137
logo/vector-text.svg
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
version="1.1"
|
||||||
|
width="765.09967"
|
||||||
|
height="158.82559"
|
||||||
|
id="svg2">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<symbol
|
||||||
|
id="*Paper_Space" />
|
||||||
|
<symbol
|
||||||
|
id="*Model_Space" />
|
||||||
|
<pattern
|
||||||
|
height="8"
|
||||||
|
id="Hatch"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="8"
|
||||||
|
x="0"
|
||||||
|
y="0">
|
||||||
|
<path
|
||||||
|
d="M8 4 l-4,4"
|
||||||
|
linecap="square"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="0.25"
|
||||||
|
id="path3030" />
|
||||||
|
<path
|
||||||
|
d="M6 2 l-4,4"
|
||||||
|
linecap="square"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="0.25"
|
||||||
|
id="path3032" />
|
||||||
|
<path
|
||||||
|
d="M4 0 l-4,4"
|
||||||
|
linecap="square"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="0.25"
|
||||||
|
id="path3034" />
|
||||||
|
</pattern>
|
||||||
|
<marker
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto"
|
||||||
|
id="DistanceX"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
d="M 3,-3 -3,3 M 0,-5 0,5"
|
||||||
|
id="path3027"
|
||||||
|
style="stroke:#000000;stroke-width:0.5" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-463.61971,-103.98436)"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
transform="translate(474.11971,-800.05225)"
|
||||||
|
id="g3038" />
|
||||||
|
<path
|
||||||
|
d="m 474.11971,216.99105 8.38645,-95.79752 25.49501,0 15.95818,65.41468 15.86248,-65.41468 25.39886,0 8.91346,95.79752 -18.06677,0 -6.32579,-64.02471 -15.43095,64.02471 -20.41521,0 -16.10201,-64.02471 -5.60688,64.02471 -18.06683,0 0,0 z"
|
||||||
|
id="path3042"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 585.06082,216.99105 0,-69.48774 18.35416,0 0,69.48774 -18.35416,0 0,0 z"
|
||||||
|
id="path3044"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 584.4376,137.15201 0,-11.54959 a 3.667629,3.667629 0 0 1 0.77873,-2.55179 3.012482,3.012482 0 0 1 2.33617,-0.85049 l 13.75388,0 a 2.665344,2.665344 0 0 1 2.15675,0.85049 3.874957,3.874957 0 0 1 0.71861,2.55179 l 0,11.54959 a 3.170925,3.170925 0 0 1 -0.71861,2.2641 2.844672,2.844672 0 0 1 -2.15675,0.7548 l -13.75388,0 a 3.183373,3.183373 0 0 1 -2.27606,-0.79069 2.91442,2.91442 0 0 1 -0.83884,-2.22821 l 0,0 z"
|
||||||
|
id="path3046"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 614.10181,182.15117 a 104.76828,104.76828 0 0 1 0.4073,-9.62042 61.45992,61.45992 0 0 1 1.22222,-7.96728 34.257292,34.257292 0 0 1 2.02456,-6.2896 18.589823,18.589823 0 0 1 2.81556,-4.58861 18.372489,18.372489 0 0 1 7.1404,-5.29557 25.178476,25.178476 0 0 1 9.29684,-1.55745 139.56012,139.56012 0 0 1 17.5877,1.01826 80.33883,80.33883 0 0 1 14.32895,3.05509 l 0,10.97421 a 913.84864,913.84864 0 0 0 -25.74636,0.0659 25.765381,25.765381 0 0 0 -2.98332,0.19783 10.614363,10.614363 0 0 0 -3.33051,1.29399 5.904958,5.904958 0 0 0 -2.63582,3.23482 31.868466,31.868466 0 0 0 -1.36576,6.43958 73.360882,73.360882 0 0 0 -0.45546,8.67975 97.248263,97.248263 0 0 0 0.31162,8.4166 30.406975,30.406975 0 0 0 0.93453,5.64883 13.352632,13.352632 0 0 0 1.53966,3.54027 6.228032,6.228032 0 0 0 2.12638,2.09068 9.932543,9.932543 0 0 0 3.12103,1.0243 26.061579,26.061579 0 0 0 4.52268,0.3415 252.7863,252.7863 0 0 0 21.37366,-0.9105 l 3.49828,-0.2876 0,11.5494 a 31.724353,31.724353 0 0 1 -11.74129,3.6421 158.5758,158.5758 0 0 1 -14.80802,0.8147 l -0.76677,0 a 36.794709,36.794709 0 0 1 -14.74822,-1.7372 18.781067,18.781067 0 0 1 -7.00851,-5.2116 19.357438,19.357438 0 0 1 -2.91432,-4.6785 33.943497,33.943497 0 0 1 -2.0816,-6.31978 60.236572,60.236572 0 0 1 -1.24921,-7.96117 102.18754,102.18754 0 0 1 -0.4162,-9.60257 l 0,0 z"
|
||||||
|
id="path3048"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 679.80386,216.99105 0,-69.48774 15.43095,0 2.87536,8.76962 a 37.96926,37.96926 0 0 1 9.88418,-7.0806 23.135088,23.135088 0 0 1 10.0038,-2.36009 49.347494,49.347494 0 0 1 4.75639,0.19169 12.434249,12.434249 0 0 1 2.95909,0.57507 l 0,17.68339 a 99.917807,99.917807 0 0 0 -9.91977,-0.38338 37.215466,37.215466 0 0 0 -5.73876,0.4073 21.894431,21.894431 0 0 0 -4.66069,1.22222 14.160958,14.160958 0 0 0 -3.88165,2.33617 19.705025,19.705025 0 0 0 -3.40259,3.74978 l 0,44.37657 -18.30631,0 0,0 z"
|
||||||
|
id="path3050"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 754.27554,165.28239 a 101.69692,101.69692 0 0 0 -2.0126,9.66857 52.999906,52.999906 0 0 0 -0.67107,7.91912 69.045724,69.045724 0 0 0 0.67107,10.97428 16.561755,16.561755 0 0 0 0.94036,3.45043 8.854315,8.854315 0 0 0 1.47954,2.49198 7.551397,7.551397 0 0 0 3.97766,2.53988 27.363959,27.363959 0 0 0 6.03841,0.5272 45.079768,45.079768 0 0 0 5.70257,-0.2636 9.767782,9.767782 0 0 0 3.66696,-1.3179 5.86791,5.86791 0 0 0 2.53952,-3.2587 27.050263,27.050263 0 0 0 1.25749,-5.53508 55.730735,55.730735 0 0 0 0.42019,-7.21251 158.11284,158.11284 0 0 0 -0.31284,-11.78882 30.217313,30.217313 0 0 0 -1.10107,-6.30187 5.911226,5.911226 0 0 0 -2.51499,-3.57004 10.986507,10.986507 0 0 0 -3.58967,-1.47372 21.310199,21.310199 0 0 0 -4.82232,-0.49134 57.038011,57.038011 0 0 0 -4.65456,0.16194 17.096194,17.096194 0 0 0 -3.08484,0.4852 7.14005,7.14005 0 0 0 -3.92981,2.99498 l 0,0 z"
|
||||||
|
id="path3052"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 733.28556,183.589 a 92.623124,92.623124 0 0 1 1.03022,-15.09572 34.923348,34.923348 0 0 1 3.25874,-10.35129 16.997543,16.997543 0 0 1 6.15803,-6.70918 27.334986,27.334986 0 0 1 8.92573,-3.45043 58.555226,58.555226 0 0 1 12.30409,-1.15014 64.576878,64.576878 0 0 1 8.27122,0.49134 39.74236,39.74236 0 0 1 6.88921,1.47341 24.998971,24.998971 0 0 1 5.51149,2.4561 17.713605,17.713605 0 0 1 4.12825,3.43847 20.147183,20.147183 0 0 1 3.00878,4.6935 33.054914,33.054914 0 0 1 2.15,6.2209 56.120992,56.120992 0 0 1 1.28816,7.7486 92.689443,92.689443 0 0 1 0.42939,9.27599 93.582889,93.582889 0 0 1 -0.42325,9.252 55.494869,55.494869 0 0 1 -1.2667,7.67662 31.745279,31.745279 0 0 1 -2.11013,6.10108 18.697304,18.697304 0 0 1 -2.95663,4.5258 17.025604,17.025604 0 0 1 -4.09145,3.2707 25.393667,25.393667 0 0 1 -5.51762,2.3362 41.865621,41.865621 0 0 1 -6.94227,1.4018 69.328567,69.328567 0 0 1 -8.36845,0.4672 63.054282,63.054282 0 0 1 -8.23963,-0.5002 39.37126,39.37126 0 0 1 -6.89197,-1.5006 25.293848,25.293848 0 0 1 -5.544,-2.5009 18.401937,18.401937 0 0 1 -4.19634,-3.5014 20.408256,20.408256 0 0 1 -2.97719,-4.5227 30.962036,30.962036 0 0 1 -2.12639,-5.85256 49.71676,49.71676 0 0 1 -1.2762,-7.18239 79.250711,79.250711 0 0 1 -0.42509,-8.5122 l 0,0 z"
|
||||||
|
id="path3054"
|
||||||
|
style="fill:none;stroke:#bebebe" />
|
||||||
|
<path
|
||||||
|
d="m 848.06104,137.39155 -21.46935,0 0,28.03468 21.37427,0 a 9.641122,9.641122 0 0 0 5.07904,-1.19799 6.289092,6.289092 0 0 0 1.92917,-1.80311 10.492988,10.492988 0 0 0 1.37711,-2.82139 28.324879,28.324879 0 0 0 1.10107,-8.69815 26.4065,26.4065 0 0 0 -0.58581,-5.91236 12.140086,12.140086 0 0 0 -1.76048,-4.22332 7.47549,7.47549 0 0 0 -2.93517,-2.5337 9.405207,9.405207 0 0 0 -4.10985,-0.84466 l 0,0 z"
|
||||||
|
id="path3070"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 957.94734,161.35288 0,-10.20776 11.26221,-3.78566 3.01798,-19.36075 15.28924,0 0,19.36075 15.57453,0 0,13.99342 -15.57453,0 0,27.89084 a 42.025479,42.025479 0 0 0 0.35885,5.97244 12.328486,12.328486 0 0 0 1.07653,3.82783 8.288976,8.288976 0 0 0 4.45643,3.95366 211.85149,211.85149 0 0 0 6.12183,2.0487 14.600045,14.600045 0 0 0 2.64989,0.6828 l 0,11.2619 -15.95782,0 a 16.804947,16.804947 0 0 1 -7.44373,-1.5545 13.606965,13.606965 0 0 1 -5.31827,-4.6635 22.537606,22.537606 0 0 1 -3.18973,-7.7724 49.35507,49.35507 0 0 1 -1.0612,-10.88151 l 0,-30.76626 -11.26221,0 0,0 z"
|
||||||
|
id="path3072"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 1197.4165,146.30501 a 24.952696,24.952696 0 0 1 9.1,1.52157 16.077531,16.077531 0 0 1 6.4991,4.56469 19.935463,19.935463 0 0 1 3.8982,7.60782 39.066225,39.066225 0 0 1 1.3004,10.65064 l 0,46.34132 -18.3042,0 0,-46.58086 a 15.801149,15.801149 0 0 0 -0.4845,-4.1304 7.859179,7.859179 0 0 0 -1.4446,-2.95019 5.977282,5.977282 0 0 0 -2.4138,-1.77 8.891394,8.891394 0 0 0 -3.3738,-0.5901 25.71484,25.71484 0 0 0 -8.9373,1.36576 29.528311,29.528311 0 0 0 -7.8364,4.67234 l 0,49.98345 -18.3072,0 0,-69.48774 14.6667,0 3.6405,7.42778 a 71.772372,71.772372 0 0 1 8.5663,-5.43911 24.453688,24.453688 0 0 1 6.6248,-2.5159 31.484828,31.484828 0 0 1 6.8058,-0.67107 l 0,0 z"
|
||||||
|
id="path3074"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 882.47028,147.50331 19.21508,0 12.07804,48.68928 a 6.616536,6.616536 0 0 0 2.23895,3.70202 6.560409,6.560409 0 0 0 4.13438,1.23404 2.645525,2.645525 0 0 0 0.52754,0.1437 l 13.89681,-53.76904 19.11999,0 -24.10395,91.48424 -9.53546,13.3224 -13.13312,0 9.82377,-35.3189 a 22.713351,22.713351 0 0 1 -7.27505,-1.1052 17.518915,17.518915 0 0 1 -5.86726,-3.3157 20.440644,20.440644 0 0 1 -4.4595,-5.5261 32.678904,32.678904 0 0 1 -3.05171,-7.73647 l -13.60851,-51.80427 0,0 z"
|
||||||
|
id="path3076"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 1011.86,216.99105 0,-102.50669 18.163,0 0,40.44673 a 72.12737,72.12737 0 0 1 8.5172,-5.39126 25.732974,25.732974 0 0 1 6.6739,-2.56375 33.530661,33.530661 0 0 1 6.95,-0.67107 24.944515,24.944515 0 0 1 9.0968,1.52157 16.082612,16.082612 0 0 1 6.5022,4.56469 19.935463,19.935463 0 0 1 3.8982,7.60782 39.066225,39.066225 0 0 1 1.3004,10.65064 l 0,46.34132 -18.3072,0 0,-46.58086 a 15.799795,15.799795 0 0 0 -0.4815,-4.1304 7.862409,7.862409 0 0 0 -1.4477,-2.95019 5.972344,5.972344 0 0 0 -2.4107,-1.77 8.899237,8.899237 0 0 0 -3.3768,-0.5901 25.71484,25.71484 0 0 0 -8.9374,1.36576 29.519786,29.519786 0 0 0 -7.8332,4.67234 l 0,49.98345 -18.3072,0 0,0 z"
|
||||||
|
id="path3078"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 1082.7855,183.589 a 92.623252,92.623252 0 0 1 1.0305,-15.09572 34.921866,34.921866 0 0 1 3.2572,-10.35129 16.998317,16.998317 0 0 1 6.1587,-6.70918 27.333351,27.333351 0 0 1 8.9251,-3.45043 58.559567,58.559567 0 0 1 12.305,-1.15014 64.58165,64.58165 0 0 1 8.2718,0.49134 39.738976,39.738976 0 0 1 6.8886,1.47341 24.998971,24.998971 0 0 1 5.5115,2.4561 17.713605,17.713605 0 0 1 4.1283,3.43847 20.147183,20.147183 0 0 1 3.0088,4.6935 33.054914,33.054914 0 0 1 2.15,6.2209 56.120992,56.120992 0 0 1 1.2881,7.7486 92.689443,92.689443 0 0 1 0.4294,9.27599 93.581477,93.581477 0 0 1 -0.4202,9.252 55.498435,55.498435 0 0 1 -1.2697,7.67662 31.745279,31.745279 0 0 1 -2.1102,6.10108 18.697304,18.697304 0 0 1 -2.9566,4.5258 17.025604,17.025604 0 0 1 -4.0914,3.2707 25.393667,25.393667 0 0 1 -5.5177,2.3362 41.856735,41.856735 0 0 1 -6.9407,1.4018 69.341232,69.341232 0 0 1 -8.37,0.4672 63.04259,63.04259 0 0 1 -8.2381,-0.5002 39.369587,39.369587 0 0 1 -6.8917,-1.5006 25.298499,25.298499 0 0 1 -5.5452,-2.5009 18.400351,18.400351 0 0 1 -4.1957,-3.5014 20.410163,20.410163 0 0 1 -2.9781,-4.5227 30.960474,30.960474 0 0 1 -2.1255,-5.85256 49.716395,49.716395 0 0 1 -1.2759,-7.18239 79.251281,79.251281 0 0 1 -0.4263,-8.5122 l 0,0 z"
|
||||||
|
id="path3080"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 1103.7764,165.28239 a 101.69564,101.69564 0 0 0 -2.012,9.66857 53.000252,53.000252 0 0 0 -0.6717,7.91912 69.045959,69.045959 0 0 0 0.6717,10.97428 16.559516,16.559516 0 0 0 0.9385,3.45043 8.857186,8.857186 0 0 0 1.4814,2.49198 7.547675,7.547675 0 0 0 3.9749,2.53988 27.366717,27.366717 0 0 0 6.039,0.5272 45.096704,45.096704 0 0 0 5.7048,-0.2636 9.763441,9.763441 0 0 0 3.6651,-1.3179 5.86791,5.86791 0 0 0 2.5395,-3.2587 27.050263,27.050263 0 0 0 1.2575,-5.53508 55.730735,55.730735 0 0 0 0.4202,-7.21251 158.11284,158.11284 0 0 0 -0.3129,-11.78882 30.217313,30.217313 0 0 0 -1.101,-6.30187 5.911226,5.911226 0 0 0 -2.515,-3.57004 10.983294,10.983294 0 0 0 -3.5885,-1.47372 21.319589,21.319589 0 0 0 -4.8244,-0.49134 57.015487,57.015487 0 0 0 -4.6528,0.16194 17.099511,17.099511 0 0 0 -3.0854,0.4852 7.138992,7.138992 0 0 0 -3.9289,2.99498 l 0,0 z"
|
||||||
|
id="path3082"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
<path
|
||||||
|
d="m 808.23539,216.99105 0,-95.79752 41.2641,0 a 34.14365,34.14365 0 0 1 12.2774,1.98899 19.541659,19.541659 0 0 1 8.37612,5.96633 23.907413,23.907413 0 0 1 4.41962,8.9975 48.211674,48.211674 0 0 1 1.47525,12.61539 51.335387,51.335387 0 0 1 -1.77276,14.40103 37.898378,37.898378 0 0 1 -1.96598,5.31336 19.829803,19.829803 0 0 1 -2.34936,3.91172 16.201726,16.201726 0 0 1 -6.46841,4.88796 26.614618,26.614618 0 0 1 -11.40636,2.39628 143.35618,143.35618 0 0 1 -14.75865,-1.19799 519.68963,519.68963 0 0 1 -7.78724,-0.95876 24.527385,24.527385 0 0 1 -2.94743,-0.47907 l 0,37.95478 -18.3563,0 0,0 z"
|
||||||
|
id="path3084"
|
||||||
|
style="fill:none;stroke:#ff0000" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
@ -7,6 +7,9 @@
|
|||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
#include "asmthumb.h"
|
#include "asmthumb.h"
|
||||||
|
|
||||||
|
// wrapper around everything in this file
|
||||||
|
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
|
||||||
|
|
||||||
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)
|
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)
|
||||||
#define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0)
|
#define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0)
|
||||||
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
|
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
|
||||||
@ -447,3 +450,5 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp
|
|||||||
asm_thumb_write_op16(as, OP_SVC(fun_id));
|
asm_thumb_write_op16(as, OP_SVC(fun_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "asmx64.h"
|
#include "asmx64.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
|
||||||
|
// wrapper around everything in this file
|
||||||
|
#if MICROPY_EMIT_X64
|
||||||
|
|
||||||
#if defined(__OpenBSD__) || defined(__MACH__)
|
#if defined(__OpenBSD__) || defined(__MACH__)
|
||||||
#define MAP_ANONYMOUS MAP_ANON
|
#define MAP_ANONYMOUS MAP_ANON
|
||||||
@ -620,3 +624,5 @@ void asm_x64_call_ind(asm_x64_t* as, void *ptr, int temp_r64) {
|
|||||||
asm_x64_write_word32(as, ptr - (void*)(as->code_base + as->code_offset + 4));
|
asm_x64_write_word32(as, ptr - (void*)(as->code_base + as->code_offset + 4));
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MICROPY_EMIT_X64
|
||||||
|
16
py/bc0.h
16
py/bc0.h
@ -1,12 +1,16 @@
|
|||||||
|
// Micro Python byte-codes.
|
||||||
|
// The comment at the end of the line (if it exists) tells the arguments to the byte-code.
|
||||||
|
|
||||||
#define MP_BC_LOAD_CONST_FALSE (0x10)
|
#define MP_BC_LOAD_CONST_FALSE (0x10)
|
||||||
#define MP_BC_LOAD_CONST_NONE (0x11)
|
#define MP_BC_LOAD_CONST_NONE (0x11)
|
||||||
#define MP_BC_LOAD_CONST_TRUE (0x12)
|
#define MP_BC_LOAD_CONST_TRUE (0x12)
|
||||||
#define MP_BC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess
|
#define MP_BC_LOAD_CONST_ELLIPSIS (0x13)
|
||||||
#define MP_BC_LOAD_CONST_INT (0x14) // qstr
|
#define MP_BC_LOAD_CONST_SMALL_INT (0x14) // 24-bit, in excess
|
||||||
#define MP_BC_LOAD_CONST_DEC (0x15) // qstr
|
#define MP_BC_LOAD_CONST_INT (0x15) // qstr
|
||||||
#define MP_BC_LOAD_CONST_ID (0x16) // qstr
|
#define MP_BC_LOAD_CONST_DEC (0x16) // qstr
|
||||||
#define MP_BC_LOAD_CONST_BYTES (0x17) // qstr
|
#define MP_BC_LOAD_CONST_ID (0x17) // qstr
|
||||||
#define MP_BC_LOAD_CONST_STRING (0x18) // qstr
|
#define MP_BC_LOAD_CONST_BYTES (0x18) // qstr
|
||||||
|
#define MP_BC_LOAD_CONST_STRING (0x19) // qstr
|
||||||
|
|
||||||
#define MP_BC_LOAD_FAST_0 (0x20)
|
#define MP_BC_LOAD_FAST_0 (0x20)
|
||||||
#define MP_BC_LOAD_FAST_1 (0x21)
|
#define MP_BC_LOAD_FAST_1 (0x21)
|
||||||
|
147
py/builtin.c
147
py/builtin.c
@ -8,6 +8,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -87,14 +88,6 @@ mp_obj_t mp_builtin_any(mp_obj_t o_in) {
|
|||||||
return mp_const_false;
|
return mp_const_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t mp_builtin_bool(int n_args, const mp_obj_t *args) {
|
|
||||||
switch (n_args) {
|
|
||||||
case 0: return mp_const_false;
|
|
||||||
case 1: if (rt_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
|
|
||||||
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "bool() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
|
mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
|
||||||
if (mp_obj_is_callable(o_in)) {
|
if (mp_obj_is_callable(o_in)) {
|
||||||
return mp_const_true;
|
return mp_const_true;
|
||||||
@ -103,42 +96,6 @@ mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_ENABLE_FLOAT
|
|
||||||
mp_obj_t mp_builtin_complex(int n_args, const mp_obj_t *args) {
|
|
||||||
assert(0 <= n_args && n_args <= 2);
|
|
||||||
|
|
||||||
if (n_args == 0) {
|
|
||||||
return mp_obj_new_complex(0, 0);
|
|
||||||
} else if (n_args == 1) {
|
|
||||||
// TODO allow string as first arg and parse it
|
|
||||||
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
|
|
||||||
return args[0];
|
|
||||||
} else {
|
|
||||||
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mp_float_t real, imag;
|
|
||||||
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
|
|
||||||
mp_obj_get_complex(args[0], &real, &imag);
|
|
||||||
} else {
|
|
||||||
real = mp_obj_get_float(args[0]);
|
|
||||||
imag = 0;
|
|
||||||
}
|
|
||||||
if (MP_OBJ_IS_TYPE(args[1], &complex_type)) {
|
|
||||||
mp_float_t real2, imag2;
|
|
||||||
mp_obj_get_complex(args[1], &real2, &imag2);
|
|
||||||
real -= imag2;
|
|
||||||
imag += real2;
|
|
||||||
} else {
|
|
||||||
imag += mp_obj_get_float(args[1]);
|
|
||||||
}
|
|
||||||
return mp_obj_new_complex(real, imag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_complex_obj, 0, 2, mp_builtin_complex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
|
mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
|
||||||
int ord = mp_obj_get_int(o_in);
|
int ord = mp_obj_get_int(o_in);
|
||||||
if (0 <= ord && ord <= 0x10ffff) {
|
if (0 <= ord && ord <= 0x10ffff) {
|
||||||
@ -147,15 +104,10 @@ mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
|
|||||||
str[1] = '\0';
|
str[1] = '\0';
|
||||||
return mp_obj_new_str(qstr_from_str_take(str, 2));
|
return mp_obj_new_str(qstr_from_str_take(str, 2));
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "chr() arg not in range(0x110000)"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t mp_builtin_dict(void) {
|
|
||||||
// TODO create from an iterable!
|
|
||||||
return rt_build_map(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
|
mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
|
||||||
if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) {
|
if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) {
|
||||||
mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in);
|
mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in);
|
||||||
@ -165,29 +117,10 @@ mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
|
|||||||
revs_args[0] = MP_OBJ_NEW_SMALL_INT(i1 % i2);
|
revs_args[0] = MP_OBJ_NEW_SMALL_INT(i1 % i2);
|
||||||
return rt_build_tuple(2, revs_args);
|
return rt_build_tuple(2, revs_args);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_ENABLE_FLOAT
|
|
||||||
static mp_obj_t mp_builtin_float(int n_args, const mp_obj_t *args) {
|
|
||||||
assert(0 <= n_args && n_args <= 1);
|
|
||||||
|
|
||||||
if (n_args == 0) {
|
|
||||||
return mp_obj_new_float(0);
|
|
||||||
} else {
|
|
||||||
// TODO allow string as arg and parse it
|
|
||||||
if (MP_OBJ_IS_TYPE(args[0], &float_type)) {
|
|
||||||
return args[0];
|
|
||||||
} else {
|
|
||||||
return mp_obj_new_float(mp_obj_get_float(args[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_float_obj, 0, 1, mp_builtin_float);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
|
static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
|
||||||
// TODO hash will generally overflow small integer; can we safely truncate it?
|
// TODO hash will generally overflow small integer; can we safely truncate it?
|
||||||
return mp_obj_new_int(mp_obj_hash(o_in));
|
return mp_obj_new_int(mp_obj_hash(o_in));
|
||||||
@ -195,23 +128,6 @@ static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
|
|||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hash_obj, mp_builtin_hash);
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hash_obj, mp_builtin_hash);
|
||||||
|
|
||||||
static mp_obj_t mp_builtin_int(int n_args, const mp_obj_t *args) {
|
|
||||||
assert(0 <= n_args && n_args <= 2);
|
|
||||||
|
|
||||||
if (n_args == 0) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(0);
|
|
||||||
} else if (n_args == 1) {
|
|
||||||
// TODO if arg is a string then parse it
|
|
||||||
return mp_obj_new_int(mp_obj_get_int(args[0]));
|
|
||||||
} else { // n_args == 2
|
|
||||||
// TODO, parse with given base
|
|
||||||
assert(0);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_int_obj, 0, 2, mp_builtin_int);
|
|
||||||
|
|
||||||
static mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
|
static mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
|
||||||
return rt_getiter(o_in);
|
return rt_getiter(o_in);
|
||||||
}
|
}
|
||||||
@ -235,29 +151,11 @@ mp_obj_t mp_builtin_len(mp_obj_t o_in) {
|
|||||||
} else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) {
|
} else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) {
|
||||||
len = mp_obj_dict_len(o_in);
|
len = mp_obj_dict_len(o_in);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
|
||||||
}
|
}
|
||||||
return MP_OBJ_NEW_SMALL_INT(len);
|
return MP_OBJ_NEW_SMALL_INT(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args) {
|
|
||||||
switch (n_args) {
|
|
||||||
case 0: return rt_build_list(0, NULL);
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
// make list from iterable
|
|
||||||
mp_obj_t iterable = rt_getiter(args[0]);
|
|
||||||
mp_obj_t list = rt_build_list(0, NULL);
|
|
||||||
mp_obj_t item;
|
|
||||||
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
|
||||||
rt_list_append(list, item);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "list() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
|
mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
// given an iterable
|
// given an iterable
|
||||||
@ -270,7 +168,7 @@ mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (max_obj == NULL) {
|
if (max_obj == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "max() arg is an empty sequence"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "max() arg is an empty sequence"));
|
||||||
}
|
}
|
||||||
return max_obj;
|
return max_obj;
|
||||||
} else {
|
} else {
|
||||||
@ -297,7 +195,7 @@ mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (min_obj == NULL) {
|
if (min_obj == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "min() arg is an empty sequence"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "min() arg is an empty sequence"));
|
||||||
}
|
}
|
||||||
return min_obj;
|
return min_obj;
|
||||||
} else {
|
} else {
|
||||||
@ -315,7 +213,7 @@ mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
|
|||||||
static mp_obj_t mp_builtin_next(mp_obj_t o) {
|
static mp_obj_t mp_builtin_next(mp_obj_t o) {
|
||||||
mp_obj_t ret = rt_iternext(o);
|
mp_obj_t ret = rt_iternext(o);
|
||||||
if (ret == mp_const_stop_iteration) {
|
if (ret == mp_const_stop_iteration) {
|
||||||
nlr_jump(mp_obj_new_exception(qstr_from_str_static("StopIteration")));
|
nlr_jump(mp_obj_new_exception(MP_QSTR_StopIteration));
|
||||||
} else {
|
} else {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -328,7 +226,7 @@ mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
|
|||||||
if (strlen(str) == 1) {
|
if (strlen(str) == 1) {
|
||||||
return mp_obj_new_int(str[0]);
|
return mp_obj_new_int(str[0]);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +234,7 @@ mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) {
|
|||||||
switch (n_args) {
|
switch (n_args) {
|
||||||
case 2: return rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]);
|
case 2: return rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]);
|
||||||
case 3: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise...
|
case 3: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise...
|
||||||
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
|
default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,36 +260,16 @@ mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args) {
|
|||||||
case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1);
|
case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1);
|
||||||
case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1);
|
case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1);
|
||||||
case 3: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
|
case 3: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
|
||||||
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
|
default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mp_obj_t mp_builtin_set(int n_args, const mp_obj_t *args) {
|
|
||||||
assert(0 <= n_args && n_args <= 1);
|
|
||||||
|
|
||||||
if (n_args == 0) {
|
|
||||||
// return a new, empty set
|
|
||||||
return mp_obj_new_set(0, NULL);
|
|
||||||
} else {
|
|
||||||
// 1 argument, an iterable from which we make a new set
|
|
||||||
mp_obj_t set = mp_obj_new_set(0, NULL);
|
|
||||||
mp_obj_t iterable = rt_getiter(args[0]);
|
|
||||||
mp_obj_t item;
|
|
||||||
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
|
||||||
mp_obj_set_store(set, item);
|
|
||||||
}
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_set_obj, 0, 1, mp_builtin_set);
|
|
||||||
|
|
||||||
mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
|
mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
|
||||||
mp_obj_t value;
|
mp_obj_t value;
|
||||||
switch (n_args) {
|
switch (n_args) {
|
||||||
case 1: value = mp_obj_new_int(0); break;
|
case 1: value = mp_obj_new_int(0); break;
|
||||||
case 2: value = args[1]; break;
|
case 2: value = args[1]; break;
|
||||||
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args));
|
default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
mp_obj_t iterable = rt_getiter(args[0]);
|
mp_obj_t iterable = rt_getiter(args[0]);
|
||||||
mp_obj_t item;
|
mp_obj_t item;
|
||||||
@ -404,8 +282,7 @@ mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
|
|||||||
static mp_obj_t mp_builtin_type(mp_obj_t o_in) {
|
static mp_obj_t mp_builtin_type(mp_obj_t o_in) {
|
||||||
// TODO implement the 3 argument version of type()
|
// TODO implement the 3 argument version of type()
|
||||||
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||||
// TODO implement int-type
|
return (mp_obj_t)&int_type;
|
||||||
return mp_const_none;
|
|
||||||
} else {
|
} else {
|
||||||
mp_obj_base_t *o = o_in;
|
mp_obj_base_t *o = o_in;
|
||||||
return (mp_obj_t)o->type;
|
return (mp_obj_t)o->type;
|
||||||
|
@ -58,7 +58,9 @@ mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mp_compile(pn, false)) {
|
mp_obj_t module_fun = mp_compile(pn, false);
|
||||||
|
|
||||||
|
if (module_fun == mp_const_none) {
|
||||||
// TODO handle compile error correctly
|
// TODO handle compile error correctly
|
||||||
rt_locals_set(old_locals);
|
rt_locals_set(old_locals);
|
||||||
rt_globals_set(old_globals);
|
rt_globals_set(old_globals);
|
||||||
@ -66,7 +68,6 @@ mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// complied successfully, execute it
|
// complied successfully, execute it
|
||||||
mp_obj_t module_fun = rt_make_function_from_id(1); // TODO we should return from mp_compile the unique_code_id for the module
|
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
rt_call_function_0(module_fun);
|
rt_call_function_0(module_fun);
|
||||||
|
83
py/compile.c
83
py/compile.c
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
@ -38,20 +39,6 @@ typedef enum {
|
|||||||
#define EMIT_OPT_ASM_THUMB (4)
|
#define EMIT_OPT_ASM_THUMB (4)
|
||||||
|
|
||||||
typedef struct _compiler_t {
|
typedef struct _compiler_t {
|
||||||
qstr qstr___class__;
|
|
||||||
qstr qstr___locals__;
|
|
||||||
qstr qstr___name__;
|
|
||||||
qstr qstr___module__;
|
|
||||||
qstr qstr___qualname__;
|
|
||||||
qstr qstr___doc__;
|
|
||||||
qstr qstr_assertion_error;
|
|
||||||
qstr qstr_micropython;
|
|
||||||
qstr qstr_byte_code;
|
|
||||||
qstr qstr_native;
|
|
||||||
qstr qstr_viper;
|
|
||||||
qstr qstr_asm_thumb;
|
|
||||||
qstr qstr_range;
|
|
||||||
|
|
||||||
bool is_repl;
|
bool is_repl;
|
||||||
pass_kind_t pass;
|
pass_kind_t pass;
|
||||||
bool had_error; // try to keep compiler clean from nlr
|
bool had_error; // try to keep compiler clean from nlr
|
||||||
@ -202,7 +189,7 @@ static int comp_next_label(compiler_t *comp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) {
|
static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) {
|
||||||
scope_t *scope = scope_new(kind, pn, rt_get_unique_code_id(kind == SCOPE_MODULE), emit_options);
|
scope_t *scope = scope_new(kind, pn, rt_get_unique_code_id(), emit_options);
|
||||||
scope->parent = comp->scope_cur;
|
scope->parent = comp->scope_cur;
|
||||||
scope->next = NULL;
|
scope->next = NULL;
|
||||||
if (comp->scope_head == NULL) {
|
if (comp->scope_head == NULL) {
|
||||||
@ -903,7 +890,7 @@ qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
|
|||||||
|
|
||||||
// returns true if it was a built-in decorator (even if the built-in had an error)
|
// returns true if it was a built-in decorator (even if the built-in had an error)
|
||||||
static bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_node_t *name_nodes, uint *emit_options) {
|
static bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_node_t *name_nodes, uint *emit_options) {
|
||||||
if (MP_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
|
if (MP_PARSE_NODE_LEAF_ARG(name_nodes[0]) != MP_QSTR_micropython) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,16 +900,16 @@ static bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
|
|||||||
}
|
}
|
||||||
|
|
||||||
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
|
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
|
||||||
if (attr == comp->qstr_byte_code) {
|
if (attr == MP_QSTR_byte_code) {
|
||||||
*emit_options = EMIT_OPT_BYTE_CODE;
|
*emit_options = EMIT_OPT_BYTE_CODE;
|
||||||
#if MICROPY_EMIT_NATIVE
|
#if MICROPY_EMIT_NATIVE
|
||||||
} else if (attr == comp->qstr_native) {
|
} else if (attr == MP_QSTR_native) {
|
||||||
*emit_options = EMIT_OPT_NATIVE_PYTHON;
|
*emit_options = EMIT_OPT_NATIVE_PYTHON;
|
||||||
} else if (attr == comp->qstr_viper) {
|
} else if (attr == MP_QSTR_viper) {
|
||||||
*emit_options = EMIT_OPT_VIPER;
|
*emit_options = EMIT_OPT_VIPER;
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
} else if (attr == comp->qstr_asm_thumb) {
|
} else if (attr == MP_QSTR_asm_thumb) {
|
||||||
*emit_options = EMIT_OPT_ASM_THUMB;
|
*emit_options = EMIT_OPT_ASM_THUMB;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -1329,7 +1316,7 @@ void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
int l_end = comp_next_label(comp);
|
int l_end = comp_next_label(comp);
|
||||||
c_if_cond(comp, pns->nodes[0], true, l_end);
|
c_if_cond(comp, pns->nodes[0], true, l_end);
|
||||||
EMIT(load_id, comp->qstr_assertion_error);
|
EMIT(load_id, MP_QSTR_AssertionError);
|
||||||
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
||||||
// assertion message
|
// assertion message
|
||||||
compile_node(comp, pns->nodes[1]);
|
compile_node(comp, pns->nodes[1]);
|
||||||
@ -1495,7 +1482,7 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
// for viper it will be much, much faster
|
// for viper it will be much, much faster
|
||||||
if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
|
if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
|
||||||
mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1];
|
mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||||
if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0]) && MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == comp->qstr_range && MP_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && MP_PARSE_NODE_IS_NULL(pns_it->nodes[2])) {
|
if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0]) && MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == MP_QSTR_range && MP_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && MP_PARSE_NODE_IS_NULL(pns_it->nodes[2])) {
|
||||||
mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
|
mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
|
||||||
mp_parse_node_t *args;
|
mp_parse_node_t *args;
|
||||||
int n_args = list_get(&pn_range_args, PN_arglist, &args);
|
int n_args = list_get(&pn_range_args, PN_arglist, &args);
|
||||||
@ -1743,7 +1730,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
|
||||||
if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
|
if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
|
||||||
// for REPL, evaluate then print the expression
|
// for REPL, evaluate then print the expression
|
||||||
EMIT(load_id, qstr_from_str_static("__repl_print__"));
|
EMIT(load_id, MP_QSTR___repl_print__);
|
||||||
compile_node(comp, pns->nodes[0]);
|
compile_node(comp, pns->nodes[0]);
|
||||||
EMIT(call_function, 1, 0, false, false);
|
EMIT(call_function, 1, 0, false, false);
|
||||||
EMIT(pop_top);
|
EMIT(pop_top);
|
||||||
@ -2683,7 +2670,7 @@ void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) {
|
|||||||
if (kind == MP_PARSE_NODE_STRING) {
|
if (kind == MP_PARSE_NODE_STRING) {
|
||||||
compile_node(comp, pns->nodes[0]); // a doc string
|
compile_node(comp, pns->nodes[0]); // a doc string
|
||||||
// store doc string
|
// store doc string
|
||||||
EMIT(store_id, comp->qstr___doc__);
|
EMIT(store_id, MP_QSTR___doc__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2796,35 +2783,35 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
|||||||
|
|
||||||
if (comp->pass == PASS_1) {
|
if (comp->pass == PASS_1) {
|
||||||
bool added;
|
bool added;
|
||||||
id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
|
id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added);
|
||||||
assert(added);
|
assert(added);
|
||||||
id_info->kind = ID_INFO_KIND_LOCAL;
|
id_info->kind = ID_INFO_KIND_LOCAL;
|
||||||
id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
|
id_info = scope_find_or_add_id(scope, MP_QSTR___locals__, &added);
|
||||||
assert(added);
|
assert(added);
|
||||||
id_info->kind = ID_INFO_KIND_LOCAL;
|
id_info->kind = ID_INFO_KIND_LOCAL;
|
||||||
id_info->param = true;
|
id_info->param = true;
|
||||||
scope->num_params = 1; // __locals__ is the parameter
|
scope->num_params = 1; // __locals__ is the parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
EMIT(load_id, comp->qstr___locals__);
|
EMIT(load_id, MP_QSTR___locals__);
|
||||||
EMIT(store_locals);
|
EMIT(store_locals);
|
||||||
EMIT(load_id, comp->qstr___name__);
|
EMIT(load_id, MP_QSTR___name__);
|
||||||
EMIT(store_id, comp->qstr___module__);
|
EMIT(store_id, MP_QSTR___module__);
|
||||||
EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
|
EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
|
||||||
EMIT(store_id, comp->qstr___qualname__);
|
EMIT(store_id, MP_QSTR___qualname__);
|
||||||
|
|
||||||
check_for_doc_string(comp, pns->nodes[2]);
|
check_for_doc_string(comp, pns->nodes[2]);
|
||||||
compile_node(comp, pns->nodes[2]); // 2 is class body
|
compile_node(comp, pns->nodes[2]); // 2 is class body
|
||||||
|
|
||||||
id_info_t *id = scope_find(scope, comp->qstr___class__);
|
id_info_t *id = scope_find(scope, MP_QSTR___class__);
|
||||||
assert(id != NULL);
|
assert(id != NULL);
|
||||||
if (id->kind == ID_INFO_KIND_LOCAL) {
|
if (id->kind == ID_INFO_KIND_LOCAL) {
|
||||||
EMIT(load_const_tok, MP_TOKEN_KW_NONE);
|
EMIT(load_const_tok, MP_TOKEN_KW_NONE);
|
||||||
} else {
|
} else {
|
||||||
#if MICROPY_EMIT_CPYTHON
|
#if MICROPY_EMIT_CPYTHON
|
||||||
EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num
|
EMIT(load_closure, MP_QSTR___class__, 0); // XXX check this is the correct local num
|
||||||
#else
|
#else
|
||||||
EMIT(load_fast, comp->qstr___class__, 0); // XXX check this is the correct local num
|
EMIT(load_fast, MP_QSTR___class__, 0); // XXX check this is the correct local num
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
EMIT(return_value);
|
EMIT(return_value);
|
||||||
@ -2917,7 +2904,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
|
|||||||
scope->num_locals = 0;
|
scope->num_locals = 0;
|
||||||
for (int i = 0; i < scope->id_info_len; i++) {
|
for (int i = 0; i < scope->id_info_len; i++) {
|
||||||
id_info_t *id = &scope->id_info[i];
|
id_info_t *id = &scope->id_info[i];
|
||||||
if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
|
if (scope->kind == SCOPE_CLASS && id->qstr == MP_QSTR___class__) {
|
||||||
// __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
|
// __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3021,20 +3008,6 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
|
|||||||
mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
||||||
compiler_t *comp = m_new(compiler_t, 1);
|
compiler_t *comp = m_new(compiler_t, 1);
|
||||||
|
|
||||||
comp->qstr___class__ = qstr_from_str_static("__class__");
|
|
||||||
comp->qstr___locals__ = qstr_from_str_static("__locals__");
|
|
||||||
comp->qstr___name__ = qstr_from_str_static("__name__");
|
|
||||||
comp->qstr___module__ = qstr_from_str_static("__module__");
|
|
||||||
comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
|
|
||||||
comp->qstr___doc__ = qstr_from_str_static("__doc__");
|
|
||||||
comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
|
|
||||||
comp->qstr_micropython = qstr_from_str_static("micropython");
|
|
||||||
comp->qstr_byte_code = qstr_from_str_static("byte_code");
|
|
||||||
comp->qstr_native = qstr_from_str_static("native");
|
|
||||||
comp->qstr_viper = qstr_from_str_static("viper");
|
|
||||||
comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
|
|
||||||
comp->qstr_range = qstr_from_str_static("range");
|
|
||||||
|
|
||||||
comp->is_repl = is_repl;
|
comp->is_repl = is_repl;
|
||||||
comp->had_error = false;
|
comp->had_error = false;
|
||||||
|
|
||||||
@ -3048,10 +3021,10 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
pn = fold_constants(pn);
|
pn = fold_constants(pn);
|
||||||
|
|
||||||
// set the outer scope
|
// set the outer scope
|
||||||
scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
|
scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
|
||||||
|
|
||||||
// compile pass 1
|
// compile pass 1
|
||||||
comp->emit = emit_pass1_new(comp->qstr___class__);
|
comp->emit = emit_pass1_new(MP_QSTR___class__);
|
||||||
comp->emit_method_table = &emit_pass1_method_table;
|
comp->emit_method_table = &emit_pass1_method_table;
|
||||||
comp->emit_inline_asm = NULL;
|
comp->emit_inline_asm = NULL;
|
||||||
comp->emit_inline_asm_method_table = NULL;
|
comp->emit_inline_asm_method_table = NULL;
|
||||||
@ -3083,11 +3056,13 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
// compile pass 2 and 3
|
// compile pass 2 and 3
|
||||||
#if !MICROPY_EMIT_CPYTHON
|
#if !MICROPY_EMIT_CPYTHON
|
||||||
emit_t *emit_bc = NULL;
|
emit_t *emit_bc = NULL;
|
||||||
|
#if MICROPY_EMIT_NATIVE
|
||||||
emit_t *emit_native = NULL;
|
emit_t *emit_native = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
emit_inline_asm_t *emit_inline_thumb = NULL;
|
emit_inline_asm_t *emit_inline_thumb = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#endif // !MICROPY_EMIT_CPYTHON
|
||||||
for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
|
for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
|
||||||
if (false) {
|
if (false) {
|
||||||
// dummy
|
// dummy
|
||||||
@ -3115,6 +3090,8 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
comp->emit_method_table = &emit_cpython_method_table;
|
comp->emit_method_table = &emit_cpython_method_table;
|
||||||
#else
|
#else
|
||||||
switch (s->emit_options) {
|
switch (s->emit_options) {
|
||||||
|
|
||||||
|
#if MICROPY_EMIT_NATIVE
|
||||||
case EMIT_OPT_NATIVE_PYTHON:
|
case EMIT_OPT_NATIVE_PYTHON:
|
||||||
case EMIT_OPT_VIPER:
|
case EMIT_OPT_VIPER:
|
||||||
#if MICROPY_EMIT_X64
|
#if MICROPY_EMIT_X64
|
||||||
@ -3131,6 +3108,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
comp->emit = emit_native;
|
comp->emit = emit_native;
|
||||||
comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
|
comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
|
||||||
break;
|
break;
|
||||||
|
#endif // MICROPY_EMIT_NATIVE
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (emit_bc == NULL) {
|
if (emit_bc == NULL) {
|
||||||
@ -3140,7 +3118,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
comp->emit_method_table = &emit_bc_method_table;
|
comp->emit_method_table = &emit_bc_method_table;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // !MICROPY_EMIT_CPYTHON
|
||||||
|
|
||||||
// compile pass 2 and pass 3
|
// compile pass 2 and pass 3
|
||||||
compile_scope(comp, s, PASS_2);
|
compile_scope(comp, s, PASS_2);
|
||||||
@ -3157,10 +3135,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) {
|
|||||||
} else {
|
} else {
|
||||||
#if MICROPY_EMIT_CPYTHON
|
#if MICROPY_EMIT_CPYTHON
|
||||||
// can't create code, so just return true
|
// can't create code, so just return true
|
||||||
|
(void)module_scope; // to suppress warning that module_scope is unused
|
||||||
return mp_const_true;
|
return mp_const_true;
|
||||||
#else
|
#else
|
||||||
// return function that executes the outer module
|
// return function that executes the outer module
|
||||||
return rt_make_function_from_id(1);
|
return rt_make_function_from_id(module_scope->unique_code_id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,6 +249,7 @@ static void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
|
|||||||
case MP_TOKEN_KW_FALSE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_FALSE); break;
|
case MP_TOKEN_KW_FALSE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_FALSE); break;
|
||||||
case MP_TOKEN_KW_NONE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_NONE); break;
|
case MP_TOKEN_KW_NONE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_NONE); break;
|
||||||
case MP_TOKEN_KW_TRUE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_TRUE); break;
|
case MP_TOKEN_KW_TRUE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_TRUE); break;
|
||||||
|
case MP_TOKEN_ELLIPSIS: emit_write_byte_1(emit, MP_BC_LOAD_CONST_ELLIPSIS); break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
|
|
||||||
|
// wrapper around everything in this file
|
||||||
#if MICROPY_EMIT_CPYTHON
|
#if MICROPY_EMIT_CPYTHON
|
||||||
|
|
||||||
struct _emit_t {
|
struct _emit_t {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
// wrapper around everything in this file
|
// wrapper around everything in this file
|
||||||
#if N_X64 || N_THUMB
|
#if (MICROPY_EMIT_X64 && N_X64) || (MICROPY_EMIT_THUMB && N_THUMB)
|
||||||
|
|
||||||
#if N_X64
|
#if N_X64
|
||||||
|
|
||||||
@ -1319,4 +1319,4 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
|
|||||||
emit_native_yield_from,
|
emit_native_yield_from,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // N_X64 || N_THUMB
|
#endif // (MICROPY_EMIT_X64 && N_X64) || (MICROPY_EMIT_THUMB && N_THUMB)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
@ -44,9 +45,9 @@ static void emit_pass1_load_id(emit_t *emit, qstr qstr) {
|
|||||||
bool added;
|
bool added;
|
||||||
id_info_t *id = scope_find_or_add_id(emit->scope, qstr, &added);
|
id_info_t *id = scope_find_or_add_id(emit->scope, qstr, &added);
|
||||||
if (added) {
|
if (added) {
|
||||||
if (strcmp(qstr_str(qstr), "AssertionError") == 0) {
|
if (qstr == MP_QSTR_AssertionError) {
|
||||||
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
|
|
||||||
// TODO how much of a hack is this?
|
// TODO how much of a hack is this?
|
||||||
|
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
|
||||||
} else if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
|
} else if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
|
||||||
// special case, super is a global, and also counts as use of __class__
|
// special case, super is a global, and also counts as use of __class__
|
||||||
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
|
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
|
||||||
|
@ -113,11 +113,11 @@ DEF_RULE(import_stmt, nc, or(2), rule(import_name), rule(import_from))
|
|||||||
DEF_RULE(import_name, c(import_name), and(2), tok(KW_IMPORT), rule(dotted_as_names))
|
DEF_RULE(import_name, c(import_name), and(2), tok(KW_IMPORT), rule(dotted_as_names))
|
||||||
DEF_RULE(import_from, c(import_from), and(4), tok(KW_FROM), rule(import_from_2), tok(KW_IMPORT), rule(import_from_3))
|
DEF_RULE(import_from, c(import_from), and(4), tok(KW_FROM), rule(import_from_2), tok(KW_IMPORT), rule(import_from_3))
|
||||||
DEF_RULE(import_from_2, nc, or(2), rule(dotted_name), rule(import_from_2b))
|
DEF_RULE(import_from_2, nc, or(2), rule(dotted_name), rule(import_from_2b))
|
||||||
DEF_RULE(import_from_2b, nc, and(2), rule(one_or_more_period_or_ellipses), opt_rule(dotted_name))
|
DEF_RULE(import_from_2b, nc, and(2), rule(one_or_more_period_or_ellipsis), opt_rule(dotted_name))
|
||||||
DEF_RULE(import_from_3, nc, or(3), tok(OP_STAR), rule(import_as_names_paren), rule(import_as_names))
|
DEF_RULE(import_from_3, nc, or(3), tok(OP_STAR), rule(import_as_names_paren), rule(import_as_names))
|
||||||
DEF_RULE(import_as_names_paren, nc, and(3), tok(DEL_PAREN_OPEN), rule(import_as_names), tok(DEL_PAREN_CLOSE))
|
DEF_RULE(import_as_names_paren, nc, and(3), tok(DEL_PAREN_OPEN), rule(import_as_names), tok(DEL_PAREN_CLOSE))
|
||||||
DEF_RULE(one_or_more_period_or_ellipses, nc, one_or_more, rule(period_or_ellipses))
|
DEF_RULE(one_or_more_period_or_ellipsis, nc, one_or_more, rule(period_or_ellipsis))
|
||||||
DEF_RULE(period_or_ellipses, nc, or(2), tok(DEL_PERIOD), tok(ELLIPSES))
|
DEF_RULE(period_or_ellipsis, nc, or(2), tok(DEL_PERIOD), tok(ELLIPSIS))
|
||||||
DEF_RULE(import_as_name, nc, and(2), tok(NAME), opt_rule(as_name))
|
DEF_RULE(import_as_name, nc, and(2), tok(NAME), opt_rule(as_name))
|
||||||
DEF_RULE(dotted_as_name, nc, and(2), rule(dotted_name), opt_rule(as_name))
|
DEF_RULE(dotted_as_name, nc, and(2), rule(dotted_name), opt_rule(as_name))
|
||||||
DEF_RULE(as_name, nc, and(2), tok(KW_AS), tok(NAME))
|
DEF_RULE(as_name, nc, and(2), tok(KW_AS), tok(NAME))
|
||||||
@ -220,7 +220,7 @@ DEF_RULE(power_dbl_star, c(power_dbl_star), and(2), tok(OP_DBL_STAR), rule(facto
|
|||||||
// testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
|
// testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
|
||||||
// trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
|
// trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
|
||||||
|
|
||||||
DEF_RULE(atom, nc, or(10), tok(NAME), tok(NUMBER), rule(atom_string), tok(ELLIPSES), tok(KW_NONE), tok(KW_TRUE), tok(KW_FALSE), rule(atom_paren), rule(atom_bracket), rule(atom_brace))
|
DEF_RULE(atom, nc, or(10), tok(NAME), tok(NUMBER), rule(atom_string), tok(ELLIPSIS), tok(KW_NONE), tok(KW_TRUE), tok(KW_FALSE), rule(atom_paren), rule(atom_bracket), rule(atom_brace))
|
||||||
DEF_RULE(atom_string, c(atom_string), one_or_more, rule(string_or_bytes))
|
DEF_RULE(atom_string, c(atom_string), one_or_more, rule(string_or_bytes))
|
||||||
DEF_RULE(string_or_bytes, nc, or(2), tok(STRING), tok(BYTES))
|
DEF_RULE(string_or_bytes, nc, or(2), tok(STRING), tok(BYTES))
|
||||||
DEF_RULE(atom_paren, c(atom_paren), and(3), tok(DEL_PAREN_OPEN), opt_rule(atom_2b), tok(DEL_PAREN_CLOSE))
|
DEF_RULE(atom_paren, c(atom_paren), and(3), tok(DEL_PAREN_OPEN), opt_rule(atom_2b), tok(DEL_PAREN_CLOSE))
|
||||||
|
@ -239,7 +239,7 @@ static const uint8_t tok_enc_kind[] = {
|
|||||||
MP_TOKEN_OP_CARET, MP_TOKEN_DEL_CARET_EQUAL,
|
MP_TOKEN_OP_CARET, MP_TOKEN_DEL_CARET_EQUAL,
|
||||||
MP_TOKEN_DEL_EQUAL, MP_TOKEN_OP_DBL_EQUAL,
|
MP_TOKEN_DEL_EQUAL, MP_TOKEN_OP_DBL_EQUAL,
|
||||||
MP_TOKEN_OP_NOT_EQUAL,
|
MP_TOKEN_OP_NOT_EQUAL,
|
||||||
MP_TOKEN_DEL_PERIOD, MP_TOKEN_ELLIPSES,
|
MP_TOKEN_DEL_PERIOD, MP_TOKEN_ELLIPSIS,
|
||||||
};
|
};
|
||||||
|
|
||||||
// must have the same order as enum in lexer.h
|
// must have the same order as enum in lexer.h
|
||||||
|
@ -20,7 +20,7 @@ typedef enum _mp_token_kind_t {
|
|||||||
MP_TOKEN_STRING,
|
MP_TOKEN_STRING,
|
||||||
MP_TOKEN_BYTES,
|
MP_TOKEN_BYTES,
|
||||||
|
|
||||||
MP_TOKEN_ELLIPSES,
|
MP_TOKEN_ELLIPSIS,
|
||||||
|
|
||||||
MP_TOKEN_KW_FALSE, // 12
|
MP_TOKEN_KW_FALSE, // 12
|
||||||
MP_TOKEN_KW_NONE,
|
MP_TOKEN_KW_NONE,
|
||||||
|
@ -4,6 +4,20 @@
|
|||||||
|
|
||||||
#include <mpconfigport.h>
|
#include <mpconfigport.h>
|
||||||
|
|
||||||
|
#ifndef INT_FMT
|
||||||
|
// printf format spec to use for machine_int_t and friends
|
||||||
|
#ifdef __LP64__
|
||||||
|
// Archs where machine_int_t == long, long != int
|
||||||
|
#define UINT_FMT "%lu"
|
||||||
|
#define INT_FMT "%ld"
|
||||||
|
#else
|
||||||
|
// Archs where machine_int_t == int
|
||||||
|
#define UINT_FMT "%u"
|
||||||
|
#define INT_FMT "%d"
|
||||||
|
#endif
|
||||||
|
#endif //INT_FMT
|
||||||
|
|
||||||
|
|
||||||
// Any options not explicitly set in mpconfigport.h will get default
|
// Any options not explicitly set in mpconfigport.h will get default
|
||||||
// values below.
|
// values below.
|
||||||
|
|
||||||
@ -11,3 +25,9 @@
|
|||||||
#ifndef MICROPY_MEM_STATS
|
#ifndef MICROPY_MEM_STATS
|
||||||
#define MICROPY_MEM_STATS (1)
|
#define MICROPY_MEM_STATS (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Whether to support slice object and correspondingly
|
||||||
|
// slice subscript operators
|
||||||
|
#ifndef MICROPY_ENABLE_SLICE
|
||||||
|
#define MICROPY_ENABLE_SLICE (1)
|
||||||
|
#endif
|
||||||
|
13
py/mpqstr.h
Normal file
13
py/mpqstr.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// See mpqstrraw.h for a list of qstr's that are available as constants.
|
||||||
|
// Reference them as MP_QSTR_xxxx.
|
||||||
|
//
|
||||||
|
// Note: it would be possible to define MP_QSTR_xxx as qstr_from_str_static("xxx")
|
||||||
|
// for qstrs that are referenced this way, but you don't want to have them in ROM.
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MP_QSTR_nil = 0,
|
||||||
|
#define Q(id) MP_QSTR_##id,
|
||||||
|
#include "mpqstrraw.h"
|
||||||
|
#undef Q
|
||||||
|
MP_QSTR_number_of,
|
||||||
|
} category_t;
|
65
py/mpqstrraw.h
Normal file
65
py/mpqstrraw.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// All the qstr definitions in this file are available as constants.
|
||||||
|
// That is, they are in ROM and you can reference them simple as MP_QSTR_xxxx.
|
||||||
|
|
||||||
|
Q(__build_class__)
|
||||||
|
Q(__class__)
|
||||||
|
Q(__doc__)
|
||||||
|
Q(__init__)
|
||||||
|
Q(__locals__)
|
||||||
|
Q(__main__)
|
||||||
|
Q(__module__)
|
||||||
|
Q(__name__)
|
||||||
|
Q(__next__)
|
||||||
|
Q(__qualname__)
|
||||||
|
Q(__repl_print__)
|
||||||
|
|
||||||
|
Q(micropython)
|
||||||
|
Q(byte_code)
|
||||||
|
Q(native)
|
||||||
|
Q(viper)
|
||||||
|
Q(asm_thumb)
|
||||||
|
|
||||||
|
Q(Ellipsis)
|
||||||
|
Q(StopIteration)
|
||||||
|
|
||||||
|
Q(AssertionError)
|
||||||
|
Q(AttributeError)
|
||||||
|
Q(IndexError)
|
||||||
|
Q(KeyError)
|
||||||
|
Q(NameError)
|
||||||
|
Q(SyntaxError)
|
||||||
|
Q(TypeError)
|
||||||
|
Q(ValueError)
|
||||||
|
|
||||||
|
Q(abs)
|
||||||
|
Q(all)
|
||||||
|
Q(any)
|
||||||
|
Q(bool)
|
||||||
|
Q(callable)
|
||||||
|
Q(chr)
|
||||||
|
Q(complex)
|
||||||
|
Q(dict)
|
||||||
|
Q(divmod)
|
||||||
|
Q(float)
|
||||||
|
Q(hash)
|
||||||
|
Q(int)
|
||||||
|
Q(iter)
|
||||||
|
Q(len)
|
||||||
|
Q(list)
|
||||||
|
Q(max)
|
||||||
|
Q(min)
|
||||||
|
Q(next)
|
||||||
|
Q(ord)
|
||||||
|
Q(pow)
|
||||||
|
Q(print)
|
||||||
|
Q(range)
|
||||||
|
Q(set)
|
||||||
|
Q(sum)
|
||||||
|
Q(tuple)
|
||||||
|
Q(type)
|
||||||
|
|
||||||
|
Q(append)
|
||||||
|
Q(pop)
|
||||||
|
Q(sort)
|
||||||
|
Q(join)
|
||||||
|
Q(format)
|
23
py/nlrx64.S
23
py/nlrx64.S
@ -5,9 +5,14 @@
|
|||||||
.text
|
.text
|
||||||
|
|
||||||
/* uint nlr_push(rdi=nlr_buf_t *nlr) */
|
/* uint nlr_push(rdi=nlr_buf_t *nlr) */
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.globl nlr_push
|
.globl nlr_push
|
||||||
.type nlr_push, @function
|
.type nlr_push, @function
|
||||||
nlr_push:
|
nlr_push:
|
||||||
|
#else
|
||||||
|
.globl _nlr_push
|
||||||
|
_nlr_push:
|
||||||
|
#endif
|
||||||
movq (%rsp), %rax # load return %rip
|
movq (%rsp), %rax # load return %rip
|
||||||
movq %rax, 16(%rdi) # store %rip into nlr_buf
|
movq %rax, 16(%rdi) # store %rip into nlr_buf
|
||||||
movq %rbp, 24(%rdi) # store %rbp into nlr_buf
|
movq %rbp, 24(%rdi) # store %rbp into nlr_buf
|
||||||
@ -22,22 +27,36 @@ nlr_push:
|
|||||||
movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list)
|
movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list)
|
||||||
xorq %rax, %rax # return 0, normal return
|
xorq %rax, %rax # return 0, normal return
|
||||||
ret # return
|
ret # return
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.size nlr_push, .-nlr_push
|
.size nlr_push, .-nlr_push
|
||||||
|
#endif
|
||||||
|
|
||||||
/* void nlr_pop() */
|
/* void nlr_pop() */
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.globl nlr_pop
|
.globl nlr_pop
|
||||||
.type nlr_pop, @function
|
.type nlr_pop, @function
|
||||||
nlr_pop:
|
nlr_pop:
|
||||||
|
#else
|
||||||
|
.globl _nlr_pop
|
||||||
|
_nlr_pop:
|
||||||
|
#endif
|
||||||
movq nlr_top(%rip), %rax # get nlr_top into %rax
|
movq nlr_top(%rip), %rax # get nlr_top into %rax
|
||||||
movq (%rax), %rax # load prev nlr_buf
|
movq (%rax), %rax # load prev nlr_buf
|
||||||
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
|
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
|
||||||
ret # return
|
ret # return
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.size nlr_pop, .-nlr_pop
|
.size nlr_pop, .-nlr_pop
|
||||||
|
#endif
|
||||||
|
|
||||||
/* void nlr_jump(rdi=uint val) */
|
/* void nlr_jump(rdi=uint val) */
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.globl nlr_jump
|
.globl nlr_jump
|
||||||
.type nlr_jump, @function
|
.type nlr_jump, @function
|
||||||
nlr_jump:
|
nlr_jump:
|
||||||
|
#else
|
||||||
|
.globl _nlr_jump
|
||||||
|
_nlr_jump:
|
||||||
|
#endif
|
||||||
movq %rdi, %rax # put return value in %rax
|
movq %rdi, %rax # put return value in %rax
|
||||||
movq nlr_top(%rip), %rdi # get nlr_top into %rdi
|
movq nlr_top(%rip), %rdi # get nlr_top into %rdi
|
||||||
movq %rax, 8(%rdi) # store return value
|
movq %rax, 8(%rdi) # store return value
|
||||||
@ -55,8 +74,12 @@ nlr_jump:
|
|||||||
xorq %rax, %rax # clear return register
|
xorq %rax, %rax # clear return register
|
||||||
inc %al # increase to make 1, non-local return
|
inc %al # increase to make 1, non-local return
|
||||||
ret # return
|
ret # return
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.size nlr_jump, .-nlr_jump
|
.size nlr_jump, .-nlr_jump
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __apple_build_version__
|
||||||
.local nlr_top
|
.local nlr_top
|
||||||
|
#endif
|
||||||
.comm nlr_top,8,8
|
.comm nlr_top,8,8
|
||||||
#endif
|
#endif
|
||||||
|
25
py/obj.c
25
py/obj.c
@ -7,15 +7,12 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_int(machine_int_t value) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *mp_obj_get_type_str(mp_obj_t o_in) {
|
const char *mp_obj_get_type_str(mp_obj_t o_in) {
|
||||||
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||||
return "int";
|
return "int";
|
||||||
@ -127,9 +124,13 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
|
|||||||
return 1;
|
return 1;
|
||||||
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
|
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
|
||||||
return MP_OBJ_SMALL_INT_VALUE(arg);
|
return MP_OBJ_SMALL_INT_VALUE(arg);
|
||||||
|
#if MICROPY_ENABLE_FLOAT
|
||||||
|
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
|
||||||
|
// TODO work out if this should be floor, ceil or trunc
|
||||||
|
return (machine_int_t)mp_obj_float_get(arg);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ machine_float_t mp_obj_get_float(mp_obj_t arg) {
|
|||||||
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
|
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
|
||||||
return mp_obj_float_get(arg);
|
return mp_obj_float_get(arg);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +165,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
|
|||||||
} else if (MP_OBJ_IS_TYPE(arg, &complex_type)) {
|
} else if (MP_OBJ_IS_TYPE(arg, &complex_type)) {
|
||||||
mp_obj_complex_get(arg, real, imag);
|
mp_obj_complex_get(arg, real, imag);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -188,11 +189,11 @@ mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) {
|
|||||||
mp_obj_list_get(o_in, &seq_len, &seq_items);
|
mp_obj_list_get(o_in, &seq_len, &seq_items);
|
||||||
}
|
}
|
||||||
if (seq_len != n) {
|
if (seq_len != n) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_IndexError, "requested length %d but object has length %d", (void*)n, (void*)(machine_uint_t)seq_len));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_IndexError, "requested length %d but object has length %d", (void*)n, (void*)(machine_uint_t)seq_len));
|
||||||
}
|
}
|
||||||
return seq_items;
|
return seq_items;
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o_in)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o_in)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,10 +205,10 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index)
|
|||||||
i += len;
|
i += len;
|
||||||
}
|
}
|
||||||
if (i < 0 || i >= len) {
|
if (i < 0 || i >= len) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_IndexError, "%s index out of range", type->name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_IndexError, "%s index out of range", type->name));
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "%s indices must be integers, not %s", type->name, mp_obj_get_type_str(index)));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "%s indices must be integers, not %s", type->name, mp_obj_get_type_str(index)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
py/obj.h
13
py/obj.h
@ -58,6 +58,7 @@ typedef mp_obj_t (*mp_fun_t)(void);
|
|||||||
typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *);
|
typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *);
|
||||||
|
|
||||||
typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o);
|
typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o);
|
||||||
|
typedef mp_obj_t (*mp_make_new_fun_t)(mp_obj_t type_in, int n_args, const mp_obj_t *args); // args are in reverse order in the array
|
||||||
typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array
|
typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array
|
||||||
typedef mp_obj_t (*mp_unary_op_fun_t)(int op, mp_obj_t);
|
typedef mp_obj_t (*mp_unary_op_fun_t)(int op, mp_obj_t);
|
||||||
typedef mp_obj_t (*mp_binary_op_fun_t)(int op, mp_obj_t, mp_obj_t);
|
typedef mp_obj_t (*mp_binary_op_fun_t)(int op, mp_obj_t, mp_obj_t);
|
||||||
@ -71,6 +72,7 @@ struct _mp_obj_type_t {
|
|||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
const char *name;
|
const char *name;
|
||||||
mp_print_fun_t print;
|
mp_print_fun_t print;
|
||||||
|
mp_make_new_fun_t make_new; // to make an instance of the type
|
||||||
|
|
||||||
mp_call_n_fun_t call_n;
|
mp_call_n_fun_t call_n;
|
||||||
mp_unary_op_fun_t unary_op; // can return NULL if op not supported
|
mp_unary_op_fun_t unary_op; // can return NULL if op not supported
|
||||||
@ -110,6 +112,8 @@ extern const mp_obj_type_t mp_const_type;
|
|||||||
extern const mp_obj_t mp_const_none;
|
extern const mp_obj_t mp_const_none;
|
||||||
extern const mp_obj_t mp_const_false;
|
extern const mp_obj_t mp_const_false;
|
||||||
extern const mp_obj_t mp_const_true;
|
extern const mp_obj_t mp_const_true;
|
||||||
|
extern const mp_obj_t mp_const_empty_tuple;
|
||||||
|
extern const mp_obj_t mp_const_ellipsis;
|
||||||
extern const mp_obj_t mp_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!)
|
extern const mp_obj_t mp_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!)
|
||||||
|
|
||||||
// Need to declare this here so we are not dependent on map.h
|
// Need to declare this here so we are not dependent on map.h
|
||||||
@ -144,6 +148,7 @@ mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items);
|
|||||||
mp_obj_t mp_obj_new_list_reverse(uint n, mp_obj_t *items);
|
mp_obj_t mp_obj_new_list_reverse(uint n, mp_obj_t *items);
|
||||||
mp_obj_t mp_obj_new_dict(int n_args);
|
mp_obj_t mp_obj_new_dict(int n_args);
|
||||||
mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items);
|
mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items);
|
||||||
|
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
|
||||||
mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth);
|
mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth);
|
||||||
mp_obj_t mp_obj_new_class(struct _mp_map_t *class_locals);
|
mp_obj_t mp_obj_new_class(struct _mp_map_t *class_locals);
|
||||||
mp_obj_t mp_obj_new_instance(mp_obj_t clas);
|
mp_obj_t mp_obj_new_instance(mp_obj_t clas);
|
||||||
@ -178,6 +183,9 @@ extern const mp_obj_type_t bool_type;
|
|||||||
mp_obj_t mp_obj_cell_get(mp_obj_t self_in);
|
mp_obj_t mp_obj_cell_get(mp_obj_t self_in);
|
||||||
void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj);
|
void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj);
|
||||||
|
|
||||||
|
// int
|
||||||
|
extern const mp_obj_type_t int_type;
|
||||||
|
|
||||||
// exception
|
// exception
|
||||||
extern const mp_obj_type_t exception_type;
|
extern const mp_obj_type_t exception_type;
|
||||||
qstr mp_obj_exception_get_type(mp_obj_t self_in);
|
qstr mp_obj_exception_get_type(mp_obj_t self_in);
|
||||||
@ -212,8 +220,13 @@ uint mp_obj_dict_len(mp_obj_t self_in);
|
|||||||
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
|
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
|
||||||
|
|
||||||
// set
|
// set
|
||||||
|
extern const mp_obj_type_t set_type;
|
||||||
void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item);
|
void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item);
|
||||||
|
|
||||||
|
// slice
|
||||||
|
extern const mp_obj_type_t slice_type;
|
||||||
|
void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *stop, machine_int_t *step);
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM)
|
typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM)
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
|
14
py/objbool.c
14
py/objbool.c
@ -4,14 +4,16 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
typedef struct _mp_obj_bool_t {
|
typedef struct _mp_obj_bool_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
bool value;
|
bool value;
|
||||||
} mp_obj_bool_t;
|
} mp_obj_bool_t;
|
||||||
|
|
||||||
void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
static void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
||||||
mp_obj_bool_t *self = self_in;
|
mp_obj_bool_t *self = self_in;
|
||||||
if (self->value) {
|
if (self->value) {
|
||||||
print(env, "True");
|
print(env, "True");
|
||||||
@ -20,10 +22,20 @@ void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_ob
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// args are reverse in the array
|
||||||
|
static mp_obj_t bool_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0: return mp_const_false;
|
||||||
|
case 1: if (rt_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
|
||||||
|
default: nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "bool takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const mp_obj_type_t bool_type = {
|
const mp_obj_type_t bool_type = {
|
||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"bool",
|
"bool",
|
||||||
bool_print, // print
|
bool_print, // print
|
||||||
|
bool_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -37,6 +37,7 @@ const mp_obj_type_t bound_meth_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"bound_method",
|
"bound_method",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
bound_meth_call_n, // call_n
|
bound_meth_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -27,6 +27,7 @@ const mp_obj_type_t cell_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"cell",
|
"cell",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
@ -25,7 +26,7 @@ mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
mp_obj_t o = mp_obj_new_instance(self_in);
|
mp_obj_t o = mp_obj_new_instance(self_in);
|
||||||
|
|
||||||
// look for __init__ function
|
// look for __init__ function
|
||||||
mp_map_elem_t *init_fn = mp_qstr_map_lookup(self->locals, qstr_from_str_static("__init__"), false);
|
mp_map_elem_t *init_fn = mp_qstr_map_lookup(self->locals, MP_QSTR___init__, false);
|
||||||
|
|
||||||
if (init_fn != NULL) {
|
if (init_fn != NULL) {
|
||||||
// call __init__ function
|
// call __init__ function
|
||||||
@ -40,13 +41,13 @@ mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
m_del(mp_obj_t, args2, n_args + 1);
|
m_del(mp_obj_t, args2, n_args + 1);
|
||||||
}
|
}
|
||||||
if (init_ret != mp_const_none) {
|
if (init_ret != mp_const_none) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
if (n_args != 0) {
|
if (n_args != 0) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "function takes 0 positional arguments but %d were given", (void*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "function takes 0 positional arguments but %d were given", (void*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ const mp_obj_type_t class_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"class",
|
"class",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
class_call_n, // call_n
|
class_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -36,6 +36,7 @@ const mp_obj_type_t closure_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"closure",
|
"closure",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
closure_call_n, // call_n
|
closure_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
@ -29,7 +30,46 @@ void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t complex_unary_op(int op, mp_obj_t o_in) {
|
// args are reverse in the array
|
||||||
|
static mp_obj_t complex_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
return mp_obj_new_complex(0, 0);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// TODO allow string as first arg and parse it
|
||||||
|
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
|
||||||
|
return args[0];
|
||||||
|
} else {
|
||||||
|
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
mp_float_t real, imag;
|
||||||
|
if (MP_OBJ_IS_TYPE(args[1], &complex_type)) {
|
||||||
|
mp_obj_get_complex(args[1], &real, &imag);
|
||||||
|
} else {
|
||||||
|
real = mp_obj_get_float(args[1]);
|
||||||
|
imag = 0;
|
||||||
|
}
|
||||||
|
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
|
||||||
|
mp_float_t real2, imag2;
|
||||||
|
mp_obj_get_complex(args[0], &real2, &imag2);
|
||||||
|
real -= imag2;
|
||||||
|
imag += real2;
|
||||||
|
} else {
|
||||||
|
imag += mp_obj_get_float(args[0]);
|
||||||
|
}
|
||||||
|
return mp_obj_new_complex(real, imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "complex takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t complex_unary_op(int op, mp_obj_t o_in) {
|
||||||
mp_obj_complex_t *o = o_in;
|
mp_obj_complex_t *o = o_in;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case RT_UNARY_OP_NOT: if (o->real != 0 || o->imag != 0) { return mp_const_true;} else { return mp_const_false; }
|
case RT_UNARY_OP_NOT: if (o->real != 0 || o->imag != 0) { return mp_const_true;} else { return mp_const_false; }
|
||||||
@ -39,7 +79,7 @@ mp_obj_t complex_unary_op(int op, mp_obj_t o_in) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
static mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
mp_float_t lhs_real, lhs_imag, rhs_real, rhs_imag;
|
mp_float_t lhs_real, lhs_imag, rhs_real, rhs_imag;
|
||||||
mp_obj_complex_get(lhs_in, &lhs_real, &lhs_imag);
|
mp_obj_complex_get(lhs_in, &lhs_real, &lhs_imag);
|
||||||
mp_obj_complex_get(rhs_in, &rhs_real, &rhs_imag);
|
mp_obj_complex_get(rhs_in, &rhs_real, &rhs_imag);
|
||||||
@ -79,6 +119,7 @@ const mp_obj_type_t complex_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"complex",
|
"complex",
|
||||||
complex_print, // print
|
complex_print, // print
|
||||||
|
complex_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
complex_unary_op, // unary_op
|
complex_unary_op, // unary_op
|
||||||
complex_binary_op, // binary_op
|
complex_binary_op, // binary_op
|
||||||
|
14
py/objdict.c
14
py/objdict.c
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -16,7 +17,7 @@ typedef struct _mp_obj_dict_t {
|
|||||||
mp_map_t map;
|
mp_map_t map;
|
||||||
} mp_obj_dict_t;
|
} mp_obj_dict_t;
|
||||||
|
|
||||||
void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
||||||
mp_obj_dict_t *self = self_in;
|
mp_obj_dict_t *self = self_in;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
print(env, "{");
|
print(env, "{");
|
||||||
@ -34,7 +35,13 @@ void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_ob
|
|||||||
print(env, "}");
|
print(env, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
// args are reverse in the array
|
||||||
|
static mp_obj_t dict_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
// TODO create from an iterable!
|
||||||
|
return rt_build_map(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
mp_obj_dict_t *o = lhs_in;
|
mp_obj_dict_t *o = lhs_in;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case RT_BINARY_OP_SUBSCR:
|
case RT_BINARY_OP_SUBSCR:
|
||||||
@ -42,7 +49,7 @@ mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
// dict load
|
// dict load
|
||||||
mp_map_elem_t *elem = mp_map_lookup_helper(&o->map, rhs_in, false);
|
mp_map_elem_t *elem = mp_map_lookup_helper(&o->map, rhs_in, false);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_KeyError, "<value>"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>"));
|
||||||
} else {
|
} else {
|
||||||
return elem->value;
|
return elem->value;
|
||||||
}
|
}
|
||||||
@ -57,6 +64,7 @@ const mp_obj_type_t dict_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"dict",
|
"dict",
|
||||||
dict_print, // print
|
dict_print, // print
|
||||||
|
dict_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
dict_binary_op, // binary_op
|
dict_binary_op, // binary_op
|
||||||
|
@ -39,6 +39,7 @@ const mp_obj_type_t exception_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"exception",
|
"exception",
|
||||||
exception_print, // print
|
exception_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
|
|
||||||
@ -18,12 +19,30 @@ typedef struct _mp_obj_float_t {
|
|||||||
|
|
||||||
mp_obj_t mp_obj_new_float(mp_float_t value);
|
mp_obj_t mp_obj_new_float(mp_float_t value);
|
||||||
|
|
||||||
void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
|
static void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
|
||||||
mp_obj_float_t *o = o_in;
|
mp_obj_float_t *o = o_in;
|
||||||
print(env, "%.8g", o->value);
|
print(env, "%.8g", o->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
|
static mp_obj_t float_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
return mp_obj_new_float(0);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// TODO allow string as arg and parse it
|
||||||
|
if (MP_OBJ_IS_TYPE(args[0], &float_type)) {
|
||||||
|
return args[0];
|
||||||
|
} else {
|
||||||
|
return mp_obj_new_float(mp_obj_get_float(args[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
|
||||||
mp_obj_float_t *o = o_in;
|
mp_obj_float_t *o = o_in;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case RT_UNARY_OP_NOT: if (o->value != 0) { return mp_const_true;} else { return mp_const_false; }
|
case RT_UNARY_OP_NOT: if (o->value != 0) { return mp_const_true;} else { return mp_const_false; }
|
||||||
@ -33,7 +52,7 @@ mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
static mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
if (MP_OBJ_IS_TYPE(rhs_in, &complex_type)) {
|
if (MP_OBJ_IS_TYPE(rhs_in, &complex_type)) {
|
||||||
return complex_type.binary_op(op, lhs_in, rhs_in);
|
return complex_type.binary_op(op, lhs_in, rhs_in);
|
||||||
}
|
}
|
||||||
@ -61,6 +80,7 @@ const mp_obj_type_t float_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"float",
|
"float",
|
||||||
float_print,
|
float_print,
|
||||||
|
float_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
float_unary_op,
|
float_unary_op,
|
||||||
float_binary_op,
|
float_binary_op,
|
||||||
|
14
py/objfun.c
14
py/objfun.c
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -24,7 +25,7 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
// check number of arguments
|
// check number of arguments
|
||||||
if (n_args != self->n_args_min) {
|
if (n_args != self->n_args_min) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch function call
|
// dispatch function call
|
||||||
@ -47,9 +48,9 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
// function takes a variable number of arguments
|
// function takes a variable number of arguments
|
||||||
|
|
||||||
if (n_args < self->n_args_min) {
|
if (n_args < self->n_args_min) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args)));
|
||||||
} else if (n_args > self->n_args_max) {
|
} else if (n_args > self->n_args_max) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args
|
// TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args
|
||||||
@ -69,6 +70,7 @@ const mp_obj_type_t fun_native_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"function",
|
"function",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
fun_native_call_n, // call_n
|
fun_native_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
@ -141,7 +143,7 @@ mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
mp_obj_fun_bc_t *self = self_in;
|
mp_obj_fun_bc_t *self = self_in;
|
||||||
|
|
||||||
if (n_args != self->n_args) {
|
if (n_args != self->n_args) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimisation: allow the compiler to optimise this tail call for
|
// optimisation: allow the compiler to optimise this tail call for
|
||||||
@ -161,6 +163,7 @@ const mp_obj_type_t fun_bc_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"function",
|
"function",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
fun_bc_call_n, // call_n
|
fun_bc_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
@ -250,7 +253,7 @@ mp_obj_t fun_asm_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
mp_obj_fun_asm_t *self = self_in;
|
mp_obj_fun_asm_t *self = self_in;
|
||||||
|
|
||||||
if (n_args != self->n_args) {
|
if (n_args != self->n_args) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_uint_t ret;
|
machine_uint_t ret;
|
||||||
@ -274,6 +277,7 @@ static const mp_obj_type_t fun_asm_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"function",
|
"function",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
fun_asm_call_n, // call_n
|
fun_asm_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "bc.h"
|
#include "bc.h"
|
||||||
@ -29,7 +30,7 @@ mp_obj_t gen_wrap_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
|||||||
const byte *bc_code;
|
const byte *bc_code;
|
||||||
mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code);
|
mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code);
|
||||||
if (n_args != bc_n_args) {
|
if (n_args != bc_n_args) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)bc_n_args, (const char*)(machine_int_t)n_args));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)bc_n_args, (const char*)(machine_int_t)n_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mp_obj_new_gen_instance(bc_code, self->n_state, n_args, args);
|
return mp_obj_new_gen_instance(bc_code, self->n_state, n_args, args);
|
||||||
@ -39,6 +40,7 @@ const mp_obj_type_t gen_wrap_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"generator",
|
"generator",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
gen_wrap_call_n, // call_n
|
gen_wrap_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
@ -93,6 +95,7 @@ const mp_obj_type_t gen_instance_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"generator",
|
"generator",
|
||||||
gen_instance_print, // print
|
gen_instance_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
@ -44,7 +45,7 @@ mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr) {
|
|||||||
return elem->value;
|
return elem->value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(self_in), qstr_str(attr)));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(self_in), qstr_str(attr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||||
@ -92,6 +93,7 @@ const mp_obj_type_t instance_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"instance",
|
"instance",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
48
py/objint.c
Normal file
48
py/objint.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
|
#include "obj.h"
|
||||||
|
|
||||||
|
typedef struct _mp_obj_int_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} mp_obj_int_t;
|
||||||
|
|
||||||
|
static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(0);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// TODO allow string as arg and parse it
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
|
||||||
|
|
||||||
|
//case 2:
|
||||||
|
// TODO, parse with given base
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mp_obj_type_t int_type = {
|
||||||
|
{ &mp_const_type },
|
||||||
|
"int",
|
||||||
|
NULL,
|
||||||
|
int_make_new, // make_new
|
||||||
|
NULL, // call_n
|
||||||
|
NULL, // unary_op
|
||||||
|
NULL, // binary_op
|
||||||
|
NULL, // getiter
|
||||||
|
NULL, // iternext
|
||||||
|
{ { NULL, NULL }, }, // method list
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_obj_t mp_obj_new_int(machine_int_t value) {
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(value);
|
||||||
|
}
|
28
py/objlist.c
28
py/objlist.c
@ -6,6 +6,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -35,6 +36,29 @@ static void list_print(void (*print)(void *env, const char *fmt, ...), void *env
|
|||||||
print(env, "]");
|
print(env, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mp_obj_t list_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
// return a new, empty list
|
||||||
|
return rt_build_list(0, NULL);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// make list from iterable
|
||||||
|
mp_obj_t iterable = rt_getiter(args[0]);
|
||||||
|
mp_obj_t list = rt_build_list(0, NULL);
|
||||||
|
mp_obj_t item;
|
||||||
|
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
||||||
|
rt_list_append(list, item);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||||
mp_obj_list_t *o = lhs;
|
mp_obj_list_t *o = lhs;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -81,7 +105,7 @@ static mp_obj_t list_pop(int n_args, const mp_obj_t *args) {
|
|||||||
assert(MP_OBJ_IS_TYPE(args[0], &list_type));
|
assert(MP_OBJ_IS_TYPE(args[0], &list_type));
|
||||||
mp_obj_list_t *self = args[0];
|
mp_obj_list_t *self = args[0];
|
||||||
if (self->len == 0) {
|
if (self->len == 0) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_IndexError, "pop from empty list"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "pop from empty list"));
|
||||||
}
|
}
|
||||||
uint index = mp_get_index(self->base.type, self->len, n_args == 1 ? mp_obj_new_int(-1) : args[1]);
|
uint index = mp_get_index(self->base.type, self->len, n_args == 1 ? mp_obj_new_int(-1) : args[1]);
|
||||||
mp_obj_t ret = self->items[index];
|
mp_obj_t ret = self->items[index];
|
||||||
@ -185,6 +209,7 @@ const mp_obj_type_t list_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"list",
|
"list",
|
||||||
list_print, // print
|
list_print, // print
|
||||||
|
list_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
list_binary_op, // binary_op
|
list_binary_op, // binary_op
|
||||||
@ -263,6 +288,7 @@ static const mp_obj_type_t list_it_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"list_iterator",
|
"list_iterator",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -25,6 +25,7 @@ const mp_obj_type_t module_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"module",
|
"module",
|
||||||
module_print, // print
|
module_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -18,6 +18,7 @@ const mp_obj_type_t none_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"NoneType",
|
"NoneType",
|
||||||
none_print, // print
|
none_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -26,6 +26,7 @@ static const mp_obj_type_t range_type = {
|
|||||||
{ &mp_const_type} ,
|
{ &mp_const_type} ,
|
||||||
"range",
|
"range",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
@ -70,6 +71,7 @@ static const mp_obj_type_t range_it_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"range_iterator",
|
"range_iterator",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
28
py/objset.c
28
py/objset.c
@ -5,7 +5,9 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
#include "runtime.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
typedef struct _mp_obj_set_t {
|
typedef struct _mp_obj_set_t {
|
||||||
@ -29,10 +31,34 @@ void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
|
|||||||
print(env, "}");
|
print(env, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const mp_obj_type_t set_type = {
|
static mp_obj_t set_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
// return a new, empty set
|
||||||
|
return mp_obj_new_set(0, NULL);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// 1 argument, an iterable from which we make a new set
|
||||||
|
mp_obj_t set = mp_obj_new_set(0, NULL);
|
||||||
|
mp_obj_t iterable = rt_getiter(args[0]);
|
||||||
|
mp_obj_t item;
|
||||||
|
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
||||||
|
mp_obj_set_store(set, item);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "set takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mp_obj_type_t set_type = {
|
||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"set",
|
"set",
|
||||||
set_print, // print
|
set_print, // print
|
||||||
|
set_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
105
py/objslice.c
Normal file
105
py/objslice.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
#include "obj.h"
|
||||||
|
#include "runtime0.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* ellipsis object, a singleton */
|
||||||
|
|
||||||
|
typedef struct _mp_obj_ellipsis_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} mp_obj_ellipsis_t;
|
||||||
|
|
||||||
|
void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
||||||
|
print(env, "Ellipsis");
|
||||||
|
}
|
||||||
|
|
||||||
|
const mp_obj_type_t ellipsis_type = {
|
||||||
|
{ &mp_const_type },
|
||||||
|
"ellipsis",
|
||||||
|
ellipsis_print, // print
|
||||||
|
NULL, // make_new
|
||||||
|
NULL, // call_n
|
||||||
|
NULL, // unary_op
|
||||||
|
NULL, // binary_op
|
||||||
|
NULL, // getiter
|
||||||
|
NULL, // iternext
|
||||||
|
{{NULL, NULL},}, // method list
|
||||||
|
};
|
||||||
|
|
||||||
|
static const mp_obj_ellipsis_t ellipsis_obj = {{&ellipsis_type}};
|
||||||
|
const mp_obj_t mp_const_ellipsis = (mp_obj_t)&ellipsis_obj;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* slice object */
|
||||||
|
|
||||||
|
#if MICROPY_ENABLE_SLICE
|
||||||
|
|
||||||
|
// TODO: This implements only variant of slice with 2 integer args only.
|
||||||
|
// CPython supports 3rd arg (step), plus args can be arbitrary Python objects.
|
||||||
|
typedef struct _mp_obj_slice_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
machine_int_t start;
|
||||||
|
machine_int_t stop;
|
||||||
|
} mp_obj_slice_t;
|
||||||
|
|
||||||
|
void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
|
||||||
|
mp_obj_slice_t *o = o_in;
|
||||||
|
print(env, "slice(" INT_FMT ", " INT_FMT ")", o->start, o->stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mp_obj_type_t slice_type = {
|
||||||
|
{ &mp_const_type },
|
||||||
|
"slice",
|
||||||
|
slice_print,
|
||||||
|
NULL, // call_n
|
||||||
|
NULL, // make_new
|
||||||
|
NULL, // unary_op
|
||||||
|
NULL, // binary_op
|
||||||
|
NULL, // getiter
|
||||||
|
NULL, // iternext
|
||||||
|
{ { NULL, NULL }, }, // method list
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Make sure to handle "empty" values, which are signified by None in CPython
|
||||||
|
mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
|
||||||
|
assert(ostep == NULL);
|
||||||
|
machine_int_t start = 0, stop = 0;
|
||||||
|
if (ostart != mp_const_none) {
|
||||||
|
start = mp_obj_get_int(ostart);
|
||||||
|
}
|
||||||
|
if (ostop != mp_const_none) {
|
||||||
|
stop = mp_obj_get_int(ostop);
|
||||||
|
if (stop == 0) {
|
||||||
|
// [x:0] is a special case - in our slice object, stop = 0 means
|
||||||
|
// "end of sequence". Fortunately, [x:0] is an empty seqence for
|
||||||
|
// any x (including negative). [x:x] is also always empty sequence.
|
||||||
|
// but x also can be 0. But note that b""[x:x] is b"" for any x (i.e.
|
||||||
|
// no IndexError, at least in Python 3.3.3). So, we just use -1's to
|
||||||
|
// signify that. -1 is catchy "special" number in case someone will
|
||||||
|
// try to print [x:0] slice ever.
|
||||||
|
start = stop = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mp_obj_slice_t *o = m_new(mp_obj_slice_t, 1);
|
||||||
|
o->base.type = &slice_type;
|
||||||
|
o->start = start;
|
||||||
|
o->stop = stop;
|
||||||
|
return (mp_obj_t)o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *stop, machine_int_t *step) {
|
||||||
|
assert(MP_OBJ_IS_TYPE(self_in, &slice_type));
|
||||||
|
mp_obj_slice_t *self = self_in;
|
||||||
|
*start = self->start;
|
||||||
|
*stop = self->stop;
|
||||||
|
*step = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
43
py/objstr.c
43
py/objstr.c
@ -7,6 +7,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -27,9 +28,42 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
const char *lhs_str = qstr_str(lhs->qstr);
|
const char *lhs_str = qstr_str(lhs->qstr);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case RT_BINARY_OP_SUBSCR:
|
case RT_BINARY_OP_SUBSCR:
|
||||||
// string access
|
// TODO: need predicate to check for int-like type (bools are such for example)
|
||||||
// XXX a massive hack!
|
// ["no", "yes"][1 == 2] is common idiom
|
||||||
|
if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
|
||||||
|
// TODO: This implements byte string access for single index so far
|
||||||
|
// TODO: Handle negative indexes.
|
||||||
return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]);
|
return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]);
|
||||||
|
#if MICROPY_ENABLE_SLICE
|
||||||
|
} else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
|
||||||
|
machine_int_t start, stop, step;
|
||||||
|
mp_obj_slice_get(rhs_in, &start, &stop, &step);
|
||||||
|
assert(step == 1);
|
||||||
|
int len = strlen(lhs_str);
|
||||||
|
if (start < 0) {
|
||||||
|
start = len + start;
|
||||||
|
if (start < 0) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
} else if (start > len) {
|
||||||
|
start = len;
|
||||||
|
}
|
||||||
|
if (stop <= 0) {
|
||||||
|
stop = len + stop;
|
||||||
|
// CPython returns empty string in such case
|
||||||
|
if (stop < 0) {
|
||||||
|
stop = start;
|
||||||
|
}
|
||||||
|
} else if (stop > len) {
|
||||||
|
stop = len;
|
||||||
|
}
|
||||||
|
return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// Message doesn't match CPython, but we don't have so much bytes as they
|
||||||
|
// to spend them on verbose wording
|
||||||
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "index must be int"));
|
||||||
|
}
|
||||||
|
|
||||||
case RT_BINARY_OP_ADD:
|
case RT_BINARY_OP_ADD:
|
||||||
case RT_BINARY_OP_INPLACE_ADD:
|
case RT_BINARY_OP_INPLACE_ADD:
|
||||||
@ -101,7 +135,7 @@ mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
|
|||||||
return mp_obj_new_str(qstr_from_str_take(joined_str, required_len + 1));
|
return mp_obj_new_str(qstr_from_str_take(joined_str, required_len + 1));
|
||||||
|
|
||||||
bad_arg:
|
bad_arg:
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "?str.join expecting a list of str's"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void vstr_printf_wrapper(void *env, const char *fmt, ...) {
|
void vstr_printf_wrapper(void *env, const char *fmt, ...) {
|
||||||
@ -125,7 +159,7 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
|
|||||||
vstr_add_char(vstr, '{');
|
vstr_add_char(vstr, '{');
|
||||||
} else if (*str == '}') {
|
} else if (*str == '}') {
|
||||||
if (arg_i >= n_args) {
|
if (arg_i >= n_args) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_IndexError, "tuple index out of range"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "tuple index out of range"));
|
||||||
}
|
}
|
||||||
mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]);
|
mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]);
|
||||||
arg_i++;
|
arg_i++;
|
||||||
@ -145,6 +179,7 @@ const mp_obj_type_t str_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"str",
|
"str",
|
||||||
str_print, // print
|
str_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
str_binary_op, // binary_op
|
str_binary_op, // binary_op
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
//#include <string.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
typedef struct _mp_obj_tuple_t {
|
typedef struct _mp_obj_tuple_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
@ -20,7 +21,7 @@ static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur);
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* tuple */
|
/* tuple */
|
||||||
|
|
||||||
void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
|
static void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
|
||||||
mp_obj_tuple_t *o = o_in;
|
mp_obj_tuple_t *o = o_in;
|
||||||
print(env, "(");
|
print(env, "(");
|
||||||
for (int i = 0; i < o->len; i++) {
|
for (int i = 0; i < o->len; i++) {
|
||||||
@ -35,7 +36,48 @@ void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_o
|
|||||||
print(env, ")");
|
print(env, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
// args are in reverse order in the array
|
||||||
|
static mp_obj_t tuple_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
|
||||||
|
switch (n_args) {
|
||||||
|
case 0:
|
||||||
|
// return a empty tuple
|
||||||
|
return mp_const_empty_tuple;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// 1 argument, an iterable from which we make a new tuple
|
||||||
|
if (MP_OBJ_IS_TYPE(args[0], &tuple_type)) {
|
||||||
|
return args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO optimise for cases where we know the length of the iterator
|
||||||
|
|
||||||
|
uint alloc = 4;
|
||||||
|
uint len = 0;
|
||||||
|
mp_obj_t *items = m_new(mp_obj_t, alloc);
|
||||||
|
|
||||||
|
mp_obj_t iterable = rt_getiter(args[0]);
|
||||||
|
mp_obj_t item;
|
||||||
|
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
|
||||||
|
if (len >= alloc) {
|
||||||
|
items = m_renew(mp_obj_t, items, alloc, alloc * 2);
|
||||||
|
alloc *= 2;
|
||||||
|
}
|
||||||
|
items[len++] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t tuple = mp_obj_new_tuple(len, items);
|
||||||
|
m_free(items, alloc);
|
||||||
|
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "tuple takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||||
mp_obj_tuple_t *o = lhs;
|
mp_obj_tuple_t *o = lhs;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case RT_BINARY_OP_SUBSCR:
|
case RT_BINARY_OP_SUBSCR:
|
||||||
@ -50,20 +92,15 @@ mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t tuple_getiter(mp_obj_t o_in) {
|
static mp_obj_t tuple_getiter(mp_obj_t o_in) {
|
||||||
return mp_obj_new_tuple_iterator(o_in, 0);
|
return mp_obj_new_tuple_iterator(o_in, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items) {
|
|
||||||
mp_obj_tuple_t *self = self_in;
|
|
||||||
*len = self->len;
|
|
||||||
*items = &self->items[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const mp_obj_type_t tuple_type = {
|
const mp_obj_type_t tuple_type = {
|
||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"tuple",
|
"tuple",
|
||||||
tuple_print, // print
|
tuple_print, // print
|
||||||
|
tuple_make_new, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
tuple_binary_op, // binary_op
|
tuple_binary_op, // binary_op
|
||||||
@ -72,7 +109,14 @@ const mp_obj_type_t tuple_type = {
|
|||||||
{{NULL, NULL},}, // method list
|
{{NULL, NULL},}, // method list
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// the zero-length tuple
|
||||||
|
static const mp_obj_tuple_t empty_tuple_obj = {{&tuple_type}, 0};
|
||||||
|
const mp_obj_t mp_const_empty_tuple = (mp_obj_t)&empty_tuple_obj;
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) {
|
mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) {
|
||||||
|
if (n == 0) {
|
||||||
|
return mp_const_empty_tuple;
|
||||||
|
}
|
||||||
mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n);
|
mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n);
|
||||||
o->base.type = &tuple_type;
|
o->base.type = &tuple_type;
|
||||||
o->len = n;
|
o->len = n;
|
||||||
@ -83,6 +127,9 @@ mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items) {
|
mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items) {
|
||||||
|
if (n == 0) {
|
||||||
|
return mp_const_empty_tuple;
|
||||||
|
}
|
||||||
mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n);
|
mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n);
|
||||||
o->base.type = &tuple_type;
|
o->base.type = &tuple_type;
|
||||||
o->len = n;
|
o->len = n;
|
||||||
@ -92,6 +139,12 @@ mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items) {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items) {
|
||||||
|
mp_obj_tuple_t *self = self_in;
|
||||||
|
*len = self->len;
|
||||||
|
*items = &self->items[0];
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* tuple iterator */
|
/* tuple iterator */
|
||||||
|
|
||||||
@ -101,7 +154,7 @@ typedef struct _mp_obj_tuple_it_t {
|
|||||||
machine_uint_t cur;
|
machine_uint_t cur;
|
||||||
} mp_obj_tuple_it_t;
|
} mp_obj_tuple_it_t;
|
||||||
|
|
||||||
mp_obj_t tuple_it_iternext(mp_obj_t self_in) {
|
static mp_obj_t tuple_it_iternext(mp_obj_t self_in) {
|
||||||
mp_obj_tuple_it_t *self = self_in;
|
mp_obj_tuple_it_t *self = self_in;
|
||||||
if (self->cur < self->tuple->len) {
|
if (self->cur < self->tuple->len) {
|
||||||
mp_obj_t o_out = self->tuple->items[self->cur];
|
mp_obj_t o_out = self->tuple->items[self->cur];
|
||||||
@ -116,6 +169,7 @@ static const mp_obj_type_t tuple_it_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"tuple_iterator",
|
"tuple_iterator",
|
||||||
NULL, // print
|
NULL, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
21
py/objtype.c
21
py/objtype.c
@ -4,17 +4,30 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
|
||||||
void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
||||||
print(env, "<a type>");
|
mp_obj_type_t *self = self_in;
|
||||||
|
print(env, "<class '%s'>", self->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t type_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_type_t *self = self_in;
|
||||||
|
if (self->make_new != NULL) {
|
||||||
|
// TODO we need to init the object if it's an instance of a type
|
||||||
|
return self->make_new(self, n_args, args);
|
||||||
|
} else {
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "cannot create '%s' instances", self->name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mp_obj_type_t mp_const_type = {
|
const mp_obj_type_t mp_const_type = {
|
||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"<a type>",
|
"type",
|
||||||
type_print, // print
|
type_print, // print
|
||||||
NULL, // call_n
|
NULL, // make_new
|
||||||
|
type_call_n, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
NULL, // getiter
|
NULL, // getiter
|
||||||
|
99
py/qstr.c
99
py/qstr.c
@ -2,55 +2,110 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
|
|
||||||
static int qstrs_alloc;
|
// NOTE: we are using linear arrays to store and search for qstr's (unique strings, interned strings)
|
||||||
static int qstrs_len;
|
// ultimately we will replace this with a static hash table of some kind
|
||||||
static const char **qstrs;
|
// also probably need to include the length in the string data, to allow null bytes in the string
|
||||||
|
|
||||||
|
#if 0 // print debugging info
|
||||||
|
#include <stdio.h>
|
||||||
|
#define DEBUG_printf(args...) printf(args)
|
||||||
|
#else // don't print debugging info
|
||||||
|
#define DEBUG_printf(args...) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _qstr_pool_t {
|
||||||
|
struct _qstr_pool_t *prev;
|
||||||
|
uint total_prev_len;
|
||||||
|
uint alloc;
|
||||||
|
uint len;
|
||||||
|
const char *qstrs[];
|
||||||
|
} qstr_pool_t;
|
||||||
|
|
||||||
|
const static qstr_pool_t const_pool = {
|
||||||
|
NULL, // no previous pool
|
||||||
|
0, // no previous pool
|
||||||
|
10, // set so that the first dynamically allocated pool is twice this size; must be <= the len (just below)
|
||||||
|
MP_QSTR_number_of, // corresponds to number of strings in array just below
|
||||||
|
{
|
||||||
|
"nil", // must be first, since 0 qstr is nil
|
||||||
|
#define Q(id) #id,
|
||||||
|
#include "mpqstrraw.h"
|
||||||
|
#undef Q
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static qstr_pool_t *last_pool = (qstr_pool_t*)&const_pool; // we won't modify the const_pool since it has no allocated room left
|
||||||
|
|
||||||
void qstr_init(void) {
|
void qstr_init(void) {
|
||||||
qstrs_alloc = 400;
|
// nothing to do!
|
||||||
qstrs_len = 1;
|
|
||||||
qstrs = m_new(const char*, qstrs_alloc);
|
|
||||||
qstrs[0] = "nil";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static qstr qstr_add(const char *str) {
|
static qstr qstr_add(const char *str) {
|
||||||
if (qstrs_len >= qstrs_alloc) {
|
DEBUG_printf("QSTR: add %s\n", str);
|
||||||
qstrs = m_renew(const char*, qstrs, qstrs_alloc, qstrs_alloc * 2);
|
|
||||||
qstrs_alloc *= 2;
|
// make sure we have room in the pool for a new qstr
|
||||||
|
if (last_pool->len >= last_pool->alloc) {
|
||||||
|
qstr_pool_t *pool = m_new_obj_var(qstr_pool_t, const char*, last_pool->alloc * 2);
|
||||||
|
pool->prev = last_pool;
|
||||||
|
pool->total_prev_len = last_pool->total_prev_len + last_pool->len;
|
||||||
|
pool->alloc = last_pool->alloc * 2;
|
||||||
|
pool->len = 0;
|
||||||
|
last_pool = pool;
|
||||||
|
DEBUG_printf("QSTR: allocate new pool of size %d\n", last_pool->alloc);
|
||||||
}
|
}
|
||||||
qstrs[qstrs_len++] = str;
|
|
||||||
return qstrs_len - 1;
|
// add the new qstr
|
||||||
|
last_pool->qstrs[last_pool->len++] = str;
|
||||||
|
|
||||||
|
// return id for the newly-added qstr
|
||||||
|
return last_pool->total_prev_len + last_pool->len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
qstr qstr_from_str_static(const char *str) {
|
qstr qstr_from_str_static(const char *str) {
|
||||||
for (int i = 0; i < qstrs_len; i++) {
|
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||||
if (strcmp(qstrs[i], str) == 0) {
|
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||||
return i;
|
if (strcmp(*qstr, str) == 0) {
|
||||||
|
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return qstr_add(str);
|
return qstr_add(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
qstr qstr_from_str_take(char *str, int alloc_len) {
|
qstr qstr_from_str_take(char *str, int alloc_len) {
|
||||||
for (int i = 0; i < qstrs_len; i++) {
|
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||||
if (strcmp(qstrs[i], str) == 0) {
|
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||||
|
if (strcmp(*qstr, str) == 0) {
|
||||||
m_del(char, str, alloc_len);
|
m_del(char, str, alloc_len);
|
||||||
return i;
|
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return qstr_add(str);
|
return qstr_add(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
qstr qstr_from_strn_copy(const char *str, int len) {
|
qstr qstr_from_strn_copy(const char *str, int len) {
|
||||||
for (int i = 0; i < qstrs_len; i++) {
|
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||||
if (strncmp(qstrs[i], str, len) == 0 && qstrs[i][len] == '\0') {
|
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||||
return i;
|
if (strncmp(*qstr, str, len) == 0 && (*qstr)[len] == '\0') {
|
||||||
|
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return qstr_add(strndup(str, len));
|
return qstr_add(strndup(str, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert qstr id to pointer to its string
|
||||||
const char *qstr_str(qstr qstr) {
|
const char *qstr_str(qstr qstr) {
|
||||||
return qstrs[qstr];
|
// search
|
||||||
|
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||||
|
if (qstr >= pool->total_prev_len) {
|
||||||
|
return pool->qstrs[qstr - pool->total_prev_len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found, return nil
|
||||||
|
return const_pool.qstrs[0];
|
||||||
}
|
}
|
||||||
|
159
py/runtime.c
159
py/runtime.c
@ -11,6 +11,7 @@
|
|||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "runtime0.h"
|
#include "runtime0.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
@ -27,22 +28,6 @@
|
|||||||
#define DEBUG_OP_printf(args...) (void)0
|
#define DEBUG_OP_printf(args...) (void)0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO make these predefined so they don't take up RAM
|
|
||||||
qstr rt_q_append;
|
|
||||||
qstr rt_q_pop;
|
|
||||||
qstr rt_q_sort;
|
|
||||||
qstr rt_q_join;
|
|
||||||
qstr rt_q_format;
|
|
||||||
qstr rt_q___build_class__;
|
|
||||||
qstr rt_q___next__;
|
|
||||||
qstr rt_q_AttributeError;
|
|
||||||
qstr rt_q_IndexError;
|
|
||||||
qstr rt_q_KeyError;
|
|
||||||
qstr rt_q_NameError;
|
|
||||||
qstr rt_q_TypeError;
|
|
||||||
qstr rt_q_SyntaxError;
|
|
||||||
qstr rt_q_ValueError;
|
|
||||||
|
|
||||||
// locals and globals need to be pointers because they can be the same in outer module scope
|
// locals and globals need to be pointers because they can be the same in outer module scope
|
||||||
static mp_map_t *map_locals;
|
static mp_map_t *map_locals;
|
||||||
static mp_map_t *map_globals;
|
static mp_map_t *map_globals;
|
||||||
@ -83,74 +68,64 @@ FILE *fp_write_code = NULL;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void rt_init(void) {
|
void rt_init(void) {
|
||||||
rt_q_append = qstr_from_str_static("append");
|
|
||||||
rt_q_pop = qstr_from_str_static("pop");
|
|
||||||
rt_q_sort = qstr_from_str_static("sort");
|
|
||||||
rt_q_join = qstr_from_str_static("join");
|
|
||||||
rt_q_format = qstr_from_str_static("format");
|
|
||||||
rt_q___build_class__ = qstr_from_str_static("__build_class__");
|
|
||||||
rt_q___next__ = qstr_from_str_static("__next__");
|
|
||||||
rt_q_AttributeError = qstr_from_str_static("AttributeError");
|
|
||||||
rt_q_IndexError = qstr_from_str_static("IndexError");
|
|
||||||
rt_q_KeyError = qstr_from_str_static("KeyError");
|
|
||||||
rt_q_NameError = qstr_from_str_static("NameError");
|
|
||||||
rt_q_TypeError = qstr_from_str_static("TypeError");
|
|
||||||
rt_q_SyntaxError = qstr_from_str_static("SyntaxError");
|
|
||||||
rt_q_ValueError = qstr_from_str_static("ValueError");
|
|
||||||
|
|
||||||
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
|
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
|
||||||
map_locals = map_globals = mp_map_new(MP_MAP_QSTR, 1);
|
map_locals = map_globals = mp_map_new(MP_MAP_QSTR, 1);
|
||||||
mp_qstr_map_lookup(map_globals, qstr_from_str_static("__name__"), true)->value = mp_obj_new_str(qstr_from_str_static("__main__"));
|
mp_qstr_map_lookup(map_globals, MP_QSTR___name__, true)->value = mp_obj_new_str(MP_QSTR___main__);
|
||||||
|
|
||||||
// init built-in hash table
|
// init built-in hash table
|
||||||
mp_map_init(&map_builtins, MP_MAP_QSTR, 3);
|
mp_map_init(&map_builtins, MP_MAP_QSTR, 3);
|
||||||
|
|
||||||
// built-in exceptions (TODO, make these proper classes)
|
// built-in exceptions (TODO, make these proper classes)
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_AttributeError, true)->value = mp_obj_new_exception(rt_q_AttributeError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_AttributeError, true)->value = mp_obj_new_exception(MP_QSTR_AttributeError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_IndexError, true)->value = mp_obj_new_exception(rt_q_IndexError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_IndexError, true)->value = mp_obj_new_exception(MP_QSTR_IndexError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_KeyError, true)->value = mp_obj_new_exception(rt_q_KeyError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_KeyError, true)->value = mp_obj_new_exception(MP_QSTR_KeyError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_NameError, true)->value = mp_obj_new_exception(rt_q_NameError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_NameError, true)->value = mp_obj_new_exception(MP_QSTR_NameError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_TypeError, true)->value = mp_obj_new_exception(rt_q_TypeError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_TypeError, true)->value = mp_obj_new_exception(MP_QSTR_TypeError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_SyntaxError, true)->value = mp_obj_new_exception(rt_q_SyntaxError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_SyntaxError, true)->value = mp_obj_new_exception(MP_QSTR_SyntaxError);
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q_ValueError, true)->value = mp_obj_new_exception(rt_q_ValueError);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_ValueError, true)->value = mp_obj_new_exception(MP_QSTR_ValueError);
|
||||||
|
|
||||||
|
// built-in objects
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_Ellipsis, true)->value = mp_const_ellipsis;
|
||||||
|
|
||||||
// built-in core functions
|
// built-in core functions
|
||||||
mp_qstr_map_lookup(&map_builtins, rt_q___build_class__, true)->value = rt_make_function_2(mp_builtin___build_class__);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR___build_class__, true)->value = rt_make_function_2(mp_builtin___build_class__);
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("__repl_print__"), true)->value = rt_make_function_1(mp_builtin___repl_print__);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR___repl_print__, true)->value = rt_make_function_1(mp_builtin___repl_print__);
|
||||||
|
|
||||||
// built-in user functions
|
// built-in types
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("abs"), true)->value = rt_make_function_1(mp_builtin_abs);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_bool, true)->value = (mp_obj_t)&bool_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("all"), true)->value = rt_make_function_1(mp_builtin_all);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("any"), true)->value = rt_make_function_1(mp_builtin_any);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("bool"), true)->value = rt_make_function_var(0, mp_builtin_bool);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("callable"), true)->value = rt_make_function_1(mp_builtin_callable);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("chr"), true)->value = rt_make_function_1(mp_builtin_chr);
|
|
||||||
#if MICROPY_ENABLE_FLOAT
|
#if MICROPY_ENABLE_FLOAT
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("complex"), true)->value = (mp_obj_t)&mp_builtin_complex_obj;
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_complex, true)->value = (mp_obj_t)&complex_type;
|
||||||
#endif
|
#endif
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("dict"), true)->value = rt_make_function_0(mp_builtin_dict);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_dict, true)->value = (mp_obj_t)&dict_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("divmod"), true)->value = rt_make_function_2(mp_builtin_divmod);
|
|
||||||
#if MICROPY_ENABLE_FLOAT
|
#if MICROPY_ENABLE_FLOAT
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("float"), true)->value = (mp_obj_t)&mp_builtin_float_obj;
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_float, true)->value = (mp_obj_t)&float_type;
|
||||||
#endif
|
#endif
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("hash"), true)->value = (mp_obj_t)&mp_builtin_hash_obj;
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_int, true)->value = (mp_obj_t)&int_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("int"), true)->value = (mp_obj_t)&mp_builtin_int_obj;
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_list, true)->value = (mp_obj_t)&list_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("iter"), true)->value = (mp_obj_t)&mp_builtin_iter_obj;
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_set, true)->value = (mp_obj_t)&set_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("len"), true)->value = rt_make_function_1(mp_builtin_len);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_tuple, true)->value = (mp_obj_t)&tuple_type;
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("list"), true)->value = rt_make_function_var(0, mp_builtin_list);
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_type, true)->value = (mp_obj_t)&mp_builtin_type_obj; // TODO
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("max"), true)->value = rt_make_function_var(1, mp_builtin_max);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("min"), true)->value = rt_make_function_var(1, mp_builtin_min);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("next"), true)->value = (mp_obj_t)&mp_builtin_next_obj;
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("ord"), true)->value = rt_make_function_1(mp_builtin_ord);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("pow"), true)->value = rt_make_function_var(2, mp_builtin_pow);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("print"), true)->value = rt_make_function_var(0, mp_builtin_print);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("range"), true)->value = rt_make_function_var(1, mp_builtin_range);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("set"), true)->value = (mp_obj_t)&mp_builtin_set_obj;
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("sum"), true)->value = rt_make_function_var(1, mp_builtin_sum);
|
|
||||||
mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("type"), true)->value = (mp_obj_t)&mp_builtin_type_obj;
|
|
||||||
|
|
||||||
|
// built-in user functions; TODO covert all to &mp_builtin_xxx's
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_abs, true)->value = rt_make_function_1(mp_builtin_abs);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_all, true)->value = rt_make_function_1(mp_builtin_all);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_any, true)->value = rt_make_function_1(mp_builtin_any);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_callable, true)->value = rt_make_function_1(mp_builtin_callable);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_chr, true)->value = rt_make_function_1(mp_builtin_chr);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_divmod, true)->value = rt_make_function_2(mp_builtin_divmod);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_hash, true)->value = (mp_obj_t)&mp_builtin_hash_obj;
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_iter, true)->value = (mp_obj_t)&mp_builtin_iter_obj;
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_len, true)->value = rt_make_function_1(mp_builtin_len);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_max, true)->value = rt_make_function_var(1, mp_builtin_max);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_min, true)->value = rt_make_function_var(1, mp_builtin_min);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_next, true)->value = (mp_obj_t)&mp_builtin_next_obj;
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_ord, true)->value = rt_make_function_1(mp_builtin_ord);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_pow, true)->value = rt_make_function_var(2, mp_builtin_pow);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_print, true)->value = rt_make_function_var(0, mp_builtin_print);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_range, true)->value = rt_make_function_var(1, mp_builtin_range);
|
||||||
|
mp_qstr_map_lookup(&map_builtins, MP_QSTR_sum, true)->value = rt_make_function_var(1, mp_builtin_sum);
|
||||||
|
|
||||||
next_unique_code_id = 2; // 1 is reserved for the __main__ module scope
|
next_unique_code_id = 1; // 0 indicates "no code"
|
||||||
unique_codes = NULL;
|
unique_codes = NULL;
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
#ifdef WRITE_CODE
|
||||||
@ -166,13 +141,9 @@ void rt_deinit(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rt_get_unique_code_id(bool is_main_module) {
|
int rt_get_unique_code_id(void) {
|
||||||
if (is_main_module) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return next_unique_code_id++;
|
return next_unique_code_id++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void alloc_unique_codes(void) {
|
static void alloc_unique_codes(void) {
|
||||||
if (unique_codes == NULL) {
|
if (unique_codes == NULL) {
|
||||||
@ -186,7 +157,7 @@ static void alloc_unique_codes(void) {
|
|||||||
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator) {
|
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator) {
|
||||||
alloc_unique_codes();
|
alloc_unique_codes();
|
||||||
|
|
||||||
assert(unique_code_id < next_unique_code_id);
|
assert(1 <= unique_code_id && unique_code_id < next_unique_code_id);
|
||||||
unique_codes[unique_code_id].kind = MP_CODE_BYTE;
|
unique_codes[unique_code_id].kind = MP_CODE_BYTE;
|
||||||
unique_codes[unique_code_id].n_args = n_args;
|
unique_codes[unique_code_id].n_args = n_args;
|
||||||
unique_codes[unique_code_id].n_locals = n_locals;
|
unique_codes[unique_code_id].n_locals = n_locals;
|
||||||
@ -355,7 +326,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*s != 0) {
|
if (*s != 0) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_SyntaxError, "invalid syntax for number"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_SyntaxError, "invalid syntax for number"));
|
||||||
}
|
}
|
||||||
if (exp_neg) {
|
if (exp_neg) {
|
||||||
exp_val = -exp_val;
|
exp_val = -exp_val;
|
||||||
@ -373,7 +344,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) {
|
|||||||
return mp_obj_new_float(dec_val);
|
return mp_obj_new_float(dec_val);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_SyntaxError, "decimal numbers not supported"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_SyntaxError, "decimal numbers not supported"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +362,7 @@ mp_obj_t rt_load_name(qstr qstr) {
|
|||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
elem = mp_qstr_map_lookup(&map_builtins, qstr, false);
|
elem = mp_qstr_map_lookup(&map_builtins, qstr, false);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,7 +376,7 @@ mp_obj_t rt_load_global(qstr qstr) {
|
|||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
elem = mp_qstr_map_lookup(&map_builtins, qstr, false);
|
elem = mp_qstr_map_lookup(&map_builtins, qstr, false);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return elem->value;
|
return elem->value;
|
||||||
@ -413,9 +384,9 @@ mp_obj_t rt_load_global(qstr qstr) {
|
|||||||
|
|
||||||
mp_obj_t rt_load_build_class(void) {
|
mp_obj_t rt_load_build_class(void) {
|
||||||
DEBUG_OP_printf("load_build_class\n");
|
DEBUG_OP_printf("load_build_class\n");
|
||||||
mp_map_elem_t *elem = mp_qstr_map_lookup(&map_builtins, rt_q___build_class__, false);
|
mp_map_elem_t *elem = mp_qstr_map_lookup(&map_builtins, MP_QSTR___build_class__, false);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_NameError, "name '__build_class__' is not defined"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_NameError, "name '__build_class__' is not defined"));
|
||||||
}
|
}
|
||||||
return elem->value;
|
return elem->value;
|
||||||
}
|
}
|
||||||
@ -465,7 +436,7 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO specify in error message what the operator is
|
// TODO specify in error message what the operator is
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "bad operand type for unary operator: '%s'", o->type->name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "bad operand type for unary operator: '%s'", o->type->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +515,7 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO specify in error message what the operator is
|
// TODO specify in error message what the operator is
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "unsupported operand type for binary operator: '%s'", mp_obj_get_type_str(lhs)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "unsupported operand type for binary operator: '%s'", mp_obj_get_type_str(lhs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||||
@ -693,13 +664,13 @@ mp_obj_t rt_call_function_n(mp_obj_t fun_in, int n_args, const mp_obj_t *args) {
|
|||||||
DEBUG_OP_printf("calling function %p(n_args=%d, args=%p)\n", fun_in, n_args, args);
|
DEBUG_OP_printf("calling function %p(n_args=%d, args=%p)\n", fun_in, n_args, args);
|
||||||
|
|
||||||
if (MP_OBJ_IS_SMALL_INT(fun_in)) {
|
if (MP_OBJ_IS_SMALL_INT(fun_in)) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "'int' object is not callable"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "'int' object is not callable"));
|
||||||
} else {
|
} else {
|
||||||
mp_obj_base_t *fun = fun_in;
|
mp_obj_base_t *fun = fun_in;
|
||||||
if (fun->type->call_n != NULL) {
|
if (fun->type->call_n != NULL) {
|
||||||
return fun->type->call_n(fun_in, n_args, args);
|
return fun->type->call_n(fun_in, n_args, args);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not callable", fun->type->name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "'%s' object is not callable", fun->type->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -756,14 +727,14 @@ void rt_unpack_sequence(mp_obj_t seq_in, uint num, mp_obj_t *items) {
|
|||||||
mp_obj_list_get(seq_in, &seq_len, &seq_items);
|
mp_obj_list_get(seq_in, &seq_len, &seq_items);
|
||||||
}
|
}
|
||||||
if (seq_len < num) {
|
if (seq_len < num) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "need more than %d values to unpack", (void*)(machine_uint_t)seq_len));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "need more than %d values to unpack", (void*)(machine_uint_t)seq_len));
|
||||||
} else if (seq_len > num) {
|
} else if (seq_len > num) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "too many values to unpack (expected %d)", (void*)(machine_uint_t)num));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "too many values to unpack (expected %d)", (void*)(machine_uint_t)num));
|
||||||
}
|
}
|
||||||
memcpy(items, seq_items, num * sizeof(mp_obj_t));
|
memcpy(items, seq_items, num * sizeof(mp_obj_t));
|
||||||
} else {
|
} else {
|
||||||
// TODO call rt_getiter and extract via rt_iternext
|
// TODO call rt_getiter and extract via rt_iternext
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(seq_in)));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(seq_in)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,12 +778,12 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
no_attr:
|
no_attr:
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
|
void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
|
||||||
DEBUG_OP_printf("load method %s\n", qstr_str(attr));
|
DEBUG_OP_printf("load method %s\n", qstr_str(attr));
|
||||||
if (MP_OBJ_IS_TYPE(base, &gen_instance_type) && attr == rt_q___next__) {
|
if (MP_OBJ_IS_TYPE(base, &gen_instance_type) && attr == MP_QSTR___next__) {
|
||||||
dest[1] = (mp_obj_t)&mp_builtin_next_obj;
|
dest[1] = (mp_obj_t)&mp_builtin_next_obj;
|
||||||
dest[0] = base;
|
dest[0] = base;
|
||||||
return;
|
return;
|
||||||
@ -850,7 +821,7 @@ void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
|
|||||||
mp_map_t *globals = mp_obj_module_get_globals(base);
|
mp_map_t *globals = mp_obj_module_get_globals(base);
|
||||||
mp_qstr_map_lookup(globals, attr, true)->value = value;
|
mp_qstr_map_lookup(globals, attr, true)->value = value;
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,26 +840,26 @@ void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
|
|||||||
|
|
||||||
mp_obj_t rt_getiter(mp_obj_t o_in) {
|
mp_obj_t rt_getiter(mp_obj_t o_in) {
|
||||||
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "'int' object is not iterable"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "'int' object is not iterable"));
|
||||||
} else {
|
} else {
|
||||||
mp_obj_base_t *o = o_in;
|
mp_obj_base_t *o = o_in;
|
||||||
if (o->type->getiter != NULL) {
|
if (o->type->getiter != NULL) {
|
||||||
return o->type->getiter(o_in);
|
return o->type->getiter(o_in);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not iterable", o->type->name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "'%s' object is not iterable", o->type->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t rt_iternext(mp_obj_t o_in) {
|
mp_obj_t rt_iternext(mp_obj_t o_in) {
|
||||||
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "? 'int' object is not iterable"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "? 'int' object is not iterable"));
|
||||||
} else {
|
} else {
|
||||||
mp_obj_base_t *o = o_in;
|
mp_obj_base_t *o = o_in;
|
||||||
if (o->type->iternext != NULL) {
|
if (o->type->iternext != NULL) {
|
||||||
return o->type->iternext(o_in);
|
return o->type->iternext(o_in);
|
||||||
} else {
|
} else {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "? '%s' object is not iterable", o->type->name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "? '%s' object is not iterable", o->type->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
py/runtime.h
15
py/runtime.h
@ -1,18 +1,3 @@
|
|||||||
extern qstr rt_q_append;
|
|
||||||
extern qstr rt_q_pop;
|
|
||||||
extern qstr rt_q_sort;
|
|
||||||
extern qstr rt_q_join;
|
|
||||||
extern qstr rt_q_format;
|
|
||||||
extern qstr rt_q___build_class__;
|
|
||||||
extern qstr rt_q___next__;
|
|
||||||
extern qstr rt_q_AttributeError;
|
|
||||||
extern qstr rt_q_IndexError;
|
|
||||||
extern qstr rt_q_KeyError;
|
|
||||||
extern qstr rt_q_NameError;
|
|
||||||
extern qstr rt_q_TypeError;
|
|
||||||
extern qstr rt_q_SyntaxError;
|
|
||||||
extern qstr rt_q_ValueError;
|
|
||||||
|
|
||||||
int rt_is_true(mp_obj_t arg);
|
int rt_is_true(mp_obj_t arg);
|
||||||
|
|
||||||
mp_obj_t rt_load_const_dec(qstr qstr);
|
mp_obj_t rt_load_const_dec(qstr qstr);
|
||||||
|
@ -81,7 +81,7 @@ extern void *const rt_fun_table[RT_F_NUMBER_OF];
|
|||||||
|
|
||||||
void rt_init(void);
|
void rt_init(void);
|
||||||
void rt_deinit(void);
|
void rt_deinit(void);
|
||||||
int rt_get_unique_code_id(bool is_main_module);
|
int rt_get_unique_code_id(void);
|
||||||
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator);
|
void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_stack, bool is_generator);
|
||||||
void rt_assign_native_code(int unique_code_id, void *f, uint len, int n_args);
|
void rt_assign_native_code(int unique_code_id, void *f, uint len, int n_args);
|
||||||
void rt_assign_inline_asm_code(int unique_code_id, void *f, uint len, int n_args);
|
void rt_assign_inline_asm_code(int unique_code_id, void *f, uint len, int n_args);
|
||||||
|
@ -46,6 +46,10 @@ void mp_show_byte_code(const byte *ip, int len) {
|
|||||||
printf("LOAD_CONST_TRUE");
|
printf("LOAD_CONST_TRUE");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MP_BC_LOAD_CONST_ELLIPSIS:
|
||||||
|
printf("LOAD_CONST_ELLIPSIS");
|
||||||
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_SMALL_INT:
|
case MP_BC_LOAD_CONST_SMALL_INT:
|
||||||
unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000;
|
unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000;
|
||||||
ip += 3;
|
ip += 3;
|
||||||
|
18
py/vm.c
18
py/vm.c
@ -99,6 +99,10 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
|
|||||||
PUSH(mp_const_true);
|
PUSH(mp_const_true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MP_BC_LOAD_CONST_ELLIPSIS:
|
||||||
|
PUSH(mp_const_ellipsis);
|
||||||
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_SMALL_INT:
|
case MP_BC_LOAD_CONST_SMALL_INT:
|
||||||
unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000;
|
unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000;
|
||||||
ip += 3;
|
ip += 3;
|
||||||
@ -410,6 +414,20 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
|
|||||||
sp++;
|
sp++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if MICROPY_ENABLE_SLICE
|
||||||
|
case MP_BC_BUILD_SLICE:
|
||||||
|
DECODE_UINT;
|
||||||
|
if (unum == 2) {
|
||||||
|
obj2 = POP();
|
||||||
|
obj1 = TOP();
|
||||||
|
SET_TOP(mp_obj_new_slice(obj1, obj2, NULL));
|
||||||
|
} else {
|
||||||
|
printf("3-argument slice is not supported\n");
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case MP_BC_UNPACK_SEQUENCE:
|
case MP_BC_UNPACK_SEQUENCE:
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
rt_unpack_sequence(sp[0], unum, sp - unum + 1);
|
rt_unpack_sequence(sp[0], unum, sp - unum + 1);
|
||||||
|
@ -73,11 +73,13 @@ PY_O = \
|
|||||||
objfun.o \
|
objfun.o \
|
||||||
objgenerator.o \
|
objgenerator.o \
|
||||||
objinstance.o \
|
objinstance.o \
|
||||||
|
objint.o \
|
||||||
objlist.o \
|
objlist.o \
|
||||||
objmodule.o \
|
objmodule.o \
|
||||||
objnone.o \
|
objnone.o \
|
||||||
objrange.o \
|
objrange.o \
|
||||||
objset.o \
|
objset.o \
|
||||||
|
objslice.o \
|
||||||
objstr.o \
|
objstr.o \
|
||||||
objtuple.o \
|
objtuple.o \
|
||||||
objtype.o \
|
objtype.o \
|
||||||
@ -161,7 +163,7 @@ $(BUILD)/flash.elf: $(OBJ)
|
|||||||
arm-none-eabi-size $@
|
arm-none-eabi-size $@
|
||||||
|
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
mkdir $@
|
mkdir -p $@
|
||||||
|
|
||||||
$(BUILD)/%.o: %.s
|
$(BUILD)/%.o: %.s
|
||||||
$(AS) -o $@ $<
|
$(AS) -o $@ $<
|
||||||
|
@ -330,6 +330,7 @@ static const mp_obj_type_t i2c_obj_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"I2C",
|
"I2C",
|
||||||
i2c_obj_print, // print
|
i2c_obj_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -108,6 +108,7 @@ static const mp_obj_type_t led_obj_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"Led",
|
"Led",
|
||||||
led_obj_print, // print
|
led_obj_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
|
#include "mpqstr.h"
|
||||||
#include "nlr.h"
|
#include "nlr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
@ -621,7 +622,7 @@ mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pin_error:
|
pin_error:
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "pin %s does not exist", pin_name));
|
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
|
||||||
@ -745,6 +746,7 @@ static const mp_obj_type_t file_obj_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"File",
|
"File",
|
||||||
file_obj_print, // print
|
file_obj_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -141,6 +141,7 @@ static const mp_obj_type_t servo_obj_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"Servo",
|
"Servo",
|
||||||
servo_obj_print, // print
|
servo_obj_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
|
@ -49,6 +49,18 @@ static uint8_t *cache_get_addr_for_write(uint32_t flash_addr) {
|
|||||||
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t *cache_get_addr_for_read(uint32_t flash_addr) {
|
||||||
|
uint32_t flash_sector_start;
|
||||||
|
uint32_t flash_sector_size;
|
||||||
|
uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
|
||||||
|
if (cache_flash_sector_id == flash_sector_id) {
|
||||||
|
// in cache, copy from there
|
||||||
|
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
||||||
|
}
|
||||||
|
// not in cache, copy straight from flash
|
||||||
|
return (uint8_t*)flash_addr;
|
||||||
|
}
|
||||||
|
|
||||||
void storage_init(void) {
|
void storage_init(void) {
|
||||||
if (!is_initialised) {
|
if (!is_initialised) {
|
||||||
cache_flash_sector_id = 0;
|
cache_flash_sector_id = 0;
|
||||||
@ -131,8 +143,9 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
||||||
// non-MBR block, just copy straight from flash
|
// non-MBR block, get data from flash memory, possibly via cache
|
||||||
uint8_t *src = (uint8_t*)FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
||||||
|
uint8_t *src = cache_get_addr_for_read(flash_addr);
|
||||||
memcpy(dest, src, BLOCK_SIZE);
|
memcpy(dest, src, BLOCK_SIZE);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
RM="/bin/rm -f"
|
RM="/bin/rm -f"
|
||||||
CPYTHON3=python3
|
CPYTHON3=python3.3
|
||||||
MP_PY=../../unix/py
|
MP_PY=../../unix/py
|
||||||
|
|
||||||
numtests=0
|
numtests=0
|
||||||
|
32
tests/basics/tests/string-slice.py
Normal file
32
tests/basics/tests/string-slice.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
print("123"[0:1])
|
||||||
|
|
||||||
|
print("123"[0:2])
|
||||||
|
|
||||||
|
print("123"[:1])
|
||||||
|
|
||||||
|
print("123"[1:])
|
||||||
|
|
||||||
|
# Idiom for copying sequence
|
||||||
|
print("123"[:])
|
||||||
|
|
||||||
|
print("123"[:-1])
|
||||||
|
|
||||||
|
# Weird cases
|
||||||
|
print("123"[0:0])
|
||||||
|
print("123"[1:0])
|
||||||
|
print("123"[1:1])
|
||||||
|
print("123"[-1:-1])
|
||||||
|
print("123"[-3:])
|
||||||
|
print("123"[-3:3])
|
||||||
|
print("123"[0:])
|
||||||
|
print("123"[:0])
|
||||||
|
print("123"[:-3])
|
||||||
|
print("123"[:-4])
|
||||||
|
# Range check testing, don't segfault, please ;-)
|
||||||
|
print("123"[:1000000])
|
||||||
|
print("123"[1000000:])
|
||||||
|
print("123"[:-1000000])
|
||||||
|
print("123"[-1000000:])
|
||||||
|
# No IndexError!
|
||||||
|
print(""[1:1])
|
||||||
|
print(""[-1:-1])
|
@ -38,11 +38,13 @@ PY_O = \
|
|||||||
objfun.o \
|
objfun.o \
|
||||||
objgenerator.o \
|
objgenerator.o \
|
||||||
objinstance.o \
|
objinstance.o \
|
||||||
|
objint.o \
|
||||||
objlist.o \
|
objlist.o \
|
||||||
objmodule.o \
|
objmodule.o \
|
||||||
objnone.o \
|
objnone.o \
|
||||||
objrange.o \
|
objrange.o \
|
||||||
objset.o \
|
objset.o \
|
||||||
|
objslice.o \
|
||||||
objstr.o \
|
objstr.o \
|
||||||
objtuple.o \
|
objtuple.o \
|
||||||
objtype.o \
|
objtype.o \
|
||||||
|
@ -11,15 +11,11 @@
|
|||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
typedef long machine_int_t; // must be pointer size
|
typedef long machine_int_t; // must be pointer size
|
||||||
typedef unsigned long machine_uint_t; // must be pointer size
|
typedef unsigned long machine_uint_t; // must be pointer size
|
||||||
#define UINT_FMT "%lu"
|
|
||||||
#define INT_FMT "%ld"
|
|
||||||
#else
|
#else
|
||||||
// These are definitions for machines where sizeof(int) == sizeof(void*),
|
// These are definitions for machines where sizeof(int) == sizeof(void*),
|
||||||
// regardless for actual size.
|
// regardless for actual size.
|
||||||
typedef int machine_int_t; // must be pointer size
|
typedef int machine_int_t; // must be pointer size
|
||||||
typedef unsigned int machine_uint_t; // must be pointer size
|
typedef unsigned int machine_uint_t; // must be pointer size
|
||||||
#define UINT_FMT "%u"
|
|
||||||
#define INT_FMT "%d"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BYTES_PER_WORD sizeof(machine_int_t)
|
#define BYTES_PER_WORD sizeof(machine_int_t)
|
||||||
|
@ -2,7 +2,7 @@ PYSRC=../py
|
|||||||
BUILD=build
|
BUILD=build
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -I. -I$(PYSRC) -Wall -Werror -ansi -std=gnu99 -Os -DUSE_READLINE #-DNDEBUG
|
CFLAGS = -I. -I$(PYSRC) -Wall -Werror -ansi -std=gnu99 -Os #-DNDEBUG
|
||||||
LDFLAGS = -lm
|
LDFLAGS = -lm
|
||||||
|
|
||||||
SRC_C = \
|
SRC_C = \
|
||||||
@ -45,11 +45,13 @@ PY_O = \
|
|||||||
objfun.o \
|
objfun.o \
|
||||||
objgenerator.o \
|
objgenerator.o \
|
||||||
objinstance.o \
|
objinstance.o \
|
||||||
|
objint.o \
|
||||||
objlist.o \
|
objlist.o \
|
||||||
objmodule.o \
|
objmodule.o \
|
||||||
objnone.o \
|
objnone.o \
|
||||||
objrange.o \
|
objrange.o \
|
||||||
objset.o \
|
objset.o \
|
||||||
|
objslice.o \
|
||||||
objstr.o \
|
objstr.o \
|
||||||
objtuple.o \
|
objtuple.o \
|
||||||
objtype.o \
|
objtype.o \
|
||||||
@ -82,10 +84,10 @@ $(BUILD)/%.o: $(PYSRC)/%.S
|
|||||||
$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
|
$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
|
$(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h mpconfigport.h
|
||||||
$(CC) $(CFLAGS) -DN_X64 -c -o $@ $<
|
$(CC) $(CFLAGS) -DN_X64 -c -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
|
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h mpconfigport.h
|
||||||
$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
|
$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
|
||||||
|
|
||||||
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
|
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
|
||||||
|
12
unix/main.c
12
unix/main.c
@ -15,7 +15,7 @@
|
|||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "repl.h"
|
#include "repl.h"
|
||||||
|
|
||||||
#ifdef USE_READLINE
|
#if MICROPY_USE_READLINE
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
@ -35,7 +35,7 @@ static char *str_join(const char *s1, int sep_char, const char *s2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *prompt(char *p) {
|
static char *prompt(char *p) {
|
||||||
#ifdef USE_READLINE
|
#if MICROPY_USE_READLINE
|
||||||
char *line = readline(p);
|
char *line = readline(p);
|
||||||
if (line) {
|
if (line) {
|
||||||
add_history(line);
|
add_history(line);
|
||||||
@ -192,6 +192,7 @@ static const mp_obj_type_t test_type = {
|
|||||||
{ &mp_const_type },
|
{ &mp_const_type },
|
||||||
"Test",
|
"Test",
|
||||||
test_print, // print
|
test_print, // print
|
||||||
|
NULL, // make_new
|
||||||
NULL, // call_n
|
NULL, // call_n
|
||||||
NULL, // unary_op
|
NULL, // unary_op
|
||||||
NULL, // binary_op
|
NULL, // binary_op
|
||||||
@ -217,6 +218,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
rt_store_name(qstr_from_str_static("test"), test_obj_new(42));
|
rt_store_name(qstr_from_str_static("test"), test_obj_new(42));
|
||||||
|
|
||||||
|
/*
|
||||||
|
printf("bytes:\n");
|
||||||
|
printf(" total %d\n", m_get_total_bytes_allocated());
|
||||||
|
printf(" cur %d\n", m_get_current_bytes_allocated());
|
||||||
|
printf(" peak %d\n", m_get_peak_bytes_allocated());
|
||||||
|
*/
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
do_repl();
|
do_repl();
|
||||||
} else if (argc == 2) {
|
} else if (argc == 2) {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
// options to control how Micro Python is built
|
// options to control how Micro Python is built
|
||||||
|
|
||||||
|
// Linking with GNU readline causes binary to be licensed under GPL
|
||||||
|
#ifndef MICROPY_USE_READLINE
|
||||||
|
#define MICROPY_USE_READLINE (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MICROPY_ENABLE_FLOAT (1)
|
#define MICROPY_ENABLE_FLOAT (1)
|
||||||
#define MICROPY_EMIT_CPYTHON (0)
|
#define MICROPY_EMIT_CPYTHON (0)
|
||||||
#define MICROPY_EMIT_X64 (1)
|
#define MICROPY_EMIT_X64 (1)
|
||||||
@ -11,15 +16,11 @@
|
|||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
typedef long machine_int_t; // must be pointer size
|
typedef long machine_int_t; // must be pointer size
|
||||||
typedef unsigned long machine_uint_t; // must be pointer size
|
typedef unsigned long machine_uint_t; // must be pointer size
|
||||||
#define UINT_FMT "%lu"
|
|
||||||
#define INT_FMT "%ld"
|
|
||||||
#else
|
#else
|
||||||
// These are definitions for machines where sizeof(int) == sizeof(void*),
|
// These are definitions for machines where sizeof(int) == sizeof(void*),
|
||||||
// regardless for actual size.
|
// regardless for actual size.
|
||||||
typedef int machine_int_t; // must be pointer size
|
typedef int machine_int_t; // must be pointer size
|
||||||
typedef unsigned int machine_uint_t; // must be pointer size
|
typedef unsigned int machine_uint_t; // must be pointer size
|
||||||
#define UINT_FMT "%u"
|
|
||||||
#define INT_FMT "%d"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BYTES_PER_WORD sizeof(machine_int_t)
|
#define BYTES_PER_WORD sizeof(machine_int_t)
|
||||||
|
Loading…
Reference in New Issue
Block a user