├── .gitignore ├── LICENSE ├── README.md ├── examples ├── Mandelbrot.mkl ├── PPCG_ChessFENScore.mkl ├── PPCG_ISawThatComing.mkl ├── PPCG_JARVIS.mkl ├── PPCG_TypeUniqChars.mkl ├── PPCG_angleBetweenTwoPoints.mkl ├── PPCG_areaOfTriangle.mkl ├── PPCG_disapprovalFace.mkl ├── PPCG_dropsort.mkl ├── PPCG_eliminationGame.mkl ├── PPCG_jQueryHeresy.mkl ├── PPCG_sleepiness.mkl ├── array_test.mkl ├── ascii_star.mkl ├── ascii_star2.mkl ├── boost_test.mkl ├── capitalsWithoutCapitals.mkl ├── collatz.mkl ├── collatz_bent.mkl ├── factorial.mkl ├── fibonacci.mkl ├── helloworld.mkl ├── helloworld_rotated.mkl ├── helloworld_shifted.mkl ├── indexInsert_test.mkl ├── input_test.mkl ├── insertionSort.mkl ├── layer_test.mkl ├── mirror_test.mkl ├── moneyBoost_test.mkl ├── putget_test.mkl ├── quine.mkl ├── range.mkl ├── rotate_test.mkl ├── sortAndSet_example.mkl ├── sortAndSet_some.mkl ├── toggle_math.mkl ├── upsidedownTent.mkl └── wormhole_test.mkl ├── minkolang_0.14.py ├── minkolang_0.15.py ├── oldcode ├── minkolang_0.1.py ├── minkolang_0.10.py ├── minkolang_0.11.py ├── minkolang_0.12.py ├── minkolang_0.13.py ├── minkolang_0.2.py ├── minkolang_0.3.py ├── minkolang_0.4.py ├── minkolang_0.5.py ├── minkolang_0.6.py ├── minkolang_0.7.py ├── minkolang_0.7_debuggable.py ├── minkolang_0.8.py └── minkolang_0.9.py └── remainingCommandsAssigned.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minkolang 2 | ##Current version: 0.9 3 | 4 | - [Introduction](#introduction) 5 | - [How To](#how-to) 6 | - [Instructions](#instructions) 7 | - [Control Structures](#control-structures) 8 | - [Example Programs](#example-programs) 9 | 10 | --- 11 | 12 | ##Introduction 13 | 14 | The Minkowskian (2+1)D semi-golfing language! 15 | 16 | This language was inspired by [Befunge](http://esolangs.org/wiki/Befunge) and [><>](http://esolangs.org/wiki/Fish), both of which are stack-based 2D programming languages. It is a (2+1)D Minkowskian language, meaning that it has two dimensions of space and one dimension of time. When the program counter is not moving through space, it is moving through time (the layers of the program). The program space is toroidal in all directions, meaning that if the program counter moves outside of the program's boundary in spacetime, then it will relocate to the opposite side. 17 | 18 | Minkolang is stack-based like many esolangs, which has an infinite well of `0`s, though it only has one stack, like Befunge and unlike ><>. It *also* has an array where data can be stored, or data can be stored by altering the program's code. Yes, Minkolang too is capable of self-modification. 19 | 20 | --- 21 | 22 | ##How To 23 | 24 | Let's say that `ndN(d2%,7@)Nd+1*3b2:dNd1=?).` is stored in `collatz.mkl` (and that it and `minkolang_0.8.py` are in the same folder). Then you would run this with an input of `13` like this: 25 | 26 |
python minkolang_0.8.py collatz.mkl 13
27 | 28 | --- 29 | 30 | ##Instructions 31 | 32 | ###Implemented 33 | 34 | **Movement** 35 | - `` Lets the program counter move through time (fall to the next layer). 36 | - `#` Net; stops the program counter from moving through time (it's a no-op). 37 | - `v < > ^` Changes the direction of the program counter. 38 | - `/\|_` Mirrors. They act like you would expect. 39 | - `! ? @ &` Trampolines. `! ?` jump one character (`?` jumps if the top of stack is non-zero); `@ &` pop `n` from top of stack and jump `n` characters (`&` is conditional, like `?`). 40 | - `V` Boost; enables the program counter to cross any number of spaces. 41 | - `$` enables the boost permanently until it encounters another `V`. 42 | - `w W` Wormholes; they allow you to jump to any point in the code. `w` pops `y`,`x` off the stack and jumps to `(x,y)` whereas `W` pops `t`,`y`,`x` off the stack and jumps to `(x,y,t)`. 43 | 44 | **Control structures** 45 | - `.` Terminates program. 46 | - `b B` Straight, T branches. 47 | - `$` reverses the branch endpoints (swaps where truthy and falsy go). 48 | - `( )` While loop; takes all of parent's stack and repeats until the stack is empty. 49 | - `$(` pops `n` and puts the top `n` elements of the parent stack into the loop's stack. `$)` pops `n` and repeats if `n` is not zero. 50 | - `[ ]` For loop. Pops `n` and repeats body `n` times. 51 | - `$` Pops `x` and puts the top `x` elements of parent stack into the loop's stack. 52 | - `{ }` [Recursion.](#recursion) 53 | - `$` Starts a new recursion. 54 | - `k` Breaks out of the current loop. (That is, its stack is pushed onto the parent stack.) 55 | 56 | **Literals** 57 | - `0...9` Pushes the corresponding digit onto the stack. 58 | - `"..."` String literal. Minkolang is smart enough to reverse this before pushing on the stack. 59 | - `'...'` Number literal. Does the work of multiplying by 10 and adding the next digit. 60 | 61 | **Math and comparisons** 62 | - `+ - * : ; % ~` Add, subtract (`a-b`), multiply, integer division (`a//b`), exponentiation (`a**b`), modulus (`a%b`), negation. `b` is popped first, then `a` so doing `53-` (for example) intuitively gives `2`, as expected. 63 | - `$` changes these into sum, reverse subtract (`b-a`), product, float division (`a/b`), reverse exponentiation (`b**a`), reverse modulus (`b%a`), and absolute value. 64 | - `= ,` Equality, greater-than (pops `b`,`a`, then pushes `a>b`, so `53` will push 1, as expected), and not. 65 | - `$` changes these into not-equal, `b>a`, and boolean (like Python's `bool()`). 66 | 67 | **Input and output** 68 | - `o O` Input/output character. 69 | - `n N` Input/output number. (`n` dumps non-digits from the input until an integer is found. This is how [this Befunge interpreter](http://www.quirkster.com/iano/js/befunge.html) works.) 70 | 71 | **Stack manipulation** 72 | - `d D` Duplicates top element of stack. `D` pops `n` and duplicates the top of stack `n` times. 73 | - `$` does the same except on the whole stack. So executing `$d` on `[1,2,3]` will give `[1,2,3,1,2,3]`. 74 | - `g G` Stack index/insert. `g` pops `n` and gets the stack's `n`th element and puts it on top of stack. `G` pops `n`,`x` and inserts `x` at the `n`-th position (zero-indexed). 75 | - `c` Stack item copy. Pops `n` and pushes `stack[n]` onto the stack without removing it. 76 | - `$` Stack slice. Pops `k` in addition and pushes `stack[k:n]` onto the stack. So `36$c` on `[0,1,2,3,4,5,6,7,8,9]` will result in `[0,1,2,3,4,5,6,7,8,9,3,4,5]`. 77 | - `i` Gets loop's counter (0-based) and pushes it onto the stack. 78 | - `$` pushes the loop's maximum number of iterations if the current loop is a For loop. 79 | - `I` Pushes the stack's length onto the stack. 80 | - `$` pushes the input string's length onto the stack. 81 | - `r` Reverses stack. 82 | - `$` swaps the top two values of the stack. 83 | - `R` Rotates stack. Pops `n` and rotates clockwise `n` times (may be negative). If the stack is `[1,2,3,4,5]`, then `2R` results in `[4,5,1,2,3]`. 84 | - `s` Sorts the stack. 85 | - `$` pops `n` and sorts the top `n` elements of the stack. 86 | - `S` Removes duplicates. So `"Hello world!"S(O).` will give you `Hel wrd!`. 87 | - `$` pops `n` and removes duplicates from the top `n` elements of the stack. 88 | - `x X` Dump. `x` pops the top of stack and throws it away. `X` pops `n` and throws away the top `n` elements of the stack. 89 | - `$` dumps from the front of the stack. 90 | - `m` Merge. Splits a list in half (if length is odd, the first half is longer) and interleaves the halves. `m` on `[1,2,3,4,5,6,7]` would result in `[1,5,2,6,3,7,4]`. 91 | - `$` pops `n` and merges the top `n` elements of the stack at the front of stack. As in, `3$m` on `[1,2,3,4,5,6,7,8,9]` would result in `[1,7,2,8,3,9,4,5,6]`. 92 | 93 | **Memory and reflection (self-modification)** 94 | - `p P` Puts to code. `p` pops `y`,`x`,`k` and replaces `Code(x,y)` with `k`. `p` pops `t`,`y`,`x`,`k` and replaces `Code(x,y,t)` with `k`. 95 | - `q Q` Gets from code. `q` pops `y`,`x` and puts `Code(x,y)` on top of stack. `Q` pops ``t`,`y`,`x` and puts `Code(x,y,t)` on top of stack. 96 | - `a A` Array get/put. `a` pops `y`,`x` and puts `Array[y][x]` on top of stack. `A` pops `k`,`y`,`x` and writes `k` to `Array[y][x]`. 97 | 98 | **Special** 99 | - `$` Toggles the functionality of many functions. This "toggle flag" only remains active for one step. 100 | - `$` (that is, `$$`) turns on the toggle flag permanently until another `$` is encountered. 101 | - `$$$` Separates layers of a program. See the [layered Hello world! example](#layered-hello-world). 102 | - `u U` Debug (print) the current stack (`u`) and the code and loops (`U`). 103 | 104 | ###To implement 105 | 106 | - `K` Park. Pops `n` and repeats the next instruction `n` times. 107 | - Register where you can store and retrieve one value 108 | - Random integer 109 | - Random direction 110 | - Escape-able characters in strings (so `"\n"` would be a newline) 111 | - Specify a base for a number literal 112 | - `M` Map 113 | - `F` Fold (reduce) 114 | 115 | ###Unassigned: 116 | 117 | - `C` 118 | - `e E` 119 | - `f` 120 | - `h H` 121 | - `j J` 122 | - `k K` 123 | - `l L` 124 | - `t T` 125 | - `y Y` 126 | - `z Z` 127 | 128 | --- 129 | 130 | ##Control Structures 131 | 132 | One significant feature that sets Minkolang apart from Befunge and ><> is that it has loops. Both for loops and while loops. 133 | 134 | ###Loops 135 | 136 | All loops have their own stack, which may have any number of elements from the parent stack (either the main program or a parent loop). Now, very interestingly, the loop's closing brace can be anywhere. When a closing brace is reached, the program counter is relocated to the opening brace and the direction is reset to what it was when the loop was entered. 137 | 138 | - **For loop** `[]`: Pops the top of the stack (`n`) and repeats the loop's contents `n` times. 139 | - **While loop** (take it all) `()`: The parent's whole stack is used to populate this loop's stack, **unless** `$` is used right beforehand, in which case, pops the top of the stack (`n`) and takes the top `n` elements of the parent's stack to populate this loop's stack. Loops until stack is empty or top of stack is 0. 140 | 141 | ###Branches 142 | 143 | Another interesting thing about Minkolang is its branches. There are two kinds of branches: straight branches (`b`) and T branches (`B`). Both kinds pop the top of the stack off and check to see if it's zero. 144 | 145 | - **Straight branch** `b`: a non-zero input will continue on in the same direction whereas a zero input will reverse direction. 146 | 147 |
       v
148 |        0         1
149 | > 0b1  b  1b0 <  b
150 |        1         0
151 |                  ^
152 | 153 | - **T branch** `B`: a non-zero input will bend to the right (clockwise) whereas a zero input will bend to the left (counter-clockwise). 154 | 155 |
  0   v   1
156 | > B  1B0  B <  0B1
157 |   1       0     ^
158 | 159 | ###Recursion 160 | 161 | As far as I know, this is absolutely the only 2D language to have recursion. In Minkolang, `{}` are the control characters. On the first use of `{` (or if `$` was used right before), a recursive function is initialized. This means popping `n` off the top of the stack, which sets the number of arguments to take. The top `n` elements of the parent stack are popped off and used to populate the recursion's stack. This applies to child instances too, which are started when the program counter encounters another `{`. Returning is done by using `}`, which simply plops the instance's stack on top of the parent (often, another recursion instance) stack. 162 | 163 | To put it another way, there are three steps to doing recursion in Minkolang: 164 | 165 | 1. Initialize. For example, if the program counter encounters `3{` and the stack is `[1,2,3,4,5]`, then the recursion's stack will be `[3,4,5]`, and any further children will also take the top three elements of their parent's stack. 166 | 2. Recurse. This is done by using `{` again. The program counter jumps to the very first `{` that started the whole recurrence. 167 | 3. Return. This is done by using `}`. The program counter jumps to the last `{` that was countered and moves from there. 168 | 169 | This is certainly a bit complicated, but try working through the [Fibonacci example](#fibonacci-sequence-recursion) below. Hopefully that'll help. 170 | 171 | --- 172 | 173 | ##Example Programs 174 | 175 | ###Hello world! 176 | 177 |
"Hello world!"(O).
178 | 179 | `"Hello world!"` is pushed onto the stack in reverse order, then `(O)` repeatedly prints the top of stack until it's empty. 180 | 181 | ###Collatz sequence (one line) 182 | 183 |
ndN(d2%,7@)Nd+1*3b2:dNd1=?).
184 | 185 | `ndN` takes the input and duplicates it so it can be output. 186 | 187 | `(d2%,7@.......b` starts a while loop with `[n]` as the stack. It is duplicated and modded by 2. This is inverted and then seven characters are skipped with `7@`, landing it squarely on the `b`. In effect, the program counter moves right if the top of stack is odd, left if it's even. 188 | 189 | `)Nd+1*3` multiplies the top of stack by three, then adds one, and outputs it (duplicated beforehand). The `)` closes the loop. 190 | 191 | `2:dNd1=?).` divides the top of stack by two and outputs it. Then it is checked to see if it's equal to `1`. If so, then the conditional trampoline `?` jumps the program counter over the closing `)` and onto the `.`, where it terminates. Otherwise, it just goes back to the start of the loop. 192 | 193 | ###Collatz sequence (three lines) 194 | 195 |
ndN(d2%,B
196 | ?=1dNd:2<.)
197 |  )Nd+1*3<
198 | 199 | This one works very similarly to the one above. The biggest difference is that the T-branch `B` is used, which directs the program counter either up or down. The toroidal nature of the program space means that the third line is executed when the top of stack is odd. 200 | 201 | ###Fibonacci sequence (recursion) 202 | 203 | This (horribly inefficient) way of calculating the Fibonacci sequence uses its recursive definition: F(n) = F(n-1) + F(n-2) where F(0) = 0 and F(1) = 1. 204 | 205 |
n1{d1`,9&d1-{r2-{+}N.
206 | 207 | `n` takes an integer in input, then the recursive function is initialized with `1{`. The `1` here specifies that the function takes one argument. 208 | 209 | `d1```,9&` looks to see if the top of stack is <= 1. If it is, then it jumps to the closing `}`, which effectively "returns" from the function. This is the base case - where the input is 0 or 1, so F(0 or 1) is the same. 210 | 211 | If the top of stack is *not* 0 or 1, then the trampoline is not taken. Hence, `d1-{` is executed, which duplicates the top of stack, subtracts 1, and runs the function on it. This is the F(n-1) part. 212 | 213 | Once that returns, `r2-{` is executed. This reverses the stack so input is now in front. Then two is subtracted and the function is run again with it as input. This is the F(n-2) part. 214 | 215 | Once *that* returns, then finally, the two values are added together and returned with `+}`. This is the F(n-1) + F(n-2) part. 216 | 217 | At the ultimate conclusion (i.e., when F(n) has been calculated), `N.` outputs F(n) as an integer and exits. 218 | 219 | ###Layered "Hello world!" 220 | 221 |
!v"Hello world!"!
222 | 
223 | $$$
224 | 
225 | $$$
226 | 
227 | V<        .)O(
228 | 229 | This demonstrates how the layers of a program can be separated. The interpreter automatically fills in lines and spaces as needed to make a complete rectangular prism for the code space. The execution is as follows: the first `!` jumps over the `v`, "Hello world!" is pushed onto the stack, then another `!` skips the first one, so the program counter is redirected downward. It lands on a space, so it moves through time (falls) until it hits the `<`. The `V` boosts it across the space to the output loop `.)O(` (normally written as `(O).`). 230 | -------------------------------------------------------------------------------- /examples/Mandelbrot.mkl: -------------------------------------------------------------------------------- 1 | 1~12$:;56*[i53*$:1-0c*99*[di39*$:2-+048*[d$~2`9&d*2c+]02@ik" "+Oxx]25*Ox]. 2 | -------------------------------------------------------------------------------- /examples/PPCG_ChessFENScore.mkl: -------------------------------------------------------------------------------- 1 | 13359$d5[0g~]I"qrbnpQRBNP"m[0p]$I[o0q+]N. 2 | -------------------------------------------------------------------------------- /examples/PPCG_ISawThatComing.mkl: -------------------------------------------------------------------------------- 1 | "|"nd0`u!vbd3*["_"]"|"25*"|"1g["\_/"]"|"(O). 2 | "[d~g1"_"<.)O(" "D*3R~1"_"*52"|"D*3R1dg2"| "*52"|"]"\/_ 3 | -------------------------------------------------------------------------------- /examples/PPCG_JARVIS.mkl: -------------------------------------------------------------------------------- 1 | ndN((d25*%1R25*:)r11(x2~gd4&x1+!*I1-)dNd9`,?). 2 | -------------------------------------------------------------------------------- /examples/PPCG_TypeUniqChars.mkl: -------------------------------------------------------------------------------- 1 | $I[xod0q6&dO1r0p]. 2 | -------------------------------------------------------------------------------- /examples/PPCG_angleBetweenTwoPoints.mkl: -------------------------------------------------------------------------------- 1 | 4[n]0c2c*1c3c*+r4[2;1R]r+1R+0g*12$:;$:8[0ci2*3+d1R;0g$:1i1+[i2*1+d1+$:*]*]$+'3.141592654'25*9;$:$:12$:r-66*5**N. 2 | -------------------------------------------------------------------------------- /examples/PPCG_areaOfTriangle.mkl: -------------------------------------------------------------------------------- 1 | ndndn0g-n1g-n0g-n0g-1R*1R*-$~2$:N. 2 | -------------------------------------------------------------------------------- /examples/PPCG_disapprovalFace.mkl: -------------------------------------------------------------------------------- 1 | "_ಠ"nD0c(O). 2 | -------------------------------------------------------------------------------- /examples/PPCG_dropsort.mkl: -------------------------------------------------------------------------------- 1 | ndN(nd1R`2&dN$I$). 2 | -------------------------------------------------------------------------------- /examples/PPCG_eliminationGame.mkl: -------------------------------------------------------------------------------- 1 | n[n]I${I,3&}N.I[igi+I%0G]I2/$(Ssr0)I2/[gx]{1+}N. 2 | -------------------------------------------------------------------------------- /examples/PPCG_jQueryHeresy.mkl: -------------------------------------------------------------------------------- 1 | #66*68*d5*2:88*5+d5+d7+d1+d3+d4+6[3i+c48*+]2c"N"11-p(od4&k13w35*[dic=,5&kk11w] ) 2 | 725*35*48*68*3+5[66+c2~g2p]27*48*1-d2+d6+d8+5[9c2~g2p]37*67*d8+3[67+c2~g2p]55*57*2[77+c2~g2p]X11-2w 3 | "This p og amm is g ilt of H s . H m st b b nt."(O). 4 | X2546*3[66+c2~g4p]44*d6+47*d3+d2+d8+6[9c2~g4p]X11-4w 5 | "P og am validat d. Cl a anc l v l 2 giv n."(O). 6 | -------------------------------------------------------------------------------- /examples/PPCG_sleepiness.mkl: -------------------------------------------------------------------------------- 1 | >2@fv$oI2:[9[i1+$z3[icizq=]++3=tt"^"3zpt]$x$x]40w 2 | o.o1F 3 | o.=12 4 | =.o1: 5 | =.=13 6 | o.-1[ 7 | -.o1d 8 | =.-1i 9 | -.=1r 10 | -.-1q 11 | ]O< 12 | -------------------------------------------------------------------------------- /examples/array_test.mkl: -------------------------------------------------------------------------------- 1 | 11aN111A11aN. 2 | -------------------------------------------------------------------------------- /examples/ascii_star.mkl: -------------------------------------------------------------------------------- 1 | "/"5D"\"5DI3$[5G]I3$[1G]"_"5DI4$[9i2*-G]2G0G" "3D88+G88+G4G0GI3$[25*63i-*G]r(O). 2 | r(O). 3 | 4 | /\\\////\\\/ 5 | 6 | Output: 7 | _/\_ 8 | \_\/_/ 9 | /_/\_\ 10 | \/ 11 | -------------------------------------------------------------------------------- /examples/ascii_star2.mkl: -------------------------------------------------------------------------------- 1 | '2002670224823664145'25*41p(d6%1qO6:). 2 | _ /\ 3 | -------------------------------------------------------------------------------- /examples/boost_test.mkl: -------------------------------------------------------------------------------- 1 | 1V N. 2 | -------------------------------------------------------------------------------- /examples/capitalsWithoutCapitals.mkl: -------------------------------------------------------------------------------- 1 | 99*32-+58*0p467+35*44*55*d8+d5+(99*2-23-r32-p)"baton rouge, laindianapolis, incolumbus, ohmontgomery, alhelena, mtdenver, coboise, idaustin, txboston, maalbany, nytallahassee, flsanta fe, nmnashville, tntrenton, njjefferson, morichmond, vapierre, sdharrisburg, paaugusta, meprovidence, ridover, deconcord, nhmontpelier, vthartford, cttopeka, kssaint paul, mnjuneau, aklincoln, neraleigh, ncmadison, wiolympia, waphoenix, azlansing, mihonolulu, hijackson, msspringfield, ilcolumbia, scannapolis, mdcheyenne, wysalt lake city, utatlanta, gabismarck, ndfrankfort, kysalem, orlittle rock, ardes moines, iasacramento, caoklahoma city, okcharleston, wvcarson city, nv"032-w 2 | 48*-o(d","=2&o)oo22$[48*-o]d?.25*o48*-o) 3 | -------------------------------------------------------------------------------- /examples/collatz.mkl: -------------------------------------------------------------------------------- 1 | ndN(d2%,7@)Nd+1*3b2:dNd1=?). 2 | -------------------------------------------------------------------------------- /examples/collatz_bent.mkl: -------------------------------------------------------------------------------- 1 | ndN(d2%,B 2 | ?=1dNd:2<.) 3 | )Nd+1*3< 4 | -------------------------------------------------------------------------------- /examples/factorial.mkl: -------------------------------------------------------------------------------- 1 | 1n[i1+*]N. 2 | -------------------------------------------------------------------------------- /examples/fibonacci.mkl: -------------------------------------------------------------------------------- 1 | n1{d1`,9&d1-{r2-{+}N. 2 | -------------------------------------------------------------------------------- /examples/helloworld.mkl: -------------------------------------------------------------------------------- 1 | "Hello world!"(O). 2 | -------------------------------------------------------------------------------- /examples/helloworld_rotated.mkl: -------------------------------------------------------------------------------- 1 | "Hello world!"x5~R3X(O). 2 | -------------------------------------------------------------------------------- /examples/helloworld_shifted.mkl: -------------------------------------------------------------------------------- 1 | "Hello world!"(1+O). 2 | -------------------------------------------------------------------------------- /examples/indexInsert_test.mkl: -------------------------------------------------------------------------------- 1 | "index"3g(O)"inert""s"3G(O). 2 | -------------------------------------------------------------------------------- /examples/input_test.mkl: -------------------------------------------------------------------------------- 1 | nN. 2 | nnNNooOO. 3 | -------------------------------------------------------------------------------- /examples/insertionSort.mkl: -------------------------------------------------------------------------------- 1 | (n$I$)I[i[dic`u3&ik!]G](N). 2 | -------------------------------------------------------------------------------- /examples/layer_test.mkl: -------------------------------------------------------------------------------- 1 | !v"Hello world!"! 2 | 3 | $$$ 4 | 5 | $$$ 6 | 7 | V< .)O( 8 | -------------------------------------------------------------------------------- /examples/mirror_test.mkl: -------------------------------------------------------------------------------- 1 | /\2@|^\ 2 | \/ V 3 | ##1N.>_ 4 | -------------------------------------------------------------------------------- /examples/moneyBoost_test.mkl: -------------------------------------------------------------------------------- 1 | $$V v 2 | /N1V < 3 | \V . 4 | -------------------------------------------------------------------------------- /examples/putget_test.mkl: -------------------------------------------------------------------------------- 1 | "HI"611Pv 2 | >QO55qN! 155p55qN. 3 | $$$ 4 | 5 | 011O" "< 6 | -------------------------------------------------------------------------------- /examples/quine.mkl: -------------------------------------------------------------------------------- 1 | "66*2-(O). 2 | -------------------------------------------------------------------------------- /examples/range.mkl: -------------------------------------------------------------------------------- 1 | n[i]. 2 | -------------------------------------------------------------------------------- /examples/rotate_test.mkl: -------------------------------------------------------------------------------- 1 | 5[i1+](N)25*O5[i1+]1~R(N). 2 | -------------------------------------------------------------------------------- /examples/sortAndSet_example.mkl: -------------------------------------------------------------------------------- 1 | "Hello world!"s(O)25*O\ 2 | "Hello world!"S(O). \ 3 | -------------------------------------------------------------------------------- /examples/sortAndSet_some.mkl: -------------------------------------------------------------------------------- 1 | "Hello world!"8$s(O)25*O\ 2 | "Hello world!"8$S(O)25*O\ 3 | "Hello world!"S(O). \ 4 | -------------------------------------------------------------------------------- /examples/toggle_math.mkl: -------------------------------------------------------------------------------- 1 | nd[i]$+dN\ 2 | (d1-)$*N#\ 3 | 35-N35$-N\ 4 | 35:N35$:N\ 5 | 35;N35$;N\ 6 | 35%N35$%N\ 7 | 25*d*1+dN\ 8 | .O:$2/ 9 | -------------------------------------------------------------------------------- /examples/upsidedownTent.mkl: -------------------------------------------------------------------------------- 1 | "\/_\/"n,2*1+gx25*"_"3D(O). 2 | -------------------------------------------------------------------------------- /examples/wormhole_test.mkl: -------------------------------------------------------------------------------- 1 | 33w .)N(\ 2 | 3 | V 4 | 1234567890/ 5 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "collatz_bent.mkl", "13"] 7 | debug = 1 8 | numSteps = 150 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [ [list(s) for s in code.split("\n")] ] 25 | if debug: print("Code:",self.code) 26 | self.inputStr = inputStr 27 | if debug: print("Input:",self.inputStr) 28 | 29 | self.position = [0,0,0] #[x,y,z] 30 | self.velocity = [1,0,0] #[dx,dy,dz] 31 | 32 | self.stack = [] 33 | self.array = [[]] 34 | self.loops = [] 35 | 36 | self.strLiteral = "" 37 | self.strMode = 0 38 | 39 | self.numLiteral = 0 40 | self.numMode = 0 41 | 42 | self.fallable = 1 43 | self.bounds = [[0,max(map(len,self.code[0]))], 44 | [0,len(self.code[0])], 45 | [0,0]] 46 | if debug: print(self.bounds) 47 | self.currChar = "" 48 | 49 | def run(self, steps=-1): #steps = -1 for run-until-halt 50 | while steps != 0: 51 | steps -= 1 52 | self.getCurrent() 53 | movedir = "" 54 | arg2 = None 55 | 56 | if self.currChar == '"': 57 | self.fallable = not self.fallable 58 | self.strMode = not self.strMode 59 | 60 | if not self.strMode: 61 | self.push(self.strLiteral) 62 | self.strLiteral = "" 63 | if self.currChar == "'": 64 | self.fallable = not self.fallable 65 | self.numMode = not self.numMode 66 | 67 | if not self.numMode: 68 | self.push(self.numLiteral) 69 | self.numLiteral = 0 70 | 71 | if self.currChar not in "'\"": 72 | if not self.strMode and not self.numMode: 73 | stack = self.loops[-1][3] if self.loops else self.stack 74 | 75 | if self.currChar == ".": #stop execution 76 | return 77 | 78 | elif self.fallable and self.currChar == " ": 79 | movedir = "fall" 80 | elif self.currChar in "v<>^": 81 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 82 | 83 | elif self.currChar in "0123456789": 84 | stack.append(int(self.currChar)) 85 | 86 | elif self.currChar in "+-*:;%=`": #operators and comparators 87 | if len(stack) < 2: 88 | stack = [0]*(2-len(stack)) + stack 89 | 90 | b = stack.pop() 91 | a = stack.pop() 92 | 93 | if self.currChar == "+": 94 | stack.append(a+b) 95 | elif self.currChar == "-": 96 | stack.append(a-b) 97 | elif self.currChar == "*": 98 | stack.append(a*b) 99 | elif self.currChar == ":": 100 | stack.append(a//b) 101 | elif self.currChar == ";": 102 | stack.append(a**b) 103 | elif self.currChar == "%": 104 | stack.append(a%b) 105 | elif self.currChar == "=": 106 | stack.append(a==b) 107 | elif self.currChar == "`": 108 | stack.append(a>b) 109 | 110 | ## if debug: print(stack) 111 | 112 | elif self.currChar in "~,": #negation and not 113 | if len(stack) < 1: 114 | stack = [0]*(1-len(stack)) + stack 115 | 116 | b = stack.pop() 117 | 118 | if self.currChar == "~": 119 | stack.append(-b) 120 | elif self.currChar == ",": 121 | stack.append(not b) 122 | 123 | elif self.currChar in "!?@&": 124 | if self.currChar == "!": 125 | movedir = "jump" 126 | arg2 = 1 127 | else: 128 | s = stack.pop() if stack else 0 129 | if self.currChar == "?" and s: 130 | movedir = "jump" 131 | arg2 = 1 132 | elif self.currChar == "@": 133 | movedir = "jump" 134 | arg2 = s 135 | elif self.currChar == "&" and s: 136 | movedir = "jump" 137 | arg2 = stack.pop() 138 | 139 | elif self.currChar in "no": #input 140 | if self.currChar == "n": 141 | beg = 0 142 | while self.inputStr[beg].isalpha(): beg += 1 143 | 144 | end = beg+1 145 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 146 | 147 | stack.append(int(self.inputStr[beg:end-1])) 148 | self.inputStr = self.inputStr[end-1:] 149 | elif self.currChar == "o": 150 | stack.append(ord(self.inputStr[0])) 151 | self.inputStr = self.inputStr[1:] 152 | 153 | elif self.currChar in "NO": #output 154 | tos = stack.pop() if stack else 0 155 | 156 | if self.currChar == "N": 157 | print(tos, end=' ', flush=True) 158 | elif self.currChar == "O": 159 | print(chr(tos), end='', flush=True) 160 | 161 | elif self.currChar in "dD": #duplication 162 | if not stack: stack = [0] 163 | 164 | if self.currChar == "d": 165 | stack.append(stack[-1]) 166 | elif self.currChar == "D": 167 | if len(stack) < 2: stack.append(0) 168 | 169 | n = stack.pop()-1 170 | stack.extend([stack[-1]]*n) 171 | 172 | elif self.currChar in "bB": #branches 173 | tos = stack.pop() if stack else 0 174 | 175 | if self.currChar == "b": 176 | if not tos: self.velocity = [-v for v in self.velocity] 177 | if self.currChar == "B": 178 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 179 | if not tos: self.velocity = [-v for v in self.velocity] 180 | 181 | elif self.currChar in "()": #while loop 182 | if self.currChar == "(": 183 | self.loops.append(["while", 184 | self.position, 185 | self.velocity, 186 | stack[:]]) 187 | 188 | if debug: print(self.loops[-1]) 189 | stack = [] 190 | 191 | elif self.currChar == ")": 192 | if self.loops[-1][0] != "while": 193 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 194 | 195 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3] == 0: 196 | self.push(self.loops[-1][3]) 197 | self.loops.pop() 198 | else: 199 | movedir = "teleport" 200 | arg2 = self.loops[-1][1:3] 201 | if debug: print(self.loops[-1][3]) 202 | 203 | else: 204 | pass 205 | else: 206 | if self.strMode: 207 | self.strLiteral += self.currChar 208 | elif self.numMode: 209 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 210 | 211 | if debug: print(stack) 212 | self.move(movedir, arg2) 213 | 214 | def getCurrent(self): 215 | if debug: print(self.position) 216 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 217 | if debug: print("Current character:",self.currChar) 218 | 219 | def move(self, direction="", arg2=None): 220 | from math import copysign 221 | 222 | if debug: print("Old velocity:",self.velocity) 223 | if direction == "fall": self.velocity = [0,0,1] 224 | if direction == "down": self.velocity = [0,1,0] 225 | if direction == "left": self.velocity = [-1,0,0] 226 | if direction == "right": self.velocity = [1,0,0] 227 | if direction == "up": self.velocity = [0,-1,0] 228 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 229 | if debug: print("New velocity:",self.velocity) 230 | 231 | if direction == "teleport": 232 | self.position, self.velocity = arg2 233 | 234 | ## if debug: print("Old position:",self.position) 235 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 236 | ## if debug: print("New position:",self.position) 237 | 238 | 239 | for i in range(3): 240 | while self.position[i] < self.bounds[i][0]: 241 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 242 | while self.position[i] > self.bounds[i][1]: 243 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 244 | ## if debug: print("New position:",self.position) 245 | 246 | if direction == "jump": 247 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 248 | 249 | def push(self, L): 250 | if type(L) == list: 251 | self.stack.extend(L) 252 | elif type(L) == str: 253 | self.stack.extend(map(ord,L[::-1])) 254 | elif type(L) == int: 255 | self.stack.append(L) 256 | 257 | if debug: 258 | prog = Program(file, sys.argv[2], debugFlag=1) 259 | prog.run(numSteps) 260 | 261 | else: 262 | Program(file, sys.argv[2]).run() 263 | print() 264 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "boost_test.mkl", "5"] 7 | debug = 1 8 | numSteps = 150 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [ [list(s) for s in code.split("\n")] ] 25 | if debug: print("Code:",self.code) 26 | self.inputStr = inputStr 27 | if debug: print("Input:",self.inputStr) 28 | 29 | self.position = [0,0,0] #[x,y,z] 30 | self.velocity = [1,0,0] #[dx,dy,dz] 31 | 32 | self.stack = [] 33 | self.array = [[]] 34 | self.loops = [] 35 | 36 | self.strLiteral = "" 37 | self.strMode = 0 38 | 39 | self.numLiteral = 0 40 | self.numMode = 0 41 | 42 | self.fallable = 1 43 | self.toggleFlag = 0 44 | 45 | self.bounds = [[0,max(map(len,self.code[0]))], 46 | [0,len(self.code[0])], 47 | [0,0]] 48 | if debug: print(self.bounds) 49 | self.currChar = "" 50 | 51 | def run(self, steps=-1): #steps = -1 for run-until-halt 52 | while steps != 0: 53 | steps -= 1 54 | self.getCurrent() 55 | movedir = "" 56 | arg2 = None 57 | stack = self.loops[-1][3] if self.loops else self.stack 58 | 59 | if self.currChar == '"': 60 | self.fallable = not self.fallable 61 | self.strMode = not self.strMode 62 | 63 | if not self.strMode: 64 | ## self.push(self.strLiteral) 65 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 66 | self.strLiteral = "" 67 | if self.currChar == "'": 68 | self.fallable = not self.fallable 69 | self.numMode = not self.numMode 70 | 71 | if not self.numMode: 72 | ## self.push(self.numLiteral) 73 | stack.append(self.numLiteral) 74 | self.numLiteral = 0 75 | 76 | if self.currChar not in "'\"": 77 | if not self.strMode and not self.numMode: 78 | 79 | if self.currChar != " " and not self.fallable: self.fallable = 1 80 | 81 | if self.currChar == ".": #stop execution 82 | return 83 | elif self.currChar == "$": #toggle functionality 84 | self.toggleFlag = 1 85 | elif self.currChar == "V": 86 | self.fallable = 0 87 | elif self.currChar == "#": #net 88 | pass 89 | 90 | elif self.fallable and self.currChar == " ": 91 | movedir = "fall" 92 | elif self.currChar in "v<>^": 93 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 94 | 95 | elif self.currChar in "0123456789": 96 | stack.append(int(self.currChar)) 97 | 98 | elif self.currChar in "+-*:;%=`": #operators and comparators 99 | if len(stack) < 2: 100 | stack = [0]*(2-len(stack)) + stack 101 | 102 | b = stack.pop() 103 | a = stack.pop() 104 | 105 | if self.currChar == "+": 106 | stack.append(a+b) 107 | elif self.currChar == "-": 108 | stack.append(a-b) 109 | elif self.currChar == "*": 110 | stack.append(a*b) 111 | elif self.currChar == ":": 112 | stack.append(a//b) 113 | elif self.currChar == ";": 114 | stack.append(a**b) 115 | elif self.currChar == "%": 116 | stack.append(a%b) 117 | elif self.currChar == "=": 118 | stack.append(int(a==b)) 119 | elif self.currChar == "`": 120 | stack.append(int(a>b)) 121 | 122 | ## if debug: print(stack) 123 | 124 | elif self.currChar in "~,": #negation and not 125 | if len(stack) < 1: 126 | stack = [0]*(1-len(stack)) + stack 127 | 128 | b = stack.pop() 129 | 130 | if self.currChar == "~": 131 | stack.append(-b) 132 | elif self.currChar == ",": 133 | stack.append(int(not b)) 134 | 135 | elif self.currChar in "!?@&": 136 | if self.currChar == "!": 137 | movedir = "jump" 138 | arg2 = 1 139 | else: 140 | s = stack.pop() if stack else 0 141 | if self.currChar == "?" and s: 142 | movedir = "jump" 143 | arg2 = 1 144 | elif self.currChar == "@": 145 | movedir = "jump" 146 | arg2 = s 147 | elif self.currChar == "&" and s: 148 | movedir = "jump" 149 | arg2 = stack.pop() 150 | 151 | elif self.currChar in "no": #input 152 | if self.currChar == "n": 153 | beg = 0 154 | while self.inputStr[beg].isalpha(): beg += 1 155 | 156 | end = beg+1 157 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 158 | 159 | stack.append(int(self.inputStr[beg:end-1])) 160 | self.inputStr = self.inputStr[end-1:] 161 | elif self.currChar == "o": 162 | stack.append(ord(self.inputStr[0])) 163 | self.inputStr = self.inputStr[1:] 164 | 165 | elif self.currChar in "NO": #output 166 | tos = stack.pop() if stack else 0 167 | 168 | if self.currChar == "N": 169 | print(tos, end=' ', flush=True) 170 | elif self.currChar == "O": 171 | print(chr(tos), end='', flush=True) 172 | 173 | elif self.currChar in "dD": #duplication 174 | if not stack: stack = [0] 175 | 176 | if self.currChar == "d": 177 | stack.append(stack[-1]) 178 | elif self.currChar == "D": 179 | if len(stack) < 2: stack.append(0) 180 | 181 | n = stack.pop()-1 182 | stack.extend([stack[-1]]*n) 183 | 184 | elif self.currChar in "bB": #branches 185 | tos = stack.pop() if stack else 0 186 | 187 | if self.currChar == "b": 188 | if not tos: self.velocity = [-v for v in self.velocity] 189 | if self.currChar == "B": 190 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 191 | if not tos: self.velocity = [-v for v in self.velocity] 192 | 193 | elif self.currChar in "i": #loop counter 194 | stack.append(self.loops[-1][4] if self.loops else -1) 195 | 196 | elif self.currChar in "()": #while loop 197 | if self.currChar == "(": 198 | tos = stack.pop() if stack and self.toggleFlag else 0 199 | 200 | newstack = stack[-tos:] 201 | self.loops.append(["while", 202 | self.position, 203 | self.velocity, 204 | newstack, 205 | 0]) 206 | 207 | ## if debug: print(self.loops[-1], self.stack) 208 | if self.toggleFlag: 209 | for i in range(tos): stack.pop() 210 | else: 211 | stack.clear() 212 | 213 | elif self.currChar == ")": 214 | if self.loops[-1][0] != "while": 215 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 216 | 217 | ## if debug: print(self.loops[-1]) 218 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 219 | ## if debug: print("?????") 220 | lastLoop = self.loops.pop() 221 | ## if debug: print(lastLoop, self.stack) 222 | parent = self.loops[-2][3] if self.loops else self.stack 223 | parent.extend(lastLoop[3][:-1]) 224 | ## if debug: print(parent, self.stack) 225 | else: 226 | self.loops[-1][0][4] += 1 #increment loop counter 227 | movedir = "teleport" 228 | arg2 = self.loops[-1][1:3] 229 | if debug: print(self.loops[-1][3]) 230 | 231 | elif self.currChar in "[]": #for loop 232 | if self.currChar == "[": 233 | iters = stack.pop() if stack else 0 234 | tos = stack.pop() if stack and self.toggleFlag else 0 235 | 236 | newstack = stack[len(stack)-tos:] 237 | self.loops.append(["for", 238 | self.position, 239 | self.velocity, 240 | newstack, 241 | 0, 242 | iters]) 243 | 244 | ## if debug: print(self.loops[-1], self.stack) 245 | if self.toggleFlag: 246 | for i in range(tos): stack.pop() 247 | else: 248 | pass 249 | 250 | elif self.currChar == "]": 251 | if self.loops[-1][0] != "for": 252 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 253 | 254 | ## if debug: print(self.loops[-1]) 255 | if self.loops[-1][4] >= self.loops[-1][5]-1: 256 | ## if debug: print("?????") 257 | lastLoop = self.loops.pop() 258 | ## if debug: print(lastLoop, self.stack) 259 | if lastLoop[5]: 260 | parent = self.loops[-2][3] if self.loops else self.stack 261 | parent.extend(lastLoop[3]) 262 | ## if debug: print(parent, self.stack) 263 | else: 264 | self.loops[-1][4] += 1 #increment loop counter 265 | movedir = "teleport" 266 | arg2 = self.loops[-1][1:3] 267 | ## if debug: print(self.loops[-1][3]) 268 | 269 | else: 270 | pass 271 | else: 272 | if self.strMode: 273 | self.strLiteral += self.currChar 274 | elif self.numMode: 275 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 276 | 277 | if self.toggleFlag and self.currChar != "$": self.toggleFlag = 0 278 | 279 | if debug: print(stack) 280 | self.move(movedir, arg2) 281 | 282 | def getCurrent(self): 283 | if debug: print(self.position) 284 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 285 | if debug: print("Current character:",self.currChar) 286 | 287 | def move(self, direction="", arg2=None): 288 | from math import copysign 289 | 290 | ## if debug: print("Old velocity:",self.velocity) 291 | if direction == "fall": self.velocity = [0,0,1] 292 | if direction == "down": self.velocity = [0,1,0] 293 | if direction == "left": self.velocity = [-1,0,0] 294 | if direction == "right": self.velocity = [1,0,0] 295 | if direction == "up": self.velocity = [0,-1,0] 296 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 297 | ## if debug: print("New velocity:",self.velocity) 298 | 299 | if direction == "teleport": 300 | self.position, self.velocity = arg2 301 | 302 | ## if debug: print("Old position:",self.position) 303 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 304 | ## if debug: print("New position:",self.position) 305 | 306 | 307 | for i in range(3): 308 | while self.position[i] < self.bounds[i][0]: 309 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 310 | while self.position[i] > self.bounds[i][1]: 311 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 312 | ## if debug: print("New position:",self.position) 313 | 314 | if direction == "jump": 315 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 316 | 317 | def push(self, L): 318 | if type(L) == list: 319 | self.stack.extend(L) 320 | elif type(L) == str: 321 | self.stack.extend(map(ord,L[::-1])) 322 | elif type(L) == int: 323 | self.stack.append(L) 324 | 325 | if debug: 326 | prog = Program(file, sys.argv[2], debugFlag=1) 327 | prog.run(numSteps) 328 | 329 | else: 330 | Program(file, sys.argv[2]).run() 331 | print() 332 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.3.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "fibonacci.mkl", "3"] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [ [list(s) for s in code.split("\n")] ] 25 | if debug: print("Code:",self.code) 26 | self.inputStr = inputStr 27 | if debug: print("Input:",self.inputStr) 28 | 29 | self.position = [0,0,0] #[x,y,z] 30 | self.velocity = [1,0,0] #[dx,dy,dz] 31 | 32 | self.stack = [] 33 | self.array = [[]] 34 | self.loops = [] 35 | 36 | self.strLiteral = "" 37 | self.strMode = 0 38 | 39 | self.numLiteral = 0 40 | self.numMode = 0 41 | 42 | self.fallable = 1 43 | self.toggleFlag = 0 44 | 45 | self.bounds = [[0,max(map(len,self.code[0]))], 46 | [0,len(self.code[0])], 47 | [0,0]] 48 | if debug: print(self.bounds) 49 | self.currChar = "" 50 | 51 | def run(self, steps=-1): #steps = -1 for run-until-halt 52 | while steps != 0: 53 | steps -= 1 54 | self.getCurrent() 55 | movedir = "" 56 | arg2 = None 57 | stack = self.loops[-1][3] if self.loops else self.stack 58 | 59 | if self.currChar == '"': 60 | self.fallable = not self.fallable 61 | self.strMode = not self.strMode 62 | 63 | if not self.strMode: 64 | ## self.push(self.strLiteral) 65 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 66 | self.strLiteral = "" 67 | if self.currChar == "'": 68 | self.fallable = not self.fallable 69 | self.numMode = not self.numMode 70 | 71 | if not self.numMode: 72 | ## self.push(self.numLiteral) 73 | stack.append(self.numLiteral) 74 | self.numLiteral = 0 75 | 76 | if self.currChar not in "'\"": 77 | if not self.strMode and not self.numMode: 78 | 79 | if self.currChar != " " and not self.fallable: self.fallable = 1 80 | 81 | if self.currChar == ".": #stop execution 82 | return 83 | elif self.currChar == "$": #toggle functionality 84 | self.toggleFlag = 1 85 | elif self.currChar == "V": 86 | self.fallable = 0 87 | elif self.currChar == "#": #net 88 | pass 89 | 90 | elif self.fallable and self.currChar == " ": 91 | movedir = "fall" 92 | elif self.currChar in "v<>^": 93 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 94 | 95 | elif self.currChar in "0123456789": 96 | stack.append(int(self.currChar)) 97 | 98 | elif self.currChar in "+-*:;%=`": #operators and comparators 99 | if len(stack) < 2: 100 | stack = [0]*(2-len(stack)) + stack 101 | 102 | b = stack.pop() 103 | a = stack.pop() 104 | 105 | if self.currChar == "+": 106 | stack.append(a+b) 107 | elif self.currChar == "-": 108 | stack.append(a-b) 109 | elif self.currChar == "*": 110 | stack.append(a*b) 111 | elif self.currChar == ":": 112 | stack.append(a//b) 113 | elif self.currChar == ";": 114 | stack.append(a**b) 115 | elif self.currChar == "%": 116 | stack.append(a%b) 117 | elif self.currChar == "=": 118 | stack.append(int(a==b)) 119 | elif self.currChar == "`": 120 | stack.append(int(a>b)) 121 | 122 | ## if debug: print(stack) 123 | 124 | elif self.currChar in "~,": #negation and not 125 | if len(stack) < 1: 126 | stack = [0]*(1-len(stack)) + stack 127 | 128 | b = stack.pop() 129 | 130 | if self.currChar == "~": 131 | stack.append(-b) 132 | elif self.currChar == ",": 133 | stack.append(int(not b)) 134 | 135 | elif self.currChar in "!?@&": 136 | if self.currChar == "!": 137 | movedir = "jump" 138 | arg2 = 1 139 | else: 140 | tos = stack.pop() if stack else 0 141 | if self.currChar == "?" and tos: 142 | movedir = "jump" 143 | arg2 = 1 144 | elif self.currChar == "@": 145 | movedir = "jump" 146 | arg2 = tos 147 | elif self.currChar == "&" and (stack.pop() if stack else 0): 148 | movedir = "jump" 149 | arg2 = tos 150 | 151 | elif self.currChar in "no": #input 152 | if self.currChar == "n": 153 | beg = 0 154 | while self.inputStr[beg].isalpha(): beg += 1 155 | 156 | end = beg+1 157 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 158 | 159 | stack.append(int(self.inputStr[beg:end-1])) 160 | self.inputStr = self.inputStr[end-1:] 161 | elif self.currChar == "o": 162 | stack.append(ord(self.inputStr[0])) 163 | self.inputStr = self.inputStr[1:] 164 | 165 | elif self.currChar in "NO": #output 166 | tos = stack.pop() if stack else 0 167 | 168 | if self.currChar == "N": 169 | print(tos, end=' ', flush=True) 170 | elif self.currChar == "O": 171 | print(chr(tos), end='', flush=True) 172 | 173 | elif self.currChar in "dD": #duplication 174 | if not stack: stack = [0] 175 | 176 | if self.currChar == "d": 177 | stack.append(stack[-1]) 178 | elif self.currChar == "D": 179 | if len(stack) < 2: stack.append(0) 180 | 181 | n = stack.pop()-1 182 | stack.extend([stack[-1]]*n) 183 | 184 | elif self.currChar in "bB": #branches 185 | tos = stack.pop() if stack else 0 186 | 187 | if self.currChar == "b": 188 | if not tos: self.velocity = [-v for v in self.velocity] 189 | if self.currChar == "B": 190 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 191 | if not tos: self.velocity = [-v for v in self.velocity] 192 | 193 | elif self.currChar in "i": #loop counter 194 | stack.append(self.loops[-1][4] if self.loops else -1) 195 | 196 | elif self.currChar == "r": #reverse stack 197 | stack.reverse() 198 | 199 | elif self.currChar in "()": #while loop 200 | if self.currChar == "(": 201 | tos = stack.pop() if stack and self.toggleFlag else 0 202 | 203 | newstack = stack[-tos:] 204 | self.loops.append(["while", 205 | self.position, 206 | self.velocity, 207 | newstack, 208 | 0]) 209 | 210 | if self.toggleFlag: 211 | for i in range(tos): stack.pop() 212 | else: 213 | stack.clear() 214 | 215 | elif self.currChar == ")": 216 | if self.loops[-1][0] != "while": 217 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 218 | 219 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 220 | lastLoop = self.loops.pop() 221 | parent = self.loops[-2][3] if self.loops else self.stack 222 | parent.extend(lastLoop[3][:-1]) 223 | else: 224 | self.loops[-1][4] += 1 #increment loop counter 225 | movedir = "teleport" 226 | arg2 = self.loops[-1][1:3] 227 | if debug: print(self.loops[-1][3]) 228 | 229 | elif self.currChar in "[]": #for loop 230 | if self.currChar == "[": 231 | iters = stack.pop() if stack else 0 232 | tos = stack.pop() if stack and self.toggleFlag else 0 233 | 234 | newstack = stack[len(stack)-tos:] 235 | self.loops.append(["for", 236 | self.position, 237 | self.velocity, 238 | newstack, 239 | 0, 240 | iters]) 241 | 242 | if self.toggleFlag: 243 | for i in range(min([tos,len(stack)])): stack.pop() 244 | else: 245 | pass 246 | 247 | elif self.currChar == "]": 248 | if self.loops[-1][0] != "for": 249 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 250 | 251 | if self.loops[-1][4] >= self.loops[-1][5]-1: lastLoop = self.loops.pop() 252 | if lastLoop[5]: 253 | parent = self.loops[-2][3] if self.loops else self.stack 254 | parent.extend(lastLoop[3]) 255 | else: 256 | self.loops[-1][4] += 1 #increment loop counter 257 | movedir = "teleport" 258 | arg2 = self.loops[-1][1:3] 259 | 260 | 261 | elif self.currChar in "{}": #recursion 262 | if self.currChar == "{": 263 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 264 | parentR = None 265 | num = stack.pop() if stack else 0 266 | else: #child recursion 267 | i = -1 268 | while self.loops[i][5]: i -= 1 #get parent recursion 269 | parentR = self.loops[i] 270 | num = self.loops[i][6] 271 | 272 | movedir = "teleport" 273 | arg2 = self.loops[i][1:3] 274 | 275 | newstack = stack[len(stack)-num:] 276 | for i in range(min([num,len(stack)])): stack.pop() 277 | 278 | self.loops.append(["recursion", 279 | self.position, 280 | self.velocity, 281 | newstack, 282 | 0, 283 | parentR, 284 | num]) 285 | 286 | elif self.currChar == "}": 287 | if self.loops[-1][0] != "recursion": 288 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 289 | 290 | lastLoop = self.loops.pop() 291 | parent = self.loops[-1][3] if self.loops else self.stack 292 | parent.extend(lastLoop[3]) 293 | 294 | if lastLoop[5]: 295 | movedir = "teleport" 296 | arg2 = lastLoop[1:3] 297 | 298 | else: 299 | pass 300 | else: 301 | if self.strMode: 302 | self.strLiteral += self.currChar 303 | elif self.numMode: 304 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 305 | 306 | if self.toggleFlag and self.currChar != "$": self.toggleFlag = 0 307 | 308 | if debug: print(stack) 309 | self.move(movedir, arg2) 310 | 311 | def getCurrent(self): 312 | if debug: print(self.position) 313 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 314 | if debug: print("Current character:",self.currChar) 315 | 316 | def move(self, direction="", arg2=None): 317 | from math import copysign 318 | 319 | ## if debug: print("Old velocity:",self.velocity) 320 | if direction == "fall": self.velocity = [0,0,1] 321 | if direction == "down": self.velocity = [0,1,0] 322 | if direction == "left": self.velocity = [-1,0,0] 323 | if direction == "right": self.velocity = [1,0,0] 324 | if direction == "up": self.velocity = [0,-1,0] 325 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 326 | ## if debug: print("New velocity:",self.velocity) 327 | 328 | if direction == "teleport": 329 | self.position, self.velocity = arg2 330 | 331 | ## if debug: print("Old position:",self.position) 332 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 333 | ## if debug: print("New position:",self.position) 334 | 335 | 336 | for i in range(3): 337 | while self.position[i] < self.bounds[i][0]: 338 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 339 | while self.position[i] > self.bounds[i][1]: 340 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 341 | ## if debug: print("New position:",self.position) 342 | 343 | if direction == "jump": 344 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 345 | 346 | def push(self, L): 347 | if type(L) == list: 348 | self.stack.extend(L) 349 | elif type(L) == str: 350 | self.stack.extend(map(ord,L[::-1])) 351 | elif type(L) == int: 352 | self.stack.append(L) 353 | 354 | if debug: 355 | prog = Program(file, sys.argv[2], debugFlag=1) 356 | prog.run(numSteps) 357 | 358 | else: 359 | Program(file, sys.argv[2]).run() 360 | print() 361 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.4.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "mirror_test.mkl", "3"] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [ [list(s) for s in code.split("\n")] ] 25 | if debug: print("Code:",self.code) 26 | self.inputStr = inputStr 27 | if debug: print("Input:",self.inputStr) 28 | 29 | self.position = [0,0,0] #[x,y,z] 30 | self.velocity = [1,0,0] #[dx,dy,dz] 31 | 32 | self.stack = [] 33 | self.array = [[]] 34 | self.loops = [] 35 | 36 | self.strLiteral = "" 37 | self.strMode = 0 38 | 39 | self.numLiteral = 0 40 | self.numMode = 0 41 | 42 | self.fallable = 1 43 | self.toggleFlag = 0 44 | 45 | self.bounds = [[0,max(map(len,self.code[0]))], 46 | [0,len(self.code[0])], 47 | [0,1]] 48 | if debug: print(self.bounds) 49 | for L in self.code[0]: 50 | while len(L) < self.bounds[0][1]: 51 | L.append("") 52 | if debug: print(L) 53 | 54 | self.currChar = "" 55 | 56 | def run(self, steps=-1): #steps = -1 for run-until-halt 57 | while steps != 0: 58 | steps -= 1 59 | self.getCurrent() 60 | movedir = "" 61 | arg2 = None 62 | stack = self.loops[-1][3] if self.loops else self.stack 63 | 64 | if self.currChar == '"': 65 | self.fallable = not self.fallable 66 | self.strMode = not self.strMode 67 | 68 | if not self.strMode: 69 | ## self.push(self.strLiteral) 70 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 71 | self.strLiteral = "" 72 | if self.currChar == "'": 73 | self.fallable = not self.fallable 74 | self.numMode = not self.numMode 75 | 76 | if not self.numMode: 77 | ## self.push(self.numLiteral) 78 | stack.append(self.numLiteral) 79 | self.numLiteral = 0 80 | 81 | if self.currChar not in "'\"": 82 | if not self.strMode and not self.numMode: 83 | 84 | if self.currChar != " " and not self.fallable: self.fallable = 1 85 | 86 | if self.currChar == ".": #stop execution 87 | return 88 | elif self.currChar == "$": #toggle functionality 89 | self.toggleFlag = 1 90 | elif self.currChar == "V": 91 | self.fallable = 0 92 | elif self.currChar == "#": #net 93 | pass 94 | 95 | elif self.fallable and self.currChar == " ": 96 | movedir = "fall" 97 | elif self.currChar in "v<>^": 98 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 99 | 100 | elif self.currChar in "/\\_|": 101 | if self.currChar == "/": 102 | self.velocity = [-self.velocity[1], 103 | -self.velocity[0], 104 | self.velocity[2]] 105 | elif self.currChar == "\\": 106 | self.velocity = [self.velocity[1], 107 | self.velocity[0], 108 | self.velocity[2]] 109 | elif self.currChar == "_": 110 | self.velocity = [self.velocity[0], 111 | -self.velocity[1], 112 | self.velocity[2]] 113 | elif self.currChar == "|": 114 | self.velocity = [-self.velocity[0], 115 | self.velocity[1], 116 | self.velocity[2]] 117 | 118 | elif self.currChar in "0123456789": 119 | stack.append(int(self.currChar)) 120 | 121 | elif self.currChar in "+-*:;%=`": #operators and comparators 122 | if len(stack) < 2: 123 | stack = [0]*(2-len(stack)) + stack 124 | 125 | b = stack.pop() 126 | a = stack.pop() 127 | 128 | if self.currChar == "+": 129 | stack.append(a+b) 130 | elif self.currChar == "-": 131 | stack.append(a-b) 132 | elif self.currChar == "*": 133 | stack.append(a*b) 134 | elif self.currChar == ":": 135 | stack.append(a//b) 136 | elif self.currChar == ";": 137 | stack.append(a**b) 138 | elif self.currChar == "%": 139 | stack.append(a%b) 140 | elif self.currChar == "=": 141 | stack.append(int(a==b)) 142 | elif self.currChar == "`": 143 | stack.append(int(a>b)) 144 | 145 | ## if debug: print(stack) 146 | 147 | elif self.currChar in "~,": #negation and not 148 | if len(stack) < 1: 149 | stack = [0]*(1-len(stack)) + stack 150 | 151 | b = stack.pop() 152 | 153 | if self.currChar == "~": 154 | stack.append(-b) 155 | elif self.currChar == ",": 156 | stack.append(int(not b)) 157 | 158 | elif self.currChar in "!?@&": 159 | if self.currChar == "!": 160 | movedir = "jump" 161 | arg2 = 1 162 | else: 163 | tos = stack.pop() if stack else 0 164 | if self.currChar == "?" and tos: 165 | movedir = "jump" 166 | arg2 = 1 167 | elif self.currChar == "@": 168 | movedir = "jump" 169 | arg2 = tos 170 | elif self.currChar == "&" and (stack.pop() if stack else 0): 171 | movedir = "jump" 172 | arg2 = tos 173 | 174 | elif self.currChar in "no": #input 175 | if self.currChar == "n": 176 | beg = 0 177 | while self.inputStr[beg].isalpha(): beg += 1 178 | 179 | end = beg+1 180 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 181 | 182 | stack.append(int(self.inputStr[beg:end-1])) 183 | self.inputStr = self.inputStr[end-1:] 184 | elif self.currChar == "o": 185 | stack.append(ord(self.inputStr[0])) 186 | self.inputStr = self.inputStr[1:] 187 | 188 | elif self.currChar in "NO": #output 189 | tos = stack.pop() if stack else 0 190 | 191 | if self.currChar == "N": 192 | print(tos, end=' ', flush=True) 193 | elif self.currChar == "O": 194 | print(chr(tos), end='', flush=True) 195 | 196 | elif self.currChar in "dD": #duplication 197 | if not stack: stack = [0] 198 | 199 | if self.currChar == "d": 200 | stack.append(stack[-1]) 201 | elif self.currChar == "D": 202 | if len(stack) < 2: stack.append(0) 203 | 204 | n = stack.pop()-1 205 | stack.extend([stack[-1]]*n) 206 | 207 | elif self.currChar in "bB": #branches 208 | tos = stack.pop() if stack else 0 209 | 210 | if self.currChar == "b": 211 | if not tos: self.velocity = [-v for v in self.velocity] 212 | if self.currChar == "B": 213 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 214 | if not tos: self.velocity = [-v for v in self.velocity] 215 | 216 | elif self.currChar in "wW": #wormhole 217 | nz = stack.pop() if stack and self.currChar == "W" else 0 218 | ny = stack.pop() if stack else 0 219 | nx = stack.pop() if stack else 0 220 | 221 | movedir = "wormhole" 222 | arg2 = [[nx,ny,nz],self.velocity] 223 | 224 | elif self.currChar in "i": #loop counter 225 | stack.append(self.loops[-1][4] if self.loops else -1) 226 | elif self.currChar == "I": #stack length 227 | stack.append(len(stack)) 228 | 229 | elif self.currChar == "r": #reverse stack 230 | stack.reverse() 231 | elif self.currChar == "R": #rotates stack 232 | tos = stack.pop() if stack else 0 233 | mod = tos % len(stack) - (tos < 0) 234 | 235 | newstack = stack[-mod:] + stack[:-mod] 236 | stack.clear() 237 | stack.extend(newstack) 238 | 239 | elif self.currChar in "xX": 240 | tos = stack.pop() if stack else 0 241 | if self.currChar == "X": 242 | for i in range(min([tos,len(stack)])): stack.pop() 243 | 244 | elif self.currChar in "()": #while loop 245 | if self.currChar == "(": 246 | tos = stack.pop() if stack and self.toggleFlag else 0 247 | 248 | newstack = stack[-tos:] 249 | self.loops.append(["while", 250 | self.position, 251 | self.velocity, 252 | newstack, 253 | 0]) 254 | 255 | if self.toggleFlag: 256 | for i in range(tos): stack.pop() 257 | else: 258 | stack.clear() 259 | 260 | elif self.currChar == ")": 261 | if self.loops[-1][0] != "while": 262 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 263 | 264 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 265 | lastLoop = self.loops.pop() 266 | parent = self.loops[-2][3] if self.loops else self.stack 267 | parent.extend(lastLoop[3][:-1]) 268 | else: 269 | self.loops[-1][4] += 1 #increment loop counter 270 | movedir = "teleport" 271 | arg2 = self.loops[-1][1:3] 272 | if debug: print(self.loops[-1][3]) 273 | 274 | elif self.currChar in "[]": #for loop 275 | if self.currChar == "[": 276 | iters = stack.pop() if stack else 0 277 | tos = stack.pop() if stack and self.toggleFlag else 0 278 | 279 | newstack = stack[len(stack)-tos:] 280 | self.loops.append(["for", 281 | self.position, 282 | self.velocity, 283 | newstack, 284 | 0, 285 | iters]) 286 | 287 | if self.toggleFlag: 288 | for i in range(min([tos,len(stack)])): stack.pop() 289 | else: 290 | pass 291 | 292 | elif self.currChar == "]": 293 | if self.loops[-1][0] != "for": 294 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 295 | 296 | if self.loops[-1][4] >= self.loops[-1][5]-1: 297 | lastLoop = self.loops.pop() 298 | if lastLoop[5]: 299 | parent = self.loops[-2][3] if self.loops else self.stack 300 | parent.extend(lastLoop[3]) 301 | else: 302 | self.loops[-1][4] += 1 #increment loop counter 303 | movedir = "teleport" 304 | arg2 = self.loops[-1][1:3] 305 | 306 | 307 | elif self.currChar in "{}": #recursion 308 | if self.currChar == "{": 309 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 310 | parentR = None 311 | num = stack.pop() if stack else 0 312 | else: #child recursion 313 | i = -1 314 | while self.loops[i][5]: i -= 1 #get parent recursion 315 | parentR = self.loops[i] 316 | num = self.loops[i][6] 317 | 318 | movedir = "teleport" 319 | arg2 = self.loops[i][1:3] 320 | 321 | newstack = stack[len(stack)-num:] 322 | for i in range(min([num,len(stack)])): stack.pop() 323 | 324 | self.loops.append(["recursion", 325 | self.position, 326 | self.velocity, 327 | newstack, 328 | 0, 329 | parentR, 330 | num]) 331 | 332 | elif self.currChar == "}": 333 | if self.loops[-1][0] != "recursion": 334 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 335 | 336 | lastLoop = self.loops.pop() 337 | parent = self.loops[-1][3] if self.loops else self.stack 338 | parent.extend(lastLoop[3]) 339 | 340 | if lastLoop[5]: 341 | movedir = "teleport" 342 | arg2 = lastLoop[1:3] 343 | 344 | else: 345 | pass 346 | else: 347 | if self.strMode: 348 | self.strLiteral += self.currChar 349 | elif self.numMode: 350 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 351 | 352 | if self.toggleFlag and self.currChar != "$": self.toggleFlag = 0 353 | 354 | if debug: print(stack) 355 | self.move(movedir, arg2) 356 | 357 | def getCurrent(self): 358 | if debug: print(self.position) 359 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 360 | if debug: print("Current character:",self.currChar) 361 | 362 | def move(self, direction="", arg2=None): 363 | from math import copysign 364 | 365 | ## if debug: print("Old velocity:",self.velocity) 366 | if direction == "fall": self.velocity = [0,0,1] 367 | if direction == "down": self.velocity = [0,1,0] 368 | if direction == "left": self.velocity = [-1,0,0] 369 | if direction == "right": self.velocity = [1,0,0] 370 | if direction == "up": self.velocity = [0,-1,0] 371 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 372 | ## if debug: print("New velocity:",self.velocity) 373 | 374 | if direction in ["teleport","wormhole"]: 375 | self.position, self.velocity = arg2 376 | 377 | if debug: print("Old position:",self.position) 378 | if direction != "wormhole": 379 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 380 | if debug: print("New position:",self.position) 381 | 382 | 383 | for i in range(3): 384 | while self.position[i] < self.bounds[i][0]: 385 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 386 | while self.position[i] >= self.bounds[i][1]: 387 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 388 | if debug: print("New position:",self.position) 389 | 390 | if direction == "jump": 391 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 392 | 393 | def push(self, L): 394 | if type(L) == list: 395 | self.stack.extend(L) 396 | elif type(L) == str: 397 | self.stack.extend(map(ord,L[::-1])) 398 | elif type(L) == int: 399 | self.stack.append(L) 400 | 401 | if debug: 402 | prog = Program(file, sys.argv[2], debugFlag=1) 403 | prog.run(numSteps) 404 | 405 | else: 406 | Program(file, sys.argv[2]).run() 407 | print() 408 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.5.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "sortAndSet_some.mkl", ""] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [ [list(s) for s in code.split("\n")] ] 25 | if debug: print("Code:",self.code) 26 | self.inputStr = inputStr 27 | if debug: print("Input:",self.inputStr) 28 | 29 | self.position = [0,0,0] #[x,y,z] 30 | self.velocity = [1,0,0] #[dx,dy,dz] 31 | 32 | self.stack = [] 33 | self.array = [[]] 34 | self.loops = [] 35 | 36 | self.strLiteral = "" 37 | self.strMode = 0 38 | 39 | self.numLiteral = 0 40 | self.numMode = 0 41 | 42 | self.fallable = 1 43 | self.toggleFlag = 0 44 | 45 | self.bounds = [[0,max(map(len,self.code[0]))], 46 | [0,len(self.code[0])], 47 | [0,1]] 48 | if debug: print(self.bounds) 49 | for L in self.code[0]: 50 | while len(L) < self.bounds[0][1]: 51 | L.append("") 52 | if debug: print(L) 53 | 54 | self.currChar = "" 55 | 56 | def run(self, steps=-1): #steps = -1 for run-until-halt 57 | while steps != 0: 58 | steps -= 1 59 | self.getCurrent() 60 | movedir = "" 61 | arg2 = None 62 | stack = self.loops[-1][3] if self.loops else self.stack 63 | 64 | if self.currChar == '"': 65 | self.fallable = not self.fallable 66 | self.strMode = not self.strMode 67 | 68 | if not self.strMode: 69 | ## self.push(self.strLiteral) 70 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 71 | self.strLiteral = "" 72 | if self.currChar == "'": 73 | self.fallable = not self.fallable 74 | self.numMode = not self.numMode 75 | 76 | if not self.numMode: 77 | ## self.push(self.numLiteral) 78 | stack.append(self.numLiteral) 79 | self.numLiteral = 0 80 | 81 | if self.currChar not in "'\"": 82 | if not self.strMode and not self.numMode: 83 | 84 | if self.currChar != " " and not self.fallable: self.fallable = 1 85 | 86 | if self.currChar == ".": #stop execution 87 | return 88 | elif self.currChar == "$": #toggle functionality 89 | self.toggleFlag = 1 90 | elif self.currChar == "V": 91 | self.fallable = 0 92 | elif self.currChar == "#": #net 93 | pass 94 | 95 | elif self.fallable and self.currChar == " ": 96 | movedir = "fall" 97 | elif self.currChar in "v<>^": 98 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 99 | 100 | elif self.currChar in "/\\_|": 101 | if self.currChar == "/": 102 | self.velocity = [-self.velocity[1], 103 | -self.velocity[0], 104 | self.velocity[2]] 105 | elif self.currChar == "\\": 106 | self.velocity = [self.velocity[1], 107 | self.velocity[0], 108 | self.velocity[2]] 109 | elif self.currChar == "_": 110 | self.velocity = [self.velocity[0], 111 | -self.velocity[1], 112 | self.velocity[2]] 113 | elif self.currChar == "|": 114 | self.velocity = [-self.velocity[0], 115 | self.velocity[1], 116 | self.velocity[2]] 117 | 118 | elif self.currChar in "0123456789": 119 | stack.append(int(self.currChar)) 120 | 121 | elif self.currChar in "+-*:;%=`": #operators and comparators 122 | if self.toggleFlag and self.currChar in "+*": 123 | if self.currChar == "+": 124 | result = sum(stack) 125 | elif self.currChar == "*": 126 | result = 1 127 | for s in stack: result *= s 128 | 129 | stack.clear() 130 | 131 | else: 132 | b = stack.pop() if stack else 0 133 | a = stack.pop() if stack else 0 134 | 135 | if self.currChar == "+": 136 | result = a+b 137 | elif self.currChar == "-": 138 | result = a-b if not self.toggleFlag else b-a 139 | elif self.currChar == "*": 140 | result = a*b 141 | elif self.currChar == ":": 142 | result = a//b if not self.toggleFlag else a/b 143 | elif self.currChar == ";": 144 | result = a**b if not self.toggleFlag else b**a 145 | elif self.currChar == "%": 146 | result = a%b if not self.toggleFlag else b%a 147 | elif self.currChar == "=": 148 | result = int(a==b if not self.toggleFlag else a!=b) 149 | elif self.currChar == "`": 150 | result = int(a>b if not self.toggleFlag else b>a) 151 | 152 | stack.append(result) 153 | 154 | elif self.currChar in "~,": #negation and not 155 | if len(stack) < 1: 156 | stack = [0]*(1-len(stack)) + stack 157 | 158 | b = stack.pop() 159 | 160 | if self.currChar == "~": 161 | stack.append(-b if not self.toggleFlag else abs(b)) 162 | elif self.currChar == ",": 163 | stack.append(int(not b if not self.toggleFlag else bool(b))) 164 | 165 | elif self.currChar in "!?@&": 166 | if self.currChar == "!": 167 | movedir = "jump" 168 | arg2 = 1 169 | else: 170 | tos = stack.pop() if stack else 0 171 | if self.currChar == "?" and tos: 172 | movedir = "jump" 173 | arg2 = 1 174 | elif self.currChar == "@": 175 | movedir = "jump" 176 | arg2 = tos 177 | elif self.currChar == "&" and (stack.pop() if stack else 0): 178 | movedir = "jump" 179 | arg2 = tos 180 | 181 | elif self.currChar in "no": #input 182 | if self.currChar == "n": 183 | beg = 0 184 | while self.inputStr[beg].isalpha(): beg += 1 185 | 186 | end = beg+1 187 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 188 | 189 | stack.append(int(self.inputStr[beg:end-1])) 190 | self.inputStr = self.inputStr[end-1:] 191 | elif self.currChar == "o": 192 | stack.append(ord(self.inputStr[0])) 193 | self.inputStr = self.inputStr[1:] 194 | 195 | elif self.currChar in "NO": #output 196 | tos = stack.pop() if stack else 0 197 | 198 | if self.currChar == "N": 199 | print(tos, end=' ', flush=True) 200 | elif self.currChar == "O": 201 | print(chr(int(tos)), end='', flush=True) 202 | 203 | elif self.currChar in "dD": #duplication 204 | if not stack: stack = [0] 205 | 206 | if self.currChar == "d": 207 | stack.append(stack[-1]) 208 | elif self.currChar == "D": 209 | if len(stack) < 2: stack.append(0) 210 | 211 | n = stack.pop()-1 212 | stack.extend([stack[-1]]*n) 213 | 214 | elif self.currChar in "bB": #branches 215 | tos = stack.pop() if stack else 0 216 | 217 | if self.currChar == "b": 218 | if not tos: self.velocity = [-v for v in self.velocity] 219 | if self.currChar == "B": 220 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 221 | if not tos: self.velocity = [-v for v in self.velocity] 222 | 223 | elif self.currChar in "wW": #wormhole 224 | nz = stack.pop() if stack and self.currChar == "W" else 0 225 | ny = stack.pop() if stack else 0 226 | nx = stack.pop() if stack else 0 227 | 228 | movedir = "wormhole" 229 | arg2 = [[nx,ny,nz],self.velocity] 230 | 231 | elif self.currChar in "gG": #stack index/insert 232 | tos = stack.pop() if stack else 0 233 | 234 | if self.currChar == "g" and stack: 235 | stack.append(stack.pop(tos)) 236 | elif self.currChar == "G" and stack: 237 | toput = stack.pop() if stack else 0 238 | stack.insert(tos, toput) 239 | 240 | elif self.currChar in "xX": #dump 241 | if self.toggleFlag: 242 | stack.clear() 243 | else: 244 | tos = stack.pop() if stack else 0 245 | if self.currChar == "X": 246 | for i in range(min([tos,len(stack)])): stack.pop() 247 | 248 | elif self.currChar in "i": #loop counter 249 | stack.append(self.loops[-1][4] if self.loops else -1) 250 | elif self.currChar == "I": #stack length 251 | stack.append(len(stack)) 252 | 253 | elif self.currChar == "r": #reverse stack 254 | stack.reverse() 255 | elif self.currChar == "R": #rotates stack 256 | tos = stack.pop() if stack else 0 257 | mod = tos % len(stack) - (tos < 0) 258 | 259 | newstack = stack[-mod:] + stack[:-mod] 260 | stack.clear() 261 | stack.extend(newstack) 262 | 263 | elif self.currChar == "s": #sort 264 | if self.toggleFlag: 265 | tos = stack.pop() if stack else 0 266 | newstack = stack[-tos:] 267 | for n in newstack: stack.pop() 268 | newstack.sort(reverse=True) 269 | stack.extend(newstack) 270 | else: 271 | stack.sort(reverse=True) 272 | elif self.currChar == "S": #set 273 | tos = stack.pop() if stack and self.toggleFlag else 0 274 | newstack = stack[-tos:] 275 | for n in newstack: stack.pop() 276 | 277 | j = len(newstack)-1 278 | seen = [] 279 | while j >= 0: 280 | if newstack[j] not in seen: seen.append(newstack[j]) 281 | j -= 1 282 | 283 | stack.extend(seen[::-1]) 284 | 285 | elif self.currChar in "()": #while loop 286 | if self.currChar == "(": 287 | tos = stack.pop() if stack and self.toggleFlag else 0 288 | 289 | newstack = stack[-tos:] 290 | self.loops.append(["while", 291 | self.position, 292 | self.velocity, 293 | newstack, 294 | 0]) 295 | 296 | if self.toggleFlag: 297 | for i in range(tos): stack.pop() 298 | else: 299 | stack.clear() 300 | 301 | elif self.currChar == ")": 302 | if self.loops[-1][0] != "while": 303 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 304 | 305 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 306 | lastLoop = self.loops.pop() 307 | parent = self.loops[-2][3] if self.loops else self.stack 308 | parent.extend(lastLoop[3][:-1]) 309 | else: 310 | self.loops[-1][4] += 1 #increment loop counter 311 | movedir = "teleport" 312 | arg2 = self.loops[-1][1:3] 313 | if debug: print(self.loops[-1][3]) 314 | 315 | elif self.currChar in "[]": #for loop 316 | if self.currChar == "[": 317 | iters = stack.pop() if stack else 0 318 | tos = stack.pop() if stack and self.toggleFlag else 0 319 | 320 | newstack = stack[len(stack)-tos:] 321 | self.loops.append(["for", 322 | self.position, 323 | self.velocity, 324 | newstack, 325 | 0, 326 | iters]) 327 | 328 | if self.toggleFlag: 329 | for i in range(min([tos,len(stack)])): stack.pop() 330 | else: 331 | pass 332 | 333 | elif self.currChar == "]": 334 | if self.loops[-1][0] != "for": 335 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 336 | 337 | if self.loops[-1][4] >= self.loops[-1][5]-1: 338 | lastLoop = self.loops.pop() 339 | if lastLoop[5]: 340 | parent = self.loops[-2][3] if self.loops else self.stack 341 | parent.extend(lastLoop[3]) 342 | else: 343 | self.loops[-1][4] += 1 #increment loop counter 344 | movedir = "teleport" 345 | arg2 = self.loops[-1][1:3] 346 | 347 | 348 | elif self.currChar in "{}": #recursion 349 | if self.currChar == "{": 350 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 351 | parentR = None 352 | num = stack.pop() if stack else 0 353 | else: #child recursion 354 | i = -1 355 | while self.loops[i][5]: i -= 1 #get parent recursion 356 | parentR = self.loops[i] 357 | num = self.loops[i][6] 358 | 359 | movedir = "teleport" 360 | arg2 = self.loops[i][1:3] 361 | 362 | newstack = stack[len(stack)-num:] 363 | for i in range(min([num,len(stack)])): stack.pop() 364 | 365 | self.loops.append(["recursion", 366 | self.position, 367 | self.velocity, 368 | newstack, 369 | 0, 370 | parentR, 371 | num]) 372 | 373 | elif self.currChar == "}": 374 | if self.loops[-1][0] != "recursion": 375 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 376 | 377 | lastLoop = self.loops.pop() 378 | parent = self.loops[-1][3] if self.loops else self.stack 379 | parent.extend(lastLoop[3]) 380 | 381 | if lastLoop[5]: 382 | movedir = "teleport" 383 | arg2 = lastLoop[1:3] 384 | 385 | else: 386 | pass 387 | else: 388 | if self.strMode: 389 | self.strLiteral += self.currChar 390 | elif self.numMode: 391 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 392 | 393 | if self.toggleFlag and self.currChar != "$": self.toggleFlag = 0 394 | 395 | if debug: print(stack) 396 | self.move(movedir, arg2) 397 | 398 | def getCurrent(self): 399 | if debug: print(self.position) 400 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 401 | if debug: print("Current character:",self.currChar) 402 | 403 | def move(self, direction="", arg2=None): 404 | from math import copysign 405 | 406 | ## if debug: print("Old velocity:",self.velocity) 407 | if direction == "fall": self.velocity = [0,0,1] 408 | if direction == "down": self.velocity = [0,1,0] 409 | if direction == "left": self.velocity = [-1,0,0] 410 | if direction == "right": self.velocity = [1,0,0] 411 | if direction == "up": self.velocity = [0,-1,0] 412 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 413 | ## if debug: print("New velocity:",self.velocity) 414 | 415 | if direction in ["teleport","wormhole"]: 416 | self.position, self.velocity = arg2 417 | 418 | if debug: print("Old position:",self.position) 419 | if direction != "wormhole": 420 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 421 | if debug: print("New position:",self.position) 422 | 423 | 424 | for i in range(3): 425 | while self.position[i] < self.bounds[i][0]: 426 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 427 | while self.position[i] >= self.bounds[i][1]: 428 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 429 | if debug: print("New position:",self.position) 430 | 431 | if direction == "jump": 432 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 433 | 434 | def push(self, L): 435 | if type(L) == list: 436 | self.stack.extend(L) 437 | elif type(L) == str: 438 | self.stack.extend(map(ord,L[::-1])) 439 | elif type(L) == int: 440 | self.stack.append(L) 441 | 442 | if debug: 443 | prog = Program(file, sys.argv[2], debugFlag=1) 444 | prog.run(numSteps) 445 | 446 | else: 447 | Program(file, sys.argv[2]).run() 448 | print() 449 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.6.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "layer_test.mkl", ""] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [] 25 | for layer in filter(bool, code.split("$$$\n")): 26 | self.code.append([list(s) for s in layer.rstrip("\n").split("\n")]) 27 | 28 | if debug: print("Code:",self.code) 29 | self.inputStr = inputStr 30 | if debug: print("Input:",self.inputStr) 31 | 32 | self.position = [0,0,0] #[x,y,z] 33 | self.velocity = [1,0,0] #[dx,dy,dz] 34 | 35 | self.stack = [] 36 | self.array = [[]] 37 | self.loops = [] 38 | 39 | self.strLiteral = "" 40 | self.strMode = 0 41 | 42 | self.numLiteral = 0 43 | self.numMode = 0 44 | 45 | self.fallable = 1 46 | self.toggleFlag = 0 47 | self.fallFlag = 0 48 | self.stuckFlag = 0 49 | 50 | self.bounds = [[0,max([ max(map(len,layer)) for layer in self.code])], 51 | [0,max(map(len,self.code))], 52 | [0,len(self.code)]] 53 | if debug: print(self.bounds) 54 | for layer in self.code: 55 | for row in layer: 56 | row.extend([" "]*(self.bounds[0][1]-len(row)+1)) 57 | if debug: print(row) 58 | while len(layer) < self.bounds[1][1]: 59 | layer.append([" "]*self.bounds[0][1]) 60 | 61 | self.currChar = "" 62 | 63 | def run(self, steps=-1): #steps = -1 for run-until-halt 64 | while steps != 0: 65 | steps -= 1 66 | self.getCurrent() 67 | movedir = "" 68 | arg2 = None 69 | stack = self.loops[-1][3] if self.loops else self.stack 70 | 71 | if self.currChar == '"': 72 | self.fallable = not self.fallable 73 | self.strMode = not self.strMode 74 | 75 | if not self.strMode: 76 | ## self.push(self.strLiteral) 77 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 78 | self.strLiteral = "" 79 | if self.currChar == "'": 80 | self.fallable = not self.fallable 81 | self.numMode = not self.numMode 82 | 83 | if not self.numMode: 84 | ## self.push(self.numLiteral) 85 | stack.append(self.numLiteral) 86 | self.numLiteral = 0 87 | 88 | if self.currChar not in "'\"": 89 | if not self.strMode and not self.numMode: 90 | 91 | if self.currChar != " " and not self.fallable and not self.fallFlag: 92 | self.fallable = 1 93 | 94 | if self.currChar == ".": #stop execution 95 | return 96 | elif self.currChar == "$": #toggle functionality 97 | if self.stuckFlag: 98 | self.toggleFlag = 0 99 | self.stuckFlag = 0 100 | else: 101 | self.toggleFlag = 1 102 | elif self.currChar == "V": 103 | if self.fallFlag: 104 | self.fallable = 1 105 | self.fallFlag = 0 106 | else: 107 | self.fallable = 0 108 | self.fallFlag = self.toggleFlag 109 | elif self.currChar == "#": #net 110 | pass 111 | 112 | elif self.fallable and self.currChar == " ": 113 | movedir = "fall" 114 | elif self.currChar in "v<>^": 115 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 116 | 117 | elif self.currChar in "/\\_|": 118 | if self.currChar == "/": 119 | self.velocity = [-self.velocity[1], 120 | -self.velocity[0], 121 | self.velocity[2]] 122 | elif self.currChar == "\\": 123 | self.velocity = [self.velocity[1], 124 | self.velocity[0], 125 | self.velocity[2]] 126 | elif self.currChar == "_": 127 | self.velocity = [self.velocity[0], 128 | -self.velocity[1], 129 | self.velocity[2]] 130 | elif self.currChar == "|": 131 | self.velocity = [-self.velocity[0], 132 | self.velocity[1], 133 | self.velocity[2]] 134 | 135 | elif self.currChar in "0123456789": 136 | stack.append(int(self.currChar)) 137 | 138 | elif self.currChar in "+-*:;%=`": #operators and comparators 139 | if self.toggleFlag and self.currChar in "+*": 140 | if self.currChar == "+": 141 | result = sum(stack) 142 | elif self.currChar == "*": 143 | result = 1 144 | for s in stack: result *= s 145 | 146 | stack.clear() 147 | 148 | else: 149 | b = stack.pop() if stack else 0 150 | a = stack.pop() if stack else 0 151 | 152 | if self.currChar == "+": 153 | result = a+b 154 | elif self.currChar == "-": 155 | result = a-b if not self.toggleFlag else b-a 156 | elif self.currChar == "*": 157 | result = a*b 158 | elif self.currChar == ":": 159 | result = a//b if not self.toggleFlag else a/b 160 | elif self.currChar == ";": 161 | result = a**b if not self.toggleFlag else b**a 162 | elif self.currChar == "%": 163 | result = a%b if not self.toggleFlag else b%a 164 | elif self.currChar == "=": 165 | result = int(a==b if not self.toggleFlag else a!=b) 166 | elif self.currChar == "`": 167 | result = int(a>b if not self.toggleFlag else b>a) 168 | 169 | stack.append(result) 170 | 171 | elif self.currChar in "~,": #negation and not 172 | if len(stack) < 1: 173 | stack = [0]*(1-len(stack)) + stack 174 | 175 | b = stack.pop() 176 | 177 | if self.currChar == "~": 178 | stack.append(-b if not self.toggleFlag else abs(b)) 179 | elif self.currChar == ",": 180 | stack.append(int(not b if not self.toggleFlag else bool(b))) 181 | 182 | elif self.currChar in "!?@&": 183 | if self.currChar == "!": 184 | movedir = "jump" 185 | arg2 = 1 186 | else: 187 | tos = stack.pop() if stack else 0 188 | if self.currChar == "?" and tos: 189 | movedir = "jump" 190 | arg2 = 1 191 | elif self.currChar == "@": 192 | movedir = "jump" 193 | arg2 = tos 194 | elif self.currChar == "&" and (stack.pop() if stack else 0): 195 | movedir = "jump" 196 | arg2 = tos 197 | 198 | elif self.currChar in "no": #input 199 | if self.currChar == "n": 200 | beg = 0 201 | while self.inputStr[beg].isalpha(): beg += 1 202 | 203 | end = beg+1 204 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 205 | 206 | stack.append(int(self.inputStr[beg:end-1])) 207 | self.inputStr = self.inputStr[end-1:] 208 | elif self.currChar == "o": 209 | stack.append(ord(self.inputStr[0])) 210 | self.inputStr = self.inputStr[1:] 211 | 212 | elif self.currChar in "NO": #output 213 | tos = stack.pop() if stack else 0 214 | 215 | if self.currChar == "N": 216 | print(tos, end=' ', flush=True) 217 | elif self.currChar == "O": 218 | print(chr(int(tos)), end='', flush=True) 219 | 220 | elif self.currChar in "dD": #duplication 221 | if not stack: stack = [0] 222 | 223 | if self.currChar == "d": 224 | stack.append(stack[-1]) 225 | elif self.currChar == "D": 226 | if len(stack) < 2: stack.append(0) 227 | 228 | n = stack.pop()-1 229 | stack.extend([stack[-1]]*n) 230 | 231 | elif self.currChar in "bB": #branches 232 | tos = stack.pop() if stack else 0 233 | if self.toggleFlag: tos = not tos 234 | 235 | if self.currChar == "b": 236 | if not tos: self.velocity = [-v for v in self.velocity] 237 | if self.currChar == "B": 238 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 239 | if not tos: self.velocity = [-v for v in self.velocity] 240 | 241 | elif self.currChar in "wW": #wormhole 242 | nz = stack.pop() if stack and self.currChar == "W" else 0 243 | ny = stack.pop() if stack else 0 244 | nx = stack.pop() if stack else 0 245 | 246 | movedir = "wormhole" 247 | arg2 = [[nx,ny,nz],self.velocity] 248 | 249 | elif self.currChar in "gG": #stack index/insert 250 | tos = stack.pop() if stack else 0 251 | 252 | if self.currChar == "g" and stack: 253 | stack.append(stack.pop(tos)) 254 | elif self.currChar == "G" and stack: 255 | toput = stack.pop() if stack else 0 256 | stack.insert(tos, toput) 257 | 258 | elif self.currChar in "xX": #dump 259 | if self.toggleFlag: 260 | stack.clear() 261 | else: 262 | tos = stack.pop() if stack else 0 263 | if self.currChar == "X": 264 | for i in range(min([tos,len(stack)])): stack.pop() 265 | 266 | elif self.currChar in "i": #loop counter 267 | stack.append(self.loops[-1][4] if self.loops else -1) 268 | elif self.currChar == "I": #stack length 269 | stack.append(len(stack)) 270 | 271 | elif self.currChar == "r": #reverse stack 272 | stack.reverse() 273 | elif self.currChar == "R": #rotates stack 274 | tos = stack.pop() if stack else 0 275 | mod = tos % len(stack) - (tos < 0) 276 | 277 | newstack = stack[-mod:] + stack[:-mod] 278 | stack.clear() 279 | stack.extend(newstack) 280 | 281 | elif self.currChar == "s": #sort 282 | if self.toggleFlag: 283 | tos = stack.pop() if stack else 0 284 | newstack = stack[-tos:] 285 | for n in newstack: stack.pop() 286 | newstack.sort(reverse=True) 287 | stack.extend(newstack) 288 | else: 289 | stack.sort(reverse=True) 290 | elif self.currChar == "S": #set 291 | tos = stack.pop() if stack and self.toggleFlag else 0 292 | newstack = stack[-tos:] 293 | for n in newstack: stack.pop() 294 | 295 | j = len(newstack)-1 296 | seen = [] 297 | while j >= 0: 298 | if newstack[j] not in seen: seen.append(newstack[j]) 299 | j -= 1 300 | 301 | stack.extend(seen[::-1]) 302 | 303 | elif self.currChar in "()": #while loop 304 | if self.currChar == "(": 305 | tos = stack.pop() if stack and self.toggleFlag else 0 306 | 307 | newstack = stack[-tos:] 308 | self.loops.append(["while", 309 | self.position, 310 | self.velocity, 311 | newstack, 312 | 0]) 313 | 314 | if self.toggleFlag: 315 | for i in range(tos): stack.pop() 316 | else: 317 | stack.clear() 318 | 319 | elif self.currChar == ")": 320 | if self.loops[-1][0] != "while": 321 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 322 | 323 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 324 | lastLoop = self.loops.pop() 325 | parent = self.loops[-2][3] if self.loops else self.stack 326 | parent.extend(lastLoop[3][:-1]) 327 | else: 328 | self.loops[-1][4] += 1 #increment loop counter 329 | movedir = "teleport" 330 | arg2 = self.loops[-1][1:3] 331 | if debug: print(self.loops[-1][3]) 332 | 333 | elif self.currChar in "[]": #for loop 334 | if self.currChar == "[": 335 | iters = stack.pop() if stack else 0 336 | tos = stack.pop() if stack and self.toggleFlag else 0 337 | 338 | newstack = stack[len(stack)-tos:] 339 | self.loops.append(["for", 340 | self.position, 341 | self.velocity, 342 | newstack, 343 | 0, 344 | iters]) 345 | 346 | if self.toggleFlag: 347 | for i in range(min([tos,len(stack)])): stack.pop() 348 | else: 349 | pass 350 | 351 | elif self.currChar == "]": 352 | if self.loops[-1][0] != "for": 353 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 354 | 355 | if self.loops[-1][4] >= self.loops[-1][5]-1: 356 | lastLoop = self.loops.pop() 357 | if lastLoop[5]: 358 | parent = self.loops[-2][3] if self.loops else self.stack 359 | parent.extend(lastLoop[3]) 360 | else: 361 | self.loops[-1][4] += 1 #increment loop counter 362 | movedir = "teleport" 363 | arg2 = self.loops[-1][1:3] 364 | 365 | 366 | elif self.currChar in "{}": #recursion 367 | if self.currChar == "{": 368 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 369 | parentR = None 370 | num = stack.pop() if stack else 0 371 | else: #child recursion 372 | i = -1 373 | while self.loops[i][5]: i -= 1 #get parent recursion 374 | parentR = self.loops[i] 375 | num = self.loops[i][6] 376 | 377 | movedir = "teleport" 378 | arg2 = self.loops[i][1:3] 379 | 380 | newstack = stack[len(stack)-num:] 381 | for i in range(min([num,len(stack)])): stack.pop() 382 | 383 | self.loops.append(["recursion", 384 | self.position, 385 | self.velocity, 386 | newstack, 387 | 0, 388 | parentR, 389 | num]) 390 | 391 | elif self.currChar == "}": 392 | if self.loops[-1][0] != "recursion": 393 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 394 | 395 | lastLoop = self.loops.pop() 396 | parent = self.loops[-1][3] if self.loops else self.stack 397 | parent.extend(lastLoop[3]) 398 | 399 | if lastLoop[5]: 400 | movedir = "teleport" 401 | arg2 = lastLoop[1:3] 402 | 403 | else: 404 | pass 405 | else: 406 | if self.strMode: 407 | self.strLiteral += self.currChar 408 | elif self.numMode: 409 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 410 | 411 | if self.toggleFlag and self.currChar != "$" and not self.stuckFlag: self.toggleFlag = 0 412 | 413 | if debug: print(stack) 414 | self.move(movedir, arg2) 415 | 416 | def getCurrent(self): 417 | if debug: print(self.position) 418 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 419 | if type(self.currChar) != str: 420 | try: 421 | self.currChar = chr(self.currChar) 422 | except [ValueError, TypeError]: 423 | self.currChar = "" 424 | if debug: print("Current character:",self.currChar) 425 | 426 | def move(self, direction="", arg2=None): 427 | from math import copysign 428 | 429 | ## if debug: print("Old velocity:",self.velocity) 430 | if direction == "fall": self.velocity = [0,0,1] 431 | if direction == "down": self.velocity = [0,1,0] 432 | if direction == "left": self.velocity = [-1,0,0] 433 | if direction == "right": self.velocity = [1,0,0] 434 | if direction == "up": self.velocity = [0,-1,0] 435 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 436 | ## if debug: print("New velocity:",self.velocity) 437 | 438 | if direction in ["teleport","wormhole"]: 439 | self.position, self.velocity = arg2 440 | 441 | if debug: print("Old position:",self.position) 442 | if direction != "wormhole": 443 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 444 | if debug: print("New position:",self.position) 445 | 446 | 447 | for i in range(3): 448 | while self.position[i] < self.bounds[i][0]: 449 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 450 | while self.position[i] >= self.bounds[i][1]: 451 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 452 | if debug: print("New position:",self.position) 453 | 454 | if direction == "jump": 455 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 456 | 457 | def push(self, L): 458 | if type(L) == list: 459 | self.stack.extend(L) 460 | elif type(L) == str: 461 | self.stack.extend(map(ord,L[::-1])) 462 | elif type(L) == int: 463 | self.stack.append(L) 464 | 465 | if debug: 466 | prog = Program(file, sys.argv[2], debugFlag=1) 467 | prog.run(numSteps) 468 | 469 | else: 470 | Program(file, sys.argv[2]).run() 471 | print() 472 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.7.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "array_test.mkl", ""] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [] 25 | for layer in filter(bool, code.split("$$$\n")): 26 | self.code.append([list(s) for s in layer.rstrip("\n").split("\n")]) 27 | 28 | if debug: print("Code:",self.code) 29 | self.codeput = {} 30 | 31 | self.inputStr = inputStr 32 | if debug: print("Input:",self.inputStr) 33 | 34 | self.position = [0,0,0] #[x,y,z] 35 | self.velocity = [1,0,0] #[dx,dy,dz] 36 | 37 | self.stack = [] 38 | self.array = [[]] 39 | self.loops = [] 40 | 41 | self.strLiteral = "" 42 | self.strMode = 0 43 | 44 | self.numLiteral = 0 45 | self.numMode = 0 46 | 47 | self.fallable = 1 48 | self.toggleFlag = 0 49 | self.fallFlag = 0 50 | self.stuckFlag = 0 51 | 52 | self.bounds = [[0,max([ max(map(len,layer)) for layer in self.code])], 53 | [0,max(map(len,self.code))], 54 | [0,len(self.code)]] 55 | if debug: print(self.bounds) 56 | for layer in self.code: 57 | for row in layer: 58 | row.extend([" "]*(self.bounds[0][1]-len(row)+1)) 59 | if debug: print(row) 60 | while len(layer) < self.bounds[1][1]: 61 | layer.append([" "]*self.bounds[0][1]) 62 | 63 | self.currChar = "" 64 | 65 | def run(self, steps=-1): #steps = -1 for run-until-halt 66 | while steps != 0: 67 | steps -= 1 68 | self.getCurrent() 69 | movedir = "" 70 | arg2 = None 71 | stack = self.loops[-1][3] if self.loops else self.stack 72 | 73 | if self.currChar == '"': 74 | self.fallable = not self.fallable 75 | self.strMode = not self.strMode 76 | 77 | if not self.strMode: 78 | ## self.push(self.strLiteral) 79 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 80 | self.strLiteral = "" 81 | if self.currChar == "'": 82 | self.fallable = not self.fallable 83 | self.numMode = not self.numMode 84 | 85 | if not self.numMode: 86 | ## self.push(self.numLiteral) 87 | stack.append(self.numLiteral) 88 | self.numLiteral = 0 89 | 90 | if self.currChar not in "'\"": 91 | if not self.strMode and not self.numMode: 92 | 93 | if self.currChar != " " and not self.fallable and not self.fallFlag: 94 | self.fallable = 1 95 | 96 | if self.currChar == ".": #stop execution 97 | return 98 | elif self.currChar == "$": #toggle functionality 99 | if self.stuckFlag: 100 | self.toggleFlag = 0 101 | self.stuckFlag = 0 102 | else: 103 | self.toggleFlag = 1 104 | elif self.currChar == "V": 105 | if self.fallFlag: 106 | self.fallable = 1 107 | self.fallFlag = 0 108 | else: 109 | self.fallable = 0 110 | self.fallFlag = self.toggleFlag 111 | elif self.currChar == "#": #net 112 | pass 113 | 114 | elif self.fallable and self.currChar == " ": 115 | movedir = "fall" 116 | elif self.currChar in "v<>^": 117 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 118 | 119 | elif self.currChar in "/\\_|": 120 | if self.currChar == "/": 121 | self.velocity = [-self.velocity[1], 122 | -self.velocity[0], 123 | self.velocity[2]] 124 | elif self.currChar == "\\": 125 | self.velocity = [self.velocity[1], 126 | self.velocity[0], 127 | self.velocity[2]] 128 | elif self.currChar == "_": 129 | self.velocity = [self.velocity[0], 130 | -self.velocity[1], 131 | self.velocity[2]] 132 | elif self.currChar == "|": 133 | self.velocity = [-self.velocity[0], 134 | self.velocity[1], 135 | self.velocity[2]] 136 | 137 | elif self.currChar in "0123456789": 138 | stack.append(int(self.currChar)) 139 | 140 | elif self.currChar in "+-*:;%=`": #operators and comparators 141 | if self.toggleFlag and self.currChar in "+*": 142 | if self.currChar == "+": 143 | result = sum(stack) 144 | elif self.currChar == "*": 145 | result = 1 146 | for s in stack: result *= s 147 | 148 | stack.clear() 149 | 150 | else: 151 | b = stack.pop() if stack else 0 152 | a = stack.pop() if stack else 0 153 | 154 | if self.currChar == "+": 155 | result = a+b 156 | elif self.currChar == "-": 157 | result = a-b if not self.toggleFlag else b-a 158 | elif self.currChar == "*": 159 | result = a*b 160 | elif self.currChar == ":": 161 | result = a//b if not self.toggleFlag else a/b 162 | elif self.currChar == ";": 163 | result = a**b if not self.toggleFlag else b**a 164 | elif self.currChar == "%": 165 | result = a%b if not self.toggleFlag else b%a 166 | elif self.currChar == "=": 167 | result = int(a==b if not self.toggleFlag else a!=b) 168 | elif self.currChar == "`": 169 | result = int(a>b if not self.toggleFlag else b>a) 170 | 171 | stack.append(result) 172 | 173 | elif self.currChar in "~,": #negation and not 174 | if len(stack) < 1: 175 | stack = [0]*(1-len(stack)) + stack 176 | 177 | b = stack.pop() 178 | 179 | if self.currChar == "~": 180 | stack.append(-b if not self.toggleFlag else abs(b)) 181 | elif self.currChar == ",": 182 | stack.append(int(not b if not self.toggleFlag else bool(b))) 183 | 184 | elif self.currChar in "!?@&": 185 | if self.currChar == "!": 186 | movedir = "jump" 187 | arg2 = 1 188 | else: 189 | tos = stack.pop() if stack else 0 190 | if self.currChar == "?" and tos: 191 | movedir = "jump" 192 | arg2 = 1 193 | elif self.currChar == "@": 194 | movedir = "jump" 195 | arg2 = tos 196 | elif self.currChar == "&" and (stack.pop() if stack else 0): 197 | movedir = "jump" 198 | arg2 = tos 199 | 200 | elif self.currChar in "no": #input 201 | if self.currChar == "n": 202 | beg = 0 203 | while self.inputStr[beg].isalpha(): beg += 1 204 | 205 | end = beg+1 206 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 207 | 208 | stack.append(int(self.inputStr[beg:end-1])) 209 | self.inputStr = self.inputStr[end-1:] 210 | elif self.currChar == "o": 211 | stack.append(ord(self.inputStr[0])) 212 | self.inputStr = self.inputStr[1:] 213 | 214 | elif self.currChar in "NO": #output 215 | tos = stack.pop() if stack else 0 216 | 217 | if self.currChar == "N": 218 | print(tos, end=' ', flush=True) 219 | elif self.currChar == "O": 220 | print(chr(int(tos)), end='', flush=True) 221 | 222 | elif self.currChar in "dD": #duplication 223 | tos = stack.pop() if stack else 0 224 | 225 | if self.currChar == "d": 226 | stack.extend([tos]*2) 227 | elif self.currChar == "D": 228 | n = stack.pop() if stack else 0 229 | stack.extend([n]*(tos+1)) 230 | 231 | elif self.currChar in "bB": #branches 232 | tos = stack.pop() if stack else 0 233 | if self.toggleFlag: tos = not tos 234 | 235 | if self.currChar == "b": 236 | if not tos: self.velocity = [-v for v in self.velocity] 237 | if self.currChar == "B": 238 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 239 | if not tos: self.velocity = [-v for v in self.velocity] 240 | 241 | elif self.currChar in "wW": #wormhole 242 | nz = stack.pop() if stack and self.currChar == "W" else 0 243 | ny = stack.pop() if stack else 0 244 | nx = stack.pop() if stack else 0 245 | 246 | movedir = "wormhole" 247 | arg2 = [[nx,ny,nz],self.velocity] 248 | 249 | elif self.currChar in "gG": #stack index/insert 250 | tos = stack.pop() if stack else 0 251 | 252 | if self.currChar == "g" and stack: 253 | stack.append(stack.pop(tos)) 254 | elif self.currChar == "G" and stack: 255 | toput = stack.pop() if stack else 0 256 | stack.insert(tos, toput) 257 | 258 | elif self.currChar in "xX": #dump 259 | if self.toggleFlag: 260 | stack.clear() 261 | else: 262 | tos = stack.pop() if stack else 0 263 | if self.currChar == "X": 264 | for i in range(min([tos,len(stack)])): stack.pop() 265 | 266 | elif self.currChar in "i": #loop counter 267 | stack.append(self.loops[-1][4] if self.loops else -1) 268 | elif self.currChar == "I": #stack length 269 | stack.append(len(stack)) 270 | 271 | elif self.currChar == "r": #reverse stack 272 | stack.reverse() 273 | elif self.currChar == "R": #rotates stack 274 | tos = stack.pop() if stack else 0 275 | mod = tos % len(stack) - (tos < 0) 276 | 277 | newstack = stack[-mod:] + stack[:-mod] 278 | stack.clear() 279 | stack.extend(newstack) 280 | 281 | elif self.currChar == "s": #sort 282 | if self.toggleFlag: 283 | tos = stack.pop() if stack else 0 284 | newstack = stack[-tos:] 285 | for n in newstack: stack.pop() 286 | newstack.sort(reverse=True) 287 | stack.extend(newstack) 288 | else: 289 | stack.sort(reverse=True) 290 | elif self.currChar == "S": #set 291 | tos = stack.pop() if stack and self.toggleFlag else 0 292 | newstack = stack[-tos:] 293 | for n in newstack: stack.pop() 294 | 295 | j = len(newstack)-1 296 | seen = [] 297 | while j >= 0: 298 | if newstack[j] not in seen: seen.append(newstack[j]) 299 | j -= 1 300 | 301 | stack.extend(seen[::-1]) 302 | 303 | elif self.currChar in "pP": #code put 304 | if self.currChar == "P": 305 | z = stack.pop() if stack else 0 306 | else: 307 | z = self.position[2] 308 | y = stack.pop() if stack else 0 309 | x = stack.pop() if stack else 0 310 | 311 | n = stack.pop() if stack else 0 312 | b = self.bounds 313 | 314 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 315 | self.code[z][y][x] = n 316 | else: 317 | self.codeput[(x,y,z)] = n 318 | 319 | elif self.currChar in "qQ": #code get 320 | if self.currChar == "Q": 321 | z = stack.pop() if stack else 0 322 | else: 323 | z = self.position[2] 324 | y = stack.pop() if stack else 0 325 | x = stack.pop() if stack else 0 326 | 327 | b = self.bounds 328 | 329 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 330 | q = self.code[z][y][x] 331 | stack.append(ord(q) if type(q) == str else q) 332 | else: 333 | if (x,y,z) in self.codeput: 334 | q = self.codeput[(x,y,z)] 335 | stack.append(ord(q) if type(q) == str else q) 336 | else: 337 | stack.append(0) 338 | 339 | elif self.currChar in "aA": #array get/put 340 | k = stack.pop() if stack and self.currChar == "A" else 0 341 | y = stack.pop() if stack else 0 342 | x = stack.pop() if stack else 0 343 | 344 | if x>=0 and y>=0: 345 | 346 | if self.currChar == "a": 347 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 348 | stack.append(self.array[y][x]) 349 | else: 350 | stack.append(0) 351 | 352 | elif self.currChar == "A": 353 | if debug: print(*self.array) 354 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 355 | pass 356 | else: 357 | for line in self.array: 358 | line.extend([0]*(x-len(line)+1)) 359 | while len(self.array) <= y: 360 | self.array.append([0]*(x+1)) 361 | if debug: print(*self.array) 362 | 363 | self.array[y][x] = k 364 | 365 | elif self.currChar in "()": #while loop 366 | if self.currChar == "(": 367 | tos = stack.pop() if stack and self.toggleFlag else 0 368 | 369 | newstack = stack[-tos:] 370 | self.loops.append(["while", 371 | self.position, 372 | self.velocity, 373 | newstack, 374 | 0]) 375 | 376 | if self.toggleFlag: 377 | for i in range(tos): stack.pop() 378 | else: 379 | stack.clear() 380 | 381 | elif self.currChar == ")": 382 | if self.loops[-1][0] != "while": 383 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 384 | 385 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 386 | lastLoop = self.loops.pop() 387 | parent = self.loops[-1][3] if self.loops else self.stack 388 | parent.extend(lastLoop[3][:-1]) 389 | else: 390 | self.loops[-1][4] += 1 #increment loop counter 391 | movedir = "teleport" 392 | arg2 = self.loops[-1][1:3] 393 | if debug: print(self.loops[-1][3]) 394 | 395 | elif self.currChar in "[]": #for loop 396 | if self.currChar == "[": 397 | iters = stack.pop() if stack else 0 398 | tos = stack.pop() if stack and self.toggleFlag else 0 399 | 400 | newstack = stack[len(stack)-tos:] 401 | self.loops.append(["for", 402 | self.position, 403 | self.velocity, 404 | newstack, 405 | 0, 406 | iters]) 407 | 408 | if self.toggleFlag: 409 | for i in range(min([tos,len(stack)])): stack.pop() 410 | else: 411 | pass 412 | 413 | elif self.currChar == "]": 414 | if self.loops[-1][0] != "for": 415 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 416 | 417 | if self.loops[-1][4] >= self.loops[-1][5]-1: 418 | lastLoop = self.loops.pop() 419 | if lastLoop[5]: 420 | parent = self.loops[-1][3] if self.loops else self.stack 421 | parent.extend(lastLoop[3]) 422 | else: 423 | self.loops[-1][4] += 1 #increment loop counter 424 | movedir = "teleport" 425 | arg2 = self.loops[-1][1:3] 426 | 427 | 428 | elif self.currChar in "{}": #recursion 429 | if self.currChar == "{": 430 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 431 | parentR = None 432 | num = stack.pop() if stack else 0 433 | else: #child recursion 434 | i = -1 435 | while self.loops[i][5]: i -= 1 #get parent recursion 436 | parentR = self.loops[i] 437 | num = self.loops[i][6] 438 | 439 | movedir = "teleport" 440 | arg2 = self.loops[i][1:3] 441 | 442 | newstack = stack[len(stack)-num:] 443 | for i in range(min([num,len(stack)])): stack.pop() 444 | 445 | self.loops.append(["recursion", 446 | self.position, 447 | self.velocity, 448 | newstack, 449 | 0, 450 | parentR, 451 | num]) 452 | 453 | elif self.currChar == "}": 454 | if self.loops[-1][0] != "recursion": 455 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 456 | 457 | lastLoop = self.loops.pop() 458 | parent = self.loops[-1][3] if self.loops else self.stack 459 | parent.extend(lastLoop[3]) 460 | 461 | if lastLoop[5]: 462 | movedir = "teleport" 463 | arg2 = lastLoop[1:3] 464 | 465 | else: 466 | pass 467 | else: 468 | if self.strMode: 469 | self.strLiteral += self.currChar 470 | elif self.numMode: 471 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 472 | 473 | if self.toggleFlag and self.currChar != "$" and not self.stuckFlag: self.toggleFlag = 0 474 | 475 | if debug: print(stack) 476 | self.move(movedir, arg2) 477 | 478 | def getCurrent(self): 479 | if debug: print(self.position) 480 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 481 | if type(self.currChar) != str: 482 | try: 483 | self.currChar = chr(self.currChar) 484 | except [ValueError, TypeError]: 485 | self.currChar = "" 486 | if debug: print("Current character:",self.currChar) 487 | 488 | def move(self, direction="", arg2=None): 489 | from math import copysign 490 | 491 | ## if debug: print("Old velocity:",self.velocity) 492 | if direction == "fall": self.velocity = [0,0,1] 493 | if direction == "down": self.velocity = [0,1,0] 494 | if direction == "left": self.velocity = [-1,0,0] 495 | if direction == "right": self.velocity = [1,0,0] 496 | if direction == "up": self.velocity = [0,-1,0] 497 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 498 | ## if debug: print("New velocity:",self.velocity) 499 | 500 | if direction in ["teleport","wormhole"]: 501 | self.position, self.velocity = arg2 502 | 503 | if debug: print("Old position:",self.position) 504 | if direction != "wormhole": 505 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 506 | if debug: print("New position:",self.position) 507 | 508 | 509 | for i in range(3): 510 | while self.position[i] < self.bounds[i][0]: 511 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 512 | while self.position[i] >= self.bounds[i][1]: 513 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 514 | if debug: print("New position:",self.position) 515 | 516 | if direction == "jump": 517 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 518 | 519 | def push(self, L): 520 | if type(L) == list: 521 | self.stack.extend(L) 522 | elif type(L) == str: 523 | self.stack.extend(map(ord,L[::-1])) 524 | elif type(L) == int: 525 | self.stack.append(L) 526 | 527 | if debug: 528 | prog = Program(file, sys.argv[2], debugFlag=1) 529 | prog.run(numSteps) 530 | 531 | else: 532 | Program(file, sys.argv[2]).run() 533 | print() 534 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.7_debuggable.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | debug = 0 5 | if "idlelib" in sys.modules: 6 | sys.argv = ["minkolang_0.1.py", "array_test.mkl", ""] 7 | debug = 1 8 | numSteps = 50 9 | 10 | if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 11 | if len(sys.argv) == 2: sys.argv.append("") 12 | 13 | ##print(sys.argv) 14 | ##print(os.curdir, os.getcwd()) 15 | 16 | file = open(sys.argv[1]).read() 17 | 18 | class Program: 19 | global debug 20 | def __init__(self, code, inputStr="", debugFlag=0): 21 | global debug 22 | debug = debugFlag 23 | 24 | self.code = [] 25 | for layer in filter(bool, code.split("$$$\n")): 26 | self.code.append([list(s) for s in layer.rstrip("\n").split("\n")]) 27 | 28 | if debug: print("Code:",self.code) 29 | self.codeput = {} 30 | 31 | self.inputStr = inputStr 32 | if debug: print("Input:",self.inputStr) 33 | 34 | self.position = [0,0,0] #[x,y,z] 35 | self.velocity = [1,0,0] #[dx,dy,dz] 36 | 37 | self.stack = [] 38 | self.array = [[]] 39 | self.loops = [] 40 | 41 | self.strLiteral = "" 42 | self.strMode = 0 43 | 44 | self.numLiteral = 0 45 | self.numMode = 0 46 | 47 | self.fallable = 1 48 | self.toggleFlag = 0 49 | self.fallFlag = 0 50 | self.stuckFlag = 0 51 | 52 | self.bounds = [[0,max([ max(map(len,layer)) for layer in self.code])], 53 | [0,max(map(len,self.code))], 54 | [0,len(self.code)]] 55 | if debug: print(self.bounds) 56 | for layer in self.code: 57 | for row in layer: 58 | row.extend([" "]*(self.bounds[0][1]-len(row)+1)) 59 | if debug: print(row) 60 | while len(layer) < self.bounds[1][1]: 61 | layer.append([" "]*self.bounds[0][1]) 62 | 63 | self.currChar = "" 64 | 65 | def run(self, steps=-1): #steps = -1 for run-until-halt 66 | while steps != 0: 67 | steps -= 1 68 | self.getCurrent() 69 | movedir = "" 70 | arg2 = None 71 | stack = self.loops[-1][3] if self.loops else self.stack 72 | 73 | if self.currChar == '"': 74 | self.fallable = not self.fallable 75 | self.strMode = not self.strMode 76 | 77 | if not self.strMode: 78 | ## self.push(self.strLiteral) 79 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 80 | self.strLiteral = "" 81 | if self.currChar == "'": 82 | self.fallable = not self.fallable 83 | self.numMode = not self.numMode 84 | 85 | if not self.numMode: 86 | ## self.push(self.numLiteral) 87 | stack.append(self.numLiteral) 88 | self.numLiteral = 0 89 | 90 | if self.currChar not in "'\"": 91 | if not self.strMode and not self.numMode: 92 | 93 | if self.currChar != " " and not self.fallable and not self.fallFlag: 94 | self.fallable = 1 95 | 96 | if self.currChar == ".": #stop execution 97 | return 98 | elif self.currChar == "$": #toggle functionality 99 | if self.stuckFlag: 100 | self.toggleFlag = 0 101 | self.stuckFlag = 0 102 | else: 103 | self.toggleFlag = 1 104 | elif self.currChar == "V": 105 | if self.fallFlag: 106 | self.fallable = 1 107 | self.fallFlag = 0 108 | else: 109 | self.fallable = 0 110 | self.fallFlag = self.toggleFlag 111 | elif self.currChar == "#": #net 112 | pass 113 | 114 | elif self.fallable and self.currChar == " ": 115 | movedir = "fall" 116 | elif self.currChar in "v<>^": 117 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 118 | 119 | elif self.currChar in "/\\_|": 120 | if self.currChar == "/": 121 | self.velocity = [-self.velocity[1], 122 | -self.velocity[0], 123 | self.velocity[2]] 124 | elif self.currChar == "\\": 125 | self.velocity = [self.velocity[1], 126 | self.velocity[0], 127 | self.velocity[2]] 128 | elif self.currChar == "_": 129 | self.velocity = [self.velocity[0], 130 | -self.velocity[1], 131 | self.velocity[2]] 132 | elif self.currChar == "|": 133 | self.velocity = [-self.velocity[0], 134 | self.velocity[1], 135 | self.velocity[2]] 136 | 137 | elif self.currChar in "0123456789": 138 | stack.append(int(self.currChar)) 139 | 140 | elif self.currChar in "+-*:;%=`": #operators and comparators 141 | if self.toggleFlag and self.currChar in "+*": 142 | if self.currChar == "+": 143 | result = sum(stack) 144 | elif self.currChar == "*": 145 | result = 1 146 | for s in stack: result *= s 147 | 148 | stack.clear() 149 | 150 | else: 151 | b = stack.pop() if stack else 0 152 | a = stack.pop() if stack else 0 153 | 154 | if self.currChar == "+": 155 | result = a+b 156 | elif self.currChar == "-": 157 | result = a-b if not self.toggleFlag else b-a 158 | elif self.currChar == "*": 159 | result = a*b 160 | elif self.currChar == ":": 161 | result = a//b if not self.toggleFlag else a/b 162 | elif self.currChar == ";": 163 | result = a**b if not self.toggleFlag else b**a 164 | elif self.currChar == "%": 165 | result = a%b if not self.toggleFlag else b%a 166 | elif self.currChar == "=": 167 | result = int(a==b if not self.toggleFlag else a!=b) 168 | elif self.currChar == "`": 169 | result = int(a>b if not self.toggleFlag else b>a) 170 | 171 | stack.append(result) 172 | 173 | elif self.currChar in "~,": #negation and not 174 | if len(stack) < 1: 175 | stack = [0]*(1-len(stack)) + stack 176 | 177 | b = stack.pop() 178 | 179 | if self.currChar == "~": 180 | stack.append(-b if not self.toggleFlag else abs(b)) 181 | elif self.currChar == ",": 182 | stack.append(int(not b if not self.toggleFlag else bool(b))) 183 | 184 | elif self.currChar in "!?@&": 185 | if self.currChar == "!": 186 | movedir = "jump" 187 | arg2 = 1 188 | else: 189 | tos = stack.pop() if stack else 0 190 | if self.currChar == "?" and tos: 191 | movedir = "jump" 192 | arg2 = 1 193 | elif self.currChar == "@": 194 | movedir = "jump" 195 | arg2 = tos 196 | elif self.currChar == "&" and (stack.pop() if stack else 0): 197 | movedir = "jump" 198 | arg2 = tos 199 | 200 | elif self.currChar in "no": #input 201 | if self.currChar == "n": 202 | beg = 0 203 | while self.inputStr[beg].isalpha(): beg += 1 204 | 205 | end = beg+1 206 | while end <= len(self.inputStr) and self.inputStr[beg:end].isdecimal(): end += 1 207 | 208 | stack.append(int(self.inputStr[beg:end-1])) 209 | self.inputStr = self.inputStr[end-1:] 210 | elif self.currChar == "o": 211 | stack.append(ord(self.inputStr[0])) 212 | self.inputStr = self.inputStr[1:] 213 | 214 | elif self.currChar in "NO": #output 215 | tos = stack.pop() if stack else 0 216 | 217 | if self.currChar == "N": 218 | print(tos, end=' ', flush=True) 219 | elif self.currChar == "O": 220 | print(chr(int(tos)), end='', flush=True) 221 | 222 | elif self.currChar in "dD": #duplication 223 | tos = stack.pop() if stack else 0 224 | 225 | if self.currChar == "d": 226 | stack.extend([tos]*2) 227 | elif self.currChar == "D": 228 | n = stack.pop() if stack else 0 229 | stack.extend([n]*(tos+1)) 230 | 231 | elif self.currChar in "bB": #branches 232 | tos = stack.pop() if stack else 0 233 | if self.toggleFlag: tos = not tos 234 | 235 | if self.currChar == "b": 236 | if not tos: self.velocity = [-v for v in self.velocity] 237 | if self.currChar == "B": 238 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 239 | if not tos: self.velocity = [-v for v in self.velocity] 240 | 241 | elif self.currChar in "wW": #wormhole 242 | nz = stack.pop() if stack and self.currChar == "W" else 0 243 | ny = stack.pop() if stack else 0 244 | nx = stack.pop() if stack else 0 245 | 246 | movedir = "wormhole" 247 | arg2 = [[nx,ny,nz],self.velocity] 248 | 249 | elif self.currChar in "gG": #stack index/insert 250 | tos = stack.pop() if stack else 0 251 | 252 | if self.currChar == "g" and stack: 253 | stack.append(stack.pop(tos)) 254 | elif self.currChar == "G" and stack: 255 | toput = stack.pop() if stack else 0 256 | stack.insert(tos, toput) 257 | 258 | elif self.currChar in "xX": #dump 259 | if self.toggleFlag: 260 | stack.clear() 261 | else: 262 | tos = stack.pop() if stack else 0 263 | if self.currChar == "X": 264 | for i in range(min([tos,len(stack)])): stack.pop() 265 | 266 | elif self.currChar in "i": #loop counter 267 | stack.append(self.loops[-1][4] if self.loops else -1) 268 | elif self.currChar == "I": #stack length 269 | stack.append(len(stack)) 270 | 271 | elif self.currChar == "r": #reverse stack 272 | stack.reverse() 273 | elif self.currChar == "R": #rotates stack 274 | tos = stack.pop() if stack else 0 275 | mod = tos % len(stack)# + (tos < 0) 276 | 277 | newstack = stack[-mod:] + stack[:-mod] 278 | stack.clear() 279 | stack.extend(newstack) 280 | 281 | elif self.currChar == "s": #sort 282 | if self.toggleFlag: 283 | tos = stack.pop() if stack else 0 284 | newstack = stack[-tos:] 285 | for n in newstack: stack.pop() 286 | newstack.sort(reverse=True) 287 | stack.extend(newstack) 288 | else: 289 | stack.sort(reverse=True) 290 | elif self.currChar == "S": #set 291 | tos = stack.pop() if stack and self.toggleFlag else 0 292 | newstack = stack[-tos:] 293 | for n in newstack: stack.pop() 294 | 295 | j = len(newstack)-1 296 | seen = [] 297 | while j >= 0: 298 | if newstack[j] not in seen: seen.append(newstack[j]) 299 | j -= 1 300 | 301 | stack.extend(seen[::-1]) 302 | 303 | elif self.currChar in "pP": #code put 304 | if self.currChar == "P": 305 | z = stack.pop() if stack else 0 306 | else: 307 | z = self.position[2] 308 | y = stack.pop() if stack else 0 309 | x = stack.pop() if stack else 0 310 | 311 | n = stack.pop() if stack else 0 312 | b = self.bounds 313 | 314 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 315 | self.code[z][y][x] = n 316 | else: 317 | self.codeput[(x,y,z)] = n 318 | 319 | elif self.currChar in "qQ": #code get 320 | if self.currChar == "Q": 321 | z = stack.pop() if stack else 0 322 | else: 323 | z = self.position[2] 324 | y = stack.pop() if stack else 0 325 | x = stack.pop() if stack else 0 326 | 327 | b = self.bounds 328 | 329 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 330 | q = self.code[z][y][x] 331 | stack.append(ord(q) if type(q) == str else q) 332 | else: 333 | if (x,y,z) in self.codeput: 334 | q = self.codeput[(x,y,z)] 335 | stack.append(ord(q) if type(q) == str else q) 336 | else: 337 | stack.append(0) 338 | 339 | elif self.currChar in "aA": #array get/put 340 | k = stack.pop() if stack and self.currChar == "A" else 0 341 | y = stack.pop() if stack else 0 342 | x = stack.pop() if stack else 0 343 | 344 | if x>=0 and y>=0: 345 | 346 | if self.currChar == "a": 347 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 348 | stack.append(self.array[y][x]) 349 | else: 350 | stack.append(0) 351 | 352 | elif self.currChar == "A": 353 | if debug: print(*self.array) 354 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 355 | pass 356 | else: 357 | for line in self.array: 358 | line.extend([0]*(x-len(line)+1)) 359 | while len(self.array) <= y: 360 | self.array.append([0]*(x+1)) 361 | if debug: print(*self.array) 362 | 363 | self.array[y][x] = k 364 | 365 | elif self.currChar == "u": 366 | print(stack) 367 | elif self.currChar == "U": 368 | print(*self.code) 369 | print(*self.loops) 370 | 371 | elif self.currChar in "()": #while loop 372 | if self.currChar == "(": 373 | tos = stack.pop() if stack and self.toggleFlag else 0 374 | 375 | newstack = stack[-tos:] 376 | self.loops.append(["while", 377 | self.position, 378 | self.velocity, 379 | newstack, 380 | 0]) 381 | 382 | if self.toggleFlag: 383 | for i in range(tos): stack.pop() 384 | else: 385 | stack.clear() 386 | 387 | elif self.currChar == ")": 388 | if self.loops[-1][0] != "while": 389 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 390 | 391 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 392 | lastLoop = self.loops.pop() 393 | parent = self.loops[-1][3] if self.loops else self.stack 394 | parent.extend(lastLoop[3][:-1]) 395 | else: 396 | self.loops[-1][4] += 1 #increment loop counter 397 | movedir = "teleport" 398 | arg2 = self.loops[-1][1:3] 399 | if debug: print(self.loops[-1][3]) 400 | 401 | elif self.currChar in "[]": #for loop 402 | if self.currChar == "[": 403 | iters = stack.pop() if stack else 0 404 | tos = stack.pop() if stack and self.toggleFlag else 0 405 | 406 | newstack = stack[len(stack)-tos:] 407 | self.loops.append(["for", 408 | self.position, 409 | self.velocity, 410 | newstack, 411 | 0, 412 | iters]) 413 | 414 | if self.toggleFlag: 415 | for i in range(min([tos,len(stack)])): stack.pop() 416 | else: 417 | pass 418 | 419 | elif self.currChar == "]": 420 | if self.loops[-1][0] != "for": 421 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 422 | 423 | if self.loops[-1][4] >= self.loops[-1][5]-1: 424 | lastLoop = self.loops.pop() 425 | if lastLoop[5]: 426 | parent = self.loops[-1][3] if self.loops else self.stack 427 | parent.extend(lastLoop[3]) 428 | else: 429 | self.loops[-1][4] += 1 #increment loop counter 430 | movedir = "teleport" 431 | arg2 = self.loops[-1][1:3] 432 | 433 | 434 | elif self.currChar in "{}": #recursion 435 | if self.currChar == "{": 436 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 437 | parentR = None 438 | num = stack.pop() if stack else 0 439 | else: #child recursion 440 | i = -1 441 | while self.loops[i][5]: i -= 1 #get parent recursion 442 | parentR = self.loops[i] 443 | num = self.loops[i][6] 444 | 445 | movedir = "teleport" 446 | arg2 = self.loops[i][1:3] 447 | 448 | newstack = stack[len(stack)-num:] 449 | for i in range(min([num,len(stack)])): stack.pop() 450 | 451 | self.loops.append(["recursion", 452 | self.position, 453 | self.velocity, 454 | newstack, 455 | 0, 456 | parentR, 457 | num]) 458 | 459 | elif self.currChar == "}": 460 | if self.loops[-1][0] != "recursion": 461 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 462 | 463 | lastLoop = self.loops.pop() 464 | parent = self.loops[-1][3] if self.loops else self.stack 465 | parent.extend(lastLoop[3]) 466 | 467 | if lastLoop[5]: 468 | movedir = "teleport" 469 | arg2 = lastLoop[1:3] 470 | 471 | else: 472 | pass 473 | else: 474 | if self.strMode: 475 | self.strLiteral += self.currChar 476 | elif self.numMode: 477 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 478 | 479 | if self.toggleFlag and self.currChar != "$" and not self.stuckFlag: self.toggleFlag = 0 480 | 481 | if debug: print(stack) 482 | self.move(movedir, arg2) 483 | 484 | def getCurrent(self): 485 | if debug: print(self.position) 486 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 487 | if type(self.currChar) != str: 488 | try: 489 | self.currChar = chr(self.currChar) 490 | except [ValueError, TypeError]: 491 | self.currChar = "" 492 | if debug: print("Current character:",self.currChar) 493 | 494 | def move(self, direction="", arg2=None): 495 | from math import copysign 496 | 497 | ## if debug: print("Old velocity:",self.velocity) 498 | if direction == "fall": self.velocity = [0,0,1] 499 | if direction == "down": self.velocity = [0,1,0] 500 | if direction == "left": self.velocity = [-1,0,0] 501 | if direction == "right": self.velocity = [1,0,0] 502 | if direction == "up": self.velocity = [0,-1,0] 503 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 504 | ## if debug: print("New velocity:",self.velocity) 505 | 506 | if direction in ["teleport","wormhole"]: 507 | self.position, self.velocity = arg2 508 | 509 | if debug: print("Old position:",self.position) 510 | if direction != "wormhole": 511 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 512 | if debug: print("New position:",self.position) 513 | 514 | 515 | for i in range(3): 516 | while self.position[i] < self.bounds[i][0]: 517 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 518 | while self.position[i] >= self.bounds[i][1]: 519 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 520 | if debug: print("New position:",self.position) 521 | 522 | if direction == "jump": 523 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 524 | 525 | def push(self, L): 526 | if type(L) == list: 527 | self.stack.extend(L) 528 | elif type(L) == str: 529 | self.stack.extend(map(ord,L[::-1])) 530 | elif type(L) == int: 531 | self.stack.append(L) 532 | 533 | if debug: 534 | prog = Program(file, sys.argv[2], debugFlag=1) 535 | prog.run(numSteps) 536 | 537 | else: 538 | Program(file, sys.argv[2]).run() 539 | print() 540 | -------------------------------------------------------------------------------- /oldcode/minkolang_0.8.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | ##import signal 4 | 5 | debug = 0 6 | if "idlelib" in sys.modules: 7 | sys.argv = ["minkolang_0.1.py", "PPCG_ISawThatComing.mkl", "-3"] 8 | debug = 1 9 | numSteps = 100 10 | 11 | ##if len(sys.argv) < 2: raise ValueError("Need at least one file name!") 12 | ##if len(sys.argv) == 2: sys.argv.append("") 13 | 14 | ##print(sys.argv) 15 | ##print(os.curdir, os.getcwd()) 16 | 17 | if len(sys.argv) > 1 and sys.argv[1][-4:] == ".mkl": 18 | file = open(sys.argv[1]).read() 19 | else: 20 | file = None 21 | 22 | class Program: 23 | global debug 24 | def __init__(self, code, inputStr="", debugFlag=0, outfile=sys.stdout): 25 | global debug 26 | debug = debugFlag 27 | 28 | self.code = [] 29 | for layer in filter(bool, code.split("$$$\n")): 30 | self.code.append([list(s) for s in layer.rstrip("\n").split("\n")]) 31 | 32 | if debug: print("Code:",self.code) 33 | self.codeput = {} 34 | 35 | self.inputStr = inputStr 36 | if debug: print("Input:",self.inputStr) 37 | 38 | self.position = [0,0,0] #[x,y,z] 39 | self.velocity = [1,0,0] #[dx,dy,dz] 40 | self.oldposition = self.position[:] 41 | 42 | self.stack = [] 43 | self.array = [[]] 44 | self.loops = [] 45 | 46 | self.strLiteral = "" 47 | self.strMode = 0 48 | 49 | self.numLiteral = 0 50 | self.numMode = 0 51 | 52 | self.fallable = 1 53 | self.toggleFlag = 0 54 | self.fallFlag = 0 55 | self.stuckFlag = 0 56 | 57 | self.bounds = [[0,max([ max(map(len,layer)) for layer in self.code])], 58 | [0,max(map(len,self.code))], 59 | [0,len(self.code)]] 60 | if debug: print(self.bounds) 61 | for layer in self.code: 62 | for row in layer: 63 | row.extend([" "]*(self.bounds[0][1]-len(row))) 64 | if debug: print(row) 65 | while len(layer) < self.bounds[1][1]: 66 | layer.append([" "]*self.bounds[0][1]) 67 | 68 | self.currChar = "" 69 | self.output = "" 70 | if outfile == None: 71 | self.outfile = open(os.devnull, 'w') 72 | else: 73 | self.outfile = outfile 74 | 75 | self.stopNow = False 76 | 77 | def run(self, steps=-1): #steps = -1 for run-until-halt 78 | self.stopNow = False 79 | 80 | while steps != 0 and self.stopNow == False: 81 | steps -= 1 82 | self.getCurrent() 83 | movedir = "" 84 | arg2 = None 85 | stack = self.loops[-1][3] if self.loops else self.stack 86 | 87 | if self.currChar == '"': 88 | self.fallable = not self.fallable 89 | self.strMode = not self.strMode 90 | 91 | if not self.strMode: 92 | ## self.push(self.strLiteral) 93 | stack.extend(list(map(ord,self.strLiteral[::-1]))) 94 | self.strLiteral = "" 95 | if self.currChar == "'": 96 | self.fallable = not self.fallable 97 | self.numMode = not self.numMode 98 | 99 | if not self.numMode: 100 | ## self.push(self.numLiteral) 101 | stack.append(self.numLiteral) 102 | self.numLiteral = 0 103 | 104 | if self.currChar not in "'\"": 105 | if not self.strMode and not self.numMode: 106 | 107 | if self.currChar != " " and not self.fallable and not self.fallFlag: 108 | self.fallable = 1 109 | 110 | if self.currChar == ".": #stop execution 111 | self.oldposition = self.position 112 | return 113 | elif self.currChar == "$": #toggle functionality 114 | if self.stuckFlag: 115 | self.toggleFlag = 0 116 | self.stuckFlag = 0 117 | else: 118 | self.toggleFlag = 1 119 | elif self.currChar == "V": 120 | if self.fallFlag: 121 | self.fallable = 1 122 | self.fallFlag = 0 123 | else: 124 | self.fallable = 0 125 | self.fallFlag = self.toggleFlag 126 | elif self.currChar == "#": #net 127 | pass 128 | 129 | elif self.fallable and self.currChar == " ": 130 | movedir = "fall" 131 | elif self.currChar in "v<>^": 132 | movedir = {"v":"down","<":"left",">":"right","^":"up"}[self.currChar] 133 | 134 | elif self.currChar in "/\\_|": 135 | if self.currChar == "/": 136 | self.velocity = [-self.velocity[1], 137 | -self.velocity[0], 138 | self.velocity[2]] 139 | elif self.currChar == "\\": 140 | self.velocity = [self.velocity[1], 141 | self.velocity[0], 142 | self.velocity[2]] 143 | elif self.currChar == "_": 144 | self.velocity = [self.velocity[0], 145 | -self.velocity[1], 146 | self.velocity[2]] 147 | elif self.currChar == "|": 148 | self.velocity = [-self.velocity[0], 149 | self.velocity[1], 150 | self.velocity[2]] 151 | 152 | elif self.currChar in "0123456789": 153 | stack.append(int(self.currChar)) 154 | 155 | elif self.currChar in "+-*:;%=`": #operators and comparators 156 | if self.toggleFlag and self.currChar in "+*": 157 | if self.currChar == "+": 158 | result = sum(stack) 159 | elif self.currChar == "*": 160 | result = 1 161 | for s in stack: result *= s 162 | 163 | stack.clear() 164 | 165 | else: 166 | b = stack.pop() if stack else 0 167 | a = stack.pop() if stack else 0 168 | 169 | if self.currChar == "+": 170 | result = a+b 171 | elif self.currChar == "-": 172 | result = a-b if not self.toggleFlag else b-a 173 | elif self.currChar == "*": 174 | result = a*b 175 | elif self.currChar == ":": 176 | result = a//b if not self.toggleFlag else a/b 177 | elif self.currChar == ";": 178 | result = a**b if not self.toggleFlag else b**a 179 | elif self.currChar == "%": 180 | result = a%b if not self.toggleFlag else b%a 181 | elif self.currChar == "=": 182 | result = int(a==b if not self.toggleFlag else a!=b) 183 | elif self.currChar == "`": 184 | result = int(a>b if not self.toggleFlag else b>a) 185 | 186 | stack.append(result) 187 | 188 | elif self.currChar in "~,": #negation and not 189 | if len(stack) < 1: 190 | stack = [0]*(1-len(stack)) + stack 191 | 192 | b = stack.pop() 193 | 194 | if self.currChar == "~": 195 | stack.append(-b if not self.toggleFlag else abs(b)) 196 | elif self.currChar == ",": 197 | stack.append(int(not b if not self.toggleFlag else bool(b))) 198 | 199 | elif self.currChar in "!?@&": 200 | if self.currChar == "!": 201 | movedir = "jump" 202 | arg2 = 1 203 | else: 204 | tos = stack.pop() if stack else 0 205 | if self.currChar == "?" and tos: 206 | movedir = "jump" 207 | arg2 = 1 208 | elif self.currChar == "@": 209 | movedir = "jump" 210 | arg2 = tos 211 | elif self.currChar == "&" and (stack.pop() if stack else 0): 212 | movedir = "jump" 213 | arg2 = tos 214 | 215 | elif self.currChar in "no": #input 216 | if self.currChar == "n": 217 | beg = 0 218 | while beg < len(self.inputStr) and not self.inputStr[beg].isdecimal(): 219 | if debug: print(beg, self.inputStr[beg]) 220 | beg += 1 221 | 222 | if beg >= len(self.inputStr): 223 | stack.append(-1) 224 | self.inputStr = "" 225 | else: 226 | end = beg+1 227 | num = 0.0 228 | 229 | while end <= len(self.inputStr): 230 | try: 231 | num = float(self.inputStr[beg:end]) 232 | end += 1 233 | except ValueError: 234 | break 235 | 236 | if num.is_integer(): num = int(num) 237 | 238 | if self.inputStr[beg-1] == "-": num *= -1 239 | 240 | stack.append(num) 241 | self.inputStr = self.inputStr[end-1:] 242 | 243 | elif self.currChar == "o": 244 | if not len(self.inputStr): 245 | stack.append(0) 246 | else: 247 | stack.append(ord(self.inputStr[0])) 248 | self.inputStr = self.inputStr[1:] 249 | 250 | elif self.currChar in "NO": #output 251 | tos = stack.pop() if stack else 0 252 | 253 | if self.currChar == "N": 254 | print(tos, end=' ', flush=True, file=self.outfile) 255 | self.output += str(tos) + ' ' 256 | elif self.currChar == "O": 257 | try: 258 | c = chr(int(tos)) 259 | except ValueError: 260 | c = "" 261 | print(c, end='', flush=True, file=self.outfile) 262 | self.output += c 263 | 264 | elif self.currChar in "dD": #duplication 265 | tos = stack.pop() if stack else 0 266 | 267 | if self.currChar == "d": 268 | stack.extend([tos]*2) 269 | elif self.currChar == "D": 270 | n = stack.pop() if stack else 0 271 | stack.extend([n]*(tos+1)) 272 | 273 | elif self.currChar in "bB": #branches 274 | tos = stack.pop() if stack else 0 275 | if self.toggleFlag: tos = not tos 276 | 277 | if self.currChar == "b": 278 | if not tos: self.velocity = [-v for v in self.velocity] 279 | if self.currChar == "B": 280 | self.velocity = [self.velocity[1],self.velocity[0],self.velocity[2]] 281 | if not tos: self.velocity = [-v for v in self.velocity] 282 | 283 | elif self.currChar in "wW": #wormhole 284 | nz = stack.pop() if stack and self.currChar == "W" else 0 285 | ny = stack.pop() if stack else 0 286 | nx = stack.pop() if stack else 0 287 | 288 | movedir = "wormhole" 289 | arg2 = [[nx,ny,nz],self.velocity] 290 | 291 | elif self.currChar in "gG": #stack index/insert 292 | tos = stack.pop() if stack else 0 293 | 294 | if self.currChar == "g" and stack: 295 | stack.append(stack.pop(tos)) 296 | elif self.currChar == "G" and stack: 297 | toput = stack.pop() if stack else 0 298 | stack.insert(tos, toput) 299 | 300 | elif self.currChar in "xX": #dump 301 | if self.toggleFlag: 302 | stack.clear() 303 | else: 304 | tos = stack.pop() if stack else 0 305 | if self.currChar == "X": 306 | for i in range(min([tos,len(stack)])): stack.pop() 307 | 308 | elif self.currChar in "i": #loop counter 309 | stack.append(self.loops[-1][4] if self.loops else -1) 310 | elif self.currChar == "I": #stack length 311 | stack.append(len(stack)) 312 | 313 | elif self.currChar == "r": #reverse stack 314 | stack.reverse() 315 | elif self.currChar == "R": #rotates stack 316 | tos = stack.pop() if stack else 0 317 | mod = tos % len(stack) 318 | 319 | newstack = stack[-mod:] + stack[:-mod] 320 | stack.clear() 321 | stack.extend(newstack) 322 | 323 | elif self.currChar == "s": #sort 324 | if self.toggleFlag: 325 | tos = stack.pop() if stack else 0 326 | newstack = stack[-tos:] 327 | for n in newstack: stack.pop() 328 | newstack.sort(reverse=True) 329 | stack.extend(newstack) 330 | else: 331 | stack.sort(reverse=True) 332 | elif self.currChar == "S": #set 333 | tos = stack.pop() if stack and self.toggleFlag else 0 334 | newstack = stack[-tos:] 335 | for n in newstack: stack.pop() 336 | 337 | j = len(newstack)-1 338 | seen = [] 339 | while j >= 0: 340 | if newstack[j] not in seen: seen.append(newstack[j]) 341 | j -= 1 342 | 343 | stack.extend(seen[::-1]) 344 | 345 | elif self.currChar in "pP": #code put 346 | if self.currChar == "P": 347 | z = stack.pop() if stack else 0 348 | else: 349 | z = self.position[2] 350 | y = stack.pop() if stack else 0 351 | x = stack.pop() if stack else 0 352 | 353 | n = stack.pop() if stack else 0 354 | b = self.bounds 355 | 356 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 357 | self.code[z][y][x] = n 358 | else: 359 | self.codeput[(x,y,z)] = n 360 | 361 | elif self.currChar in "qQ": #code get 362 | if self.currChar == "Q": 363 | z = stack.pop() if stack else 0 364 | else: 365 | z = self.position[2] 366 | y = stack.pop() if stack else 0 367 | x = stack.pop() if stack else 0 368 | 369 | b = self.bounds 370 | 371 | if b[0][0] <= x < b[0][1] and b[1][0] <= y < b[1][1] and b[2][0] <= z < b[2][1]: 372 | q = self.code[z][y][x] 373 | stack.append(ord(q) if type(q) == str else q) 374 | else: 375 | if (x,y,z) in self.codeput: 376 | q = self.codeput[(x,y,z)] 377 | stack.append(ord(q) if type(q) == str else q) 378 | else: 379 | stack.append(0) 380 | 381 | elif self.currChar in "aA": #array get/put 382 | k = stack.pop() if stack and self.currChar == "A" else 0 383 | y = stack.pop() if stack else 0 384 | x = stack.pop() if stack else 0 385 | 386 | if x>=0 and y>=0: 387 | 388 | if self.currChar == "a": 389 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 390 | stack.append(self.array[y][x]) 391 | else: 392 | stack.append(0) 393 | 394 | elif self.currChar == "A": 395 | if debug: print(*self.array) 396 | if 0 <= y < len(self.array) and 0 <= x < len(self.array[0]): 397 | pass 398 | else: 399 | for line in self.array: 400 | line.extend([0]*(x-len(line)+1)) 401 | while len(self.array) <= y: 402 | self.array.append([0]*(x+1)) 403 | if debug: print(*self.array) 404 | 405 | self.array[y][x] = k 406 | 407 | elif self.currChar == "u": 408 | print(stack, file=self.outfile) 409 | elif self.currChar == "U": 410 | print(*self.code, file=self.outfile) 411 | print(*self.loops, file=self.outfile) 412 | 413 | elif self.currChar in "()": #while loop 414 | if self.currChar == "(": 415 | tos = stack.pop() if stack and self.toggleFlag else 0 416 | 417 | newstack = stack[-tos:] 418 | self.loops.append(["while", 419 | self.position, 420 | self.velocity, 421 | newstack, 422 | 0]) 423 | 424 | if self.toggleFlag: 425 | for n in newstack: stack.pop() 426 | else: 427 | stack.clear() 428 | 429 | elif self.currChar == ")": 430 | if self.loops[-1][0] != "while": 431 | raise ValueError("Expected a while loop. Got a %s loop."%self.loops[-1][0]) 432 | 433 | if len(self.loops[-1][3]) == 0 or self.loops[-1][3][-1] == 0: 434 | lastLoop = self.loops.pop() 435 | parent = self.loops[-1][3] if self.loops else self.stack 436 | parent.extend(lastLoop[3][:-1]) 437 | else: 438 | self.loops[-1][4] += 1 #increment loop counter 439 | movedir = "teleport" 440 | arg2 = self.loops[-1][1:3] 441 | if debug: print(self.loops[-1][3]) 442 | 443 | elif self.currChar in "[]": #for loop 444 | if self.currChar == "[": 445 | iters = stack.pop() if stack else 0 446 | tos = stack.pop() if stack and self.toggleFlag else 0 447 | 448 | newstack = stack[-tos:] 449 | self.loops.append(["for", 450 | self.position, 451 | self.velocity, 452 | newstack, 453 | 0, 454 | iters]) 455 | 456 | if self.toggleFlag: 457 | for n in newstack: stack.pop() 458 | else: 459 | stack.clear() 460 | 461 | elif self.currChar == "]": 462 | if self.loops[-1][0] != "for": 463 | raise ValueError("Expected a for loop. Got a %s loop."%self.loops[-1][0]) 464 | 465 | if self.loops[-1][4] >= self.loops[-1][5]-1: 466 | lastLoop = self.loops.pop() 467 | if lastLoop[5]: 468 | parent = self.loops[-1][3] if self.loops else self.stack 469 | parent.extend(lastLoop[3]) 470 | else: 471 | self.loops[-1][4] += 1 #increment loop counter 472 | movedir = "teleport" 473 | arg2 = self.loops[-1][1:3] 474 | 475 | 476 | elif self.currChar in "{}": #recursion 477 | if self.currChar == "{": 478 | if not self.loops or self.loops[-1][0] != "recursion" or self.toggleFlag: #new function 479 | parentR = None 480 | num = stack.pop() if stack else 0 481 | else: #child recursion 482 | i = -1 483 | while self.loops[i][5]: i -= 1 #get parent recursion 484 | parentR = self.loops[i] 485 | num = self.loops[i][6] 486 | 487 | movedir = "teleport" 488 | arg2 = self.loops[i][1:3] 489 | 490 | newstack = stack[len(stack)-num:] 491 | for i in range(min([num,len(stack)])): stack.pop() 492 | 493 | self.loops.append(["recursion", 494 | self.position, 495 | self.velocity, 496 | newstack, 497 | 0, 498 | parentR, 499 | num]) 500 | 501 | elif self.currChar == "}": 502 | if self.loops[-1][0] != "recursion": 503 | raise ValueError("Expected recursion. Got a %s loop."%self.loops[-1][0]) 504 | 505 | lastLoop = self.loops.pop() 506 | parent = self.loops[-1][3] if self.loops else self.stack 507 | parent.extend(lastLoop[3]) 508 | 509 | if lastLoop[5]: 510 | movedir = "teleport" 511 | arg2 = lastLoop[1:3] 512 | 513 | else: 514 | pass 515 | else: #if in string or number mode 516 | if self.strMode: 517 | self.strLiteral += self.currChar 518 | elif self.numMode: 519 | if self.currChar == "-": 520 | self.numLiteral *= -1 521 | elif self.currChar.isdigit(): 522 | self.numLiteral = 10*self.numLiteral + int(self.currChar) 523 | 524 | if self.toggleFlag and self.currChar != "$" and not self.stuckFlag: self.toggleFlag = 0 525 | 526 | if debug: print(stack) 527 | self.move(movedir, arg2) 528 | 529 | def getCurrent(self): 530 | if debug: print(self.position) 531 | self.currChar = self.code[self.position[2]][self.position[1]][self.position[0]] 532 | if type(self.currChar) != str: 533 | try: 534 | self.currChar = chr(self.currChar) 535 | except [ValueError, TypeError]: 536 | self.currChar = "" 537 | if debug: print("Current character:",self.currChar) 538 | 539 | def move(self, direction="", arg2=None): 540 | from math import copysign 541 | self.oldposition = self.position[:] 542 | 543 | ## if debug: print("Old velocity:",self.velocity) 544 | if direction == "fall": self.velocity = [0,0,1] 545 | if direction == "down": self.velocity = [0,1,0] 546 | if direction == "left": self.velocity = [-1,0,0] 547 | if direction == "right": self.velocity = [1,0,0] 548 | if direction == "up": self.velocity = [0,-1,0] 549 | if direction == "jump": self.velocity = [(arg2+1)*v for v in self.velocity] 550 | ## if debug: print("New velocity:",self.velocity) 551 | 552 | if direction in ["teleport","wormhole"]: 553 | self.position, self.velocity = arg2 554 | 555 | if debug: print("Old position:",self.position) 556 | if direction != "wormhole": 557 | self.position = [a+b for a,b in zip(self.position, self.velocity)] 558 | if debug: print("New position:",self.position) 559 | 560 | 561 | for i in range(3): 562 | while self.position[i] < self.bounds[i][0]: 563 | self.position[i] += (self.bounds[i][1]-self.bounds[i][0]) 564 | while self.position[i] >= self.bounds[i][1]: 565 | self.position[i] -= (self.bounds[i][1]-self.bounds[i][0]) 566 | if debug: print("New position:",self.position) 567 | 568 | if direction == "jump": 569 | self.velocity = [bool(v)*int(copysign(1,v)) for v in self.velocity] #resets after a jump 570 | 571 | def push(self, L): 572 | if type(L) == list: 573 | self.stack.extend(L) 574 | elif type(L) == str: 575 | self.stack.extend(map(ord,L[::-1])) 576 | elif type(L) == int: 577 | self.stack.append(L) 578 | 579 | def getCode(self): return self.code 580 | def getArray(self): return self.array 581 | def getLoops(self): return self.loops 582 | def getStack(self): return self.stack 583 | def getOutput(self): return self.output 584 | def getPosition(self): return self.position 585 | def getvelocity(self): return self.velocity 586 | def getOldPosition(self): return self.oldposition 587 | 588 | def stop(self): self.stopNow = True 589 | 590 | if file: 591 | if debug: 592 | prog = Program(file, sys.argv[2], debugFlag=1) 593 | prog.run(numSteps) 594 | 595 | else: 596 | Program(file, sys.argv[2]).run() 597 | print() 598 | -------------------------------------------------------------------------------- /remainingCommandsAssigned.txt: -------------------------------------------------------------------------------- 1 | U Base conversion 2 | W Strings --------------------------------------------------------------------------------