From 6ee1e383d6b95d0bb5f2902ec91b8d831e4b5803 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 03:47:34 +0200 Subject: [PATCH 01/25] str slice: Trim slice indexes to be in range. --- py/objstr.c | 11 +++++++++++ tests/basics/tests/slice-bstr1.py | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/py/objstr.c b/py/objstr.c index 59547e3cd6..54e6f37705 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -41,9 +41,20 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { 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 diff --git a/tests/basics/tests/slice-bstr1.py b/tests/basics/tests/slice-bstr1.py index 0bed959141..74dbc20617 100644 --- a/tests/basics/tests/slice-bstr1.py +++ b/tests/basics/tests/slice-bstr1.py @@ -22,6 +22,11 @@ print(b"123"[0:]) print(b"123"[:0]) print(b"123"[:-3]) print(b"123"[:-4]) +# Range check testing, don't segfault, please ;-) +print(b"123"[:1000000]) +print(b"123"[1000000:]) +print(b"123"[:-1000000]) +print(b"123"[-1000000:]) # No IndexError! print(b""[1:1]) print(b""[-1:-1]) From 2c62e262b2c84b077355d67c6302bd02f6a28552 Mon Sep 17 00:00:00 2001 From: stevie67 Date: Sat, 4 Jan 2014 03:02:32 +0100 Subject: [PATCH 02/25] Fix issue #62: Cache loses data Use the storage cache not only for writing but also for reading. This avoids reading stale data and thus data loss. --- stm/storage.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stm/storage.c b/stm/storage.c index 6878de22e6..7342a53ac3 100644 --- a/stm/storage.c +++ b/stm/storage.c @@ -49,6 +49,16 @@ static uint8_t *cache_get_addr_for_write(uint32_t flash_addr) { 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) + 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) { if (!is_initialised) { cache_flash_sector_id = 0; @@ -131,8 +141,8 @@ bool storage_read_block(uint8_t *dest, uint32_t block) { return true; } else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { - // non-MBR block, just copy straight from flash - 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); return true; From 2a5e6538b941d1fc9c1c0ef0bb0827b5ed2425d2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 12:34:36 +0000 Subject: [PATCH 03/25] stm: Add comments for storage read from cache. --- stm/storage.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stm/storage.c b/stm/storage.c index 7342a53ac3..daee4adb5e 100644 --- a/stm/storage.c +++ b/stm/storage.c @@ -53,8 +53,10 @@ 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) + 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; } @@ -141,6 +143,7 @@ bool storage_read_block(uint8_t *dest, uint32_t block) { return true; } else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { + // non-MBR block, get data from flash memory, possibly via cache 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); From 9b8f424944a6144a1528e5d21dd474e6d833d1a1 Mon Sep 17 00:00:00 2001 From: Jonathan Greig Date: Sat, 4 Jan 2014 06:53:06 -0600 Subject: [PATCH 04/25] Added SVG vector text. --- logo/vector-text.svg | 137 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 logo/vector-text.svg diff --git a/logo/vector-text.svg b/logo/vector-text.svg new file mode 100644 index 0000000000..fa8f9ba332 --- /dev/null +++ b/logo/vector-text.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + From 116e6e0551dee938b4378c89e044a5eea38c009b Mon Sep 17 00:00:00 2001 From: Jonathan Greig Date: Sat, 4 Jan 2014 06:54:54 -0600 Subject: [PATCH 05/25] Added DXF R2000 vector text. --- logo/vector-text-R2000.dxf | 9888 ++++++++++++++++++++++++++++++++++++ 1 file changed, 9888 insertions(+) create mode 100644 logo/vector-text-R2000.dxf diff --git a/logo/vector-text-R2000.dxf b/logo/vector-text-R2000.dxf new file mode 100644 index 0000000000..a963203b3f --- /dev/null +++ b/logo/vector-text-R2000.dxf @@ -0,0 +1,9888 @@ + 0 +SECTION + 2 +HEADER + 9 +$ACADVER + 1 +AC1015 + 9 +$ACADMAINTVER + 70 + 6 + 9 +$DWGCODEPAGE + 3 +ANSI_1252 + 9 +$INSBASE + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$EXTMIN + 10 +0.0000000000000001 + 20 +0.0 + 30 +0.0 + 9 +$EXTMAX + 10 +3.692708053216686 + 20 +0.6839852852251591 + 30 +0.0 + 9 +$LIMMIN + 10 +0.0 + 20 +0.0 + 9 +$LIMMAX + 10 +12.0 + 20 +9.0 + 9 +$ORTHOMODE + 70 + 0 + 9 +$REGENMODE + 70 + 1 + 9 +$FILLMODE + 70 + 1 + 9 +$QTEXTMODE + 70 + 0 + 9 +$MIRRTEXT + 70 + 1 + 9 +$LTSCALE + 40 +1.0 + 9 +$ATTMODE + 70 + 1 + 9 +$TEXTSIZE + 40 +0.2 + 9 +$TRACEWID + 40 +0.05 + 9 +$TEXTSTYLE + 7 +Standard + 9 +$CLAYER + 8 +TEXT-RED + 9 +$CELTYPE + 6 +ByLayer + 9 +$CECOLOR + 62 + 256 + 9 +$CELTSCALE + 40 +1.0 + 9 +$DISPSILH + 70 + 0 + 9 +$DIMSCALE + 40 +1.0 + 9 +$DIMASZ + 40 +0.18 + 9 +$DIMEXO + 40 +0.0625 + 9 +$DIMDLI + 40 +0.38 + 9 +$DIMRND + 40 +0.0 + 9 +$DIMDLE + 40 +0.0 + 9 +$DIMEXE + 40 +0.18 + 9 +$DIMTP + 40 +0.0 + 9 +$DIMTM + 40 +0.0 + 9 +$DIMTXT + 40 +0.18 + 9 +$DIMCEN + 40 +0.09 + 9 +$DIMTSZ + 40 +0.0 + 9 +$DIMTOL + 70 + 0 + 9 +$DIMLIM + 70 + 0 + 9 +$DIMTIH + 70 + 1 + 9 +$DIMTOH + 70 + 1 + 9 +$DIMSE1 + 70 + 0 + 9 +$DIMSE2 + 70 + 0 + 9 +$DIMTAD + 70 + 0 + 9 +$DIMZIN + 70 + 0 + 9 +$DIMBLK + 1 + + 9 +$DIMASO + 70 + 1 + 9 +$DIMSHO + 70 + 1 + 9 +$DIMPOST + 1 + + 9 +$DIMAPOST + 1 + + 9 +$DIMALT + 70 + 0 + 9 +$DIMALTD + 70 + 2 + 9 +$DIMALTF + 40 +25.4 + 9 +$DIMLFAC + 40 +1.0 + 9 +$DIMTOFL + 70 + 0 + 9 +$DIMTVP + 40 +0.0 + 9 +$DIMTIX + 70 + 0 + 9 +$DIMSOXD + 70 + 0 + 9 +$DIMSAH + 70 + 0 + 9 +$DIMBLK1 + 1 + + 9 +$DIMBLK2 + 1 + + 9 +$DIMSTYLE + 2 +Standard + 9 +$DIMCLRD + 70 + 0 + 9 +$DIMCLRE + 70 + 0 + 9 +$DIMCLRT + 70 + 0 + 9 +$DIMTFAC + 40 +1.0 + 9 +$DIMGAP + 40 +0.09 + 9 +$DIMJUST + 70 + 0 + 9 +$DIMSD1 + 70 + 0 + 9 +$DIMSD2 + 70 + 0 + 9 +$DIMTOLJ + 70 + 1 + 9 +$DIMTZIN + 70 + 0 + 9 +$DIMALTZ + 70 + 0 + 9 +$DIMALTTZ + 70 + 0 + 9 +$DIMUPT + 70 + 0 + 9 +$DIMDEC + 70 + 3 + 9 +$DIMTDEC + 70 + 3 + 9 +$DIMALTU + 70 + 2 + 9 +$DIMALTTD + 70 + 2 + 9 +$DIMTXSTY + 7 +Standard + 9 +$DIMAUNIT + 70 + 0 + 9 +$DIMADEC + 70 + 0 + 9 +$DIMALTRND + 40 +0.0 + 9 +$DIMAZIN + 70 + 0 + 9 +$DIMDSEP + 70 + 46 + 9 +$DIMATFIT + 70 + 3 + 9 +$DIMFRAC + 70 + 0 + 9 +$DIMLDRBLK + 1 + + 9 +$DIMLUNIT + 70 + 2 + 9 +$DIMLWD + 70 + -2 + 9 +$DIMLWE + 70 + -2 + 9 +$DIMTMOVE + 70 + 2 + 9 +$LUNITS + 70 + 2 + 9 +$LUPREC + 70 + 3 + 9 +$SKETCHINC + 40 +0.1 + 9 +$FILLETRAD + 40 +0.5 + 9 +$AUNITS + 70 + 0 + 9 +$AUPREC + 70 + 0 + 9 +$MENU + 1 +. + 9 +$ELEVATION + 40 +0.0 + 9 +$PELEVATION + 40 +0.0 + 9 +$THICKNESS + 40 +0.0 + 9 +$LIMCHECK + 70 + 0 + 9 +$CHAMFERA + 40 +0.0 + 9 +$CHAMFERB + 40 +0.0 + 9 +$CHAMFERC + 40 +0.0 + 9 +$CHAMFERD + 40 +0.0 + 9 +$SKPOLY + 70 + 0 + 9 +$TDCREATE + 40 +2456662.269745891 + 9 +$TDUCREATE + 40 +2456662.519745903 + 9 +$TDUPDATE + 40 +2456662.282164352 + 9 +$TDUUPDATE + 40 +2456662.532164352 + 9 +$TDINDWG + 40 +0.0000000116 + 9 +$TDUSRTIMER + 40 +2456662.519895833 + 9 +$USRTIMER + 70 + 1 + 9 +$ANGBASE + 50 +0.0 + 9 +$ANGDIR + 70 + 0 + 9 +$PDMODE + 70 + 0 + 9 +$PDSIZE + 40 +0.0 + 9 +$PLINEWID + 40 +0.0 + 9 +$SPLFRAME + 70 + 0 + 9 +$SPLINETYPE + 70 + 6 + 9 +$SPLINESEGS + 70 + 8 + 9 +$HANDSEED + 5 +1D7 + 9 +$SURFTAB1 + 70 + 6 + 9 +$SURFTAB2 + 70 + 6 + 9 +$SURFTYPE + 70 + 6 + 9 +$SURFU + 70 + 6 + 9 +$SURFV + 70 + 6 + 9 +$UCSBASE + 2 + + 9 +$UCSNAME + 2 + + 9 +$UCSORG + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSXDIR + 10 +1.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSYDIR + 10 +0.0 + 20 +1.0 + 30 +0.0 + 9 +$UCSORTHOREF + 2 + + 9 +$UCSORTHOVIEW + 70 + 0 + 9 +$UCSORGTOP + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSORGBOTTOM + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSORGLEFT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSORGRIGHT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSORGFRONT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$UCSORGBACK + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSBASE + 2 + + 9 +$PUCSNAME + 2 + + 9 +$PUCSORG + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSXDIR + 10 +1.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSYDIR + 10 +0.0 + 20 +1.0 + 30 +0.0 + 9 +$PUCSORTHOREF + 2 + + 9 +$PUCSORTHOVIEW + 70 + 0 + 9 +$PUCSORGTOP + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSORGBOTTOM + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSORGLEFT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSORGRIGHT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSORGFRONT + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PUCSORGBACK + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$USERI1 + 70 + 0 + 9 +$USERI2 + 70 + 0 + 9 +$USERI3 + 70 + 0 + 9 +$USERI4 + 70 + 0 + 9 +$USERI5 + 70 + 0 + 9 +$USERR1 + 40 +0.0 + 9 +$USERR2 + 40 +0.0 + 9 +$USERR3 + 40 +0.0 + 9 +$USERR4 + 40 +0.0 + 9 +$USERR5 + 40 +0.0 + 9 +$WORLDVIEW + 70 + 1 + 9 +$SHADEDGE + 70 + 3 + 9 +$SHADEDIF + 70 + 70 + 9 +$TILEMODE + 70 + 1 + 9 +$MAXACTVP + 70 + 64 + 9 +$PINSBASE + 10 +0.0 + 20 +0.0 + 30 +0.0 + 9 +$PLIMCHECK + 70 + 0 + 9 +$PEXTMIN + 10 +1.000000000000000E+20 + 20 +1.000000000000000E+20 + 30 +1.000000000000000E+20 + 9 +$PEXTMAX + 10 +-1.000000000000000E+20 + 20 +-1.000000000000000E+20 + 30 +-1.000000000000000E+20 + 9 +$PLIMMIN + 10 +0.0 + 20 +0.0 + 9 +$PLIMMAX + 10 +0.0 + 20 +0.0 + 9 +$UNITMODE + 70 + 0 + 9 +$VISRETAIN + 70 + 1 + 9 +$PLINEGEN + 70 + 0 + 9 +$PSLTSCALE + 70 + 1 + 9 +$TREEDEPTH + 70 + 3020 + 9 +$CMLSTYLE + 2 +Standard + 9 +$CMLJUST + 70 + 0 + 9 +$CMLSCALE + 40 +1.0 + 9 +$PROXYGRAPHICS + 70 + 1 + 9 +$MEASUREMENT + 70 + 0 + 9 +$CELWEIGHT +370 + -1 + 9 +$ENDCAPS +280 + 0 + 9 +$JOINSTYLE +280 + 0 + 9 +$LWDISPLAY +290 + 0 + 9 +$INSUNITS + 70 + 0 + 9 +$HYPERLINKBASE + 1 + + 9 +$STYLESHEET + 1 + + 9 +$XEDIT +290 + 1 + 9 +$CEPSNTYPE +380 + 0 + 9 +$PSTYLEMODE +290 + 1 + 9 +$FINGERPRINTGUID + 2 +{394BC0E0-D500-95D9-65ED-9BB4C8BE75F1} + 9 +$VERSIONGUID + 2 +{FAEB1C32-E019-11D5-929B-00C0DF256EC4} + 9 +$EXTNAMES +290 + 1 + 9 +$PSVPSCALE + 40 +0.0 + 9 +$OLESTARTUP +290 + 0 + 0 +ENDSEC + 0 +SECTION + 2 +CLASSES + 0 +CLASS + 1 +ACDBDICTIONARYWDFLT + 2 +AcDbDictionaryWithDefault + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +SCALE + 2 +AcDbScale + 3 +ObjectDBX Classes + 90 + 1153 +280 + 0 +281 + 0 + 0 +CLASS + 1 +VISUALSTYLE + 2 +AcDbVisualStyle + 3 +ObjectDBX Classes + 90 + 4095 +280 + 0 +281 + 0 + 0 +CLASS + 1 +MATERIAL + 2 +AcDbMaterial + 3 +ObjectDBX Classes + 90 + 1153 +280 + 0 +281 + 0 + 0 +CLASS + 1 +TABLESTYLE + 2 +AcDbTableStyle + 3 +ObjectDBX Classes + 90 + 4095 +280 + 0 +281 + 0 + 0 +CLASS + 1 +SUN + 2 +AcDbSun + 3 +SCENEOE + 90 + 1153 +280 + 0 +281 + 0 + 0 +CLASS + 1 +RASTERVARIABLES + 2 +AcDbRasterVariables + 3 +ISM + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +DICTIONARYVAR + 2 +AcDbDictionaryVar + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +ACDBPLACEHOLDER + 2 +AcDbPlaceHolder + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +LAYOUT + 2 +AcDbLayout + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +VPORT + 5 +8 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +VPORT + 5 +22 +330 +8 +100 +AcDbSymbolTableRecord +100 +AcDbViewportTableRecord + 2 +*ACTIVE + 70 + 0 + 10 +0.0 + 20 +0.0 + 11 +1.0 + 21 +1.0 + 12 +1.846354026608343 + 22 +0.3419926426125796 + 13 +0.0 + 23 +0.0 + 14 +10.0 + 24 +10.0 + 15 +10.0 + 25 +10.0 + 16 +0.0 + 26 +0.0 + 36 +1.0 + 17 +0.0 + 27 +0.0 + 37 +0.0 + 40 +1.733730323509535 + 41 +2.172519083969465 + 42 +50.0 + 43 +0.0 + 44 +0.0 + 50 +0.0 + 51 +0.0 + 71 + 16 + 72 + 100 + 73 + 1 + 74 + 1 + 75 + 0 + 76 + 0 + 77 + 0 + 78 + 0 +281 + 0 + 65 + 0 +110 +0.0 +120 +0.0 +130 +0.0 +111 +1.0 +121 +0.0 +131 +0.0 +112 +0.0 +122 +1.0 +132 +0.0 + 79 + 0 +146 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LTYPE + 5 +5 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +LTYPE + 5 +14 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +ByBlock + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +15 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +ByLayer + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +16 +330 +5 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CONTINUOUS + 70 + 0 + 3 +Solid line + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 5 +2 +102 +{ACAD_XDICTIONARY +360 +1B3 +102 +} +330 +0 +100 +AcDbSymbolTable + 70 + 3 + 0 +LAYER + 5 +10 +330 +2 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +0 + 70 + 0 + 62 + 7 + 6 +CONTINUOUS +370 + -3 +390 +F + 0 +LAYER + 5 +21 +330 +2 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +TEXT-GRAY + 70 + 0 + 62 + 254 + 6 +CONTINUOUS +370 + -3 +390 +F + 0 +LAYER + 5 +1B9 +330 +2 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +TEXT-RED + 70 + 0 + 62 + 1 + 6 +CONTINUOUS +370 + -3 +390 +F +1001 +AcAecLayerStandard +1000 + +1000 + + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 5 +3 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +STYLE + 5 +11 +330 +3 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +Standard + 70 + 0 + 40 +0.0 + 41 +1.0 + 50 +0.0 + 71 + 0 + 42 +0.2 + 3 +txt + 4 + + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 5 +6 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +UCS + 5 +7 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +APPID + 5 +9 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +APPID + 5 +12 +330 +9 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACAD + 70 + 0 + 0 +APPID + 5 +1BA +330 +9 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +AcAecLayerStandard + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +DIMSTYLE + 5 +A +330 +0 +100 +AcDbSymbolTable + 70 + 1 +100 +AcDbDimStyleTable + 0 +DIMSTYLE +105 +23 +330 +A +100 +AcDbSymbolTableRecord +100 +AcDbDimStyleTableRecord + 2 +Standard + 70 + 0 +178 + 0 +340 +11 + 0 +ENDTAB + 0 +TABLE + 2 +BLOCK_RECORD + 5 +1 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +BLOCK_RECORD + 5 +1D +330 +1 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*Model_Space +340 +1E + 0 +BLOCK_RECORD + 5 +1B +330 +1 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*Paper_Space +340 +1C + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +BLOCK + 5 +18D +330 +1D +100 +AcDbEntity + 8 +0 +100 +AcDbBlockBegin + 2 +*Model_Space + 70 + 0 + 10 +0.0 + 20 +0.0 + 30 +0.0 + 3 +*Model_Space + 1 +*Model_Space + 0 +ENDBLK + 5 +18E +330 +1D +100 +AcDbEntity + 8 +0 +100 +AcDbBlockEnd + 0 +BLOCK + 5 +18F +330 +1B +100 +AcDbEntity + 67 + 1 + 8 +0 +100 +AcDbBlockBegin + 2 +*Paper_Space + 70 + 0 + 10 +0.0 + 20 +0.0 + 30 +0.0 + 3 +*Paper_Space + 1 +*Paper_Space + 0 +ENDBLK + 5 +190 +330 +1B +100 +AcDbEntity + 67 + 1 + 8 +0 +100 +AcDbBlockEnd + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LWPOLYLINE + 5 +24 +102 +{ACAD_REACTORS +330 +1BD +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 14 + 70 + 1 + 43 +0.0 + 10 +0.0000000000000001 + 20 +0.1752767944487085 + 10 +0.0416193345059499 + 20 +0.6506897567371471 + 10 +0.1681431038010463 + 20 +0.6506897567371471 + 10 +0.247338516041492 + 20 +0.3260572124180542 + 10 +0.3260590389156172 + 20 +0.6506897567371471 + 10 +0.4521056357224397 + 20 +0.6506897567371471 + 10 +0.4963403625301471 + 20 +0.1752767944487085 + 10 +0.4066806413363264 + 20 +0.1752767944487085 + 10 +0.3752877144762009 + 20 +0.4930112663057366 + 10 +0.2987087599944248 + 20 +0.1752767944487085 + 10 +0.1973944622688229 + 20 +0.1752767944487085 + 10 +0.1174851938975943 + 20 +0.4930112663057366 + 10 +0.0896600256100814 + 20 +0.1752767944487085 + 10 +0.0000000000000001 + 20 +0.1752767944487085 + 0 +LWPOLYLINE + 5 +34 +102 +{ACAD_REACTORS +330 +1BE +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 5 + 70 + 1 + 43 +0.0 + 10 +0.5505660310062117 + 20 +0.1752767944487085 + 10 +0.5505660310062117 + 20 +0.5201225784624666 + 10 +0.6416519423802962 + 20 +0.5201225784624666 + 10 +0.6416519423802962 + 20 +0.1752767944487085 + 10 +0.5505660310062117 + 20 +0.1752767944487085 + 0 +LWPOLYLINE + 5 +3B +102 +{ACAD_REACTORS +330 +1BF +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 13 + 70 + 1 + 43 +0.0 + 10 +0.5474731617999196 + 20 +0.5714928224153991 + 10 +0.5474731617999196 + 20 +0.6288098380164536 + 42 +-0.1883074803638932 + 10 +0.5513377262264826 + 20 +0.6414735544516654 + 42 +-0.2159435161643535 + 10 +0.5629314195061711 + 20 +0.6456942859029685 + 10 +0.6311876334269211 + 20 +0.6456942859029685 + 42 +-0.2288445935800111 + 10 +0.6418909091447587 + 20 +0.6414735544516654 + 42 +-0.1763562374232752 + 10 +0.6454571456360689 + 20 +0.6288098380164536 + 10 +0.6454571456360689 + 20 +0.5714928224153991 + 42 +-0.1943541296589125 + 10 +0.6418909091447587 + 20 +0.5602568182417533 + 42 +-0.2096410684182619 + 10 +0.6311876334269211 + 20 +0.5565109761567706 + 10 +0.5629314195061711 + 20 +0.5565109761567706 + 42 +-0.1965331617699563 + 10 +0.551636054161735 + 20 +0.5604349017541234 + 42 +-0.2135460038275524 + 10 +0.5474731617999196 + 20 +0.5714928224153991 + 0 +LWPOLYLINE + 5 +4A +102 +{ACAD_REACTORS +330 +1C5 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 12 + 70 + 1 + 43 +0.0 + 10 +1.855753791898883 + 20 +0.5703040769182958 + 10 +1.749208100737245 + 20 +0.5703040769182958 + 10 +1.749208100737245 + 20 +0.4311767133994287 + 10 +1.855281946695168 + 20 +0.4311767133994287 + 42 +0.1378892503752188 + 10 +1.880487613061407 + 20 +0.4371219629662482 + 42 +0.1061516643405155 + 10 +1.890061504452931 + 20 +0.4460702789425233 + 42 +0.0752237691491799 + 10 +1.896895649500299 + 20 +0.460071904842465 + 42 +0.0778530288832081 + 10 +1.902359921375588 + 20 +0.5032381305759515 + 42 +0.0564276025149389 + 10 +1.899452746088178 + 20 +0.5325792918405643 + 42 +0.095076106856608 + 10 +1.890715999412924 + 20 +0.5535383513733607 + 42 +0.1319298941216669 + 10 +1.876149681349825 + 20 +0.5661122650117364 + 42 +0.1129501247093477 + 10 +1.855753791898883 + 20 +0.5703040769182958 + 0 +LWPOLYLINE + 5 +58 +102 +{ACAD_REACTORS +330 +1C7 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 23 + 70 + 1 + 43 +0.0 + 10 +2.401085080890193 + 20 +0.451391475175396 + 10 +2.401085080890193 + 20 +0.502049385078848 + 10 +2.456975906310984 + 20 +0.5208364345932495 + 10 +2.471953186325706 + 20 +0.6169178168015124 + 10 +2.547828939245814 + 20 +0.6169178168015124 + 10 +2.547828939245814 + 20 +0.5208364345932495 + 10 +2.625120227777072 + 20 +0.5208364345932495 + 10 +2.625120227777072 + 20 +0.451391475175396 + 10 +2.547828939245814 + 20 +0.451391475175396 + 10 +2.547828939245814 + 20 +0.312977967787312 + 42 +0.0356379455033458 + 10 +2.549609774369517 + 20 +0.2833386307955768 + 42 +0.0811642329835157 + 10 +2.554952279740622 + 20 +0.2643422951021078 + 42 +0.1858874482849488 + 10 +2.577068121063173 + 20 +0.244721753866562 + 42 +0.0076184446139192 + 10 +2.607448863857263 + 20 +0.2345547073915278 + 42 +0.0469611640188665 + 10 +2.620599646309214 + 20 +0.2311657933719365 + 10 +2.620599646309214 + 20 +0.1752767944487085 + 10 +2.541405756150071 + 20 +0.1752767944487085 + 42 +-0.1146121843643247 + 10 +2.504464842943029 + 20 +0.1829913113213321 + 42 +-0.132229815857891 + 10 +2.478071953160988 + 20 +0.2061345575229422 + 42 +-0.0940182241125145 + 10 +2.462242307616974 + 20 +0.2447068374697993 + 42 +-0.0555506677049525 + 10 +2.456975906310984 + 20 +0.2987081511619036 + 10 +2.456975906310984 + 20 +0.451391475175396 + 10 +2.401085080890193 + 20 +0.451391475175396 + 0 +LWPOLYLINE + 5 +71 +102 +{ACAD_REACTORS +330 +1CA +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 22 + 70 + 1 + 43 +0.0 + 10 +3.589495720107105 + 20 +0.5260693501105883 + 42 +-0.0932412511784359 + 10 +3.634655872346617 + 20 +0.5185183047698327 + 42 +-0.1254375778784052 + 10 +3.666908775142547 + 20 +0.4958651687475662 + 42 +-0.1084619648488494 + 10 +3.686254428494896 + 20 +0.4581099420437885 + 42 +-0.0689905889343237 + 10 +3.692708053216686 + 20 +0.4052541467398021 + 10 +3.692708053216686 + 20 +0.1752767944487085 + 10 +3.601870241094878 + 20 +0.1752767944487085 + 10 +3.601870241094878 + 20 +0.4064428922369056 + 42 +0.0660852200863579 + 10 +3.59946535263723 + 20 +0.4269407611351025 + 42 +0.1056585132217627 + 10 +3.592296349703354 + 20 +0.4415816611820138 + 42 +0.1272161701661909 + 10 +3.580317569854181 + 20 +0.4503655923776398 + 42 +0.0972102752618352 + 10 +3.56357467552878 + 20 +0.4532940768032824 + 42 +0.0885878555139059 + 10 +3.519221226379493 + 20 +0.4465162487641 + 42 +0.077710311269079 + 10 +3.480332049105495 + 20 +0.4233288622047228 + 10 +3.480332049105495 + 20 +0.1752767944487085 + 10 +3.389479016170664 + 20 +0.1752767944487085 + 10 +3.389479016170664 + 20 +0.5201225784624666 + 10 +3.462264944047086 + 20 +0.5201225784624666 + 10 +3.480332049105495 + 20 +0.4832608134831443 + 42 +-0.0353892151285229 + 10 +3.522843779878989 + 20 +0.5102534032982943 + 42 +-0.0728322192286089 + 10 +3.555720736008866 + 20 +0.5227390362211358 + 42 +-0.0544633437581111 + 10 +3.589495720107105 + 20 +0.5260693501105883 + 0 +LWPOLYLINE + 5 +89 +102 +{ACAD_REACTORS +330 +1C6 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 17 + 70 + 1 + 43 +0.0 + 10 +2.026516093204943 + 20 +0.5201225784624666 + 10 +2.12187448679461 + 20 +0.5201225784624666 + 10 +2.181814048479542 + 20 +0.2784929327615455 + 42 +0.1680883445175794 + 10 +2.192925241986399 + 20 +0.2601209548182838 + 42 +0.1691212946679427 + 10 +2.213442897941526 + 20 +0.2539970129065732 + 42 +0.0518086164809523 + 10 +2.216060877781497 + 20 +0.2532834611920508 + 10 +2.285026381589124 + 20 +0.5201225784624666 + 10 +2.379912929975073 + 20 +0.5201225784624666 + 10 +2.2602925604266 + 20 +0.0661149499446615 + 10 +2.21297105273781 + 20 +0.0 + 10 +2.147795531372934 + 20 +0.0 + 10 +2.196547795485895 + 20 +0.1752767944487085 + 42 +-0.0815316895695442 + 10 +2.160444026995122 + 20 +0.1807616144215795 + 42 +-0.0970784439939463 + 10 +2.131326611681949 + 20 +0.1972162265483224 + 42 +-0.0875143454723418 + 10 +2.109195549546374 + 20 +0.2246403264126769 + 42 +-0.0638836232247607 + 10 +2.094050840588399 + 20 +0.2630342184309034 + 10 +2.026516093204943 + 20 +0.5201225784624666 + 0 +LWPOLYLINE + 5 +9C +102 +{ACAD_REACTORS +330 +1C8 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 22 + 70 + 1 + 43 +0.0 + 10 +2.66863653221009 + 20 +0.1752767944487085 + 10 +2.66863653221009 + 20 +0.683985285225159 + 10 +2.758774186932835 + 20 +0.683985285225159 + 10 +2.758774186932835 + 20 +0.4832608134831443 + 42 +-0.0349812911378511 + 10 +2.80104238469796 + 20 +0.5100159586151339 + 42 +-0.0697958386932639 + 10 +2.834162873836206 + 20 +0.5227390362211358 + 42 +-0.0522006296457192 + 10 +2.868653236146531 + 20 +0.5260693501105883 + 42 +-0.0932412511784358 + 10 +2.913798167573019 + 20 +0.5185183047698327 + 42 +-0.1254375778784047 + 10 +2.946066291181972 + 20 +0.4958651687475662 + 42 +-0.1084619648488494 + 10 +2.965411944534321 + 20 +0.4581099420437885 + 42 +-0.0689905889343073 + 10 +2.971865569256112 + 20 +0.4052541467398021 + 10 +2.971865569256112 + 20 +0.1752767944487085 + 10 +2.881012536321281 + 20 +0.1752767944487085 + 10 +2.881012536321281 + 20 +0.4064428922369056 + 42 +0.0660852200863579 + 10 +2.878622868676655 + 20 +0.4269407611351025 + 42 +0.1056585132217627 + 10 +2.871438644929757 + 20 +0.4415816611820138 + 42 +0.1272161701661909 + 10 +2.859475085893608 + 20 +0.4503655923776398 + 42 +0.0972102752618352 + 10 +2.842716970755184 + 20 +0.4532940768032824 + 42 +0.088587855513906 + 10 +2.798363521605896 + 20 +0.4465162487641 + 42 +0.0777103112690791 + 10 +2.759489565144921 + 20 +0.4233288622047228 + 10 +2.759489565144921 + 20 +0.1752767944487085 + 10 +2.66863653221009 + 20 +0.1752767944487085 + 0 +LWPOLYLINE + 5 +B4 +102 +{ACAD_REACTORS +330 +1C0 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 34 + 70 + 1 + 43 +0.0 + 10 +0.6946873432779551 + 20 +0.3481760979032103 + 42 +-0.0229891281782208 + 10 +0.6967086672474216 + 20 +0.3959192221127403 + 42 +-0.0328228697904816 + 10 +0.7027741612371234 + 20 +0.4354583281028243 + 42 +-0.0483316739793035 + 10 +0.7128214199136659 + 20 +0.4666716493692773 + 42 +-0.0727828188712317 + 10 +0.7267941262688635 + 20 +0.489443507733124 + 42 +-0.1227899169725496 + 10 +0.762229701067922 + 20 +0.5157237634987931 + 42 +-0.0944303865644604 + 10 +0.8083670295035159 + 20 +0.5234528923519188 + 42 +-0.0315898411800418 + 10 +0.8956492597031299 + 20 +0.5183995824282526 + 42 +-0.0456865147865019 + 10 +0.9667593760657095 + 20 +0.5032381305759515 + 10 +0.9667593760657095 + 20 +0.448776539498029 + 42 +0.0070437593452633 + 10 +0.8389882611433709 + 20 +0.4484492920180325 + 42 +0.0290350112768282 + 10 +0.82418297631581 + 20 +0.4474675495780431 + 42 +0.0847606935358247 + 10 +0.8076546954540353 + 20 +0.4410458885636011 + 42 +0.1825489438203349 + 10 +0.7945739287419907 + 20 +0.4249924970681467 + 42 +0.0517789759014607 + 10 +0.7877961007028083 + 20 +0.3930348780448645 + 42 +0.0296456838705223 + 10 +0.7855358099688792 + 20 +0.3499599771895165 + 42 +0.0216618761660938 + 10 +0.7870822445720254 + 20 +0.3081910220915498 + 42 +0.0471796273319681 + 10 +0.7917200263001613 + 20 +0.280157633081881 + 42 +0.072662787539697 + 10 +0.7993608744377529 + 20 +0.262588400817457 + 42 +0.1214661602111968 + 10 +0.8099134641066621 + 20 +0.2522132858283972 + 42 +0.0832516876593145 + 10 +0.8254021634389597 + 20 +0.247129686486815 + 42 +0.0435906078463293 + 10 +0.8478467743228099 + 20 +0.2454353055810845 + 42 +0.021166726074658 + 10 +0.9539175761181276 + 20 +0.2499539083432495 + 10 +0.9712784354522652 + 20 +0.2513808595641643 + 10 +0.9712784354522652 + 20 +0.1940650616281518 + 42 +-0.0978017422898016 + 10 +0.9130101190372676 + 20 +0.1759903461632311 + 42 +-0.0233934475797722 + 10 +0.8395225116804813 + 20 +0.1719472415999074 + 10 +0.8357173084247086 + 20 +0.1719472415999074 + 42 +-0.1019475670653864 + 10 +0.7625265069218723 + 20 +0.1805684623043164 + 42 +-0.117873950403685 + 10 +0.7277454270828068 + 20 +0.2064319722094134 + 42 +-0.0715503088956374 + 10 +0.7132826105482655 + 20 +0.2296496481867064 + 42 +-0.0491245187935067 + 10 +0.7029522447494936 + 20 +0.2610127422533067 + 42 +-0.0334830700706472 + 10 +0.6967528076051885 + 20 +0.3005215588254747 + 42 +-0.023527584931374 + 10 +0.6946873432779551 + 20 +0.3481760979032103 + 0 +LWPOLYLINE + 5 +D8 +102 +{ACAD_REACTORS +330 +1C1 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 16 + 70 + 1 + 43 +0.0 + 10 +1.020746077777311 + 20 +0.1752767944487085 + 10 +1.020746077777311 + 20 +0.5201225784624666 + 10 +1.097325032259088 + 20 +0.5201225784624666 + 10 +1.111594544468236 + 20 +0.4766017077855419 + 42 +-0.0805753976673698 + 10 +1.160646658597752 + 20 +0.5117404767306502 + 42 +-0.1124747672601628 + 10 +1.210292384435168 + 20 +0.5234528923519188 + 42 +-0.0241299749672376 + 10 +1.233896821271378 + 20 +0.5225015915379756 + 42 +-0.060832138395251 + 10 +1.248581861676056 + 20 +0.519647689096146 + 10 +1.248581861676056 + 20 +0.4318905695302117 + 42 +0.0248536783236681 + 10 +1.199353186115472 + 20 +0.4337931711580981 + 42 +0.0387057739818888 + 10 +1.170873522867967 + 20 +0.4317718471886316 + 42 +0.0551847743452131 + 10 +1.147743975398077 + 20 +0.4257063531989297 + 42 +0.080499651857314 + 10 +1.128480514436053 + 20 +0.4141126599192412 + 42 +0.0645077730986141 + 10 +1.111594544468236 + 20 +0.39550369391721 + 10 +1.111594544468236 + 20 +0.1752767944487085 + 10 +1.020746077777311 + 20 +0.1752767944487085 + 0 +LWPOLYLINE + 5 +EA +102 +{ACAD_REACTORS +330 +1C9 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 30 + 70 + 1 + 43 +0.0 + 10 +3.020617833369073 + 20 +0.3410405807579851 + 42 +-0.0409081205529831 + 10 +3.025732026544832 + 20 +0.4159559003763376 + 42 +-0.0781599297384411 + 10 +3.041896529975355 + 20 +0.4673261443292702 + 42 +-0.1364366144086533 + 10 +3.072459922525721 + 20 +0.5006216728172821 + 42 +-0.0882009175036989 + 10 +3.116752488422916 + 20 +0.5177450874682596 + 42 +-0.0529086836461284 + 10 +3.177818390271558 + 20 +0.5234528923519188 + 42 +-0.0321103580647159 + 10 +3.218868922994835 + 20 +0.5210145181056196 + 42 +-0.0444041287441238 + 10 +3.253054869044698 + 20 +0.5137024395293266 + 42 +-0.0605636228964518 + 10 +3.280406670047193 + 20 +0.5015136124604352 + 42 +-0.0762678881360705 + 10 +3.300893884376273 + 20 +0.4844495589802478 + 42 +-0.0695139514449708 + 10 +3.315825501951926 + 20 +0.4611571488110112 + 42 +-0.0499044136612151 + 10 +3.326495291881113 + 20 +0.4302847737562754 + 42 +-0.0350340529330662 + 10 +3.332888033350811 + 20 +0.3918309117347381 + 42 +-0.0250615206333876 + 10 +3.335018947174044 + 20 +0.3457970848277011 + 42 +-0.0247570817049555 + 10 +3.332933695789881 + 20 +0.2998822846785048 + 42 +-0.035093333100506 + 10 +3.326632279198321 + 20 +0.2617856551386192 + 42 +-0.0509721690967282 + 10 +3.316160359838434 + 20 +0.2315076528324352 + 42 +-0.0726634493786117 + 10 +3.301487496084174 + 20 +0.2090479733436921 + 42 +-0.0773754337522631 + 10 +3.281182931511371 + 20 +0.1928163461277374 + 42 +-0.0591962390389137 + 10 +3.253800688882829 + 20 +0.1812223484317884 + 42 +-0.0423681953096553 + 10 +3.219355989011574 + 20 +0.174265980255845 + 42 +-0.0302514249026995 + 10 +3.177818390271558 + 20 +0.1719472415999074 + 42 +-0.0327640807112059 + 10 +3.136935286491535 + 20 +0.1744296039958433 + 42 +-0.0448781589059774 + 10 +3.10273411962865 + 20 +0.1818763867673907 + 42 +-0.060332284523739 + 10 +3.075214889682901 + 20 +0.1942878943308099 + 42 +-0.0746618379907621 + 10 +3.054392817467312 + 20 +0.2116639744779708 + 42 +-0.0666236365557017 + 10 +3.03961340802189 + 20 +0.2341087375699512 + 42 +-0.0504061851560683 + 10 +3.029065384596889 + 20 +0.2631532451887439 + 42 +-0.0367317311855017 + 10 +3.022733526379283 + 20 +0.2987971929180886 + 42 +-0.0269050519350767 + 10 +3.020617833369073 + 20 +0.3410405807579851 + 0 +LWPOLYLINE + 5 +10A +102 +{ACAD_REACTORS +330 +1C2 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 21 + 70 + 1 + 43 +0.0 + 10 +1.390325682953593 + 20 +0.4318905695302117 + 42 +0.0242919032698246 + 10 +1.38033778544784 + 20 +0.3839084785562191 + 42 +0.0375411437912006 + 10 +1.377007471558388 + 20 +0.3446083393305977 + 42 +0.0398730504554166 + 10 +1.38033778544784 + 20 +0.2901464438364147 + 42 +0.0541422102818605 + 10 +1.38500448672072 + 20 +0.2730230291854372 + 42 +0.0823828350418203 + 10 +1.392347006923059 + 20 +0.2606561186041756 + 42 +0.1602559612730944 + 10 +1.412086879332706 + 20 +0.2480513067153631 + 42 +0.0555482263236158 + 10 +1.442053616012568 + 20 +0.2454353055810845 + 42 +0.0316904222703728 + 10 +1.470353673666401 + 20 +0.2467432300441587 + 42 +0.1007429782984575 + 10 +1.488551677716809 + 20 +0.2532834611920508 + 42 +0.1818370389300056 + 10 +1.501154510899928 + 20 +0.2694555750290851 + 42 +0.0526041808970857 + 10 +1.507395044239396 + 20 +0.2969244240837275 + 42 +0.0324432335036989 + 10 +1.50948029562356 + 20 +0.3327178401969589 + 42 +0.018652937942289 + 10 +1.507927772695204 + 20 +0.3912220792138144 + 42 +0.0530768467862457 + 10 +1.502463500819915 + 20 +0.4224962837323597 + 42 +0.1914595274942226 + 10 +1.48998243414098 + 20 +0.4402133100912379 + 42 +0.0889989641192241 + 10 +1.472167994578754 + 20 +0.4475269107488332 + 42 +0.0570509400215991 + 10 +1.448236310262548 + 20 +0.4499652849951324 + 42 +0.0204219730568417 + 10 +1.425137204418705 + 20 +0.4491616260675131 + 42 +0.045760246847436 + 10 +1.409828110680079 + 20 +0.4467536934472601 + 42 +0.1785155631256146 + 10 +1.390325682953593 + 20 +0.4318905695302117 + 0 +LWPOLYLINE + 5 +121 +102 +{ACAD_REACTORS +330 +1C9 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 21 + 70 + 1 + 43 +0.0 + 10 +3.124789077699108 + 20 +0.4318905695302117 + 42 +0.0242919032698246 + 10 +3.114804224355961 + 20 +0.3839084785562191 + 42 +0.0375411437912007 + 10 +3.111470866303904 + 20 +0.3446083393305977 + 42 +0.0398730504554166 + 10 +3.114804224355961 + 20 +0.2901464438364147 + 42 +0.0541422102818607 + 10 +3.119461793141027 + 20 +0.2730230291854372 + 42 +0.0823828350418199 + 10 +3.12681344583118 + 20 +0.2606561186041756 + 42 +0.1602559612730945 + 10 +3.146539619509106 + 20 +0.2480513067153631 + 42 +0.0555482263236158 + 10 +3.176509400351572 + 20 +0.2454353055810845 + 42 +0.0316904222703728 + 10 +3.204820112574522 + 20 +0.2467432300441587 + 42 +0.1007429782984576 + 10 +3.223008984137115 + 20 +0.2532834611920508 + 42 +0.1818370389300056 + 10 +3.235611817320236 + 20 +0.2694555750290851 + 42 +0.0526041808970857 + 10 +3.241852350659703 + 20 +0.2969244240837275 + 42 +0.0324432335036989 + 10 +3.243937602043866 + 20 +0.3327178401969589 + 42 +0.018652937942289 + 10 +3.242385079115511 + 20 +0.3912220792138144 + 42 +0.0530768467862456 + 10 +3.236920807240222 + 20 +0.4224962837323597 + 42 +0.1914595274942226 + 10 +3.224439740561286 + 20 +0.4402133100912379 + 42 +0.0889989641192241 + 10 +3.20663138932427 + 20 +0.4475269107488332 + 42 +0.0570509400215991 + 10 +3.182689050438947 + 20 +0.4499652849951324 + 42 +0.0204219730568417 + 10 +3.159599077082918 + 20 +0.4491616260675131 + 42 +0.045760246847436 + 10 +3.144286939181689 + 20 +0.4467536934472601 + 42 +0.178515563125615 + 10 +3.124789077699108 + 20 +0.4318905695302117 + 0 +LWPOLYLINE + 5 +138 +102 +{ACAD_REACTORS +330 +1C5 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbPolyline + 90 + 17 + 70 + 1 + 43 +0.0 + 10 +1.658111534794044 + 20 +0.1752767944487085 + 10 +1.658111534794044 + 20 +0.6506897567371471 + 10 +1.862892353206713 + 20 +0.6506897567371471 + 42 +-0.0918352741933524 + 10 +1.923821267738147 + 20 +0.6408190594916725 + 42 +-0.133922059302927 + 10 +1.965389308104209 + 20 +0.6112100119178533 + 42 +-0.1060028202258852 + 10 +1.987322499670483 + 20 +0.566558234833313 + 42 +-0.0661506729116568 + 10 +1.99464371073459 + 20 +0.5039519867067345 + 42 +-0.0710178368558241 + 10 +1.985846080807243 + 20 +0.4324841812381122 + 42 +-0.0374247138640044 + 10 +1.976089539659442 + 20 +0.4061156447569091 + 42 +-0.057718769966508 + 10 +1.964430396883754 + 20 +0.3867030198272586 + 42 +-0.1271250474471338 + 10 +1.932329702218055 + 20 +0.3624456101123582 + 42 +-0.110827379232239 + 10 +1.875723498585179 + 20 +0.3505535888974171 + 42 +-0.0258396192335467 + 10 +1.802480946318064 + 20 +0.3564988384642365 + 42 +-0.0037744416271255 + 10 +1.763835302052436 + 20 +0.3612568646152548 + 42 +-0.0304647996844293 + 10 +1.749208100737245 + 20 +0.3636343556094617 + 10 +1.749208100737245 + 20 +0.1752767944487085 + 10 +1.658111534794044 + 20 +0.1752767944487085 + 0 +LWPOLYLINE + 5 +14B +102 +{ACAD_REACTORS +330 +1C2 +102 +} +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbPolyline + 90 + 30 + 70 + 1 + 43 +0.0 + 10 +1.286159004867464 + 20 +0.3410405807579851 + 42 +-0.040908120552983 + 10 +1.29127167596192 + 20 +0.4159559003763376 + 42 +-0.0781599297384411 + 10 +1.307443789798954 + 20 +0.4673261443292702 + 42 +-0.1364366144086534 + 10 +1.338004138186717 + 20 +0.5006216728172821 + 42 +-0.088200917503699 + 10 +1.382299748246516 + 20 +0.5177450874682596 + 42 +-0.0529086836461285 + 10 +1.443361083851251 + 20 +0.5234528923519188 + 42 +-0.0321103580647177 + 10 +1.484408572411924 + 20 +0.5210145181056196 + 42 +-0.0444041287441238 + 10 +1.518597562624391 + 20 +0.5137024395293266 + 42 +-0.0605636228964518 + 10 +1.545949363626886 + 20 +0.5015136124604352 + 42 +-0.0762678881361016 + 10 +1.566436577955966 + 20 +0.4844495589802478 + 42 +-0.0695139514449315 + 10 +1.581368195531619 + 20 +0.4611571488110112 + 42 +-0.0499044136612151 + 10 +1.592037985460806 + 20 +0.4302847737562754 + 42 +-0.0350340529330662 + 10 +1.598430726930504 + 20 +0.3918309117347381 + 42 +-0.0250615206333974 + 10 +1.600561640753737 + 20 +0.3457970848277011 + 42 +-0.0247570817049556 + 10 +1.59846116855655 + 20 +0.2998822846785048 + 42 +-0.035093333100506 + 10 +1.592174972778014 + 20 +0.2617856551386192 + 42 +-0.0509721690967282 + 10 +1.581703053418127 + 20 +0.2315076528324352 + 42 +-0.0726634493786118 + 10 +1.567030189663867 + 20 +0.2090479733436921 + 42 +-0.0773754337522942 + 10 +1.546725625091063 + 20 +0.1928163461277374 + 42 +-0.0591962390389137 + 10 +1.519343382462522 + 20 +0.1812223484317884 + 42 +-0.0423681953096553 + 10 +1.484891072184755 + 20 +0.174265980255845 + 42 +-0.0302514249026978 + 10 +1.443361083851251 + 20 +0.1719472415999074 + 42 +-0.0327640807112059 + 10 +1.402470369664717 + 20 +0.1744296039958433 + 42 +-0.0448781589059774 + 10 +1.368267680720529 + 20 +0.1818763867673907 + 42 +-0.060332284523739 + 10 +1.340754539099989 + 20 +0.1942878943308099 + 42 +-0.0746618379907621 + 10 +1.319929422721796 + 20 +0.2116639744779708 + 42 +-0.0666236365556613 + 10 +1.305154579520281 + 20 +0.2341087375699512 + 42 +-0.0504061851560684 + 10 +1.294601989851372 + 20 +0.2631532451887439 + 42 +-0.0367317311855017 + 10 +1.288268609552464 + 20 +0.2987971929180886 + 42 +-0.0269050519351071 + 10 +1.286159004867464 + 20 +0.3410405807579851 + 0 +HATCH + 5 +1BD +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 14 + 72 + 1 + 10 +0.0000000000000001 + 20 +0.1752767944487085 + 11 +0.0416193345059499 + 21 +0.6506897567371471 + 72 + 1 + 10 +0.0416193345059499 + 20 +0.6506897567371471 + 11 +0.1681431038010463 + 21 +0.6506897567371471 + 72 + 1 + 10 +0.1681431038010463 + 20 +0.6506897567371471 + 11 +0.247338516041492 + 21 +0.3260572124180542 + 72 + 1 + 10 +0.247338516041492 + 20 +0.3260572124180542 + 11 +0.3260590389156172 + 21 +0.6506897567371471 + 72 + 1 + 10 +0.3260590389156172 + 20 +0.6506897567371471 + 11 +0.4521056357224397 + 21 +0.6506897567371471 + 72 + 1 + 10 +0.4521056357224397 + 20 +0.6506897567371471 + 11 +0.4963403625301471 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.4963403625301471 + 20 +0.1752767944487085 + 11 +0.4066806413363264 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.4066806413363264 + 20 +0.1752767944487085 + 11 +0.3752877144762009 + 21 +0.4930112663057366 + 72 + 1 + 10 +0.3752877144762009 + 20 +0.4930112663057366 + 11 +0.2987087599944248 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.2987087599944248 + 20 +0.1752767944487085 + 11 +0.1973944622688229 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.1973944622688229 + 20 +0.1752767944487085 + 11 +0.1174851938975943 + 21 +0.4930112663057366 + 72 + 1 + 10 +0.1174851938975943 + 20 +0.4930112663057366 + 11 +0.0896600256100814 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.0896600256100814 + 20 +0.1752767944487085 + 11 +0.0000000000000001 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.0000000000000001 + 20 +0.1752767944487085 + 11 +0.0000000000000001 + 21 +0.1752767944487085 + 97 + 1 +330 +24 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1BE +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 5 + 72 + 1 + 10 +0.5505660310062117 + 20 +0.1752767944487085 + 11 +0.5505660310062117 + 21 +0.5201225784624666 + 72 + 1 + 10 +0.5505660310062117 + 20 +0.5201225784624666 + 11 +0.6416519423802962 + 21 +0.5201225784624666 + 72 + 1 + 10 +0.6416519423802962 + 20 +0.5201225784624666 + 11 +0.6416519423802962 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.6416519423802962 + 20 +0.1752767944487085 + 11 +0.5505660310062117 + 21 +0.1752767944487085 + 72 + 1 + 10 +0.5505660310062117 + 20 +0.1752767944487085 + 11 +0.5505660310062117 + 21 +0.1752767944487085 + 97 + 1 +330 +34 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1BF +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 13 + 72 + 1 + 10 +0.5474731617999196 + 20 +0.5714928224153991 + 11 +0.5474731617999196 + 21 +0.6288098380164536 + 72 + 2 + 10 +0.5656218268345913 + 20 +0.630192970755272 + 40 +0.0182012938747197 + 50 +175.6418407014946 + 51 +218.2992114073367 + 73 + 0 + 72 + 2 + 10 +0.5617930966007493 + 20 +0.6307876795407876 + 40 +0.0149500064305679 + 50 +225.6246753032742 + 51 +274.3668398711414 + 73 + 0 + 72 + 1 + 10 +0.5629314195061711 + 20 +0.6456942859029685 + 11 +0.6311876334269211 + 21 +0.6456942859029685 + 72 + 2 + 10 +0.6321698296440981 + 20 +0.6325035330064808 + 40 +0.0132272699898821 + 50 +265.7415594617891 + 51 +317.3010585925538 + 73 + 0 + 72 + 2 + 10 +0.6262804611730807 + 20 +0.6302434840168466 + 40 +0.0192301993709753 + 50 +324.2689673804306 + 51 +364.2754703081528 + 73 + 0 + 72 + 1 + 10 +0.6454571456360689 + 20 +0.6288098380164536 + 11 +0.6454571456360689 + 21 +0.5714928224153991 + 72 + 2 + 10 +0.6297669641888812 + 20 +0.5702888340215038 + 40 +0.0157363077593922 + 50 +355.611999000231 + 51 +399.6062175218991 + 73 + 0 + 72 + 2 + 10 +0.6322686211170757 + 20 +0.5705867464421508 + 40 +0.0141172179806454 + 50 +47.03124341518984 + 51 +94.39156764264102 + 73 + 0 + 72 + 1 + 10 +0.6311876334269211 + 20 +0.5565109761567706 + 11 +0.5629314195061711 + 21 +0.5565109761567706 + 72 + 2 + 10 +0.5620823708457157 + 20 +0.572286229491247 + 40 +0.0157980853711685 + 50 +86.91922452913958 + 51 +131.3944660406891 + 73 + 0 + 72 + 2 + 10 +0.5619098596911134 + 20 +0.570615150925454 + 40 +0.0144633520750158 + 50 +135.2620677004958 + 51 +183.4789850614727 + 73 + 0 + 72 + 1 + 10 +0.5474731617999196 + 20 +0.5714928224153991 + 11 +0.5474731617999196 + 21 +0.5714928224153991 + 97 + 1 +330 +3B + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C0 +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 34 + 72 + 2 + 10 +1.214616030315336 + 20 +0.350077974119305 + 40 +0.5199321655154222 + 50 +179.7904154992175 + 51 +185.0582076977404 + 73 + 0 + 72 + 2 + 10 +1.000572124284262 + 20 +0.3695398595471971 + 40 +0.3050063463138826 + 50 +184.961591177561 + 51 +192.4813391512255 + 73 + 0 + 72 + 2 + 10 +0.8688743989493632 + 20 +0.3992160253637114 + 40 +0.170008215907044 + 50 +192.3087569665484 + 51 +203.3769478223085 + 73 + 0 + 72 + 2 + 10 +0.7976119460679242 + 20 +0.4303172999651613 + 40 +0.0922554716323781 + 50 +203.2074684948184 + 51 +219.8587008780153 + 73 + 0 + 72 + 2 + 10 +0.7972117188097253 + 20 +0.4315246663413517 + 40 +0.0911769133466147 + 50 +219.4374770529955 + 51 +247.4386863416477 + 73 + 0 + 72 + 2 + 10 +0.8055784036639897 + 20 +0.398531115770543 + 40 +0.124952897918856 + 50 +249.7009350090099 + 51 +271.2787999327404 + 73 + 0 + 72 + 2 + 10 +0.8120564786102148 + 20 +-0.1691304899318403 + 40 +0.6925932092147039 + 50 +269.6947835186498 + 51 +276.9322349981942 + 73 + 0 + 72 + 2 + 10 +0.8484128964611991 + 20 +0.1225112149529162 + 40 +0.3986964678983381 + 50 +276.8042143326444 + 51 +287.2675164228719 + 73 + 0 + 72 + 1 + 10 +0.9667593760657095 + 20 +0.5032381305759515 + 11 +0.9667593760657095 + 21 +0.448776539498029 + 72 + 2 + 10 +0.9144880443227094 + 20 +-4.086066981505726 + 40 +4.535144766389704 + 50 +89.3396036583715 + 51 +90.9538876909594 + 73 + 1 + 72 + 2 + 10 +0.8400315841062043 + 20 +0.3205880251107224 + 40 +0.1278655234922502 + 50 +90.46751199340585 + 51 +97.1199774171112 + 73 + 1 + 72 + 2 + 10 +0.8347233227483223 + 20 +0.3958571165940125 + 40 +0.0526757600392865 + 50 +101.54272561012 + 51 +120.9221245987022 + 73 + 1 + 72 + 2 + 10 +0.8223667308685831 + 20 +0.4157021086294436 + 40 +0.029304456442492 + 50 +120.1351163505028 + 51 +161.5166003585789 + 73 + 1 + 72 + 2 + 10 +0.9450695696956614 + 20 +0.3763766174814469 + 40 +0.1581532222056973 + 50 +162.0975481756131 + 51 +173.9538270794763 + 73 + 1 + 72 + 2 + 10 +1.149594366372439 + 20 +0.3524533042818777 + 40 +0.3640670943255288 + 50 +173.6000944629489 + 51 +180.3923953532557 + 73 + 1 + 72 + 2 + 10 +1.268138893295446 + 20 +0.346914547227496 + 40 +0.4826126922076991 + 50 +179.638444150984 + 51 +184.6022041776311 + 73 + 1 + 72 + 2 + 10 +0.9376165336263994 + 20 +0.3186947544718952 + 40 +0.1509003001157511 + 50 +183.9914206989488 + 51 +194.7961827171795 + 73 + 1 + 72 + 2 + 10 +0.8556691262907683 + 20 +0.2975229405501065 + 40 +0.0662649326044679 + 50 +195.1922580686626 + 51 +211.8161260167849 + 73 + 1 + 72 + 2 + 10 +0.8256760335810848 + 20 +0.2787995943136916 + 40 +0.0309077724093995 + 50 +211.6347351863199 + 51 +239.3370203444206 + 73 + 1 + 72 + 2 + 10 +0.8328177638353177 + 20 +0.2958607887822569 + 40 +0.0492921034260791 + 50 +242.3114767787511 + 51 +261.3474606529535 + 73 + 1 + 72 + 2 + 10 +0.8463235842781011 + 20 +0.3747617950344397 + 40 +0.1293354591063143 + 50 +260.6908797927596 + 51 +270.6747908046021 + 73 + 1 + 72 + 2 + 10 +0.8475369120546362 + 20 +1.499934543466537 + 40 +1.25449927615356 + 50 +270.0141521009336 + 51 +274.864484102984 + 73 + 1 + 72 + 1 + 10 +0.9539175761181276 + 20 +0.2499539083432495 + 11 +0.9712784354522652 + 21 +0.2513808595641643 + 72 + 1 + 10 +0.9712784354522652 + 20 +0.2513808595641643 + 11 +0.9712784354522652 + 21 +0.1940650616281518 + 72 + 2 + 10 +0.8963837746081258 + 20 +0.3325480038481863 + 40 +0.1574380370459314 + 50 +61.59448955636654 + 51 +83.93793890179708 + 73 + 0 + 72 + 2 + 10 +0.8330823004026875 + 20 +0.9588829323823655 + 40 +0.7869620433976263 + 50 +84.17070136778845 + 51 +89.53110693540054 + 73 + 0 + 72 + 1 + 10 +0.8395225116804813 + 20 +0.1719472415999074 + 11 +0.8357173084247086 + 21 +0.1719472415999074 + 72 + 2 + 10 +0.8200434901136805 + 20 +0.3538739274501789 + 40 +0.1826006232325358 + 50 +85.075865127039 + 51 +108.3600821200968 + 73 + 0 + 72 + 2 + 10 +0.7992279764644755 + 20 +0.2662427996310877 + 40 +0.093204559668334 + 50 +113.1894915396505 + 51 +140.0801272454766 + 73 + 0 + 72 + 2 + 10 +0.8012223158134221 + 20 +0.2683158374418412 + 40 +0.0960649049009913 + 50 +139.8951733394063 + 51 +156.2653987660679 + 73 + 0 + 72 + 2 + 10 +0.867342438096846 + 20 +0.2977766777590661 + 40 +0.168450950198126 + 50 +156.1444339138709 + 51 +167.3939009796797 + 73 + 0 + 72 + 2 + 10 +0.99451280167804 + 20 +0.3270031053307328 + 40 +0.2989352544876143 + 50 +167.2468323736907 + 51 +174.9177209790342 + 73 + 0 + 72 + 2 + 10 +1.20180856877263 + 20 +0.3462839419889538 + 40 +0.5071247554608478 + 50 +174.8226486749857 + 51 +180.2137793480696 + 73 + 0 + 72 + 1 + 10 +0.6946873432779551 + 20 +0.3481760979032103 + 11 +0.6946873432779551 + 21 +0.3481760979032103 + 97 + 1 +330 +B4 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C1 +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 16 + 72 + 1 + 10 +1.020746077777311 + 20 +0.1752767944487085 + 11 +1.020746077777311 + 21 +0.5201225784624666 + 72 + 1 + 10 +1.020746077777311 + 20 +0.5201225784624666 + 11 +1.097325032259088 + 21 +0.5201225784624666 + 72 + 1 + 10 +1.097325032259088 + 20 +0.5201225784624666 + 11 +1.111594544468236 + 21 +0.4766017077855419 + 72 + 2 + 10 +1.244437268897258 + 20 +0.3429659792394641 + 40 +0.1884295554783436 + 50 +225.1705040479414 + 51 +243.5972159016927 + 73 + 0 + 72 + 2 + 10 +1.211173613045121 + 20 +0.4086440720149234 + 40 +0.114812202274129 + 50 +243.8907918763913 + 51 +269.5602281386679 + 73 + 0 + 72 + 2 + 10 +1.212244334515651 + 20 +0.2785645037372034 + 40 +0.2448961677679514 + 50 +269.5433179430547 + 51 +275.0724278925614 + 73 + 0 + 72 + 2 + 10 +1.229554147138809 + 20 +0.4609473043473566 + 40 +0.0617072855517635 + 50 +274.0355485122913 + 51 +287.9600884366593 + 73 + 0 + 72 + 1 + 10 +1.248581861676056 + 20 +0.519647689096146 + 11 +1.248581861676056 + 21 +0.4318905695302117 + 72 + 2 + 10 +1.204841316941958 + 20 +-0.0620372588614032 + 40 +0.4958608019528185 + 50 +84.9392850010685 + 51 +90.63415610337293 + 73 + 1 + 72 + 2 + 10 +1.198149495755201 + 20 +0.2491083832840643 + 40 +0.1846887103819838 + 50 +89.62657779356016 + 51 +98.49286189291752 + 73 + 1 + 72 + 2 + 10 +1.186703181985212 + 20 +0.32427591283572 + 40 +0.1086552070090232 + 50 +98.37706810352306 + 51 +111.0116715202816 + 73 + 1 + 72 + 2 + 10 +1.173884337196004 + 20 +0.3604725103818166 + 40 +0.070276402608659 + 50 +111.8368548044861 + 51 +130.2463188715139 + 73 + 1 + 72 + 2 + 10 +1.191856507616234 + 20 +0.3396388865736808 + 40 +0.0977898738515406 + 50 +130.3972532514171 + 51 +145.1608900952568 + 73 + 1 + 72 + 1 + 10 +1.111594544468236 + 20 +0.39550369391721 + 11 +1.111594544468236 + 21 +0.1752767944487085 + 72 + 1 + 10 +1.111594544468236 + 20 +0.1752767944487085 + 11 +1.020746077777311 + 21 +0.1752767944487085 + 72 + 1 + 10 +1.020746077777311 + 20 +0.1752767944487085 + 11 +1.020746077777311 + 21 +0.1752767944487085 + 97 + 1 +330 +D8 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C2 +330 +1D +100 +AcDbEntity + 8 +TEXT-GRAY +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 2 + 92 + 1 + 93 + 30 + 72 + 2 + 10 +1.745775880860402 + 20 +0.3473056857538349 + 40 +0.4596595742917985 + 50 +179.219041199578 + 51 +188.5892672078823 + 73 + 0 + 72 + 2 + 10 +1.462665276168372 + 20 +0.3902293883547505 + 40 +0.1733136452000416 + 50 +188.5364777731353 + 51 +206.4130707393759 + 73 + 0 + 72 + 2 + 10 +1.382597433515457 + 20 +0.4290189590384098 + 40 +0.0843534860499277 + 50 +207.0087701028281 + 51 +238.085854021312 + 73 + 0 + 72 + 2 + 10 +1.408309618919584 + 20 +0.3846069642931946 + 40 +0.1356549785854117 + 50 +238.7839320009168 + 51 +258.9459185787553 + 73 + 0 + 72 + 2 + 10 +1.439724993974423 + 20 +0.2328843812063898 + 40 +0.29059126074079 + 50 +258.6024639297659 + 51 +270.7169453069864 + 73 + 0 + 72 + 2 + 10 +1.444920074652102 + 20 +0.2029818501508946 + 40 +0.3204748341784855 + 50 +269.7212762564572 + 51 +277.0779005236373 + 73 + 0 + 72 + 2 + 10 +1.460416453713881 + 20 +0.3252503357550985 + 40 +0.1972288945641309 + 50 +276.9871111277841 + 51 +287.1571071678799 + 73 + 0 + 72 + 2 + 10 +1.482143870267849 + 20 +0.3951169191449219 + 40 +0.1240620704779083 + 50 +287.0876504098538 + 51 +300.9508770078874 + 73 + 0 + 72 + 2 + 10 +1.500583736465673 + 20 +0.4262167749073336 + 40 +0.0879070752171196 + 50 +301.0685629566324 + 51 +318.5141019927507 + 73 + 0 + 72 + 2 + 10 +1.490538341293795 + 20 +0.4193627680062952 + 40 +0.0999841621843878 + 50 +319.38514811862 + 51 +335.2909851831375 + 73 + 0 + 72 + 2 + 10 +1.432430719209494 + 20 +0.3924029450769723 + 40 +0.1640411911207225 + 50 +335.220473520381 + 51 +346.6482421759119 + 73 + 0 + 72 + 2 + 10 +1.321167690210193 + 20 +0.3654957782609066 + 40 +0.2785109168173717 + 50 +346.5482508793782 + 51 +354.5741818072581 + 73 + 0 + 72 + 2 + 10 +1.140576365463508 + 20 +0.34757052037717 + 40 +0.459988693945271 + 50 +354.4784226911817 + 51 +360.2208980900735 + 73 + 0 + 72 + 2 + 10 +1.136142388530695 + 20 +0.3440375062016253 + 40 +0.4644225855321327 + 50 +359.7829203976418 + 51 +365.4556667991741 + 73 + 0 + 72 + 2 + 10 +1.324257241032597 + 20 +0.3255607991203732 + 40 +0.2754036673203588 + 50 +5.350003779949623 + 51 +13.38950403845408 + 73 + 0 + 72 + 2 + 10 +1.438822228558409 + 20 +0.2978741757969074 + 40 +0.1575418848528459 + 50 +13.24247481022855 + 51 +24.9143339913515 + 73 + 0 + 72 + 2 + 10 +1.49750166023149 + 20 +0.2704935387993822 + 40 +0.0927888674313809 + 50 +24.84449572776879 + 51 +41.46851456153187 + 73 + 0 + 72 + 2 + 10 +1.504747507691185 + 20 +0.2661434323058319 + 40 +0.0844927447051385 + 50 +42.51194694689715 + 51 +60.20982750498259 + 73 + 0 + 72 + 2 + 10 +1.484241834436404 + 20 +0.3022559330899828 + 40 +0.1260208208552944 + 50 +60.27608629427618 + 51 +73.82705129133484 + 73 + 0 + 72 + 2 + 10 +1.461143797848464 + 20 +0.3806703565348255 + 40 +0.2077659731176355 + 50 +73.73258141531123 + 51 +83.43685270361343 + 73 + 0 + 72 + 2 + 10 +1.444981387538941 + 20 +0.5159994031828512 + 40 +0.3440559769484268 + 50 +83.33882871764017 + 51 +90.26983081888446 + 73 + 0 + 72 + 2 + 10 +1.441836581268094 + 20 +0.4848621958152928 + 40 +0.3129186678351786 + 50 +89.72086066320244 + 51 +97.22714964633519 + 73 + 0 + 72 + 2 + 10 +1.426768810557204 + 20 +0.3683000729345016 + 40 +0.1953872384683834 + 50 +97.14382290172345 + 51 +107.4222425802834 + 73 + 0 + 72 + 2 + 10 +1.405753699036433 + 20 +0.3016738701941614 + 40 +0.1255254500273459 + 50 +107.3755052356472 + 51 +121.1859060075268 + 73 + 0 + 72 + 2 + 10 +1.388200250824436 + 20 +0.2723186857145772 + 40 +0.091323052757868 + 50 +121.3012045363258 + 51 +138.3807483919028 + 73 + 0 + 72 + 2 + 10 +1.396390386155313 + 20 +0.2780817143578742 + 40 +0.1012797862356359 + 50 +139.0208188923022 + 51 +154.2673000625914 + 73 + 0 + 72 + 2 + 10 +1.443564578953644 + 20 +0.3008357842563767 + 40 +0.153654894821596 + 50 +154.2614231301619 + 51 +165.8039007823683 + 73 + 0 + 72 + 2 + 10 +1.533704415876427 + 20 +0.3240227080426966 + 40 +0.2467287207424286 + 50 +165.7173228384291 + 51 +174.1318325417901 + 73 + 0 + 72 + 2 + 10 +1.679452490871063 + 20 +0.3395070071807061 + 40 +0.3932964759323175 + 50 +174.0587164483615 + 51 +180.2234129253398 + 73 + 0 + 72 + 1 + 10 +1.286159004867464 + 20 +0.3410405807579851 + 11 +1.286159004867464 + 21 +0.3410405807579851 + 97 + 1 +330 +14B + 92 + 16 + 93 + 21 + 72 + 2 + 10 +1.87884778741299 + 20 +0.3051697834906549 + 40 +0.5046900079850218 + 50 +165.4581922653545 + 51 +171.0243917073363 + 73 + 1 + 72 + 2 + 10 +1.640017569701684 + 20 +0.3421119050184488 + 40 +0.2630219456806235 + 50 +170.856419407449 + 51 +179.4561773269252 + 73 + 1 + 72 + 2 + 10 +1.719600323247084 + 20 +0.3382249259339413 + 40 +0.342652316488281 + 50 +178.9325511963493 + 51 +188.0659430044691 + 73 + 1 + 72 + 2 + 10 +1.461506204624639 + 20 +0.3030699205237911 + 40 +0.0821908055767169 + 50 +189.0465869719995 + 51 +201.4429641704123 + 73 + 1 + 72 + 2 + 10 +1.425949825821255 + 20 +0.2889700547677836 + 40 +0.0439411927350844 + 50 +201.2794750422889 + 51 +220.1176890207309 + 73 + 1 + 72 + 2 + 10 +1.421375505703486 + 20 +0.2843571418367111 + 40 +0.0374752217300239 + 50 +219.2307545260716 + 51 +255.6490576647813 + 73 + 1 + 72 + 2 + 10 +1.438807477461641 + 20 +0.3811952640733502 + 40 +0.1357987619432282 + 50 +258.6520849549118 + 51 +271.3697308658793 + 73 + 1 + 72 + 2 + 10 +1.445896027874007 + 20 +0.4691190853840432 + 40 +0.2237167796028082 + 50 +269.0158770897956 + 51 +276.276357003502 + 73 + 1 + 72 + 2 + 10 +1.463387403735492 + 20 +0.2947145002894463 + 40 +0.0484744436347309 + 50 +278.2625944015626 + 51 +301.2735466815289 + 73 + 1 + 72 + 2 + 10 +1.473353916121774 + 20 +0.2781237012056268 + 40 +0.0291206023535156 + 50 +301.4591386210279 + 51 +342.6827079184787 + 73 + 1 + 72 + 2 + 10 +1.374091031750538 + 20 +0.3127659022243659 + 40 +0.1342419911030445 + 50 +341.1780241039497 + 51 +353.2229122868627 + 73 + 1 + 72 + 2 + 10 +1.232912256678613 + 20 +0.3308726804904729 + 40 +0.2765741939881523 + 50 +352.9494162843384 + 51 +360.3822505868759 + 73 + 1 + 72 + 2 + 10 +0.7248612462910731 + 20 +0.3411691780724345 + 40 +0.7846645638024572 + 50 +359.3828759745637 + 51 +363.6573187603917 + 73 + 1 + 72 + 2 + 10 +1.358304373290006 + 20 +0.3811941386031548 + 40 +0.1499590652226746 + 50 +3.834298057692314 + 51 +15.98721166096502 + 73 + 1 + 72 + 2 + 10 +1.473936824340389 + 20 +0.4156549366241289 + 40 +0.0293355637618033 + 50 +13.48613242730697 + 51 +56.84075856181408 + 73 + 1 + 72 + 2 + 10 +1.460693878894012 + 20 +0.3942253340844751 + 40 +0.054522595367914 + 50 +57.50799133160251 + 51 +77.8514521481949 + 73 + 1 + 72 + 2 + 10 +1.449551855505779 + 20 +0.3442176219715277 + 40 +0.1057558456740848 + 50 +77.65179244717869 + 51 +90.71274674017063 + 73 + 1 + 72 + 2 + 10 +1.446520818841627 + 20 +0.1669086878434607 + 40 +0.2830617955533721 + 50 +89.65275773185921 + 51 +94.33247869604129 + 73 + 1 + 72 + 2 + 10 +1.430610265978255 + 20 +0.3644952794934767 + 40 +0.0848430589089613 + 50 +93.69860806412952 + 51 +104.1787730439532 + 73 + 1 + 72 + 2 + 10 +1.420228457430697 + 20 +0.4128805599428683 + 40 +0.0354338310931719 + 50 +107.0684876277999 + 51 +147.5547663680418 + 73 + 1 + 72 + 1 + 10 +1.390325682953593 + 20 +0.4318905695302117 + 11 +1.390325682953593 + 21 +0.4318905695302117 + 97 + 1 +330 +10A + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C5 +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 2 + 92 + 1 + 93 + 17 + 72 + 1 + 10 +1.658111534794044 + 20 +0.1752767944487085 + 11 +1.658111534794044 + 21 +0.6506897567371471 + 72 + 1 + 10 +1.658111534794044 + 20 +0.6506897567371471 + 11 +1.862892353206713 + 21 +0.6506897567371471 + 72 + 2 + 10 +1.866712771298765 + 20 +0.4812885811102773 + 40 +0.1694442501183315 + 50 +268.7080565864779 + 51 +289.696280270266 + 73 + 0 + 72 + 2 + 10 +1.890323704356795 + 20 +0.5498088066581733 + 40 +0.0969791362784035 + 50 +290.2068256429989 + 51 +320.7179581453081 + 73 + 0 + 72 + 2 + 10 +1.872231214265821 + 20 +0.5377375192902893 + 40 +0.1186450067238793 + 50 +321.7376468722154 + 51 +345.941318148983 + 73 + 0 + 72 + 2 + 10 +1.755413737650509 + 20 +0.5077074919349243 + 40 +0.239259448802611 + 50 +345.7608112632561 + 51 +360.8993727822122 + 73 + 0 + 72 + 2 + 10 +1.739929769421669 + 20 +0.4990316766439469 + 40 +0.2547614597035357 + 50 +358.8933548673149 + 51 +375.1421636632072 + 73 + 0 + 72 + 2 + 10 +1.805070643979139 + 20 +0.4843830829172414 + 40 +0.1880777885766737 + 50 +16.01826700445136 + 51 +24.59137858751017 + 73 + 0 + 72 + 2 + 10 +1.886457278838033 + 20 +0.4467408832612785 + 40 +0.098409106202089 + 50 +24.38210075542359 + 51 +37.59560803165674 + 73 + 0 + 72 + 2 + 10 +1.901447144532471 + 20 +0.4366823005906129 + 40 +0.0804040955571766 + 50 +38.43315571073376 + 51 +67.41262732859074 + 73 + 0 + 72 + 2 + 10 +1.877530541683213 + 20 +0.482621245957908 + 40 +0.1320800191028363 + 50 +65.48738102872184 + 51 +90.78391246376287 + 73 + 0 + 72 + 2 + 10 +1.89658449370416 + 20 +1.061679540017775 + 40 +0.711431865658397 + 50 +91.68029910103571 + 51 +97.60098612101147 + 73 + 0 + 72 + 2 + 10 +2.098301318614009 + 20 +2.918534187606983 + 40 +2.579056963876972 + 50 +96.58637858697409 + 51 +97.45141278012369 + 73 + 0 + 72 + 2 + 10 +1.776013741879782 + 20 +0.4823678310216308 + 40 +0.1217217342158525 + 50 +95.74213501202033 + 51 +102.7219939836472 + 73 + 0 + 72 + 1 + 10 +1.749208100737245 + 20 +0.3636343556094617 + 11 +1.749208100737245 + 21 +0.1752767944487085 + 72 + 1 + 10 +1.749208100737245 + 20 +0.1752767944487085 + 11 +1.658111534794044 + 21 +0.1752767944487085 + 72 + 1 + 10 +1.658111534794044 + 20 +0.1752767944487085 + 11 +1.658111534794044 + 21 +0.1752767944487085 + 97 + 1 +330 +138 + 92 + 16 + 93 + 12 + 72 + 1 + 10 +1.855753791898883 + 20 +0.5703040769182958 + 11 +1.749208100737245 + 21 +0.5703040769182958 + 72 + 1 + 10 +1.749208100737245 + 20 +0.5703040769182958 + 11 +1.749208100737245 + 21 +0.4311767133994287 + 72 + 1 + 10 +1.749208100737245 + 20 +0.4311767133994287 + 11 +1.855281946695168 + 21 +0.4311767133994287 + 72 + 2 + 10 +1.857310696196809 + 20 +0.4789795547126073 + 40 +0.0478458719447492 + 50 +267.5698291459668 + 51 +298.9736848744403 + 73 + 1 + 72 + 2 + 10 +1.864437662714773 + 20 +0.4638897212446849 + 40 +0.0312107960389064 + 50 +300.9469057674883 + 51 +325.1843100261158 + 73 + 1 + 72 + 2 + 10 +1.847208640489655 + 20 +0.4756552874383635 + 40 +0.0520734162270339 + 50 +325.3793523193102 + 51 +342.5869620344669 + 73 + 1 + 72 + 2 + 10 +1.761853469548879 + 20 +0.499095419473726 + 40 +0.1405675106851083 + 50 +343.8821453186945 + 51 +361.6888272002417 + 73 + 1 + 72 + 2 + 10 +1.771325527872711 + 20 +0.505069610767784 + 40 +0.1310471922643137 + 50 +359.1992235790916 + 51 +372.1177778779552 + 73 + 1 + 72 + 2 + 10 +1.840471280377904 + 20 +0.5202934512206887 + 40 +0.0602474495482526 + 50 +11.76645972748428 + 51 +33.49099599484823 + 73 + 1 + 72 + 2 + 10 +1.86002067419837 + 20 +0.5327033580204925 + 40 +0.0370985166555385 + 50 +34.16739135196509 + 51 +64.22988058382727 + 73 + 1 + 72 + 2 + 10 +1.856792087819456 + 20 +0.5236405260900577 + 40 +0.0466751007960158 + 50 +65.49764645855024 + 51 +91.27465994990668 + 73 + 1 + 72 + 1 + 10 +1.855753791898883 + 20 +0.5703040769182958 + 11 +1.855753791898883 + 21 +0.5703040769182958 + 97 + 1 +330 +4A + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C6 +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 17 + 72 + 1 + 10 +2.026516093204943 + 20 +0.5201225784624666 + 11 +2.12187448679461 + 21 +0.5201225784624666 + 72 + 1 + 10 +2.12187448679461 + 20 +0.5201225784624666 + 11 +2.181814048479542 + 21 +0.2784929327615455 + 72 + 2 + 10 +2.213922500215711 + 20 +0.2853658521330381 + 40 +0.0328357989636449 + 50 +192.0820235727047 + 51 +230.2482576268844 + 73 + 1 + 72 + 2 + 10 +2.211977736162895 + 20 +0.2865212844941371 + 40 +0.0325572563546005 + 50 +234.1829062182941 + 51 +272.5793312178134 + 73 + 1 + 72 + 2 + 10 +2.218185855487651 + 20 +0.2662392650291758 + 40 +0.0131289140189778 + 50 +248.8223744883709 + 51 +260.6854283382104 + 73 + 1 + 72 + 1 + 10 +2.216060877781497 + 20 +0.2532834611920508 + 11 +2.285026381589124 + 21 +0.5201225784624666 + 72 + 1 + 10 +2.285026381589124 + 20 +0.5201225784624666 + 11 +2.379912929975073 + 21 +0.5201225784624666 + 72 + 1 + 10 +2.379912929975073 + 20 +0.5201225784624666 + 11 +2.2602925604266 + 21 +0.0661149499446615 + 72 + 1 + 10 +2.2602925604266 + 20 +0.0661149499446615 + 11 +2.21297105273781 + 21 +0.0 + 72 + 1 + 10 +2.21297105273781 + 20 +0.0 + 11 +2.147795531372934 + 21 +0.0 + 72 + 1 + 10 +2.147795531372934 + 20 +0.0 + 11 +2.196547795485895 + 21 +0.1752767944487085 + 72 + 2 + 10 +2.195202176373045 + 20 +0.2879880150203464 + 40 +0.1127192527190687 + 50 +89.31599859402309 + 51 +107.9604459396842 + 73 + 0 + 72 + 2 + 10 +2.187860498124107 + 20 +0.2632664971382323 + 40 +0.0869408911919764 + 50 +108.3817089051841 + 51 +130.5609495896915 + 73 + 0 + 72 + 2 + 10 +2.198002807128255 + 20 +0.2736653212156158 + 40 +0.101440520082671 + 50 +131.0937856248721 + 51 +151.0996267706195 + 73 + 0 + 72 + 2 + 10 +2.251259362016389 + 20 +0.3028621870346081 + 40 +0.1621751716283119 + 50 +151.1623473832895 + 51 +165.7835266974244 + 73 + 0 + 72 + 1 + 10 +2.094050840588399 + 20 +0.2630342184309034 + 11 +2.026516093204943 + 21 +0.5201225784624666 + 72 + 1 + 10 +2.026516093204943 + 20 +0.5201225784624666 + 11 +2.026516093204943 + 21 +0.5201225784624666 + 97 + 1 +330 +89 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C7 +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 23 + 72 + 1 + 10 +2.401085080890193 + 20 +0.451391475175396 + 11 +2.401085080890193 + 21 +0.502049385078848 + 72 + 1 + 10 +2.401085080890193 + 20 +0.502049385078848 + 11 +2.456975906310984 + 21 +0.5208364345932495 + 72 + 1 + 10 +2.456975906310984 + 20 +0.5208364345932495 + 11 +2.471953186325706 + 21 +0.6169178168015124 + 72 + 1 + 10 +2.471953186325706 + 20 +0.6169178168015124 + 11 +2.547828939245814 + 21 +0.6169178168015124 + 72 + 1 + 10 +2.547828939245814 + 20 +0.6169178168015124 + 11 +2.547828939245814 + 21 +0.5208364345932495 + 72 + 1 + 10 +2.547828939245814 + 20 +0.5208364345932495 + 11 +2.625120227777072 + 21 +0.5208364345932495 + 72 + 1 + 10 +2.625120227777072 + 20 +0.5208364345932495 + 11 +2.625120227777072 + 21 +0.451391475175396 + 72 + 1 + 10 +2.625120227777072 + 20 +0.451391475175396 + 11 +2.547828939245814 + 21 +0.451391475175396 + 72 + 1 + 10 +2.547828939245814 + 20 +0.451391475175396 + 11 +2.547828939245814 + 21 +0.312977967787312 + 72 + 2 + 10 +2.756375078424425 + 20 +0.3106349819782397 + 40 +0.208559300317214 + 50 +179.3563172584847 + 51 +187.5204775666663 + 73 + 1 + 72 + 2 + 10 +2.610407599922477 + 20 +0.2901879066221412 + 40 +0.0611824171745163 + 50 +186.4276465021346 + 51 +204.9884326299174 + 73 + 1 + 72 + 2 + 10 +2.591486060141609 + 20 +0.2832478516776391 + 40 +0.0411355950463604 + 50 +207.3607300982318 + 51 +249.4822289731461 + 73 + 1 + 72 + 2 + 10 +2.925871745813213 + 20 +1.236527392855755 + 40 +1.05135264976578 + 50 +250.6239679589966 + 51 +252.369953071448 + 73 + 1 + 72 + 2 + 10 +2.632025513918952 + 20 +0.3027146749676596 + 40 +0.0724554546479011 + 50 +250.172060625216 + 51 +260.9268652271251 + 73 + 1 + 72 + 1 + 10 +2.620599646309214 + 20 +0.2311657933719365 + 11 +2.620599646309214 + 21 +0.1752767944487085 + 72 + 1 + 10 +2.620599646309214 + 20 +0.1752767944487085 + 11 +2.541405756150071 + 21 +0.1752767944487085 + 72 + 2 + 10 +2.539541691321775 + 20 +0.2586536504670411 + 40 +0.0833976909583584 + 50 +88.71924580725035 + 51 +114.8723068619946 + 73 + 0 + 72 + 2 + 10 +2.534259066943731 + 20 +0.2435901096002027 + 40 +0.0675271066805567 + 50 +116.1816665503854 + 51 +146.3117142175992 + 73 + 0 + 72 + 2 + 10 +2.571816472169667 + 20 +0.2671405893161746 + 40 +0.1118470865035182 + 50 +146.9451672649385 + 51 +168.4294027765594 + 73 + 0 + 72 + 2 + 10 +2.701886448180166 + 20 +0.2953352474010394 + 40 +0.2449337665542188 + 50 +168.070822892956 + 51 +180.7890266060776 + 73 + 0 + 72 + 1 + 10 +2.456975906310984 + 20 +0.2987081511619036 + 11 +2.456975906310984 + 21 +0.451391475175396 + 72 + 1 + 10 +2.456975906310984 + 20 +0.451391475175396 + 11 +2.401085080890193 + 21 +0.451391475175396 + 72 + 1 + 10 +2.401085080890193 + 20 +0.451391475175396 + 11 +2.401085080890193 + 21 +0.451391475175396 + 97 + 1 +330 +58 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C8 +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 22 + 72 + 1 + 10 +2.66863653221009 + 20 +0.1752767944487085 + 11 +2.66863653221009 + 21 +0.6839852852251591 + 72 + 1 + 10 +2.66863653221009 + 20 +0.683985285225159 + 11 +2.758774186932835 + 21 +0.683985285225159 + 72 + 1 + 10 +2.758774186932835 + 20 +0.683985285225159 + 11 +2.758774186932835 + 21 +0.4832608134831443 + 72 + 2 + 10 +2.970884692343786 + 20 +0.1949308647558484 + 40 +0.3579455626750722 + 50 +233.6598667174819 + 51 +241.6737203338166 + 73 + 0 + 72 + 2 + 10 +2.862953103918855 + 20 +0.398321949096261 + 40 +0.1277046941848677 + 50 +241.0008951743301 + 51 +256.9710241053807 + 73 + 0 + 72 + 2 + 10 +2.867314180648163 + 20 +0.3596725627348979 + 40 +0.1664021752218955 + 50 +258.5084157090225 + 51 +270.4610700343784 + 73 + 0 + 72 + 2 + 10 +2.871155730201377 + 20 +0.4023028257494028 + 40 +0.1237918213330042 + 50 +268.8416672957483 + 51 +290.1493812176847 + 73 + 0 + 72 + 2 + 10 +2.88549439287798 + 20 +0.4438925273392474 + 40 +0.0798129708700709 + 50 +290.7705399537808 + 51 +319.3693426350027 + 73 + 0 + 72 + 2 + 10 +2.86973875277353 + 20 +0.4329212526250472 + 40 +0.0989334609539707 + 50 +320.4891190671877 + 51 +345.2499775321184 + 73 + 0 + 72 + 2 + 10 +2.778017766714932 + 20 +0.4084074663129932 + 40 +0.1938734483480787 + 50 +345.1454837561613 + 51 +360.9319474711875 + 73 + 0 + 72 + 1 + 10 +2.971865569256112 + 20 +0.4052541467398021 + 11 +2.971865569256112 + 21 +0.1752767944487085 + 72 + 1 + 10 +2.971865569256112 + 20 +0.1752767944487085 + 11 +2.881012536321281 + 21 +0.1752767944487085 + 72 + 1 + 10 +2.881012536321281 + 20 +0.1752767944487085 + 11 +2.881012536321281 + 21 +0.4064428922369056 + 72 + 2 + 10 +2.802613036220481 + 20 +0.4076912084297279 + 40 +0.0784094376294883 + 50 +359.0877849241664 + 51 +374.2114110518409 + 73 + 1 + 72 + 2 + 10 +2.840775464266772 + 20 +0.4174522933113873 + 40 +0.0390186755568009 + 50 +14.07416101436572 + 51 +38.19979694511947 + 73 + 1 + 72 + 2 + 10 +2.848474408609313 + 20 +0.4228438207727886 + 40 +0.0296388733419943 + 50 +39.21298268016682 + 51 +68.21300572178883 + 73 + 1 + 72 + 2 + 10 +2.843635884024977 + 20 +0.4091395078042849 + 40 +0.0441641298463429 + 50 +68.98305490508943 + 51 +91.1922266305568 + 73 + 1 + 72 + 2 + 10 +2.839517556631515 + 20 +0.3257194842430624 + 40 +0.1276147049428117 + 50 +88.56339333889899 + 51 +108.8133720429226 + 73 + 1 + 72 + 2 + 10 +2.853071660183995 + 20 +0.3106172986056333 + 40 +0.146497457591775 + 50 +111.9279820567162 + 51 +129.7021521663467 + 73 + 1 + 72 + 1 + 10 +2.759489565144921 + 20 +0.4233288622047228 + 11 +2.759489565144921 + 21 +0.1752767944487085 + 72 + 1 + 10 +2.759489565144921 + 20 +0.1752767944487085 + 11 +2.66863653221009 + 21 +0.1752767944487085 + 72 + 1 + 10 +2.66863653221009 + 20 +0.1752767944487085 + 11 +2.66863653221009 + 21 +0.1752767944487085 + 97 + 1 +330 +9C + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1C9 +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 2 + 92 + 1 + 93 + 30 + 72 + 2 + 10 +3.480235470402663 + 20 +0.3472963994916086 + 40 +0.4596602087851077 + 50 +179.2201999001178 + 51 +188.5904259084221 + 73 + 0 + 72 + 2 + 10 +3.197121821548028 + 20 +0.3902535820648669 + 40 +0.1733062924357386 + 50 +188.5287545821982 + 51 +206.4053475484388 + 73 + 0 + 72 + 2 + 10 +3.11705169577316 + 20 +0.4290134848926255 + 40 +0.084357328189102 + 50 +207.0116131808711 + 51 +238.088697099355 + 73 + 0 + 72 + 2 + 10 +3.142763881177286 + 20 +0.3846155256577634 + 40 +0.1356468679361114 + 50 +238.7826076590414 + 51 +258.9445942368799 + 73 + 0 + 72 + 2 + 10 +3.174180017272777 + 20 +0.2328628655440478 + 40 +0.2906128032937941 + 50 +258.6028609455173 + 51 +270.7173423227377 + 73 + 0 + 72 + 2 + 10 +3.179378903153711 + 20 +0.2029581738044638 + 40 +0.3204985176522159 + 50 +269.7210247461867 + 51 +277.0776490133664 + 73 + 0 + 72 + 2 + 10 +3.19487528221549 + 20 +0.325267440923209 + 40 +0.1972121016147459 + 50 +276.9881545773719 + 51 +287.1581506174676 + 73 + 0 + 72 + 2 + 10 +3.216601176688156 + 20 +0.3951169191449229 + 40 +0.1240620704779073 + 50 +287.0876504098541 + 51 +300.9508770078876 + 73 + 0 + 72 + 2 + 10 +3.235041042885957 + 20 +0.4262167749073067 + 40 +0.0879070752171545 + 50 +301.0685629566362 + 51 +318.5141019927475 + 73 + 0 + 72 + 2 + 10 +3.22499564771415 + 20 +0.4193627680063226 + 40 +0.0999841621843335 + 50 +319.385148118614 + 51 +335.2909851831404 + 73 + 0 + 72 + 2 + 10 +3.166888025629801 + 20 +0.3924029450769745 + 40 +0.1640411911207218 + 50 +335.2204735203817 + 51 +346.6482421759127 + 73 + 0 + 72 + 2 + 10 +3.055624996630501 + 20 +0.3654957782609082 + 40 +0.2785109168173713 + 50 +346.5482508793785 + 51 +354.5741818072585 + 73 + 0 + 72 + 2 + 10 +2.875033671883636 + 20 +0.3475705203771616 + 40 +0.4599886939454501 + 50 +354.4784226911829 + 51 +360.2208980900725 + 73 + 0 + 72 + 2 + 10 +2.870607305357513 + 20 +0.3438838987998202 + 40 +0.4644155825717984 + 50 +359.7639661566379 + 51 +365.4367125581701 + 73 + 0 + 72 + 2 + 10 +3.058722157859415 + 20 +0.3256690965276672 + 40 +0.2754213630050057 + 50 +5.372287081245953 + 51 +13.41178733975041 + 73 + 0 + 72 + 2 + 10 +3.173279534978716 + 20 +0.2978741757969097 + 40 +0.1575418848528468 + 50 +13.24247481022931 + 51 +24.91433399135224 + 73 + 0 + 72 + 2 + 10 +3.231958966651797 + 20 +0.27049353879938 + 40 +0.0927888674313799 + 50 +24.84449572776762 + 51 +41.46851456153065 + 73 + 0 + 72 + 2 + 10 +3.239204814111471 + 20 +0.2661434323058576 + 40 +0.0844927447051714 + 50 +42.51194694690035 + 51 +60.20982750497873 + 73 + 0 + 72 + 2 + 10 +3.218699140856711 + 20 +0.3022559330899847 + 40 +0.1260208208552961 + 50 +60.27608629427653 + 51 +73.8270512913352 + 73 + 0 + 72 + 2 + 10 +3.195604909472027 + 20 +0.3806255307799783 + 40 +0.207721876247583 + 50 +73.73012549511914 + 51 +83.43439678342133 + 73 + 0 + 72 + 2 + 10 +3.179442499162505 + 20 +0.5160622385854792 + 40 +0.3441188295924385 + 50 +83.33941300651419 + 51 +90.27041510775888 + 73 + 0 + 72 + 2 + 10 +3.176297692891656 + 20 +0.4848041884129171 + 40 +0.3128606426025486 + 50 +89.72150576644664 + 51 +97.22779474957937 + 73 + 0 + 72 + 2 + 10 +3.161234488424673 + 20 +0.3682916110468403 + 40 +0.1953789369211231 + 50 +97.14435294680244 + 51 +107.4227726253624 + 73 + 0 + 72 + 2 + 10 +3.140217093781949 + 20 +0.301699006668967 + 40 +0.1255485308215694 + 50 +107.370753656409 + 51 +121.1811544282885 + 73 + 0 + 72 + 2 + 10 +3.12266212348865 + 20 +0.2723085493673603 + 40 +0.0913151827909786 + 50 +121.3053248468621 + 51 +138.3848687024391 + 73 + 0 + 72 + 2 + 10 +3.130851497778824 + 20 +0.2780987727770228 + 40 +0.1012892502687907 + 50 +139.0126872013657 + 51 +154.2591683716641 + 73 + 0 + 72 + 2 + 10 +3.178025690577206 + 20 +0.3008131945580285 + 40 +0.1536471429745666 + 50 +154.2693808990751 + 51 +165.8118585512815 + 73 + 0 + 72 + 2 + 10 +3.268168571662594 + 20 +0.3240123625755021 + 40 +0.2467269061818614 + 50 +165.7196946403268 + 51 +174.1342043436877 + 73 + 0 + 72 + 2 + 10 +3.413914363535721 + 20 +0.3395635385525735 + 40 +0.3932993037049538 + 50 +174.0504793005304 + 51 +180.2151757775018 + 73 + 0 + 72 + 1 + 10 +3.020617833369073 + 20 +0.3410405807579851 + 11 +3.020617833369073 + 21 +0.3410405807579851 + 97 + 1 +330 +EA + 92 + 16 + 93 + 21 + 72 + 2 + 10 +3.613312704239808 + 20 +0.3052010939876257 + 40 +0.5046836205998101 + 50 +165.4616764010741 + 51 +171.0278758430559 + 73 + 1 + 72 + 2 + 10 +3.374482486528501 + 20 +0.3420916614133984 + 40 +0.2630236606104225 + 50 +170.85201298578 + 51 +179.4517709052564 + 73 + 1 + 72 + 2 + 10 +3.454065240073902 + 20 +0.3382439821810626 + 40 +0.3426534838299237 + 50 +178.9357418182288 + 51 +188.0691336263486 + 73 + 1 + 72 + 2 + 10 +3.195968077288853 + 20 +0.3030278751539043 + 40 +0.0821796951545775 + 50 +189.0181381128171 + 51 +201.4145153112299 + 73 + 1 + 72 + 2 + 10 +3.160411698485469 + 20 +0.2889975802415061 + 40 +0.0439554436806379 + 50 +201.3107480863471 + 51 +220.1489620647889 + 73 + 1 + 72 + 2 + 10 +3.155835095245747 + 20 +0.2843363205812091 + 40 +0.037456749731058 + 50 +219.2127101386138 + 51 +255.6310132773234 + 73 + 1 + 72 + 2 + 10 +3.173261739719343 + 20 +0.3812089223380726 + 40 +0.1358124526943521 + 50 +258.6525891616267 + 51 +271.3702350725942 + 73 + 1 + 72 + 2 + 10 +3.180357139497569 + 20 +0.4692030529375931 + 40 +0.2238008263021876 + 50 +269.0148826539333 + 51 +276.2753625676396 + 73 + 1 + 72 + 2 + 10 +3.197849276399706 + 20 +0.2946920674583943 + 40 +0.0484529004947375 + 50 +278.2717501461559 + 51 +301.2827024261222 + 73 + 1 + 72 + 2 + 10 +3.207811222542081 + 20 +0.2781237012056277 + 40 +0.0291206023535162 + 50 +301.4591386210265 + 51 +342.6827079184772 + 73 + 1 + 72 + 2 + 10 +3.108548338170845 + 20 +0.3127659022243659 + 40 +0.1342419911030445 + 50 +341.1780241039497 + 51 +353.2229122868627 + 73 + 1 + 72 + 2 + 10 +2.967369563098919 + 20 +0.330872680490466 + 40 +0.2765741939881519 + 50 +352.9494162843399 + 51 +360.3822505868774 + 73 + 1 + 72 + 2 + 10 +2.459318552711379 + 20 +0.3411691780724464 + 40 +0.7846645638024574 + 50 +359.3828759745628 + 51 +363.6573187603909 + 73 + 1 + 72 + 2 + 10 +3.092761679710313 + 20 +0.3811941386031558 + 40 +0.1499590652226746 + 50 +3.834298057691928 + 51 +15.98721166096461 + 73 + 1 + 72 + 2 + 10 +3.208394130760695 + 20 +0.4156549366241278 + 40 +0.029335563761804 + 50 +13.48613242730889 + 51 +56.84075856181601 + 73 + 1 + 72 + 2 + 10 +3.195154229476923 + 20 +0.3942423008569769 + 40 +0.0545066495896497 + 50 +57.50110974384233 + 51 +77.84457056043473 + 73 + 1 + 72 + 2 + 10 +3.184009922966737 + 20 +0.344171085093621 + 40 +0.1058024453263516 + 50 +77.65436364628005 + 51 +90.71531793927198 + 73 + 1 + 72 + 2 + 10 +3.180978125261934 + 20 +0.1670204385423348 + 40 +0.2829500192598661 + 50 +89.65354521146901 + 51 +94.33326617565109 + 73 + 1 + 72 + 2 + 10 +3.165070616561166 + 20 +0.3644786832754941 + 40 +0.084859522413094 + 50 +93.69685967486203 + 51 +104.1770246546857 + 73 + 1 + 72 + 2 + 10 +3.15468956905426 + 20 +0.4128867508985087 + 40 +0.0354285831761041 + 50 +107.0749560136262 + 51 +147.5612347538681 + 73 + 1 + 72 + 1 + 10 +3.124789077699108 + 20 +0.4318905695302117 + 11 +3.124789077699108 + 21 +0.4318905695302117 + 97 + 1 +330 +121 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +HATCH + 5 +1CA +330 +1D +100 +AcDbEntity + 8 +TEXT-RED +100 +AcDbHatch + 10 +0.0 + 20 +0.0 + 30 +0.0 +210 +0.0 +220 +0.0 +230 +1.0 + 2 +SOLID + 70 + 1 + 71 + 1 + 91 + 1 + 92 + 1 + 93 + 22 + 72 + 2 + 10 +3.592005824568463 + 20 +0.4022623702532142 + 40 +0.1238324225952604 + 50 +268.8385251676425 + 51 +290.1462390895788 + 73 + 0 + 72 + 2 + 10 +3.606344487245067 + 20 +0.4439223854568978 + 40 +0.0797877541011788 + 50 +290.7832534290268 + 51 +319.3820561102488 + 73 + 0 + 72 + 2 + 10 +3.590581236734105 + 20 +0.4329212526250472 + 40 +0.0989334609539707 + 50 +320.4891190671877 + 51 +345.2499775321184 + 73 + 0 + 72 + 2 + 10 +3.498860250675552 + 20 +0.4084074663130021 + 40 +0.1938734483480326 + 50 +345.1454837561604 + 51 +360.9319474711903 + 73 + 0 + 72 + 1 + 10 +3.692708053216686 + 20 +0.4052541467398021 + 11 +3.692708053216686 + 21 +0.1752767944487085 + 72 + 1 + 10 +3.692708053216686 + 20 +0.1752767944487085 + 11 +3.601870241094878 + 21 +0.1752767944487085 + 72 + 1 + 10 +3.601870241094878 + 20 +0.1752767944487085 + 11 +3.601870241094878 + 21 +0.4064428922369056 + 72 + 2 + 10 +3.523463130587567 + 20 +0.4076338796510298 + 40 +0.0784161554089863 + 50 +359.1297561618085 + 51 +374.2533822894829 + 73 + 1 + 72 + 2 + 10 +3.561625558633858 + 20 +0.4174879054254667 + 40 +0.0390026472343202 + 50 +14.02613509500026 + 51 +38.15177102575402 + 73 + 1 + 72 + 2 + 10 +3.569324502976398 + 20 +0.4228143935386817 + 40 +0.029663379390137 + 50 +39.24772886833219 + 51 +68.2477519099542 + 73 + 1 + 72 + 2 + 10 +3.564485978392062 + 20 +0.4091782819430569 + 40 +0.0441252062777969 + 50 +68.97422263922098 + 51 +91.18339436468834 + 73 + 1 + 72 + 2 + 10 +3.560375261405112 + 20 +0.3257194842430623 + 40 +0.1276147049428117 + 50 +88.56339333889899 + 51 +108.8133720429226 + 73 + 1 + 72 + 2 + 10 +3.573921754551081 + 20 +0.3105686277924473 + 40 +0.1465397674015583 + 50 +111.9181151967782 + 51 +129.6922853064086 + 73 + 1 + 72 + 1 + 10 +3.480332049105495 + 20 +0.4233288622047228 + 11 +3.480332049105495 + 21 +0.1752767944487085 + 72 + 1 + 10 +3.480332049105495 + 20 +0.1752767944487085 + 11 +3.389479016170664 + 21 +0.1752767944487085 + 72 + 1 + 10 +3.389479016170664 + 20 +0.1752767944487085 + 11 +3.389479016170664 + 21 +0.5201225784624666 + 72 + 1 + 10 +3.389479016170664 + 20 +0.5201225784624666 + 11 +3.462264944047086 + 21 +0.5201225784624666 + 72 + 1 + 10 +3.462264944047086 + 20 +0.5201225784624666 + 11 +3.480332049105495 + 21 +0.4832608134831443 + 72 + 2 + 10 +3.692032830344103 + 20 +0.1968176418438357 + 40 +0.3561838168078713 + 50 +233.5331050519283 + 51 +241.6403323622616 + 73 + 0 + 72 + 2 + 10 +3.581912438010629 + 20 +0.4042431550954748 + 40 +0.1213560014894028 + 50 +240.8735520743203 + 51 +257.5360464861715 + 73 + 0 + 72 + 2 + 10 +3.587849834142919 + 20 +0.3698286725878678 + 40 +0.1562493464094038 + 50 +258.1337893490277 + 51 +270.603548530042 + 73 + 0 + 72 + 1 + 10 +3.589495720107105 + 20 +0.5260693501105883 + 11 +3.589495720107105 + 21 +0.5260693501105883 + 97 + 1 +330 +71 + 75 + 0 + 76 + 1 + 98 + 1 + 10 +-0.0349603810164775 + 20 +0.1524455749140718 +1001 +ACAD +1010 +0.0 +1020 +0.0 +1030 +0.0 + 0 +ENDSEC + 0 +SECTION + 2 +OBJECTS + 0 +DICTIONARY + 5 +C +330 +0 +100 +AcDbDictionary +281 + 1 + 3 +ACAD_DETAILVIEWSTYLE +350 +1D4 + 3 +ACAD_GROUP +350 +D + 3 +ACAD_IMAGE_VARS +350 +1B2 + 3 +ACAD_LAYOUT +350 +1A + 3 +ACAD_MLINESTYLE +350 +17 + 3 +ACAD_PLOTSETTINGS +350 +19 + 3 +ACAD_PLOTSTYLENAME +350 +E + 3 +ACAD_SCALELIST +350 +16B + 3 +ACAD_SECTIONVIEWSTYLE +350 +1D5 + 3 +AcDbVariableDictionary +350 +1CF + 3 +APPDATA +350 +1B0 + 3 +DWGPROPS +350 +1D6 + 0 +DICTIONARY + 5 +1B3 +330 +2 +100 +AcDbDictionary +280 + 1 +281 + 1 + 3 +ACAD_LAYERSTATES +360 +1B4 + 3 +ACLYDICTIONARY +360 +1BB + 0 +DICTIONARY + 5 +1D4 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +DICTIONARY + 5 +D +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +RASTERVARIABLES + 5 +1B2 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbRasterVariables + 90 + 0 + 70 + 1 + 71 + 1 + 72 + 0 + 0 +DICTIONARY + 5 +1A +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 3 +Model +350 +1E + 3 +Sheet 1 +350 +1C + 0 +DICTIONARY + 5 +17 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 3 +Standard +350 +18 + 0 +DICTIONARY + 5 +19 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +ACDBDICTIONARYWDFLT + 5 +E +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 3 +Normal +350 +F +100 +AcDbDictionaryWithDefault +340 +F + 0 +DICTIONARY + 5 +16B +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 3 +A0 +350 +16C + 3 +A1 +350 +16D + 3 +A2 +350 +16E + 3 +A3 +350 +16F + 3 +A4 +350 +170 + 3 +A5 +350 +171 + 3 +A6 +350 +172 + 3 +A7 +350 +173 + 3 +A8 +350 +174 + 3 +A9 +350 +175 + 3 +B0 +350 +176 + 3 +B1 +350 +177 + 3 +B2 +350 +178 + 3 +B3 +350 +179 + 3 +B4 +350 +17A + 3 +B5 +350 +17B + 3 +B6 +350 +17C + 3 +B7 +350 +17D + 3 +B8 +350 +17E + 3 +B9 +350 +17F + 3 +C0 +350 +180 + 3 +C1 +350 +181 + 3 +C2 +350 +182 + 3 +C3 +350 +183 + 3 +C4 +350 +184 + 3 +C5 +350 +185 + 3 +C6 +350 +186 + 3 +C7 +350 +187 + 3 +C8 +350 +188 + 3 +C9 +350 +189 + 3 +D0 +350 +18A + 3 +D1 +350 +18B + 3 +D2 +350 +18C + 0 +DICTIONARY + 5 +1D5 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +DICTIONARY + 5 +1CF +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +DICTIONARY + 5 +1B0 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbDictionary +281 + 1 + 0 +XRECORD + 5 +1D6 +102 +{ACAD_REACTORS +330 +C +102 +} +330 +C +100 +AcDbXrecord +280 + 1 + 1 +DWGPROPS COOKIE + 2 +vector-text + 3 + + 4 +Jonathan Greig + 6 +Generated outlines with CNCFontFab using the "Exo Bold" font. + 7 +MicroPython Text + 8 + + 9 + +300 += +301 += +302 += +303 += +304 += +305 += +306 += +307 += +308 += +309 += + 40 +0.0 + 41 +2456662.519745903 + 42 +2456662.532164352 + 1 + + 90 + 0 + 0 +DICTIONARY + 5 +1B4 +102 +{ACAD_REACTORS +330 +1B3 +102 +} +330 +1B3 +100 +AcDbDictionary +281 + 1 + 3 +ARGON_LAYERP_1 +350 +1B5 + 3 +ARGON_LAYERP_2 +350 +1B8 + 3 +ARGON_LAYERP_3 +350 +1C3 + 0 +DICTIONARY + 5 +1BB +102 +{ACAD_REACTORS +330 +1B3 +102 +} +330 +1B3 +100 +AcDbDictionary +281 + 1 +1001 +ACAD +1000 + Date: Sat, 4 Jan 2014 13:55:24 +0000 Subject: [PATCH 06/25] Improve configurability for native x64/thumb emitter. With MICROPY_EMIT_X64 and MICROPY_EMIT_THUMB disabled, the respective emitters and assemblers will not be included in the code. This can significantly reduce binary size for unix version. --- py/asmthumb.c | 5 +++++ py/asmx64.c | 6 ++++++ py/compile.c | 7 ++++++- py/emitcpy.c | 1 + py/emitnative.c | 4 ++-- unix/Makefile | 4 ++-- 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/py/asmthumb.c b/py/asmthumb.c index ee8041ac9f..ba95d80c68 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -7,6 +7,9 @@ #include "mpconfig.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_FIT16(x) (((x) & 0xffff0000) == 0) #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)); } } + +#endif // MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB diff --git a/py/asmx64.c b/py/asmx64.c index c425034ba0..ed9ca80f5c 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -6,6 +6,10 @@ #include "misc.h" #include "asmx64.h" +#include "mpconfig.h" + +// wrapper around everything in this file +#if MICROPY_EMIT_X64 #if defined(__OpenBSD__) || defined(__MACH__) #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)); */ } + +#endif // MICROPY_EMIT_X64 diff --git a/py/compile.c b/py/compile.c index 68ac20804d..8db7c6d942 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3083,11 +3083,13 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { // compile pass 2 and 3 #if !MICROPY_EMIT_CPYTHON emit_t *emit_bc = NULL; +#if MICROPY_EMIT_NATIVE emit_t *emit_native = NULL; #endif #if MICROPY_EMIT_INLINE_THUMB emit_inline_asm_t *emit_inline_thumb = NULL; #endif +#endif // !MICROPY_EMIT_CPYTHON for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) { if (false) { // dummy @@ -3115,6 +3117,8 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { comp->emit_method_table = &emit_cpython_method_table; #else switch (s->emit_options) { + +#if MICROPY_EMIT_NATIVE case EMIT_OPT_NATIVE_PYTHON: case EMIT_OPT_VIPER: #if MICROPY_EMIT_X64 @@ -3131,6 +3135,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { comp->emit = emit_native; comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER); break; +#endif // MICROPY_EMIT_NATIVE default: if (emit_bc == NULL) { @@ -3140,7 +3145,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { comp->emit_method_table = &emit_bc_method_table; break; } -#endif +#endif // !MICROPY_EMIT_CPYTHON // compile pass 2 and pass 3 compile_scope(comp, s, PASS_2); diff --git a/py/emitcpy.c b/py/emitcpy.c index 652617cc88..7b2d50fb7e 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -13,6 +13,7 @@ #include "runtime0.h" #include "emit.h" +// wrapper around everything in this file #if MICROPY_EMIT_CPYTHON struct _emit_t { diff --git a/py/emitnative.c b/py/emitnative.c index a29922d96c..cc00c57319 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -34,7 +34,7 @@ #include "runtime.h" // 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 @@ -1319,4 +1319,4 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_yield_from, }; -#endif // N_X64 || N_THUMB +#endif // (MICROPY_EMIT_X64 && N_X64) || (MICROPY_EMIT_THUMB && N_THUMB) diff --git a/unix/Makefile b/unix/Makefile index 38d6ba8e15..a5c6ddcc04 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -83,10 +83,10 @@ $(BUILD)/%.o: $(PYSRC)/%.S $(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h $(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 $@ $< -$(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 $@ $< # optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster) From eb7bfcb28697f6fb2d4d933bc39233aa15423a20 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 15:57:35 +0000 Subject: [PATCH 07/25] Split qstr into pools, and put initial pool in ROM. Qstr's are now split into a linked-list of qstr pools. This has 2 benefits: the first pool can be in ROM (huge benefit, since we no longer use RAM for the core qstrs), and subsequent pools use m_new for the next pool instead of m_renew (thus avoiding a huge single table for all the qstrs). Still would be better to use a hash table, but this scheme takes us part of the way (eventually convert the pools to hash tables). Also fixed bug with import. Also improved the way the module code is referenced (not magic number 1 anymore). --- py/builtin.c | 25 ++++---- py/builtinimport.c | 5 +- py/compile.c | 76 ++++++++-------------- py/mpqstr.h | 13 ++++ py/mpqstrraw.h | 63 ++++++++++++++++++ py/obj.c | 13 ++-- py/objclass.c | 7 +- py/objdict.c | 3 +- py/objfun.c | 11 ++-- py/objgenerator.c | 3 +- py/objinstance.c | 3 +- py/objlist.c | 3 +- py/objstr.c | 7 +- py/qstr.c | 101 ++++++++++++++++++++++------- py/runtime.c | 155 ++++++++++++++++++--------------------------- py/runtime.h | 15 ----- py/runtime0.h | 2 +- stm/main.c | 3 +- unix/main.c | 7 ++ 19 files changed, 294 insertions(+), 221 deletions(-) create mode 100644 py/mpqstr.h create mode 100644 py/mpqstrraw.h diff --git a/py/builtin.c b/py/builtin.c index d29a2bf8c3..b565ed4640 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -8,6 +8,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -91,7 +92,7 @@ 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)); + 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)); } } @@ -147,7 +148,7 @@ mp_obj_t mp_builtin_chr(mp_obj_t o_in) { str[1] = '\0'; return mp_obj_new_str(qstr_from_str_take(str, 2)); } 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)")); } } @@ -165,7 +166,7 @@ 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); return rt_build_tuple(2, revs_args); } 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))); } } @@ -235,7 +236,7 @@ mp_obj_t mp_builtin_len(mp_obj_t o_in) { } else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) { len = mp_obj_dict_len(o_in); } 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); } @@ -254,7 +255,7 @@ mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args) { } 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)); + 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)); } } @@ -270,7 +271,7 @@ mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) { } } 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; } else { @@ -297,7 +298,7 @@ mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) { } } 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; } else { @@ -315,7 +316,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) { mp_obj_t ret = rt_iternext(o); 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 { return ret; } @@ -328,7 +329,7 @@ mp_obj_t mp_builtin_ord(mp_obj_t o_in) { if (strlen(str) == 1) { return mp_obj_new_int(str[0]); } 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 +337,7 @@ mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) { switch (n_args) { 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... - 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,7 +363,7 @@ 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 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])); - 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)); } } @@ -391,7 +392,7 @@ mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) { switch (n_args) { case 1: value = mp_obj_new_int(0); 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 item; diff --git a/py/builtinimport.c b/py/builtinimport.c index 47dbf21216..90a0fc3394 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -58,7 +58,9 @@ mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) { 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 rt_locals_set(old_locals); 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 - 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; if (nlr_push(&nlr) == 0) { rt_call_function_0(module_fun); diff --git a/py/compile.c b/py/compile.c index 8db7c6d942..f8fa2cb2c2 100644 --- a/py/compile.c +++ b/py/compile.c @@ -7,6 +7,7 @@ #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "lexer.h" #include "parse.h" #include "scope.h" @@ -38,20 +39,6 @@ typedef enum { #define EMIT_OPT_ASM_THUMB (4) 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; pass_kind_t pass; 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) { - 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->next = 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) 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; } @@ -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]); - if (attr == comp->qstr_byte_code) { + if (attr == MP_QSTR_byte_code) { *emit_options = EMIT_OPT_BYTE_CODE; #if MICROPY_EMIT_NATIVE - } else if (attr == comp->qstr_native) { + } else if (attr == MP_QSTR_native) { *emit_options = EMIT_OPT_NATIVE_PYTHON; - } else if (attr == comp->qstr_viper) { + } else if (attr == MP_QSTR_viper) { *emit_options = EMIT_OPT_VIPER; #endif #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; #endif } 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) { int l_end = comp_next_label(comp); c_if_cond(comp, pns->nodes[0], true, l_end); - EMIT(load_id, comp->qstr_assertion_error); + EMIT(load_id, MP_QSTR_assertion_error); if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // assertion message 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 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]; - 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 *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 (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) { // 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]); EMIT(call_function, 1, 0, false, false); 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) { compile_node(comp, pns->nodes[0]); // a 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) { 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); 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); id_info->kind = ID_INFO_KIND_LOCAL; id_info->param = true; scope->num_params = 1; // __locals__ is the parameter } - EMIT(load_id, comp->qstr___locals__); + EMIT(load_id, MP_QSTR___locals__); EMIT(store_locals); - EMIT(load_id, comp->qstr___name__); - EMIT(store_id, comp->qstr___module__); + EMIT(load_id, MP_QSTR___name__); + EMIT(store_id, MP_QSTR___module__); 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]); 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); if (id->kind == ID_INFO_KIND_LOCAL) { EMIT(load_const_tok, MP_TOKEN_KW_NONE); } else { #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 - 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 } EMIT(return_value); @@ -2917,7 +2904,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) { scope->num_locals = 0; for (int i = 0; i < scope->id_info_len; 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 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) { 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->had_error = false; @@ -3048,10 +3021,10 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { pn = fold_constants(pn); // 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 - 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_inline_asm = NULL; comp->emit_inline_asm_method_table = NULL; @@ -3162,10 +3135,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, bool is_repl) { } else { #if MICROPY_EMIT_CPYTHON // can't create code, so just return true + (void)module_scope; // to suppress warning that module_scope is unused return mp_const_true; #else // 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 } } diff --git a/py/mpqstr.h b/py/mpqstr.h new file mode 100644 index 0000000000..1440fb3b80 --- /dev/null +++ b/py/mpqstr.h @@ -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; diff --git a/py/mpqstrraw.h b/py/mpqstrraw.h new file mode 100644 index 0000000000..85cf1ff7bd --- /dev/null +++ b/py/mpqstrraw.h @@ -0,0 +1,63 @@ +// 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(assertion_error) +Q(micropython) +Q(byte_code) +Q(native) +Q(viper) +Q(asm_thumb) + +Q(StopIteration) + +Q(AttributeError) +Q(IndexError) +Q(KeyError) +Q(NameError) +Q(TypeError) +Q(SyntaxError) +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(type) + +Q(append) +Q(pop) +Q(sort) +Q(join) +Q(format) diff --git a/py/obj.c b/py/obj.c index d88d0ac3d7..2b834ffe43 100644 --- a/py/obj.c +++ b/py/obj.c @@ -7,6 +7,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -144,7 +145,7 @@ machine_float_t mp_obj_get_float(mp_obj_t arg) { } else if (MP_OBJ_IS_TYPE(arg, &float_type)) { return mp_obj_float_get(arg); } 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)) { mp_obj_complex_get(arg, real, imag); } 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 @@ -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); } 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; } 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; } 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; } 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))); } } diff --git a/py/objclass.c b/py/objclass.c index 203923a722..f223c5ff25 100644 --- a/py/objclass.c +++ b/py/objclass.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime.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); // 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) { // 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); } 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 { // TODO 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)); } } diff --git a/py/objdict.c b/py/objdict.c index 50ce279040..acf1a9f801 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -42,7 +43,7 @@ mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // dict load mp_map_elem_t *elem = mp_map_lookup_helper(&o->map, rhs_in, false); if (elem == NULL) { - nlr_jump(mp_obj_new_exception_msg(rt_q_KeyError, "")); + nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "")); } else { return elem->value; } diff --git a/py/objfun.c b/py/objfun.c index e998bd28d2..c4783867a5 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "map.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 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 @@ -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 if (n_args < self->n_args_min) { - nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "() missing %d required positional arguments: ", (const char*)(machine_int_t)(self->n_args_min - n_args))); + nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "() missing %d required positional arguments: ", (const char*)(machine_int_t)(self->n_args_min - n_args))); } else if (n_args > self->n_args_max) { - nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, " 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, " 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 @@ -141,7 +142,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; 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 @@ -250,7 +251,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; 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; diff --git a/py/objgenerator.c b/py/objgenerator.c index ecdd72dc6d..849212269b 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime.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; mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code); 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); diff --git a/py/objinstance.c b/py/objinstance.c index e5d23af2d5..6cfcdf6c15 100644 --- a/py/objinstance.c +++ b/py/objinstance.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime.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; } } - 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) { diff --git a/py/objlist.c b/py/objlist.c index e371057981..30d3a41e4a 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -81,7 +82,7 @@ static mp_obj_t list_pop(int n_args, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(args[0], &list_type)); mp_obj_list_t *self = args[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]); mp_obj_t ret = self->items[index]; diff --git a/py/objstr.c b/py/objstr.c index 54e6f37705..03a761863f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -7,6 +7,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -61,7 +62,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } 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(rt_q_TypeError, "index must be int")); + nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "index must be int")); } case RT_BINARY_OP_ADD: @@ -134,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)); 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, ...) { @@ -158,7 +159,7 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) { vstr_add_char(vstr, '{'); } else if (*str == '}') { 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]); arg_i++; diff --git a/py/qstr.c b/py/qstr.c index 0dd8a04b70..0ed7aa9a24 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -2,55 +2,110 @@ #include #include "misc.h" +#include "mpqstr.h" -static int qstrs_alloc; -static int qstrs_len; -static const char **qstrs; +// NOTE: we are using linear arrays to store and search for qstr's (unique strings, interned strings) +// ultimately we will replace this with a static hash table of some kind +// also probably need to include the length in the string data, to allow null bytes in the string + +#if 0 // print debugging info +#include +#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) { - qstrs_alloc = 400; - qstrs_len = 1; - qstrs = m_new(const char*, qstrs_alloc); - qstrs[0] = "nil"; + // nothing to do! } static qstr qstr_add(const char *str) { - if (qstrs_len >= qstrs_alloc) { - qstrs = m_renew(const char*, qstrs, qstrs_alloc, qstrs_alloc * 2); - qstrs_alloc *= 2; + DEBUG_printf("QSTR: add %s\n", str); + + // 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) { - for (int i = 0; i < qstrs_len; i++) { - if (strcmp(qstrs[i], str) == 0) { - return i; + for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) { + for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) { + if (strcmp(*qstr, str) == 0) { + return pool->total_prev_len + (qstr - pool->qstrs); + } } } return qstr_add(str); } qstr qstr_from_str_take(char *str, int alloc_len) { - for (int i = 0; i < qstrs_len; i++) { - if (strcmp(qstrs[i], str) == 0) { - m_del(char, str, alloc_len); - return i; + for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) { + 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); + return pool->total_prev_len + (qstr - pool->qstrs); + } } } return qstr_add(str); } qstr qstr_from_strn_copy(const char *str, int len) { - for (int i = 0; i < qstrs_len; i++) { - if (strncmp(qstrs[i], str, len) == 0 && qstrs[i][len] == '\0') { - return i; + for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) { + for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) { + if (strncmp(*qstr, str, len) == 0 && (*qstr)[len] == '\0') { + return pool->total_prev_len + (qstr - pool->qstrs); + } } } return qstr_add(strndup(str, len)); } +// convert qstr id to pointer to its string 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]; } diff --git a/py/runtime.c b/py/runtime.c index 3144321f3a..a1f9ee3b7b 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -11,6 +11,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" #include "runtime.h" @@ -27,22 +28,6 @@ #define DEBUG_OP_printf(args...) (void)0 #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 static mp_map_t *map_locals; static mp_map_t *map_globals; @@ -83,74 +68,58 @@ FILE *fp_write_code = NULL; #endif 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()) 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 mp_map_init(&map_builtins, MP_MAP_QSTR, 3); // 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, rt_q_IndexError, true)->value = mp_obj_new_exception(rt_q_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, rt_q_NameError, true)->value = mp_obj_new_exception(rt_q_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, rt_q_SyntaxError, true)->value = mp_obj_new_exception(rt_q_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_AttributeError, true)->value = mp_obj_new_exception(MP_QSTR_AttributeError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_IndexError, true)->value = mp_obj_new_exception(MP_QSTR_IndexError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_KeyError, true)->value = mp_obj_new_exception(MP_QSTR_KeyError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_NameError, true)->value = mp_obj_new_exception(MP_QSTR_NameError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_TypeError, true)->value = mp_obj_new_exception(MP_QSTR_TypeError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_SyntaxError, true)->value = mp_obj_new_exception(MP_QSTR_SyntaxError); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_ValueError, true)->value = mp_obj_new_exception(MP_QSTR_ValueError); // 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, qstr_from_str_static("__repl_print__"), true)->value = rt_make_function_1(mp_builtin___repl_print__); + 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, MP_QSTR___repl_print__, true)->value = rt_make_function_1(mp_builtin___repl_print__); // built-in user functions - 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, 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); + 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_bool, true)->value = rt_make_function_var(0, mp_builtin_bool); + 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); #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)&mp_builtin_complex_obj; #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, qstr_from_str_static("divmod"), true)->value = rt_make_function_2(mp_builtin_divmod); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_dict, true)->value = rt_make_function_0(mp_builtin_dict); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_divmod, true)->value = rt_make_function_2(mp_builtin_divmod); #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)&mp_builtin_float_obj; #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, qstr_from_str_static("int"), true)->value = (mp_obj_t)&mp_builtin_int_obj; - 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, qstr_from_str_static("len"), true)->value = rt_make_function_1(mp_builtin_len); - 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, 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; + 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_int, true)->value = (mp_obj_t)&mp_builtin_int_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_list, true)->value = rt_make_function_var(0, mp_builtin_list); + 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_set, true)->value = (mp_obj_t)&mp_builtin_set_obj; + mp_qstr_map_lookup(&map_builtins, MP_QSTR_sum, true)->value = rt_make_function_var(1, mp_builtin_sum); + mp_qstr_map_lookup(&map_builtins, MP_QSTR_type, true)->value = (mp_obj_t)&mp_builtin_type_obj; - - 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; #ifdef WRITE_CODE @@ -166,12 +135,8 @@ void rt_deinit(void) { #endif } -int rt_get_unique_code_id(bool is_main_module) { - if (is_main_module) { - return 1; - } else { - return next_unique_code_id++; - } +int rt_get_unique_code_id(void) { + return next_unique_code_id++; } static void alloc_unique_codes(void) { @@ -186,7 +151,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) { 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].n_args = n_args; unique_codes[unique_code_id].n_locals = n_locals; @@ -355,7 +320,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) { } } 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) { exp_val = -exp_val; @@ -373,7 +338,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) { return mp_obj_new_float(dec_val); } #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 } @@ -391,7 +356,7 @@ mp_obj_t rt_load_name(qstr qstr) { if (elem == NULL) { elem = mp_qstr_map_lookup(&map_builtins, qstr, false); 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 +370,7 @@ mp_obj_t rt_load_global(qstr qstr) { if (elem == NULL) { elem = mp_qstr_map_lookup(&map_builtins, qstr, false); 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; @@ -413,9 +378,9 @@ mp_obj_t rt_load_global(qstr qstr) { mp_obj_t rt_load_build_class(void) { 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) { - 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; } @@ -465,7 +430,7 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) { } } // 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 +509,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 - 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) { @@ -693,13 +658,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); 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 { mp_obj_base_t *fun = fun_in; if (fun->type->call_n != NULL) { return fun->type->call_n(fun_in, n_args, args); } 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 +721,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); } 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) { - 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)); } else { // 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 +772,12 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr 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) { 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[0] = base; return; @@ -850,7 +815,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_qstr_map_lookup(globals, attr, true)->value = value; } 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 +834,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) { 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 { mp_obj_base_t *o = o_in; if (o->type->getiter != NULL) { return o->type->getiter(o_in); } 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) { 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 { mp_obj_base_t *o = o_in; if (o->type->iternext != NULL) { return o->type->iternext(o_in); } 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)); } } } diff --git a/py/runtime.h b/py/runtime.h index cf9180275e..96f1671f67 100644 --- a/py/runtime.h +++ b/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); mp_obj_t rt_load_const_dec(qstr qstr); diff --git a/py/runtime0.h b/py/runtime0.h index 8ec2c058f0..97dbe5ddbc 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -81,7 +81,7 @@ extern void *const rt_fun_table[RT_F_NUMBER_OF]; void rt_init(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_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); diff --git a/stm/main.c b/stm/main.c index e8db2be2ca..b7ae8aacca 100644 --- a/stm/main.c +++ b/stm/main.c @@ -15,6 +15,7 @@ #include "misc.h" #include "ff.h" #include "mpconfig.h" +#include "mpqstr.h" #include "nlr.h" #include "misc.h" #include "lexer.h" @@ -621,7 +622,7 @@ mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) { } 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); diff --git a/unix/main.c b/unix/main.c index 1aa3331202..e73f69ee24 100644 --- a/unix/main.c +++ b/unix/main.c @@ -217,6 +217,13 @@ int main(int argc, char **argv) { 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) { do_repl(); } else if (argc == 2) { From 5830fae26f7dfeb7a263ba5e1b024694930c64ff Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 18:55:44 +0200 Subject: [PATCH 08/25] Don't error out if build/ directory already exists. --- stm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm/Makefile b/stm/Makefile index e84e21eae2..729913baee 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -162,7 +162,7 @@ $(BUILD)/flash.elf: $(OBJ) arm-none-eabi-size $@ $(BUILD): - mkdir $@ + mkdir -p $@ $(BUILD)/%.o: %.s $(AS) -o $@ $< From 21dfb55dadb01b135edca9b66ca6b53a82bec60a Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 19:06:34 +0200 Subject: [PATCH 09/25] tests/basics requires python3.3 tests/bytecode/run-tests already uses puthon3.3, so let's just use it here too. Fore reference, errors with python 3.2.3: File "tests/generator1.py", line 12 return None SyntaxError: 'return' with argument inside generator File "tests/list_clear.py", line 3, in x.clear() AttributeError: 'list' object has no attribute 'clear' etc. --- tests/basics/run-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basics/run-tests b/tests/basics/run-tests index 72e69c2d8e..0037b13045 100755 --- a/tests/basics/run-tests +++ b/tests/basics/run-tests @@ -1,7 +1,7 @@ #!/usr/bin/env bash RM="/bin/rm -f" -CPYTHON3=python3 +CPYTHON3=python3.3 MP_PY=../../unix/py numtests=0 From 9464cde3c94b1c69a9cf433d8b0ac8a7c78f8bf1 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 19:12:05 +0200 Subject: [PATCH 10/25] Unbreak string slice test by just switching to normal (not byte) strings. --- tests/basics/tests/slice-bstr1.py | 32 ------------------------------ tests/basics/tests/string-slice.py | 32 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 32 deletions(-) delete mode 100644 tests/basics/tests/slice-bstr1.py create mode 100644 tests/basics/tests/string-slice.py diff --git a/tests/basics/tests/slice-bstr1.py b/tests/basics/tests/slice-bstr1.py deleted file mode 100644 index 74dbc20617..0000000000 --- a/tests/basics/tests/slice-bstr1.py +++ /dev/null @@ -1,32 +0,0 @@ -print(b"123"[0:1]) - -print(b"123"[0:2]) - -print(b"123"[:1]) - -print(b"123"[1:]) - -# Idiom for copying sequence -print(b"123"[:]) - -print(b"123"[:-1]) - -# Weird cases -print(b"123"[0:0]) -print(b"123"[1:0]) -print(b"123"[1:1]) -print(b"123"[-1:-1]) -print(b"123"[-3:]) -print(b"123"[-3:3]) -print(b"123"[0:]) -print(b"123"[:0]) -print(b"123"[:-3]) -print(b"123"[:-4]) -# Range check testing, don't segfault, please ;-) -print(b"123"[:1000000]) -print(b"123"[1000000:]) -print(b"123"[:-1000000]) -print(b"123"[-1000000:]) -# No IndexError! -print(b""[1:1]) -print(b""[-1:-1]) diff --git a/tests/basics/tests/string-slice.py b/tests/basics/tests/string-slice.py new file mode 100644 index 0000000000..7538ae5700 --- /dev/null +++ b/tests/basics/tests/string-slice.py @@ -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]) From d674bd59890b8f63e6f67415a2107900562a645b Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 19:38:19 +0200 Subject: [PATCH 11/25] Convert USE_READLINE config option to be consistent with others. --- unix/Makefile | 2 +- unix/main.c | 4 ++-- unix/mpconfigport.h | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/unix/Makefile b/unix/Makefile index a5c6ddcc04..c7be62e999 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -2,7 +2,7 @@ PYSRC=../py BUILD=build 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 SRC_C = \ diff --git a/unix/main.c b/unix/main.c index e73f69ee24..ecb2fa338e 100644 --- a/unix/main.c +++ b/unix/main.c @@ -15,7 +15,7 @@ #include "runtime.h" #include "repl.h" -#ifdef USE_READLINE +#if MICROPY_USE_READLINE #include #include #endif @@ -35,7 +35,7 @@ static char *str_join(const char *s1, int sep_char, const char *s2) { } static char *prompt(char *p) { -#ifdef USE_READLINE +#if MICROPY_USE_READLINE char *line = readline(p); if (line) { add_history(line); diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index 36cf138c17..7a4622b8b6 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -1,5 +1,10 @@ // 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_EMIT_CPYTHON (0) #define MICROPY_EMIT_X64 (1) From e9906ac3d771a312b05d76e42aee8e806dd0d128 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 18:44:46 +0000 Subject: [PATCH 12/25] Add ellipsis object. --- py/bc0.h | 16 ++++++++++------ py/emitbc.c | 1 + py/grammar.h | 8 ++++---- py/lexer.c | 2 +- py/lexer.h | 2 +- py/mpqstrraw.h | 1 + py/obj.h | 1 + py/objslice.c | 29 +++++++++++++++++++++++++++++ py/runtime.c | 3 +++ py/showbc.c | 4 ++++ py/vm.c | 4 ++++ 11 files changed, 59 insertions(+), 12 deletions(-) diff --git a/py/bc0.h b/py/bc0.h index 773e23d2ea..0a4a49ce66 100644 --- a/py/bc0.h +++ b/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_NONE (0x11) #define MP_BC_LOAD_CONST_TRUE (0x12) -#define MP_BC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess -#define MP_BC_LOAD_CONST_INT (0x14) // qstr -#define MP_BC_LOAD_CONST_DEC (0x15) // qstr -#define MP_BC_LOAD_CONST_ID (0x16) // qstr -#define MP_BC_LOAD_CONST_BYTES (0x17) // qstr -#define MP_BC_LOAD_CONST_STRING (0x18) // qstr +#define MP_BC_LOAD_CONST_ELLIPSIS (0x13) +#define MP_BC_LOAD_CONST_SMALL_INT (0x14) // 24-bit, in excess +#define MP_BC_LOAD_CONST_INT (0x15) // qstr +#define MP_BC_LOAD_CONST_DEC (0x16) // qstr +#define MP_BC_LOAD_CONST_ID (0x17) // 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_1 (0x21) diff --git a/py/emitbc.c b/py/emitbc.c index dc1988582c..c0ec2469a6 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -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_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_ELLIPSIS: emit_write_byte_1(emit, MP_BC_LOAD_CONST_ELLIPSIS); break; default: assert(0); } } diff --git a/py/grammar.h b/py/grammar.h index b1faab79e1..4d53bd3fc4 100644 --- a/py/grammar.h +++ b/py/grammar.h @@ -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_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_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_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(period_or_ellipses, nc, or(2), tok(DEL_PERIOD), tok(ELLIPSES)) +DEF_RULE(one_or_more_period_or_ellipsis, nc, one_or_more, rule(period_or_ellipsis)) +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(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)) @@ -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))* [','] ) // 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(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)) diff --git a/py/lexer.c b/py/lexer.c index 4df91b0365..d4205236c3 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -239,7 +239,7 @@ static const uint8_t tok_enc_kind[] = { MP_TOKEN_OP_CARET, MP_TOKEN_DEL_CARET_EQUAL, MP_TOKEN_DEL_EQUAL, MP_TOKEN_OP_DBL_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 diff --git a/py/lexer.h b/py/lexer.h index 27244fde96..3cb48ce9e1 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -20,7 +20,7 @@ typedef enum _mp_token_kind_t { MP_TOKEN_STRING, MP_TOKEN_BYTES, - MP_TOKEN_ELLIPSES, + MP_TOKEN_ELLIPSIS, MP_TOKEN_KW_FALSE, // 12 MP_TOKEN_KW_NONE, diff --git a/py/mpqstrraw.h b/py/mpqstrraw.h index 85cf1ff7bd..e73bd828eb 100644 --- a/py/mpqstrraw.h +++ b/py/mpqstrraw.h @@ -20,6 +20,7 @@ Q(native) Q(viper) Q(asm_thumb) +Q(Ellipsis) Q(StopIteration) Q(AttributeError) diff --git a/py/obj.h b/py/obj.h index 16c7c36dd1..f0ba6999e9 100644 --- a/py/obj.h +++ b/py/obj.h @@ -110,6 +110,7 @@ extern const mp_obj_type_t mp_const_type; extern const mp_obj_t mp_const_none; extern const mp_obj_t mp_const_false; extern const mp_obj_t mp_const_true; +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!) // Need to declare this here so we are not dependent on map.h diff --git a/py/objslice.c b/py/objslice.c index 03607e4c3e..d99325fd73 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -9,6 +9,35 @@ #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, // 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. diff --git a/py/runtime.c b/py/runtime.c index a1f9ee3b7b..72881067d4 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -84,6 +84,9 @@ void rt_init(void) { mp_qstr_map_lookup(&map_builtins, MP_QSTR_SyntaxError, true)->value = mp_obj_new_exception(MP_QSTR_SyntaxError); 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 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, MP_QSTR___repl_print__, true)->value = rt_make_function_1(mp_builtin___repl_print__); diff --git a/py/showbc.c b/py/showbc.c index a3bfa2833b..eb7d41b24d 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -46,6 +46,10 @@ void mp_show_byte_code(const byte *ip, int len) { printf("LOAD_CONST_TRUE"); break; + case MP_BC_LOAD_CONST_ELLIPSIS: + printf("LOAD_CONST_ELLIPSIS"); + break; + case MP_BC_LOAD_CONST_SMALL_INT: unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000; ip += 3; diff --git a/py/vm.c b/py/vm.c index 382780640b..8e7ef7485b 100644 --- a/py/vm.c +++ b/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); break; + case MP_BC_LOAD_CONST_ELLIPSIS: + PUSH(mp_const_ellipsis); + break; + case MP_BC_LOAD_CONST_SMALL_INT: unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000; ip += 3; From 5d02e2d6fa3afcd8aa9ecb475b0c4599da6ca03d Mon Sep 17 00:00:00 2001 From: Mikael Eiman Date: Sat, 4 Jan 2014 20:15:04 +0100 Subject: [PATCH 13/25] OSX: fixes to make nlrx64.S with Apple's clang --- py/nlrx64.S | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/py/nlrx64.S b/py/nlrx64.S index 6d0e2118f7..37d3137785 100644 --- a/py/nlrx64.S +++ b/py/nlrx64.S @@ -5,9 +5,14 @@ .text /* uint nlr_push(rdi=nlr_buf_t *nlr) */ +#ifndef __llvm__ .globl nlr_push .type nlr_push, @function nlr_push: +#else + .globl _nlr_push +_nlr_push: +#endif movq (%rsp), %rax # load return %rip movq %rax, 16(%rdi) # store %rip into nlr_buf movq %rbp, 24(%rdi) # store %rbp into nlr_buf @@ -22,22 +27,32 @@ nlr_push: movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list) xorq %rax, %rax # return 0, normal return ret # return - .size nlr_push, .-nlr_push +// .size nlr_push, .-nlr_push /* void nlr_pop() */ +#ifndef __llvm__ .globl nlr_pop .type nlr_pop, @function nlr_pop: +#else + .globl _nlr_pop +_nlr_pop: +#endif movq nlr_top(%rip), %rax # get nlr_top into %rax movq (%rax), %rax # load prev nlr_buf movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list) ret # return - .size nlr_pop, .-nlr_pop +// .size nlr_pop, .-nlr_pop /* void nlr_jump(rdi=uint val) */ +#ifndef __llvm__ .globl nlr_jump .type nlr_jump, @function nlr_jump: +#else + .globl _nlr_jump + _nlr_jump: +#endif movq %rdi, %rax # put return value in %rax movq nlr_top(%rip), %rdi # get nlr_top into %rdi movq %rax, 8(%rdi) # store return value @@ -55,8 +70,12 @@ nlr_jump: xorq %rax, %rax # clear return register inc %al # increase to make 1, non-local return ret # return +#ifndef __llvm__ .size nlr_jump, .-nlr_jump +#endif +#ifndef __llvm__ .local nlr_top +#endif .comm nlr_top,8,8 #endif From f53cdd947cacbe273bcef0c68ced83162a16a24a Mon Sep 17 00:00:00 2001 From: Mikael Eiman Date: Sat, 4 Jan 2014 20:19:19 +0100 Subject: [PATCH 14/25] OSX: fixes to make nlrx64.S with Apple's clang (forgot a few places) --- py/nlrx64.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/py/nlrx64.S b/py/nlrx64.S index 37d3137785..20a3704fd4 100644 --- a/py/nlrx64.S +++ b/py/nlrx64.S @@ -27,7 +27,9 @@ _nlr_push: movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list) xorq %rax, %rax # return 0, normal return ret # return -// .size nlr_push, .-nlr_push +#ifndef __llvm__ + .size nlr_push, .-nlr_push +#endif /* void nlr_pop() */ #ifndef __llvm__ @@ -42,7 +44,9 @@ _nlr_pop: movq (%rax), %rax # load prev nlr_buf movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list) ret # return -// .size nlr_pop, .-nlr_pop +#ifndef __llvm__ + .size nlr_pop, .-nlr_pop +#endif /* void nlr_jump(rdi=uint val) */ #ifndef __llvm__ From d67091371da5fed82547988864577928e8468b8e Mon Sep 17 00:00:00 2001 From: Mikael Eiman Date: Sat, 4 Jan 2014 20:27:13 +0100 Subject: [PATCH 15/25] OSX: fixes to make nlrx64.S with Apple's clang (switched to Apple-specific define instead of __llvm__) --- py/nlrx64.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/py/nlrx64.S b/py/nlrx64.S index 20a3704fd4..441817b4f3 100644 --- a/py/nlrx64.S +++ b/py/nlrx64.S @@ -5,7 +5,7 @@ .text /* uint nlr_push(rdi=nlr_buf_t *nlr) */ -#ifndef __llvm__ +#ifndef __apple_build_version__ .globl nlr_push .type nlr_push, @function nlr_push: @@ -27,12 +27,12 @@ _nlr_push: movq %rdi, nlr_top(%rip) # stor new nlr_buf (to make linked list) xorq %rax, %rax # return 0, normal return ret # return -#ifndef __llvm__ +#ifndef __apple_build_version__ .size nlr_push, .-nlr_push #endif /* void nlr_pop() */ -#ifndef __llvm__ +#ifndef __apple_build_version__ .globl nlr_pop .type nlr_pop, @function nlr_pop: @@ -44,12 +44,12 @@ _nlr_pop: movq (%rax), %rax # load prev nlr_buf movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list) ret # return -#ifndef __llvm__ +#ifndef __apple_build_version__ .size nlr_pop, .-nlr_pop #endif /* void nlr_jump(rdi=uint val) */ -#ifndef __llvm__ +#ifndef __apple_build_version__ .globl nlr_jump .type nlr_jump, @function nlr_jump: @@ -74,11 +74,11 @@ nlr_jump: xorq %rax, %rax # clear return register inc %al # increase to make 1, non-local return ret # return -#ifndef __llvm__ +#ifndef __apple_build_version__ .size nlr_jump, .-nlr_jump #endif -#ifndef __llvm__ +#ifndef __apple_build_version__ .local nlr_top #endif .comm nlr_top,8,8 From 71c5181a8dfa69ba9f5ca322a3aba0660be2e166 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 20:21:15 +0000 Subject: [PATCH 16/25] Convert Python types to proper Python type hierarchy. Now much more inline with how CPython does types. --- py/builtin.c | 126 +--------------------------------------------- py/compile.c | 2 +- py/emitpass1.c | 5 +- py/mpqstrraw.h | 5 +- py/obj.c | 12 ++--- py/obj.h | 7 +++ py/objbool.c | 14 +++++- py/objboundmeth.c | 1 + py/objcell.c | 1 + py/objclass.c | 1 + py/objclosure.c | 1 + py/objcomplex.c | 45 ++++++++++++++++- py/objdict.c | 11 +++- py/objexcept.c | 1 + py/objfloat.c | 26 ++++++++-- py/objfun.c | 3 ++ py/objgenerator.c | 2 + py/objinstance.c | 1 + py/objlist.c | 25 +++++++++ py/objmodule.c | 1 + py/objnone.c | 1 + py/objrange.c | 2 + py/objset.c | 28 ++++++++++- py/objslice.c | 2 + py/objstr.c | 1 + py/objtuple.c | 76 ++++++++++++++++++++++++---- py/objtype.c | 21 ++++++-- py/runtime.c | 29 ++++++----- stm/Makefile | 1 + stm/i2c.c | 1 + stm/led.c | 1 + stm/main.c | 1 + stm/servo.c | 1 + unix-cpy/Makefile | 1 + unix/Makefile | 1 + unix/main.c | 1 + 36 files changed, 285 insertions(+), 173 deletions(-) diff --git a/py/builtin.c b/py/builtin.c index b565ed4640..6babc76692 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -88,14 +88,6 @@ mp_obj_t mp_builtin_any(mp_obj_t o_in) { 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(MP_QSTR_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) { if (mp_obj_is_callable(o_in)) { return mp_const_true; @@ -104,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) { int ord = mp_obj_get_int(o_in); if (0 <= ord && ord <= 0x10ffff) { @@ -152,11 +108,6 @@ mp_obj_t mp_builtin_chr(mp_obj_t o_in) { } } -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) { 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); @@ -170,25 +121,6 @@ mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t 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) { // TODO hash will generally overflow small integer; can we safely truncate it? return mp_obj_new_int(mp_obj_hash(o_in)); @@ -196,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); -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) { return rt_getiter(o_in); } @@ -241,24 +156,6 @@ mp_obj_t mp_builtin_len(mp_obj_t o_in) { 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(MP_QSTR_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) { if (n_args == 1) { // given an iterable @@ -367,26 +264,6 @@ mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *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 value; switch (n_args) { @@ -405,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) { // TODO implement the 3 argument version of type() if (MP_OBJ_IS_SMALL_INT(o_in)) { - // TODO implement int-type - return mp_const_none; + return (mp_obj_t)&int_type; } else { mp_obj_base_t *o = o_in; return (mp_obj_t)o->type; diff --git a/py/compile.c b/py/compile.c index f8fa2cb2c2..0e19890315 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1316,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) { int l_end = comp_next_label(comp); c_if_cond(comp, pns->nodes[0], true, l_end); - EMIT(load_id, MP_QSTR_assertion_error); + EMIT(load_id, MP_QSTR_AssertionError); if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // assertion message compile_node(comp, pns->nodes[1]); diff --git a/py/emitpass1.c b/py/emitpass1.c index 1c11241e0d..f78ec7e27e 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -7,6 +7,7 @@ #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "lexer.h" #include "parse.h" #include "scope.h" @@ -44,9 +45,9 @@ static void emit_pass1_load_id(emit_t *emit, qstr qstr) { bool added; id_info_t *id = scope_find_or_add_id(emit->scope, qstr, &added); if (added) { - if (strcmp(qstr_str(qstr), "AssertionError") == 0) { - id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT; + if (qstr == MP_QSTR_AssertionError) { // 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) { // special case, super is a global, and also counts as use of __class__ id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT; diff --git a/py/mpqstrraw.h b/py/mpqstrraw.h index e73bd828eb..fe74c3e927 100644 --- a/py/mpqstrraw.h +++ b/py/mpqstrraw.h @@ -13,7 +13,6 @@ Q(__next__) Q(__qualname__) Q(__repl_print__) -Q(assertion_error) Q(micropython) Q(byte_code) Q(native) @@ -23,12 +22,13 @@ Q(asm_thumb) Q(Ellipsis) Q(StopIteration) +Q(AssertionError) Q(AttributeError) Q(IndexError) Q(KeyError) Q(NameError) -Q(TypeError) Q(SyntaxError) +Q(TypeError) Q(ValueError) Q(abs) @@ -55,6 +55,7 @@ Q(print) Q(range) Q(set) Q(sum) +Q(tuple) Q(type) Q(append) diff --git a/py/obj.c b/py/obj.c index 2b834ffe43..77580e1fee 100644 --- a/py/obj.c +++ b/py/obj.c @@ -13,10 +13,6 @@ #include "runtime.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) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return "int"; @@ -128,9 +124,13 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) { return 1; } else if (MP_OBJ_IS_SMALL_INT(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 { - assert(0); - return 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))); } } diff --git a/py/obj.h b/py/obj.h index f0ba6999e9..03e67dd479 100644 --- a/py/obj.h +++ b/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 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_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); @@ -71,6 +72,7 @@ struct _mp_obj_type_t { mp_obj_base_t base; const char *name; 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_unary_op_fun_t unary_op; // can return NULL if op not supported @@ -110,6 +112,7 @@ extern const mp_obj_type_t mp_const_type; extern const mp_obj_t mp_const_none; extern const mp_obj_t mp_const_false; 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!) @@ -180,6 +183,9 @@ extern const mp_obj_type_t bool_type; 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); +// int +extern const mp_obj_type_t int_type; + // exception extern const mp_obj_type_t exception_type; qstr mp_obj_exception_get_type(mp_obj_t self_in); @@ -214,6 +220,7 @@ 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); // set +extern const mp_obj_type_t set_type; void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item); // slice diff --git a/py/objbool.c b/py/objbool.c index 9b53ffae94..1d94ee03be 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -4,14 +4,16 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" +#include "runtime.h" typedef struct _mp_obj_bool_t { mp_obj_base_t base; bool value; } 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; if (self->value) { 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 = { { &mp_const_type }, "bool", bool_print, // print + bool_make_new, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objboundmeth.c b/py/objboundmeth.c index 8bd238c65e..264c2effd4 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -37,6 +37,7 @@ const mp_obj_type_t bound_meth_type = { { &mp_const_type }, "bound_method", NULL, // print + NULL, // make_new bound_meth_call_n, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objcell.c b/py/objcell.c index cba1980579..daaa340a7f 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -27,6 +27,7 @@ const mp_obj_type_t cell_type = { { &mp_const_type }, "cell", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objclass.c b/py/objclass.c index f223c5ff25..197dfa7268 100644 --- a/py/objclass.c +++ b/py/objclass.c @@ -64,6 +64,7 @@ const mp_obj_type_t class_type = { { &mp_const_type }, "class", NULL, // print + NULL, // make_new class_call_n, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objclosure.c b/py/objclosure.c index e3354d42d9..550bb5067f 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -36,6 +36,7 @@ const mp_obj_type_t closure_type = { { &mp_const_type }, "closure", NULL, // print + NULL, // make_new closure_call_n, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objcomplex.c b/py/objcomplex.c index ab9c146774..5408d71cf2 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.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; switch (op) { 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_obj_complex_get(lhs_in, &lhs_real, &lhs_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 }, "complex", complex_print, // print + complex_make_new, // make_new NULL, // call_n complex_unary_op, // unary_op complex_binary_op, // binary_op diff --git a/py/objdict.c b/py/objdict.c index acf1a9f801..3737f5eab0 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -17,7 +17,7 @@ typedef struct _mp_obj_dict_t { mp_map_t map; } 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; bool first = true; print(env, "{"); @@ -35,7 +35,13 @@ void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_ob 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; switch (op) { case RT_BINARY_OP_SUBSCR: @@ -58,6 +64,7 @@ const mp_obj_type_t dict_type = { { &mp_const_type }, "dict", dict_print, // print + dict_make_new, // make_new NULL, // call_n NULL, // unary_op dict_binary_op, // binary_op diff --git a/py/objexcept.c b/py/objexcept.c index e735852c37..ec03b9bf1a 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -39,6 +39,7 @@ const mp_obj_type_t exception_type = { { &mp_const_type }, "exception", exception_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objfloat.c b/py/objfloat.c index f151fe25a0..8fc925e0b6 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -6,6 +6,7 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.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); -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; 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; switch (op) { 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)) { return complex_type.binary_op(op, lhs_in, rhs_in); } @@ -61,6 +80,7 @@ const mp_obj_type_t float_type = { { &mp_const_type }, "float", float_print, + float_make_new, // make_new NULL, // call_n float_unary_op, float_binary_op, diff --git a/py/objfun.c b/py/objfun.c index c4783867a5..22b82a9ca0 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -70,6 +70,7 @@ const mp_obj_type_t fun_native_type = { { &mp_const_type }, "function", NULL, // print + NULL, // make_new fun_native_call_n, // call_n NULL, // unary_op NULL, // binary_op @@ -162,6 +163,7 @@ const mp_obj_type_t fun_bc_type = { { &mp_const_type }, "function", NULL, // print + NULL, // make_new fun_bc_call_n, // call_n NULL, // unary_op NULL, // binary_op @@ -275,6 +277,7 @@ static const mp_obj_type_t fun_asm_type = { { &mp_const_type }, "function", NULL, // print + NULL, // make_new fun_asm_call_n, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objgenerator.c b/py/objgenerator.c index 849212269b..7fbca075e2 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -40,6 +40,7 @@ const mp_obj_type_t gen_wrap_type = { { &mp_const_type }, "generator", NULL, // print + NULL, // make_new gen_wrap_call_n, // call_n NULL, // unary_op NULL, // binary_op @@ -94,6 +95,7 @@ const mp_obj_type_t gen_instance_type = { { &mp_const_type }, "generator", gen_instance_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objinstance.c b/py/objinstance.c index 6cfcdf6c15..fd8cada7cb 100644 --- a/py/objinstance.c +++ b/py/objinstance.c @@ -93,6 +93,7 @@ const mp_obj_type_t instance_type = { { &mp_const_type }, "instance", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objlist.c b/py/objlist.c index 967df44fd6..3018826113 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -36,6 +36,29 @@ static void list_print(void (*print)(void *env, const char *fmt, ...), void *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) { mp_obj_list_t *o = lhs; switch (op) { @@ -165,6 +188,7 @@ const mp_obj_type_t list_type = { { &mp_const_type }, "list", list_print, // print + list_make_new, // make_new NULL, // call_n NULL, // unary_op list_binary_op, // binary_op @@ -242,6 +266,7 @@ static const mp_obj_type_t list_it_type = { { &mp_const_type }, "list_iterator", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objmodule.c b/py/objmodule.c index addab14b75..9263eb44f0 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -25,6 +25,7 @@ const mp_obj_type_t module_type = { { &mp_const_type }, "module", module_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objnone.c b/py/objnone.c index f7b665e997..11dd4939b1 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -18,6 +18,7 @@ const mp_obj_type_t none_type = { { &mp_const_type }, "NoneType", none_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objrange.c b/py/objrange.c index b7fd17fa0a..b163f779b8 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -26,6 +26,7 @@ static const mp_obj_type_t range_type = { { &mp_const_type} , "range", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op @@ -70,6 +71,7 @@ static const mp_obj_type_t range_it_type = { { &mp_const_type }, "range_iterator", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objset.c b/py/objset.c index f225ca7f66..826f8bdc86 100644 --- a/py/objset.c +++ b/py/objset.c @@ -5,7 +5,9 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" +#include "runtime.h" #include "map.h" 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, "}"); } -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 }, "set", set_print, // print + set_make_new, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objslice.c b/py/objslice.c index d99325fd73..a624be9631 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -24,6 +24,7 @@ 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 @@ -58,6 +59,7 @@ const mp_obj_type_t slice_type = { "slice", slice_print, NULL, // call_n + NULL, // make_new NULL, // unary_op NULL, // binary_op NULL, // getiter diff --git a/py/objstr.c b/py/objstr.c index 03a761863f..27c9440d03 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -179,6 +179,7 @@ const mp_obj_type_t str_type = { { &mp_const_type }, "str", str_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op str_binary_op, // binary_op diff --git a/py/objtuple.c b/py/objtuple.c index b98d6ede7b..d55259d1a6 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -1,13 +1,14 @@ #include #include -//#include #include #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" #include "runtime0.h" +#include "runtime.h" typedef struct _mp_obj_tuple_t { 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 */ -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; print(env, "("); 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, ")"); } -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; switch (op) { 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); } -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 = { { &mp_const_type }, "tuple", tuple_print, // print + tuple_make_new, // make_new NULL, // call_n NULL, // unary_op tuple_binary_op, // binary_op @@ -72,7 +109,14 @@ const mp_obj_type_t tuple_type = { {{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) { + 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); o->base.type = &tuple_type; 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) { + 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); o->base.type = &tuple_type; o->len = n; @@ -92,6 +139,12 @@ mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items) { 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 */ @@ -101,7 +154,7 @@ typedef struct _mp_obj_tuple_it_t { machine_uint_t cur; } 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; if (self->cur < self->tuple->len) { 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 }, "tuple_iterator", NULL, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/py/objtype.c b/py/objtype.c index 83ae48d2d1..aeeaebb95d 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -4,17 +4,30 @@ #include "nlr.h" #include "misc.h" #include "mpconfig.h" +#include "mpqstr.h" #include "obj.h" -void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { - print(env, ""); +static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + mp_obj_type_t *self = self_in; + print(env, "", 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 = { { &mp_const_type }, - "", + "type", type_print, // print - NULL, // call_n + NULL, // make_new + type_call_n, // call_n NULL, // unary_op NULL, // binary_op NULL, // getiter diff --git a/py/runtime.c b/py/runtime.c index 72881067d4..197c08b55a 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -91,26 +91,31 @@ void rt_init(void) { 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, 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, MP_QSTR_bool, true)->value = (mp_obj_t)&bool_type; +#if MICROPY_ENABLE_FLOAT + mp_qstr_map_lookup(&map_builtins, MP_QSTR_complex, true)->value = (mp_obj_t)&complex_type; +#endif + mp_qstr_map_lookup(&map_builtins, MP_QSTR_dict, true)->value = (mp_obj_t)&dict_type; +#if MICROPY_ENABLE_FLOAT + mp_qstr_map_lookup(&map_builtins, MP_QSTR_float, true)->value = (mp_obj_t)&float_type; +#endif + mp_qstr_map_lookup(&map_builtins, MP_QSTR_int, true)->value = (mp_obj_t)&int_type; + mp_qstr_map_lookup(&map_builtins, MP_QSTR_list, true)->value = (mp_obj_t)&list_type; + mp_qstr_map_lookup(&map_builtins, MP_QSTR_set, true)->value = (mp_obj_t)&set_type; + mp_qstr_map_lookup(&map_builtins, MP_QSTR_tuple, true)->value = (mp_obj_t)&tuple_type; + mp_qstr_map_lookup(&map_builtins, MP_QSTR_type, true)->value = (mp_obj_t)&mp_builtin_type_obj; // TODO + + // 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_bool, true)->value = rt_make_function_var(0, mp_builtin_bool); 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); -#if MICROPY_ENABLE_FLOAT - mp_qstr_map_lookup(&map_builtins, MP_QSTR_complex, true)->value = (mp_obj_t)&mp_builtin_complex_obj; -#endif - mp_qstr_map_lookup(&map_builtins, MP_QSTR_dict, true)->value = rt_make_function_0(mp_builtin_dict); mp_qstr_map_lookup(&map_builtins, MP_QSTR_divmod, true)->value = rt_make_function_2(mp_builtin_divmod); -#if MICROPY_ENABLE_FLOAT - mp_qstr_map_lookup(&map_builtins, MP_QSTR_float, true)->value = (mp_obj_t)&mp_builtin_float_obj; -#endif 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_int, true)->value = (mp_obj_t)&mp_builtin_int_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_list, true)->value = rt_make_function_var(0, mp_builtin_list); 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; @@ -118,9 +123,7 @@ void rt_init(void) { 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_set, true)->value = (mp_obj_t)&mp_builtin_set_obj; mp_qstr_map_lookup(&map_builtins, MP_QSTR_sum, true)->value = rt_make_function_var(1, mp_builtin_sum); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_type, true)->value = (mp_obj_t)&mp_builtin_type_obj; next_unique_code_id = 1; // 0 indicates "no code" unique_codes = NULL; diff --git a/stm/Makefile b/stm/Makefile index 729913baee..d75c945bfc 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -73,6 +73,7 @@ PY_O = \ objfun.o \ objgenerator.o \ objinstance.o \ + objint.o \ objlist.o \ objmodule.o \ objnone.o \ diff --git a/stm/i2c.c b/stm/i2c.c index e00cf41309..3f29f02c0c 100644 --- a/stm/i2c.c +++ b/stm/i2c.c @@ -330,6 +330,7 @@ static const mp_obj_type_t i2c_obj_type = { { &mp_const_type }, "I2C", i2c_obj_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/stm/led.c b/stm/led.c index 08077641a9..9305716be9 100644 --- a/stm/led.c +++ b/stm/led.c @@ -108,6 +108,7 @@ static const mp_obj_type_t led_obj_type = { { &mp_const_type }, "Led", led_obj_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/stm/main.c b/stm/main.c index b7ae8aacca..0ab44ca8d4 100644 --- a/stm/main.c +++ b/stm/main.c @@ -746,6 +746,7 @@ static const mp_obj_type_t file_obj_type = { { &mp_const_type }, "File", file_obj_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/stm/servo.c b/stm/servo.c index ae421048b9..1e31db5140 100644 --- a/stm/servo.c +++ b/stm/servo.c @@ -141,6 +141,7 @@ static const mp_obj_type_t servo_obj_type = { { &mp_const_type }, "Servo", servo_obj_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op diff --git a/unix-cpy/Makefile b/unix-cpy/Makefile index 7fee3438fb..a1eb9b77e4 100644 --- a/unix-cpy/Makefile +++ b/unix-cpy/Makefile @@ -38,6 +38,7 @@ PY_O = \ objfun.o \ objgenerator.o \ objinstance.o \ + objint.o \ objlist.o \ objmodule.o \ objnone.o \ diff --git a/unix/Makefile b/unix/Makefile index c7be62e999..984f1c3bf3 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -45,6 +45,7 @@ PY_O = \ objfun.o \ objgenerator.o \ objinstance.o \ + objint.o \ objlist.o \ objmodule.o \ objnone.o \ diff --git a/unix/main.c b/unix/main.c index ecb2fa338e..16fcf6ef8d 100644 --- a/unix/main.c +++ b/unix/main.c @@ -192,6 +192,7 @@ static const mp_obj_type_t test_type = { { &mp_const_type }, "Test", test_print, // print + NULL, // make_new NULL, // call_n NULL, // unary_op NULL, // binary_op From 8b2688f893951e93428a91ad8db30b19343febc9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 23:47:11 +0000 Subject: [PATCH 17/25] Add FONT-LICENSE for Exo font used in Micro Python name-logo. --- logo/FONT-LICENSE.txt | 97 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 logo/FONT-LICENSE.txt diff --git a/logo/FONT-LICENSE.txt b/logo/FONT-LICENSE.txt new file mode 100644 index 0000000000..daa919c440 --- /dev/null +++ b/logo/FONT-LICENSE.txt @@ -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. From 45b43c21c4f8e30dcff00c2429eddba20ca002aa Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 01:50:45 +0000 Subject: [PATCH 18/25] Oops: add objint.c --- py/objint.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 py/objint.c diff --git a/py/objint.c b/py/objint.c new file mode 100644 index 0000000000..5bc747e8f0 --- /dev/null +++ b/py/objint.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#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); +} From 8cfc9f07b90c9793ed73d1e67da9124014d794d7 Mon Sep 17 00:00:00 2001 From: xyb Date: Sun, 5 Jan 2014 18:47:51 +0800 Subject: [PATCH 19/25] Implements str iterator --- py/objstr.c | 53 ++++++++++++++++++++++++++++++++++- tests/basics/tests/string1.py | 3 ++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/py/objstr.c b/py/objstr.c index 27c9440d03..a1d139e83a 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -17,6 +17,11 @@ typedef struct _mp_obj_str_t { qstr qstr; } mp_obj_str_t; +static mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur); + +/******************************************************************************/ +/* str */ + void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { mp_obj_str_t *self = self_in; // TODO need to escape chars etc @@ -85,6 +90,10 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { return MP_OBJ_NULL; // op not supported } +static mp_obj_t str_getiter(mp_obj_t o_in) { + return mp_obj_new_str_iterator(o_in, 0); +} + mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(self_in, &str_type)); mp_obj_str_t *self = self_in; @@ -183,7 +192,7 @@ const mp_obj_type_t str_type = { NULL, // call_n NULL, // unary_op str_binary_op, // binary_op - NULL, // getiter + str_getiter, // getiter NULL, // iternext { // method list { "join", &str_join_obj }, @@ -204,3 +213,45 @@ qstr mp_obj_str_get(mp_obj_t self_in) { mp_obj_str_t *self = self_in; return self->qstr; } + +/******************************************************************************/ +/* str iterator */ + +typedef struct _mp_obj_str_it_t { + mp_obj_base_t base; + mp_obj_str_t *str; + machine_uint_t cur; +} mp_obj_str_it_t; + +mp_obj_t str_it_iternext(mp_obj_t self_in) { + mp_obj_str_it_t *self = self_in; + const char *str = qstr_str(self->str->qstr); + if (self->cur < strlen(str)) { + mp_obj_t o_out = mp_obj_new_str(qstr_from_strn_copy(str + self->cur, 1)); + self->cur += 1; + return o_out; + } else { + return mp_const_stop_iteration; + } +} + +static const mp_obj_type_t str_it_type = { + { &mp_const_type }, + "str_iterator", + NULL, // print + NULL, // make_new + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + str_it_iternext, // iternext + { { NULL, NULL }, }, // method str +}; + +mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur) { + mp_obj_str_it_t *o = m_new_obj(mp_obj_str_it_t); + o->base.type = &str_it_type; + o->str = str; + o->cur = cur; + return o; +} diff --git a/tests/basics/tests/string1.py b/tests/basics/tests/string1.py index 28aeaddbc4..9d6f21d132 100644 --- a/tests/basics/tests/string1.py +++ b/tests/basics/tests/string1.py @@ -7,3 +7,6 @@ x += 'def' print(x) print('123' + "456") + +# iter +print(list('str')) From 11f1e4b8f12759e0492626e8d75c79c760d6ffcb Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 11:39:59 +0000 Subject: [PATCH 20/25] Add test for basic builtin types. --- tests/basics/tests/types1.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/basics/tests/types1.py diff --git a/tests/basics/tests/types1.py b/tests/basics/tests/types1.py new file mode 100644 index 0000000000..850b31b08c --- /dev/null +++ b/tests/basics/tests/types1.py @@ -0,0 +1,28 @@ +# basic types + +print(bool) +print(int) +print(float) +print(complex) +print(tuple) +print(list) +print(set) +print(dict) + +print(type(bool()) == bool) +print(type(int()) == int) +print(type(float()) == float) +print(type(complex()) == complex) +print(type(tuple()) == tuple) +print(type(list()) == list) +print(type(set()) == set) +print(type(dict()) == dict) + +print(type(False) == bool) +print(type(0) == int) +print(type(0.0) == float) +print(type(1j) == complex) +print(type(()) == tuple) +print(type([]) == list) +print(type({None}) == set) +print(type({}) == dict) From 1dd657fa87cdfe93ddc30df014a385c801d8dacf Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 11:57:17 +0000 Subject: [PATCH 21/25] Add fatfs readme/license. --- stm/fatfs/00readme.txt | 147 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 stm/fatfs/00readme.txt diff --git a/stm/fatfs/00readme.txt b/stm/fatfs/00readme.txt new file mode 100644 index 0000000000..bd0939ffab --- /dev/null +++ b/stm/fatfs/00readme.txt @@ -0,0 +1,147 @@ +FatFs Module Source Files R0.10 (C)ChaN, 2013 + + +FILES + + ffconf.h Configuration file for FatFs module. + ff.h Common include file for FatFs and application module. + ff.c FatFs module. + diskio.h Common include file for FatFs and disk I/O module. + diskio.c An example of glue function to attach existing disk I/O module to FatFs. + integer.h Integer type definitions for FatFs. + option Optional external functions. + + Low level disk I/O module is not included in this archive because the FatFs + module is only a generic file system layer and not depend on any specific + storage device. You have to provide a low level disk I/O module that written + to control your storage device. + + + +AGREEMENTS + + FatFs module is an open source software to implement FAT file system to + small embedded systems. This is a free software and is opened for education, + research and commercial developments under license policy of following trems. + + Copyright (C) 2013, ChaN, all right reserved. + + * The FatFs module is a free software and there is NO WARRANTY. + * No restriction on use. You can use, modify and redistribute it for + personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * Redistributions of source code must retain the above copyright notice. + + + +REVISION HISTORY + + Feb 26, 2006 R0.00 Prototype + + Apr 29, 2006 R0.01 First release. + + Jun 01, 2006 R0.02 Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + + Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. + + Sep 22, 2006 R0.03 Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + + Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + + Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + + Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) + Fixed an endian sensitive code in f_mkfs. (FatFs) + Added a capability of extending the file size to f_lseek. + Added minimization level 3. + Fixed a problem that can collapse a sector when recreate an + existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) + + May 05, 2007 R0.04b Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (0 < ofs <= csize) collapses the file object. + + Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + + Feb 03, 2008 R0.05a Added f_truncate(). + Added f_utime(). + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read() can be mistruncated. + Fixed cached sector is not flushed when create and close without write. + + Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) + Added string functions: fputc(), fputs(), fprintf() and fgets(). + Improved performance of f_lseek() on move to the same or following cluster. + + Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. + Added long file name support. + Added multiple code page support. + Added re-entrancy for multitask operation. + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + + Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. + Added multiple sector size support. + + Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion for extended characters. + + Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h. + Added a configuration option, _LFN_UNICODE. + Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. + Fixed name matching error on the 13 char boundary. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. + + May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN) + Added file lock feature. (_FS_SHARE) + Added fast seek feature. (_USE_FASTSEEK) + Changed some types on the API, XCHAR->TCHAR. + Changed fname member in the FILINFO structure on Unicode cfg. + String functions support UTF-8 encoding files on Unicode cfg. + + Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) + Added sector erase feature. (_USE_ERASE) + Moved file lock semaphore table from fs object to the bss. + Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. + Fixed f_mkfs() creates wrong FAT32 volume. + + Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). + f_lseek() reports required table size on creating CLMP. + Extended format syntax of f_printf function. + Ignores duplicated directory separators in given path names. + + Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. + Added f_fdisk(). (_MULTI_PARTITION = 2) + + Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16. + Changed f_open() and f_opendir() reject null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. + + Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL == 1) + + Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE) + Added f_closedir(). + Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) + Added forced mount feature with changes of f_mount(). + Improved behavior of volume auto detection. + Improved write throughput of f_puts() and f_printf(). + Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). + Fixed f_write() can be truncated when the file size is close to 4GB. + Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. From de7fcc0c065c6854e02e0146165be0940fd30510 Mon Sep 17 00:00:00 2001 From: mux Date: Sun, 5 Jan 2014 14:52:37 +0200 Subject: [PATCH 22/25] Move user switch code into a separate module * Move user switch code from main.c into a separate module (usrsw) * Add usrsw.c to Makefile --- stm/Makefile | 1 + stm/main.c | 55 +---------------------------------------- stm/usrsw.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ stm/usrsw.h | 7 ++++++ 4 files changed, 78 insertions(+), 54 deletions(-) create mode 100644 stm/usrsw.c create mode 100644 stm/usrsw.h diff --git a/stm/Makefile b/stm/Makefile index d75c945bfc..93e87ec4af 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -36,6 +36,7 @@ SRC_C = \ sdio.c \ pybwlan.c \ i2c.c \ + usrsw.c \ SRC_S = \ startup_stm32f40xx.s \ diff --git a/stm/main.c b/stm/main.c index 0ab44ca8d4..f6aa42abf0 100644 --- a/stm/main.c +++ b/stm/main.c @@ -39,6 +39,7 @@ #include "audio.h" #include "pybwlan.h" #include "i2c.h" +#include "usrsw.h" int errno; @@ -73,52 +74,6 @@ static void impl02_c_version(void) { } } -#define PYB_USRSW_PORT (GPIOA) -#define PYB_USRSW_PIN (GPIO_Pin_13) - -void sw_init(void) { - // make it an input with pull-up - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure); - - // the rest does the EXTI interrupt - - /* Enable SYSCFG clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - - /* Connect EXTI Line13 to PA13 pin */ - SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource13); - - /* Configure EXTI Line13, rising edge */ - EXTI_InitTypeDef EXTI_InitStructure; - EXTI_InitStructure.EXTI_Line = EXTI_Line13; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - /* Enable and set EXTI15_10 Interrupt to the lowest priority */ - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -} - -int sw_get(void) { - if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) { - // pulled high, so switch is not pressed - return 0; - } else { - // pulled low, so switch is pressed - return 1; - } -} - void __fatal_error(const char *msg) { lcd_print_strn("\nFATAL ERROR:\n", 14); lcd_print_strn(msg, strlen(msg)); @@ -156,14 +111,6 @@ mp_obj_t pyb_led(mp_obj_t state) { return state; } -mp_obj_t pyb_sw(void) { - if (sw_get()) { - return mp_const_true; - } else { - return mp_const_false; - } -} - /* void g(uint i) { printf("g:%d\n", i); diff --git a/stm/usrsw.c b/stm/usrsw.c new file mode 100644 index 0000000000..e2565d0e0b --- /dev/null +++ b/stm/usrsw.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "usrsw.h" + +#define PYB_USRSW_PORT (GPIOA) +#define PYB_USRSW_PIN (GPIO_Pin_13) + +void sw_init(void) { + // make it an input with pull-up + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(PYB_USRSW_PORT, &GPIO_InitStructure); + + // the rest does the EXTI interrupt + + /* Enable SYSCFG clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + + /* Connect EXTI Line13 to PA13 pin */ + SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource13); + + /* Configure EXTI Line13, rising edge */ + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_InitStructure.EXTI_Line = EXTI_Line13; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + /* Enable and set EXTI15_10 Interrupt to the lowest priority */ + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +int sw_get(void) { + if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) { + // pulled high, so switch is not pressed + return 0; + } else { + // pulled low, so switch is pressed + return 1; + } +} + +/******************************************************************************/ +/* Micro Python bindings */ + +mp_obj_t pyb_sw(void) { + if (sw_get()) { + return mp_const_true; + } else { + return mp_const_false; + } +} + + diff --git a/stm/usrsw.h b/stm/usrsw.h new file mode 100644 index 0000000000..2833baaac7 --- /dev/null +++ b/stm/usrsw.h @@ -0,0 +1,7 @@ +#ifndef __USRSW_H__ +#define __USRSW_H__ +void sw_init(void); +int sw_get(void); + +mp_obj_t pyb_sw(void); +#endif //__USRSW_H__ From f0691f4ed58cab324dee151886ec13cecc1b6771 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 13:44:06 +0000 Subject: [PATCH 23/25] Fix qstr in objlist.c; add more tests for list.index. list.index fails on an edge case. --- py/objlist.c | 2 +- tests/basics/tests/list_index.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/py/objlist.c b/py/objlist.c index 7b3b6f1772..6c0de405fe 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -194,7 +194,7 @@ static mp_obj_t list_index(int n_args, const mp_obj_t *args) { } } - nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "Object not in list.")); + nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in list")); } static MP_DEFINE_CONST_FUN_OBJ_2(list_append_obj, mp_obj_list_append); diff --git a/tests/basics/tests/list_index.py b/tests/basics/tests/list_index.py index cc853fe0e7..f28263fba6 100644 --- a/tests/basics/tests/list_index.py +++ b/tests/basics/tests/list_index.py @@ -1,12 +1,24 @@ a = [1, 2, 3] +print(a.index(1)) +print(a.index(2)) +print(a.index(3)) +print(a.index(3, 2)) +try: + print(a.index(3, 2, 2)) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") + a = a + a b = [0, 0, a] print(a.index(2)) print(b.index(a)) print(a.index(2, 2)) + try: a.index(2, 2, 2) except ValueError: print("Raised ValueError") else: - raise AssertionError("Did not raise ValueError") + print("Did not raise ValueError") From 823877bce03b5d3848a0d1a7302260dc95e7a9cd Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 14:04:55 +0000 Subject: [PATCH 24/25] stm: rename sw_xx to switch_xx; change Python bindings to new version. --- stm/main.c | 10 +++++----- stm/usrsw.c | 10 +++++----- stm/usrsw.h | 9 +++------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/stm/main.c b/stm/main.c index f6aa42abf0..2121742fd8 100644 --- a/stm/main.c +++ b/stm/main.c @@ -773,7 +773,7 @@ int main(void) { led_state(PYB_LED_G1, 1); // more sub-system init - sw_init(); + switch_init(); storage_init(); //usart_init(); disabled while wi-fi is enabled @@ -822,7 +822,7 @@ soft_reset: rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_0(pyb_gc)); rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_1(pyb_delay)); rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_1(pyb_led)); - rt_store_attr(m, qstr_from_str_static("switch"), rt_make_function_0(pyb_sw)); + rt_store_attr(m, qstr_from_str_static("switch"), (mp_obj_t)&pyb_switch_obj); rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_2(pyb_servo_set)); rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_2(pyb_pwm_set)); rt_store_attr(m, qstr_from_str_static("accel"), (mp_obj_t)&pyb_mma_read_obj); @@ -848,10 +848,10 @@ soft_reset: // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; - if (sw_get()) { + if (switch_get()) { reset_filesystem = true; for (int i = 0; i < 50; i++) { - if (!sw_get()) { + if (!switch_get()) { reset_filesystem = false; break; } @@ -1122,7 +1122,7 @@ soft_reset: data[2] = -2; data[3] = 0; for (;;) { - if (sw_get()) { + if (switch_get()) { data[0] = 0x01; // 0x04 is middle, 0x02 is right } else { data[0] = 0x00; diff --git a/stm/usrsw.c b/stm/usrsw.c index e2565d0e0b..385547843f 100644 --- a/stm/usrsw.c +++ b/stm/usrsw.c @@ -12,7 +12,7 @@ #define PYB_USRSW_PORT (GPIOA) #define PYB_USRSW_PIN (GPIO_Pin_13) -void sw_init(void) { +void switch_init(void) { // make it an input with pull-up GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = PYB_USRSW_PIN; @@ -45,7 +45,7 @@ void sw_init(void) { NVIC_Init(&NVIC_InitStructure); } -int sw_get(void) { +int switch_get(void) { if (PYB_USRSW_PORT->IDR & PYB_USRSW_PIN) { // pulled high, so switch is not pressed return 0; @@ -58,12 +58,12 @@ int sw_get(void) { /******************************************************************************/ /* Micro Python bindings */ -mp_obj_t pyb_sw(void) { - if (sw_get()) { +static mp_obj_t pyb_switch(void) { + if (switch_get()) { return mp_const_true; } else { return mp_const_false; } } - +MP_DEFINE_CONST_FUN_OBJ_0(pyb_switch_obj, pyb_switch); diff --git a/stm/usrsw.h b/stm/usrsw.h index 2833baaac7..2da8f069ba 100644 --- a/stm/usrsw.h +++ b/stm/usrsw.h @@ -1,7 +1,4 @@ -#ifndef __USRSW_H__ -#define __USRSW_H__ -void sw_init(void); -int sw_get(void); +void switch_init(void); +int switch_get(void); -mp_obj_t pyb_sw(void); -#endif //__USRSW_H__ +MP_DECLARE_CONST_FUN_OBJ(pyb_switch_obj); From 12e2656472bf53e467c066eda6f3e177a97210ca Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 5 Jan 2014 14:34:17 +0000 Subject: [PATCH 25/25] stm: allow more flash for the binary. --- stm/stm32f405.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm/stm32f405.ld b/stm/stm32f405.ld index 5dfa8c145d..c19e6a1c19 100644 --- a/stm/stm32f405.ld +++ b/stm/stm32f405.ld @@ -7,7 +7,7 @@ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */ - FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x020000 /* sector 5, 128 KiB */ + FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */ CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */ }