diff --git a/.gitignore b/.gitignore index 7c74bb519..7ea5fe64d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,19 @@ +# Lambda template +_build +_coverage +/_esy +/node_modules +/esy.lock +/.melange.eobjs + +# Fsharp +test +*.fs +*.fsi + +# Fsharp Ionide +.fake + +# MS _build .DS_Store diff --git a/CSharpStrange/.envrc b/CSharpStrange/.envrc deleted file mode 100644 index 686a37170..000000000 --- a/CSharpStrange/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) diff --git a/CSharpStrange/.gitignore b/CSharpStrange/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/CSharpStrange/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/CSharpStrange/.ocamlformat b/CSharpStrange/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/CSharpStrange/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/CSharpStrange/.zanuda b/CSharpStrange/.zanuda deleted file mode 100644 index 39f42da0d..000000000 --- a/CSharpStrange/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml \ No newline at end of file diff --git a/CSharpStrange/COPYING b/CSharpStrange/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/CSharpStrange/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/CSharpStrange/COPYING.CC0 b/CSharpStrange/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/CSharpStrange/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/CSharpStrange/COPYING.LESSER b/CSharpStrange/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/CSharpStrange/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/CSharpStrange/CSharpStrange.opam b/CSharpStrange/CSharpStrange.opam deleted file mode 100644 index 7e5c764d0..000000000 --- a/CSharpStrange/CSharpStrange.opam +++ /dev/null @@ -1,36 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for strange subset of C# language" -description: - "An interpreter for subset of C# language with async/await and LINQ (and some other stuff which will be added later)" -maintainer: ["Dmitrii Kuznetsov dmitrvlkuznetsov@gmail.com"] -authors: ["Dmitrii Kuznetsov dmitrvlkuznetsov@gmail.com"] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/f1i3g3/fp2024" -bug-reports: "https://github.com/f1i3g3/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "base" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/CSharpStrange/Makefile b/CSharpStrange/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/CSharpStrange/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/CSharpStrange/bin/REPL.ml b/CSharpStrange/bin/REPL.ml deleted file mode 100644 index 26d45ea39..000000000 --- a/CSharpStrange/bin/REPL.ml +++ /dev/null @@ -1,31 +0,0 @@ -open C_sharp_strange_lib.Ast -open C_sharp_strange_lib.Parser -open Printf -open Stdio - -type opts = - { mutable dump_parse_tree : bool - ; mutable file_path : string option - } - -let () = - let opts = { dump_parse_tree = false; file_path = None } in - let _ = - Arg.parse - [ "-parseast", Arg.Unit (fun () -> opts.dump_parse_tree <- true), "\n" - ; "-filepath", Arg.String (fun file_path -> opts.file_path <- Some file_path), "\n" - ] - (fun _ -> - Stdlib.Format.eprintf "Something got wrong\n"; - Stdlib.exit 1) - "\n" - in - let path = - match opts.file_path with - | None -> String.trim @@ In_channel.input_all stdin - | Some path -> String.trim @@ In_channel.read_all path - in - match apply_parser parse_prog path with - | Ok ast -> if opts.dump_parse_tree then print_endline (show_program ast) - | Error msg -> failwith (sprintf "Failed to parse file: %s" msg) -;; diff --git a/CSharpStrange/bin/dune b/CSharpStrange/bin/dune deleted file mode 100644 index f1f0d7674..000000000 --- a/CSharpStrange/bin/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (modules REPL) - (libraries c_sharp_strange_lib stdio) - (instrumentation - (backend bisect_ppx))) diff --git a/CSharpStrange/bin/factorial.cs b/CSharpStrange/bin/factorial.cs deleted file mode 100644 index f85758ec7..000000000 --- a/CSharpStrange/bin/factorial.cs +++ /dev/null @@ -1,19 +0,0 @@ -public class Program -{ - public int Factorial(int n) - { - if (n == 0) - { - return 1; - } - else - { - return n * Factorial(n - 1); - } - } - - public static void Main() - { - - } -} \ No newline at end of file diff --git a/CSharpStrange/dune-project b/CSharpStrange/dune-project deleted file mode 100644 index dba4e1cb9..000000000 --- a/CSharpStrange/dune-project +++ /dev/null @@ -1,35 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Dmitrii Kuznetsov dmitrvlkuznetsov@gmail.com") - -(maintainers "Dmitrii Kuznetsov dmitrvlkuznetsov@gmail.com") - -(bug_reports "https://github.com/f1i3g3/fp2024") - -(homepage "https://github.com/f1i3g3/fp2024") - -(package - (name CSharpStrange) - (synopsis "An interpreter for strange subset of C# language") - (description - "An interpreter for subset of C# language with async/await and LINQ (and some other stuff which will be added later)") - ; TODO: actual documentation (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - base - ; After adding dependencies to 'dune' files add the same dependecies here too - )) diff --git a/CSharpStrange/lib/ast.ml b/CSharpStrange/lib/ast.ml deleted file mode 100644 index 7f03ac5b9..000000000 --- a/CSharpStrange/lib/ast.ml +++ /dev/null @@ -1,108 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** Values types *) -type val_type = - | ValInt of int (** Int value *) - | ValChar of char (** Char value *) - | ValNull (** Null *) - | ValBool of bool (** Bool value *) - | ValString of string (** string value *) -[@@deriving eq, show { with_path = false }] - -(** Identidicator *) -type ident = Id of string [@@deriving eq, show { with_path = false }] - -(** Basic types declarations *) -type base_type = - | TypeInt (** Declaration of int *) - | TypeChar (** Declaration of char *) - | TypeBool (** Declaration of bool *) - | TypeString (** Declaration of string *) -[@@deriving eq, show { with_path = false }] - -(** Type delcaration *) -type _type = - | TypeBase of base_type (** Declaration of basic type *) - | TypeVoid (** Declaration of void *) -[@@deriving eq, show { with_path = false }] - -(** Variable *) -type var_type = TypeVar of _type [@@deriving eq, show { with_path = false }] - -(** Modifiers *) -type modifier = - | MPublic (** Public modifier, used for main() method only *) - | MStatic (** Static modifier, used for main() method only *) - | MAsync (** Async modifier *) -[@@deriving eq, show { with_path = false }] - -type var_decl = Var of var_type * ident [@@deriving eq, show { with_path = false }] -type params = Params of var_decl list [@@deriving eq, show { with_path = false }] - -(** Binary operations *) -type bin_op = - | OpAdd (** Sum: a [+] b *) - | OpSub (** a [-] b *) - | OpMul (** a [*] b *) - | OpDiv (** a [/] b in integers *) - | OpMod (** a [%] b *) - | OpEqual (** a [==] b *) - | OpNonEqual (** a [!=] b *) - | OpLess (** a [<] b *) - | OpMore (** a [>] b *) - | OpLessEqual (** a [<=] b *) - | OpMoreEqual (** a [>=] b *) - | OpAnd (** a [&&] b *) - | OpOr (** a [||] b *) - | OpAssign (** a [=] b *) -[@@deriving eq, show { with_path = false }] - -(** Unary operations *) -type un_op = OpNot (** [!] a *) [@@deriving eq, show { with_path = false }] - -(** From clauses *) -type from_clause = FromClause of string * ident -[@@deriving eq, show { with_path = false }] - -(** Language expressions *) -type expr = - | EValue of val_type (** Some value *) - | EBinOp of bin_op * expr * expr (** Binary operation *) - | EUnOp of un_op * expr (** Unary operation *) - | EId of ident (** Identificator expression *) - | EArrayAccess of expr * expr (** Array access: a = arr[i] *) - | EFuncCall of expr * expr list (** Call of function: name(arguments) *) - | EAwait of expr (** [Await] expression *) -[@@deriving eq, show { with_path = false }] - -(** Language statements *) -type stmt = - | SFor of stmt option * expr option * expr option * stmt - (** For cycle: [for] (int i = 0, j = 3; i < 4; i++, j--) \{\} *) - | SIf of expr * stmt * stmt option - (** If condition: [if] (a) [then] \{ b \} ([else] \{ c \} ) *) - | SWhile of expr * stmt (** While cycle: [while] (a) \{ \} *) - | SReturn of expr option (** Return: [return] (a) *) - | SBlock of stmt list (** Block of statements: \{ a \}; could be empty: \{\} *) - | SBreak (** Cycle [break] *) - | SContinue (** Cycle [continue] *) - | SExpr of expr (** Another expression *) - | SDecl of var_decl * expr option (** Var declaration *) -[@@deriving eq, show { with_path = false }] - -(** C Sharp class fields *) -type field = - | VarField of modifier list * var_type * ident * expr option - (** Class field - always initialized *) - | Method of modifier list * _type * ident * params * stmt (** Class method *) -[@@deriving eq, show { with_path = false }] - -(** C Sharp class *) -type c_sharp_class = - | Class of modifier list * ident * field list (** Basic class (Program) name *) -[@@deriving eq, show { with_path = false }] - -(** Program AST *) -type program = Program of c_sharp_class [@@deriving eq, show { with_path = false }] diff --git a/CSharpStrange/lib/dune b/CSharpStrange/lib/dune deleted file mode 100644 index 1fe37a666..000000000 --- a/CSharpStrange/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name c_sharp_strange_lib) - (public_name CSharpStrange.Lib) - (modules Ast Parser Prettyprinter) - (libraries angstrom base) - (preprocess - (pps ppx_deriving.show ppx_deriving.eq ppx_expect ppx_inline_test)) - (instrumentation - (backend bisect_ppx))) diff --git a/CSharpStrange/lib/parser.ml b/CSharpStrange/lib/parser.ml deleted file mode 100644 index 9b0019156..000000000 --- a/CSharpStrange/lib/parser.ml +++ /dev/null @@ -1,393 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Angstrom -open Base - -(* Chain functions *) -let chainl0 expr op = op >>= (fun op1 -> expr >>| op1) <|> expr - -let chainl1 expr op = - let rec pars e1 = lift2 (fun op1 e2 -> op1 e1 e2) op expr >>= pars <|> return e1 in - expr >>= pars -;; - -let chainr1 expr op = - fix (fun x -> lift2 (fun op1 -> op1) (lift2 (fun e1 op2 -> op2 e1) expr op) x <|> expr) -;; - -(* Special functions *) -let reserved = - [ "true" - ; "false" - ; "if" - ; "else" - ; "while" - ; "public" - ; "static" - ; "void" - ; "string" - ; "char" - ; "int" - ; "bool" - ; "for" - ; "null" - ; "new" - ; "return" - ; "break" - ; "continue" - ; "class" - ; "async" - ; "await" - ] -;; - -let in_reserved t = List.mem reserved t ~equal:String.equal - -let is_space = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -let is_token_sym = function - | 'a' .. 'z' | '0' .. '9' | 'A' .. 'Z' | '_' -> true - | _ -> false -;; - -let skip_spaces = skip_while is_space - -let parens p = - skip_spaces *> (char '(' <|> fail "<(> error)") *> p - <* skip_spaces - <* (char ')' <|> fail "<)> error)") -;; - -let braces p = - skip_spaces *> (char '{' <|> fail "<{> error)") *> p - <* skip_spaces - <* (char '}' <|> fail "<}> error)") -;; - -let brackets p = - skip_spaces *> (char '[' <|> fail "<[> error)") *> p - <* skip_spaces - <* (char ']' <|> fail "<]> error)") -;; - -let skip_semicolons = fix (fun f -> skip_spaces *> char ';' *> f <|> return "") -let skip_semicolons1 = skip_spaces *> char ';' *> skip_semicolons - -(* Values *) - -let parse_int = - take_while1 Char.is_digit - >>= fun num -> return @@ ValInt (Int.of_string num) <|> fail "Not an int" -;; - -let parse_char = - char '\'' *> any_char - <* char '\'' - >>= (fun c -> return @@ ValChar c) - <|> fail "Not a char" -;; - -let parse_bool = - choice - [ string "true" *> return (ValBool true); string "false" *> return (ValBool false) ] - <|> fail "Not a bool" -;; - -let parse_val_string = - char '\"' - *> take_till (function - | '\"' -> true - | _ -> false) - <* char '\"' - >>= (fun s -> return @@ ValString s) - <|> fail "Not a string" -;; - -let parse_null = string "null" *> return ValNull <|> fail "Not a null" - -(* Modifiers *) - -let parse_modifiers = - many - (choice - [ string "public" *> skip_spaces *> return MPublic - ; string "static" *> skip_spaces *> return MStatic - ; string "async" *> skip_spaces *> return MAsync - ]) - <|> fail "Modifier error" -;; - -(* Type words *) -let parse_type_word = - take_while is_token_sym - >>= function - | "int" -> return TypeInt - | "char" -> return TypeChar - | "bool" -> return TypeBool - | "string" -> return TypeString - | _ -> fail "Wrong type word" -;; - -let parse_base_type = parse_type_word >>= fun tp -> return @@ TypeBase tp -let val_to_expr p = skip_spaces *> p >>| fun x -> EValue x - -let parse_value = - choice - [ val_to_expr parse_bool - ; val_to_expr parse_char - ; val_to_expr parse_int - ; val_to_expr parse_null - ; val_to_expr parse_val_string - ] - <|> fail "Value error" -;; - -let parse_id = - take_while is_token_sym - >>= fun str -> - match not (String.is_empty str || in_reserved str || Char.is_digit str.[0]) with - | true -> return (Id str) - | _ -> fail "Not an identifier" -;; - -(* Expressions *) - -(* Variables && functions *) -let parse_var_type = - choice ?failure_msg:(Some "Incorrect type") [ parse_base_type ] - >>= fun x -> return (TypeVar x) -;; - -let parse_var = - let parse_decl_id typ_ = - char ' ' *> skip_spaces *> parse_id >>| fun id -> Var (typ_, id) - in - skip_spaces *> parse_var_type >>= parse_decl_id -;; - -let parse_id_expr = skip_spaces *> (parse_id >>| fun x -> EId x) <* skip_spaces -let parse_call_id = parse_id_expr -let parse_args_list arg = parens @@ sep_by (skip_spaces *> char ',') arg - -let parse_call_args id arg = - parse_args_list arg >>= fun args -> return @@ EFuncCall (id, args) -;; - -let parse_call_expr arg = parse_call_id >>= fun id -> parse_call_args id arg - -(* Operations *) -let parse_op op typ = skip_spaces *> string op *> return typ - -(* Binary operations *) -let parse_bin_op op typ = parse_op op typ >>| fun t a b -> EBinOp (t, a, b) -let ( ^+^ ) = parse_bin_op "+" OpAdd -let ( ^-^ ) = parse_bin_op "-" OpSub -let ( ^*^ ) = parse_bin_op "*" OpMul -let ( ^/^ ) = parse_bin_op "/" OpDiv -let ( ^%^ ) = parse_bin_op "%" OpMod -let ( ^==^ ) = parse_bin_op "==" OpEqual -let ( ^!=^ ) = parse_bin_op "!=" OpNonEqual -let ( ^<^ ) = parse_bin_op "<" OpLess -let ( ^>^ ) = parse_bin_op ">" OpMore -let ( ^<=^ ) = parse_bin_op "<=" OpLessEqual -let ( ^>=^ ) = parse_bin_op ">=" OpMoreEqual -let ( ^&&^ ) = parse_bin_op "&&" OpAnd -let ( ^||^ ) = parse_bin_op "||" OpOr -let ( ^=^ ) = parse_bin_op "=" OpAssign - -(* Unary operations *) -let parse_un_op op typ = parse_op op typ >>| fun t a -> EUnOp (t, a) -let ( ^!^ ) = parse_un_op "!" OpNot - -let parse_ops = - fix (fun expr -> - let lv1 = choice [ parens expr; parse_value; parse_call_expr expr; parse_id_expr ] in - let lv2 = chainl0 lv1 (choice [ ( ^!^ ) ]) in - let lv3 = chainl1 lv2 (choice [ ( ^*^ ); ( ^/^ ); ( ^%^ ) ]) in - let lv4 = chainl1 lv3 (choice [ ( ^+^ ); ( ^-^ ) ]) in - let lv5 = chainl1 lv4 (choice [ ( ^<=^ ); ( ^>=^ ); ( ^<^ ); ( ^>^ ) ]) in - let lv6 = chainl1 lv5 (choice [ ( ^==^ ); ( ^!=^ ) ]) in - let lv7 = chainl1 lv6 (choice [ ( ^&&^ ) ]) in - let lv8 = chainl1 lv7 (choice [ ( ^||^ ) ]) in - chainr1 lv8 (choice [ ( ^=^ ) ])) - <|> fail "Expr error" -;; - -let parse_assign = - lift3 (fun id eq ex -> eq id ex) parse_id_expr ( ^=^ ) parse_ops <|> fail "Assign error" -;; - -(* Statements *) - -let get_opt p = p >>| fun x -> Some x - -let parse_decl = - lift2 - (fun dcl e -> SDecl (dcl, e)) - parse_var - (option None (skip_spaces *> char '=' *> parse_ops >>| fun e -> Some e)) -;; - -let expr_to_stmt expr = expr >>| fun x -> SExpr x -let parse_stmt_ops = expr_to_stmt @@ choice [ parse_assign; parse_call_expr parse_ops ] - -let parse_if_else f_if_body = - let parse_if_cond = string "if" *> skip_spaces *> parens parse_ops in - let parse_else_cond ifls body = - skip_spaces - *> (get_opt @@ (string "else" *> skip_spaces *> choice [ ifls; body ]) <|> return None) - in - fix (fun ifls -> - let parse_body = f_if_body <|> (parse_stmt_ops <* skip_semicolons1) in - let parse_else_body = parse_else_cond ifls parse_body in - lift3 - (fun cond if_body else_body -> SIf (cond, if_body, else_body)) - parse_if_cond - parse_body - parse_else_body) - <|> fail "If error" -;; - -let parse_for body = - let expr_to_option_stmt expr = get_opt @@ expr_to_stmt expr in - let p_body = body <|> (parse_stmt_ops <* skip_semicolons1) in - let p_for_init = - option None (get_opt parse_decl <|> expr_to_option_stmt parse_assign) - in - let p_for_expr = option None (get_opt parse_ops) in - let p_for = - lift2 - (fun (f_init_p, f_cond_p, f_iter_p) f_body -> - SFor (f_init_p, f_cond_p, f_iter_p, f_body)) - (parens - @@ lift3 - (fun init cond incr -> init, cond, incr) - (p_for_init <* skip_spaces <* char ';') - (p_for_expr <* skip_spaces <* char ';') - p_for_expr) - p_body - in - string "for" *> p_for <|> fail "For error" -;; - -let parse_while body = - let p_body = body <|> skip_semicolons1 *> parse_stmt_ops in - let p_cond = parens parse_ops in - let p_while = string "while" *> skip_spaces *> p_cond in - lift2 (fun cond body -> SWhile (cond, body)) p_while p_body <|> fail "While error" -;; - -let parse_return = - lift2 - (fun _ expr -> SReturn expr) - (string "return") - (parse_ops >>= (fun ret -> return (Some ret)) <|> return None) - <|> fail "Return error" -;; - -let parse_break = skip_spaces *> string "break" *> return SBreak <|> fail "Break error" - -let parse_continue = - skip_spaces *> string "continue" *> return SContinue <|> fail "Continue error" -;; - -let parse_block = - fix (fun block -> - let sc p = p <* skip_semicolons1 in - let op_sc p = p <* skip_semicolons in - let body_step = - choice - ?failure_msg:(Some "Error in some block sentence") - [ sc parse_decl - ; sc parse_break - ; sc parse_continue - ; sc parse_return - ; sc parse_stmt_ops - ; op_sc @@ parse_if_else block - ; op_sc @@ parse_for block - ; op_sc @@ parse_while block - ] - in - braces (skip_semicolons *> many (skip_spaces *> body_step)) - >>= fun stmt_lst -> return @@ SBlock stmt_lst) -;; - -(* Program class functions *) -let parse_field_sign = - let f_value = skip_spaces *> char '=' *> get_opt parse_ops in - lift4 - (fun f_modif f_type f_id f_val -> f_modif, f_type, f_id, f_val) - (skip_spaces *> parse_modifiers) - (skip_spaces *> parse_var_type) - (skip_spaces *> parse_id) - (option None f_value) - <* skip_semicolons1 -;; - -let parse_method_type = - let parse_void = string "void" *> return TypeVoid in - choice ?failure_msg:(Some "Not a method type") [ parse_base_type; parse_void ] -;; - -let parse_method_sign = - let parse_args = - parens @@ sep_by (skip_spaces *> char ',' <* skip_spaces) parse_var - >>= fun exp -> return (Params exp) - in - lift4 - (fun m_modif m_type m_id m_params -> m_modif, m_type, m_id, m_params) - (skip_spaces *> parse_modifiers) - (skip_spaces *> parse_method_type) - (skip_spaces *> parse_id) - (skip_spaces *> parse_args) -;; - -let parse_method_member = - lift2 - (fun (mds, tp, id, ps) bd -> Method (mds, tp, id, ps, bd)) - parse_method_sign - parse_block -;; - -let parse_field_member = - parse_field_sign - >>| function - | mds, tp, id, Some ex -> VarField (mds, tp, id, Some (EBinOp (OpAssign, EId id, ex))) - | mds, tp, id, None -> VarField (mds, tp, id, None) -;; - -let parse_class_members = - let member = - choice ?failure_msg:(Some "Method error") [ parse_method_member; parse_field_member ] - in - braces @@ sep_by skip_spaces member -;; - -let parse_class = - let class_id = - skip_spaces *> string "class" *> skip_spaces *> parse_id <|> fail "Class sign error" - in - lift3 - (fun cl_mdf cl_id cl_mbs -> Class (cl_mdf, cl_id, cl_mbs)) - (skip_spaces *> parse_modifiers) - class_id - parse_class_members -;; - -let parse_prog : program t = parse_class <* skip_spaces >>| fun prog -> Program prog - -(* Main functions *) - -let apply_parser parser = parse_string ~consume:Consume.All parser - -let parse_option p str = - match apply_parser p str with - | Ok x -> Some x - | Error _ -> None -;; diff --git a/CSharpStrange/lib/parser.mli b/CSharpStrange/lib/parser.mli deleted file mode 100644 index 730e660bb..000000000 --- a/CSharpStrange/lib/parser.mli +++ /dev/null @@ -1,28 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Angstrom -open Base - -val parens : 'a t -> 'a t -val braces : 'a t -> 'a t -val brackets : 'a t -> 'a t -val parse_int : val_type t -val parse_char : val_type t -val parse_bool : val_type t -val parse_val_string : val_type t -val parse_modifiers : modifier list t -val parse_ops : expr t -val parse_decl : stmt t -val parse_return : stmt t -val parse_break : stmt t -val parse_continue : stmt t -val parse_block : stmt t -val parse_method_member : field t -val parse_field_member : field t -val parse_class : c_sharp_class t -val parse_prog : program t -val apply_parser : 'a t -> string -> ('a, string) Result.t -val parse_option : 'a t -> string -> 'a option diff --git a/CSharpStrange/lib/prettyprinter.ml b/CSharpStrange/lib/prettyprinter.ml deleted file mode 100644 index a8e971cfa..000000000 --- a/CSharpStrange/lib/prettyprinter.ml +++ /dev/null @@ -1,165 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Format -open Ast - -let pp_list : 'a. (formatter -> 'a -> unit) -> string -> formatter -> 'a list -> unit = - fun pp sep fmt lst -> - let rec aux fmt = function - | [] -> () - | [ x ] -> pp fmt x - | x :: xs -> fprintf fmt "%a%s%a" pp x sep aux xs - in - aux fmt lst -;; - -let pp_option : 'a. (formatter -> 'a -> unit) -> formatter -> 'a option -> unit = - fun pp fmt -> function - | None -> fprintf fmt "" - | Some x -> pp fmt x -;; - -let pp_ident fmt (Id s) = fprintf fmt "%s" s - -let pp_base_type fmt = function - | TypeInt -> fprintf fmt "int" - | TypeChar -> fprintf fmt "char" - | TypeBool -> fprintf fmt "bool" - | TypeString -> fprintf fmt "string" -;; - -let pp_type fmt = function - | TypeBase bt -> pp_base_type fmt bt - | TypeVoid -> fprintf fmt "void" -;; - -let pp_var_type fmt (TypeVar t) = pp_type fmt t - -let pp_modifier fmt = function - | MPublic -> fprintf fmt "public" - | MStatic -> fprintf fmt "static" - | MAsync -> fprintf fmt "async" -;; - -let pp_var_decl fmt (Var (vt, id)) = fprintf fmt "%a %a" pp_var_type vt pp_ident id - -let pp_bin_op fmt = function - | OpAdd -> fprintf fmt "+" - | OpSub -> fprintf fmt "-" - | OpMul -> fprintf fmt "*" - | OpDiv -> fprintf fmt "/" - | OpMod -> fprintf fmt "%%" - | OpEqual -> fprintf fmt "==" - | OpNonEqual -> fprintf fmt "!=" - | OpLess -> fprintf fmt "<" - | OpMore -> fprintf fmt ">" - | OpLessEqual -> fprintf fmt "<=" - | OpMoreEqual -> fprintf fmt ">=" - | OpAnd -> fprintf fmt "&&" - | OpOr -> fprintf fmt "||" - | OpAssign -> fprintf fmt "=" -;; - -let pp_un_op fmt = function - | OpNot -> fprintf fmt "!" -;; - -let pp_val_type fmt = function - | ValInt n -> fprintf fmt "%d" n - | ValChar c -> fprintf fmt "'%c'" c - | ValNull -> fprintf fmt "null" - | ValBool b -> fprintf fmt "%b" b - | ValString s -> fprintf fmt {|%S|} s -;; - -let rec pp_expr fmt = function - | EValue v -> pp_val_type fmt v - | EBinOp (op, e1, e2) -> fprintf fmt "(%a %a %a)" pp_expr e1 pp_bin_op op pp_expr e2 - | EUnOp (op, e) -> fprintf fmt "(%a%a)" pp_un_op op pp_expr e - | EId id -> pp_ident fmt id - | EArrayAccess (e1, e2) -> fprintf fmt "%a[%a]" pp_expr e1 pp_expr e2 - | EFuncCall (e, args) -> fprintf fmt "%a(%a)" pp_expr e (pp_list pp_expr ", ") args - | EAwait e -> fprintf fmt "await %a" pp_expr e -;; - -let rec pp_stmt fmt = function - | SFor (init, cond, incr, body) -> - fprintf - fmt - "@[for (%a; %a; %a) {@ %a@]@ }" - (pp_option pp_stmt) - init - (pp_option pp_expr) - cond - (pp_option pp_expr) - incr - pp_stmt - body - | SIf (cond, then_branch, else_branch) -> - fprintf - fmt - "@[if (%a) {@ %a@]@ }%a" - pp_expr - cond - pp_stmt - then_branch - (pp_option (fun fmt -> fprintf fmt "@ @[else {@ %a@]@ }" pp_stmt)) - else_branch - | SWhile (cond, body) -> - fprintf fmt "@[while (%a) {@ %a@]@ }" pp_expr cond pp_stmt body - | SReturn e -> fprintf fmt "return %a;" (pp_option pp_expr) e - | SBlock stmts -> pp_sblock fmt stmts - | SBreak -> fprintf fmt "break;" - | SContinue -> fprintf fmt "continue;" - | SExpr e -> fprintf fmt "%a;" pp_expr e - | SDecl (vd, e) -> fprintf fmt "%a = %a;" pp_var_decl vd (pp_option pp_expr) e - -and pp_sblock fmt = function - | [] -> fprintf fmt "" - | stmts -> fprintf fmt "@[%a@]" (pp_list pp_stmt "@ ") stmts -;; - -let pp_field fmt = function - | VarField (mods, t, id, e) -> - fprintf - fmt - "@[%a %a %a = %a;@]" - (pp_list pp_modifier " ") - mods - pp_var_type - t - pp_ident - id - (pp_option pp_expr) - e - | Method (mods, t, id, Params params, body) -> - fprintf - fmt - "@[%a %a %a(%a)@ @[{@ %a@]@ @[}@]@ " - (pp_list pp_modifier " ") - mods - pp_type - t - pp_ident - id - (pp_list pp_var_decl ", ") - params - pp_stmt - body -;; - -let pp_c_sharp_class fmt (Class (mods, id, fields)) = - fprintf - fmt - "@[%a class %a@ @[{@ %a@]@ @[}@]" - (pp_list pp_modifier " ") - mods - pp_ident - id - (pp_list pp_field " ") - fields -;; - -let pp_prog fmt (Program cls) = pp_c_sharp_class fmt cls diff --git a/CSharpStrange/lib/prettyprinter.mli b/CSharpStrange/lib/prettyprinter.mli deleted file mode 100644 index 949077e67..000000000 --- a/CSharpStrange/lib/prettyprinter.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val pp_prog : Format.formatter -> program -> unit diff --git a/CSharpStrange/tests/ast_fact.t b/CSharpStrange/tests/ast_fact.t deleted file mode 100644 index f62ed32b9..000000000 --- a/CSharpStrange/tests/ast_fact.t +++ /dev/null @@ -1,25 +0,0 @@ - $ ../bin/REPL.exe -parseast -filepath="../bin/factorial.cs" - (Program - (Class ([MPublic], (Id "Program"), - [(Method ([MPublic], (TypeBase TypeInt), (Id "Factorial"), - (Params [(Var ((TypeVar (TypeBase TypeInt)), (Id "n")))]), - (SBlock - [(SIf ((EBinOp (OpEqual, (EId (Id "n")), (EValue (ValInt 0)))), - (SBlock [(SReturn (Some (EValue (ValInt 1))))]), - (Some (SBlock - [(SReturn - (Some (EBinOp (OpMul, (EId (Id "n")), - (EFuncCall ((EId (Id "Factorial")), - [(EBinOp (OpSub, (EId (Id "n")), - (EValue (ValInt 1)))) - ] - )) - )))) - ])) - )) - ]) - )); - (Method ([MPublic; MStatic], TypeVoid, (Id "Main"), (Params []), - (SBlock []))) - ] - ))) diff --git a/CSharpStrange/tests/dune b/CSharpStrange/tests/dune deleted file mode 100644 index f112a01f1..000000000 --- a/CSharpStrange/tests/dune +++ /dev/null @@ -1,14 +0,0 @@ -(library - (name tests) - (public_name CSharpStrange.Lib.Tests) - (modules Parser_tests Pp_tests) - (libraries angstrom c_sharp_strange_lib) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) - -(cram - (applies_to ast_fact) - (deps ../bin/REPL.exe ../bin/factorial.cs)) diff --git a/CSharpStrange/tests/parser_tests.ml b/CSharpStrange/tests/parser_tests.ml deleted file mode 100644 index bcc62dba8..000000000 --- a/CSharpStrange/tests/parser_tests.ml +++ /dev/null @@ -1,422 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open C_sharp_strange_lib.Ast -open C_sharp_strange_lib.Parser - -let%test "Parse one integer" = apply_parser parse_int {|1|} = Ok (ValInt 1) -let%test "Parse one char" = apply_parser parse_char {|'c'|} = Ok (ValChar 'c') -let%test "Parse true" = apply_parser parse_bool {|true|} = Ok (ValBool true) -let%test "Parse false" = apply_parser parse_bool {|false|} = Ok (ValBool false) - -let%test "Parse string" = - apply_parser parse_val_string {|"sample"|} = Ok (ValString "sample") -;; - -let%test "Parse parens" = apply_parser (parens parse_int) {|(1)|} = Ok (ValInt 1) -let%test "Parse braces" = apply_parser (braces parse_int) {|{1}|} = Ok (ValInt 1) -let%test "Parse brackets" = apply_parser (brackets parse_int) {|[1]|} = Ok (ValInt 1) -let%test "Parse one modifier 1" = apply_parser parse_modifiers {|static|} = Ok [ MStatic ] -let%test "Parse one modifier 2" = apply_parser parse_modifiers {|public|} = Ok [ MPublic ] - -let%test "Parse two modifiers" = - apply_parser parse_modifiers {|public async|} = Ok [ MPublic; MAsync ] -;; - -let%test "Parse add 1" = - apply_parser parse_ops {| 1 + 2|} - = Ok (EBinOp (OpAdd, EValue (ValInt 1), EValue (ValInt 2))) -;; - -let%test "Parse add 2" = - apply_parser parse_ops {| a + b|} = Ok (EBinOp (OpAdd, EId (Id "a"), EId (Id "b"))) -;; - -let%test "Parse many adds" = - apply_parser parse_ops {| 1 + 2 + 3|} - = Ok - (EBinOp - (OpAdd, EBinOp (OpAdd, EValue (ValInt 1), EValue (ValInt 2)), EValue (ValInt 3))) -;; - -let%test "Parse adds with mul 1" = - apply_parser parse_ops {|1 + 2 * 3|} - = Ok - (EBinOp - (OpAdd, EValue (ValInt 1), EBinOp (OpMul, EValue (ValInt 2), EValue (ValInt 3)))) -;; - -let%test "Parse adds with mul 2" = - apply_parser parse_ops {| (1 + 2 ) * 3|} - = Ok - (EBinOp - (OpMul, EBinOp (OpAdd, EValue (ValInt 1), EValue (ValInt 2)), EValue (ValInt 3))) -;; - -let%test "Parse div with mod" = - apply_parser parse_ops {| 1 / 2 % 3|} - = Ok - (EBinOp - (OpMod, EBinOp (OpDiv, EValue (ValInt 1), EValue (ValInt 2)), EValue (ValInt 3))) -;; - -let%test "Parse div with mod" = - apply_parser parse_ops {| 1 - 2 / 3 + 4|} - = Ok - (EBinOp - ( OpAdd - , EBinOp - ( OpSub - , EValue (ValInt 1) - , EBinOp (OpDiv, EValue (ValInt 2), EValue (ValInt 3)) ) - , EValue (ValInt 4) )) -;; - -let%test "Parse simple boolean expression" = - apply_parser parse_ops {| ( 1 + 2 == 3 + 4 )|} - = Ok - (EBinOp - ( OpEqual - , EBinOp (OpAdd, EValue (ValInt 1), EValue (ValInt 2)) - , EBinOp (OpAdd, EValue (ValInt 3), EValue (ValInt 4)) )) -;; - -let%test "Parse complex boolean expression" = - apply_parser parse_ops {|( 1 + 2 < 3 + 4) && (5 == 8)|} - = Ok - (EBinOp - ( OpAnd - , EBinOp - ( OpLess - , EBinOp (OpAdd, EValue (ValInt 1), EValue (ValInt 2)) - , EBinOp (OpAdd, EValue (ValInt 3), EValue (ValInt 4)) ) - , EBinOp (OpEqual, EValue (ValInt 5), EValue (ValInt 8)) )) -;; - -let%test "Parse ident expr" = apply_parser parse_ops {| x|} = Ok (EId (Id "x")) -let%test "Parse id in expressions 1" = apply_parser parse_ops {| x|} = Ok (EId (Id "x")) - -let%test "Parse id in expressions 2" = - apply_parser parse_ops {|x + 1|} = Ok (EBinOp (OpAdd, EId (Id "x"), EValue (ValInt 1))) -;; - -let%test "Parse var declaration 1" = - apply_parser parse_decl {|int x|} - = Ok (SDecl (Var (TypeVar (TypeBase TypeInt), Id "x"), None)) -;; - -let%test "Parse var declaration 2" = - apply_parser parse_decl {|int x = 1|} - = Ok (SDecl (Var (TypeVar (TypeBase TypeInt), Id "x"), Some (EValue (ValInt 1)))) -;; - -let%test "Parse multiple var declarations" = - apply_parser parse_decl {|int x = y = z = 1|} - = Ok - (SDecl - ( Var (TypeVar (TypeBase TypeInt), Id "x") - , Some - (EBinOp - ( OpAssign - , EId (Id "y") - , EBinOp (OpAssign, EId (Id "z"), EValue (ValInt 1)) )) )) -;; - -let%test "Parse return 1" = - apply_parser parse_return {|return 5|} = Ok (SReturn (Some (EValue (ValInt 5)))) -;; - -let%test "Parse return 2" = apply_parser parse_return {|return|} = Ok (SReturn None) -let%test "Parse break" = apply_parser parse_break {|break|} = Ok SBreak -let%test "Parse continue" = apply_parser parse_continue {|continue|} = Ok SContinue -let%test "Parse empty block 1" = apply_parser parse_block {|{}|} = Ok (SBlock []) -let%test "Parse empty block 2" = apply_parser parse_block {|{;;;;}|} = Ok (SBlock []) - -let%test "Parse block 1" = - apply_parser parse_block {|{return 5;}|} - = Ok (SBlock [ SReturn (Some (EValue (ValInt 5))) ]) -;; - -let%test "Parse block 2" = - apply_parser parse_block {|{int x = 6; x = 6 + 1; return x;}|} - = Ok - (SBlock - [ SDecl (Var (TypeVar (TypeBase TypeInt), Id "x"), Some (EValue (ValInt 6))) - ; SExpr - (EBinOp - ( OpAssign - , EId (Id "x") - , EBinOp (OpAdd, EValue (ValInt 6), EValue (ValInt 1)) )) - ; SReturn (Some (EId (Id "x"))) - ]) -;; - -let%test "Parse while" = - apply_parser - parse_block - {| - { - int x = 1; - while ( x < 1 ) - { - x = 2; - break; - continue; - } - }|} - = Ok - (SBlock - [ SDecl (Var (TypeVar (TypeBase TypeInt), Id "x"), Some (EValue (ValInt 1))) - ; SWhile - ( EBinOp (OpLess, EId (Id "x"), EValue (ValInt 1)) - , SBlock - [ SExpr (EBinOp (OpAssign, EId (Id "x"), EValue (ValInt 2))) - ; SBreak - ; SContinue - ] ) - ]) -;; - -let%test "Parse for" = - apply_parser - parse_block - {|{ - for (int i = 1;i < 5; i = i+1) - { - i = i + 1; - } - }|} - = Ok - (SBlock - [ SFor - ( Some - (SDecl - (Var (TypeVar (TypeBase TypeInt), Id "i"), Some (EValue (ValInt 1)))) - , Some (EBinOp (OpLess, EId (Id "i"), EValue (ValInt 5))) - , Some - (EBinOp - ( OpAssign - , EId (Id "i") - , EBinOp (OpAdd, EId (Id "i"), EValue (ValInt 1)) )) - , SBlock - [ SExpr - (EBinOp - ( OpAssign - , EId (Id "i") - , EBinOp (OpAdd, EId (Id "i"), EValue (ValInt 1)) )) - ] ) - ]) -;; - -let%test "Parse if" = - apply_parser - parse_block - {|{if (x == 5) - x=1; - else if (x == 2) - { - x=2; - } - }|} - = Ok - (SBlock - [ SIf - ( EBinOp (OpEqual, EId (Id "x"), EValue (ValInt 5)) - , SExpr (EBinOp (OpAssign, EId (Id "x"), EValue (ValInt 1))) - , Some - (SIf - ( EBinOp (OpEqual, EId (Id "x"), EValue (ValInt 2)) - , SBlock - [ SExpr (EBinOp (OpAssign, EId (Id "x"), EValue (ValInt 2))) ] - , None )) ) - ]) -;; - -let%test "Parse field 1" = - apply_parser parse_field_member {|public int X;|} - = Ok (VarField ([ MPublic ], TypeVar (TypeBase TypeInt), Id "X", None)) -;; - -let%test "Parse field 2" = - apply_parser parse_field_member {|public int X = 1;|} - = Ok - (VarField - ( [ MPublic ] - , TypeVar (TypeBase TypeInt) - , Id "X" - , Some (EBinOp (OpAssign, EId (Id "X"), EValue (ValInt 1))) )) -;; - -let%test "Parse method 1" = - apply_parser parse_method_member {|public int Func() {}|} - = Ok (Method ([ MPublic ], TypeBase TypeInt, Id "Func", Params [], SBlock [])) -;; - -let%test "Parse method 2" = - apply_parser parse_method_member {|public int Func() - { - return 2; - }|} - = Ok - (Method - ( [ MPublic ] - , TypeBase TypeInt - , Id "Func" - , Params [] - , SBlock [ SReturn (Some (EValue (ValInt 2))) ] )) -;; - -let%test "Parse method 3" = - apply_parser - parse_method_member - {|public int Factorial(int n) - { - if (n == 0) - { - return 1; - } - else - { - return n * Factorial(n - 1); - } - }|} - = Ok - (Method - ( [ MPublic ] - , TypeBase TypeInt - , Id "Factorial" - , Params [ Var (TypeVar (TypeBase TypeInt), Id "n") ] - , SBlock - [ SIf - ( EBinOp (OpEqual, EId (Id "n"), EValue (ValInt 0)) - , SBlock [ SReturn (Some (EValue (ValInt 1))) ] - , Some - (SBlock - [ SReturn - (Some - (EBinOp - ( OpMul - , EId (Id "n") - , EFuncCall - ( EId (Id "Factorial") - , [ EBinOp (OpSub, EId (Id "n"), EValue (ValInt 1)) - ] ) ))) - ]) ) - ] )) -;; - -let%test "Parse class 1" = - apply_parser parse_class {| - public class Sample {}|} - = Ok (Class ([ MPublic ], Id "Sample", [])) -;; - -let%test "Parse class 2" = - apply_parser - parse_class - {| - public class Sample { - public int X; - public int Y = 1; - }|} - = Ok - (Class - ( [ MPublic ] - , Id "Sample" - , [ VarField ([ MPublic ], TypeVar (TypeBase TypeInt), Id "X", None) - ; VarField - ( [ MPublic ] - , TypeVar (TypeBase TypeInt) - , Id "Y" - , Some (EBinOp (OpAssign, EId (Id "Y"), EValue (ValInt 1))) ) - ] )) -;; - -let%test "Parse class 3" = - apply_parser - parse_class - {| - public class Sample { - - public int X; - - public int add(int x) { - X = X + x; - } - }|} - = Ok - (Class - ( [ MPublic ] - , Id "Sample" - , [ VarField ([ MPublic ], TypeVar (TypeBase TypeInt), Id "X", None) - ; Method - ( [ MPublic ] - , TypeBase TypeInt - , Id "add" - , Params [ Var (TypeVar (TypeBase TypeInt), Id "x") ] - , SBlock - [ SExpr - (EBinOp - ( OpAssign - , EId (Id "X") - , EBinOp (OpAdd, EId (Id "X"), EId (Id "x")) )) - ] ) - ] )) -;; - -let%test "Parse factorial" = - apply_parser - parse_prog - {| - public class Program - { - public static void Main() {} - - public int Factorial(int n) - { - if (n == 0) - { - return 1; - } - else - { - return n * Factorial(n - 1); - } - } - } - - |} - = Ok - (Program - (Class - ( [ MPublic ] - , Id "Program" - , [ Method ([ MPublic; MStatic ], TypeVoid, Id "Main", Params [], SBlock []) - ; Method - ( [ MPublic ] - , TypeBase TypeInt - , Id "Factorial" - , Params [ Var (TypeVar (TypeBase TypeInt), Id "n") ] - , SBlock - [ SIf - ( EBinOp (OpEqual, EId (Id "n"), EValue (ValInt 0)) - , SBlock [ SReturn (Some (EValue (ValInt 1))) ] - , Some - (SBlock - [ SReturn - (Some - (EBinOp - ( OpMul - , EId (Id "n") - , EFuncCall - ( EId (Id "Factorial") - , [ EBinOp - ( OpSub - , EId (Id "n") - , EValue (ValInt 1) ) - ] ) ))) - ]) ) - ] ) - ] ))) -;; diff --git a/CSharpStrange/tests/parser_tests.mli b/CSharpStrange/tests/parser_tests.mli deleted file mode 100644 index 2a5ede905..000000000 --- a/CSharpStrange/tests/parser_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/CSharpStrange/tests/pp_tests.ml b/CSharpStrange/tests/pp_tests.ml deleted file mode 100644 index af45e6841..000000000 --- a/CSharpStrange/tests/pp_tests.ml +++ /dev/null @@ -1,119 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open C_sharp_strange_lib.Prettyprinter -open C_sharp_strange_lib.Parser -open Format - -let fact_str = - {| -public class Program -{ - public int Factorial(int n) - { - if (n == 0) - { - return 1; - } - else - { - return n * Factorial(n - 1); - } - } - - public static void Main() - { - - } -} - -|} -;; - -let fact_prog = parse_option parse_prog fact_str - -let pretty_fact_str = function - | Some x -> asprintf "%a" pp_prog x - | None -> "" -;; - -let parse_after_pp prog = parse_option parse_prog (pretty_fact_str prog) -let%test "Factorial pp" = parse_after_pp fact_prog = fact_prog - -let cycles_str = - {| -public class Program -{ - public int Cycles(int n, bool e, string x) - { - int x = 0; - while (x < n) - { - if (x == -1) - { - break; - } - - if (x == -2) - { - continue; - } - - x = x + 1; - } - - for (int i = 1; i < n; i++) - { - break; - } - - for (;;) - { - break; - } - - for (int i = 1;; i++) - { - break; - } - } - - public static void Main() - { - Cycles(5, true, "sample"); - } -} -|} -;; - -let cycles_prog = parse_option parse_prog cycles_str -let%test "Cycles pp" = parse_after_pp cycles_prog = cycles_prog - -let binops_prog = - parse_option - parse_prog - {| - -public class Program -{ - public int Binops(int n, bool e, string x) - { - int x_ = n; - bool sample = !e || ((1 + 2 < 3 + 4) && (5 == 8)); - string e = x; - char eeAe065ef = 'a'; - e = null; - const int a = 1; - } - - - public static void Main() - { - Binops(5, true, ""); - } -} -|} -;; - -let%test "Binops pp" = parse_after_pp binops_prog = binops_prog diff --git a/CSharpStrange/tests/pp_tests.mli b/CSharpStrange/tests/pp_tests.mli deleted file mode 100644 index 2a5ede905..000000000 --- a/CSharpStrange/tests/pp_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2025, Dmitrii Kuznetsov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EChirkov/.envrc b/EChirkov/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/EChirkov/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/EChirkov/.gitignore b/EChirkov/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/EChirkov/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/EChirkov/.ocamlformat b/EChirkov/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/EChirkov/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/EChirkov/.zanuda b/EChirkov/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/EChirkov/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/EChirkov/COPYING b/EChirkov/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/EChirkov/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/EChirkov/COPYING.CC0 b/EChirkov/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/EChirkov/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/EChirkov/COPYING.LESSER b/EChirkov/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/EChirkov/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/EChirkov/EChirkov.opam b/EChirkov/EChirkov.opam deleted file mode 100644 index 94c130e52..000000000 --- a/EChirkov/EChirkov.opam +++ /dev/null @@ -1,33 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for miniml" -description: "An interpreter for miniml" -maintainer: ["Dmitri Chirkov"] -authors: ["Dmitri Chirkov "] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/kinokotakenoko9/MiniMl" -bug-reports: "https://github.com/kinokotakenoko9/MiniMl" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/EChirkov/Makefile b/EChirkov/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/EChirkov/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/EChirkov/bin/dune b/EChirkov/bin/dune deleted file mode 100644 index 5b2a8d229..000000000 --- a/EChirkov/bin/dune +++ /dev/null @@ -1,10 +0,0 @@ -(executable - (name main) - (public_name main) - (modules main) - (libraries EChirkov angstrom stdio base) - (instrumentation - (backend bisect_ppx))) - -(cram - (deps ./main.exe %{bin:main})) diff --git a/EChirkov/bin/main.ml b/EChirkov/bin/main.ml deleted file mode 100644 index 1a092e471..000000000 --- a/EChirkov/bin/main.ml +++ /dev/null @@ -1,47 +0,0 @@ -(** Copyright 2024, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Stdio -open EChirkov.Ast -open EChirkov.Parser -open EChirkov.Interpreter -open EChirkov.Inferencer - -let usage () = - printf "Usage: miniML [--interpret | --dump-ast | --infer] \n"; - Stdlib.exit 1 -;; - -let read_file filename = - try In_channel.read_all filename with - | Sys_error err -> - printf "Error: %s\n" err; - Stdlib.exit 1 -;; - -let () = - if Array.length Stdlib.Sys.argv <> 3 then usage (); - let mode = Stdlib.Sys.argv.(1) in - let filename = Stdlib.Sys.argv.(2) in - let source_code = read_file filename in - match parse source_code with - | Error msg -> printf "Parsing error: %s\n" msg - | Ok ast -> - (match mode with - | "--dump-ast" -> printf "AST:\n%s\n" (show_program ast) - | "--interpret" -> - (match interpret ast with - | Ok _ -> () - | Error err -> - printf "Interpretation error: %s\n" (EChirkov.Interpreter.pp_error err)) - | "--infer" -> - (match inference ast with - | Ok env -> EChirkov.Inferencer.print_env env - | Error msg -> - Stdlib.Format.printf - "Type inference error: %a\n" - EChirkov.Inferencer.pp_error - msg) - | _ -> usage ()) -;; diff --git a/EChirkov/dune b/EChirkov/dune deleted file mode 100644 index 98e54536a..000000000 --- a/EChirkov/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/EChirkov/dune-project b/EChirkov/dune-project deleted file mode 100644 index fc736ac4a..000000000 --- a/EChirkov/dune-project +++ /dev/null @@ -1,32 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Dmitri Chirkov ") - -(maintainers "Dmitri Chirkov") - -(bug_reports "https://github.com/kinokotakenoko9/MiniMl") - -(homepage "https://github.com/kinokotakenoko9/MiniMl") - -(package - (name EChirkov) - (synopsis "An interpreter for miniml") - (description "An interpreter for miniml") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/EChirkov/lib/ast.ml b/EChirkov/lib/ast.ml deleted file mode 100644 index 4739f697b..000000000 --- a/EChirkov/lib/ast.ml +++ /dev/null @@ -1,98 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type id = string [@@deriving show { with_path = false }] - -type const = - | CInt of int - | CBool of bool - | CUnit -(* () *) -(* | CString of string *) -[@@deriving show { with_path = false }] - -type op_un = - | Neg (* - *) - | Pos (* + *) -[@@deriving show { with_path = false }] - -type rec_flag = - | Recursive - | Nonrecursive -[@@deriving show { with_path = false }] - -type op_bin = - | Add - | Sub - | Mul - | Div - | And (* && *) - | Or (* || *) - | Gt (* > *) - | Lt (* < *) - | Gte (* >= *) - | Lte (* <= *) - | Eq (* = *) - | NEq (* <> *) -[@@deriving show { with_path = false }] - -type binder = int [@@deriving show { with_path = false }] - -type core_type = - | TPrim of string - | TVar of binder - | TArrow of core_type * core_type - | TTuple of core_type * core_type * core_type list - | TList of core_type - | TOption of core_type -[@@deriving show { with_path = false }] - -let ty_int = TPrim "int" -let ty_bool = TPrim "bool" -let ty_unit = TPrim "unit" -let ty_arrow (l, r) = TArrow (l, r) -let ty_var v = TVar v -let ty_tuple (t1, t2, tl) = TTuple (t1, t2, tl) -let ty_list l = TList l -let ty_option o = TOption o - -type pattern = - | PAny (* _ *) - | PVar of id - (* | PUnit *) - | PTuple of pattern * pattern * pattern list - (* | PCons of pattern * pattern (* h :: t *) *) - | PList of pattern list (* [23; 34] *) - | PConst of const (* 23 *) - | POption of pattern option (* | PType of pattern * core_type *) -[@@deriving show { with_path = false }] - -type expression = - | EConst of const - | EVar of id - | EUnary of op_un * expression - | EBinary of op_bin * expression * expression - | ETuple of expression * expression * expression list - | EList of expression list - | EOption of expression option - (* | EMatch of expression * case * case list (* match *) *) - | EIf of expression * expression * expression option (* if x then false else true *) - | EFun of pattern * expression (* fun x -> x *) - (* | EFunction of case * case list (* function *) *) - | EApply of expression * expression (* f x *) - | ELet of rec_flag * value_binding * value_binding list * expression - | EType of expression * core_type -(* let x = 23 in x *) -(* | ECons of expression * expression *) -[@@deriving show { with_path = false }] - -(* and case = pattern * expression [@@deriving show { with_path = false }] *) -and value_binding = pattern * expression [@@deriving show { with_path = false }] - -type structure_item = - | SValue of rec_flag * value_binding * value_binding list (* let f x = x *) -(* | SEval of expression *) -[@@deriving show { with_path = false }] - -type program = structure_item list [@@deriving show { with_path = false }] diff --git a/EChirkov/lib/dune b/EChirkov/lib/dune deleted file mode 100644 index 6c23ab4c4..000000000 --- a/EChirkov/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name EChirkov) - (public_name EChirkov.Lib) - (modules Ast Parser Inferencer Interpreter) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/EChirkov/lib/inferencer.ml b/EChirkov/lib/inferencer.ml deleted file mode 100644 index 9c35e27a8..000000000 --- a/EChirkov/lib/inferencer.ml +++ /dev/null @@ -1,665 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base - -module VarSet = struct - include Stdlib.Set.Make (Int) -end - -type fresh = int - -let alph = - [ "🍏" - ; "🍎" - ; "🍐" - ; "🍊" - ; "🍋" - ; "🍋‍🟩" - ; "🍌" - ; "🍉" - ; "🍇" - ; "🍓" - ; "🫐" - ; "🍈" - ; "🍒" - ; "🍑" - ; "🥭" - ; "🍍" - ; "🥥" - ; "🥝" - ] -;; - -module IntMap = Stdlib.Map.Make (Int) - -let binder_to_alpha b = - let rec to_string n = - if n < 0 - then "" - else ( - let rem = Stdlib.( mod ) n (List.length alph) in - let char = - match List.nth alph rem with - | Some c -> c - | None -> Int.to_string b - in - let rest = to_string ((n / List.length alph) - 1) in - rest ^ char) - in - to_string b -;; - -let pp_ty fmt ty = - let compute_var_mapping = - let rec collect_vars acc = function - | TPrim _ -> acc - | TVar v -> if IntMap.mem v acc then acc else IntMap.add v (IntMap.cardinal acc) acc - | TArrow (l, r) -> collect_vars (collect_vars acc l) r - | TTuple (t1, t2, tl) -> - List.fold_left ~f:collect_vars ~init:(collect_vars (collect_vars acc t1) t2) tl - | TOption t -> collect_vars acc t - | TList t -> collect_vars acc t - in - collect_vars IntMap.empty ty - in - let rec helper var_mappings fmt = function - | TPrim s -> Stdlib.Format.fprintf fmt "%s" s - | TVar v -> - Stdlib.Format.fprintf fmt "%s" (binder_to_alpha (IntMap.find v var_mappings)) - | TArrow (l, r) -> - Stdlib.Format.fprintf - fmt - "(%a -> %a)" - (helper var_mappings) - l - (helper var_mappings) - r - | TTuple (t1, t2, tl) -> - Stdlib.Format.fprintf - fmt - "(%a)" - (Stdlib.Format.pp_print_list - ~pp_sep:(fun _ _ -> Stdlib.Format.printf " * ") - (fun fmt ty -> - match ty with - | TPrim _ | TVar _ -> Stdlib.Format.fprintf fmt "%a" (helper var_mappings) ty - | _ -> Stdlib.Format.fprintf fmt "(%a)" (helper var_mappings) ty)) - (t1 :: t2 :: tl) - | TOption o -> Stdlib.Format.fprintf fmt "%a option" (helper var_mappings) o - | TList l -> Stdlib.Format.fprintf fmt "%a list" (helper var_mappings) l - in - helper compute_var_mapping fmt ty -;; - -type error = - | OccursCheck of binder * core_type - | NoVariable of id - | UnificationFailed of core_type * core_type - | InvalidLeftHandSide - | InvalidRightHandSide - -let pp_error fmt = function - | OccursCheck (v, t) -> - Stdlib.Format.fprintf - fmt - "Cannot construct type: %a appears within %a" - pp_ty - (ty_var v) - pp_ty - t - | NoVariable s -> Stdlib.Format.fprintf fmt "Undefined variable '%s'" s - | UnificationFailed (l, r) -> - Stdlib.Format.fprintf fmt "Unification failed on %a and %a" pp_ty l pp_ty r - | InvalidLeftHandSide -> Stdlib.Format.fprintf fmt "Invalid left hand side" - | InvalidRightHandSide -> Stdlib.Format.fprintf fmt "Invalid right hand side" -;; - -module Result : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RMap : sig - val fold - : ('k, 'v, 'cmp) Base.Map.t - -> init:'b t - -> f:('k -> 'v -> 'b -> 'b t) - -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - val fold_right : 'a list -> init:'b t -> f:('a -> 'b -> 'b t) -> 'b t - val map : 'a list -> f:('a -> 'b t) -> 'b list t - end - - (** Creation of a fresh name from internal state *) - val fresh : int t - - (** Running a transformer: getting the inner result value *) - val run : 'a t -> ('a, error) Result.t -end = struct - (* A compositon: State monad after Result monad *) - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let last, r = m st in - match r with - | Result.Error x -> last, Result.fail x - | Result.Ok a -> f a last - ;; - - let fail e st = st, Base.Result.fail e - let return x last = last, Base.Result.return x - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Ok x -> st, Result.return (f x) - | st, Result.Error e -> st, Result.fail e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - module RMap = struct - let fold xs ~init ~f = - Map.fold xs ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_right xs ~init ~f = - let open Syntax in - Base.List.fold_right xs ~init ~f:(fun x acc -> - let* acc = acc in - f x acc) - ;; - - let map xs ~f = - let open Syntax in - let rec helper acc = function - | x :: t -> - let* res = f x in - helper (res :: acc) t - | [] -> return (List.rev acc) - in - helper [] xs - ;; - end - - let fresh : int t = fun last -> last + 1, Result.Ok last - let run m = snd (m 0) -end - -module Type = struct - let rec occurs_in v = function - | TPrim _ -> false - | TVar x -> x = v - | TArrow (l, r) -> occurs_in v l || occurs_in v r - | TTuple (t1, t2, tl) -> - occurs_in v t1 || occurs_in v t2 || Base.List.exists tl ~f:(occurs_in v) - | TList l -> occurs_in v l - | TOption typ -> occurs_in v typ - ;; - - let free_vars = - let rec helper acc = function - | TPrim _ -> acc - | TVar x -> VarSet.add x acc - | TArrow (l, r) -> helper (helper acc l) r - | TTuple (t1, t2, tl) -> - let acc' = helper (helper acc t1) t2 in - List.fold_left ~f:(fun acc t -> helper acc t) ~init:acc' tl - | TList t -> helper acc t - | TOption t -> helper acc t - in - helper VarSet.empty - ;; -end - -(* ========== Substitutions ========== *) - -module Subst : sig - type t - - val empty : t - val singleton : fresh -> core_type -> t Result.t - val remove : t -> fresh -> t - val apply : t -> core_type -> core_type - val unify : core_type -> core_type -> t Result.t - val compose : t -> t -> t Result.t - val compose_all : t list -> t Result.t -end = struct - open Result - open Result.Syntax - - type t = (fresh, core_type, Int.comparator_witness) Map.t - - let empty = Map.empty (module Int) - let mapping k v = if Type.occurs_in k v then fail (OccursCheck (k, v)) else return (k, v) - - let singleton k v = - let* k, v = mapping k v in - return (Map.singleton (module Int) k v) - ;; - - let find s k = Map.find s k - let remove s k = Map.remove s k - - let apply s = - let rec helper = function - | TVar v as ty -> - (match find s v with - | Some ty' -> helper ty' - | None -> ty) - | TArrow (l, r) -> ty_arrow (helper l, helper r) - | TTuple (t1, t2, tl) -> ty_tuple (helper t1, helper t2, List.map ~f:helper tl) - | TOption t -> ty_option (helper t) - | TList t -> ty_list (helper t) - | TPrim s -> TPrim s - in - helper - ;; - - let rec unify l r = - match l, r with - | TPrim l, TPrim r when String.equal l r -> return empty - | TVar l, TVar r when l = r -> return empty - | TVar v, t | t, TVar v -> singleton v t - | TArrow (l1, r1), TArrow (l2, r2) -> - let* s1 = unify l1 l2 in - let* s2 = unify (apply s1 r1) (apply s1 r2) in - compose s1 s2 - | TList t1, TList t2 -> unify t1 t2 - | TTuple (t11, t12, t1l), TTuple (t21, t22, t2l) -> - if List.length t1l <> List.length t2l - then fail (UnificationFailed (l, r)) - else ( - let rec unify_tuples subst types1 types2 = - match types1, types2 with - | [], [] -> return subst - | t1 :: rest1, t2 :: rest2 -> - let* s2 = unify (apply subst t1) (apply subst t2) in - let* composed_subst = compose subst s2 in - unify_tuples composed_subst rest1 rest2 - | _, _ -> fail (UnificationFailed (l, r)) - in - unify_tuples empty (t11 :: t12 :: t1l) (t21 :: t22 :: t2l)) - | TOption t1, TOption t2 -> unify t1 t2 - | _ -> fail (UnificationFailed (l, r)) - - and extend k v s = - match find s k with - | None -> - let v = apply s v in - let* s2 = singleton k v in - RMap.fold s ~init:(return s2) ~f:(fun k v acc -> - let v = apply s2 v in - let* k, v = mapping k v in - return (Map.update acc k ~f:(fun _ -> v))) - | Some v2 -> - let* s2 = unify v v2 in - compose s s2 - - and compose s1 s2 = RMap.fold s2 ~init:(return s1) ~f:extend - - and compose_all ss = - List.fold_left ss ~init:(return empty) ~f:(fun acc s -> - let* acc = acc in - compose acc s) - ;; -end - -(* ========== Scheme ========== *) - -module Scheme = struct - type binder_set = VarSet.t - type t = S of binder_set * core_type - - let free_vars (S (xs, t)) = VarSet.diff (Type.free_vars t) xs - - let apply s (S (xs, t)) = - let s2 = VarSet.fold (fun k s -> Subst.remove s k) xs s in - S (xs, Subst.apply s2 t) - ;; -end - -(* ========== Env ========== *) - -module TypeEnv = struct - type t = (id, Scheme.t, String.comparator_witness) Map.t - - let extend e k v = Map.update e k ~f:(fun _ -> v) - let remove e k = Map.remove e k - let empty = Map.empty (module String) - - let free_vars : t -> VarSet.t = - Map.fold ~init:VarSet.empty ~f:(fun ~key:_ ~data:s acc -> - VarSet.union acc (Scheme.free_vars s)) - ;; - - let apply s env = Map.map env ~f:(Scheme.apply s) - let find x env = Map.find env x -end - -open Result -open Result.Syntax - -let fresh_var = fresh >>| fun n -> TVar n - -let instantiate : Scheme.t -> core_type Result.t = - fun (S (bs, t)) -> - VarSet.fold - (fun name typ -> - let* typ = typ in - let* f1 = fresh_var in - let* s = Subst.singleton name f1 in - return (Subst.apply s typ)) - bs - (return t) -;; - -let generalize env ty = - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - Scheme.S (free, ty) -;; - -let generalize_rec env ty x = - let env = TypeEnv.remove env x in - generalize env ty -;; - -let rec infer_pattern env = function - | PAny -> - let* fresh = fresh_var in - return (Subst.empty, env, fresh) - | PConst c -> - (match c with - | CInt _ -> return (Subst.empty, env, ty_int) - | CBool _ -> return (Subst.empty, env, ty_bool) - | CUnit -> return (Subst.empty, env, ty_unit)) - | PVar x -> - let* fresh = fresh_var in - let env = TypeEnv.extend env x (Scheme.S (VarSet.empty, fresh)) in - return (Subst.empty, env, fresh) - | PTuple (t1, t2, tl) -> - let* s1, env1, t1' = infer_pattern env t1 in - let* s2, env2, t2' = infer_pattern (TypeEnv.apply s1 env1) t2 in - let* sub, tl', env = - RList.fold_right - ~f:(fun p acc -> - let sub_prev, acc, env = acc in - let* sub_cur, env, t = infer_pattern env p in - let* sub = Subst.compose sub_prev sub_cur in - return (sub, t :: acc, env)) - ~init:(return (s2, [], env2)) - tl - in - return (sub, env, ty_tuple (t1', t2', tl')) - | PList [] -> - let* fresh = fresh_var in - return (Subst.empty, env, ty_list fresh) - | PList pl -> - let* fresh_el_type = fresh_var in - let* final_sub, final_env = - RList.fold_left - pl - ~init:(return (Subst.empty, env)) - ~f:(fun (sub_acc, env_acc) pat -> - let* sub_cur, env_cur, t = infer_pattern env_acc pat in - let* unified_sub = Subst.compose sub_acc sub_cur in - let* final_sub = Subst.unify (Subst.apply sub_cur fresh_el_type) t in - let combined_sub = Subst.compose unified_sub final_sub in - let* combined_sub = combined_sub in - return (combined_sub, TypeEnv.apply final_sub env_cur)) - in - return (final_sub, final_env, TList (Subst.apply final_sub fresh_el_type)) - | POption (Some p) -> - let* sub, env1, t1 = infer_pattern env p in - return (sub, env1, ty_option t1) - | POption None -> - let* fresh = fresh_var in - return (Subst.empty, env, ty_option fresh) -;; - -let rec infer_expression env = function - | EConst c -> - (match c with - | CInt _ -> return (Subst.empty, ty_int) - | CBool _ -> return (Subst.empty, ty_bool) - | CUnit -> return (Subst.empty, ty_unit)) - | EVar x -> - (match TypeEnv.find x env with - | Some s -> - let* t = instantiate s in - return (Subst.empty, t) - | None -> fail (NoVariable x)) - | EUnary (_, e) -> - let* sub1, t1 = infer_expression env e in - let* sub2 = Subst.unify (Subst.apply sub1 t1) ty_int in - let* sub = Subst.compose_all [ sub1; sub2 ] in - return (sub, Subst.apply sub ty_int) - | EBinary (op, e1, e2) -> - let* sub1, t1 = infer_expression env e1 in - let* sub2, t2 = infer_expression (TypeEnv.apply sub1 env) e2 in - let* e1t, e2t, et = - match op with - | Mul | Div | Add | Sub -> return (ty_int, ty_int, ty_int) - | Eq | NEq | Lt | Lte | Gt | Gte -> - let* fresh = fresh_var in - return (fresh, fresh, ty_bool) - | And | Or -> return (ty_bool, ty_bool, ty_bool) - in - let* sub3 = Subst.unify (Subst.apply sub2 t1) e1t in - let* sub4 = Subst.unify (Subst.apply sub3 t2) e2t in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4 ] in - return (sub, Subst.apply sub et) - | EIf (i, t, e) -> - let* sub1, t1 = infer_expression env i in - let* sub2, t2 = infer_expression (TypeEnv.apply sub1 env) t in - let* sub3, t3 = - match e with - | Some e -> - let* sub3, t3 = infer_expression (TypeEnv.apply sub2 env) e in - return (sub3, t3) - | None -> return (Subst.empty, ty_unit) - in - let* sub4 = Subst.unify t1 ty_bool in - let* sub5 = Subst.unify t2 t3 in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4; sub5 ] in - return (sub, Subst.apply sub t2) - | ELet (Nonrecursive, b, bl, e) -> - let bindings = b :: bl in - let* env2, s1 = infer_nonrec_bs env bindings in - let* s2, t = infer_expression env2 e in - let* sub = Subst.compose s1 s2 in - return (sub, t) - | ELet (Recursive, b, bl, e) -> - let bindings = b :: bl in - let* env2, s1 = infer_rec_bs env bindings in - let* s, t = infer_expression env2 e in - let* sub = Subst.compose s1 s in - return (sub, t) - | EFun (p, e) -> - let* _, env, t = infer_pattern env p in - let* sub, t1 = infer_expression env e in - return (sub, Subst.apply sub (ty_arrow (t, t1))) - | ETuple (e0, e1, exps) -> - let* sub0, t0 = infer_expression env e0 in - let* sub1, t1 = infer_expression env e1 in - let* subs, ts = - RList.map exps ~f:(fun e -> infer_expression env e) - >>| List.fold_right ~f:(fun (p, e) (ps, es) -> p :: ps, e :: es) ~init:([], []) - in - let* sub = Subst.compose_all (sub0 :: sub1 :: subs) in - return (sub, TTuple (t0, t1, ts)) - | EApply (e1, e2) -> - let* fresh = fresh_var in - let* s1, t1 = infer_expression env e1 in - let* s2, t2 = infer_expression (TypeEnv.apply s1 env) e2 in - let* s3 = Subst.unify (ty_arrow (t2, fresh)) (Subst.apply s2 t1) in - let* sub = Subst.compose_all [ s1; s2; s3 ] in - let t = Subst.apply sub fresh in - return (sub, t) - | EList [] -> - let* fresh = fresh_var in - return (Subst.empty, ty_list fresh) - | EList (l :: ls) -> - (match l :: ls with - | [] -> - let* fresh = fresh_var in - return (Subst.empty, ty_list fresh) - | h :: tl -> - let* sr, tr = - List.fold_left tl ~init:(infer_expression env h) ~f:(fun acc e -> - let* sub, t = acc in - let* s1, t1 = infer_expression env e in - let* s2 = Subst.unify t t1 in - let* final_s = Subst.compose_all [ sub; s1; s2 ] in - let final_t = Subst.apply final_s t in - return (final_s, final_t)) - in - return (sr, ty_list tr)) - | EOption (Some eo) -> - let* s, t = infer_expression env eo in - return (s, ty_option t) - | EOption None -> - let* t = fresh_var in - return (Subst.empty, ty_option t) - | EType (e, t) -> - let* s1, t1 = infer_expression env e in - let* s2 = Subst.unify t1 t in - let* s1 = Subst.compose s2 s1 in - return (s1, t1) - -and infer_nonrec_bs env bl = - let* env2, sub2 = - Base.List.fold_left - ~f:(fun acc b -> - let* env, sub = acc in - let p, e = b in - let* s, t = infer_expression env e in - let* sub = Subst.compose s sub in - let env = TypeEnv.apply sub env in - let* env, sub = - match p with - | PVar x -> return (TypeEnv.extend env x (generalize env t), sub) - | _ -> - let* _, env, t' = infer_pattern env p in - let* sub' = Subst.unify t' t in - let* sub = Subst.compose_all [ sub'; sub ] in - return (TypeEnv.apply sub env, sub) - in - return (env, sub)) - ~init:(return (env, Subst.empty)) - bl - in - return (env2, sub2) - -and infer_rec_bs env bl = - let* env0 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, _ = b in - match p with - | PVar x -> - let* fresh = fresh_var in - let sc = Scheme.S (VarSet.empty, fresh) in - let env = TypeEnv.extend env x sc in - return env - | _ -> fail InvalidLeftHandSide) - ~init:(return env) - bl - in - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar x -> - let* fresh = fresh_var in - let sc = Scheme.S (VarSet.empty, fresh) in - let env = TypeEnv.extend env x sc in - let* s1, t1 = infer_expression env e in - (match t1 with - | TArrow _ -> - let* s2 = Subst.unify t1 fresh in - let* s3 = Subst.compose s1 s2 in - let env = TypeEnv.apply s3 env in - let t2 = Subst.apply s3 t1 in - let sc = generalize_rec env t2 x in - let env = TypeEnv.extend env x sc in - return env - | _ -> fail InvalidRightHandSide) - | _ -> fail InvalidLeftHandSide) - ~init:(return env0) - bl - in - return (env2, Subst.empty) -;; - -let infer_structure_item env = function - | SValue (Nonrecursive, b, bl) -> - let bindings = b :: bl in - let* env, _ = infer_nonrec_bs env bindings in - return env - | SValue (Recursive, b, bl) -> - let bindings = b :: bl in - let* env, _ = infer_rec_bs env bindings in - return env -;; - -let infer_program p = - let env = - TypeEnv.extend - TypeEnv.empty - "print_int" - (Scheme.S (VarSet.empty, ty_arrow (ty_int, ty_unit))) - in - List.fold_left - ~f:(fun acc item -> - let* env = acc in - let* env = infer_structure_item env item in - return env) - ~init:(return env) - p -;; - -(* ========== print ========== *) - -let print_env env = - Base.Map.iteri env ~f:(fun ~key ~data:(Scheme.S (_, ty)) -> - match key with - | key when String.equal key "print_int" -> () - | key -> Stdlib.Format.printf "val %s : %a\n" key pp_ty ty) -;; - -(* inference *) - -let inference p = run (infer_program p) diff --git a/EChirkov/lib/inferencer.mli b/EChirkov/lib/inferencer.mli deleted file mode 100644 index 24b2f5e33..000000000 --- a/EChirkov/lib/inferencer.mli +++ /dev/null @@ -1,30 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Stdlib - -module VarSet : sig - include Set.S with type elt = int -end - -module Scheme : sig - type binder_set = VarSet.t - type t = S of binder_set * core_type -end - -type error = - | OccursCheck of binder * core_type - | NoVariable of id - | UnificationFailed of core_type * core_type - | InvalidLeftHandSide - | InvalidRightHandSide - -val inference - : structure_item list - -> ((string, Scheme.t, Base.String.comparator_witness) Base.Map.t, error) result - -val pp_error : Format.formatter -> error -> unit -val print_env : (string, Scheme.t, 'a) Base.Map.t -> unit diff --git a/EChirkov/lib/interpreter.ml b/EChirkov/lib/interpreter.ml deleted file mode 100644 index 4dc78c7d4..000000000 --- a/EChirkov/lib/interpreter.ml +++ /dev/null @@ -1,320 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base - -(* ========== errors ========== *) - -type error = - | UnboundVariable of string - | TypeMissmatch - | DivisionByZero - -let pp_error = function - | UnboundVariable s -> "Unbound variable: " ^ s - | TypeMissmatch -> "Type error" - | DivisionByZero -> "Division by zero" -;; - -(* ========== values ========== *) - -type value = - | VInt of int - | VString of string - | VBool of bool - | VTuple of value * value * value list - | VFun of rec_flag * pattern * expression * environment - | VFunMutual of rec_flag * pattern * expression * environment - | VList of value list - | VOption of value option - | VUnit - | VPrintInt - -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -(* ========== result monad ========== *) - -module type Monad = sig - include Base.Monad.S2 - - val fail : error -> ('a, error) t - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -(* ========== environment ========== *) - -module Environment (M : Monad) = struct - open M - - let empty = Base.Map.empty (module Base.String) (* create empty env *) - - let find env name = - (* get from env by name *) - match Base.Map.find env name with - | Some x -> return x - | None -> fail (UnboundVariable name) - ;; - - (* put in env binding *) - let extend env k v = Base.Map.update env k ~f:(fun _ -> v) -end - -(* ========== evaluation ========== *) - -module Evaluate (M : Monad) = struct - open M - open Environment (M) - - let rec match_pattern env = function - | PAny, _ -> Some env - | PConst (CInt i1), VInt i2 when i1 = i2 -> Some env - | PConst (CBool b1), VBool b2 when Bool.equal b1 b2 -> Some env - | PConst CUnit, VUnit -> Some env - | PVar x, v -> Some (extend env x v) - | PTuple (p1, p2, prest), VTuple (v1, v2, vrest) -> - match_pattern_list env (p1 :: p2 :: prest) (v1 :: v2 :: vrest) - | PList pl, VList vl -> match_pattern_list env pl vl - | POption None, VOption None -> Some env - | POption (Some p), VOption (Some v) -> - let env = match_pattern env (p, v) in - (match env with - | Some env -> Some env - | None -> None) - | _ -> None - - and match_pattern_list env patterns values = - if List.length patterns <> List.length values - then None - else ( - let f1 acc (p, v) = - match acc with - | None -> None - | Some env' -> match_pattern env' (p, v) - in - let rec zip l1 l2 = - match l1, l2 with - | [], [] -> [] - | x :: xs, y :: ys -> (x, y) :: zip xs ys - | _ -> [] - in - List.fold_left ~f:f1 ~init:(Some env) (zip patterns values)) - ;; - - let rec eq_value v1 v2 = - match v1, v2 with - | VList x, VList y -> - let rec eq_list lst1 lst2 = - match lst1, lst2 with - | [], [] -> true - | VInt a :: t1, VInt b :: t2 -> a = b && eq_list t1 t2 - | VBool a :: t1, VBool b :: t2 -> - ((a && b) || ((not a) && not b)) && eq_list t1 t2 - | VList a :: t1, VList b :: t2 -> eq_list a b && eq_list t1 t2 - | _ -> false - in - Some (VBool (eq_list x y)) - | VInt x, VInt y -> Some (VBool (x = y)) - | VBool x, VBool y -> Some (VBool ((x && y) || ((not x) && not y))) - | VOption (Some x), VOption (Some y) -> eq_value x y - | VOption None, VOption None - | VOption None, VOption (Some _) - | VOption (Some _), VOption None -> Some (VBool false) - | _ -> None - ;; - - let rec eval_expression env = function - | EConst c -> - (match c with - | CInt i -> return (VInt i) - | CBool b -> return (VBool b) - | CUnit -> return VUnit) - | EVar x -> - let* v = find env x in - let v = - match v with - | VFun (Recursive, p, e, env) -> VFun (Recursive, p, e, extend env x v) - | _ -> v - in - return v - | EBinary (op, e1, e2) -> - let* v1 = eval_expression env e1 in - let* v2 = eval_expression env e2 in - (match op, v1, v2 with - | Add, VInt x, VInt y -> return (VInt (x + y)) - | Sub, VInt x, VInt y -> return (VInt (x - y)) - | Mul, VInt x, VInt y -> return (VInt (x * y)) - | Div, VInt x, VInt y -> - (match y with - | 0 -> fail DivisionByZero - | _ -> return (VInt (x / y))) - | Lt, VInt x, VInt y -> return (VBool (x < y)) - | Gt, VInt x, VInt y -> return (VBool (x > y)) - | Eq, x, y -> - (match eq_value x y with - | Some v -> return v - | None -> fail TypeMissmatch) - | NEq, x, y -> - (match eq_value x y with - | Some v -> - (match v with - | VBool v -> return (VBool (not v)) - | _ -> fail TypeMissmatch) - | None -> fail TypeMissmatch) - | Lte, VInt x, VInt y -> return (VBool (x <= y)) - | Gte, VInt x, VInt y -> return (VBool (x >= y)) - | And, VBool x, VBool y -> return (VBool (x && y)) - | Or, VBool x, VBool y -> return (VBool (x || y)) - | _ -> fail TypeMissmatch) - | EUnary (op, e) -> - let* v = eval_expression env e in - (match op, v with - | Pos, VInt x -> return (VInt x) - | Neg, VInt x -> return (VInt (-x)) - | _ -> fail TypeMissmatch) - | EIf (i, t, e) -> - let* cv = eval_expression env i in - (match cv with - | VBool true -> eval_expression env t - | VBool false -> - (match e with - | Some e -> eval_expression env e - | None -> return VUnit) - | _ -> fail TypeMissmatch) - | ELet (Nonrecursive, b, bl, e) -> - let bindings = b :: bl in - let* env2 = eval_nonrec_bs env bindings in - eval_expression env2 e - | ELet (Recursive, (PVar x, e1), [], e) -> - let* v = eval_expression env e1 in - let env1 = extend env x v in - let v = - match v with - | VFun (_, p, e, _) -> VFun (Recursive, p, e, env1) - | _ -> v - in - let env2 = extend env x v in - eval_expression env2 e - | ELet (Recursive, b, bl, e) -> - let bindings = b :: bl in - let* env2 = eval_rec_bs env bindings in - eval_expression env2 e - | EFun (p, e) -> return (VFun (Nonrecursive, p, e, env)) - | EApply (e1, e2) -> - let* v1 = eval_expression env e1 in - let* v2 = eval_expression env e2 in - (match v1 with - | VFun (_, p, e, env) -> - let* env' = - match match_pattern env (p, v2) with - | Some env -> return env - | None -> fail TypeMissmatch - in - eval_expression env' e - | VFunMutual (_, p, e, _) -> - let* env' = - match match_pattern env (p, v2) with - | Some env -> return env - | None -> fail TypeMissmatch - in - eval_expression env' e - | VPrintInt -> - (match v2 with - | VInt i -> - Stdlib.Format.printf "%d\n" i; - (* TODO: think *) return VUnit - | _ -> fail TypeMissmatch) - | _ -> fail TypeMissmatch) - | ETuple (e1, e2, el) -> - let* v1 = eval_expression env e1 in - let* v2 = eval_expression env e2 in - let* vl = - Base.List.fold_left - ~f:(fun acc e -> - let* acc = acc in - let* v = eval_expression env e in - return (v :: acc)) - ~init:(return []) - el - in - return (VTuple (v1, v2, List.rev vl)) - | EList el -> - let rec eval_list_elements env = function - | [] -> return [] - | e :: es -> - let* v = eval_expression env e in - let* vs = eval_list_elements env es in - return (v :: vs) - in - let* vl = eval_list_elements env el in - return (VList vl) - | EOption opt_expr -> - (match opt_expr with - | None -> return (VOption None) - | Some e -> - let* v = eval_expression env e in - return (VOption (Some v))) - | EType (e, _) -> eval_expression env e - - and eval_rec_bs env bl = - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar name -> - (match e with - | EFun (p1, e1) -> - return (extend env name (VFunMutual (Recursive, p1, e1, env))) - | _ -> return env) - | _ -> return env) - ~init:(return env) - bl - in - return env2 - - and eval_nonrec_bs env bl = - let* env2 = - List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - let* v = eval_expression env e in - match match_pattern env (p, v) with - | Some env2 -> return env2 - | None -> return env) - ~init:(return env) - bl - in - return env2 - ;; - - let eval_structure_item env s = - let env = extend env "print_int" VPrintInt in - match s with - | SValue (Nonrecursive, b, bl) -> eval_nonrec_bs env (b :: bl) - | SValue (Recursive, b, bl) -> eval_rec_bs env (b :: bl) - ;; - - let eval_program (p : program) = - List.fold_left - ~f:(fun env structure_item -> - let* env = env in - let* env = eval_structure_item env structure_item in - return env) - ~init:(return empty) - p - ;; -end - -module Interpret = Evaluate (struct - include Result - - let ( let* ) m f = bind m ~f - end) - -(* interpret *) - -let interpret = Interpret.eval_program diff --git a/EChirkov/lib/interpreter.mli b/EChirkov/lib/interpreter.mli deleted file mode 100644 index ef0adf893..000000000 --- a/EChirkov/lib/interpreter.mli +++ /dev/null @@ -1,30 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - | UnboundVariable of string - | TypeMissmatch - | DivisionByZero - -type value = - | VInt of int - | VString of string - | VBool of bool - | VTuple of value * value * value list - | VFun of rec_flag * pattern * expression * environment - | VFunMutual of rec_flag * pattern * expression * environment - | VList of value list - | VOption of value option - | VUnit - | VPrintInt - -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -val interpret - : program - -> ((string, value, Base.String.comparator_witness) Base.Map.t, error) result - -val pp_error : error -> string diff --git a/EChirkov/lib/parser.ml b/EChirkov/lib/parser.ml deleted file mode 100644 index 4d17b4c06..000000000 --- a/EChirkov/lib/parser.ml +++ /dev/null @@ -1,293 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Angstrom -open Base - -(* ========== errors ========== *) - -type error = - | UnexpectedToken of string - | Expected of string - | ReservedKeyword of string - | WildcardUsed - -let pp_error = function - | UnexpectedToken tok -> "Unexpected token: " ^ tok - | Expected msg -> "Expected: " ^ msg - | ReservedKeyword name -> "Reserved keyword cannot be used: " ^ name - | WildcardUsed -> "Wildcard '_' cannot be used as a variable name." -;; - -(* ========== basic ========== *) - -let is_ws = function - | '\x20' | '\x0a' | '\x0d' | '\x09' -> true - | _ -> false -;; - -let ws = take_while is_ws - -let is_digit = function - | '0' .. '9' -> true - | _ -> false -;; - -let is_keyword = function - | "let" | "in" | "if" | "then" | "else" | "fun" | "rec" | "true" | "false" | "and" -> - true - | _ -> false -;; - -let is_id c = Char.is_alphanum c || Char.equal c '_' || Char.equal c '\'' -let token str = ws *> string str -let parens s = token "(" *> s <* token ")" -let p_digits = take_while1 is_digit - -let chainl1 e op = - let rec go acc = lift2 (fun f x -> f acc x) op e >>= go <|> return acc in - e >>= fun init -> go init <|> fail (Expected "operator" |> pp_error) -;; - -let p_rec_flag = - choice [ token "rec" *> take_while1 is_ws *> return Recursive; return Nonrecursive ] -;; - -(* ========== consts ========== *) - -(* let p_string = - token "\"" *> take_till (Char.equal '\"') <* token "\"" >>| fun s -> CString s - ;; *) - -let p_integer = - let* num = ws *> p_digits in - let* next = peek_char in - match next with - | Some ('a' .. 'z' | '_') -> fail "unexpected character after number" - | _ -> return (CInt (Int.of_string num)) -;; - -let p_boolean = - let t = token "true" *> return (CBool true) in - let f = token "false" *> return (CBool false) in - choice [ t; f ] -;; - -let p_unit = token "()" *> return CUnit - -let p_const = - choice - ~failure_msg:(Expected "a constant (integer, string, boolean, unit)" |> pp_error) - [ p_integer; (*p_string;*) p_boolean; p_unit ] -;; - -let p_variable = - let* _ = ws in - let* first_char = peek_char_fail in - match first_char with - | 'a' .. 'z' | '_' -> - let* name = take_while is_id in - (match name with - | "_" -> fail (pp_error WildcardUsed) - | name when is_keyword name -> fail (pp_error (ReservedKeyword name)) - | name -> return name) - | _ -> fail (pp_error (UnexpectedToken "Expected an identifier")) -;; - -(* ========== type anonotaions ========== *) - -let rec p_tlist t = - let* t = t in - let* _ = token "list" in - p_tlist (return (ty_list t)) <|> return (ty_list t) -;; - -let p_toption t = - let* t = t in - let* _ = token "option" in - return (ty_option t) -;; - -let p_ttuple t = - let* f = t in - let* s = token "*" *> t in - let+ rest = many (token "*" *> t) in - ty_tuple (f, s, rest) -;; - -let p_type = - fix - @@ fun t -> - let types = - choice - [ token "int" *> return ty_int - ; token "bool" *> return ty_bool - ; token "unit" *> return ty_unit - ] - <|> parens t - in - let t_list = p_tlist types <|> types in - let t_opt = p_toption t_list <|> t_list in - let t_tup = p_ttuple t_opt <|> t_opt in - t_tup -;; - -let p_etype e = - let* e = token "(" *> e in - let+ ty = token ":" *> p_type <* token ")" in - EType (e, ty) -;; - -(* ========== patterns ========== *) - -let p_any = token "_" *> return PAny - -let p_ptuple e = - let tuple = - lift3 - (fun e1 e2 rest -> PTuple (e1, e2, rest)) - (e <* token ",") - e - (many (token "," *> e)) - <* ws - in - parens tuple <|> tuple -;; - -let p_plist e = - token "[" *> sep_by (token ";" *> ws) e <* token "]" >>| fun es -> PList es -;; - -let p_poption e = - choice - [ token "None" *> return (POption None) - ; (token "Some" *> choice [ parens e; e ] >>| fun e -> POption (Some e)) - ] -;; - -let p_pattern = - fix - @@ fun p -> - let term = - choice - [ (p_variable >>| fun v -> PVar v) - ; (p_unit >>| fun _ -> PConst CUnit) - ; p_poption p (* ; p_ptype p *) - ; p_plist p - ; p_any - ] - in - let tuples = p_ptuple term <|> term in - tuples -;; - -(* ========== exprs ========== *) - -let p_list e = token "[" *> sep_by (token ";" *> ws) e <* token "]" >>| fun es -> EList es - -let p_branch e = - lift3 - (fun ei et ee -> EIf (ei, et, ee)) - (token "if" *> e) - (token "then" *> e) - (option None (token "else" *> e >>| fun ee -> Some ee)) -;; - -let p_binop tkn binop = token tkn *> return (fun el er -> EBinary (binop, el, er)) <* ws - -let p_unop e = - lift2 - (fun unop e -> EUnary (unop, e)) - (choice [ token "-" *> return Neg <* ws; token "+" *> return Pos <* ws ]) - e -;; - -let p_tuple e = - let tuple = - lift3 - (fun e1 e2 rest -> ETuple (e1, e2, rest)) - (e <* token ",") - e - (many (token "," *> e)) - <* ws - in - parens tuple <|> tuple -;; - -let p_option e = - choice - [ token "None" *> return (EOption None) - ; (token "Some" *> choice [ parens e; e ] >>| fun e -> EOption (Some e)) - ] -;; - -let p_fun e = - let* ps = token "fun" *> many1 p_pattern in - let+ e = token "->" *> e in - List.fold_right ps ~init:e ~f:(fun p e -> EFun (p, e)) -;; - -let p_binding expr = - let* p = p_pattern in - let* ps = many p_pattern <* token "=" <* ws in - let+ e = p_etype expr <|> expr in - p, List.fold_right ps ~init:e ~f:(fun p e -> EFun (p, e)) -;; - -let p_let expr = - lift4 - (fun rf b bl e -> ELet (rf, b, bl, e)) - (token "let" *> p_rec_flag) - (p_binding expr) - (many (token "and" *> p_binding expr)) - (token "in" *> expr) -;; - -let p_expression = - fix - @@ fun e -> - let term = parens e in - let term = p_const >>| (fun e -> EConst e) <|> term in - let term = p_etype e <|> term in - let term = p_variable >>| (fun v -> EVar v) <|> term in - let term = p_list e <|> term in - let apply = chainl1 term (return (fun e1 e2 -> EApply (e1, e2))) in - let opt = p_option apply <|> apply in - let branch = p_branch e <|> opt in - let unary_op = branch <|> p_unop branch in - let multiplydivide_op = chainl1 unary_op (p_binop "*" Mul <|> p_binop "/" Div) in - let plusminus_op = chainl1 multiplydivide_op (p_binop "+" Add <|> p_binop "-" Sub) in - let compare_op = - chainl1 - plusminus_op - (choice - [ p_binop "=" Eq - ; p_binop "<>" NEq - ; p_binop "<=" Lte - ; p_binop "<" Lt - ; p_binop ">=" Gte - ; p_binop ">" Gt - ]) - in - let bool_op = chainl1 compare_op (p_binop "&&" And <|> p_binop "||" Or) in - let tuples = p_tuple bool_op <|> bool_op in - choice [ tuples; p_let e; p_fun e ] -;; - -(* ========== top level ========== *) - -let p_structure_item = - lift3 - (fun rf b bl -> SValue (rf, b, bl)) - (token "let" *> p_rec_flag) - (p_binding p_expression) - (many (token "and" *> p_binding p_expression)) -;; - -let p_program = many p_structure_item <* ws - -(* parse *) - -let parse s = parse_string ~consume:All p_program s diff --git a/EChirkov/lib/parser.mli b/EChirkov/lib/parser.mli deleted file mode 100644 index 150f7cfd5..000000000 --- a/EChirkov/lib/parser.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val parse : string -> (structure_item list, string) result diff --git a/EChirkov/tests/dune b/EChirkov/tests/dune deleted file mode 100644 index 6f2869d8a..000000000 --- a/EChirkov/tests/dune +++ /dev/null @@ -1,40 +0,0 @@ -(library - (name tests) - (public_name EChirkov.Tests) - (libraries EChirkov) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to test) - (deps - ../bin/main.exe - manytests/typed/001fac.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/006partial.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml)) diff --git a/EChirkov/tests/inferencer_tests.ml b/EChirkov/tests/inferencer_tests.ml deleted file mode 100644 index 5e2270b0f..000000000 --- a/EChirkov/tests/inferencer_tests.ml +++ /dev/null @@ -1,277 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EChirkov.Parser -open EChirkov.Inferencer - -let test_inferencer s = - match parse s with - | Ok s -> - (* print_endline (show_program s); *) - (match inference s with - | Ok env -> EChirkov.Inferencer.print_env env - | Error e -> Format.printf "Type inference error: %a" EChirkov.Inferencer.pp_error e) - | Error _ -> print_endline "Parsing error" -;; - -let%expect_test "inference factorial function" = - test_inferencer "let rec factorial n = if n < 2 then 1 else n * factorial(n - 1)"; - [%expect {|val factorial : (int -> int)|}] -;; - -(* ========== const ========== *) - -let%expect_test "inference int" = - test_inferencer "let x = 2"; - [%expect {|val x : int|}] -;; - -let%expect_test "inference bool" = - test_inferencer "let x = true"; - [%expect {|val x : bool|}] -;; - -let%expect_test "inference unit" = - test_inferencer "let x = ()"; - [%expect {|val x : unit|}] -;; - -(* ========== bop ========== *) - -let%expect_test "inference bop add sub mul div" = - test_inferencer "let x = 23 + 23 - 45 - (2 * 345) / (-98)"; - [%expect {| - val x : int|}] -;; - -let%expect_test "inference bop unit unify" = - test_inferencer "let x = true || ()"; - [%expect {| - Type inference error: Unification failed on unit and bool|}] -;; - -let%expect_test "inference bop bool unify" = - test_inferencer "let f x y = x && (y : int)"; - [%expect {| - Type inference error: Unification failed on bool and int|}] -;; - -(* ========== tuples ========== *) - -let%expect_test "inference tuple fst" = - test_inferencer "let f t = let (x, y) = t in x"; - [%expect {| - val f : ((🍏 * 🍎) -> 🍏)|}] -;; - -let%expect_test "inference tuple 2" = - test_inferencer "let (x, y) = (23, 12)"; - [%expect {| - val x : int - val y : int|}] -;; - -let%expect_test "inference tuple 3" = - test_inferencer "let (x, y, z) = (23, 12, true)"; - [%expect {| - val x : int - val y : int - val z : bool|}] -;; - -let%expect_test "inference tuples" = - test_inferencer - {| - let rec fix f x = f (fix f) x - let map f p = let (a,b) = p in (f a, f b) - let fixpoly l = - fix (fun self l -> map (fun li x -> li (self l) x) l) l - let feven p n = - let (e, o) = p in - if n = 0 then 1 else o (n - 1) - let fodd p n = - let (e, o) = p in - if n = 0 then 0 else e (n - 1) - let tie = fixpoly (feven, fodd) - - let rec meven n = if n = 0 then 1 else modd (n - 1) - and modd n = if n = 0 then 1 else meven (n - 1) - let main = - let () = print_int (modd 1) in - let () = print_int (meven 2) in - let (even,odd) = tie in - let () = print_int (odd 3) in - let () = print_int (even 4) in - 0 - |}; - [%expect - {| - val feven : ((🍏 * ((int -> int))) -> (int -> int)) - val fix : (((🍏 -> 🍎) -> (🍏 -> 🍎)) -> (🍏 -> 🍎)) - val fixpoly : (((((((🍏 -> 🍎)) * ((🍏 -> 🍎))) -> (🍏 -> 🍎))) * (((((🍏 -> 🍎)) * ((🍏 -> 🍎))) -> (🍏 -> 🍎)))) -> (((🍏 -> 🍎)) * ((🍏 -> 🍎)))) - val fodd : ((((int -> int)) * 🍏) -> (int -> int)) - val main : int - val map : ((🍏 -> 🍎) -> ((🍏 * 🍏) -> (🍎 * 🍎))) - val meven : (int -> int) - val modd : (int -> int) - val tie : (((int -> int)) * ((int -> int))) |}] -;; - -(* ========== list ========== *) - -let%expect_test "inference list pat" = - test_inferencer "let [a] = [false]"; - [%expect {| - val a : bool|}] -;; - -let%expect_test "inference list integers" = - test_inferencer "let l = [1; 2; 3]"; - [%expect {| val l : int list |}] -;; - -(* ========== vars ========== *) - -let%expect_test "inference var simple" = - test_inferencer "let a = 23 let b = a let c = b"; - [%expect {| - val a : int - val b : int - val c : int|}] -;; - -let%expect_test "inference var no" = - test_inferencer "let a = 23 let b = 45 let c = d"; - [%expect {| - Type inference error: Undefined variable 'd'|}] -;; - -(* ========== fun ========== *) - -let%expect_test "2+2" = - test_inferencer - {| - let two = fun f -> fun x -> f (f x) - let plus = fun m -> fun n -> fun f -> fun x -> m f (n f x) - let four = plus two two - let x = four (fun x -> x + 1) 0 - |}; - [%expect - {| - val four : ((🍏 -> 🍏) -> (🍏 -> 🍏)) - val plus : ((🍏 -> (🍎 -> 🍐)) -> ((🍏 -> (🍊 -> 🍎)) -> (🍏 -> (🍊 -> 🍐)))) - val two : ((🍏 -> 🍏) -> (🍏 -> 🍏)) - val x : int|}] -;; - -let%expect_test "2*2" = - test_inferencer - {| - let two = fun f -> fun x -> f (f x) - let mul = fun m -> fun n -> fun f -> fun x -> m (n f) x - let four = mul two two - let x = four (fun x -> x + 1) 0 - |}; - [%expect - {| - val four : ((🍏 -> 🍏) -> (🍏 -> 🍏)) - val mul : ((🍏 -> (🍎 -> 🍐)) -> ((🍊 -> 🍏) -> (🍊 -> (🍎 -> 🍐)))) - val two : ((🍏 -> 🍏) -> (🍏 -> 🍏)) - val x : int|}] -;; - -let%expect_test "inference id" = - test_inferencer "let id = fun x -> x"; - [%expect {| val id : (🍏 -> 🍏) |}] -;; - -let%expect_test "inference app" = - test_inferencer "let id = fun x -> x let x = id 42"; - [%expect {| - val id : (🍏 -> 🍏) - val x : int |}] -;; - -let%expect_test "inference higher-order" = - test_inferencer "let apply = fun f -> fun x -> f x"; - [%expect {| val apply : ((🍏 -> 🍎) -> (🍏 -> 🍎)) |}] -;; - -let%expect_test "inference pattern on tuples" = - test_inferencer "let fst = fun p -> let (x, y) = p in x"; - [%expect {| val fst : ((🍏 * 🍎) -> 🍏) |}] -;; - -let%expect_test "inference composition" = - test_inferencer "let compose = fun f -> fun g -> fun x -> f (g x)"; - [%expect {| val compose : ((🍏 -> 🍎) -> ((🍐 -> 🍏) -> (🍐 -> 🍎))) |}] -;; - -(* ========== option ========== *) - -let%expect_test "inference option Some" = - test_inferencer "let o = Some 42"; - [%expect {| val o : int option |}] -;; - -let%expect_test "inference option None" = - test_inferencer "let o = None"; - [%expect {| val o : 🍏 option |}] -;; - -let%expect_test "inference wrap" = - test_inferencer "let wrap = fun x -> Some x"; - [%expect {| val wrap : (🍏 -> 🍏 option) |}] -;; - -(* ========== if ========== *) - -let%expect_test "inference simple if" = - test_inferencer "let abs = fun x -> if x < 0 then -x else x"; - [%expect {| val abs : (int -> int) |}] -;; - -let%expect_test "inference nested if" = - test_inferencer "let sign = fun x -> if x > 0 then 1 else if x < 0 then -1 else 0"; - [%expect {| val sign : (int -> int) |}] -;; - -(* ========== let ========== *) - -let%expect_test "inference shadowing" = - test_inferencer "let x = let x = 42 in let x = true in x"; - [%expect {| val x : bool |}] -;; - -let%expect_test "inference multiple let" = - test_inferencer "let x = let a = 10 and b = 2 in a + b"; - [%expect {| val x : int |}] -;; - -let%expect_test "inference let rec self" = - test_inferencer "let rec x = x x"; - [%expect {| Type inference error: Cannot construct type: 🍏 appears within (🍏 -> 🍎) |}] -;; - -let%expect_test "inference let rec lhs" = - test_inferencer "let rec (x, y) = (23, 34)"; - [%expect {| Type inference error: Invalid left hand side |}] -;; - -let%expect_test "inference let rec rhs" = - test_inferencer "let rec f = f 23"; - [%expect {| Type inference error: Invalid right hand side |}] -;; - -(* ========== constraint ========== *) - -let%expect_test "inference constraint" = - test_inferencer "let f x y = y (x : bool)"; - [%expect {| val f : (bool -> ((bool -> 🍏) -> 🍏)) |}] -;; - -let%expect_test "inference constraint 2" = - test_inferencer "let f = fun x -> fun y -> (x x y : int)"; - [%expect {| Type inference error: Cannot construct type: 🍏 appears within (🍏 -> 🍎) |}] -;; diff --git a/EChirkov/tests/inferencer_tests.mli b/EChirkov/tests/inferencer_tests.mli deleted file mode 100644 index a8c0d9e24..000000000 --- a/EChirkov/tests/inferencer_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EChirkov/tests/interpreter_tests.ml b/EChirkov/tests/interpreter_tests.ml deleted file mode 100644 index 21b0a703e..000000000 --- a/EChirkov/tests/interpreter_tests.ml +++ /dev/null @@ -1,199 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EChirkov.Parser -open EChirkov.Interpreter - -let test_interpreter s = - match parse s with - | Ok s -> - (* print_endline (show_program s); *) - (match interpret s with - | Ok _ -> () - | Error e -> print_endline ("Interpretation error: " ^ pp_error e)) - | Error _ -> print_endline "Parsing error" -;; - -let%expect_test "interpret factorial function" = - test_interpreter - "let () = let rec factorial n = if n < 2 then 1 else n * factorial(n - 1) in \ - print_int (factorial 17)"; - [%expect {|355687428096000|}] -;; - -(* ========== const ========== *) - -let%expect_test "interpret int" = - test_interpreter "let () = print_int 23"; - [%expect {|23|}] -;; - -(* ========== bop ========== *) - -let%expect_test "interpret addition" = - test_interpreter "let () = print_int (23 + 23)"; - [%expect {| - 46|}] -;; - -let%expect_test "interpret subtraction" = - test_interpreter "let () = print_int (23 - 21)"; - [%expect {| - 2|}] -;; - -let%expect_test "interpret multiplication" = - test_interpreter "let () = print_int (123 * 23)"; - [%expect {| - 2829|}] -;; - -let%expect_test "interpret division whole" = - test_interpreter "let () = print_int (240 / 4)"; - [%expect {| - 60|}] -;; - -let%expect_test "interpret division" = - test_interpreter "let () = print_int (123 / 23)"; - [%expect {| - 5|}] -;; - -let%expect_test "interpret addition multiplication division" = - test_interpreter "let () = print_int (6 / 2 * (1 + 2))"; - [%expect {|9|}] -;; - -(* ========== unop ========== *) - -let%expect_test "interpret neg" = - test_interpreter "let () = print_int (-1)"; - [%expect {| - -1|}] -;; - -let%expect_test "interpret neg" = - test_interpreter "let () = print_int -1"; - [%expect {| - Interpretation error: Type error|}] -;; - -let%expect_test "interpret neg add" = - test_interpreter "let () = print_int (-500 + +100)"; - [%expect {| - -400|}] -;; - -(* ========== tuples ========== *) - -let%expect_test "interpret tuple fst" = - test_interpreter "let fst (x, y) = x let () = print_int (fst (23, 34))"; - [%expect {| - 23|}] -;; - -let%expect_test "interpret tuple multiple patterns" = - test_interpreter - {| - let () = - let a, b = 23, 34 in - let c, d = a, b in - let _ = print_int a in - let _ = print_int b in - let _ = print_int c in - print_int d - |}; - [%expect {| - 23 - 34 - 23 - 34|}] -;; - -(* ========== list ========== *) - -let%expect_test "interpret list empty" = - test_interpreter "let () = print_int (if [] = [] then 1 else 0)"; - [%expect {| - 1|}] -;; - -let%expect_test "interpret list 1" = - test_interpreter "let () = let [a] = [23] in print_int a"; - [%expect {| - 23|}] -;; - -(* ========== option ========== *) - -let%expect_test "interpret var simple" = - test_interpreter - {| - let x = None - let y = Some 23 - let z = Some 34 - let w = Some 23 - let () = print_int (if y = z then 1 else 0) - let () = print_int (if x = y then 1 else 0) - let () = print_int (if y = w then 1 else 0) - let () = print_int (if x = w then 1 else 0) - |}; - [%expect {| - 0 - 0 - 1 - 0|}] -;; - -(* ========== vars ========== *) - -let%expect_test "interpret var simple" = - test_interpreter "let asd = 23 let () = print_int asd"; - [%expect {| - 23|}] -;; - -(* ========== fun ========== *) - -let%expect_test "interpret fun list" = - test_interpreter - {| - let empty = fun f -> fun x -> x - let cons x xs = fun f -> fun x0 -> xs f (f x x0) - let print_list l = l (fun x rest -> let _ = print_int x in rest) () - let my_list = cons 1 (cons 2 (cons 3 empty)) - let () = print_list my_list - |}; - [%expect {| - 1 - 2 - 3|}] -;; - -(* ========== let ========== *) - -let%expect_test "interpret let simple" = - test_interpreter "let () = let x = 5 in let y = 2 in print_int (x + y)"; - [%expect {| - 7|}] -;; - -let%expect_test "interpret let unbound" = - test_interpreter "let () = print_int a"; - [%expect {| - Interpretation error: Unbound variable: a|}] -;; - -let%expect_test "interpret let types" = - test_interpreter "let a = 23 and () = print_int (a + false)"; - [%expect {| - Interpretation error: Type error|}] -;; - -let%expect_test "interpret let zero" = - test_interpreter "let () = print_int (23 / 0)"; - [%expect {| - Interpretation error: Division by zero|}] -;; diff --git a/EChirkov/tests/interpreter_tests.mli b/EChirkov/tests/interpreter_tests.mli deleted file mode 100644 index a8c0d9e24..000000000 --- a/EChirkov/tests/interpreter_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EChirkov/tests/parser_tests.ml b/EChirkov/tests/parser_tests.ml deleted file mode 100644 index 597bf76fc..000000000 --- a/EChirkov/tests/parser_tests.ml +++ /dev/null @@ -1,374 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EChirkov.Parser -open EChirkov.Ast - -let test_parser s = - match parse s with - | Ok s -> print_endline (show_program s) - | Error _ -> print_endline "Parsing error" -;; - -let%expect_test "parse simple let" = - test_parser "let x = 23"; - [%expect {|[(SValue (Nonrecursive, ((PVar "x"), (EConst (CInt 23))), []))]|}] -;; - -let%expect_test "parse factorial function" = - test_parser "let rec factorial n = if n < 2 then 1 else n * factorial(n - 1)"; - [%expect - {| - [(SValue (Recursive, - ((PVar "factorial"), - (EFun ((PVar "n"), - (EIf ((EBinary (Lt, (EVar "n"), (EConst (CInt 2)))), - (EConst (CInt 1)), - (Some (EBinary (Mul, (EVar "n"), - (EApply ((EVar "factorial"), - (EBinary (Sub, (EVar "n"), (EConst (CInt 1)))))) - ))) - )) - ))), - [])) - ]|}] -;; - -(* ========== const ========== *) - -let%expect_test "parse int" = - test_parser "let () = 23"; - [%expect {|[(SValue (Nonrecursive, ((PConst CUnit), (EConst (CInt 23))), []))]|}] -;; - -let%expect_test "parse bool t" = - test_parser "let () = true"; - [%expect {|[(SValue (Nonrecursive, ((PConst CUnit), (EConst (CBool true))), []))]|}] -;; - -let%expect_test "parse bool f" = - test_parser "let () = false"; - [%expect {|[(SValue (Nonrecursive, ((PConst CUnit), (EConst (CBool false))), []))]|}] -;; - -(* ========== bop ========== *) - -let%expect_test "parse compare int" = - test_parser "let () = 2 > 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (Gt, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare int" = - test_parser "let () = 2 < 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (Lt, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare int" = - test_parser "let () = 2 >= 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (Gte, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare int" = - test_parser "let () = 2 <= 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (Lte, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare int" = - test_parser "let () = 2 = 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (Eq, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare int" = - test_parser "let () = 2 <> 56"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EBinary (NEq, (EConst (CInt 2)), (EConst (CInt 56))))), - [])) - ]|}] -;; - -let%expect_test "parse compare and" = - test_parser "let () = true && false"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (EBinary (And, (EConst (CBool true)), (EConst (CBool false))))), - [])) - ]|}] -;; - -let%expect_test "parse compare or" = - test_parser "let () = false || true"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (EBinary (Or, (EConst (CBool false)), (EConst (CBool true))))), - [])) - ]|}] -;; - -(* ========== unop ========== *) - -let%expect_test "parse neg" = - test_parser "let () = (-1)"; - [%expect - {| - [(SValue (Nonrecursive, ((PConst CUnit), (EUnary (Neg, (EConst (CInt 1))))), - [])) - ]|}] -;; - -let%expect_test "parse neg apply" = - test_parser "let () = asd (-1)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (EApply ((EVar "asd"), (EUnary (Neg, (EConst (CInt 1))))))), - [])) - ]|}] -;; - -let%expect_test "parse neg pos" = - test_parser "let () = (-1) + (+5)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (EBinary (Add, (EUnary (Neg, (EConst (CInt 1)))), - (EUnary (Pos, (EConst (CInt 5))))))), - [])) - ]|}] -;; - -(* ========== tuples ========== *) - -let%expect_test "parse tuple 2" = - test_parser "let () = (12, 23)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (ETuple ((EConst (CInt 12)), (EConst (CInt 23)), []))), - [])) - ]|}] -;; - -let%expect_test "parse tuple 3" = - test_parser "let () = (12, 23, 45)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (ETuple ((EConst (CInt 12)), (EConst (CInt 23)), [(EConst (CInt 45))]))), - [])) - ]|}] -;; - -let%expect_test "parse tuple 2 d" = - test_parser "let () = (12, true)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (ETuple ((EConst (CInt 12)), (EConst (CBool true)), []))), - [])) - ]|}] -;; - -let%expect_test "parse tuple 3 d" = - test_parser "let () = (12, true, ())"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (ETuple ((EConst (CInt 12)), (EConst (CBool true)), [(EConst CUnit)]))), - [])) - ]|}] -;; - -let%expect_test "parse tuple inn" = - test_parser "let () = ((12, 23), 45, (345, false, true))"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (ETuple ((ETuple ((EConst (CInt 12)), (EConst (CInt 23)), [])), - (EConst (CInt 45)), - [(ETuple ((EConst (CInt 345)), (EConst (CBool false)), - [(EConst (CBool true))])) - ] - ))), - [])) - ]|}] -;; - -let%expect_test "parse tuple pat" = - test_parser "let (a, b) = (6, 9)"; - [%expect - {| - [(SValue (Nonrecursive, - ((PTuple ((PVar "a"), (PVar "b"), [])), - (ETuple ((EConst (CInt 6)), (EConst (CInt 9)), []))), - [])) - ]|}] -;; - -(* ========== list ========== *) - -let%expect_test "parse list empty" = - test_parser "let () = []"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EList [])), []))]|}] -;; - -let%expect_test "parse list 1" = - test_parser "let () = [23]"; - [%expect - {| - [(SValue (Nonrecursive, ((PConst CUnit), (EList [(EConst (CInt 23))])), []))]|}] -;; - -let%expect_test "parse list 2" = - test_parser "let () = [23; 45]"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), (EList [(EConst (CInt 23)); (EConst (CInt 45))])), - [])) - ]|}] -;; - -let%expect_test "parse list list" = - test_parser "let () = [[234; 456]; []]"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (EList [(EList [(EConst (CInt 234)); (EConst (CInt 456))]); (EList [])])), - [])) - ]|}] -;; - -let%expect_test "parse list pat" = - test_parser "let [a] = [6]"; - [%expect - {| - [(SValue (Nonrecursive, ((PList [(PVar "a")]), (EList [(EConst (CInt 6))])), - [])) - ]|}] -;; - -(* ========== option ========== *) - -let%expect_test "parse option var" = - test_parser "let () = Some x"; - [%expect - {| - [(SValue (Nonrecursive, ((PConst CUnit), (EOption (Some (EVar "x")))), []))]|}] -;; - -let%expect_test "parse option p var" = - test_parser "let () = Some (x)"; - [%expect - {| - [(SValue (Nonrecursive, ((PConst CUnit), (EOption (Some (EVar "x")))), []))]|}] -;; - -let%expect_test "parse option none" = - test_parser "let () = None"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EOption None)), []))]|}] -;; - -(* ========== vars ========== *) - -let%expect_test "parse var simple" = - test_parser "let () = asd"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EVar "asd")), []))]|}] -;; - -let%expect_test "parse var start underscore" = - test_parser "let () = _asd"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EVar "_asd")), []))]|}] -;; - -let%expect_test "parse var underscore fail" = - test_parser "let () = _"; - [%expect {| - Parsing error|}] -;; - -let%expect_test "parse var double underscore not fail" = - test_parser "let () = __"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EVar "__")), []))]|}] -;; - -let%expect_test "parse underscore number" = - test_parser "let () = _0kajsndf"; - [%expect {| - [(SValue (Nonrecursive, ((PConst CUnit), (EVar "_0kajsndf")), []))]|}] -;; - -let%expect_test "parse number" = - test_parser "let () = 0kajsndf"; - [%expect {| - Parsing error|}] -;; - -(* ========== fun ========== *) - -let%expect_test "parse fun simple" = - test_parser "let () = fun x -> y"; - [%expect - {| - [(SValue (Nonrecursive, ((PConst CUnit), (EFun ((PVar "x"), (EVar "y")))), - [])) - ]|}] -;; - -(* ========== let ========== *) - -let%expect_test "parse fun simple" = - test_parser "let () = let x = 5 in let y = 2 in x + y"; - [%expect - {| - [(SValue (Nonrecursive, - ((PConst CUnit), - (ELet (Nonrecursive, ((PVar "x"), (EConst (CInt 5))), [], - (ELet (Nonrecursive, ((PVar "y"), (EConst (CInt 2))), [], - (EBinary (Add, (EVar "x"), (EVar "y"))))) - ))), - [])) - ]|}] -;; diff --git a/EChirkov/tests/parser_tests.mli b/EChirkov/tests/parser_tests.mli deleted file mode 100644 index a8c0d9e24..000000000 --- a/EChirkov/tests/parser_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EChirkov/tests/test.t b/EChirkov/tests/test.t deleted file mode 100644 index c06ee88eb..000000000 --- a/EChirkov/tests/test.t +++ /dev/null @@ -1,139 +0,0 @@ -(** Copyright 2024-2025, Dmitri Chirkov*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ../bin/main.exe --interpret manytests/typed/001fac.ml - 24 - - $ ../bin/main.exe --interpret manytests/typed/002fac.ml - 24 - - $ ../bin/main.exe --interpret manytests/typed/003fib.ml - 3 - 3 - - $ ../bin/main.exe --interpret manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - - $ ../bin/main.exe --interpret manytests/typed/005fix.ml - 720 - - $ ../bin/main.exe --interpret manytests/typed/006partial.ml - 1122 - - $ ../bin/main.exe --interpret manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - - $ ../bin/main.exe --interpret manytests/typed/006partial3.ml - 4 - 8 - 9 - - $ ../bin/main.exe --interpret manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - - $ ../bin/main.exe --interpret manytests/typed/009let_poly.ml - - $ ../bin/main.exe --interpret manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - - $ ../bin/main.exe --infer manytests/typed/001fac.ml - val fac : (int -> int) - val main : int - - $ ../bin/main.exe --infer manytests/typed/002fac.ml - val fac_cps : (int -> ((int -> 🍏) -> 🍏)) - val main : int - - $ ../bin/main.exe --infer manytests/typed/003fib.ml - val fib : (int -> int) - val fib_acc : (int -> (int -> (int -> int))) - val main : int - - $ ../bin/main.exe --infer manytests/typed/004manyargs.ml - val main : int - val test10 : (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> int)))))))))) - val test3 : (int -> (int -> (int -> int))) - val wrap : (🍏 -> 🍏) - - $ ../bin/main.exe --infer manytests/typed/005fix.ml - val fac : ((int -> int) -> (int -> int)) - val fix : (((🍏 -> 🍎) -> (🍏 -> 🍎)) -> (🍏 -> 🍎)) - val main : int - - $ ../bin/main.exe --infer manytests/typed/006partial.ml - val foo : (int -> int) - val main : int - - $ ../bin/main.exe --infer manytests/typed/006partial2.ml - val foo : (int -> (int -> (int -> int))) - val main : int - - $ ../bin/main.exe --infer manytests/typed/006partial3.ml - val foo : (int -> (int -> (int -> unit))) - val main : int - - $ ../bin/main.exe --infer manytests/typed/007order.ml - val _start : (unit -> (unit -> (int -> (unit -> (int -> (int -> (unit -> (int -> (int -> int))))))))) - val main : unit - - $ ../bin/main.exe --infer manytests/typed/008ascription.ml - val addi : ((🍏 -> (bool -> int)) -> ((🍏 -> bool) -> (🍏 -> int))) - val main : int - - $ ../bin/main.exe --infer manytests/typed/009let_poly.ml - val temp : (int * bool) - - $ ../bin/main.exe --infer manytests/typed/015tuples.ml - val feven : ((🍏 * ((int -> int))) -> (int -> int)) - val fix : (((🍏 -> 🍎) -> (🍏 -> 🍎)) -> (🍏 -> 🍎)) - val fixpoly : (((((((🍏 -> 🍎)) * ((🍏 -> 🍎))) -> (🍏 -> 🍎))) * (((((🍏 -> 🍎)) * ((🍏 -> 🍎))) -> (🍏 -> 🍎)))) -> (((🍏 -> 🍎)) * ((🍏 -> 🍎)))) - val fodd : ((((int -> int)) * 🍏) -> (int -> int)) - val main : int - val map : ((🍏 -> 🍎) -> ((🍏 * 🍏) -> (🍎 * 🍎))) - val meven : (int -> int) - val modd : (int -> int) - val tie : (((int -> int)) * ((int -> int))) - - - $ ../bin/main.exe --infer manytests/do_not_type/001.ml - Type inference error: Undefined variable 'fac' - - $ ../bin/main.exe --infer manytests/do_not_type/002if.ml - Type inference error: Unification failed on int and bool - - $ ../bin/main.exe --infer manytests/do_not_type/003occurs.ml - Type inference error: Cannot construct type: 🍏 appears within (🍏 -> 🍎) - - $ ../bin/main.exe --infer manytests/do_not_type/004let_poly.ml - Type inference error: Unification failed on bool and int - - $ ../bin/main.exe --infer manytests/do_not_type/015tuples.ml - Type inference error: Invalid left hand side - - $ ../bin/main.exe --infer manytests/do_not_type/016tuples_mismatch.ml - Type inference error: Unification failed on (🍏 * 🍎) and (int * int * int) - - $ ../bin/main.exe --infer manytests/do_not_type/097fun_vs_list.ml - Type inference error: Unification failed on 🍏 list and (🍏 -> 🍏) - - $ ../bin/main.exe --infer manytests/do_not_type/097fun_vs_unit.ml - Type inference error: Unification failed on unit and (🍏 -> 🍏) - - $ ../bin/main.exe --infer manytests/do_not_type/098rec_int.ml - Type inference error: Invalid right hand side diff --git a/EIshbaev/.envrc b/EIshbaev/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/EIshbaev/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/EIshbaev/.gitignore b/EIshbaev/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/EIshbaev/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/EIshbaev/.ocamlformat b/EIshbaev/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/EIshbaev/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/EIshbaev/.zanuda b/EIshbaev/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/EIshbaev/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/EIshbaev/COPYING b/EIshbaev/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/EIshbaev/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/EIshbaev/COPYING.CC0 b/EIshbaev/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/EIshbaev/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/EIshbaev/COPYING.LESSER b/EIshbaev/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/EIshbaev/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/EIshbaev/EIshbaev.opam b/EIshbaev/EIshbaev.opam deleted file mode 100644 index e62b04460..000000000 --- a/EIshbaev/EIshbaev.opam +++ /dev/null @@ -1,35 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for MiniML" -description: - "FIXME. A longer description, for example, which are the most interesing features being supported, etc." -maintainer: ["Ishbaev Azamat "] -authors: ["Ishbaev Azamat "] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Kakadu/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Kakadu/fp2024" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/EIshbaev/Makefile b/EIshbaev/Makefile deleted file mode 100644 index e234db4bf..000000000 --- a/EIshbaev/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/language dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/EIshbaev/bin/dune b/EIshbaev/bin/dune deleted file mode 100644 index 4acbd36ec..000000000 --- a/EIshbaev/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name main) - (public_name EIshbaev) - (libraries EIshbaev_lib) - (instrumentation - (backend bisect_ppx))) diff --git a/EIshbaev/bin/main.ml b/EIshbaev/bin/main.ml deleted file mode 100644 index f8a74740a..000000000 --- a/EIshbaev/bin/main.ml +++ /dev/null @@ -1,29 +0,0 @@ -(** Copyright 2024-2025, Azamat Ishbaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EIshbaev_lib.Ast - -let () = - let fact : structure = - [ ExprLet - ( Rec - , [ ( PatVar "fact" - , ExprFunc - ( "x" - , ExprCond - ( ExprBinop (Lesq, ExprVar "x", ExprConst (ConstInt 1)) - , ExprConst (ConstInt 1) - , ExprBinop - ( Mul - , ExprVar "x" - , ExprApp - ( ExprVar "fact" - , ExprBinop (Sub, ExprVar "x", ExprConst (ConstInt 1)) ) ) ) - ) ) - ] - , ExprVar "n" ) - ] - in - print_endline (show_structure fact) -;; diff --git a/EIshbaev/dune b/EIshbaev/dune deleted file mode 100644 index 98e54536a..000000000 --- a/EIshbaev/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/EIshbaev/dune-project b/EIshbaev/dune-project deleted file mode 100644 index 0432d90a9..000000000 --- a/EIshbaev/dune-project +++ /dev/null @@ -1,34 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Ishbaev Azamat ") - -(maintainers "Ishbaev Azamat ") - -(bug_reports "https://github.com/Kakadu/fp2024") - -(homepage "https://github.com/Kakadu/fp2024") - -(package - (name EIshbaev) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for MiniML") - (description - "FIXME. A longer description, for example, which are the most interesing features being supported, etc.") - (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files add the same dependecies here too - )) diff --git a/EIshbaev/lib/ast.ml b/EIshbaev/lib/ast.ml deleted file mode 100644 index 5a146ede2..000000000 --- a/EIshbaev/lib/ast.ml +++ /dev/null @@ -1,59 +0,0 @@ -(** Copyright 2024-2025, Azamat Ishbaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type name = string [@@deriving show { with_path = false }] - -(** Constants *) -type const = - | ConstInt of int (** integers *) - | ConstBool of bool (** true or false *) - | ConstUnit (** Unit () *) - | ConstNil (** [] *) -[@@deriving show { with_path = false }] - -(** Binary operations *) -type binop = - | Add (** "+" *) - | Sub (** "-" *) - | Div (** "/" *) - | Mul (** "*" *) - | Lesq (** "<=" *) - | Greq (** ">=" *) - | Gre (** ">" *) - | Les (** "<" *) - | Eql (** "=" *) - | Neq (** "!=" *) - | And (** "&&" *) - | Or (** "||" *) -[@@deriving show { with_path = false }] - -(** Recursive flag *) -type recursive = - | Rec (** recursive function *) - | NotRec (** Non-recursive functions *) -[@@deriving show { with_path = false }] - -type pattern = - | PatConst of const (** const -> ... *) - | PatVar of name (** var -> ... *) - | PatWild (** _ -> ... *) - | PatEmpty (** [] -> ... *) - | PatTuple of pattern * pattern * pattern list (** x_1 :: x_2, x_3 :: x_4 *) - | PatConc of pattern * pattern * pattern list (** x_1 :: x_2 -> ... *) - | PatOr of pattern * pattern * pattern list (** x_1 | x_2 -> ... *) -[@@deriving show { with_path = false }] - -type expr = - | ExprConst of const (** consts *) - | ExprVar of name (** variebles with names *) - | ExprBinop of binop * expr * expr (** x_1 binop x_2 *) - | ExprTuple of expr * expr * expr list (** list with x_i separeted via "," *) - | ExprFunc of name * expr (** anonymous functions *) - | ExprCond of expr * expr * expr (** if then else *) - | ExprLet of recursive * (pattern * expr) list * expr (** let rec fun *) - | ExprApp of expr * expr (** application *) - | ExprMatch of expr * (pattern * expr) list (** match x_1 with | x_2 -> x_3 | ... *) -[@@deriving show { with_path = false }] - -type structure = expr list [@@deriving show { with_path = false }] diff --git a/EIshbaev/lib/ast.mli b/EIshbaev/lib/ast.mli deleted file mode 100644 index 5a146ede2..000000000 --- a/EIshbaev/lib/ast.mli +++ /dev/null @@ -1,59 +0,0 @@ -(** Copyright 2024-2025, Azamat Ishbaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type name = string [@@deriving show { with_path = false }] - -(** Constants *) -type const = - | ConstInt of int (** integers *) - | ConstBool of bool (** true or false *) - | ConstUnit (** Unit () *) - | ConstNil (** [] *) -[@@deriving show { with_path = false }] - -(** Binary operations *) -type binop = - | Add (** "+" *) - | Sub (** "-" *) - | Div (** "/" *) - | Mul (** "*" *) - | Lesq (** "<=" *) - | Greq (** ">=" *) - | Gre (** ">" *) - | Les (** "<" *) - | Eql (** "=" *) - | Neq (** "!=" *) - | And (** "&&" *) - | Or (** "||" *) -[@@deriving show { with_path = false }] - -(** Recursive flag *) -type recursive = - | Rec (** recursive function *) - | NotRec (** Non-recursive functions *) -[@@deriving show { with_path = false }] - -type pattern = - | PatConst of const (** const -> ... *) - | PatVar of name (** var -> ... *) - | PatWild (** _ -> ... *) - | PatEmpty (** [] -> ... *) - | PatTuple of pattern * pattern * pattern list (** x_1 :: x_2, x_3 :: x_4 *) - | PatConc of pattern * pattern * pattern list (** x_1 :: x_2 -> ... *) - | PatOr of pattern * pattern * pattern list (** x_1 | x_2 -> ... *) -[@@deriving show { with_path = false }] - -type expr = - | ExprConst of const (** consts *) - | ExprVar of name (** variebles with names *) - | ExprBinop of binop * expr * expr (** x_1 binop x_2 *) - | ExprTuple of expr * expr * expr list (** list with x_i separeted via "," *) - | ExprFunc of name * expr (** anonymous functions *) - | ExprCond of expr * expr * expr (** if then else *) - | ExprLet of recursive * (pattern * expr) list * expr (** let rec fun *) - | ExprApp of expr * expr (** application *) - | ExprMatch of expr * (pattern * expr) list (** match x_1 with | x_2 -> x_3 | ... *) -[@@deriving show { with_path = false }] - -type structure = expr list [@@deriving show { with_path = false }] diff --git a/EIshbaev/lib/dune b/EIshbaev/lib/dune deleted file mode 100644 index 612e5786b..000000000 --- a/EIshbaev/lib/dune +++ /dev/null @@ -1,18 +0,0 @@ -(library - (name EIshbaev_lib) - (public_name EIshbaev.Lib) - (modules Ast) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) - -; (library -; (name tests) -; (modules tests) -; (libraries lambda_lib) -; (preprocess -; (pps ppx_expect ppx_deriving.show)) -; (instrumentation -; (backend bisect_ppx)) -; (inline_tests)) diff --git a/EIshbaev/tests/ast_test.t b/EIshbaev/tests/ast_test.t deleted file mode 100644 index 3a71fdb44..000000000 --- a/EIshbaev/tests/ast_test.t +++ /dev/null @@ -1,17 +0,0 @@ - $ ../bin/main.exe - [(ExprLet (Rec, - [((PatVar "fact"), - (ExprFunc ("x", - (ExprCond ( - (ExprBinop (Lesq, (ExprVar "x"), (ExprConst (ConstInt 1)))), - (ExprConst (ConstInt 1)), - (ExprBinop (Mul, (ExprVar "x"), - (ExprApp ((ExprVar "fact"), - (ExprBinop (Sub, (ExprVar "x"), (ExprConst (ConstInt 1)))) - )) - )) - )) - ))) - ], - (ExprVar "n"))) - ] diff --git a/EIshbaev/tests/dune b/EIshbaev/tests/dune deleted file mode 100644 index 1c7c3c129..000000000 --- a/EIshbaev/tests/dune +++ /dev/null @@ -1,3 +0,0 @@ -(cram - (applies_to ast_test) - (deps ../bin/main.exe)) diff --git a/ELutsyuk/.envrc b/ELutsyuk/.envrc deleted file mode 100644 index 686a37170..000000000 --- a/ELutsyuk/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) diff --git a/ELutsyuk/.gitignore b/ELutsyuk/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/ELutsyuk/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/ELutsyuk/.ocamlformat b/ELutsyuk/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/ELutsyuk/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/ELutsyuk/.zanuda b/ELutsyuk/.zanuda deleted file mode 100644 index be4445a2b..000000000 --- a/ELutsyuk/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore print_ast.ml diff --git a/ELutsyuk/ELutsyuk.opam b/ELutsyuk/ELutsyuk.opam deleted file mode 100644 index 2786b53fc..000000000 --- a/ELutsyuk/ELutsyuk.opam +++ /dev/null @@ -1,36 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for miniML" -description: "An interpreter for a subset of the ML language (WIP)" -maintainer: ["Victoria Lutsyuk "] -authors: ["Victoria Lutsyuk "] -license: "MIT" -homepage: "https://github.com/vicitori/miniML-interpreter" -doc: "https://kakadu.github.io/fp2024/docs/ELutsyuk" -bug-reports: "https://github.com/vicitori/miniML-interpreter" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "base" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/ELutsyuk/LICENSE b/ELutsyuk/LICENSE deleted file mode 100644 index 3a5c8e1ae..000000000 --- a/ELutsyuk/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2024 Anastasia Migunova, Victoria Lutsyuk - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ELutsyuk/Makefile b/ELutsyuk/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/ELutsyuk/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/ELutsyuk/bin/dune b/ELutsyuk/bin/dune deleted file mode 100644 index a94d15ea4..000000000 --- a/ELutsyuk/bin/dune +++ /dev/null @@ -1,10 +0,0 @@ -(executable - (name main) - (public_name main) - (libraries - ELutsyuk.MiniML_Forest - ELutsyuk.MiniML_Parser - ELutsyuk.MiniML_Inferencer - ELutsyuk.MiniML_Interpreter) - (instrumentation - (backend bisect_ppx))) diff --git a/ELutsyuk/bin/main.ml b/ELutsyuk/bin/main.ml deleted file mode 100644 index 2a6773355..000000000 --- a/ELutsyuk/bin/main.ml +++ /dev/null @@ -1,94 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest -open Parser -open Inferencer.InfAuxilary -open Inferencer.Inference -open Interpreter.Interpret -open Stdlib.Format - -let run_infer input = - match parse input with - | Ok program -> - (match inference program with - | Ok (_, env) -> - (* Getting the environment without builtin *) - let remove_builtins env = - let env = TypeEnv.remove env "print_int" in - TypeEnv.remove env "print_endline" - in - Base.Map.iteri (remove_builtins env) ~f:(fun ~key ~data:(Scheme (_, ty)) -> - printf "val %s: %a\n" key TypesTree.pp_typ ty) - | Error err -> printf "Inferencing error: %a.\n" TypesTree.pp_error err) - | Error err -> printf "Parsing error: %s.\n" err -;; - -let run_eval input = - match parse input with - | Ok program -> - (match Interpreter.IntAuxilary.Res.run (interpret program) with - | Ok _ -> () - | Error err -> printf "Interpretation error: %a.\n" ValuesTree.pp_error err) - | Error err -> printf "Parsing error: %s.\n" err -;; - -let get_input filename = - let channel = open_in filename in - let input = really_input_string channel (in_channel_length channel) in - close_in channel; - input -;; - -type config = - { is_infer : bool - ; is_eval : bool - ; file : string option - ; input : string option - } - -let parse_args () = - let rec prs_args args flags = - match args with - | [] -> flags - | "-infer" :: rest -> prs_args rest { flags with is_infer = true } - | "-eval" :: rest -> prs_args rest { flags with is_eval = true } - | "-file" :: filename :: rest -> prs_args rest { flags with file = Some filename } - | arg :: rest -> prs_args rest { flags with input = Some arg } - in - let default_flags = { is_infer = false; is_eval = false; file = None; input = None } in - let args = - match Array.to_list Sys.argv with - | _ :: list -> list - | _ -> [] - in - prs_args args default_flags -;; - -let main () = - let config = parse_args () in - let input = - match config.file with - | Some filename -> get_input filename - | None -> - (match config.input with - | Some s -> s - | None -> "") - in - if config.is_infer - then run_infer input - else if config.is_eval - then run_eval input - else if config.is_infer && config.is_eval - then ( - let _ = run_infer input in - let _ = run_eval input in - ()) - else - printf - "Error: Could not parse arguments: Please restart program and put -infer or -eval \ - flag.\n" -;; - -let () = main () diff --git a/ELutsyuk/dune b/ELutsyuk/dune deleted file mode 100644 index 2b55f5424..000000000 --- a/ELutsyuk/dune +++ /dev/null @@ -1,16 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w +A-4-40-42-44-70))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - -; (executable -; (name REPL) -; (public_name REPL) -; (modules REPL) -; (libraries lambda_lib stdio)) - -; (cram -; (deps ./REPL.exe %{bin:REPL})) diff --git a/ELutsyuk/dune-project b/ELutsyuk/dune-project deleted file mode 100644 index 765beff2e..000000000 --- a/ELutsyuk/dune-project +++ /dev/null @@ -1,32 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license MIT) - -(authors "Victoria Lutsyuk ") - -(maintainers "Victoria Lutsyuk ") - -(bug_reports "https://github.com/vicitori/miniML-interpreter") - -(homepage "https://github.com/vicitori/miniML-interpreter") - -(package - (name ELutsyuk) - (synopsis "An interpreter for miniML") - (description "An interpreter for a subset of the ML language (WIP)") - (documentation "https://kakadu.github.io/fp2024/docs/ELutsyuk") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - base)) diff --git a/ELutsyuk/lib/forest/Ast.ml b/ELutsyuk/lib/forest/Ast.ml deleted file mode 100644 index 2341f6095..000000000 --- a/ELutsyuk/lib/forest/Ast.ml +++ /dev/null @@ -1,98 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open TypesTree - -(** Expression identifier *) -type id = string [@@deriving show { with_path = false }] - -(** Represents constant values. *) -type const = - | Int of int (** Integer constants, e.g. [-1], [ 2], [0]. *) - | Str of string (** String constants, e.g. [{|meow|}], ["miniML"]. *) - | Bool of bool (** Boolean constants, e.g. [true], [false]. *) - | Unit (** [()] *) -[@@deriving show { with_path = false }] - -(** Represents binary operators, such as arithmetic or logical operations. *) -type binop = - | Mul (** Multiplication, e.g. [a * b]. *) - | Div (** Division, e.g. [a / b]. *) - | Add (** Addition, e.g. [a + b]. *) - | Sub (** Subtraction, e.g. [a - b]. *) - | Eq (** Equality comparison, e.g. [a = b]. *) - | Ne (** Inequality comparison, e.g. [a <> b]. *) - | Lt (** Less-than comparison, e.g. [a < b]. *) - | Le (** Less-than-or-equal comparison, e.g. [a <= b]. *) - | Gt (** Greater-than comparison, e.g. [a > b]. *) - | Ge (** Greater-than-or-equal comparison, e.g. [a >= b]. *) - | And (** Logical AND, e.g. [a && b]. *) - | Or (** Logical OR, e.g. [a || b]. *) -[@@deriving show { with_path = false }] - -type unary = - | Minus - | Plus - | Not -[@@deriving show { with_path = false }] - -(** Represents patterns for matching values in expressions. *) -type pat = - | PatAny (** Matches any value without binding it, e.g. [_]. *) - (* | PatUnit *) - | PatConst of const (** Matches a constant value, e.g. [42], [true]. *) - | PatListCons of pat * pat (** Matches a cons pattern for lists, e.g. [x::y]. *) - | PatVar of id (** Matches any value and binds it to a variable, e.g. [x]. *) - | PatTup of pat * pat * pat list (** Matches tuples, e.g. [x, y], [a, b, c]. *) - | PatList of pat list (** *) - | PatType of pat * typ -[@@deriving show { with_path = false }] - -(** Indicates whether a [let] binding is recursive or non-recursive. *) -type rec_state = - | Rec (** Recursive binding, e.g. [let rec fact = ...]. *) - | NonRec (** Non-recursive binding, e.g. [let x = ...]. *) -[@@deriving show { with_path = false }] - -(** Represents expressions in the language. *) -type expr = - | Var of id (** Variable reference, e.g. [x], [my_var]. *) - | Const of const (** Constant value, e.g. [42], ["hello"], [true]. *) - | Unary of unary * expr - | BinOp of binop * expr * expr (** Binary operation, e.g. [x + y], [a >= b]. *) - | Option of expr option (** Options, e.g. [Some("meow"), None]. *) - | Let of rec_state * let_binding * let_binding list * expr - (** [let] expression, e.g. [let x = 5 in e] *) - | App of expr * expr (** Function application, e.g. [e1 e2], [(fun x -> x) 42]. *) - | Fun of pat * pat list * expr (** Function definition, e.g. [fun p -> e]. *) - | Branch of expr * expr * expr - (** Conditional expression, e.g. [if e1 then e2 else e3]. *) - | Tup of expr * expr * expr list (** Tuple expression, e.g. [(e1, e2)], [(x, y, z)]. *) - | List of expr list (** List expression, e.g. [[]], [[e1; e2; e3]]. *) - | Type of expr * typ -[@@deriving show { with_path = false }] - -(** Represents a binding in a [let] expression. *) -and let_binding = - | Binding of pat * expr - (** The pattern being bound, e.g. [x], [(a, b)]. The expression being assigned, e.g. [42], [fun x -> x + 1]. *) -[@@deriving show { with_path = false }] - -(* Represents a single case in a [match] expression. -and match_case = - { match_pat : pat (** The pattern to match, e.g. [0], [_], [(x, y)]. *) - ; match_expr : expr (** The expression to evaluate if the pattern matches. *) - } -[@@deriving show { with_path = false }] *) - -(** Represents a top-level item in a program. *) -type structure_item = - | Eval of expr - (** An expression to be evaluated but not bound, e.g. [1 + 2], [print_endline "Hi"]. *) - | Value of rec_state * let_binding * let_binding list - (** A value or function binding, e.g. [let x = 5], [let rec fact n = ...]. *) -[@@deriving show { with_path = false }] - -(** Represents an entire program as a list of top-level items. *) -type program = structure_item list [@@deriving show { with_path = false }] diff --git a/ELutsyuk/lib/forest/Ast.mli b/ELutsyuk/lib/forest/Ast.mli deleted file mode 100644 index 856a464de..000000000 --- a/ELutsyuk/lib/forest/Ast.mli +++ /dev/null @@ -1,98 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open TypesTree - -(** Expression identifier *) -type id = string [@@deriving show { with_path = false }] - -(** Represents constant values. *) -type const = - | Int of int (** Integer constants, e.g. [-1], [ 2], [0]. *) - | Str of string (** String constants, e.g. [{|meow|}], ["miniML"]. *) - | Bool of bool (** Boolean constants, e.g. [true], [false]. *) - | Unit (** [()] *) -[@@deriving show { with_path = false }] - -(** Represents binary operators, such as arithmetic or logical operations. *) -type binop = - | Mul (** Multiplication, e.g. [a * b]. *) - | Div (** Division, e.g. [a / b]. *) - | Add (** Addition, e.g. [a + b]. *) - | Sub (** Subtraction, e.g. [a - b]. *) - | Eq (** Equality comparison, e.g. [a = b]. *) - | Ne (** Inequality comparison, e.g. [a <> b]. *) - | Lt (** Less-than comparison, e.g. [a < b]. *) - | Le (** Less-than-or-equal comparison, e.g. [a <= b]. *) - | Gt (** Greater-than comparison, e.g. [a > b]. *) - | Ge (** Greater-than-or-equal comparison, e.g. [a >= b]. *) - | And (** Logical AND, e.g. [a && b]. *) - | Or (** Logical OR, e.g. [a || b]. *) -[@@deriving show { with_path = false }] - -(** Represents patterns for matching values in expressions. *) -type pat = - | PatAny (** Matches any value without binding it, e.g. [_]. *) - (* | PatUnit *) - | PatConst of const (** Matches a constant value, e.g. [42], [true]. *) - | PatListCons of pat * pat (** Matches a cons pattern for lists, e.g. [x::y]. *) - | PatVar of id (** Matches any value and binds it to a variable, e.g. [x]. *) - | PatTup of pat * pat * pat list (** Matches tuples, e.g. [x, y], [a, b, c]. *) - | PatList of pat list (** *) - | PatType of pat * typ -[@@deriving show { with_path = false }] - -type unary = - | Minus - | Plus - | Not -[@@deriving show { with_path = false }] - -(** Indicates whether a [let] binding is recursive or non-recursive. *) -type rec_state = - | Rec (** Recursive binding, e.g. [let rec fact = ...]. *) - | NonRec (** Non-recursive binding, e.g. [let x = ...]. *) -[@@deriving show { with_path = false }] - -(** Represents expressions in the language. *) -type expr = - | Var of id (** Variable reference, e.g. [x], [my_var]. *) - | Const of const (** Constant value, e.g. [42], ["hello"], [true]. *) - | Unary of unary * expr - | BinOp of binop * expr * expr (** Binary operation, e.g. [x + y], [a >= b]. *) - | Option of expr option (** Options, e.g. [Some("meow"), None]. *) - | Let of rec_state * let_binding * let_binding list * expr - (** [let] expression, e.g. [let x = 5 in e] *) - | App of expr * expr (** Function application, e.g. [e1 e2], [(fun x -> x) 42]. *) - | Fun of pat * pat list * expr (** Function definition, e.g. [fun p -> e]. *) - | Branch of expr * expr * expr - (** Conditional expression, e.g. [if e1 then e2 else e3]. *) - | Tup of expr * expr * expr list (** Tuple expression, e.g. [(e1, e2)], [(x, y, z)]. *) - | List of expr list (** List expression, e.g. [[]], [[e1; e2; e3]]. *) - | Type of expr * typ -[@@deriving show { with_path = false }] - -(** Represents a binding in a [let] expression. *) -and let_binding = - | Binding of pat * expr - (** The pattern being bound, e.g. [x], [(a, b)]. The expression being assigned, e.g. [42], [fun x -> x + 1]. *) -[@@deriving show { with_path = false }] - -(* Represents a single case in a [match] expression. -and match_case = - { match_pat : pat (** The pattern to match, e.g. [0], [_], [(x, y)]. *) - ; match_expr : expr (** The expression to evaluate if the pattern matches. *) - } -[@@deriving show { with_path = false }] *) - -(** Represents a top-level item in a program. *) -type structure_item = - | Eval of expr - (** An expression to be evaluated but not bound, e.g. [1 + 2], [print_endline "Hi"]. *) - | Value of rec_state * let_binding * let_binding list - (** A value or function binding, e.g. [let x = 5], [let rec fact n = ...]. *) -[@@deriving show { with_path = false }] - -(** Represents an entire program as a list of top-level items. *) -type program = structure_item list [@@deriving show { with_path = false }] diff --git a/ELutsyuk/lib/forest/TypesTree.ml b/ELutsyuk/lib/forest/TypesTree.ml deleted file mode 100644 index c78af169e..000000000 --- a/ELutsyuk/lib/forest/TypesTree.ml +++ /dev/null @@ -1,93 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Stdlib.Format - -type var = int [@@deriving show { with_path = false }] - -type constant = - | TInt - | TStr - | TBool - | TUnit -[@@deriving show { with_path = false }] - -type typ = - | TypConst of constant - | TypVar of var - | TypArrow of typ * typ - | TypTuple of typ list - | TypList of typ - | TypOption of typ - -type error = - | OccursCheckFailed of int * typ - | UnificationFailed of typ * typ - | UnboundVariable of string - | InvalidRecursivePattern - | UnexpectedFuncType of typ - | IllegalLHS - | IllegalRHS - -(* Type constructors *) -let int_typ = TypConst TInt -let bool_typ = TypConst TBool -let string_typ = TypConst TStr -let unit_typ = TypConst TUnit -let constant_typ ty = TypConst ty -let var_typ name = TypVar name -let arrow_typ ty1 ty2 = TypArrow (ty1, ty2) -let tup_typ ty = TypTuple ty -let list_typ ty = TypList ty -let option_typ ty = TypOption ty - -let rec pp_typ ppf = function - | TypConst TInt -> fprintf ppf "int" - | TypConst TBool -> fprintf ppf "bool" - | TypConst TStr -> fprintf ppf "string" - | TypConst TUnit -> fprintf ppf "unit" - | TypVar ty -> fprintf ppf "'%d" ty - | TypArrow (ty1, ty2) -> - (match ty1 with - | TypArrow _ -> fprintf ppf "(%a) -> %a" pp_typ ty1 pp_typ ty2 - | _ -> fprintf ppf "%a -> %a" pp_typ ty1 pp_typ ty2) - | TypList ty -> fprintf ppf "%a list" pp_typ ty - | TypTuple ty -> - fprintf ppf "(%a)" (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt " * ") pp_typ) ty - | TypOption ty -> fprintf ppf "%a option" pp_typ ty -;; - -let pp_error ppf = function - | OccursCheckFailed (id, ty) -> - fprintf - ppf - "occurs check failed: variable '%d' cannot appear in its own type %a" - id - pp_typ - ty - | UnificationFailed (t1, t2) -> - fprintf - ppf - "type unification failed: cannot unify types %a and %a" - pp_typ - t1 - pp_typ - t2 - | UnboundVariable name -> - fprintf ppf "unbound variable: '%s' is not defined in the current scope" name - | InvalidRecursivePattern -> - fprintf ppf "invalid recursive pattern: recursive patterns can only be variables" - | UnexpectedFuncType ty -> - fprintf ppf "unexpected function type: expected a function type but got %a" pp_typ ty - | IllegalLHS -> - fprintf - ppf - "illegal left-hand side: only variables can appear on the left-hand side of a \ - 'let' binding" - | IllegalRHS -> - fprintf - ppf - "illegal right-hand side: the right-hand side of a 'let' binding must be an \ - expression, not a pattern" -;; diff --git a/ELutsyuk/lib/forest/TypesTree.mli b/ELutsyuk/lib/forest/TypesTree.mli deleted file mode 100644 index f046b8cda..000000000 --- a/ELutsyuk/lib/forest/TypesTree.mli +++ /dev/null @@ -1,42 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -type var = int [@@deriving show { with_path = false }] - -type constant = - | TInt - | TStr - | TBool - | TUnit -[@@deriving show { with_path = false }] - -type typ = - | TypConst of constant - | TypVar of var - | TypArrow of typ * typ - | TypTuple of typ list - | TypList of typ - | TypOption of typ - -type error = - | OccursCheckFailed of int * typ - | UnificationFailed of typ * typ - | UnboundVariable of string - | InvalidRecursivePattern - | UnexpectedFuncType of typ - | IllegalLHS - | IllegalRHS - -val int_typ : typ -val bool_typ : typ -val string_typ : typ -val unit_typ : typ -val constant_typ : constant -> typ -val var_typ : var -> typ -val arrow_typ : typ -> typ -> typ -val tup_typ : typ list -> typ -val list_typ : typ -> typ -val option_typ : typ -> typ -val pp_typ : Format.formatter -> typ -> unit -val pp_error : Format.formatter -> error -> unit diff --git a/ELutsyuk/lib/forest/ValuesTree.ml b/ELutsyuk/lib/forest/ValuesTree.ml deleted file mode 100644 index 54e703c36..000000000 --- a/ELutsyuk/lib/forest/ValuesTree.ml +++ /dev/null @@ -1,66 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Base -open Stdlib.Format -open Ast - -type value = - | ValInt of int - | ValStr of string - | ValBool of bool - | ValUnit - | ValList of value list - | ValTup of value * value * value list - | ValFun of rec_state * pat * pat list * expr * env - | ValBuiltIn of string - | ValOption of value option - -and env = (id, value, String.comparator_witness) Map.t - -type error = - | NoVariable of string - | TypeError - | PatternMatchingFail - -let rec pp_value ppf = function - | ValInt v -> fprintf ppf "%i" v - | ValBool v -> fprintf ppf "'%b'" v - | ValStr v -> fprintf ppf "%S" v - | ValUnit -> fprintf ppf "()" - | ValList v -> - fprintf ppf "[%a]" (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf "; ") pp_value) v - | ValTup (v1, v2, vs) -> - fprintf - ppf - "(%a, %a%a)" - pp_value - v1 - pp_value - v2 - (fun ppf -> function - | [] -> () - | rest -> - fprintf - ppf - ", %a" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - rest) - vs - | ValFun _ | ValBuiltIn _ -> fprintf ppf "" - | ValOption v -> - (match v with - | Some v -> fprintf ppf "Some %a" pp_value v - | None -> fprintf ppf "None") -;; - -let pp_error ppf = function - | NoVariable str -> fprintf ppf "Variable '%S' is not defined in the current scope" str - | TypeError -> - fprintf ppf "type error: the types do not match or an invalid type was encountered" - | PatternMatchingFail -> - fprintf - ppf - "pattern matching failed: no matching pattern was found for the given input" -;; diff --git a/ELutsyuk/lib/forest/ValuesTree.mli b/ELutsyuk/lib/forest/ValuesTree.mli deleted file mode 100644 index 73a528c23..000000000 --- a/ELutsyuk/lib/forest/ValuesTree.mli +++ /dev/null @@ -1,28 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Base -open Stdlib.Format -open Ast - -type value = - | ValInt of int - | ValStr of string - | ValBool of bool - | ValUnit - | ValList of value list - | ValTup of value * value * value list - | ValFun of rec_state * pat * pat list * expr * env - | ValBuiltIn of string - | ValOption of value option - -and env = (id, value, String.comparator_witness) Map.t - -type error = - | NoVariable of string - | TypeError - | PatternMatchingFail - -val pp_value : formatter -> value -> unit -val pp_error : formatter -> error -> unit diff --git a/ELutsyuk/lib/forest/dune b/ELutsyuk/lib/forest/dune deleted file mode 100644 index db3f8929b..000000000 --- a/ELutsyuk/lib/forest/dune +++ /dev/null @@ -1,10 +0,0 @@ -(include_subdirs qualified) - -(library - (name forest) - (public_name ELutsyuk.MiniML_Forest) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/ELutsyuk/lib/inferencer/Inference.ml b/ELutsyuk/lib/inferencer/Inference.ml deleted file mode 100644 index 448c1899d..000000000 --- a/ELutsyuk/lib/inferencer/Inference.ml +++ /dev/null @@ -1,375 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.Ast -open Forest.TypesTree -open InfAuxilary -open InfAuxilary.FreshResult - -let fresh_var = - let* fresh = fresh in - return @@ var_typ fresh -;; - -(* Makes type scheme copy. *) -let instantiate (Scheme (vars, ty)) = - VarSet.fold - (fun old_var ty -> - let* ty = ty in - let* fresh_var = fresh_var in - let* sub = Subst.singleton old_var fresh_var in - return @@ Subst.apply sub ty) - vars - (return ty) -;; - -(* Generalizes a type by quantifying over its free variables that are not bound in the environment. *) -let generalize env typ = - let vars = VarSet.diff (Type.type_vars typ) (TypeEnv.free env) in - Scheme (vars, typ) -;; - -let inf_const = function - | Int _ -> int_typ - | Bool _ -> bool_typ - | Str _ -> string_typ - | Unit -> unit_typ -;; - -let rec inf_pat env = function - | PatAny -> - let* ty_var = fresh_var in - return (Subst.empty, env, ty_var) - | PatConst pat -> return (Subst.empty, env, inf_const pat) - | PatListCons (pat1, pat2) -> - let* sub1, env1, ty1 = inf_pat env pat1 in - let* _, env2, ty2 = inf_pat (TypeEnv.apply sub1 env1) pat2 in - let* final_sub = Subst.unify (list_typ ty1) ty2 in - let env = TypeEnv.apply final_sub env2 in - return (final_sub, env, Subst.apply final_sub ty2) - | PatVar name -> - let* ty_var = fresh_var in - let sch = Scheme (VarSet.empty, ty_var) in - let env = TypeEnv.extend env name sch in - return (Subst.empty, env, ty_var) - | PatTup (pat1, pat2, pats) -> - let pats = pat1 :: pat2 :: pats in - let* sub, env, ty = - List.fold_left - (fun acc pat -> - let* sub1, env, tys = acc in - let* sub2, env_upd, ty1 = inf_pat env pat in - let* final_sub = Subst.compose sub1 sub2 in - return (final_sub, env_upd, ty1 :: tys)) - (return (Subst.empty, env, [])) - pats - in - return (sub, env, tup_typ ty) - | PatList [] -> - let* ty_var = fresh_var in - return (Subst.empty, env, list_typ ty_var) - | PatList pat -> - let* fresh_typ = fresh_var in - let* sub, env = - List.fold_left - (fun acc pat -> - let* prev_sub, prev_env = acc in - let* new_sub, curr_env, el_typ = inf_pat prev_env pat in - let* unified_sub = Subst.compose prev_sub new_sub in - let* final_sub = Subst.unify (Subst.apply prev_sub fresh_typ) el_typ in - let* sub = Subst.compose unified_sub final_sub in - return (sub, TypeEnv.apply final_sub curr_env)) - (return (Subst.empty, env)) - pat - in - return (sub, env, list_typ @@ Subst.apply sub fresh_typ) - | PatType (pat, ty) -> - let* sub, env, ty1 = inf_pat env pat in - let ty = Subst.apply sub ty in - let* sub = Subst.unify ty1 ty in - return (sub, TypeEnv.apply sub env, Subst.apply sub ty) -;; - -(* Returns operands type and result type *) -let binop_signature = function - | Eq | Ne | Lt | Le | Gt | Ge -> - let* ty_var = fresh_var in - return (ty_var, bool_typ) - | Mul | Div | Add | Sub -> return (int_typ, int_typ) - | And | Or -> return (bool_typ, bool_typ) -;; - -(* Checks that the left-hand side of a 'let rec' is a variable. *) -let check_rec_lhs pat = - match pat with - | PatVar _ -> return pat - | _ -> fail @@ IllegalLHS -;; - -(* Checks that the right-hand side of a 'let rec' is a function. *) -let check_rec_rhs expr = - match expr with - | Fun _ -> return expr - | _ -> fail @@ IllegalRHS -;; - -let rec inf_expr env = function - | Var name -> - (match TypeEnv.find env name with - | Some sch -> - let* ty = instantiate sch in - return (Subst.empty, ty) - | None -> fail @@ UnboundVariable name) - | Const exp -> return (Subst.empty, inf_const exp) - | Unary (op, exp) -> - let* sub1, exp_ty = inf_expr env exp in - let* op_ty = - match op with - | Minus | Plus -> return int_typ - | Not -> return bool_typ - in - let* sub2 = Subst.unify exp_ty op_ty in - let* sub = Subst.compose_many_sub [ sub1; sub2 ] in - return @@ (sub, Subst.apply sub op_ty) - | BinOp (op, exp1, exp2) -> - let* args_ty, res_ty = binop_signature op in - let* sub1, ty1 = inf_expr env exp1 in - let* sub2, ty2 = inf_expr (TypeEnv.apply sub1 env) exp2 in - let* sub3 = Subst.unify (Subst.apply sub2 ty1) args_ty in - let* sub4 = Subst.unify (Subst.apply sub3 ty2) args_ty in - let* final_sub = Subst.compose_many_sub [ sub1; sub2; sub3; sub4 ] in - return (final_sub, Subst.apply final_sub res_ty) - | Option (Some exp) -> - let* sub, ty = inf_expr env exp in - return (sub, option_typ ty) - | Option None -> - let* ty_var = fresh_var in - return (Subst.empty, option_typ ty_var) - | List exp -> - (match exp with - | [] -> - let* ty_var = fresh_var in - return (Subst.empty, list_typ ty_var) - | _ :: _ -> - let* s, tys = - List.fold_left - (fun acc e -> - let* acc_sub, acc_ty = acc in - let* inf_sub, inf_ty = inf_expr (TypeEnv.apply acc_sub env) e in - let* composed_sub = Subst.compose inf_sub acc_sub in - return (composed_sub, inf_ty :: acc_ty)) - (return (Subst.empty, [])) - exp - in - return (s, list_typ (List.hd tys))) - | Let (NonRec, Binding (PatVar x, exp1), _, exp2) -> - let* sub1, ty1 = inf_expr env exp1 in - let ty_copy = generalize (TypeEnv.apply sub1 env) ty1 in - let env3 = TypeEnv.extend env x ty_copy in - let* sub2, ty2 = inf_expr (TypeEnv.apply sub1 env3) exp2 in - let* final_sub = Subst.compose sub1 sub2 in - return (final_sub, ty2) - | Let (NonRec, Binding (pat, exp1), bindings, exp2) -> - let* s1, t1 = inf_expr env exp1 in - let* s2, env1, ty_pat = inf_pat env pat in - let* sub1 = Subst.compose s1 s2 in - let* unified_sub = Subst.unify (Subst.apply sub1 ty_pat) t1 in - let initial_env = TypeEnv.apply unified_sub env1 in - let* extended_env = - List.fold_left - (fun acc_env (Binding (pat, expr)) -> - let* acc_env = acc_env in - let* sub_bind, ty_bind = inf_expr acc_env expr in - let* sub_pat, env_pat, ty_pat = inf_pat acc_env pat in - let* combined_subst = Subst.compose sub_bind sub_pat in - let* final_subst = Subst.unify (Subst.apply combined_subst ty_pat) ty_bind in - let updated_env = TypeEnv.merge_envs final_subst acc_env env_pat in - return updated_env) - (return initial_env) - bindings - in - let* sub3, ty2 = inf_expr extended_env exp2 in - let* full_subst = Subst.compose_many_sub [ sub3; unified_sub; sub1 ] in - return (full_subst, ty2) - | Let (Rec, Binding (PatVar x, exp1), [], exp2) -> - let* exp1 = check_rec_rhs exp1 in - let* var_ty = fresh_var in - let env2 = TypeEnv.extend env x (Scheme (VarSet.empty, var_ty)) in - let* s1, t1 = inf_expr env2 exp1 in - let* s2 = Subst.unify (Subst.apply s1 var_ty) t1 in - let* sub_final = Subst.compose s1 s2 in - let env3 = TypeEnv.apply sub_final env in - let env4 = TypeEnv.apply s1 env3 in - let ty_gen = generalize env4 (Subst.apply sub_final var_ty) in - let* s3, t2 = inf_expr (TypeEnv.extend env4 x ty_gen) exp2 in - let* s_final = Subst.compose sub_final s3 in - return (s_final, t2) - | Let (Rec, binding, bindings, exp2) -> - let* env_ext, sub_acc = - List.fold_left - (fun acc_env (Binding (pat, expr)) -> - let* expr = check_rec_rhs expr in - let* pattern = check_rec_lhs pat in - let* env_acc, _ = acc_env in - let* s_expr, ty_expr = inf_expr env_acc expr in - let* s_pat, env_pat, ty_pat = inf_pat env_acc pattern in - let* subst = Subst.compose s_expr s_pat in - let* unified_sub = Subst.unify ty_expr ty_pat in - let* combined_sub = Subst.compose subst unified_sub in - let extended_env = TypeEnv.apply combined_sub env_pat in - return (extended_env, combined_sub)) - (return (env, Subst.empty)) - (binding :: bindings) - in - let* sub2, t2 = inf_expr env_ext exp2 in - let* final_subst = Subst.compose sub_acc sub2 in - return (final_subst, t2) - | App (fun_exp, arg_exp) -> - let* sub1, fun_ty = inf_expr env fun_exp in - let* sub2, arg_ty = inf_expr (TypeEnv.apply sub1 env) arg_exp in - let* res_typ = fresh_var in - let ty1 = Subst.apply sub2 fun_ty in - let ty2 = arrow_typ arg_ty res_typ in - let* sub3 = Subst.unify ty1 ty2 in - let* sub = Subst.compose_many_sub [ sub1; sub2; sub3 ] in - let ty = Subst.apply sub res_typ in - return (sub, ty) - | Fun (pat, pats, exp) -> - let* env, tys = - List.fold_left - (fun acc pat -> - let* env, pat_types = acc in - let* _, env, typ = inf_pat env pat in - return (env, typ :: pat_types)) - (return (env, [])) - (pat :: pats) - in - let* sub, ty = inf_expr env exp in - let arrow_type = - List.fold_right - (fun pat_type acc -> TypArrow (Subst.apply sub pat_type, acc)) - (List.rev tys) - ty - in - return (sub, arrow_type) - | Branch (cond, br1, br2) -> - let* sub1, ty1 = inf_expr env cond in - let* sub2, ty2 = inf_expr (TypeEnv.apply sub1 env) br1 in - let* sub3, ty3 = inf_expr (TypeEnv.apply sub2 env) br2 in - let* sub4 = Subst.unify ty1 bool_typ in - let* sub5 = Subst.unify ty2 ty3 in - let* final_sub = Subst.compose_many_sub [ sub1; sub2; sub3; sub4; sub5 ] in - let ty = Subst.apply final_sub ty3 in - return (final_sub, ty) - | Tup (el1, el2, els) -> - let* sub, ty = - List.fold_left - (fun acc expr -> - let* sub, ty = acc in - let* sub1, ty1 = inf_expr (TypeEnv.apply sub env) expr in - let* sub2 = Subst.compose sub sub1 in - return (sub2, ty1 :: ty)) - (return (Subst.empty, [])) - (el1 :: el2 :: els) - in - return (sub, tup_typ (List.rev_map (Subst.apply sub) ty)) - | Type (el, typ) -> - let* sub1, typ1 = inf_expr env el in - let* sub2 = Subst.unify typ1 (Subst.apply sub1 typ) in - let* final_sub = Subst.compose sub1 sub2 in - return (final_sub, Subst.apply sub2 typ1) -;; - -let inf_struct_item env = function - | Eval expr -> - let* subst, _ = inf_expr env expr in - let updated_env = TypeEnv.apply subst env in - return (subst, updated_env) - | Value (Rec, Binding (PatVar x, expr), []) -> - let* expr = check_rec_rhs expr in - let* tv = fresh_var in - let env = TypeEnv.extend env x (Scheme (VarSet.empty, tv)) in - let* subst, inferred_ty = inf_expr env expr in - let* subst2 = Subst.unify (Subst.apply subst tv) inferred_ty in - let* composed_subst = Subst.compose subst subst2 in - let env2 = TypeEnv.apply composed_subst env in - let generalized_ty = generalize env2 (Subst.apply composed_subst inferred_ty) in - let env = TypeEnv.extend env2 x generalized_ty in - return (composed_subst, env) - | Value (Rec, binding, bindings) -> - let all_bindings = binding :: bindings in - let* env_with_placeholders = - List.fold_left - (fun acc_env (Binding (pattern, _)) -> - let* ty_pattern = check_rec_lhs pattern in - let* env_acc = acc_env in - let* s_pat, env_pat, _ = inf_pat env_acc ty_pattern in - let extended_env = TypeEnv.apply s_pat env_pat in - return extended_env) - (return env) - all_bindings - in - let* env_ext, s_acc = - List.fold_left - (fun acc_env (Binding (ty_pattern, expr)) -> - let* expr = check_rec_rhs expr in - let* env_acc, _ = acc_env in - let* s_expr, t_expr = inf_expr env_acc expr in - let* s_pat, env_pat, t_pat = inf_pat env_acc ty_pattern in - let* subst = Subst.compose s_expr s_pat in - let* unified_subst = Subst.unify t_expr t_pat in - let* combined_subst = Subst.compose subst unified_subst in - let extended_env = TypeEnv.apply combined_subst env_pat in - return (extended_env, combined_subst)) - (return (env_with_placeholders, Subst.empty)) - all_bindings - in - return (s_acc, env_ext) - | Value (NonRec, Binding (PatVar x, expr), _) -> - let* subst, inferred_ty = inf_expr env expr in - let env2 = TypeEnv.apply subst env in - let generalized_ty = generalize env2 inferred_ty in - let env = TypeEnv.extend (TypeEnv.apply subst env) x generalized_ty in - return (subst, env) - | Value (NonRec, Binding (pattern, expr), _) -> - let* subst_expr, inferred_ty = inf_expr env expr in - let* subst_pat, env_pat, t_pat = inf_pat env pattern in - let* combined_subst = - let* composed = Subst.compose subst_expr subst_pat in - return composed - in - let* unified_subst = Subst.unify (Subst.apply combined_subst t_pat) inferred_ty in - let updated_env = TypeEnv.apply unified_subst env_pat in - let* final_subst = Subst.compose unified_subst combined_subst in - return (final_subst, updated_env) -;; - -let inf_program env structure = - let rec process_structure env subst = function - | [] -> return (subst, env) - | item :: rest -> - let* subst', env' = inf_struct_item env item in - let* composed_subst = Subst.compose subst subst' in - process_structure env' composed_subst rest - in - process_structure env Subst.empty structure -;; - -let start_env = - let print_env = - TypeEnv.extend - TypeEnv.empty - "print_int" - (Scheme (VarSet.empty, arrow_typ int_typ unit_typ)) - in - let env = - TypeEnv.extend - print_env - "print_endline" - (Scheme (VarSet.empty, arrow_typ string_typ unit_typ)) - in - env -;; - -let inference tree = run (inf_program start_env tree) diff --git a/ELutsyuk/lib/inferencer/Inference.mli b/ELutsyuk/lib/inferencer/Inference.mli deleted file mode 100644 index 4b06fd259..000000000 --- a/ELutsyuk/lib/inferencer/Inference.mli +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.Ast -open Forest.TypesTree -open InfAuxilary - -val inference : structure_item list -> (Subst.t * TypeEnv.t, error) result diff --git a/ELutsyuk/lib/inferencer/dune b/ELutsyuk/lib/inferencer/dune deleted file mode 100644 index c97154547..000000000 --- a/ELutsyuk/lib/inferencer/dune +++ /dev/null @@ -1,10 +0,0 @@ -(include_subdirs qualified) - -(library - (name inferencer) - (public_name ELutsyuk.MiniML_Inferencer) - (libraries base angstrom forest) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/ELutsyuk/lib/inferencer/infAuxilary.ml b/ELutsyuk/lib/inferencer/infAuxilary.ml deleted file mode 100644 index afab54207..000000000 --- a/ELutsyuk/lib/inferencer/infAuxilary.ml +++ /dev/null @@ -1,215 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Base -open Forest.Ast -open Forest.TypesTree - -module FreshResult : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val fresh : int t - val run : 'a t -> ('a, error) Result.t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t -end = struct - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) monad bind_func state = - match monad state with - | state, Result.Error err -> state, Error err - | state, Result.Ok value -> bind_func value state - ;; - - let return res state = state, Result.return res - let fail res state = state, Result.fail res - - (* let bind value f = value >>= f *) - let fresh state = return state (state + 1) - let run monad = snd (monad 0) - let ( let* ) = ( >>= ) -end - -module VarSet = struct - include Stdlib.Set.Make (Int) -end - -module Type : sig - val has_type_var : int -> typ -> bool - val type_vars : typ -> VarSet.t -end = struct - (* Checks whether the given type contains a specific type variable. *) - let rec has_type_var var = function - | TypConst _ -> false - | TypVar ty -> ty = var - | TypArrow (ty1, ty2) -> has_type_var var ty1 || has_type_var var ty2 - | TypTuple ty -> List.exists ty ~f:(has_type_var var) - | TypList ty -> has_type_var var ty - | TypOption ty -> has_type_var var ty - ;; - - (* Collects all free type variables occurring in the given type. *) - let type_vars typ = - let rec collect_vars acc = function - | TypConst _ -> acc - | TypVar var_name -> VarSet.add var_name acc - | TypArrow (ty1, ty2) -> collect_vars (collect_vars acc ty1) ty2 - | TypTuple ty -> - let free ty = collect_vars VarSet.empty ty in - List.fold ty ~init:acc ~f:(fun acc ty -> VarSet.union acc (free ty)) - | TypList ty -> collect_vars acc ty - | TypOption ty -> collect_vars acc ty - in - collect_vars VarSet.empty typ - ;; -end - -module Subst : sig - type t - - val empty : t - val singleton : var -> typ -> t FreshResult.t - val find : t -> var -> typ option - val remove : t -> var -> t - val apply : t -> typ -> typ - val unify : typ -> typ -> t FreshResult.t - val compose_many_sub : t list -> t FreshResult.t - val compose : t -> t -> t FreshResult.t -end = struct - open FreshResult - - type t = (var, typ, Int.comparator_witness) Map.t - - let empty : t = Map.empty (module Int) - - let singleton var typ = - if Type.has_type_var var typ - then fail (OccursCheckFailed (var, typ)) - else return (Map.singleton (module Int) var typ) - ;; - - let find sub var = Map.find sub var - let remove sub var = Map.remove sub var - - (* Applies a substitutions to a type, recursively replacing all matching type variables. *) - let apply sub_map = - let rec upd_typ = function - | TypConst ty -> constant_typ ty - | TypVar var_name -> - (match find sub_map var_name with - | Some ty -> ty - | None -> var_typ var_name) - | TypArrow (ty1, ty2) -> arrow_typ (upd_typ ty1) (upd_typ ty2) - | TypTuple ty -> tup_typ (List.map ty ~f:upd_typ) - | TypList ty -> list_typ (upd_typ ty) - | TypOption ty -> option_typ (upd_typ ty) - in - upd_typ - ;; - - (* Tries to unify two types, returning a substitution that makes them equal, or fails. *) - let rec unify typ1 typ2 = - match typ1, typ2 with - | TypConst ty1, TypConst ty2 when Poly.(ty1 = ty2) -> return empty - | TypVar a, TypVar b when a = b -> return empty - | TypVar var, typ | typ, TypVar var -> singleton var typ - | TypArrow (a1, a2), TypArrow (b1, b2) -> - let* sub1 = unify a1 b1 in - let* sub2 = unify a2 b2 in - compose sub1 sub2 - | TypTuple ty1, TypTuple ty2 -> - let rec unify_tup sub = function - | [], [] -> return sub - | t1 :: ts1, t2 :: ts2 -> - if List.length ts1 <> List.length ts2 - then fail @@ UnificationFailed (typ1, typ2) - else - let* sub1 = unify (apply sub t1) (apply sub t2) in - let* final_sub = compose sub sub1 in - unify_tup final_sub (ts1, ts2) - | _, _ -> fail @@ UnificationFailed (typ1, typ2) - in - unify_tup empty (ty1, ty2) - | TypList a, TypList b -> unify a b - | TypOption a, TypOption b -> unify a b - | _ -> fail @@ UnificationFailed (typ1, typ2) - - (* Extends an existing substitution with a new variable binding, applying substitution recursively to maintain consistency. *) - and extend sub_map new_var new_typ = - match find sub_map new_var with - | None -> - let new_typ = apply sub_map new_typ in - let* new_sub = singleton new_var new_typ in - Map.fold sub_map ~init:(return new_sub) ~f:(fun ~key:new_var ~data:new_typ acc -> - let* acc = acc in - let new_typ = apply new_sub new_typ in - return (Map.set acc ~key:new_var ~data:new_typ)) - | Some ty -> - let* new_sub = unify new_typ ty in - compose sub_map new_sub - - (* Composes two substitutions, applying the second to the first and merging them. *) - and compose sub_map1 sub_map2 = - Map.fold sub_map1 ~init:(return sub_map2) ~f:(fun ~key:var ~data:typ acc -> - let* acc = acc in - extend acc var typ) - ;; - - (* Composition of several substitutions. *) - let compose_many_sub sub_list = - List.fold_left sub_list ~init:(return empty) ~f:(fun acc sub -> - let* acc = acc in - compose sub acc) - ;; -end - -type scheme = Scheme of VarSet.t * typ - -module Scheme = struct - (* Returns the set of free type variables in a type scheme, excluding the bound ones. *) - let free = function - | Scheme (bind_vars, ty) -> VarSet.diff (Type.type_vars ty) bind_vars - ;; - - (* Applies a substitution to a type scheme, skipping its bound variables. *) - let apply sub (Scheme (bind_vars, ty)) = - let subst = VarSet.fold (fun var sub -> Subst.remove sub var) bind_vars sub in - Scheme (bind_vars, Subst.apply subst ty) - ;; -end - -module TypeEnv : sig - type t = (id, scheme, String.comparator_witness) Map.t - - val empty : t - val free : t -> VarSet.t - val apply : Subst.t -> t -> t - val extend : t -> id -> scheme -> t - val find : t -> id -> scheme option - val remove : t -> id -> t - val merge_envs : Subst.t -> t -> t -> t -end = struct - type t = (id, scheme, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - - (* Returns the set of free type variables in a type scheme, excluding the bound variables that are part of the environment. *) - let free env = - Map.fold env ~init:VarSet.empty ~f:(fun ~key:_ ~data:sch acc -> - VarSet.union acc (Scheme.free sch)) - ;; - - let apply sub env = Map.map env ~f:(Scheme.apply sub) - let extend env id scheme = Map.update env id ~f:(fun _ -> scheme) - let find env id = Map.find env id - let remove = Map.remove - - let merge_envs subst acc_env env_pat = - let acc_env = apply subst acc_env in - let env_pat = apply subst env_pat in - Map.fold env_pat ~init:acc_env ~f:(fun ~key ~data acc_env -> extend acc_env key data) - ;; -end diff --git a/ELutsyuk/lib/inferencer/infAuxilary.mli b/ELutsyuk/lib/inferencer/infAuxilary.mli deleted file mode 100644 index a54882ae2..000000000 --- a/ELutsyuk/lib/inferencer/infAuxilary.mli +++ /dev/null @@ -1,58 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.Ast -open Forest.TypesTree - -module FreshResult : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val fresh : int t - val run : 'a t -> ('a, error) Result.t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t -end - -module Subst : sig - type t - - val empty : t - val singleton : var -> typ -> t FreshResult.t - val find : t -> var -> typ option - val remove : t -> var -> t - val apply : t -> typ -> typ - val unify : typ -> typ -> t FreshResult.t - val compose_many_sub : t list -> t FreshResult.t - val compose : t -> t -> t FreshResult.t -end - -module VarSet : sig - type elt = int - type t = Set.Make(Base.Int).t - - val empty : t - val diff : t -> t -> t - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a -end - -module Type : sig - val has_type_var : int -> typ -> bool - val type_vars : typ -> VarSet.t -end - -type scheme = Scheme of VarSet.t * typ - -module TypeEnv : sig - type t = (id, scheme, Base.String.comparator_witness) Base.Map.t - - val empty : t - val free : t -> VarSet.t - val apply : Subst.t -> t -> t - val extend : t -> id -> scheme -> t - val find : t -> id -> scheme option - val remove : t -> id -> t - val merge_envs : Subst.t -> t -> t -> t -end diff --git a/ELutsyuk/lib/interpreter/IntAuxilary.ml b/ELutsyuk/lib/interpreter/IntAuxilary.ml deleted file mode 100644 index bd64b72a3..000000000 --- a/ELutsyuk/lib/interpreter/IntAuxilary.ml +++ /dev/null @@ -1,54 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Base -open Forest.ValuesTree - -module Res : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val run : 'a t -> ('a, error) Result.t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t -end = struct - type 'a t = ('a, error) Result.t - - let return = Result.return - let fail = Result.fail - let run m = m - - let ( >>= ) monad func = - match monad with - | Ok res -> func res - | Error err -> fail err - ;; - - let ( let* ) = ( >>= ) -end - -module EvalEnv : sig - type t = env - - val empty : t - val extend : t -> string -> value -> t - val compose : t -> t -> t - val find_val : t -> string -> value Res.t -end = struct - type t = env - - let empty = Map.empty (module String) - let extend env id value = Map.update env id ~f:(fun _ -> value) - - let compose env1 env2 = - Map.fold env2 ~f:(fun ~key ~data acc -> extend acc key data) ~init:env1 - ;; - - let find_val env id = - match Map.find env id with - | Some value -> Res.return value - | None -> Res.fail (NoVariable id) - ;; -end diff --git a/ELutsyuk/lib/interpreter/IntAuxilary.mli b/ELutsyuk/lib/interpreter/IntAuxilary.mli deleted file mode 100644 index be0739068..000000000 --- a/ELutsyuk/lib/interpreter/IntAuxilary.mli +++ /dev/null @@ -1,24 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.ValuesTree - -module Res : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val run : 'a t -> ('a, error) Result.t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t -end - -module EvalEnv : sig - type t = env - - val empty : t - val extend : t -> string -> value -> t - val compose : t -> t -> t - val find_val : t -> string -> value Res.t -end diff --git a/ELutsyuk/lib/interpreter/Interpret.ml b/ELutsyuk/lib/interpreter/Interpret.ml deleted file mode 100644 index 8c90a437a..000000000 --- a/ELutsyuk/lib/interpreter/Interpret.ml +++ /dev/null @@ -1,253 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open IntAuxilary.EvalEnv -open IntAuxilary.Res -open Forest.ValuesTree -open Forest.Ast - -let rec match_pattern env = function - | PatAny, _ -> Some env - | PatConst (Int x), ValInt v when x = v -> Some env - | PatConst (Bool x), ValBool v when x = v -> Some env - | PatConst (Str x), ValStr v when x = v -> Some env - | PatConst Unit, ValUnit -> Some env - | PatVar x, v -> Some (extend env x v) - | PatList pats, ValList vals -> match_list_pat env pats vals - | PatTup (p1, p2, ps), ValTup (v1, v2, vs) -> - match_list_pat env (p1 :: p2 :: ps) (v1 :: v2 :: vs) - | PatListCons (p1, p2), ValList (v :: vs) -> - let env = match_pattern env (p2, ValList vs) in - (match env with - | Some env -> match_pattern env (p1, v) - | None -> None) - | _ -> None - -and match_list_pat env pats vals = - let helper acc p v = - match acc with - | None -> None - | Some env -> match_pattern env (p, v) - in - match Base.List.fold2 pats vals ~f:helper ~init:(Some env) with - | Ok res -> res - | _ -> None -;; - -let eval_const = function - | Int v -> return @@ ValInt v - | Str v -> return @@ ValStr v - | Bool v -> return @@ ValBool v - | Unit -> return @@ ValUnit -;; - -let eval_unary_op = function - | Minus, ValInt v -> return @@ ValInt (-v) - | Plus, ValInt v -> return @@ ValInt v - | Not, ValBool v -> return @@ ValBool (not v) - | _ -> fail TypeError -;; - -(* thanks to Homka122 for such beautiful bin_op evaluation *) -let arithmetic_int_operators = [ Mul, ( * ); Div, ( / ); Add, ( + ); Sub, ( - ) ] - -let comparison_operators = - [ Eq, ( = ); Le, ( <= ); Lt, ( < ); Gt, ( > ); Ge, ( >= ); Ne, ( <> ) ] -;; - -let logical_operators = [ And, ( && ); Or, ( || ) ] - -let is_arithmetic_operator name = - List.exists (fun (list_op, _) -> name = list_op) arithmetic_int_operators -;; - -let is_comparison_operator name = - List.exists (fun (list_op, _) -> name = list_op) comparison_operators -;; - -let is_logical_operator name = - List.exists (fun (list_op, _) -> name = list_op) logical_operators -;; - -let eval_arithmetic_int_binop op_name v1 v2 = - let operator = - snd (List.find (fun (op_list, _) -> op_list = op_name) arithmetic_int_operators) - in - match v1, v2 with - | ValInt v1, ValInt v2 -> return (ValInt (operator v1 v2)) - | _ -> fail TypeError -;; - -let rec eval_comparison_binop eval_expr env op_name v1 v2 = - let operator () = - snd (List.find (fun (op_list, _) -> op_list = op_name) comparison_operators) - in - let rec eval_list_comparison list1 list2 = - match list1, list2 with - | [], [] -> return (ValBool true) - | l :: ls, r :: rs -> - let* res = eval_comparison_binop eval_expr env op_name l r in - (match res with - | ValBool false -> return (ValBool false) - | ValBool true -> eval_list_comparison ls rs - | _ -> fail TypeError) - | _, _ -> return (ValBool false) - in - match v1, v2 with - | ValInt v1, ValInt v2 -> return (ValBool ((operator ()) v1 v2)) - | ValStr v1, ValStr v2 -> return (ValBool ((operator ()) v1 v2)) - | ValBool v1, ValBool v2 -> return (ValBool ((operator ()) v1 v2)) - | ValUnit, ValUnit -> return (ValBool ((operator ()) () ())) - | ValList v1, ValList v2 -> eval_list_comparison v1 v2 - | ValTup (l1, l2, ls), ValTup (r1, r2, rs) -> - eval_list_comparison (l1 :: l2 :: ls) (r1 :: r2 :: rs) - | ValOption v1, ValOption v2 -> - (match v1, v2 with - | Some v1, Some v2 -> eval_comparison_binop eval_expr env op_name v1 v2 - | None, None -> return (ValBool ((operator ()) None None)) - | _ -> return (ValBool false)) - | _ -> fail TypeError -;; - -let eval_logical_binop op_name v1 v2 = - let operator = - snd (List.find (fun (op_list, _) -> op_list = op_name) logical_operators) - in - match v1, v2 with - | ValBool v1, ValBool v2 -> return (ValBool (operator v1 v2)) - | _ -> fail TypeError -;; - -let rec eval_expr (env : env) = function - | Var name -> find_val env name - | Const exp -> eval_const exp - | Unary (op, exp) -> - let* v = eval_expr env exp in - eval_unary_op (op, v) - | BinOp (op, exp1, exp2) when is_comparison_operator op -> - let* v1 = eval_expr env exp1 in - let* v2 = eval_expr env exp2 in - eval_comparison_binop eval_expr env op v1 v2 - | BinOp (op, exp1, exp2) when is_arithmetic_operator op -> - let* v1 = eval_expr env exp1 in - let* v2 = eval_expr env exp2 in - eval_arithmetic_int_binop op v1 v2 - | BinOp (op, exp1, exp2) when is_logical_operator op -> - let* v1 = eval_expr env exp1 in - let* v2 = eval_expr env exp2 in - eval_logical_binop op v1 v2 - | BinOp (_, _, _) -> fail TypeError - | Option (Some exp) -> - let* v = eval_expr env exp in - return (ValOption (Some v)) - | Option None -> return (ValOption None) - | Let (NonRec, Binding (pat, exp_bind), _, exp_in) -> - let* v = eval_expr env exp_bind in - (match match_pattern env (pat, v) with - | Some env -> eval_expr env exp_in - | None -> fail PatternMatchingFail) - | Let (Rec, binding, bindings, exp_in) -> - let* env = eval_let_bindings env (binding :: bindings) in - eval_expr env exp_in - | App (exp1, exp2) -> - let* v1 = eval_expr env exp1 in - let* v2 = eval_expr env exp2 in - (match v1 with - | ValFun (_, pat, pats, body, func_env) -> - (match match_pattern func_env (pat, v2) with - | Some extended_env -> - let env' = compose env extended_env in - (match pats with - | [] -> eval_expr env' body - | p :: pl -> return (ValFun (NonRec, p, pl, body, env'))) - | None -> fail PatternMatchingFail) - | ValBuiltIn "print_int" -> - (match v2 with - | ValInt v -> - Format.printf "%d\n" v; - return ValUnit - | _ -> fail TypeError) - | _ -> fail TypeError) - | Fun (pat, pats, exp) -> return (ValFun (NonRec, pat, pats, exp, env)) - | Branch (cond, _then, Const Unit) -> - let* v_cond = eval_expr env cond in - (match v_cond with - | ValBool true -> eval_expr env _then - | ValBool false -> return ValUnit - | _ -> fail TypeError) - | Branch (cond, _then, _else) -> - let* v_cond = eval_expr env cond in - (match v_cond with - | ValBool true -> eval_expr env _then - | ValBool false -> eval_expr env _else - | _ -> fail TypeError) - | Tup (exp1, exp2, exps) -> - let* v1 = eval_expr env exp1 in - let* v2 = eval_expr env exp2 in - let* vs = - List.fold_left - (fun acc exp -> - let* acc = acc in - let* v = eval_expr env exp in - return (v :: acc)) - (return []) - exps - in - return (ValTup (v1, v2, List.rev vs)) - | List exp -> - let* vl = - List.fold_left - (fun acc e -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - (return []) - exp - in - return (ValList (List.rev vl)) - | Type (exp, _) -> eval_expr env exp - -and eval_let_bindings env binding_list = - let bindings = List.map (fun (Binding (pat, exp)) -> pat, exp) binding_list in - let rec update_env acc_env = function - | [] -> return acc_env - | (PatVar id, exp) :: list_rest -> - let* value = - match exp with - | Fun (pat, pats, exp) -> return (ValFun (Rec, pat, pats, exp, acc_env)) - | _ -> eval_expr acc_env exp - in - let upd_env = extend acc_env id value in - update_env upd_env list_rest - | _ -> fail TypeError - in - let* env = update_env env bindings in - return env -;; - -let eval_structure_item env = function - | Eval exp -> - let* _ = eval_expr env exp in - return env - | Value (NonRec, Binding (pat, exp), _) -> - let* v = eval_expr env exp in - (match match_pattern env (pat, v) with - | Some env -> return env - | None -> fail PatternMatchingFail) - | Value (Rec, binding, binding_list) -> - let* env = eval_let_bindings env (binding :: binding_list) in - return env -;; - -let start_env = extend empty "print_int" (ValBuiltIn "print_int") - -let interpret tree = - List.fold_left - (fun env str_item -> - let* env = env in - let* env = eval_structure_item env str_item in - return env) - (return start_env) - tree -;; diff --git a/ELutsyuk/lib/interpreter/Interpret.mli b/ELutsyuk/lib/interpreter/Interpret.mli deleted file mode 100644 index f817577d1..000000000 --- a/ELutsyuk/lib/interpreter/Interpret.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.Ast -open Forest.ValuesTree - -val interpret : program -> env IntAuxilary.Res.t diff --git a/ELutsyuk/lib/interpreter/dune b/ELutsyuk/lib/interpreter/dune deleted file mode 100644 index 1962c5770..000000000 --- a/ELutsyuk/lib/interpreter/dune +++ /dev/null @@ -1,10 +0,0 @@ -(include_subdirs qualified) - -(library - (name interpreter) - (public_name ELutsyuk.MiniML_Interpreter) - (libraries base angstrom forest parser inferencer) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/ELutsyuk/lib/parser/Constants.ml b/ELutsyuk/lib/parser/Constants.ml deleted file mode 100644 index 665837e6a..000000000 --- a/ELutsyuk/lib/parser/Constants.ml +++ /dev/null @@ -1,91 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast -open Base -open PrsAuxilary - -(* https://ocaml.org/manual/5.3/lex.html#sss:character-literals *) - -let prs_escape_sequence = - let p_ascii = - choice - [ (let* num_opt = take_while1 Char.is_digit >>| Stdlib.int_of_string_opt in - match num_opt with - | Some char_code when char_code >= 0 && char_code <= 255 -> - return @@ Char.of_int_exn char_code - | _ -> fail "Invalid decimal escape sequence") - ; (char 'x' - *> - let* scanned = - take_while (function - | '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' -> true - | _ -> false) - in - let num_opt = Stdlib.int_of_string_opt ("0x" ^ scanned) in - match num_opt with - | Some char_code when char_code >= 0 && char_code <= 255 -> - return @@ Char.of_int_exn char_code - | _ -> fail "Invalid hex escape sequence") - ; (char 'o' - *> - let* scanned = take 3 in - let num_opt = Stdlib.int_of_string_opt ("0o" ^ scanned) in - match num_opt with - | Some char_code when char_code >= 0 && char_code <= 255 -> - return @@ Char.of_int_exn char_code - | _ -> fail "Invalid octal escape sequence") - ] - in - char '\\' - *> choice - [ char '\\' *> return '\\' - ; char '\"' *> return '\"' - ; char '\'' *> return '\'' - ; char 'n' *> return '\n' - ; char 't' *> return '\t' - ; char 'b' *> return '\b' - ; char 'r' *> return '\r' - ; string "space" *> return ' ' - ; p_ascii - ] -;; - -let prs_str = - let p_regular_str = - let is_content ch = Char.( <> ) ch '"' && Char.( <> ) ch '\\' in - let p_content = choice [ prs_escape_sequence; satisfy is_content ] in - let+ content_char_list = string "\"" *> many p_content <* string "\"" in - String.of_char_list content_char_list - in - let p_quoted_str = - string "{|" *> take_while (fun ch -> Char.( <> ) ch '|') <* string "|}" - in - let+ parsed = p_regular_str <|> p_quoted_str in - Str parsed -;; - -let prs_int = - trim - @@ - let+ parsed = take_while1 Char.is_digit >>| Int.of_string in - Int parsed -;; - -let prs_bool = - trim - @@ - let+ parsed = choice [ token "true" *> return true; token "false" *> return false ] in - Bool parsed -;; - -let prs_unit = - trim - @@ - let+ _ = token "()" in - Unit -;; - -let prs_const = choice [ prs_int; prs_str; prs_bool; prs_unit ] diff --git a/ELutsyuk/lib/parser/Constants.mli b/ELutsyuk/lib/parser/Constants.mli deleted file mode 100644 index b55f22b9e..000000000 --- a/ELutsyuk/lib/parser/Constants.mli +++ /dev/null @@ -1,12 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast - -val prs_int : const t -val prs_str : const t -val prs_bool : const t -val prs_unit : const t -val prs_const : const t diff --git a/ELutsyuk/lib/parser/Expressions.ml b/ELutsyuk/lib/parser/Expressions.ml deleted file mode 100644 index b97e67148..000000000 --- a/ELutsyuk/lib/parser/Expressions.ml +++ /dev/null @@ -1,172 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast -open PrsAuxilary -open Constants -open Patterns -open Types - -let prs_expr_var = - trim - @@ - let+ parsed = prs_id in - Var parsed -;; - -let prs_expr_const = - trim - @@ - let+ parsed = prs_const in - Const parsed -;; - -let prs_expr_list expr = - square_par - @@ - let+ parsed = sep_by (token ";") expr in - List parsed -;; - -let prs_expr_tuple expr = - let* el1 = expr in - let* el2 = token "," *> expr in - let+ rest = many (token "," *> expr) in - Tup (el1, el2, rest) -;; - -let prs_expr_fun expr = - let* pat = token "fun" *> prs_pat in - let* params = many prs_pat in - let+ body_expr = token "->" *> expr in - Fun (pat, params, body_expr) -;; - -let rec prs_expr_body expr = - let* pat = prs_pat in - let* pats = many prs_pat in - choice - [ prs_expr_body expr - ; (let+ exp = token "=" *> expr in - Fun (pat, pats, exp)) - ] -;; - -let prs_let_binding expr = - let* pat = prs_pat in - let+ body_expr = choice [ token "=" *> expr; prs_expr_body expr ] in - Binding (pat, body_expr) -;; - -let prs_expr_let expr = - trim - @@ (token "let" - *> - let* is_rec = token "rec" *> return Rec <|> return NonRec in - let* binding = prs_let_binding expr in - let* bindings_list = many (token "and" *> prs_let_binding expr) in - let+ in_expr = token "in" *> expr in - Let (is_rec, binding, bindings_list, in_expr)) -;; - -let prs_expr_branch prs_expr = - let* if_cond = token "if" *> prs_expr in - let* then_cond = token "then" *> prs_expr in - let+ else_cond = token "else" *> prs_expr <|> return @@ Const Unit in - Branch (if_cond, then_cond, else_cond) -;; - -let chainl1 expr oper = - let rec go acc = lift2 (fun f x -> f acc x) oper expr >>= go <|> return acc in - expr >>= go -;; - -let prs_bin_op binop sign = - trim @@ (token sign *> return (fun exp1 exp2 -> BinOp (binop, exp1, exp2))) -;; - -let prs_logical = choice [ prs_bin_op And "&&"; prs_bin_op Or "||" ] -let prs_mul = prs_bin_op Mul "*" -let prs_add = prs_bin_op Add "+" -let prs_sub = prs_bin_op Sub "-" -let prs_div = prs_bin_op Div "/" - -let prs_rel = - choice - [ prs_bin_op Eq "=" - ; prs_bin_op Ne "<>" - ; prs_bin_op Le "<=" - ; prs_bin_op Ge ">=" - ; prs_bin_op Lt "<" - ; prs_bin_op Gt ">" - ] -;; - -let prs_unary op sign = trim @@ (token sign *> return (fun exp -> Unary (op, exp))) -let prs_minus = prs_unary Minus "-" -let prs_plus = prs_unary Plus "+" -let prs_not = prs_unary Not "not" <* skip_ws - -let prs_option expr = - let p_some_expr = - token "Some" - *> - let* p_expr = round_par expr <|> expr in - return (Some p_expr) - in - let p_none = token "None" *> return None in - let+ parsed = p_some_expr <|> p_none in - Option parsed -;; - -let prs_expr_app expr = - let app = return @@ fun exp1 exp2 -> App (exp1, exp2) in - chainl1 expr app -;; - -let prs_expr_type expr = - let expr_with_type = - let* exp = expr in - let* _ = token ":" in - let+ typ = prs_typ in - Type (exp, typ) - in - expr_with_type <|> round_par expr_with_type -;; - -let unary_chain exp op = - fix (fun self -> op >>= (fun unop -> self >>= fun exp -> return (unop exp)) <|> exp) -;; - -let prs_expr = - fix (fun expr -> - let atom_expr = - choice - [ prs_expr_const - ; prs_expr_var - ; round_par expr - ; prs_expr_list expr - ; prs_expr_fun expr - ; prs_option expr - ; round_par (prs_expr_type expr) - ] - in - let let_expr = prs_expr_let expr in - let ite_expr = prs_expr_branch (expr <|> atom_expr) <|> atom_expr in - let app_expr = prs_expr_app (ite_expr <|> atom_expr) <|> ite_expr in - let un_expr = - choice - [ unary_chain app_expr prs_not - ; unary_chain app_expr prs_minus - ; unary_chain app_expr prs_plus - ] - in - let factor_expr = chainl1 un_expr (prs_mul <|> prs_div) in - let sum_expr = chainl1 factor_expr (prs_add <|> prs_sub) in - let rel_expr = chainl1 sum_expr prs_rel in - let log_expr = chainl1 rel_expr prs_logical in - let tup_expr = prs_expr_tuple log_expr <|> log_expr in - choice [ let_expr; tup_expr ]) -;; diff --git a/ELutsyuk/lib/parser/Expressions.mli b/ELutsyuk/lib/parser/Expressions.mli deleted file mode 100644 index 449e4312f..000000000 --- a/ELutsyuk/lib/parser/Expressions.mli +++ /dev/null @@ -1,22 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast - -val prs_expr_var : expr t -val prs_expr_const : expr t -val prs_expr_list : expr t -> expr t -val prs_expr_tuple : expr t -> expr t -val prs_expr_app : expr t -> expr t -val prs_expr_branch : expr t -> expr t -val prs_expr_fun : expr t -> expr t -val prs_expr_let : expr t -> expr t -val prs_let_binding : expr t -> let_binding t - -(* val prs_expr_unary : expr t -> expr t *) -val prs_bin_op : binop -> id -> (expr -> expr -> expr) t -val prs_option : expr t -> expr t -val prs_expr_type : expr t -> expr t -val prs_expr : expr t diff --git a/ELutsyuk/lib/parser/Parser.ml b/ELutsyuk/lib/parser/Parser.ml deleted file mode 100644 index 7d748f164..000000000 --- a/ELutsyuk/lib/parser/Parser.ml +++ /dev/null @@ -1,26 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast -open PrsAuxilary -open Expressions - -let prs_structure = - let p_struct_binding = - let* _ = token "let" in - let* rec_state = choice [ string "rec " *> return Rec; return NonRec ] in - let* binding = prs_let_binding prs_expr in - let+ bindings_list = many (token "and" *> prs_let_binding prs_expr) in - Value (rec_state, binding, bindings_list) - in - let p_struct_eval = - let+ eval = prs_expr in - Eval eval - in - p_struct_binding <|> p_struct_eval -;; - -let prs_program = sep_by (many (token ";;")) prs_structure <* many (token ";;") <* skip_ws -let parse str = parse_string ~consume:All prs_program str diff --git a/ELutsyuk/lib/parser/Parser.mli b/ELutsyuk/lib/parser/Parser.mli deleted file mode 100644 index 2d2bd812a..000000000 --- a/ELutsyuk/lib/parser/Parser.mli +++ /dev/null @@ -1,11 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast - -val prs_program : program t - -(* val parse_program : program t *) -val parse : id -> (program, string) result diff --git a/ELutsyuk/lib/parser/Types.ml b/ELutsyuk/lib/parser/Types.ml deleted file mode 100644 index 0ba660cf3..000000000 --- a/ELutsyuk/lib/parser/Types.ml +++ /dev/null @@ -1,49 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.TypesTree -open PrsAuxilary - -let prs_typ_constant = - choice - [ (token "int" >>| fun _ -> TypConst TInt) - ; (token "string" >>| fun _ -> TypConst TStr) - ; (token "bool" >>| fun _ -> TypConst TBool) - ; (token "unit" >>| fun _ -> TypConst TUnit) - ] -;; - -let rec prs_typ_arrow prs_typ = - let* left_ty = prs_typ in - let+ right_ty = token "->" *> (prs_typ_arrow prs_typ <|> prs_typ) in - TypArrow (left_ty, right_ty) -;; - -let prs_typ_tup prs_typ = - let* ty1 = prs_typ in - let+ tys = many1 (token "*" *> prs_typ) in - TypTuple (ty1 :: tys) -;; - -let rec prs_typ_list prs_typ = - let* ty = prs_typ in - let* _ = token "list" in - prs_typ_list (return (TypList ty)) <|> return (TypList ty) -;; - -let rec prs_typ_option prs_typ = - let* ty = prs_typ in - let* _ = token "option" in - prs_typ_option (return (TypOption ty)) <|> return (TypOption ty) -;; - -let prs_typ = - fix (fun typ -> - let atom = prs_typ_constant <|> round_par typ in - let list_or_option = prs_typ_list atom <|> prs_typ_option atom <|> atom in - let tuple = prs_typ_tup list_or_option <|> list_or_option in - let arrow = prs_typ_arrow tuple <|> tuple in - arrow) -;; diff --git a/ELutsyuk/lib/parser/Types.mli b/ELutsyuk/lib/parser/Types.mli deleted file mode 100644 index ffffde3a3..000000000 --- a/ELutsyuk/lib/parser/Types.mli +++ /dev/null @@ -1,13 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.TypesTree - -val prs_typ_constant : typ t -val prs_typ_arrow : typ t -> typ t -val prs_typ_tup : typ t -> typ t -val prs_typ_list : typ t -> typ t -val prs_typ_option : typ t -> typ t -val prs_typ : typ t diff --git a/ELutsyuk/lib/parser/dune b/ELutsyuk/lib/parser/dune deleted file mode 100644 index a74d0d411..000000000 --- a/ELutsyuk/lib/parser/dune +++ /dev/null @@ -1,11 +0,0 @@ -(include_subdirs qualified) - -(library - (name parser) - (public_name ELutsyuk.MiniML_Parser) - (libraries base angstrom forest) - (preprocess - (pps ppx_expect)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) diff --git a/ELutsyuk/lib/parser/patterns.ml b/ELutsyuk/lib/parser/patterns.ml deleted file mode 100644 index 814cbcdbb..000000000 --- a/ELutsyuk/lib/parser/patterns.ml +++ /dev/null @@ -1,89 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast -open Types -open Constants -open PrsAuxilary - -let prs_pat_var = - trim - @@ - let* parsed = prs_id in - if String.equal parsed "_" then fail "Any pattern" else return @@ PatVar parsed -;; - -let prs_pat_constant = - trim - @@ - let+ parsed = prs_const in - PatConst parsed -;; - -let prs_pat_any = - trim - @@ - let* _ = token "_" in - let* rest = take_while Base.Char.is_alphanum in - match rest with - | "" -> return PatAny - | _ -> fail "Not any pattern" -;; - -let prs_pat_tuple pat = - trim - @@ - let* el1 = pat in - let* el2 = token "," *> pat in - let+ rest = many (token "," *> pat) in - PatTup (el1, el2, rest) -;; - -let prs_pat_cons pat = - trim - @@ - let* el1 = pat in - let* rest = many (token "::" *> pat) in - let rec helper = function - | [] -> el1 - | [ el2 ] -> el2 - | el2 :: rest -> PatListCons (el2, helper rest) - in - return (helper (el1 :: rest)) -;; - -let prs_pat_list pat = - square_par - @@ - let+ parsed = sep_by (token ";") pat in - PatList parsed -;; - -let prs_pat_type pat = - round_par - @@ - let* pat = pat in - let* _ = token ":" in - let+ typ = prs_typ in - PatType (pat, typ) -;; - -let prs_pat = - fix - @@ fun pat -> - let atomary = - choice - [ prs_pat_var - ; prs_pat_any - ; prs_pat_constant - ; round_par pat - ; prs_pat_type pat - ; prs_pat_list pat - ] - in - let cons = prs_pat_cons atomary in - let tuple = prs_pat_tuple atomary <|> cons in - tuple -;; diff --git a/ELutsyuk/lib/parser/patterns.mli b/ELutsyuk/lib/parser/patterns.mli deleted file mode 100644 index a4f34c506..000000000 --- a/ELutsyuk/lib/parser/patterns.mli +++ /dev/null @@ -1,14 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast - -val prs_pat_var : pat t -val prs_pat_constant : pat t -val prs_pat_any : pat t -val prs_pat_tuple : pat t -> pat t -val prs_pat_cons : pat t -> pat t -val prs_pat_list : pat t -> pat t -val prs_pat : pat t diff --git a/ELutsyuk/lib/parser/prsAuxilary.ml b/ELutsyuk/lib/parser/prsAuxilary.ml deleted file mode 100644 index f9c7aae28..000000000 --- a/ELutsyuk/lib/parser/prsAuxilary.ml +++ /dev/null @@ -1,46 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Base - -(* https://ocaml.org/manual/4.07/manual049.html *) -let is_keyword = function - | "if" - | "then" - | "else" - | "fun" - | "let" - | "rec" - | "and" - | "in" - | "match" - | "with" - | "true" - | "false" - | "Some" - | "None" - | "val" -> true - | _ -> false -;; - -let skip_ws = skip_while Char.is_whitespace -let trim t = skip_ws *> t <* skip_ws -let token t = skip_ws *> string t <* skip_ws -let round_par p = token "(" *> p <* token ")" -let square_par p = token "[" *> p <* token "]" - -(** Parses first letter then try parse the rest of id *) -let prs_id = - trim - @@ - let is_first_letter ch = - Char.is_lowercase ch || Char.is_uppercase ch || Char.equal '_' ch - in - let is_rest_letter ch = Char.is_alphanum ch || Char.equal '_' ch in - let* p_first = satisfy is_first_letter >>| Char.escaped in - let* p_rest = take_while is_rest_letter in - let id = p_first ^ p_rest in - if is_keyword id then fail "Error: parse_id: id match the keyword." else return id -;; diff --git a/ELutsyuk/lib/parser/prsAuxilary.mli b/ELutsyuk/lib/parser/prsAuxilary.mli deleted file mode 100644 index c66e75095..000000000 --- a/ELutsyuk/lib/parser/prsAuxilary.mli +++ /dev/null @@ -1,13 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast - -val skip_ws : unit t -val trim : 'a t -> 'a t -val token : string -> string t -val round_par : 'a t -> 'a t -val square_par : 'a t -> 'a t -val prs_id : id t diff --git a/ELutsyuk/lib/parser/unitTests.ml b/ELutsyuk/lib/parser/unitTests.ml deleted file mode 100644 index 50412b34a..000000000 --- a/ELutsyuk/lib/parser/unitTests.ml +++ /dev/null @@ -1,355 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Forest.Ast -open Forest.TypesTree -open PrsAuxilary -open Constants -open Patterns -open Expressions -open Types - -let pp printer parser str = - match parse_string ~consume:Angstrom.Consume.All parser str with - | Ok res -> printer Format.std_formatter res - | Error _ -> print_endline "Syntax error" -;; - -(* ================================= auxiliary ================================= *) - -let%expect_test "normal_id" = - pp Format.pp_print_string prs_id "_id"; - [%expect {| _id |}] -;; - -let%expect_test "incorrect_id_num" = - pp Format.pp_print_string prs_id "1id"; - [%expect {| Syntax error |}] -;; - -let%expect_test "keyword_id" = - pp Format.pp_print_string prs_id "let"; - [%expect {| Syntax error |}] -;; - -(* ================================= constants ================================= *) - -let%expect_test "num_without_sign_before" = - pp pp_const prs_int "2024"; - [%expect {| (Int 2024) |}] -;; - -let%expect_test "quoted_string_with_double_slash" = - pp pp_const prs_str "{|str\\meow|}"; - [%expect {| (Str "str\\meow") |}] -;; - -let%expect_test "regular_string_with_double_slash" = - pp pp_const prs_str {|"str\\meow"|}; - [%expect {| (Str "str\\meow") |}] -;; - -let%expect_test "regular_string_with_slash" = - pp pp_const prs_str {|"str\meow"|}; - [%expect {| Syntax error |}] -;; - -let%expect_test "regular_unclosed_string" = - pp pp_const prs_str {|"str|}; - [%expect {| Syntax error |}] -;; - -let%expect_test "quoted_unclosed_string" = - pp pp_const prs_str "{|str"; - [%expect {| Syntax error |}] -;; - -let%expect_test "quoted_empty_string" = - pp pp_const prs_str "\"\""; - [%expect {| (Str "") |}] -;; - -let%expect_test "regular_empty_string" = - pp pp_const prs_str "{||}"; - [%expect {| (Str "") |}] -;; - -let%expect_test "regular_string_one_space" = - pp pp_const prs_str "\" \""; - [%expect {| (Str " ") |}] -;; - -let%expect_test "quoted_string_one_space" = - pp pp_const prs_str "{| |}"; - [%expect {| (Str " ") |}] -;; - -let%expect_test "quoted_string_two_spaces" = - pp pp_const prs_str "{| |}"; - [%expect {| (Str " ") |}] -;; - -let%expect_test "quoted_string_with_text" = - pp pp_const prs_str "{| hello |}"; - [%expect {| (Str " hello ") |}] -;; - -let%expect_test "regular_string_escape_sequence" = - pp pp_const prs_str "\"Hex\\x41\\x42\\x43\""; - [%expect {| (Str "HexABC") |}] -;; - -let%expect_test "regular_string_incorrect_escape_sequence" = - pp pp_const prs_str "\"meow\n\""; - [%expect {| (Str "meow\n") |}] -;; - -let%expect_test "true" = - pp pp_const prs_bool "true"; - [%expect {| (Bool true) |}] -;; - -let%expect_test "false" = - pp pp_const prs_bool "false"; - [%expect {| (Bool false) |}] -;; - -let%expect_test "incorrect_bool_with_char_after" = - pp pp_const prs_bool "truee"; - [%expect {| Syntax error |}] -;; - -let%expect_test "unit" = - pp pp_const prs_unit "()"; - [%expect {| Unit |}] -;; - -(* ================================== patterns ================================= *) - -let%expect_test "pat_var" = - pp pp_pat prs_pat_var "meow\n"; - [%expect {| (PatVar "meow") |}] -;; - -let%expect_test "pat_constant" = - pp pp_pat prs_pat_constant " \r{|meow|}\n"; - [%expect {| (PatConst (Str "meow")) |}] -;; - -let%expect_test "pat_constructor" = - pp pp_pat (prs_pat_cons prs_pat) "a :: []"; - [%expect {| (PatListCons ((PatVar "a"), (PatList []))) |}] -;; - -let%expect_test "pat_empty_str" = - pp pp_pat prs_pat_constant " \r{||}\n"; - [%expect {| (PatConst (Str "")) |}] -;; - -let%expect_test "pat_any" = - pp pp_pat prs_pat_any "\r_\n"; - [%expect {| PatAny |}] -;; - -let%expect_test "pat_simple_tuple" = - pp pp_pat prs_pat "1, 2, 3"; - [%expect - {| - (PatTup ((PatConst (Int 1)), (PatConst (Int 2)), [(PatConst (Int 3))])) |}] -;; - -let%expect_test "incorrect_pat_tuple_of_one_element" = - pp pp_pat (prs_pat_tuple prs_pat) "1"; - [%expect {| Syntax error |}] -;; - -let%expect_test "parse_empty_list" = - pp pp_pat (prs_pat_list prs_pat) "[]"; - [%expect {| - (PatList []) |}] -;; - -(* ================================ expressions ================================ *) - -let%expect_test "expr_cons_int" = - pp pp_expr prs_expr_const "1"; - [%expect {| - (Const (Int 1)) |}] -;; - -let%expect_test "expr_cons_str" = - pp pp_expr prs_expr_const " {|meow|} "; - [%expect {| - (Const (Str "meow")) |}] -;; - -let%expect_test "expr_cons_unit" = - pp pp_expr prs_expr_const " () "; - [%expect {| - (Const Unit) |}] -;; - -let%expect_test "simple_list" = - pp pp_expr (prs_expr_list prs_expr) " [ 1 ; 2\n; 3] "; - [%expect {| (List [(Const (Int 1)); (Const (Int 2)); (Const (Int 3))]) |}] -;; - -let%expect_test "complex_list" = - pp pp_expr (prs_expr_list prs_expr) " [ [1;2;3] ; 2\n; 3] "; - [%expect - {| - (List - [(List [(Const (Int 1)); (Const (Int 2)); (Const (Int 3))]); - (Const (Int 2)); (Const (Int 3))]) |}] -;; - -let%expect_test "empty_list" = - pp pp_expr (prs_expr_list prs_expr) "[]"; - [%expect {| (List []) |}] -;; - -let%expect_test "incorrect_tuple_one_el" = - pp pp_expr (prs_expr_tuple prs_expr) "(1)"; - [%expect {| Syntax error |}] -;; - -let%expect_test "simple_fun" = - pp pp_expr (prs_expr_fun prs_expr) "fun x -> x"; - [%expect {| (Fun ((PatVar "x"), [], (Var "x"))) |}] -;; - -let%expect_test "fun_two_var" = - pp pp_expr (prs_expr_fun prs_expr) "fun x y -> x + y"; - [%expect - {| - (Fun ((PatVar "x"), [(PatVar "y")], (BinOp (Add, (Var "x"), (Var "y"))))) |}] -;; - -let%expect_test "fun_of_fun" = - pp pp_expr (prs_expr_fun prs_expr) "fun x -> fun _ -> x"; - [%expect {| (Fun ((PatVar "x"), [], (Fun (PatAny, [], (Var "x"))))) |}] -;; - -let%expect_test "let_with_in" = - pp pp_expr (prs_expr_let prs_expr) "let meow = 5 in meow + 1"; - [%expect - {| - (Let (NonRec, (Binding ((PatVar "meow"), (Const (Int 5)))), [], - (BinOp (Add, (Var "meow"), (Const (Int 1)))))) |}] -;; - -let%expect_test "simple_app" = - pp pp_expr (prs_expr_app prs_expr) "fact 1"; - [%expect {| - (App ((Var "fact"), (Const (Int 1)))) |}] -;; - -let%expect_test "app_two_par" = - pp pp_expr (prs_expr_app prs_expr) "foo 1 2"; - [%expect {| - (App ((App ((Var "foo"), (Const (Int 1)))), (Const (Int 2)))) |}] -;; - -let%expect_test "app_in_app" = - pp pp_expr (prs_expr_app prs_expr) "foo (g 1) 2"; - [%expect - {| - (App ((App ((Var "foo"), (App ((Var "g"), (Const (Int 1)))))), - (Const (Int 2)))) |}] -;; - -let%expect_test "simple_branch" = - pp pp_expr (prs_expr_branch prs_expr) "if x = 5 then 7 else 6"; - [%expect - {| - (Branch ((BinOp (Eq, (Var "x"), (Const (Int 5)))), (Const (Int 7)), - (Const (Int 6)))) |}] -;; - -let%expect_test "branch_in_branch" = - pp pp_expr (prs_expr_branch prs_expr) "if x = 5 then (if x = 7 then 7) else 4"; - [%expect - {| - (Branch ((BinOp (Eq, (Var "x"), (Const (Int 5)))), - (Branch ((BinOp (Eq, (Var "x"), (Const (Int 7)))), (Const (Int 7)), - (Const Unit))), - (Const (Int 4)))) |}] -;; - -let%expect_test "prs_some" = - pp pp_expr (prs_option prs_expr) "Some (n - 1) "; - [%expect {| - (Option (Some (BinOp (Sub, (Var "n"), (Const (Int 1)))))) |}] -;; - -let%expect_test "prs_none" = - pp pp_expr (prs_option prs_expr) "None "; - [%expect {| - (Option None) |}] -;; - -let%expect_test "prs_expr_binop_with_some" = - pp pp_expr prs_expr "Some n - 1 "; - [%expect {| - (Option (Some (BinOp (Sub, (Var "n"), (Const (Int 1)))))) |}] -;; - -let%expect_test "prs_expr_some" = - pp pp_expr prs_expr "Some (n - 1) "; - [%expect {| - (Option (Some (BinOp (Sub, (Var "n"), (Const (Int 1)))))) |}] -;; - -(* =================================== types =================================== *) - -let%expect_test "prs_typ_constant_int" = - pp pp_typ prs_typ_constant "int"; - [%expect {| int |}] -;; - -let%expect_test "prs_typ_constant_string" = - pp pp_typ prs_typ_constant "string"; - [%expect {| string |}] -;; - -let%expect_test "prs_typ_arrow_simple" = - pp pp_typ (prs_typ_arrow prs_typ_constant) "int -> string"; - [%expect {| int -> string |}] -;; - -let%expect_test "prs_typ_arrow_nested" = - pp pp_typ (prs_typ_arrow prs_typ_constant) "int -> string -> bool"; - [%expect {| int -> string -> bool |}] -;; - -let%expect_test "prs_typ_tup_pair" = - pp pp_typ (prs_typ_tup prs_typ_constant) "int * string"; - [%expect {| (int * string) |}] -;; - -let%expect_test "prs_typ_tup_triple" = - pp pp_typ (prs_typ_tup prs_typ_constant) "int * string * bool"; - [%expect {| (int * string * bool) |}] -;; - -let%expect_test "prs_typ_list" = - pp pp_typ (prs_typ_list prs_typ_constant) "int list"; - [%expect {| int list |}] -;; - -let%expect_test "prs_typ_list_nested" = - pp pp_typ (prs_typ_list prs_typ_constant) "int list list"; - [%expect {| int list list |}] -;; - -let%expect_test "prs_typ_option" = - pp pp_typ (prs_typ_option prs_typ_constant) "int option"; - [%expect {| int option |}] -;; - -let%expect_test "prs_typ_option_nested" = - pp pp_typ (prs_typ_option prs_typ_constant) "int option option"; - [%expect {| int option option |}] -;; diff --git a/ELutsyuk/lib/parser/unitTests.mli b/ELutsyuk/lib/parser/unitTests.mli deleted file mode 100644 index e027138eb..000000000 --- a/ELutsyuk/lib/parser/unitTests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) diff --git a/ELutsyuk/tests/InferTests.ml b/ELutsyuk/tests/InferTests.ml deleted file mode 100644 index 50e17f3ad..000000000 --- a/ELutsyuk/tests/InferTests.ml +++ /dev/null @@ -1,85 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Inferencer.Inference -open Parser - -let test_inference str = - let open Stdlib.Format in - match parse str with - | Ok parsed -> - (match inference parsed with - | Ok (_, env) -> - Base.Map.iteri env ~f:(fun ~key ~data:(Scheme (_, typ)) -> - if String.equal key "print_int" || String.equal key "print_endline" - then () - else Stdlib.Format.printf "val %s : %a\n" key Forest.TypesTree.pp_typ typ) - | Error err -> printf "Infer error: %a\n" Forest.TypesTree.pp_error err) - | Error err -> printf "Parsing error: %s\n" err -;; - -let%expect_test "inference_arithmetic" = - test_inference "let cat = 1 + 2 * 3 / 10"; - [%expect {| - val cat : int |}] -;; - -let%expect_test "inference_fun_with_argument" = - test_inference {| let foo x = x + 100 |}; - [%expect {| - val foo : int -> int |}] -;; - -let%expect_test "inference_rec_fun_with_argument" = - test_inference {| let rec foo x = foo 5 - 1 |}; - [%expect {| - val foo : int -> int |}] -;; - -let%expect_test "inference_fun_with_nesting" = - test_inference {| let add_one x = let double y = y * 2 in double (x + 1) |}; - [%expect {| val add_one : int -> int |}] -;; - -let%expect_test "inference_polymorphic_fun" = - test_inference "let identity x = x"; - [%expect {| val identity : '0 -> '0 |}] -;; - -let%expect_test "inference_fun_with_tuple_argument" = - test_inference {| let sum (x, y) = x + y|}; - [%expect {| val sum : (int * int) -> int |}] -;; - -let%expect_test "inference_unbound_variable" = - test_inference {| let foo x = x + a |}; - [%expect - {| - Infer error: unbound variable: 'a' is not defined in the current scope |}] -;; - -let%expect_test "inference_many_fun" = - test_inference {| let a = fun x y -> fun z -> fun w -> fun c -> x + y + z + w+ c |}; - [%expect {| -val a : int -> int -> int -> int -> int -> int |}] -;; - -let%expect_test "inference_unit" = - test_inference {| let x = () |}; - [%expect {| - val x : unit |}] -;; - -let%expect_test "inference_tuple" = - test_inference {| let meow = ();; let x = (1, "a", meow ) |}; - [%expect {| - val meow : unit - val x : (int * string * unit) |}] -;; - -let%expect_test "inference_combined_type" = - test_inference {| let foo x = if x then [Some x; Some x] else [None; None]|}; - [%expect {| - val foo : bool -> bool option list |}] -;; diff --git a/ELutsyuk/tests/InferTests.mli b/ELutsyuk/tests/InferTests.mli deleted file mode 100644 index e027138eb..000000000 --- a/ELutsyuk/tests/InferTests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) diff --git a/ELutsyuk/tests/ParserTests.ml b/ELutsyuk/tests/ParserTests.ml deleted file mode 100644 index 9d2b1fbd8..000000000 --- a/ELutsyuk/tests/ParserTests.ml +++ /dev/null @@ -1,130 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - -open Forest.Ast -open Parser - -let test_parse str = - let open Stdlib.Format in - match parse str with - | Ok program -> printf "%s\n" (show_program program) - | Error err -> printf "%s\n" err -;; - -let%expect_test "parse_arithmetic" = - test_parse "1 + 2 * 3"; - [%expect - {| - [(Eval - (BinOp (Add, (Const (Int 1)), - (BinOp (Mul, (Const (Int 2)), (Const (Int 3))))))) - ] |}] -;; - -let%expect_test "parse_application" = - test_parse "fact (n - 1)"; - [%expect - {| - [(Eval (App ((Var "fact"), (BinOp (Sub, (Var "n"), (Const (Int 1)))))))] |}] -;; - -let%expect_test "parse_application" = - test_parse "foo -1"; - [%expect {| - [(Eval (BinOp (Sub, (Var "foo"), (Const (Int 1)))))] |}] -;; - -let%expect_test "parse_multiple_bindings" = - test_parse "let x = 10\n let y = x + 5"; - [%expect - {| -[(Value (NonRec, (Binding ((PatVar "x"), (Const (Int 10)))), [])); - (Value (NonRec, - (Binding ((PatVar "y"), (BinOp (Add, (Var "x"), (Const (Int 5)))))), - [])) - ] |}] -;; - -let%expect_test "parse_brackets" = - test_parse "(1 + 2) * 3"; - [%expect - {| - [(Eval - (BinOp (Mul, (BinOp (Add, (Const (Int 1)), (Const (Int 2)))), - (Const (Int 3))))) - ] |}] -;; - -let%expect_test "complex_tuple" = - test_parse "((1, 1, 1), (2, 2, 2), {|meow|})"; - [%expect - {| - [(Eval - (Tup ((Tup ((Const (Int 1)), (Const (Int 1)), [(Const (Int 1))])), - (Tup ((Const (Int 2)), (Const (Int 2)), [(Const (Int 2))])), - [(Const (Str "meow"))]))) - ] |}] -;; - -let%expect_test "parse_tuple" = - test_parse "(1, 2, 3)"; - [%expect {| - [(Eval (Tup ((Const (Int 1)), (Const (Int 2)), [(Const (Int 3))])))] |}] -;; - -let%expect_test "parse_two_func" = - test_parse - "let rec fac n = if n<=1 then 1 else n * fac (n-1)\n\ - let main =\n\ - \ let () = print_int (fac 4) in\n\ - \ 0\n\ - ;;"; - [%expect - {| - [(Value (Rec, - (Binding ((PatVar "fac"), - (Fun ((PatVar "n"), [], - (Branch ((BinOp (Le, (Var "n"), (Const (Int 1)))), (Const (Int 1)), - (BinOp (Mul, (Var "n"), - (App ((Var "fac"), (BinOp (Sub, (Var "n"), (Const (Int 1)))) - )) - )) - )) - )) - )), - [])); - (Value (NonRec, - (Binding ((PatVar "main"), - (Let (NonRec, - (Binding ((PatConst Unit), - (App ((Var "print_int"), (App ((Var "fac"), (Const (Int 4)))))) - )), - [], (Const (Int 0)))) - )), - [])) - ] |}] -;; - -let%expect_test "parse_sub_without_ws" = - test_parse "a-1"; - [%expect {| - [(Eval (BinOp (Sub, (Var "a"), (Const (Int 1)))))] |}] -;; - -let%expect_test "parse_sub_with_ws" = - test_parse "a - 1"; - [%expect {| - [(Eval (BinOp (Sub, (Var "a"), (Const (Int 1)))))] |}] -;; - -let%expect_test "parse_unary_minus" = - test_parse "a -1"; - [%expect {| - [(Eval (BinOp (Sub, (Var "a"), (Const (Int 1)))))] |}] -;; - -let%expect_test "parse_unary_plus" = - test_parse "a +1"; - [%expect {| [(Eval (BinOp (Add, (Var "a"), (Const (Int 1)))))] |}] -;; diff --git a/ELutsyuk/tests/ParserTests.mli b/ELutsyuk/tests/ParserTests.mli deleted file mode 100644 index e027138eb..000000000 --- a/ELutsyuk/tests/ParserTests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) diff --git a/ELutsyuk/tests/dune b/ELutsyuk/tests/dune deleted file mode 100644 index c623642bc..000000000 --- a/ELutsyuk/tests/dune +++ /dev/null @@ -1,42 +0,0 @@ -(library - (name tests) - (libraries - ELutsyuk.MiniML_Forest - ELutsyuk.MiniML_Parser - ELutsyuk.MiniML_Interpreter - ELutsyuk.MiniML_Inferencer) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to tests) - (deps - ../bin/main.exe - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml)) diff --git a/ELutsyuk/tests/manytests b/ELutsyuk/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/ELutsyuk/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/ELutsyuk/tests/tests.t b/ELutsyuk/tests/tests.t deleted file mode 100644 index 1ab675ada..000000000 --- a/ELutsyuk/tests/tests.t +++ /dev/null @@ -1,152 +0,0 @@ -(** Copyright 2024, Victoria Lutsyuk *) - -(** SPDX-License-Identifier: MIT *) - - $ ../bin/main.exe -eval -file manytests/typed/001fac.ml - 24 - - $ ../bin/main.exe -eval -file manytests/typed/002fac.ml - 24 - - $ ../bin/main.exe -eval -file manytests/typed/003fib.ml - 3 - 3 - - $ ../bin/main.exe -eval -file manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - - $ ../bin/main.exe -eval -file manytests/typed/005fix.ml - 720 - - $ ../bin/main.exe -eval -file manytests/typed/006partial.ml - 1122 - - - $ ../bin/main.exe -eval -file manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - - - $ ../bin/main.exe -eval -file manytests/typed/006partial3.ml - 4 - 8 - 9 - - $ ../bin/main.exe -eval -file manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - - - $ ../bin/main.exe -eval -file manytests/typed/008ascription.ml - 8 - - $ ../bin/main.exe -eval -file manytests/typed/009let_poly.ml - - $ ../bin/main.exe -eval -file manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - - $ ../bin/main.exe -infer -file manytests/typed/001fac.ml - val fac: int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/002fac.ml - val fac_cps: int -> (int -> int) -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/003fib.ml - val fib: int -> int - val fib_acc: int -> int -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/004manyargs.ml - val main: int - val test10: int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val test3: int -> int -> int -> int - val wrap: '0 -> '0 - - $ ../bin/main.exe -infer -file manytests/typed/005fix.ml - val fac: (int -> int) -> int -> int - val fix: ((int -> int) -> int -> int) -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial.ml - val foo: int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial2.ml - val foo: int -> int -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial3.ml - val foo: int -> int -> int -> unit - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/007order.ml - val _start: unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main: unit - - - $ ../bin/main.exe -infer -file manytests/typed/008ascription.ml - val addi: ('2 -> bool -> int) -> ('2 -> bool) -> '2 -> int - val main: int - - - - $ ../bin/main.exe -infer -file manytests/typed/009let_poly.ml - val temp: (int * bool) - - - $ ../bin/main.exe -infer -file manytests/typed/015tuples.ml - val feven: (int -> int * '28) -> int -> int - val fix: ((((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int)) -> ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int)) -> ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int) - val fixpoly: ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int) - val fodd: ('35 * int -> int) -> int -> int - val main: int - val map: ('9 -> '11) -> ('9 * '9) -> ('11 * '11) - val meven: int -> int - val modd: int -> int - val tie: (int -> int * int -> int) - - - - $ ../bin/main.exe -infer -file manytests/do_not_type/001.ml - Inferencing error: unbound variable: 'fac' is not defined in the current scope. - - $ ../bin/main.exe -infer -file manytests/do_not_type/002if.ml - Inferencing error: type unification failed: cannot unify types int and bool. - - - $ ../bin/main.exe -infer -file manytests/do_not_type/003occurs.ml - Inferencing error: occurs check failed: variable '1' cannot appear in its own type '1 -> '3. - - - $ ../bin/main.exe -infer -file manytests/do_not_type/004let_poly.ml - Inferencing error: type unification failed: cannot unify types int and bool. - - $ ../bin/main.exe -infer -file manytests/do_not_type/015tuples.ml - Inferencing error: illegal left-hand side: only variables can appear on the left-hand side of a 'let' binding. - - $ ../bin/main.exe -infer -file manytests/do_not_type/016tuples_mismatch.ml - Inferencing error: type unification failed: cannot unify types ('1 * '0) and (int * int * int). - - $ ../bin/main.exe -infer -file manytests/do_not_type/097fun_vs_list.ml - Inferencing error: type unification failed: cannot unify types '2 list and '0 -> '0. - - $ ../bin/main.exe -infer -file manytests/do_not_type/097fun_vs_unit.ml - Inferencing error: type unification failed: cannot unify types unit and '0 -> '0. - - $ ../bin/main.exe -infer -file manytests/do_not_type/098rec_int.ml - Inferencing error: illegal right-hand side: the right-hand side of a 'let' binding must be an expression, not a pattern. diff --git a/EMigunova/.envrc b/EMigunova/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/EMigunova/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/EMigunova/.gitignore b/EMigunova/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/EMigunova/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/EMigunova/.ocamlformat b/EMigunova/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/EMigunova/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/EMigunova/.ocamlinit b/EMigunova/.ocamlinit deleted file mode 100644 index 57cb5691b..000000000 --- a/EMigunova/.ocamlinit +++ /dev/null @@ -1,10 +0,0 @@ -#require "base";; -#require "angstrom";; -#load "parse.cmo";; -#load "inference.cmo";; -#load "interpreter.cmo";; -open Ast;; -open Parse;; -open Inference;; -open Interpreter;; - diff --git a/EMigunova/.zanuda b/EMigunova/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/EMigunova/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/EMigunova/COPYING b/EMigunova/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/EMigunova/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/EMigunova/COPYING.CC0 b/EMigunova/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/EMigunova/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/EMigunova/COPYING.LESSER b/EMigunova/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/EMigunova/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/EMigunova/EMigunova.opam b/EMigunova/EMigunova.opam deleted file mode 100644 index f3591117e..000000000 --- a/EMigunova/EMigunova.opam +++ /dev/null @@ -1,36 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for miniML" -description: - "FIXME. A longer description, for example, which are the most interesting features being supported, etc." -maintainer: ["Migunova Anastasia "] -authors: ["Migunova Anastasia "] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/MigunovaAnastasia1/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/EMigunova" -bug-reports: "https://github.com/MigunovaAnastasia1/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/EMigunova/Makefile b/EMigunova/Makefile deleted file mode 100644 index e234db4bf..000000000 --- a/EMigunova/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/language dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/EMigunova/bin/REPL.ml b/EMigunova/bin/REPL.ml deleted file mode 100644 index b2efc3fa8..000000000 --- a/EMigunova/bin/REPL.ml +++ /dev/null @@ -1,68 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EMigunova_lib - -type options = - { mutable dump_parsetree : bool - ; mutable dump_inference : bool - } - -let run_single dump_parsetree dump_inference = - let text = In_channel.(input_all stdin) |> String.trim in - let ast = Parse.parse text in - match ast with - | Error _ -> Format.printf "Syntax error" - | Result.Ok ast -> - if dump_parsetree then Format.printf "%a\n" Ast.pp_structure ast; - if dump_inference - then ( - let infer = Inference.run_inferencer ast in - match infer with - | Error e -> - Printf.printf "Type inference error: "; - Inference.print_error e - | Result.Ok infer_result_list -> - let inter = Interpreter.run_interpreter ast in - (match inter with - | Error e -> Interpreter.print_error e - | Result.Ok inter_result_list -> - Base.List.fold2_exn - infer_result_list - inter_result_list - ~init:() - ~f:(fun () (name, ty) (_, value) -> - Printf.printf "val %s : " name; - Inference.print_type ty; - Printf.printf " = "; - Interpreter.print_value value; - Printf.printf "\n"))); - if not (dump_inference || dump_parsetree) - then ( - match Inference.run_inferencer ast with - | Error _ -> () - | _ -> - let _ = Interpreter.run_interpreter ast in - ()) -;; - -let () = - let options = { dump_parsetree = false; dump_inference = false } in - let () = - let open Stdlib.Arg in - parse - [ ( "--dparsetree" - , Unit (fun () -> options.dump_parsetree <- true) - , "Dump parse tree, don't eval enything" ) - ; ( "--dinference" - , Unit (fun () -> options.dump_inference <- true) - , "Eval and display type inference info" ) - ] - (fun _ -> - Stdlib.Format.eprintf "Anonymous arguments are not supported\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for MiniML Calculus" - in - run_single options.dump_parsetree options.dump_inference -;; diff --git a/EMigunova/bin/dune b/EMigunova/bin/dune deleted file mode 100644 index b4ff2cd1d..000000000 --- a/EMigunova/bin/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (libraries EMigunova_lib)) - -(cram - (deps ./REPL.exe %{bin:REPL})) diff --git a/EMigunova/bin/repl.t b/EMigunova/bin/repl.t deleted file mode 100644 index e38e3ca4f..000000000 --- a/EMigunova/bin/repl.t +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ./REPL.exe -help - Read-Eval-Print-Loop for MiniML Calculus - --dparsetree Dump parse tree, don't eval enything - --dinference Eval and display type inference info - -help Display this list of options - --help Display this list of options diff --git a/EMigunova/dune b/EMigunova/dune deleted file mode 100644 index 98e54536a..000000000 --- a/EMigunova/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/EMigunova/dune-project b/EMigunova/dune-project deleted file mode 100644 index 3f6b334cb..000000000 --- a/EMigunova/dune-project +++ /dev/null @@ -1,35 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Migunova Anastasia ") - -(maintainers "Migunova Anastasia ") - -(bug_reports "https://github.com/MigunovaAnastasia1/fp2024") - -(homepage "https://github.com/MigunovaAnastasia1/fp2024") - -(package - (name EMigunova) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for miniML") - (description - "FIXME. A longer description, for example, which are the most interesting features being supported, etc.") - (documentation "https://kakadu.github.io/fp2024/docs/EMigunova") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files add the same dependecies here too - )) diff --git a/EMigunova/lib/ast.ml b/EMigunova/lib/ast.ml deleted file mode 100644 index f075157d4..000000000 --- a/EMigunova/lib/ast.ml +++ /dev/null @@ -1,98 +0,0 @@ -(** Copyright 2024, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** identidicator *) -type ident = string [@@deriving show { with_path = false }] - -(** constants *) -type constant = - | Const_int of int - | Const_bool of bool - | Const_char of char - | Const_string of string - | Const_unit (** Represents a single value [ () ]*) -[@@deriving show { with_path = false }] - -(** types *) -type ttype = - | Type_int - | Type_bool - | Type_char - | Type_string - | Type_unit - | Type_var of ident (** Represents type variable, e.g. [ 'a ]*) - | Type_option of ttype option (**e.g. [ int option ]*) - | Type_list of ttype (**e.g. [ bool list ]*) - | Type_tuple of ttype list (**e.g. [ int*int*bool ]*) - | Type_arrow of ttype * ttype (**e.g. [ int -> bool ]*) -[@@deriving show { with_path = false }] - -(** patterns *) -type pattern = - | Pattern_any (** The pattern [ _ ]. *) - | Pattern_const of constant (** e.g. [ () ], [ true ], [ 2 ] *) - | Pattern_var of string (** A variable pattern such as [ x ] *) - | Pattern_option of pattern option (** e.g. [ Some x ], [ None ] *) - | Pattern_tuple of pattern list (** Represnts n-tuples (x1, x2, ... ,xn) *) - | Pattern_list_sugar_case of pattern list (** e.g. [ [x1; x2; x3] ] *) - | Pattern_list_constructor_case of pattern list (** e.g. [ x1::x2::[x3;x4] ] *) -[@@deriving show { with_path = false }] - -(** binary operators*) -type binary_op = - | Plus (** [+] *) - | Sub (** [-] *) - | Mul (** [*] *) - | Div (** [/] *) - | And (** [&&]*) - | Or (** [||]*) - | Equal (** [=]*) - | NotEqual (** [<>] or [!=]*) - | Less (** [<]*) - | LessEqual (** [<=]*) - | Greater (** [>]*) - | GreaterEqual (** [>=]*) -[@@deriving show { with_path = false }] - -(** expressions*) -type expression = - | Expr_var of ident (** e.g. [x] *) - | Expr_const of constant (** e.g. [3], [true], ["string"] *) - | Expr_option of expression option (** e.g. [Some (x-3)], [None] *) - | Expr_list_sugar of expression list (** e.g. [ [4;5;6] ] *) - | Expr_list_construct of expression list (** e.g. [ 4::5::6::[] ] *) - | Expr_tuple of expression list (** e.g. [ (x,5+y)) ] *) - | Expr_binary_op of binary_op * expression * expression - (** e.g. [ 2+3 ], [ 23 true | _ -> false] *) - | Expr_construct_in of let_binding * expression (** e.g. [ let x = 4 in x] *) - | Expr_anonym_fun of pattern list * expression (** e.g. [ fun a b -> a + b ] *) - | Expr_function_fun of (pattern * expression) list - (** e.g. [ function | (a,b) -> a+b | _ -> 0] *) - | Expr_application of expression * expression list - (** e.g. [ f a b ] [ (fun a -> a*3) 5 ] [ (function | true -> 1 | false -> 0) x ] *) - | Typed_expression of ttype * expression (** e.g. [ (x : int) ] *) - -(** recursive flag *) -and rec_flag = - | Recursive - | Non_recursive - -(** LHS of let binding comes in two forms: (1) let [ pattern ] = ... ; - (2) let [ fun_id arg1 arg2 ] = ... *) -and let_declaration = - | Let_pattern of pattern - | Let_fun of ident * pattern list - -(** let bindind *) -and let_binding = - | Let_binding of rec_flag * let_declaration * expression - | Let_rec_and_binding of let_binding list -[@@deriving show { with_path = false }] - -(** entire program*) -type structure = let_binding list [@@deriving show { with_path = false }] diff --git a/EMigunova/lib/dune b/EMigunova/lib/dune deleted file mode 100644 index ce2300b5c..000000000 --- a/EMigunova/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name EMigunova_lib) - (public_name EMigunova.Lib) - (modules Ast Parse Inference Interpreter) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/EMigunova/lib/inference.ml b/EMigunova/lib/inference.ml deleted file mode 100644 index f9ec6b527..000000000 --- a/EMigunova/lib/inference.ml +++ /dev/null @@ -1,951 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -let rec print_type (ty : ttype) = - match ty with - | Type_int -> Printf.printf "int" - | Type_bool -> Printf.printf "bool" - | Type_char -> Printf.printf "char" - | Type_string -> Printf.printf "string" - | Type_unit -> Printf.printf "unit" - | Type_var ident -> Printf.printf "%s" ident - | Type_option (Some ty) -> - (match ty with - | Type_tuple _ -> - Printf.printf "("; - print_type ty; - Printf.printf ")" - | _ -> print_type ty); - Printf.printf " option" - | Type_option None -> () - | Type_list ty -> - (match ty with - | Type_tuple _ -> - Printf.printf "("; - print_type ty; - Printf.printf ")" - | _ -> print_type ty); - Printf.printf " list" - | Type_tuple ty_list -> - (match ty_list with - | first :: second :: rest -> - (match first with - | Type_arrow _ | Type_tuple _ -> - Printf.printf "("; - print_type first; - Printf.printf ")" - | _ -> print_type first); - Printf.printf "*"; - print_type (Type_tuple (second :: rest)) - | single :: [] -> - (match single with - | Type_arrow _ | Type_tuple _ -> - Printf.printf "("; - print_type single; - Printf.printf ")" - | _ -> print_type single) - | _ -> ()) - | Type_arrow (ty1, ty2) -> - (match ty1 with - | Type_arrow _ -> - Printf.printf "("; - print_type ty1; - Printf.printf ")" - | _ -> print_type ty1); - Printf.printf "->"; - print_type ty2 -;; - -type error = - [ `No_variable_rec - | `No_arg_rec - | `Bound_several_times of string - | `Occurs_check of string * ttype (* * core_type *) - | `No_variable of string - | `Unification_failed of string * ttype * ttype (* of core_type * core_type *) - ] - -let print_error (e : error) = - match e with - | `No_variable_rec -> - Printf.printf - "Recursive binding failed: a function was expected as the RHS. Recursive binding \ - is impossible for that variable. It would lead to infinite recursion." - | `No_arg_rec -> - Printf.printf - "Recursive binding failed: the LHS of the recursive binding must not be a composed \ - pattern (e.g. tuple, list, etc.). A variable is required." - | `Bound_several_times id -> - Printf.printf - "Binding faild: simultaneous binding of one identifier to several values. The \ - identifier that was bound several times: '%s'." - id - | `Occurs_check (id, ty) -> - Printf.printf "Occurs check failed: the type variable %s occurs inside" id; - print_type ty - | `No_variable id -> Printf.printf "Undefined variable '%s'" id - | `Unification_failed (id, ty1, ty2) -> - Printf.printf "Unification( %s ) failed for following unifiable types: " id; - print_type ty1; - Printf.printf " and "; - print_type ty2 -;; - -module State = struct - open Base - - type 'a t = int -> int * ('a, error) Result.t - - let return x state = state, Result.return x - let fail e state = state, Result.fail e - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> f result state - | state, Result.Error e -> fail e state - ;; - - module Syntax = struct - let ( let* ) = ( >>= ) - end - - let ( >>| ) (monad : 'a t) (f : 'a -> 'b) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> return (f result) state - | state, Result.Error e -> fail e state - ;; - - module RList = struct - let fold_left xs ~init ~f = - List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_right xs ~init ~f = - List.fold_right xs ~init ~f:(fun x acc -> - let open Syntax in - let* acc = acc in - f x acc) - ;; - end - - module RMap = struct - let fold map ~init ~f = - Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - let fresh state = state + 1, Result.Ok state - let run monad = snd (monad 0) -end - -module VarSet = struct - include Set.Make (String) -end - -type scheme = Scheme of VarSet.t * ttype - -module Type = struct - (*gets type_core and returns set of idents of all type_core's type variables *) - let free_vars = - let rec helper acc = function - | Type_option (Some ty) | Type_list ty -> helper acc ty - | Type_var name -> VarSet.add name acc - | Type_tuple ty_list -> List.fold_left helper acc ty_list - | Type_arrow (ty1, ty2) -> VarSet.union (helper acc ty1) (helper acc ty2) - | _ -> acc - in - helper VarSet.empty - ;; - - (*gets the identifier and core_type and checks whether a type variable with this identifier occurs in the type*) - let occurs_in var ty = VarSet.mem var (free_vars ty) -end - -module Subst = struct - open State - open State.Syntax - open Base - - let empty = Map.empty (module String) - let singleton1 = Map.singleton (module String) - - (*gets some name of type variable and core_type and checks if an name doesn't occur in a type (bad case of infinite loop) - and returns wrapped sub*) - let singleton key value = - match value with - | Type_var id when String.equal key id -> return empty - | _ -> - if Type.occurs_in key value - then fail (`Occurs_check (key, value)) - else return (Map.singleton (module String) key value) - ;; - - let remove = Map.remove - - (*gets substitution and core_type then performs a substitution and returns new concretized core_type*) - let apply sub = - let rec helper = function - | Type_var name as ty -> - (match Map.find sub name with - | Some ty -> ty - | None -> ty) - | Type_option (Some ty) -> Type_option (Some (helper ty)) - | Type_list ty -> Type_list (helper ty) - | Type_tuple ty_list -> Type_tuple (List.map ty_list ~f:helper) - | Type_arrow (ty1, ty2) -> Type_arrow (helper ty1, helper ty2) - | ty -> ty - in - helper - ;; - - let rec unify (debug_info : string) (l : ttype) (r : ttype) = - match l, r with - | Type_unit, Type_unit - | Type_int, Type_int - | Type_char, Type_char - | Type_string, Type_string - | Type_bool, Type_bool - | Type_option None, Type_option None - | Type_option (Some _), Type_option None - | Type_option None, Type_option (Some _) -> return empty - | Type_var l, Type_var r when String.equal l r -> return empty - | Type_var name, ty | ty, Type_var name -> singleton name ty - | Type_list ty1, Type_list ty2 | Type_option (Some ty1), Type_option (Some ty2) -> - unify "list_unify" ty1 ty2 - | Type_tuple list1, Type_tuple list2 -> - let rec helper acc = function - | first_ty1 :: rest1, first_ty2 :: rest2 -> - let* acc_sub = acc in - let* unified_sub = - unify "tuple_unify" (apply acc_sub first_ty1) (apply acc_sub first_ty2) - in - helper (compose acc_sub unified_sub) (rest1, rest2) - | [], [] -> acc - | _ -> fail (`Unification_failed (debug_info, l, r)) - (*considering case when list1 and list2 have different lengths*) - in - helper (return empty) (list1, list2) - | Type_arrow (arg1, res1), Type_arrow (arg2, res2) -> - let* unified_sub1 = unify "([type1] -> [...]) and ([type2] -> [...])" arg1 arg2 in - let* unified_sub2 = - unify "arrow_unify_result" (apply unified_sub1 res1) (apply unified_sub1 res2) - in - compose unified_sub1 unified_sub2 - | _ -> fail (`Unification_failed (debug_info, l, r)) - - and extend key value sub = - match Map.find sub key with - | None -> - let value = apply sub value in - let* new_sub = singleton key value in - Map.fold sub ~init:(return new_sub) ~f:(fun ~key ~data acc -> - let* acc = acc in - let new_data = apply new_sub data in - return (Map.update acc key ~f:(fun _ -> new_data))) - | Some existing_value -> - let* new_sub = unify "extend sub" value existing_value in - compose sub new_sub - - and compose sub1 sub2 = RMap.fold sub2 ~init:(return sub1) ~f:extend - - let compose_all sub_list = RList.fold_left sub_list ~init:(return empty) ~f:compose -end - -module Scheme = struct - let free_vars (Scheme (bind_set, ty)) = VarSet.diff (Type.free_vars ty) bind_set - - let apply sub (Scheme (bind_set, ty)) = - let new_sub = VarSet.fold (fun key sub -> Subst.remove sub key) bind_set sub in - let new_ty = Subst.apply new_sub ty in - let is_generalized_type_var id = not (Base.String.is_prefix ~prefix:"'ty" id) in - let rec extract_id_from_ty acc_set = function - | Type_var id -> VarSet.add id acc_set - | Type_option (Some ty) -> extract_id_from_ty acc_set ty - | Type_tuple ty_list -> - Base.List.fold_left ty_list ~init:acc_set ~f:(fun acc_set ty -> - extract_id_from_ty acc_set ty) - | Type_list ty -> extract_id_from_ty acc_set ty - | Type_arrow (ty1, ty2) -> extract_id_from_ty (extract_id_from_ty acc_set ty1) ty2 - | _ -> acc_set - in - let new_bind_set = - VarSet.fold - (fun id new_bind_set -> - if is_generalized_type_var id then VarSet.add id new_bind_set else new_bind_set) - (extract_id_from_ty VarSet.empty new_ty) - VarSet.empty - in - Scheme (new_bind_set, new_ty) - ;; -end - -module TypeEnv = struct - open Base - - type t = (ident, scheme, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let rec extend_with_pattern env_acc pat (Scheme (bind_set, ty) as scheme) = - match pat, ty with - | Pattern_var id, _ -> extend env_acc id scheme - | Pattern_tuple pat_list, Type_tuple ty_list -> - (match pat_list, ty_list with - | first_pat :: pat_rest, first_ty :: ty_rest -> - let new_acc_env = - extend_with_pattern env_acc first_pat (Scheme (bind_set, first_ty)) - in - extend_with_pattern - new_acc_env - (Pattern_tuple pat_rest) - (Scheme (bind_set, Type_tuple ty_rest)) - | _ -> env_acc) - | Pattern_list_sugar_case pat_list, Type_list ty -> - Base.List.fold_left pat_list ~init:env_acc ~f:(fun env_acc pat -> - extend_with_pattern env_acc pat (Scheme (bind_set, ty))) - | Pattern_list_constructor_case pat_list, Type_list ty -> - (match pat_list with - | single_pat :: [] -> - extend_with_pattern env_acc single_pat (Scheme (bind_set, Type_list ty)) - | first :: rest -> - extend_with_pattern - (extend_with_pattern env_acc first (Scheme (bind_set, ty))) - (Pattern_list_constructor_case rest) - (Scheme (bind_set, Type_list ty)) - | [] -> env_acc) - | Pattern_option (Some pat), Type_option (Some ty) -> - extend_with_pattern env_acc pat (Scheme (bind_set, ty)) - | _ -> env_acc - ;; - - let free_vars env = - Map.fold env ~init:VarSet.empty ~f:(fun ~key:_ ~data acc -> - VarSet.union acc (Scheme.free_vars data)) - ;; - - let apply sub env = Map.map env ~f:(Scheme.apply sub) - let find = Map.find - - let find_type_exn env key = - let (Scheme (_, ty)) = Map.find_exn env key in - ty - ;; -end - -module Infer = struct - open Ast - open State - open State.Syntax - - let unify = Subst.unify - let fresh_var = fresh >>| fun n -> Type_var ("'ty" ^ Int.to_string n) - - let fresh_var_instantiate id = - (*e.g. 'ty3instantiate_'a *) - fresh >>| fun n -> Type_var (Printf.sprintf "%s%dinstantiate_%s" "'ty" n id) - ;; - - let instantiate (Scheme (bind_set, ty)) = - VarSet.fold - (fun name ty -> - let* ty = ty in - let* fresh = fresh_var_instantiate name in - let* sub = Subst.singleton name fresh in - return (Subst.apply sub ty)) - bind_set - (return ty) - ;; - - let generalize ~only_instantiated env ty = - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - let new_free, new_ty, _ = - VarSet.fold - (fun str (temp_free, temp_ty, n) -> - let degree = n / 26 in - let new_str = - if Base.String.is_substring ~substring:"instantiate" str - then ( - let index = String.index str '_' in - String.sub str (index + 1) (String.length str - (index + 1))) - else if only_instantiated - then str - else - (* 97 - is number 'a' in ASCII-table *) - Printf.sprintf - "'%c%s" - (Char.chr (97 + (n mod 26))) - (if degree = 0 then "" else Int.to_string degree) - (*new_str : 'a, ... ,'z, 'a1, ... ,'z1, ...*) - in - let sub = Subst.singleton1 str (Type_var new_str) in - let new_free = VarSet.add new_str temp_free in - let new_ty = Subst.apply sub temp_ty in - new_free, new_ty, n + 1) - free - (VarSet.empty, ty, 0) - in - Scheme (new_free, new_ty) - ;; - - let rec extract_names_from_pat f acc = function - | Pattern_var id -> f acc id - | Pattern_option (Some pat) -> extract_names_from_pat f acc pat - | Pattern_tuple pat_list - | Pattern_list_sugar_case pat_list - | Pattern_list_constructor_case pat_list -> - (match pat_list with - | [] -> return acc - | first_pat :: rest_pats -> - let* acc = extract_names_from_pat f acc first_pat in - extract_names_from_pat f acc (Pattern_tuple rest_pats)) - | _ -> return acc - ;; - - module StringSet = struct - include Set.Make (String) - - let add_id set value = - if mem value set then fail (`Bound_several_times value) else return (add value set) - ;; - end - - let rec remove_patterns_from_env env = function - | [] -> return env - | pat :: rest_pats -> - let* env = - extract_names_from_pat (fun env id -> return (Base.Map.remove env id)) env pat - in - remove_patterns_from_env env rest_pats - ;; - - let check_names_from_pat pat = - extract_names_from_pat StringSet.add_id StringSet.empty pat - ;; - - let rec infer_pattern env pat = - let* _ = check_names_from_pat pat in - match pat with - | Pattern_any -> - let* fresh_type_var = fresh_var in - return (env, fresh_type_var) - | Pattern_var id -> - let* fresh_type_var = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh_type_var)) in - return (env, fresh_type_var) - | Pattern_const const -> - (match const with - | Const_int _ -> return (env, Type_int) - | Const_string _ -> return (env, Type_string) - | Const_char _ -> return (env, Type_char) - | Const_bool _ -> return (env, Type_bool) - | Const_unit -> return (env, Type_unit)) - | Pattern_tuple pat_list -> - let* env, list_of_types = - RList.fold_right - pat_list - ~init:(return (env, [])) - ~f:(fun element (env, list_of_types) -> - let* new_env, element_type = infer_pattern env element in - return (new_env, element_type :: list_of_types)) - in - return (env, Type_tuple list_of_types) - | Pattern_option None -> return (env, Type_option None) - | Pattern_option (Some pat) -> - let* env, type_of_pat = infer_pattern env pat in - return (env, Type_option (Some type_of_pat)) - | Pattern_list_sugar_case pat_list -> - let* list_element_type_var = fresh_var in - let* env, sub = - RList.fold_left - pat_list - ~init:(return (env, Subst.empty)) - ~f:(fun (acc_env, acc_sub) pat -> - let* env, pat_type = infer_pattern acc_env pat in - let* unified_sub = - unify "infer pattern list sugar" list_element_type_var pat_type - in - let* composed_sub = Subst.compose unified_sub acc_sub in - return (env, composed_sub)) - in - let list_element_type = Subst.apply sub list_element_type_var in - let env = TypeEnv.apply sub env in - return (env, Type_list list_element_type) - | Pattern_list_constructor_case pat_list -> - let* fresh = fresh_var in - let rec helper env sub_acc rest = - match rest with - | [] -> return (env, sub_acc) - | single :: [] -> - let* env, ty = infer_pattern env single in - let* unified_sub = unify "" (Type_list fresh) ty in - let* composed_sub = Subst.compose sub_acc unified_sub in - helper env composed_sub [] - | first :: rest -> - let* env, ty = infer_pattern env first in - let* unified_sub = unify "" fresh ty in - let* composed_sub = Subst.compose sub_acc unified_sub in - helper env composed_sub rest - in - let* env, sub = helper env Subst.empty pat_list in - let result_ty = Subst.apply sub fresh in - return (env, Type_list result_ty) - ;; - - let rec get_pat_type_from_env env = function - | Pattern_var id -> return (TypeEnv.find_type_exn env id) - | Pattern_any -> fresh_var - | Pattern_const const -> - (match const with - | Const_int _ -> return Type_int - | Const_string _ -> return Type_string - | Const_char _ -> return Type_char - | Const_bool _ -> return Type_bool - | Const_unit -> return Type_unit) - | Pattern_option (Some pat) -> - let* ty = get_pat_type_from_env env pat in - return (Type_option (Some ty)) - | Pattern_tuple pat_list -> - let* ty_list = - RList.fold_left pat_list ~init:(return []) ~f:(fun acc_list pat -> - let* ty = get_pat_type_from_env env pat in - return (acc_list @ [ ty ])) - in - return (Type_tuple ty_list) - | Pattern_list_sugar_case (first_pat :: _) - | Pattern_list_constructor_case (first_pat :: _) -> - let* ty = get_pat_type_from_env env first_pat in - return (Type_list ty) - | _ -> return (Type_option None) - ;; - - let extend_env_with_args env args_list = - RList.fold_right - args_list - ~init:(return (env, [])) - ~f:(fun pat (env, pat_ty_list) -> - let* env, pat_ty = infer_pattern env pat in - return (env, pat_ty :: pat_ty_list)) - ;; - - (*this function is called when we deal with recursive bindings. - And our language forbids recursive values*) - let extend_env_with_bind_names env let_binding_list = - RList.fold_left let_binding_list ~init:(return env) ~f:(fun env -> - function - | Let_binding (_, Let_fun (id, _), _) -> - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return env - | Let_binding (_, Let_pattern (Pattern_var id), Expr_anonym_fun (_, _)) - | Let_binding (_, Let_pattern (Pattern_var id), Expr_function_fun _) -> - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return env - | Let_binding (_, Let_pattern (Pattern_var _), _) -> fail `No_variable_rec - | _ -> fail `No_arg_rec) - ;; - - let rec check_names_from_let_binds = - RList.fold_left ~init:(return StringSet.empty) ~f:(fun set_acc -> - function - | Let_binding (_, Let_fun (fun_identifier, _), _) -> - StringSet.add_id set_acc fun_identifier - | Let_binding (_, Let_pattern pat, _) -> - extract_names_from_pat StringSet.add_id set_acc pat - | Let_rec_and_binding let_binding_list -> - let* let_rec_and_acc = check_names_from_let_binds let_binding_list in - return (StringSet.union set_acc let_rec_and_acc)) - ;; - - let rec get_names_from_let_bind env = function - | Let_binding (_, Let_pattern pat, _) -> - extract_names_from_pat - (fun acc id -> return (acc @ [ id, TypeEnv.find_type_exn env id ])) - [] - pat - | Let_binding (_, Let_fun (id, _), _) -> - extract_names_from_pat - (fun acc id -> return (acc @ [ id, TypeEnv.find_type_exn env id ])) - [] - (Pattern_var id) - | Let_rec_and_binding let_binding_list -> - RList.fold_left - let_binding_list - ~init:(return []) - ~f:(fun result_list let_binding -> - let* last_element = get_names_from_let_bind env let_binding in - return (result_list @ last_element)) - ;; - - let lookup_env id env = - match TypeEnv.find env id with - | Some scheme -> - let* ans = instantiate scheme in - return (Subst.empty, ans) - | None -> fail (`No_variable id) - ;; - - let rec infer_expression env = function - | Expr_var id -> lookup_env id env - | Expr_const const -> - (match const with - | Const_int _ -> return (Subst.empty, Type_int) - | Const_string _ -> return (Subst.empty, Type_string) - | Const_char _ -> return (Subst.empty, Type_char) - | Const_bool _ -> return (Subst.empty, Type_bool) - | Const_unit -> return (Subst.empty, Type_unit)) - | Expr_construct_in (let_binding, expression) -> - (match let_binding with - | Let_binding (Non_recursive, _, _) -> - let* env, sub = infer_value_non_rec_binding env let_binding in - let* expr_sub, expr_ty = infer_expression env expression in - let* composed_sub = Subst.compose sub expr_sub in - return (composed_sub, expr_ty) - | Let_binding (Recursive, _, _) | Let_rec_and_binding _ -> - let let_binding_list = - match let_binding with - | Let_rec_and_binding let_binding_list -> let_binding_list - | _ -> let_binding :: [] - in - let* env = extend_env_with_bind_names env let_binding_list in - let* env, sub1 = infer_rec_value_binding_list env Subst.empty let_binding_list in - let* sub2, ty2 = infer_expression env expression in - let* composed_sub = Subst.compose sub2 sub1 in - return (composed_sub, ty2)) - | Expr_anonym_fun (first_pat :: rest_pats, expr) -> - let* env, ty1 = infer_pattern env first_pat in - let* sub, ty2 = - match rest_pats with - | [] -> infer_expression env expr - | hd :: tl -> infer_expression env (Expr_anonym_fun (hd :: tl, expr)) - in - return (sub, Type_arrow (Subst.apply sub ty1, ty2)) - | Expr_binary_op (bin_op, exp1, exp2) -> - let* sub1, ty1 = infer_expression env exp1 in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) exp2 in - let* required_arg_ty, required_result_ty = - match bin_op with - | Plus | Sub | Mul | Div -> return (Type_int, Type_int) - | Equal | NotEqual | Less | LessEqual | Greater | GreaterEqual -> - let* fresh = fresh_var in - return (fresh, Type_bool) - | _ -> return (Type_bool, Type_bool) - in - let* unified_sub1 = - Subst.unify "expr binary op1" required_arg_ty (Subst.apply sub2 ty1) - in - let* unified_sub2 = - Subst.unify "expr binary op2" required_arg_ty (Subst.apply unified_sub1 ty2) - in - let* composed_sub = Subst.compose_all [ sub1; sub2; unified_sub1; unified_sub2 ] in - let* sub_expr1_type = unify "" ty1 (Subst.apply composed_sub required_arg_ty) in - let* sub_expr2_type = unify "" ty2 (Subst.apply composed_sub required_arg_ty) in - let* composed_sub = - Subst.compose_all [ sub_expr1_type; sub_expr2_type; composed_sub ] - in - return (composed_sub, required_result_ty) - | Expr_application (expr, expr_list) -> - let* fresh = fresh_var in - let rec build_arrow_chain expression_list = - match expression_list with - | first_expr :: [] -> - let* sub, ty = infer_expression env first_expr in - return (sub, Type_arrow (ty, fresh)) - | first_expr :: expression_list -> - let* sub1, ty1 = build_arrow_chain expression_list in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) first_expr in - let* composed_sub = Subst.compose sub1 sub2 in - return (composed_sub, Subst.apply composed_sub (Type_arrow (ty2, ty1))) - | [] -> return (Subst.empty, Type_option None) - in - let* args_sub, required_ty = build_arrow_chain expr_list in - let* expr_sub, expr_ty = infer_expression (TypeEnv.apply args_sub env) expr in - let* unified_sub = - unify "fun application " expr_ty (Subst.apply expr_sub required_ty) - in - let* composed_sub = Subst.compose_all [ unified_sub; expr_sub; args_sub ] in - let final_ty = Subst.apply composed_sub fresh in - return (composed_sub, final_ty) - | Expr_function_fun case_list -> - let* fresh_for_matching = fresh_var in - let* fresh_for_result = fresh_var in - infer_match_exp - env - ~with_exp:false - Subst.empty - fresh_for_matching - fresh_for_result - case_list - | Expr_match_with (expr, case_list) -> - let* expr_sub, expr_ty = infer_expression env expr in - let env = TypeEnv.apply expr_sub env in - let* fresh_for_result = fresh_var in - infer_match_exp env ~with_exp:true expr_sub expr_ty fresh_for_result case_list - | Expr_tuple expr_list -> - let* sub, ty_list = - RList.fold_right - ~f:(fun expr (sub_acc, ty_list) -> - let* sub, ty = infer_expression (TypeEnv.apply sub_acc env) expr in - let* sub_acc = Subst.compose sub_acc sub in - return (sub_acc, ty :: ty_list)) - ~init:(return (Subst.empty, [])) - expr_list - in - let result_ty = Subst.apply sub (Type_tuple ty_list) in - return (sub, result_ty) - | Expr_list_construct expr_list -> - let* fresh = fresh_var in - let rec infer_list_constract env acc_sub = function - | [] -> return (Subst.empty, Type_option None) - | end_element :: [] -> - let* expr_sub, expr_ty = infer_expression env end_element in - let* unified_sub = unify "expr list construct end" expr_ty (Type_list fresh) in - let* composed_sub = Subst.compose_all [ expr_sub; unified_sub; acc_sub ] in - return (composed_sub, Type_list (Subst.apply composed_sub fresh)) - | expr_element :: expr_rest -> - let* expr_sub, expr_ty = infer_expression env expr_element in - let* unified_sub = unify "expr list construct element" expr_ty fresh in - let* composed_sub = Subst.compose_all [ expr_sub; unified_sub; acc_sub ] in - let env = TypeEnv.apply composed_sub env in - let* sub, ty = infer_list_constract env composed_sub expr_rest in - return (sub, ty) - in - infer_list_constract env Subst.empty expr_list - | Expr_list_sugar expr_list -> - let* fresh = fresh_var in - let* sub = - RList.fold_left expr_list ~init:(return Subst.empty) ~f:(fun acc_sub expr -> - let* expr_sub, expr_type = infer_expression (TypeEnv.apply acc_sub env) expr in - let* unified_sub = - unify - "expr list sugar" - expr_type - (Subst.apply acc_sub (Subst.apply expr_sub fresh)) - in - let* composed_sub = Subst.compose_all [ acc_sub; unified_sub; expr_sub ] in - return composed_sub) - in - let fresh = Subst.apply sub fresh in - return (sub, Type_list fresh) - | Expr_option None -> return (Subst.empty, Type_option None) - | Expr_option (Some expr) -> - let* sub, ty = infer_expression env expr in - return (sub, Type_option (Some ty)) - | Expr_if_then_else (if_expr, then_expr, else_expr) -> - let* sub1, ty1 = infer_expression env if_expr in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) then_expr in - let* sub3, ty3 = - infer_expression (TypeEnv.apply sub2 (TypeEnv.apply sub1 env)) else_expr - in - let* sub4 = unify "if (here) then else" ty1 Type_bool in - let* sub5 = unify "if _ then [first type] else [second type]" ty2 ty3 in - let* final_sub = Subst.compose_all [ sub5; sub4; sub3; sub2; sub1 ] in - return (final_sub, Subst.apply final_sub ty2) - | Typed_expression (ty, expr) -> - let* expr_sub, expr_ty = infer_expression env expr in - let* unified_sub = unify "typed expression" expr_ty ty in - let* final_sub = Subst.compose unified_sub expr_sub in - return (final_sub, Subst.apply unified_sub expr_ty) - | _ -> return (Subst.empty, Type_option None) - - and infer_match_exp env ~with_exp match_exp_sub match_exp_ty result_ty case_list = - let* cases_sub, case_ty = - RList.fold_left - case_list - ~init:(return (match_exp_sub, result_ty)) - ~f:(fun (sub_acc, ty_acc) (pat, case_exp) -> - let* env, pat_sub = - if with_exp - then ( - let env = TypeEnv.apply sub_acc env in - let* _, pat_ty = infer_pattern env pat in - let* unified_sub1 = - unify - "infer_match_exp, match expression" - pat_ty - (Subst.apply sub_acc match_exp_ty) - in - let gen_pat_ty_sch = - generalize ~only_instantiated:true env (Subst.apply unified_sub1 pat_ty) - in - let env = TypeEnv.extend_with_pattern env pat gen_pat_ty_sch in - return (env, unified_sub1)) - else - let* env, pat_ty = infer_pattern env pat in - let* unified_sub1 = unify "" pat_ty match_exp_ty in - let env = TypeEnv.apply unified_sub1 env in - return (env, unified_sub1) - in - let* composed_sub1 = Subst.compose sub_acc pat_sub in - let* case_exp_sub, case_exp_ty = - infer_expression (TypeEnv.apply composed_sub1 env) case_exp - in - let* unified_sub2 = - unify "infer_match_exp, result expression" ty_acc case_exp_ty - in - let* composed_sub2 = - Subst.compose_all [ composed_sub1; case_exp_sub; unified_sub2 ] - in - return (composed_sub2, Subst.apply composed_sub2 ty_acc)) - in - let final_ty = - if with_exp - then case_ty - else Type_arrow (Subst.apply cases_sub match_exp_ty, case_ty) - in - return (cases_sub, final_ty) - - and infer_value_non_rec_binding env = function - | Let_binding (Non_recursive, Let_fun (id, pattern_list), expr) -> - let* env, _ = extend_env_with_args env pattern_list in - let* expr_sub, expr_ty = infer_expression env expr in - let env = TypeEnv.apply expr_sub env in - let* let_bind_ty = - let rec build_arrow_chain = function - | single_ty :: [] -> Type_arrow (single_ty, expr_ty) - | first_ty :: rest -> Type_arrow (first_ty, build_arrow_chain rest) - | _ -> expr_ty - in - let* pat_types = - RList.fold_left pattern_list ~init:(return []) ~f:(fun acc_list pat -> - let* pat_ty = get_pat_type_from_env env pat in - return (acc_list @ [ pat_ty ])) - in - return (build_arrow_chain pat_types) - in - let* env = remove_patterns_from_env env pattern_list in - let generalized_let_bind_ty = generalize ~only_instantiated:false env let_bind_ty in - let env = TypeEnv.extend env id generalized_let_bind_ty in - return (env, expr_sub) - | Let_binding (Non_recursive, Let_pattern pat, expr) -> - let* expr_sub, expr_ty = infer_expression env expr in - let env = TypeEnv.apply expr_sub env in - let* _, pat_ty = infer_pattern env pat in - let* unified_sub1 = unify "let binding with pattern" expr_ty pat_ty in - let env = TypeEnv.apply unified_sub1 env in - let let_pat_ty_sch = - generalize ~only_instantiated:false env (Subst.apply unified_sub1 expr_ty) - in - let (Scheme (_, let_pat_ty)) = let_pat_ty_sch in - let* env, init_pat_ty = infer_pattern env pat in - let* unified_sub2 = unify "" init_pat_ty let_pat_ty in - let env = TypeEnv.apply unified_sub1 env in - let env = TypeEnv.extend_with_pattern env pat let_pat_ty_sch in - let* composed_sub = Subst.compose_all [ unified_sub1; unified_sub2; expr_sub ] in - return (env, composed_sub) - | Let_binding (Recursive, _, _) | Let_rec_and_binding _ -> return (env, Subst.empty) - - and infer_rec_value_binding_list env sub let_binds = - let infer_rec_vb env new_sub ty id pattern_list rest = - let env = TypeEnv.apply new_sub env in - let infered_let_bind_type = TypeEnv.find_type_exn env id in - (*this type was infered during infering RSH of rec let_biding*) - let* manual_let_bind_ty = - (*this type is built by us manually*) - let rec build_arrow_chain = function - | single_ty :: [] -> Type_arrow (single_ty, ty) - | first_ty :: rest -> Type_arrow (first_ty, build_arrow_chain rest) - | [] -> infered_let_bind_type - in - let* pat_types = - RList.fold_right pattern_list ~init:(return []) ~f:(fun pat pat_ty_list -> - let* pat_ty = get_pat_type_from_env env pat in - return (pat_ty :: pat_ty_list)) - in - return (build_arrow_chain pat_types) - in - let* unified_sub = - unify "rec let binding" manual_let_bind_ty infered_let_bind_type - in - let* composed_sub = Subst.compose_all [ new_sub; unified_sub; sub ] in - let* env = remove_patterns_from_env env (Pattern_var id :: pattern_list) in - let generalized_let_bind_sch = - generalize - ~only_instantiated:false - env - (Subst.apply composed_sub manual_let_bind_ty) - in - let env = TypeEnv.extend env id generalized_let_bind_sch in - infer_rec_value_binding_list (TypeEnv.apply composed_sub env) composed_sub rest - in - match let_binds with - | [] -> return (env, sub) - | Let_binding - ( Recursive - , Let_fun (id, []) - , ((Expr_anonym_fun (_, _) | Expr_function_fun _) as expr) ) - :: rest -> - let* new_sub, ty = infer_expression env expr in - infer_rec_vb env new_sub ty id [] rest - | Let_binding (Recursive, Let_fun (_, []), _) :: _ -> fail `No_variable_rec - | Let_binding (Recursive, Let_fun (id, pattern_list), expr) :: rest -> - let* env, _ = extend_env_with_args env pattern_list in - let* expr_sub, ty = infer_expression env expr in - infer_rec_vb env expr_sub ty id pattern_list rest - | _ -> fail `No_variable_rec - - and infer_let_biding (env, out_list) let_binding = - match let_binding with - | Let_binding (Non_recursive, _, _) -> - let* env, _ = infer_value_non_rec_binding env let_binding in - let* id_list = get_names_from_let_bind env let_binding in - return (env, out_list @ id_list) - | Let_binding (Recursive, _, _) -> - let* env = extend_env_with_bind_names env (let_binding :: []) in - let* env, _ = infer_rec_value_binding_list env Subst.empty (let_binding :: []) in - let* id_list = get_names_from_let_bind env let_binding in - return (env, out_list @ id_list) - | Let_rec_and_binding biding_list -> - let* _ = check_names_from_let_binds biding_list in - let* env = extend_env_with_bind_names env biding_list in - let* env, _ = infer_rec_value_binding_list env Subst.empty biding_list in - let* id_list = - RList.fold_left biding_list ~init:(return []) ~f:(fun result_list let_binding -> - let* last_element = get_names_from_let_bind env let_binding in - return (result_list @ last_element)) - in - return (env, out_list @ id_list) - ;; - - let infer_srtucture env ast = - let* _, out_list = RList.fold_left ast ~init:(return (env, [])) ~f:infer_let_biding in - let rec remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (id1, _), (id2, _) -> String.equal id1 id2 - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> - x :: remove_duplicates xs - | _ :: xs -> remove_duplicates xs - | [] -> [] - in - return (remove_duplicates out_list) - ;; -end - -let env_with_print_funs = - let print_fun_list = - [ "print_int", Scheme (VarSet.empty, Type_arrow (Type_int, Type_unit)) - ; "print_endline", Scheme (VarSet.empty, Type_arrow (Type_string, Type_unit)) - ] - in - List.fold_left - (fun env (id, sch) -> TypeEnv.extend env id sch) - TypeEnv.empty - print_fun_list -;; - -let run_inferencer ast = State.run (Infer.infer_srtucture env_with_print_funs ast) diff --git a/EMigunova/lib/inference.mli b/EMigunova/lib/inference.mli deleted file mode 100644 index cfd044220..000000000 --- a/EMigunova/lib/inference.mli +++ /dev/null @@ -1,43 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `No_variable_rec - (** Represents an error where a recursive variable is not allowed because that would lead to infinite recursion. - E.g. [let rec x = x + 1] *) - | `No_arg_rec - (** Represents an error where the left-hand side of the recursive binding is not a var. - E.g. [let rec [ a; b ] = ..] *) - | `Bound_several_times of string - (** Represents an error where a pattern bound the variable multiple times. - E.g. [let x, x = ..] *) - | `Occurs_check of string * ttype - (** Represents an occurs check failure. - This occurs when attempting to unify types, and one type is found to occur within another in a way that violates the rules of type systems. - E.g. [let rec f x = f] *) - | `No_variable of string - (** Represents an error indicating that a variable could not be found in the current scope. *) - | `Unification_failed of string * ttype * ttype - (** Represents that type unification has failed. - This occurs when two types cannot made equivalent during type inference. *) - ] - -(*val pp_error : Format.formatter -> error -> unit*) - -module VarSet : sig - type t = Set.Make(String).t -end - -type scheme = Scheme of VarSet.t * ttype - -module TypeEnv : sig - type t = (ident, scheme, Base.String.comparator_witness) Base.Map.t -end - -val env_with_print_funs : TypeEnv.t -val print_error : error -> unit -val print_type : ttype -> unit -val run_inferencer : let_binding list -> ((ident * ttype) list, error) result diff --git a/EMigunova/lib/interpreter.ml b/EMigunova/lib/interpreter.ml deleted file mode 100644 index 16638dbdc..000000000 --- a/EMigunova/lib/interpreter.ml +++ /dev/null @@ -1,471 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `Type_error - | `Division_by_zero - | `Match_failure - | `Too_many_args_for_anonym_fun - | `Too_many_args_for_fun of string - | `No_variable of string - ] - -let print_error (e : error) = - match e with - | `Type_error -> Printf.printf "Type error" - | `Division_by_zero -> Printf.printf "Division by zero" - | `Match_failure -> Printf.printf "Matching failure" - | `Too_many_args_for_fun id -> Printf.printf "Too many arguments for function '%s'" id - | `Too_many_args_for_anonym_fun -> - Printf.printf "Too many arguments for anonym function" - | `No_variable id -> Printf.printf "Undefined variable '%s'" id -;; - -type value = - | Val_integer of int - | Val_char of char - | Val_string of string - | Val_unit - | Val_bool of bool - | Val_fun of rec_flag * ident list option * pattern list * expression * env - | Val_function of (pattern * expression) list * env - | Val_tuple of value list - | Val_list of value list - | Val_option of value option - | Val_builtin of string - -and env = (string, value, Base.String.comparator_witness) Base.Map.t - -let rec print_value = function - | Val_integer int -> Printf.printf "%i" int - | Val_char char -> Printf.printf "'%c'" char - | Val_string str -> Printf.printf "%S" str - | Val_unit -> Printf.printf "()" - | Val_bool bool -> Printf.printf "%b" bool - | Val_tuple val_list -> - Printf.printf "("; - let rec help = function - | first :: [] -> print_value first - | first :: rest -> - print_value first; - Printf.printf ", "; - help rest - | _ -> () - in - help val_list; - Printf.printf ")" - | Val_fun _ -> Printf.printf "" - | Val_function _ -> Printf.printf "" - | Val_list val_list -> - let rec help = function - | [] -> () - | single :: [] -> print_value single - | first :: rest -> - print_value first; - Printf.printf "; "; - help rest - in - Printf.printf "["; - help val_list; - Printf.printf "]" - | Val_option value -> - (match value with - | Some value -> - Printf.printf "Some "; - print_value value - | None -> Printf.printf "None") - | Val_builtin _ -> Printf.printf "" - -and print_env env = - Printf.printf "Type enviroment: \n"; - Base.Map.iteri env ~f:(fun ~key ~data -> - Printf.printf "val %s : " key; - print_value data; - Printf.printf "\n"); - Printf.printf "\n" -;; - -module Res = struct - open Base - - type 'a t = ('a, error) Result.t - - let fail = Result.fail - let return = Result.return - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - match monad with - | Ok result -> f result - | Error x -> fail x - ;; - - let ( let* ) = ( >>= ) -end - -module EvalEnv = struct - open Base - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let find_exn env key = - match Map.find env key with - | Some value -> Res.return value - | None -> Res.fail (`No_variable key) - ;; - - let find_exn1 env key = - let val' = Map.find_exn env key in - val' - ;; -end - -module Inter = struct - open Ast - open Res - open EvalEnv - - let eval_arith opr val1 val2 = return (Val_integer (opr val1 val2)) - let eval_eq opr val1 val2 = return (Val_bool (opr val1 val2)) - let eval_bool opr val1 val2 = return (Val_bool (opr val1 val2)) - - let eval_bin_op = function - | Mul, Val_integer val1, Val_integer val2 -> eval_arith ( * ) val1 val2 - | Div, Val_integer val1, Val_integer val2 when val2 <> 0 -> eval_arith ( / ) val1 val2 - | Div, _, Val_integer 0 -> fail `Division_by_zero - | Plus, Val_integer val1, Val_integer val2 -> eval_arith ( + ) val1 val2 - | Sub, Val_integer val1, Val_integer val2 -> eval_arith ( - ) val1 val2 - | GreaterEqual, val1, val2 -> eval_eq ( >= ) val1 val2 - | LessEqual, val1, val2 -> eval_eq ( <= ) val1 val2 - | NotEqual, val1, val2 -> eval_eq ( <> ) val1 val2 - | Equal, val1, val2 -> eval_eq ( = ) val1 val2 - | Greater, val1, val2 -> eval_eq ( > ) val1 val2 - | Less, val1, val2 -> eval_eq ( < ) val1 val2 - | And, Val_bool val1, Val_bool val2 -> eval_bool ( && ) val1 val2 - | Or, Val_bool val1, Val_bool val2 -> eval_bool ( || ) val1 val2 - | _ -> fail `Type_error - ;; - - let rec match_pattern env = function - | Pattern_any, _ -> Some env - | Pattern_const Const_unit, _ -> Some env - | Pattern_option None, Val_option None -> Some env - | Pattern_var name, value -> Some (extend env name value) - | Pattern_const (Const_int pat), Val_integer value when pat = value -> Some env - | Pattern_const (Const_char pat), Val_char value when pat = value -> Some env - | Pattern_const (Const_string pat), Val_string value when pat = value -> Some env - | Pattern_const (Const_bool pat), Val_bool value when pat = value -> Some env - | Pattern_tuple pat_list, Val_tuple val_list -> - let env = - Base.List.fold2 - ~f:(fun env pat value -> - match env with - | Some env -> match_pattern env (pat, value) - | None -> None) - ~init:(Some env) - pat_list - val_list - in - (match env with - | Ok env -> env - | _ -> None) - | Pattern_list_sugar_case pat_list, Val_list val_list -> - (match pat_list, val_list with - | [], [] -> Some env - | first_pat :: rest_pat, first_val :: rest_val -> - let env = match_pattern env (first_pat, first_val) in - (match env with - | Some env -> - match_pattern env (Pattern_list_sugar_case rest_pat, Val_list rest_val) - | None -> None) - | _ -> None) - | Pattern_list_constructor_case pat_list, Val_list val_list -> - (match pat_list, val_list with - | single_pat :: [], val_list -> match_pattern env (single_pat, Val_list val_list) - | _ :: _ :: _, [] -> None - | first_pat :: rest_pat, first_val :: rest_val -> - let env = match_pattern env (first_pat, first_val) in - (match env with - | Some env -> - match_pattern env (Pattern_list_constructor_case rest_pat, Val_list rest_val) - | None -> None) - | _ -> None) - | Pattern_option (Some pat), Val_option (Some value) -> match_pattern env (pat, value) - | _ -> None - ;; - - let rec extend_names_from_pat env = function - | Pattern_any, _ -> return env - | Pattern_const Const_unit, Val_unit -> return env - | Pattern_option None, Val_option None -> return env - | Pattern_var id, value -> return (extend env id value) - | Pattern_tuple pat_list, Val_tuple val_list -> - (match - Base.List.fold2 pat_list val_list ~init:(return env) ~f:(fun acc pat value -> - let* env = acc in - extend_names_from_pat env (pat, value)) - with - | Ok acc -> acc - | _ -> fail `Type_error) - | Pattern_list_sugar_case pat_list, Val_list val_list -> - (match pat_list, val_list with - | first_pat :: rest_pat, first_val :: rest_val -> - let* env = extend_names_from_pat env (first_pat, first_val) in - let* env = - extend_names_from_pat env (Pattern_list_sugar_case rest_pat, Val_list rest_val) - in - return env - | _, _ -> return env) - | Pattern_list_constructor_case pat_list, Val_list val_list -> - (match pat_list, val_list with - | first_pat :: rest_pat, first_val :: rest_val -> - let* env = extend_names_from_pat env (first_pat, first_val) in - let* env = - extend_names_from_pat - env - (Pattern_list_constructor_case rest_pat, Val_list rest_val) - in - return env - | _, _ -> return env) - | Pattern_option (Some pat), Val_option (Some value) -> - extend_names_from_pat env (pat, value) - | _ -> fail `Type_error - ;; - - let rec eval_expression env = function - | Expr_var id -> find_exn env id - | Expr_const const -> - (match const with - | Const_int int -> return (Val_integer int) - | Const_char char -> return (Val_char char) - | Const_string str -> return (Val_string str) - | Const_bool bool -> return (Val_bool bool) - | Const_unit -> return Val_unit) - | Expr_construct_in (let_binding, expr) -> - let* env = eval_value_binding env let_binding in - eval_expression env expr - | Expr_anonym_fun (pat_list, expr) -> - return (Val_fun (Non_recursive, None, pat_list, expr, env)) - | Expr_binary_op (op, exp1, exp2) -> - let* value1 = eval_expression env exp1 in - let* value2 = eval_expression env exp2 in - eval_bin_op (op, value1, value2) - | Expr_application (exp, expr_list) -> - let* fun_val = eval_expression env exp in - let val_list = Base.List.map expr_list ~f:(fun expr -> eval_expression env expr) in - let rec help_fun val_list = function - | Val_fun (rec_flag, ident, pat_list, expr, fun_env) -> - let fun_env = - match ident, rec_flag with - | Some ident_list, Recursive -> - Base.List.fold_left ident_list ~init:fun_env ~f:(fun acc_env ident -> - EvalEnv.extend acc_env ident (EvalEnv.find_exn1 env ident)) - | _ -> fun_env - in - let rec helper pat_list val_list fun_env = - match pat_list, val_list with - | _ :: _, [] -> - return (Val_fun (Non_recursive, ident, pat_list, expr, fun_env)) - | first_pat :: rest_pat, first_val :: rest_val -> - let* arg_val = first_val in - let new_fun_env = match_pattern fun_env (first_pat, arg_val) in - (match new_fun_env with - | Some new_fun_env -> helper rest_pat rest_val new_fun_env - | None -> fail `Match_failure) - | [], _ :: _ -> - let* partial_application_val = eval_expression fun_env expr in - help_fun val_list partial_application_val - | [], [] -> - let _ = - match ident with - | Some (first :: []) -> first - | Some _ -> "several_idents" - | _ -> "no_ident" - in - eval_expression fun_env expr - in - helper pat_list val_list fun_env - | Val_function (case_list, env) -> - (match expr_list with - | [] -> return fun_val - | single :: [] -> - let* arg_val = eval_expression env single in - find_and_eval_case env arg_val case_list - | _ -> fail `Too_many_args_for_anonym_fun) - | Val_builtin builtin -> - (match val_list with - | [] -> return fun_val - | single :: [] -> - let* arg_val = single in - (match builtin, arg_val with - | "print_int", Val_integer integer -> - print_int integer; - Printf.printf "\n"; - (*to make the manytests results readable*) - return Val_unit - | "print_endline", Val_string str -> - print_endline str; - return Val_unit - | _ -> fail `Type_error) - | _ -> fail (`Too_many_args_for_fun builtin)) - | _ -> fail `Type_error - in - help_fun val_list fun_val - | Expr_function_fun case_list -> return (Val_function (case_list, env)) - | Expr_match_with (expr, case_list) -> - let* match_value = eval_expression env expr in - find_and_eval_case env match_value case_list - | Expr_tuple expr_list -> - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - return (value :: acc)) - ~init:(return []) - expr_list - in - return (Val_tuple val_list) - | Expr_list_sugar expr_list -> - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - return (value :: acc)) - ~init:(return []) - expr_list - in - return (Val_list val_list) - | Expr_list_construct expr_list -> - let rec helper acc_list = function - | [] -> eval_expression env (Expr_list_sugar []) - | single_expr :: [] -> - let* value = eval_expression env single_expr in - (match value with - | Val_list val_list -> return (Val_list (acc_list @ val_list)) - | _ -> return (Val_list [])) - | first_expr :: rest_exprs -> - let* value = eval_expression env first_expr in - helper (acc_list @ [ value ]) rest_exprs - in - helper [] expr_list - | Expr_option (Some expr) -> - let* value = eval_expression env expr in - return (Val_option (Some value)) - | Expr_option None -> return (Val_option None) - | Expr_if_then_else (if_expr, then_expr, else_expr) -> - let* if_value = eval_expression env if_expr in - (match if_value with - | Val_bool true -> eval_expression env then_expr - | Val_bool false -> eval_expression env else_expr - | _ -> fail `Type_error) - | Typed_expression (_, expr) -> eval_expression env expr - - and find_and_eval_case env value = function - | [] -> fail `Match_failure - | (pat, expr) :: rest_cases -> - let env_temp = match_pattern env (pat, value) in - (match env_temp with - | Some env -> eval_expression env expr - | None -> find_and_eval_case env value rest_cases) - - and eval_value_binding env = function - | Let_binding (rec_flag, Let_fun (id, pat_list), expr) -> - (match pat_list with - | _ :: _ -> - let env = extend env id (Val_fun (rec_flag, Some [ id ], pat_list, expr, env)) in - return env - | [] -> - let* value = eval_expression env expr in - let env = extend env id value in - return env) - | Let_binding (_, Let_pattern pat, expr) -> - let* value = eval_expression env expr in - let* env = extend_names_from_pat env (pat, value) in - return env - | Let_rec_and_binding binding_list -> - let list_of_names = - Base.List.fold_left binding_list ~init:[] ~f:(fun acc_list -> - function - | Let_binding (_, Let_fun (id, _), _) -> acc_list @ [ id ] - | _ -> acc_list) - in - Base.List.fold_left binding_list ~init:(return env) ~f:(fun acc_env let_binding -> - let* env = acc_env in - let* env = eval_value_binding env let_binding in - match let_binding with - | Let_binding (_, Let_fun (id, _), _) -> - let added_value = EvalEnv.find_exn1 env id in - (match added_value with - | Val_fun (Recursive, Some _, pat_list, expr, fun_env) -> - let env = - extend - env - id - (Val_fun (Recursive, Some list_of_names, pat_list, expr, fun_env)) - in - let _ = print_env in - return env - | _ -> return env) - | _ -> return env) - ;; - - let eval_let_bind env out_list value_binding = - let rec extract_names_from_pat env acc = function - | Pattern_var id -> acc @ [ id, EvalEnv.find_exn1 env id ] - | Pattern_tuple pat_list - | Pattern_list_sugar_case pat_list - | Pattern_list_constructor_case pat_list -> - Base.List.fold_left pat_list ~init:acc ~f:(extract_names_from_pat env) - | Pattern_option (Some pat) -> extract_names_from_pat env acc pat - | _ -> acc - in - let rec get_names_from_let_binds env = function - | Let_binding (_, Let_fun (id, _), _) -> [ id, EvalEnv.find_exn1 env id ] - | Let_binding (_, Let_pattern pat, _) -> extract_names_from_pat env [] pat - | Let_rec_and_binding binding_list -> - Base.List.fold_left binding_list ~init:[] ~f:(fun acc_list let_binding -> - acc_list @ get_names_from_let_binds env let_binding) - in - let* env = eval_value_binding env value_binding in - let eval_list = get_names_from_let_binds env value_binding in - return (env, out_list @ eval_list) - ;; - - let eval_structure env ast = - let* _, out_list = - Base.List.fold_left - ~f:(fun acc let_bind -> - let* env, out_list = acc in - let* env, out_list = eval_let_bind env out_list let_bind in - return (env, out_list)) - ~init:(return (env, [])) - ast - in - let rec remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (id1, _), (id2, _) -> String.equal id1 id2 - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> - x :: remove_duplicates xs - | _ :: xs -> remove_duplicates xs - | [] -> [] - in - return (remove_duplicates out_list) - ;; -end - -let empty_env = EvalEnv.empty - -let env_with_print_funs = - let env = EvalEnv.extend empty_env "print_int" (Val_builtin "print_int") in - EvalEnv.extend env "print_endline" (Val_builtin "print_endline") -;; - -let run_interpreter ast = Inter.eval_structure env_with_print_funs ast diff --git a/EMigunova/lib/interpreter.mli b/EMigunova/lib/interpreter.mli deleted file mode 100644 index c7bd2ceec..000000000 --- a/EMigunova/lib/interpreter.mli +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `Type_error - | `Division_by_zero - | `Match_failure - | `Too_many_args_for_anonym_fun - | `Too_many_args_for_fun of string - | `No_variable of string - ] - -type value = - | Val_integer of int - | Val_char of char - | Val_string of string - | Val_unit - | Val_bool of bool - | Val_fun of rec_flag * ident list option * pattern list * expression * env - | Val_function of (pattern * expression) list * env - | Val_tuple of value list - | Val_list of value list - | Val_option of value option - | Val_builtin of string - -and env = (string, value, Base.String.comparator_witness) Base.Map.t - -val print_value : value -> unit -val print_error : error -> unit -val run_interpreter : let_binding list -> ((ident * value) list, error) result diff --git a/EMigunova/lib/parse.ml b/EMigunova/lib/parse.ml deleted file mode 100644 index 5fd8c6a9e..000000000 --- a/EMigunova/lib/parse.ml +++ /dev/null @@ -1,604 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast - -let is_char = function - | 'A' .. 'Z' | 'a' .. 'z' -> true - | _ -> false -;; - -let is_digit = function - | '0' .. '9' -> true - | _ -> false -;; - -let is_sep = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -let is_keyword = function - | "let" - | "rec" - | "and" - | "fun" - | "if" - | "then" - | "else" - | "match" - | "with" - | "in" - | "true" - | "false" - | "Some" - | "None" - | "type" - | "val" - | "function" - | "_" -> true - | _ -> false -;; - -let skip_sep = skip_while is_sep -let trim t = skip_sep *> t <* skip_sep -let token t = skip_sep *> string t <* skip_sep -let round_par p = token "(" *> p <* token ")" -let square_par p = token "[" *> p <* token "]" -let round_par_many t = fix (fun p -> trim t <|> round_par p) -let round_par_many1 t = round_par_many (round_par t) - -let parse_id = - let* p_first = satisfy is_char <|> satisfy (Char.equal '_') >>| Char.escaped in - let* p_rest = - take_while1 (fun ch -> is_char ch || is_digit ch || Char.equal '_' ch) <|> return "" - in - let id = p_first ^ p_rest in - if is_keyword id - then fail "Error! parse_id: id must not match the keyword." - else if id = "_" - then fail "wildcard \"_\" not expected" - else return id -;; - -let parse_int = trim @@ take_while1 is_digit >>| fun x -> Const_int (int_of_string x) - -let parse_char = - let* char = token "'" *> any_char <* token "'" in - return @@ Const_char char -;; - -let parse_str = - let p_empty_string = trim @@ string "\"\"" <|> string "{||}" >>| fun _ -> "" in - let p_content = - choice - [ trim @@ (string "{|" *> take_till (Char.equal '|')) <* string "|}" - ; trim @@ (string "\"" *> take_till (Char.equal '\"')) <* token "\"" - ] - in - let* str = p_empty_string <|> p_content in - return @@ Const_string str -;; - -let parse_bool = - let* bool = choice [ token "true" *> return true; token "false" *> return false ] in - return @@ Const_bool bool -;; - -let parse_unit = - let* _ = token "()" in - return @@ Const_unit -;; - -let parse_const = choice [ parse_int; parse_char; parse_str; parse_bool; parse_unit ] - -(* -------parse patterns------ *) - -let parse_any_pattern = - let* _ = trim @@ satisfy (fun ch -> Char.equal '_' ch) in - return @@ Pattern_any -;; - -let parse_var_pattern = - let* var = trim parse_id in - return @@ Pattern_var var -;; - -let parse_const_pattern = - let parse_neg_int = - trim @@ (token "-" *> take_while1 is_digit >>| fun x -> Const_int (-int_of_string x)) - in - let* const = trim @@ (parse_const <|> parse_neg_int) in - return @@ Pattern_const const -;; - -let parse_base_pattern = - choice [ parse_var_pattern; parse_any_pattern; parse_const_pattern ] -;; - -let parse_list_sugar_case_pattern parse_pattern = - let empty_list_parser = - let* _ = token "[" *> token "]" in - return @@ Pattern_list_sugar_case [] - in - let list_single_parser = - let* pat = token "[" *> parse_pattern <* token "]" in - return @@ Pattern_list_sugar_case [ pat ] - in - let list_parser = - let* _ = token "[" in - let* first = parse_pattern in - let* rest = many1 (token ";" *> parse_pattern) in - let* _ = token "]" in - return @@ Pattern_list_sugar_case (first :: rest) - in - empty_list_parser <|> list_single_parser <|> list_parser -;; - -let parse_list_construct_case_pattern parse_pattern = - let* first = parse_pattern in - let* rest = many1 @@ (token "::" *> parse_pattern) in - return @@ Pattern_list_constructor_case (first :: rest) -;; - -let parse_tuple_pattern parse_pattern = - let* first = parse_pattern in - let* rest = many1 @@ (token "," *> parse_pattern) in - return @@ Pattern_tuple (first :: rest) -;; - -let parse_option_pattern parser_for_argument_of_some = - let parser_some = - let* pattern_some = token "Some" *> parser_for_argument_of_some in - return @@ Pattern_option (Some pattern_some) - in - let parser_none = - let* _ = token "None" in - return @@ Pattern_option None - in - parser_some <|> parser_none -;; - -let parse_pattern = - fix - @@ fun parse_pattern -> - round_par_many - @@ - let parse_option_argument = - fix - @@ fun parse_option_argument -> - round_par_many - @@ choice - [ parse_base_pattern - ; parse_option_pattern parse_option_argument - ; parse_list_sugar_case_pattern parse_pattern - ] - <|> round_par_many1 parse_pattern - in - let parse_list_construct_element = - round_par_many - @@ choice - [ parse_base_pattern - ; parse_option_pattern parse_option_argument - ; parse_list_sugar_case_pattern parse_pattern - ] - <|> round_par_many1 parse_pattern - in - let parse_tuple_element = - round_par_many - @@ choice - [ parse_list_construct_case_pattern parse_list_construct_element - ; parse_base_pattern - ; parse_option_pattern parse_option_argument - ; parse_list_sugar_case_pattern parse_pattern - ] - <|> round_par_many1 parse_pattern - in - round_par_many - @@ choice - [ parse_tuple_pattern parse_tuple_element - ; parse_list_construct_case_pattern parse_list_construct_element - ; parse_base_pattern - ; parse_option_pattern parse_option_argument - ; parse_list_sugar_case_pattern parse_pattern - ] -;; - -let parse_expr_var = - let* var = parse_id in - return @@ Expr_var var -;; - -let parse_expr_const = - let* const = parse_const in - return @@ Expr_const const -;; - -let parse_expr_list_sugar parse_expr = - let empty_list_parse = token "[" *> token "]" *> (return @@ Expr_list_sugar []) in - let non_empty_list_parse = - square_par - @@ - let* first = parse_expr in - let* other = many (token ";" *> parse_expr) in - return @@ Expr_list_sugar (first :: other) - in - empty_list_parse <|> non_empty_list_parse -;; - -let parse_expr_option parse_expression = - fix - @@ fun parse_expr_option -> - let parse_some = - let* _ = token "Some" in - let* argument = - round_par_many - @@ choice - [ parse_expr_const; parse_expr_var; parse_expr_list_sugar parse_expression ] - <|> round_par_many1 @@ choice [ parse_expr_option; parse_expression ] - in - return @@ Expr_option (Some argument) - in - let parse_none = - let* _ = token "None" in - return @@ Expr_option None - in - parse_some <|> parse_none -;; - -let parse_expr_base_elements parse_expression = - round_par_many - @@ choice - [ parse_expr_const - ; parse_expr_var - ; parse_expr_option parse_expression - ; parse_expr_list_sugar parse_expression - ] -;; - -(*let's add ability to specify type annotations*) - -let parse_type = - fix - @@ fun parse_type -> - let base_type_parser = - round_par_many - @@ choice - [ token "int" *> return Type_int - ; token "char" *> return Type_char - ; token "bool" *> return Type_bool - ; token "string" *> return Type_string - ; token "unit" *> return Type_unit - ] - in - let tuple_type_parser parser_tuple_element_type = - round_par_many - @@ - let* first = parser_tuple_element_type in - let* rest = many1 @@ (token "*" *> parser_tuple_element_type) in - return (Type_tuple (first :: rest)) - in - let parser_tuple_element_type = - round_par_many (base_type_parser <|> round_par_many1 parse_type) - in - let list_type_parser = - fix - @@ fun list_type_parser -> - let* element_type = - choice - @@ [ tuple_type_parser parser_tuple_element_type - ; base_type_parser - ; round_par_many1 list_type_parser - ] - in - let rec list_type_parser element_type = - (let* _ = token "list" in - list_type_parser (Type_list element_type)) - <|> return element_type - in - list_type_parser element_type - in - choice - [ list_type_parser; tuple_type_parser parser_tuple_element_type; base_type_parser ] -;; - -let type_annotation expression_parser = - (round_par_many1 - @@ - let* expression = expression_parser in - let* ttype = token ":" *> parse_type in - return @@ Typed_expression (ttype, expression)) - <|> round_par_many expression_parser -;; - -let type_annotation1 expression_parser = - round_par_many1 - @@ - let* expression = expression_parser in - let* ttype = token ":" *> parse_type in - return @@ Typed_expression (ttype, expression) -;; - -(* ----if then else parser------ *) - -let parse_if_when_else parse_expression = - let* if_condition = token "if" *> parse_expression in - let* then_expression = token "then" *> parse_expression in - let* else_expression = - token "else" *> parse_expression <|> return @@ Expr_const Const_unit - in - return @@ Expr_if_then_else (if_condition, then_expression, else_expression) -;; - -(* --- match with parser --- *) - -let parse_match_with parse_expression = - let* compared_expression = token "match" *> parse_expression <* token "with" in - let* pattern_first = (token "|" <|> return "") *> parse_pattern in - let* return_expression_first = token "->" *> parse_expression in - let parser_rest = - token "|" *> parse_pattern - >>= fun first_element -> - token "->" *> parse_expression >>| fun second_element -> first_element, second_element - in - let* rest = many parser_rest in - return - @@ Expr_match_with - (compared_expression, (pattern_first, return_expression_first) :: rest) -;; - -(* ---let-binding parser--- *) - -let parse_rec_flag = - let recursive = token "let " *> token "rec " >>= fun _ -> return Recursive in - let non_recursive = token "let " >>= fun _ -> return Non_recursive in - recursive <|> non_recursive -;; - -let parse_let_declaration = - let parser_fun_case = - let* fun_ident = parse_id in - let* arguments_list = many parse_pattern <* token "=" in - return @@ Let_fun (fun_ident, arguments_list) - in - let parser_pattern_case = - parse_pattern <* token "=" >>= fun pattern -> return @@ Let_pattern pattern - in - parser_fun_case <|> parser_pattern_case -;; - -let parse_let_biding parse_expression = - let* rec_flag = parse_rec_flag in - let* let_declaration = parse_let_declaration in - let* let_definition = parse_expression in - return @@ Let_binding (rec_flag, let_declaration, let_definition) -;; - -(* ---parser of mutually recursive let-bindings--- *) - -let parse_let_rec_and_binding parse_expression = - let parse_first = - let* _ = token "let" *> token "rec" in - let* let_declaration = parse_let_declaration in - let* let_definition = parse_expression in - return @@ Let_binding (Recursive, let_declaration, let_definition) - in - let parse_one_of_rest = - let* _ = token "and" in - let* let_declaration = parse_let_declaration in - let* let_definition = parse_expression in - return @@ Let_binding (Recursive, let_declaration, let_definition) - in - let* first = parse_first in - let* rest = many1 parse_one_of_rest in - return @@ Let_rec_and_binding (first :: rest) -;; - -(* ---in-construction parser--- *) - -let parse_in_construction parse_expression = - let* parse_let_biding = parse_let_biding parse_expression in - let* parse_expression = token "in" *> parse_expression in - return @@ Expr_construct_in (parse_let_biding, parse_expression) -;; - -(* ---anonymous function with keyword "fun" parser--- *) - -let parse_anonymouse_fun parse_expression = - let parse_argument = - round_par_many - @@ choice - @@ [ parse_base_pattern - ; parse_list_sugar_case_pattern parse_pattern - ; token "None" *> (return @@ Pattern_option None) - ] - <|> round_par_many1 parse_pattern - in - let* list_of_arguments = token "fun" *> many1 parse_argument in - let* parse_expression = token "->" *> round_par_many parse_expression in - return @@ Expr_anonym_fun (list_of_arguments, parse_expression) -;; - -(* ---anonymous function with keyword "function" parser--- *) - -let parse_function_fun parse_expression = - let* _ = token "function" in - let* pattern_first = (token "|" <|> return "") *> parse_pattern in - let* return_expression_first = token "->" *> parse_expression in - let parser_one_matching = - token "|" *> parse_pattern - >>= fun first_element -> - token "->" *> parse_expression >>| fun second_element -> first_element, second_element - in - let* rest = many parser_one_matching in - return @@ Expr_function_fun ((pattern_first, return_expression_first) :: rest) -;; - -(* ---application parser---*) - -let parse_application parse_expression = - round_par_many - @@ - let parse_application_element = - round_par_many - @@ choice - @@ [ parse_expr_const; parse_expr_var; parse_expr_list_sugar parse_expression ] - <|> round_par_many1 parse_expression - <|> type_annotation1 parse_expression - in - let* first = parse_application_element in - let* rest = many1 parse_application_element in - return @@ Expr_application (first, rest) -;; - -let parse_bin_op_T1 = token "||" *> return Or -let parse_bin_op_T2 = token "&&" *> return And - -let parse_bin_op_T3 = - choice - [ token "=" *> return Equal - ; token "<=" *> return LessEqual - ; token ">=" *> return GreaterEqual - ; token ">" *> return Greater - ; token "<" *> return Less - ; (token "!=" <|> token "<>") *> return NotEqual - ] -;; - -let parse_bin_op_T4 = choice [ token "+" *> return Plus; token "-" *> return Sub ] -let parse_bin_op_T5 = choice [ token "*" *> return Mul; token "/" *> return Div ] - -(* ---------binary operators parser--------- *) - -let parse_bin_op_expression parse_expression = - let parse_expr_base = - parse_application parse_expression - <|> parse_expr_base_elements parse_expression - <|> round_par_many1 parse_expression - <|> type_annotation1 parse_expression - >>= fun result -> return result "base" - in - let parse_expr_mul_div = - let* first_operand = parse_expr_base in - let rec parse_mul_div_chain left_expression = - (let* operator = parse_bin_op_T5 in - let* right_expression = parse_expr_base in - parse_mul_div_chain @@ Expr_binary_op (operator, left_expression, right_expression)) - <|> return left_expression - "mul div" - in - parse_mul_div_chain first_operand - in - let parse_expr_add_sub = - let rec parse_add_sub_chain left_expression = - (let* operator = parse_bin_op_T4 in - let* right_expression = parse_expr_mul_div in - parse_add_sub_chain @@ Expr_binary_op (operator, left_expression, right_expression)) - <|> return left_expression - in - (let* first_operand = parse_expr_mul_div in - parse_add_sub_chain first_operand) - <|> - (*implemention of negative int*) - let* operator = parse_bin_op_T4 in - let* right_expression = parse_expr_mul_div in - parse_add_sub_chain - @@ Expr_binary_op (operator, Expr_const (Const_int 0), right_expression) - in - let parse_expr_compare = - let* first_operand = parse_expr_add_sub in - let rec parse_compare_chain left_expression = - (let* operator = parse_bin_op_T3 in - let* right_expression = parse_expr_add_sub in - parse_compare_chain @@ Expr_binary_op (operator, left_expression, right_expression)) - <|> return left_expression - in - parse_compare_chain first_operand - in - let parse_expr_and = - let* first_operand = parse_expr_compare in - let rec parse_and_chain left_expression = - (let* operator = parse_bin_op_T2 in - let* right_expression = parse_expr_compare in - parse_and_chain @@ Expr_binary_op (operator, left_expression, right_expression)) - <|> return left_expression - "and" - in - parse_and_chain first_operand - in - let parse_expr_or = - let* first_operand = parse_expr_and in - let rec parse_or_chain left_expression = - (let* operator = parse_bin_op_T1 in - let* right_expression = parse_expr_and in - parse_or_chain @@ Expr_binary_op (operator, left_expression, right_expression)) - <|> return left_expression - "or" - in - parse_or_chain first_operand - in - parse_expr_or -;; - -(* ---expression parser--- *) - -let parse_expression_without_tuple_list parse_expression = - (*also this implemention doesn't consider tuple and list_constructor_case constructions, then we will add it*) - type_annotation - @@ choice - [ parse_bin_op_expression parse_expression - ; parse_if_when_else parse_expression - ; parse_match_with parse_expression - ; parse_function_fun parse_expression - ; parse_anonymouse_fun parse_expression - ; parse_in_construction parse_expression - ] -;; - -(*let's add ability to parse tuple and list_constructor_case constructions*) - -let parse_expr_list_construct parse_expression = - let parse_element = - round_par_many @@ parse_expression_without_tuple_list parse_expression - <|> round_par_many1 parse_expression - in - let* first = parse_element in - let* rest = many1 @@ (token "::" *> parse_element) in - return @@ Expr_list_construct (first :: rest) -;; - -let parse_expr_tuple parse_expression = - let parse_element = - round_par_many - @@ choice - [ parse_expr_list_construct parse_expression - ; parse_expression_without_tuple_list parse_expression - ] - <|> round_par_many1 parse_expression - in - let* first = parse_element in - let* rest = many1 @@ (token "," *> parse_element) in - return @@ Expr_tuple (first :: rest) -;; - -let parse_expression = - fix - @@ fun parse_expression -> - choice - [ parse_expr_tuple parse_expression - ; parse_expr_list_construct parse_expression - ; parse_expression_without_tuple_list parse_expression - ] -;; - -let parse_structure = - let* parse_let_bindings = - many1 - (parse_let_rec_and_binding parse_expression <|> parse_let_biding parse_expression) - in - return parse_let_bindings -;; - -let parse = parse_string ~consume:All parse_structure diff --git a/EMigunova/lib/parse.mli b/EMigunova/lib/parse.mli deleted file mode 100644 index fbc428259..000000000 --- a/EMigunova/lib/parse.mli +++ /dev/null @@ -1,32 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast - -val parse_id : ident t -val parse_int : constant t -val parse_char : constant t -val parse_str : constant t -val parse_bool : constant t -val parse_unit : constant t -val parse_const : constant t -val parse_any_pattern : pattern t -val parse_var_pattern : pattern t -val parse_const_pattern : pattern t -val parse_tuple_pattern : pattern t -> pattern t -val parse_pattern : pattern t -val parse_expr_var : expression t -val parse_expr_const : expression t -val parse_expr_list_sugar : expression t -> expression t -val parse_expr_base_elements : expression t -> expression t -val parse_bin_op_expression : expression t -> expression t -val parse_if_when_else : expression t -> expression t -val parse_match_with : expression t -> expression t -val parse_let_biding : expression t -> let_binding t -val parse_in_construction : expression t -> expression t -val parse_anonymouse_fun : expression t -> expression t -val parse_function_fun : expression t -> expression t -val parse_expression : expression t -val parse : ident -> (let_binding list, ident) result diff --git a/EMigunova/tests/.gitignore b/EMigunova/tests/.gitignore deleted file mode 100644 index 26685e795..000000000 --- a/EMigunova/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -lam*.txt \ No newline at end of file diff --git a/EMigunova/tests/dune b/EMigunova/tests/dune deleted file mode 100644 index 07a30bab1..000000000 --- a/EMigunova/tests/dune +++ /dev/null @@ -1,30 +0,0 @@ -(cram - (applies_to *) - (deps - ../bin/REPL.exe - manytests/typed/001fac.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/006partial.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml)) diff --git a/EMigunova/tests/manytests b/EMigunova/tests/manytests deleted file mode 120000 index f6572219a..000000000 --- a/EMigunova/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -./../../manytests \ No newline at end of file diff --git a/EMigunova/tests/manytests_inference.t b/EMigunova/tests/manytests_inference.t deleted file mode 100644 index 48667c3cf..000000000 --- a/EMigunova/tests/manytests_inference.t +++ /dev/null @@ -1,170 +0,0 @@ - $ ../bin/REPL.exe --dinference < - > let c = 'x' - > let s = "asv" - > - > let cons2 a b xs = a::b::xs - > let x = cons2 1 2 [3] - > let xxx = (1,2,3,(4,5)) - val c : char = 'x' - val s : string = "asv" - val cons2 : 'a->'a->'a list->'a list = - val x : int list = [1; 2; 3] - val xxx : int*int*int*(int*int) = (1, 2, 3, (4, 5)) - - $ ../bin/REPL.exe --dinference < - > let f xs = match xs with - > | [x] -> [x] - > - val f : 'a list->'a list = - - $ ../bin/REPL.exe --dinference < manytests/typed/001fac.ml - 24 - val fac : int->int = - val main : int = 0 - $ ../bin/REPL.exe --dinference < manytests/typed/001fac.ml - 24 - val fac : int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/002fac.ml - 24 - val fac_cps : int->(int->'a)->'a = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/003fib.ml - 3 - 3 - val fib_acc : int->int->int->int = - val fib : int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - val wrap : 'a->'a = - val test3 : int->int->int->int = - val test10 : int->int->int->int->int->int->int->int->int->int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/005fix.ml - 720 - val fix : (('a->'b)->'a->'b)->'a->'b = - val fac : (int->int)->int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - val foo : int->int->int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/006partial3.ml - 4 - 8 - 9 - val foo : int->int->int->unit = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/006partial.ml - 1122 - val foo : int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - val _start : unit->unit->int->unit->int->int->unit->int->int->int = - val main : unit = () - - $ ../bin/REPL.exe --dinference < manytests/typed/008ascription.ml - 8 - val addi : ('a->bool->int)->('a->bool)->'a->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/009let_poly.ml - val temp : int*bool = (1, true) - - $ ../bin/REPL.exe --dinference < manytests/typed/010sukharev.ml - val _1 : int->int->int*'a->bool = - val _2 : int = 1 - val _3 : (int*string) option = Some (1, "hi") - val _4 : int->'a = - val _5 : int = 42 - val _6 : 'a option->'a = - val int_of_option : int option->int = - val _42 : int->bool = - val id1 : 'a->'a = - val id2 : 'a->'a = - - $ ../bin/REPL.exe --dinference < manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - val fix : (('a->'b)->'a->'b)->'a->'b = - val map : ('b->'a)->'b*'b->'a*'a = - val fixpoly : (('a->'b)*('a->'b)->'a->'b)*(('a->'b)*('a->'b)->'a->'b)->('a->'b)*('a->'b) = - val feven : 'a*(int->int)->int->int = - val fodd : (int->int)*'a->int->int = - val tie : (int->int)*(int->int) = (, ) - val meven : int->int = - val modd : int->int = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/typed/016lists.ml - 1 - 2 - 3 - 8 - val length : 'a list->int = - val length_tail : 'a list->int = - val map : ('a->'b)->'a list->'b list = - val append : 'a list->'a list->'a list = - val concat : 'a list list->'a list = - val iter : ('a->unit)->'a list->unit = - val cartesian : 'b list->'a list->('b*'a) list = - val main : int = 0 - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/001.ml - Type inference error: Undefined variable 'fac' - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/002if.ml - Type inference error: Unification( if _ then [first type] else [second type] ) failed for following unifiable types: int and bool - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/003occurs.ml - Type inference error: Occurs check failed: the type variable 'ty2 occurs inside'ty2->'ty4->'ty5 - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/004let_poly.ml - Type inference error: Unification( ([type1] -> [...]) and ([type2] -> [...]) ) failed for following unifiable types: bool and int - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/005.ml - Type inference error: Unification( ([type1] -> [...]) and ([type2] -> [...]) ) failed for following unifiable types: string and int - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/015tuples.ml - Type inference error: Recursive binding failed: the LHS of the recursive binding must not be a composed pattern (e.g. tuple, list, etc.). A variable is required. - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/016tuples_mismatch.ml - Type inference error: Unification( let binding with pattern ) failed for following unifiable types: int*int*int and 'ty1*'ty0 - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/097fun_vs_list.ml - Type inference error: Unification( let binding with pattern ) failed for following unifiable types: 'ty0->'ty0 and 'ty2 list - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/097fun_vs_unit.ml - Type inference error: Unification( let binding with pattern ) failed for following unifiable types: 'ty0->'ty0 and unit - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/098rec_int.ml - Type inference error: Recursive binding failed: a function was expected as the RHS. Recursive binding is impossible for that variable. It would lead to infinite recursion. - - $ ../bin/REPL.exe --dinference < manytests/do_not_type/099.ml - Type inference error: Recursive binding failed: the LHS of the recursive binding must not be a composed pattern (e.g. tuple, list, etc.). A variable is required. diff --git a/EMigunova/tests/parsetree_factorial.t b/EMigunova/tests/parsetree_factorial.t deleted file mode 100644 index 545e4edc1..000000000 --- a/EMigunova/tests/parsetree_factorial.t +++ /dev/null @@ -1,22 +0,0 @@ -(** Copyright 2025, Migunova Anastasia *) -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ../bin/REPL.exe --dparsetree < let rec factorial n = if n <= 1 then 1 else n * factorial (n-1) - [(Let_binding (Recursive, (Let_fun ("factorial", [(Pattern_var "n")])), - (Expr_if_then_else ( - (Expr_binary_op (LessEqual, (Expr_var "n"), (Expr_const (Const_int 1)) - )), - (Expr_const (Const_int 1)), - (Expr_binary_op (Mul, (Expr_var "n"), - (Expr_application ((Expr_var "factorial"), - [(Expr_binary_op (Sub, (Expr_var "n"), - (Expr_const (Const_int 1)))) - ] - )) - )) - )) - )) - ] - - diff --git a/ETenyaeva/.envrc b/ETenyaeva/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/ETenyaeva/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/ETenyaeva/.gitignore b/ETenyaeva/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/ETenyaeva/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/ETenyaeva/.ocamlformat b/ETenyaeva/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/ETenyaeva/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/ETenyaeva/.vscode/settings.json b/ETenyaeva/.vscode/settings.json deleted file mode 100644 index 9c9d88247..000000000 --- a/ETenyaeva/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ocaml.sandbox": { - "kind": "opam", - "switch": "4.14.2+flambda" - } -} \ No newline at end of file diff --git a/ETenyaeva/.zanuda b/ETenyaeva/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/ETenyaeva/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/ETenyaeva/COPYING b/ETenyaeva/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/ETenyaeva/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/ETenyaeva/COPYING.CC0 b/ETenyaeva/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/ETenyaeva/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/ETenyaeva/COPYING.LESSER b/ETenyaeva/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/ETenyaeva/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/ETenyaeva/ETenyaeva.opam b/ETenyaeva/ETenyaeva.opam deleted file mode 100644 index 019cae0c1..000000000 --- a/ETenyaeva/ETenyaeva.opam +++ /dev/null @@ -1,36 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for MiniML" -description: - "FIXME. A longer description, for example, which are the most interesing features being supported, etc." -maintainer: ["Ekaterina Tenyaeva "] -authors: ["Ekaterina Tenyaeva "] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Kakadu/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Kakadu/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/ETenyaeva/Makefile b/ETenyaeva/Makefile deleted file mode 100644 index a0a833fae..000000000 --- a/ETenyaeva/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -run: - dune exec ./bin/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/language dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/ETenyaeva/bin/REPL.ml b/ETenyaeva/bin/REPL.ml deleted file mode 100644 index 26f98789e..000000000 --- a/ETenyaeva/bin/REPL.ml +++ /dev/null @@ -1,81 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type options = - { mutable dump_parsetree : bool - ; mutable dump_inference : bool - } - -let run_single dump_parsetree dump_inference = - let text = In_channel.(input_all stdin) |> String.trim in - let ast = ETenyaeva_lib.Parser.parse text in - match ast with - | Error _ -> Format.printf "Syntax error" - | Result.Ok ast -> - if dump_parsetree then Format.printf "%a\n" ETenyaeva_lib.Ast.pp_structure ast; - if dump_inference - then ( - let infer = - ETenyaeva_lib.Inferencer.run_inferencer - ETenyaeva_lib.Inferencer.env_with_print_funs - ast - in - match infer with - | Error e -> - Format.printf "Inferencer error: %a\n" ETenyaeva_lib.Inferencer.pp_error e - | Result.Ok (_, infer_out_list) -> - List.iter - (function - | Some id, ty -> - Format.printf "val %s : %a\n" id ETenyaeva_lib.Inferencer.pp_type ty - | None, ty -> Format.printf "- : %a\n" ETenyaeva_lib.Inferencer.pp_type ty) - infer_out_list); - if not (dump_inference || dump_parsetree) - then ( - let infer = - ETenyaeva_lib.Inferencer.run_inferencer - ETenyaeva_lib.Inferencer.env_with_print_funs - ast - in - match infer with - | Error e -> - Format.printf "Inferencer error: %a\n" ETenyaeva_lib.Inferencer.pp_error e - | Result.Ok (_, _) -> - let inter = - ETenyaeva_lib.Interpreter.run_interpreter - ETenyaeva_lib.Interpreter.env_with_print_funs - ast - in - (match inter with - | Error e -> - Format.printf "Interpreter error: %a\n" ETenyaeva_lib.Interpreter.pp_error e - | Result.Ok (_, inter_out_list) -> - List.iter - (function - | Some id, val' -> - Format.printf "val %s = %a\n" id ETenyaeva_lib.Interpreter.pp_value val' - | None, val' -> - Format.printf "- = %a\n" ETenyaeva_lib.Interpreter.pp_value val') - inter_out_list)) -;; - -let () = - let options = { dump_parsetree = false; dump_inference = false } in - let () = - let open Stdlib.Arg in - parse - [ ( "--dparsetree" - , Unit (fun () -> options.dump_parsetree <- true) - , "Dump parse tree, don't eval enything" ) - ; ( "--dinference" - , Unit (fun () -> options.dump_inference <- true) - , "Eval and display type inference info" ) - ] - (fun _ -> - Stdlib.Format.eprintf "Anonymous arguments are not supported\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for MiniML Calculus" - in - run_single options.dump_parsetree options.dump_inference -;; diff --git a/ETenyaeva/bin/dune b/ETenyaeva/bin/dune deleted file mode 100644 index dbb6f9b1b..000000000 --- a/ETenyaeva/bin/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (libraries ETenyaeva_lib)) - -(cram - (deps ./REPL.exe %{bin:REPL})) diff --git a/ETenyaeva/bin/repl.t b/ETenyaeva/bin/repl.t deleted file mode 100644 index 7a6bb19eb..000000000 --- a/ETenyaeva/bin/repl.t +++ /dev/null @@ -1,10 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ./REPL.exe -help - Read-Eval-Print-Loop for MiniML Calculus - --dparsetree Dump parse tree, don't eval enything - --dinference Eval and display type inference info - -help Display this list of options - --help Display this list of options diff --git a/ETenyaeva/dune b/ETenyaeva/dune deleted file mode 100644 index 98e54536a..000000000 --- a/ETenyaeva/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/ETenyaeva/dune-project b/ETenyaeva/dune-project deleted file mode 100644 index 128ce91f0..000000000 --- a/ETenyaeva/dune-project +++ /dev/null @@ -1,35 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Ekaterina Tenyaeva ") - -(maintainers "Ekaterina Tenyaeva ") - -(bug_reports "https://github.com/Kakadu/fp2024") - -(homepage "https://github.com/Kakadu/fp2024") - -(package - (name ETenyaeva) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for MiniML") - (description - "FIXME. A longer description, for example, which are the most interesing features being supported, etc.") - (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files add the same dependecies here too - )) diff --git a/ETenyaeva/lib/ast.ml b/ETenyaeva/lib/ast.ml deleted file mode 100644 index 39ea70a08..000000000 --- a/ETenyaeva/lib/ast.ml +++ /dev/null @@ -1,104 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type id = string (* identifier *) [@@deriving show { with_path = false }] - -type rec_flag = - | Rec (** recursive *) - | NonRec (** non-recursive *) -[@@deriving show { with_path = false }] - -type const = - | Int of int (** integer, e.g. 26 *) - | Bool of bool (** boolean, e.g. true *) - | String of string (** string, e.g. "string" *) - | Char of char (** char, e.g. 'a' *) - | Unit (** [()] *) -[@@deriving show { with_path = false }] - -type typ = - | TypInt (** integer type - [int] *) - | TypChar (** char type - [char] *) - | TypStr (** string type - [string] *) - | TypBool (** boolean type - [bool] *) - | TypUnit (** unit type - [unit] *) - | TypVar of id (** variable type *) - | TypArrow of typ * typ (** arrow type *) - | TypList of typ (** list type, e.g. [int list], [string list] *) - | TypTuple of typ * typ * typ list (** tuple type, e.g. [int * int * string] *) - | TypOption of typ (** type option *) -[@@deriving show { with_path = false }] - -type binary_oper = - | Add (** [+] *) - | Sub (** [-] *) - | Mult (* [*] *) - | Div (** [/] *) - | And (** [&&] *) - | Or (** [||] *) - | Equals (** [=] *) - | NotEquals (** [<>] *) - | LessThan (** [<] *) - | LessEquals (** [<=] *) - | GreaterThan (** [>] *) - | GreaterEquals (** [>=] *) -[@@deriving show { with_path = false }] - -type unary_oper = - | Neg (** negation of a value, e.g. -5 *) - | Not (** [not] *) -[@@deriving show { with_path = false }] - -type pattern = - | PatConst of const (** matches a constant value, e.g. 42, true *) - | PatVar of id (** matches any value and binds it to a variable, e.g. x *) - | PatAny (** matches any value without binding it - [_] *) - | PatTup of pattern * pattern * pattern list - (** matches tuples, e.g. (x, y), (a, b, c) *) - | PatList of pattern list (** matches lists of patterns, e.g. [y; x] *) - | PatListConstructor of pattern list (** matches lists of patterns, e.g. a::b::[] *) - | PatOption of pattern option (** matches an optional pattern, e.g. Some x or None *) - | PatWithTyp of typ * pattern (** typed pattern, e.g. a: int *) -[@@deriving show { with_path = false }] - -type expr = - | ExpVar of id (** variable, e.g. x *) - | ExpConst of const (** constant, e.g. 10*) - | ExpIfThenElse of expr * expr * expr option - (** conditional expression, e.g. if a then b else c*) - | ExpFun of pattern * expr (** function, e.g. fun (x, y) -> x + y *) - | ExpFunction of case_expr * case_expr list - (** function, e.g. function x | 0 -> "zero" | _ -> "nonzero" *) - | ExpBinOper of binary_oper * expr * expr (** binary operation, e.g. 1 + 5*) - | ExpUnOper of unary_oper * expr (** unary operation, e.g. -7 *) - | ExpList of expr list (** list expression, e.g. [1, "string", 2, (1 + 7)] *) - | ExpListConstructor of expr list (** list expression, e.g. 1::2::[] *) - | ExpLet of rec_flag * let_binding * let_binding list * expr (** let, e.g. let x = 5 *) - | ExpApp of expr * expr (** application, e.g. (fun (x, y) -> x + y) (1, 2) *) - | ExpTup of expr * expr * expr list (** tuple expression, e.g. (e1, e2), (x, y, z) *) - | ExpMatch of expr * case_expr * case_expr list - (** pattern matching, e.g. match x with | 0 -> "zero" | _ -> "nonzero" *) - | ExpOption of expr option (** optonal expression, e.g. Some x*) - | ExpWithTyp of typ * expr (** typed expression, e.g. a: int *) -[@@deriving show { with_path = false }] - -and let_binding = - { pat : pattern (** the pattern being bound, e.g. x, (a, b) *) - ; expr : expr (** the expression being assigned, e.g. 42, fun x -> x + 1 *) - } -[@@deriving show { with_path = false }] - -and case_expr = - { case_pat : pattern (** the pattern to match, e.g. x, _ *) - ; case_expr : expr (** the expression to evaluate if the pattern matches *) - } -[@@deriving show { with_path = false }] - -type structure_item = - | EvalExp of expr (** an expression to be evaluated but not bound, e.g. 1 + 2*) - | Binding of rec_flag * let_binding * let_binding list - (** a value or function binding, e.g. let x = 1*) -[@@deriving show { with_path = false }] - -type structure = structure_item list [@@deriving show { with_path = false }] diff --git a/ETenyaeva/lib/dune b/ETenyaeva/lib/dune deleted file mode 100644 index 6e1463c94..000000000 --- a/ETenyaeva/lib/dune +++ /dev/null @@ -1,18 +0,0 @@ -(library - (name ETenyaeva_lib) - (public_name ETenyaeva.lib) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) - -; (library -; (name tests) -; (modules tests) -; (libraries ETenyaeva_lib) -; (preprocess -; (pps ppx_expect ppx_deriving.show)) -; (instrumentation -; (backend bisect_ppx)) -; (inline_tests)) diff --git a/ETenyaeva/lib/inferencer.ml b/ETenyaeva/lib/inferencer.ml deleted file mode 100644 index 047ac0725..000000000 --- a/ETenyaeva/lib/inferencer.ml +++ /dev/null @@ -1,838 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Stdlib.Format - -let rec pp_type fmt = function - | TypInt -> fprintf fmt "int" - | TypBool -> fprintf fmt "bool" - | TypUnit -> fprintf fmt "unit" - | TypStr -> fprintf fmt "string" - | TypChar -> fprintf fmt "char" - | TypVar id -> fprintf fmt "%s" id - | TypArrow ((TypArrow (_, _) as ty1), ty2) -> - fprintf fmt "(%a) -> %a" pp_type ty1 pp_type ty2 - | TypArrow (ty1, ty2) -> fprintf fmt "%a -> %a" pp_type ty1 pp_type ty2 - | TypList ty -> - (match ty with - | TypInt | TypBool | TypUnit | TypStr | TypVar _ | TypChar -> - fprintf fmt "%a list" pp_type ty - | _ -> fprintf fmt "(%a) list" pp_type ty) - | TypTuple (f, s, xs) -> - fprintf - fmt - "%a" - (pp_print_list - ~pp_sep:(fun _ _ -> printf " * ") - (fun fmt ty -> - match ty with - | TypInt | TypBool | TypUnit | TypStr | TypVar _ | TypChar -> pp_type fmt ty - | _ -> fprintf fmt "(%a)" pp_type ty)) - (f :: s :: xs) - | TypOption TypUnit -> () - | TypOption ty -> - (match ty with - | TypInt | TypBool | TypUnit | TypStr | TypVar _ | TypChar -> - fprintf fmt "%a option" pp_type ty - | _ -> fprintf fmt "(%a) option" pp_type ty) -;; - -type error = - | NoVariableRec - | NoArgRec - | SeveralBounds of string - | OccursCheck of string * typ - | NoVariable of string - | UnificationFailed of typ * typ - -let pp_error fmt = function - | OccursCheck (id, typ) -> - fprintf fmt "Occurs check failed. Type variable %s occurs inside %a\n" id pp_type typ - | NoVariable name -> fprintf fmt "Unbound variable %s'." name - | NoVariableRec -> - fprintf fmt "Only variables are allowed as left-hand side of `let rec'" - | UnificationFailed (ty1, ty2) -> - fprintf fmt "Failed to unify types: %a and %a\n" pp_type ty1 pp_type ty2 - | NoArgRec -> - fprintf fmt "This kind of expression is not allowed as right-hand side of `let rec'" - | SeveralBounds name -> fprintf fmt "Multiple bounds for variable %s'." name -;; - -module State = struct - open Base - - type 'a t = int -> int * ('a, error) Result.t - - let return x state = state, Result.return x - let fail e state = state, Result.fail e - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> f result state - | state, Result.Error e -> fail e state - ;; - - module Syntax = struct - let ( let* ) = ( >>= ) - end - - let ( >>| ) (monad : 'a t) (f : 'a -> 'b) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> return (f result) state - | state, Result.Error e -> fail e state - ;; - - module RList = struct - let fold_left xs ~init ~f = - List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_right xs ~init ~f = - List.fold_right xs ~init ~f:(fun x acc -> - let open Syntax in - let* acc = acc in - f x acc) - ;; - end - - module RMap = struct - let fold map ~init ~f = - Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - let fresh state = state + 1, Result.Ok state - let run monad = snd (monad 0) -end - -module VarSet = struct - include Stdlib.Set.Make (String) -end - -type scheme = Scheme of VarSet.t * typ - -module Type = struct - open Base - - (* gets a variable var and type ty, and checks whether the - variable is contained in the set of free variables of this type*) - let occurs_in var ty = - let rec helper ty = - match ty with - | TypOption ty | TypList ty -> helper ty - | TypVar name -> String.equal name var - | TypTuple (fst_ty, snd_ty, ty_list) -> - List.exists ~f:helper (fst_ty :: snd_ty :: ty_list) - | TypArrow (l, r) -> helper l || helper r - | _ -> false - in - match ty with - | TypVar _ -> false - | _ -> helper ty - ;; - - let free_vars = - let rec helper acc = function - | TypOption ty | TypList ty -> helper acc ty - | TypVar name -> VarSet.add name acc - | TypTuple (fst_ty, snd_ty, ty_list) -> - List.fold_left ~f:helper ~init:acc (fst_ty :: snd_ty :: ty_list) - | TypArrow (l, r) -> helper (helper acc l) r - | _ -> acc - in - helper VarSet.empty - ;; -end - -module Subst = struct - open State - open Base - open State.Syntax - - let empty = Map.empty (module String) - let singleton1 = Map.singleton (module String) - - let singleton key value = - if Type.occurs_in key value - then fail (OccursCheck (key, value)) - else return (Map.singleton (module String) key value) - ;; - - let remove = Map.remove - - let apply sub = - let rec helper = function - | TypVar name as ty -> - (match Map.find sub name with - | Some name -> name - | None -> ty) - | TypOption ty -> TypOption (helper ty) - | TypList ty -> TypList (helper ty) - | TypTuple (fst_ty, snd_ty, ty_list) -> - TypTuple (helper fst_ty, helper snd_ty, List.map ty_list ~f:helper) - | TypArrow (l, r) -> TypArrow (helper l, helper r) - | ty -> ty - in - helper - ;; - - let rec unify l r = - match l, r with - | TypUnit, TypUnit - | TypInt, TypInt - | TypChar, TypChar - | TypStr, TypStr - | TypBool, TypBool -> return empty - | TypVar l, TypVar r when String.equal l r -> return empty - | TypVar name, ty | ty, TypVar name -> singleton name ty - | TypList ty1, TypList ty2 | TypOption ty1, TypOption ty2 -> unify ty1 ty2 - | TypTuple (fst1, snd1, list1), TypTuple (fst2, snd2, list2) -> - (match - List.fold2 - (fst1 :: snd1 :: list1) - (fst2 :: snd2 :: list2) - ~init:(return empty) - ~f:(fun acc ty1 ty2 -> - let* sub_acc = acc in - let* unified_sub = unify (apply sub_acc ty1) (apply sub_acc ty2) in - compose sub_acc unified_sub) - with - | Ok res -> res - | _ -> fail (UnificationFailed (l, r))) - | TypArrow (l1, r1), TypArrow (l2, r2) -> - let* sub1 = unify l1 l2 in - let* sub2 = unify (apply sub1 r1) (apply sub1 r2) in - compose sub1 sub2 - | _ -> fail (UnificationFailed (l, r)) - - and extend key value sub = - match Map.find sub key with - | None -> - let value = apply sub value in - let* new_sub = singleton key value in - Map.fold sub ~init:(return new_sub) ~f:(fun ~key ~data acc -> - let* acc = acc in - let new_data = apply new_sub data in - return (Map.update acc key ~f:(fun _ -> new_data))) - | Some existing_value -> - let* new_sub = unify value existing_value in - compose sub new_sub - - and compose sub1 sub2 = RMap.fold sub2 ~init:(return sub1) ~f:extend - - let compose_all sub_list = RList.fold_left sub_list ~init:(return empty) ~f:compose -end - -module Scheme = struct - let free_vars (Scheme (bind_set, ty)) = VarSet.diff (Type.free_vars ty) bind_set - - let apply sub (Scheme (bind_set, ty)) = - let new_sub = VarSet.fold (fun key sub -> Subst.remove sub key) bind_set sub in - Scheme (bind_set, Subst.apply new_sub ty) - ;; -end - -module TypeEnv = struct - open Base - - type t = (id, scheme, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let free_vars env = - Map.fold env ~init:VarSet.empty ~f:(fun ~key:_ ~data acc -> - VarSet.union acc (Scheme.free_vars data)) - ;; - - let apply sub env = Map.map env ~f:(Scheme.apply sub) - let find = Map.find - - let rec extend_with_pattern env_acc pat (Scheme (bind_set, ty) as scheme) = - match pat, ty with - | PatVar id, _ -> extend env_acc id scheme - | PatTup (fst_pat, snd_pat, pat_list), TypTuple (fst_ty, snd_ty, ty_list) -> - let env = - List.fold2 - ~init:env_acc - ~f:(fun env pat ty -> extend_with_pattern env pat (Scheme (bind_set, ty))) - (fst_pat :: snd_pat :: pat_list) - (fst_ty :: snd_ty :: ty_list) - in - (match env with - | Ok env -> env - | _ -> env_acc) - | PatListConstructor pat_list, TypList ty -> - (match pat_list with - | single_pat :: [] -> - extend_with_pattern env_acc single_pat (Scheme (bind_set, TypList ty)) - | first :: rest -> - extend_with_pattern - (extend_with_pattern env_acc first (Scheme (bind_set, ty))) - (PatListConstructor rest) - (Scheme (bind_set, TypList ty)) - | [] -> env_acc) - | PatList pat_list, TypList ty -> - List.fold_left pat_list ~init:env_acc ~f:(fun env_acc pat -> - extend_with_pattern env_acc pat (Scheme (bind_set, ty))) - | PatOption (Some pat), TypOption ty -> - extend_with_pattern env_acc pat (Scheme (bind_set, ty)) - | _ -> env_acc - ;; - - (** looks for a type by key in the environment and throws an exception if the key is not found*) - let find_type_exn env key = - let (Scheme (_, ty)) = Map.find_exn env key in - ty - ;; -end - -module Infer = struct - open State - open State.Syntax - - let unify = Subst.unify - let fresh_var = fresh >>| fun n -> TypVar ("'ty" ^ Int.to_string n) - - let instantiate (Scheme (bind_set, ty)) = - VarSet.fold - (fun name ty -> - let* ty = ty in - let* fresh = fresh_var in - let* sub = Subst.singleton name fresh in - return (Subst.apply sub ty)) - bind_set - (return ty) - ;; - - (** generalizes type ty by removing certain variables from the environment, - evaluating free variables, creating new names for them, and returning a new generic schema*) - let generalize env ty ~remove_from_env id = - let env = - match remove_from_env, id, ty with - | true, Some id, TypArrow _ -> Base.Map.remove env id - | _ -> env - in - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - let new_free, new_ty, _ = - VarSet.fold - (fun str (temp_free, temp_ty, n) -> - let degree = n / 26 in - let new_str = - Printf.sprintf - "'%c%s" - (Stdlib.Char.chr (97 + (n mod 26))) - (if degree = 0 then "" else Int.to_string degree) - in - let sub = Subst.singleton1 str (TypVar new_str) in - let new_free = VarSet.add new_str temp_free in - let new_ty = Subst.apply sub temp_ty in - new_free, new_ty, n + 1) - free - (VarSet.empty, ty, 0) - in - Scheme (new_free, new_ty) - ;; - - let lookup_env id env = - match TypeEnv.find env id with - | Some scheme -> - let* ans = instantiate scheme in - return (Subst.empty, ans) - | None -> fail (NoVariable id) - ;; - - let rec infer_pattern env = function - | PatAny -> - let* fresh = fresh_var in - return (env, fresh) - | PatVar id -> - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return (env, fresh) - | PatConst const -> - (match const with - | Int _ -> return (env, TypInt) - | String _ -> return (env, TypStr) - | Char _ -> return (env, TypChar) - | Bool _ -> return (env, TypBool) - | Unit -> return (env, TypUnit)) - | PatTup (fst_pat, snd_pat, pat_list) -> - let* env1, ty1 = infer_pattern env fst_pat in - let* env2, ty2 = infer_pattern env1 snd_pat in - let* env_rest, ty_list = - RList.fold_right - ~f:(fun pat acc -> - let* env_acc, ty_list = return acc in - let* env, ty = infer_pattern env_acc pat in - return (env, ty :: ty_list)) - ~init:(return (env2, [])) - pat_list - in - return (env_rest, TypTuple (ty1, ty2, ty_list)) - | PatOption None -> - let* fresh = fresh_var in - return (env, TypOption fresh) - | PatOption (Some pat) -> - let* env, ty = infer_pattern env pat in - return (env, TypOption ty) - | PatListConstructor pat_list -> - let* fresh = fresh_var in - let rec helper env sub_acc rest = - match rest with - | [] -> return (env, sub_acc) - | single :: [] -> - let* env, ty = infer_pattern env single in - let* unified_sub = unify (TypList fresh) ty in - let* composed_sub = Subst.compose sub_acc unified_sub in - helper env composed_sub [] - | first :: rest -> - let* env, ty = infer_pattern env first in - let* unified_sub = unify fresh ty in - let* composed_sub = Subst.compose sub_acc unified_sub in - helper env composed_sub rest - in - let* env, sub = helper env Subst.empty pat_list in - let result_ty = Subst.apply sub fresh in - return (env, TypList result_ty) - | PatList pat_list -> - let* list_element_type_var = fresh_var in - let* env, sub = - RList.fold_left - pat_list - ~init:(return (env, Subst.empty)) - ~f:(fun (acc_env, acc_sub) pat -> - let* env, pat_type = infer_pattern acc_env pat in - let* unified_sub = unify list_element_type_var pat_type in - let* composed_sub = Subst.compose unified_sub acc_sub in - return (env, composed_sub)) - in - let list_element_type = Subst.apply sub list_element_type_var in - let env = TypeEnv.apply sub env in - return (env, TypList list_element_type) - | PatWithTyp (c_ty, pat) -> - let* env, ty = infer_pattern env pat in - let* unified_sub = unify ty c_ty in - return (TypeEnv.apply unified_sub env, Subst.apply unified_sub ty) - ;; - - let extend_env_with_bind_names env value_binding_list = - RList.fold_right - value_binding_list - ~init:(return (env, [])) - ~f:(fun let_bind acc -> - match let_bind with - | { pat = PatVar id | PatWithTyp (_, PatVar id); _ } -> - let* env, fresh_acc = return acc in - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return (env, fresh :: fresh_acc) - | _ -> fail NoVariableRec) - ;; - - (** Recursively traverses patterns by extracting variable names. - Applies the given func to each identifier found. - Uses the accumulator acc to store intermediate results.*) - let rec extract_names_from_pat func acc = function - | PatVar id -> func acc id - | PatTup (fst_pat, snd_pat, pat_list) -> - RList.fold_left - (fst_pat :: snd_pat :: pat_list) - ~init:(return acc) - ~f:(extract_names_from_pat func) - | PatOption (Some pat) -> extract_names_from_pat func acc pat - | PatListConstructor pat_list | PatList pat_list -> - (match pat_list with - | [] -> return acc - | first_pat :: rest_pats -> - let* acc = extract_names_from_pat func acc first_pat in - extract_names_from_pat func acc (PatList rest_pats)) - | PatWithTyp (_, pat) -> extract_names_from_pat func acc pat - | _ -> return acc - ;; - - module StringSet = struct - include Stdlib.Set.Make (String) - - let add_id set value = - if mem value set then fail (SeveralBounds value) else return (add value set) - ;; - end - - let check_names_from_let_binds = - RList.fold_left ~init:(return StringSet.empty) ~f:(fun set_acc { pat; _ } -> - extract_names_from_pat StringSet.add_id set_acc pat) - ;; - - let infer_binop_type = function - | Equals | NotEquals | GreaterThan | GreaterEquals | LessThan | LessEquals -> - fresh_var >>| fun fresh_ty -> fresh_ty, fresh_ty, TypBool - | Add | Sub | Mult | Div -> return (TypInt, TypInt, TypInt) - | And | Or -> return (TypBool, TypBool, TypBool) - ;; - - let infer_unop_type = function - | Neg -> return (TypInt, TypInt) - | Not -> return (TypBool, TypBool) - ;; - - (** takes a type environment and an expression, and then returns the type of that expression*) - let rec infer_expression env = function - | ExpVar id -> lookup_env id env - | ExpConst const -> - (match const with - | Int _ -> return (Subst.empty, TypInt) - | String _ -> return (Subst.empty, TypStr) - | Bool _ -> return (Subst.empty, TypBool) - | Char _ -> return (Subst.empty, TypChar) - | Unit -> return (Subst.empty, TypUnit)) - | ExpTup (fst_exp, snd_exp, exp_list) -> - let* sub1, ty1 = infer_expression env fst_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) snd_exp in - let env = TypeEnv.apply sub2 env in - let* sub_rest, ty_list = - RList.fold_right - ~f:(fun exp acc -> - let* sub_acc, ty_list = return acc in - let* sub, ty = infer_expression (TypeEnv.apply sub_acc env) exp in - let* sub_acc = Subst.compose sub_acc sub in - return (sub_acc, ty :: ty_list)) - ~init:(return (Subst.empty, [])) - exp_list - in - let* sub_result = Subst.compose_all [ sub1; sub2; sub_rest ] in - let ty1 = Subst.apply sub_result ty1 in - let ty2 = Subst.apply sub_result ty2 in - let ty_list = Base.List.map ~f:(fun ty -> Subst.apply sub_result ty) ty_list in - return (sub_result, TypTuple (ty1, ty2, ty_list)) - | ExpIfThenElse (if_exp, then_exp, None) -> - let* sub1, ty1 = infer_expression env if_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) then_exp in - let* sub3 = unify ty1 TypBool in - let* sub4 = unify ty2 TypUnit in - let* final_sub = Subst.compose_all [ sub4; sub3; sub2; sub1 ] in - return (final_sub, Subst.apply final_sub ty2) - | ExpIfThenElse (if_exp, then_exp, Some else_exp) -> - let* sub1, ty1 = infer_expression env if_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) then_exp in - let* sub3, ty3 = infer_expression (TypeEnv.apply sub2 env) else_exp in - let* sub4 = unify ty1 TypBool in - let* sub5 = unify ty2 ty3 in - let* final_sub = Subst.compose_all [ sub5; sub4; sub3; sub2; sub1 ] in - return (final_sub, Subst.apply final_sub ty2) - | ExpWithTyp (c_ty, exp) -> - let* sub, ty = infer_expression env exp in - let* unified_sub = unify ty c_ty in - let* final_sub = Subst.compose unified_sub sub in - return (final_sub, Subst.apply unified_sub ty) - | ExpFunction (case, case_list) -> - let* fresh_for_matching = fresh_var in - let* fresh_for_result = fresh_var in - infer_match_exp - env - ~with_exp:false - Subst.empty - fresh_for_matching - fresh_for_result - (case :: case_list) - | ExpMatch (exp, case, case_list) -> - let* exp_sub, exp_ty = infer_expression env exp in - let env = TypeEnv.apply exp_sub env in - let* fresh_for_result = fresh_var in - infer_match_exp - env - ~with_exp:true - exp_sub - exp_ty - fresh_for_result - (case :: case_list) - | ExpUnOper (operation, expr) -> - let* subst1, ty = infer_expression env expr in - let* ty1_op, ty_res = infer_unop_type operation in - let* subst2 = Subst.unify (Subst.apply subst1 ty) ty1_op in - let* subst = Subst.compose_all [ subst1; subst2 ] in - return (subst, Subst.apply subst ty_res) - | ExpBinOper (op, expr1, expr2) -> - let* subst1, ty = infer_expression env expr1 in - let* subst2, ty' = infer_expression (TypeEnv.apply subst1 env) expr2 in - let* ty1_op, ty2_op, ty_res = infer_binop_type op in - let* subst3 = Subst.unify (Subst.apply subst2 ty) ty1_op in - let* subst4 = Subst.unify (Subst.apply subst3 ty') ty2_op in - let* subst = Subst.compose_all [ subst1; subst2; subst3; subst4 ] in - return (subst, Subst.apply subst ty_res) - | ExpApp (exp1, exp2) -> - let* sub1, ty1 = infer_expression env exp1 in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) exp2 in - let* fresh = fresh_var in - let* sub3 = unify (Subst.apply sub2 ty1) (TypArrow (ty2, fresh)) in - let* composed_sub = Subst.compose_all [ sub3; sub2; sub1 ] in - let final_ty = Subst.apply composed_sub fresh in - return (composed_sub, final_ty) - | ExpList exprs -> - (match exprs with - | [] -> - let* fresh = fresh_var in - return (Subst.empty, TypList fresh) - | _ :: _ -> - let infer_list_elements env es = - let rec aux env = function - | [] -> return ([], []) - | e :: es' -> - let* s, t = infer_expression env e in - let* s', ts = aux (TypeEnv.apply s env) es' in - return (s' @ [ s ], t :: ts) - in - aux env es - in - let* subst, tys = infer_list_elements env exprs in - let* total_subst = Subst.compose_all subst in - (match tys with - | [] -> fail (SeveralBounds "inferred empty list type") - | ty :: _ -> return (total_subst, TypList ty))) - | ExpListConstructor expr_list -> - let* fresh = fresh_var in - let rec infer_list_constract env acc_sub = function - | [] -> - let* fresh1 = fresh_var in - return (Subst.empty, TypOption fresh1) - | end_element :: [] -> - let* expr_sub, expr_ty = infer_expression env end_element in - let* unified_sub = unify expr_ty (TypList fresh) in - let* composed_sub = Subst.compose_all [ expr_sub; unified_sub; acc_sub ] in - return (composed_sub, TypList (Subst.apply composed_sub fresh)) - | expr_element :: expr_rest -> - let* expr_sub, expr_ty = infer_expression env expr_element in - let* unified_sub = unify expr_ty fresh in - let* composed_sub = Subst.compose_all [ expr_sub; unified_sub; acc_sub ] in - let env = TypeEnv.apply composed_sub env in - let* sub, ty = infer_list_constract env composed_sub expr_rest in - return (sub, ty) - in - infer_list_constract env Subst.empty expr_list - | ExpOption None -> - let* fresh = fresh_var in - return (Subst.empty, TypOption fresh) - | ExpOption (Some expr) -> - let* sub, ty = infer_expression env expr in - return (sub, TypOption ty) - | ExpFun (pat, expr) -> - let* env, ty1 = infer_pattern env pat in - let* sub, ty2 = infer_expression env expr in - return (sub, TypArrow (Subst.apply sub ty1, ty2)) - | ExpLet (NonRec, value_binding, value_binding_list, exp) -> - let* _ = check_names_from_let_binds (value_binding :: value_binding_list) in - let* env, sub1 = - infer_value_binding_list env Subst.empty (value_binding :: value_binding_list) - in - let* sub2, ty2 = infer_expression env exp in - let* composed_sub = Subst.compose sub2 sub1 in - return (composed_sub, ty2) - | ExpLet (Rec, value_binding, value_binding_list, exp) -> - let* env, fresh_acc = - extend_env_with_bind_names env (value_binding :: value_binding_list) - in - let* env, sub1 = - infer_rec_value_binding_list - env - fresh_acc - Subst.empty - (value_binding :: value_binding_list) - in - let* sub2, ty2 = infer_expression env exp in - let* composed_sub = Subst.compose sub2 sub1 in - return (composed_sub, ty2) - - and infer_match_exp env ~with_exp match_exp_sub match_exp_ty result_ty case_list = - let* cases_sub, case_ty = - RList.fold_left - case_list - ~init:(return (match_exp_sub, result_ty)) - ~f:(fun acc { case_pat = pat; case_expr = case_exp } -> - let* sub_acc, ty_acc = return acc in - let* env, pat_sub = - let* env, pat_ty = infer_pattern env pat in - let* unified_sub1 = unify match_exp_ty pat_ty in - let* pat_names = - extract_names_from_pat StringSet.add_id StringSet.empty pat - >>| StringSet.elements - in - if with_exp - then ( - let env = TypeEnv.apply unified_sub1 env in - let generalized_schemes = - Base.List.map pat_names ~f:(fun name -> - let ty = TypeEnv.find_type_exn env name in - let generalized_ty = - generalize env ty ~remove_from_env:true (Some name) - in - name, generalized_ty) - in - let env = - Base.List.fold generalized_schemes ~init:env ~f:(fun env (key, value) -> - TypeEnv.extend env key value) - in - return (env, unified_sub1)) - else return (env, unified_sub1) - in - let* composed_sub1 = Subst.compose sub_acc pat_sub in - let* case_exp_sub, case_exp_ty = - infer_expression (TypeEnv.apply composed_sub1 env) case_exp - in - let* unified_sub2 = unify ty_acc case_exp_ty in - let* composed_sub2 = - Subst.compose_all [ composed_sub1; case_exp_sub; unified_sub2 ] - in - return (composed_sub2, Subst.apply composed_sub2 ty_acc)) - in - let final_ty = - if with_exp then case_ty else TypArrow (Subst.apply cases_sub match_exp_ty, case_ty) - in - return (cases_sub, final_ty) - - and infer_value_binding_list env sub let_binds = - let infer_vb new_sub env ty pat rest = - let* composed_sub = Subst.compose sub new_sub in - let env = TypeEnv.apply composed_sub env in - let generalized_ty = - generalize env (Subst.apply composed_sub ty) ~remove_from_env:false None - in - let* env, pat_ty = infer_pattern env pat in - let env = TypeEnv.extend_with_pattern env pat generalized_ty in - let* unified_sub = unify ty pat_ty in - let* final_sub = Subst.compose composed_sub unified_sub in - let env = TypeEnv.apply final_sub env in - infer_value_binding_list env final_sub rest - in - match let_binds with - | [] -> return (env, sub) - | { pat = PatWithTyp (pat_ty, pat); expr = ExpFun (e_pat, expr) } :: rest -> - let* new_sub, ty = - infer_expression env (ExpFun (e_pat, ExpWithTyp (pat_ty, expr))) - in - infer_vb new_sub env ty pat rest - | { pat = PatWithTyp (pat_ty, pat); expr = ExpFunction _ as expr } :: rest -> - let* new_sub, ty = infer_expression env (ExpWithTyp (pat_ty, expr)) in - infer_vb new_sub env ty pat rest - | { pat; expr } :: rest -> - let* new_sub, ty = infer_expression env expr in - infer_vb new_sub env ty pat rest - - and infer_rec_value_binding_list env fresh_acc sub let_binds = - let infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty = - let* new_sub = - match required_ty with - | Some c_ty -> - let* unified_sub = unify ty c_ty in - Subst.compose unified_sub new_sub - | None -> return new_sub - in - let* unified_sub = unify (Subst.apply new_sub fresh) ty in - let* composed_sub = Subst.compose_all [ new_sub; unified_sub; sub ] in - let env = TypeEnv.apply composed_sub env in - let generalized_ty = - generalize env (Subst.apply composed_sub fresh) ~remove_from_env:true (Some id) - in - let env = TypeEnv.extend env id generalized_ty in - infer_rec_value_binding_list env fresh_acc composed_sub rest - in - match let_binds, fresh_acc with - | [], _ -> return (env, sub) - | ( { pat = PatVar id; expr = (ExpFun _ | ExpFunction _) as exp } :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = infer_expression env exp in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | ( { pat = PatWithTyp (pat_ty, PatVar id); expr = ExpFun (pat, expr) } :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = infer_expression env (ExpFun (pat, ExpWithTyp (pat_ty, expr))) in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | ( { pat = PatWithTyp (pat_ty, PatVar id); expr = ExpFunction _ as expr } :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = infer_expression env (ExpWithTyp (pat_ty, expr)) in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | { pat = PatVar id; expr } :: rest, fresh :: fresh_acc -> - let* new_sub, ty = infer_expression env expr in - let update_fresh = Subst.apply new_sub fresh in - if ty = update_fresh - then fail NoArgRec - else infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | { pat = PatWithTyp (pat_ty, PatVar id); expr } :: rest, fresh :: fresh_acc -> - let* new_sub, ty = infer_expression env expr in - let update_fresh = Subst.apply new_sub fresh in - if ty = update_fresh - then fail NoArgRec - else infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:(Some pat_ty) - | _ -> fail NoVariableRec - ;; - - let infer_structure_item (env, out_list) = - let get_names_from_let_binds env = - RList.fold_left ~init:(return []) ~f:(fun acc { pat; _ } -> - extract_names_from_pat - (fun acc id -> return (acc @ [ Some id, TypeEnv.find_type_exn env id ])) - acc - pat) - in - function - | EvalExp exp -> - let* _, ty = infer_expression env exp in - return (env, out_list @ [ None, ty ]) - | Binding (NonRec, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* _ = check_names_from_let_binds value_binding_list in - let* env, _ = infer_value_binding_list env Subst.empty value_binding_list in - let* id_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ id_list) - | Binding (Rec, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env, fresh_acc = extend_env_with_bind_names env value_binding_list in - let* env, _ = - infer_rec_value_binding_list env fresh_acc Subst.empty value_binding_list - in - let* id_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ id_list) - ;; - - let infer_srtucture env ast = - let* env, out_list = - RList.fold_left ast ~init:(return (env, [])) ~f:infer_structure_item - in - let remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (Some id1, _), (Some id2, _) -> String.equal id1 id2 - | _ -> false - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> x :: xs - | _ :: xs -> xs - | [] -> [] - in - return (env, remove_duplicates out_list) - ;; -end - -let empty_env = TypeEnv.empty - -let env_with_print_funs = - let print_fun_list = - [ "print_int", Scheme (VarSet.empty, TypArrow (TypInt, TypUnit)) - ; "print_endline", Scheme (VarSet.empty, TypArrow (TypStr, TypUnit)) - ] - in - Base.List.fold_left - ~f:(fun env (id, sch) -> TypeEnv.extend env id sch) - ~init:TypeEnv.empty - print_fun_list -;; - -let run_inferencer env ast = State.run (Infer.infer_srtucture env ast) diff --git a/ETenyaeva/lib/inferencer.mli b/ETenyaeva/lib/inferencer.mli deleted file mode 100644 index 104013c34..000000000 --- a/ETenyaeva/lib/inferencer.mli +++ /dev/null @@ -1,41 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - | NoVariableRec - | NoArgRec - | SeveralBounds of string - | OccursCheck of string * Ast.typ - | NoVariable of string - | UnificationFailed of Ast.typ * Ast.typ - -val pp_type : Format.formatter -> Ast.typ -> unit -val pp_error : Format.formatter -> error -> unit - -module VarSet : sig - type t - - val empty : t - val add : string -> t -> t - val remove : string -> t -> t - val mem : string -> t -> bool - val union : t -> t -> t - val inter : t -> t -> t - val diff : t -> t -> t - val elements : t -> string list -end - -type scheme = Scheme of VarSet.t * Ast.typ - -module TypeEnv : sig - type t = (Ast.id, scheme, Base.String.comparator_witness) Base.Map.t -end - -val empty_env : TypeEnv.t -val env_with_print_funs : TypeEnv.t - -val run_inferencer - : TypeEnv.t - -> Ast.structure - -> (TypeEnv.t * (Ast.id option * Ast.typ) list, error) result diff --git a/ETenyaeva/lib/interpreter.ml b/ETenyaeva/lib/interpreter.ml deleted file mode 100644 index a0d8646e2..000000000 --- a/ETenyaeva/lib/interpreter.ml +++ /dev/null @@ -1,435 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - | TypeError - | DivisionByZero - | MatchFailure - | NoVariable of id - -let pp_error ppf : error -> _ = function - | TypeError -> Format.fprintf ppf "Type error" - | DivisionByZero -> Format.fprintf ppf "Division by zero" - | MatchFailure -> Format.fprintf ppf "Matching failure" - | NoVariable id -> Format.fprintf ppf "Undefined variable '%s'" id -;; - -type value = - | ValInt of int - | ValChar of char - | ValString of string - | ValUnit - | ValBool of bool - | ValFun of rec_flag * pattern * expr * env - | ValFunction of case_expr list * env - | ValTuple of value * value * value list - | ValList of value list - | ValOption of value option - | ValBuiltin of id - -and env = (id, value, Base.String.comparator_witness) Base.Map.t - -let rec pp_value ppf = - let open Stdlib.Format in - function - | ValInt int -> fprintf ppf "%i" int - | ValChar char -> fprintf ppf "'%c'" char - | ValString str -> fprintf ppf "%S" str - | ValBool bool -> fprintf ppf "%b" bool - | ValUnit -> fprintf ppf "()" - | ValOption value -> - (match value with - | Some value -> fprintf ppf "Some %a" pp_value value - | None -> fprintf ppf "None") - | ValList vls -> - fprintf - ppf - "[%a]" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf "; ") pp_value) - vls - | ValTuple (fst_val, snd_val, val_list) -> - fprintf - ppf - "(%a)" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - (fst_val :: snd_val :: val_list) - | ValFun _ -> fprintf ppf "" - | ValFunction _ -> fprintf ppf "" - | ValBuiltin _ -> fprintf ppf "" -;; - -module Res = struct - open Base - - type 'a t = ('a, error) Result.t - - let fail = Result.fail - let return = Result.return - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - match monad with - | Ok result -> f result - | Error x -> fail x - ;; - - let ( let* ) = ( >>= ) -end - -module EvalEnv = struct - open Base - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let compose env1 env2 = - Map.fold env2 ~f:(fun ~key ~data env_acc -> extend env_acc key data) ~init:env1 - ;; - - let find_exn env key = - match Map.find env key with - | Some value -> Res.return value - | None -> Res.fail (NoVariable key) - ;; - - let find_exn1 env key = - let val' = Map.find_exn env key in - val' - ;; -end - -module Inter = struct - open Res - open EvalEnv - - let eval_arith opr val1 val2 = return (ValInt (opr val1 val2)) - let eval_eq opr val1 val2 = return (ValBool (opr val1 val2)) - let eval_bool opr val1 val2 = return (ValBool (opr val1 val2)) - - let eval_un_op = function - | Neg, ValInt val1 -> return (ValInt (-val1)) - | Not, ValBool val1 -> return (ValBool (not val1)) - | _ -> fail TypeError - ;; - - let eval_bin_op = function - | Mult, ValInt val1, ValInt val2 -> eval_arith ( * ) val1 val2 - | Div, ValInt val1, ValInt val2 when val2 <> 0 -> eval_arith ( / ) val1 val2 - | Div, _, ValInt 0 -> fail DivisionByZero - | Add, ValInt val1, ValInt val2 -> eval_arith ( + ) val1 val2 - | Sub, ValInt val1, ValInt val2 -> eval_arith ( - ) val1 val2 - | GreaterEquals, val1, val2 -> eval_eq ( >= ) val1 val2 - | LessEquals, val1, val2 -> eval_eq ( <= ) val1 val2 - | NotEquals, val1, val2 -> eval_eq ( <> ) val1 val2 - | Equals, val1, val2 -> eval_eq ( = ) val1 val2 - | GreaterThan, val1, val2 -> eval_eq ( > ) val1 val2 - | LessThan, val1, val2 -> eval_eq ( < ) val1 val2 - | And, ValBool val1, ValBool val2 -> eval_bool ( && ) val1 val2 - | Or, ValBool val1, ValBool val2 -> eval_bool ( || ) val1 val2 - | _ -> fail TypeError - ;; - - let rec match_pattern env = function - | PatAny, _ -> Some env - | PatVar name, value -> Some (extend env name value) - | PatConst (Int pat), ValInt value when pat = value -> Some env - | PatConst (Char pat), ValChar value when pat = value -> Some env - | PatConst (Bool pat), ValBool value when pat = value -> Some env - | PatConst Unit, _ -> Some env - | PatConst (String pat), ValString value when pat = value -> Some env - | PatTup (fst_pat, snd_pat, pat_list), ValTuple (fst_val, snd_val, val_list) -> - let env = - Base.List.fold2 - ~f:(fun env pat value -> - match env with - | Some env -> match_pattern env (pat, value) - | None -> None) - ~init:(Some env) - (fst_pat :: snd_pat :: pat_list) - (fst_val :: snd_val :: val_list) - in - (match env with - | Ok env -> env - | _ -> None) - | PatListConstructor pat_list, ValList val_list -> - (match pat_list, val_list with - | single_pat :: [], val_list -> match_pattern env (single_pat, ValList val_list) - | _ :: _ :: _, [] -> None - | first_pat :: rest_pat, first_val :: rest_val -> - let env = match_pattern env (first_pat, first_val) in - (match env with - | Some env -> match_pattern env (PatListConstructor rest_pat, ValList rest_val) - | None -> None) - | _ -> None) - | PatList pat_list, ValList val_list -> - (match pat_list, val_list with - | [], [] -> Some env - | first_pat :: rest_pat, first_val :: rest_val -> - let env = match_pattern env (first_pat, first_val) in - (match env with - | Some env -> match_pattern env (PatList rest_pat, ValList rest_val) - | None -> None) - | _ -> None) - | PatWithTyp (_, pat), value -> match_pattern env (pat, value) - | PatOption None, ValOption None -> Some env - | PatOption (Some pat), ValOption (Some value) -> match_pattern env (pat, value) - | _ -> None - ;; - - let rec extend_names_from_pat env = function - | PatAny, _ -> return env - | PatConst Unit, ValUnit -> return env - | PatOption None, ValOption None -> return env - | PatVar id, value -> return (extend env id value) - | PatTup (fst_pat, snd_pat, pat_list), ValTuple (fst_val, snd_val, val_list) -> - (match - Base.List.fold2 - (fst_pat :: snd_pat :: pat_list) - (fst_val :: snd_val :: val_list) - ~init:(return env) - ~f:(fun acc pat value -> - let* env = acc in - extend_names_from_pat env (pat, value)) - with - | Ok acc -> acc - | _ -> fail TypeError) - | PatList pat_list, ValList val_list -> - (match pat_list, val_list with - | first_pat :: rest_pat, first_val :: rest_val -> - let* env = extend_names_from_pat env (first_pat, first_val) in - let* env = extend_names_from_pat env (PatList rest_pat, ValList rest_val) in - return env - | _, _ -> return env) - | PatListConstructor pat_list, ValList val_list -> - (match pat_list, val_list with - | first_pat :: rest_pat, first_val :: rest_val -> - let* env = extend_names_from_pat env (first_pat, first_val) in - let* env = - extend_names_from_pat env (PatListConstructor rest_pat, ValList rest_val) - in - return env - | _, _ -> return env) - | PatOption (Some pat), ValOption (Some value) -> - extend_names_from_pat env (pat, value) - | _ -> fail TypeError - ;; - - let rec eval_expression env = function - | ExpVar id -> find_exn env id - | ExpConst const -> - (match const with - | Int int -> return (ValInt int) - | Char char -> return (ValChar char) - | String str -> return (ValString str) - | Bool bool -> return (ValBool bool) - | Unit -> return ValUnit) - | ExpLet (NonRec, value_binding, value_binding_list, exp) -> - let* env = eval_value_binding_list env (value_binding :: value_binding_list) in - eval_expression env exp - | ExpLet (Rec, value_binding, value_binding_list, exp) -> - let* env = eval_rec_value_binding_list env (value_binding :: value_binding_list) in - eval_expression env exp - | ExpFun (pat, exp) -> return (ValFun (NonRec, pat, exp, env)) - | ExpFunction (case, case_list) -> return (ValFunction (case :: case_list, env)) - | ExpMatch (exp, case, case_list) -> - let* match_value = eval_expression env exp in - find_and_eval_case env match_value (case :: case_list) - | ExpBinOper (op, exp1, exp2) -> - let* value1 = eval_expression env exp1 in - let* value2 = eval_expression env exp2 in - eval_bin_op (op, value1, value2) - | ExpUnOper (op, e) -> - let* v = eval_expression env e in - eval_un_op (op, v) - | ExpListConstructor expr_list -> - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - match value with - | ValList lst -> return (lst @ acc) - | _ -> return (value :: acc)) - ~init:(return []) - expr_list - in - return (ValList val_list) - | ExpList expr_list -> - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - return (value :: acc)) - ~init:(return []) - expr_list - in - return (ValList val_list) - | ExpApp (exp1, exp2) -> - let* fun_val = eval_expression env exp1 in - let* arg_val = eval_expression env exp2 in - (match fun_val with - | ValFun (rec_flag, pat, exp, fun_env) -> - let* new_env = - match rec_flag, match_pattern fun_env (pat, arg_val) with - | Rec, Some extended_env -> return (compose env extended_env) - | NonRec, Some extended_env -> return extended_env - | _, None -> fail MatchFailure - in - eval_expression new_env exp - | ValFunction (case_list, env) -> find_and_eval_case env arg_val case_list - | ValBuiltin builtin -> - (match builtin, arg_val with - | "print_int", ValInt integer -> - Format.printf "%d\n" integer; - return ValUnit - | "print_endline", ValString str -> - print_endline str; - return ValUnit - | _ -> fail TypeError) - | _ -> fail TypeError) - | ExpOption None -> return (ValOption None) - | ExpOption (Some expr) -> - let* value = eval_expression env expr in - return (ValOption (Some value)) - | ExpTup (fst_exp, snd_exp, exp_list) -> - let* fst_val = eval_expression env fst_exp in - let* snd_val = eval_expression env snd_exp in - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - return (value :: acc)) - ~init:(return []) - exp_list - in - return (ValTuple (fst_val, snd_val, val_list)) - | ExpIfThenElse (if_exp, then_exp, Some else_exp) -> - let* value_if_exp = eval_expression env if_exp in - (match value_if_exp with - | ValBool true -> eval_expression env then_exp - | ValBool false -> eval_expression env else_exp - | _ -> fail TypeError) - | ExpIfThenElse (fst_val, snd_val, None) -> - let* value_fst_val = eval_expression env fst_val in - (match value_fst_val with - | ValBool true -> - let* value_snd_val = eval_expression env snd_val in - (match value_snd_val with - | ValUnit as v -> return v - | _ -> fail TypeError) - | ValBool false -> return ValUnit - | _ -> fail TypeError) - | ExpWithTyp (_, exp) -> eval_expression env exp - - and find_and_eval_case env value = function - | [] -> fail MatchFailure - | { case_pat; case_expr } :: tail -> - let env_temp = match_pattern env (case_pat, value) in - (match env_temp with - | Some env -> eval_expression env case_expr - | None -> find_and_eval_case env value tail) - - and eval_value_binding_list env value_binding_list = - Base.List.fold_left - ~f:(fun acc { pat; expr } -> - let* env = acc in - let* value = eval_expression env expr in - match pat with - | PatVar name | PatWithTyp (_, PatVar name) -> - let env = extend env name value in - return env - | _ -> - let* env = extend_names_from_pat env (pat, value) in - return env) - ~init:(return env) - value_binding_list - - and eval_rec_value_binding_list env value_binding_list = - Base.List.fold_left - ~f:(fun acc { pat; expr } -> - let* env = acc in - let* value = eval_expression env expr in - match pat with - | PatVar name | PatWithTyp (_, PatVar name) -> - let value = - match value with - | ValFun (_, pat, expr, env) -> ValFun (Rec, pat, expr, env) - | other -> other - in - let env = extend env name value in - return env - | _ -> fail TypeError) - ~init:(return env) - value_binding_list - ;; - - let eval_structure_item env out_list = - let rec extract_names_from_pat env acc = function - | PatVar id -> acc @ [ Some id, EvalEnv.find_exn1 env id ] - | PatTup (fst_pat, snd_pat, pat_list) -> - Base.List.fold_left - (fst_pat :: snd_pat :: pat_list) - ~init:acc - ~f:(extract_names_from_pat env) - | PatList pat_list -> - Base.List.fold_left pat_list ~init:acc ~f:(extract_names_from_pat env) - | PatWithTyp (_, pat) -> extract_names_from_pat env acc pat - | _ -> acc - in - let get_names_from_let_binds env = - Base.List.fold_left ~init:[] ~f:(fun acc { pat; _ } -> - extract_names_from_pat env acc pat) - in - function - | EvalExp exp -> - let* val' = eval_expression env exp in - return (env, out_list @ [ None, val' ]) - | Binding (NonRec, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env = eval_value_binding_list env value_binding_list in - let eval_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ eval_list) - | Binding (Rec, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env = eval_rec_value_binding_list env value_binding_list in - let eval_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ eval_list) - ;; - - let eval_structure env ast = - let* env, out_list = - Base.List.fold_left - ~f:(fun acc item -> - let* env, out_list = acc in - let* env, out_list = eval_structure_item env out_list item in - return (env, out_list)) - ~init:(return (env, [])) - ast - in - let remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (Some id1, _), (Some id2, _) -> String.equal id1 id2 - | _ -> false - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> x :: xs - | _ :: xs -> xs - | [] -> [] - in - return (env, remove_duplicates out_list) - ;; -end - -let empty_env = EvalEnv.empty - -let env_with_print_funs = - let env = EvalEnv.extend empty_env "print_int" (ValBuiltin "print_int") in - EvalEnv.extend env "print_endline" (ValBuiltin "print_endline") -;; - -let run_interpreter = Inter.eval_structure diff --git a/ETenyaeva/lib/interpreter.mli b/ETenyaeva/lib/interpreter.mli deleted file mode 100644 index 06c182310..000000000 --- a/ETenyaeva/lib/interpreter.mli +++ /dev/null @@ -1,39 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - | TypeError - (** Represents a type error that occurs when a type mismatch is detected in an expression. *) - | DivisionByZero - (** Represents the error that occurs when attempting to perform a division by zero operation. *) - | MatchFailure - (** Represents a match error occurs when a pattern matching attempt fails. *) - | NoVariable of Ast.id - (** Represents an error that occurs when attempting to use a variable that has not been declared or initialized. *) - -val pp_error : Format.formatter -> error -> unit - -type value = - | ValInt of int - | ValChar of char - | ValString of string - | ValUnit - | ValBool of bool - | ValFun of Ast.rec_flag * Ast.pattern * Ast.expr * env - | ValFunction of Ast.case_expr list * env - | ValTuple of value * value * value list - | ValList of value list - | ValOption of value option - | ValBuiltin of Ast.id - -and env = (Ast.id, value, Base.String.comparator_witness) Base.Map.t - -val pp_value : Format.formatter -> value -> unit -val empty_env : env -val env_with_print_funs : env - -val run_interpreter - : env - -> Ast.structure - -> (env * (Ast.id option * value) list, error) result diff --git a/ETenyaeva/lib/parser.ml b/ETenyaeva/lib/parser.ml deleted file mode 100644 index 9058dbc59..000000000 --- a/ETenyaeva/lib/parser.ml +++ /dev/null @@ -1,482 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Ast -open Angstrom - -let skip_whitespaces = skip_while Char.is_whitespace - -let parse_comments = - skip_whitespaces *> string "(*" *> many_till any_char (string "*)") *> return () -;; - -let ws = many parse_comments *> skip_whitespaces -let token str = ws *> string str - -let skip_round_par parse = - token "(" *> parse <* (token ")" <|> fail "There is no closing bracket.") -;; - -let is_keyword = function - | "let" - | "rec" - | "and" - | "if" - | "then" - | "else" - | "match" - | "with" - | "in" - | "true" - | "false" - | "Some" - | "None" - | "type" - | "val" - | "while" - | "for" - | "_" -> true - | _ -> false -;; - -let is_separator = function - | ')' - | '(' - | '<' - | '>' - | '@' - | ',' - | ';' - | ':' - | '\\' - | '"' - | '/' - | '[' - | ']' - | '?' - | '=' - | '{' - | '}' - | ' ' - | '\r' - | '\t' - | '\n' - | '*' - | '-' -> true - | _ -> false -;; - -let keyword str = - token str - *> - let* is_space = - peek_char - >>| function - | Some c -> is_separator c - | None -> true - in - if is_space - then return str <* ws - else fail (Printf.sprintf "There is no separator after %S." str) -;; - -let safe_tl = function - | [] -> [] - | _ :: tail -> tail -;; - -let parse_chain_left_associative parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* elem = parse in - go (f acc elem)) - <|> return acc - in - let* elem = parse in - go elem -;; - -let parse_chain_right_associative parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* elem = parse in - let* next_elem = go elem in - return (f acc next_elem)) - <|> return acc - in - let* elem = parse in - go elem -;; - -(* ==================== constant ==================== *) - -let parse_const_int = - take_while1 Char.is_digit >>| fun int_value -> Int (Int.of_string int_value) -;; - -let parse_const_char = - string "\'" *> any_char <* string "\'" >>| fun char_value -> Char char_value -;; - -let parse_const_string = - choice - [ string "\"" *> take_till (Char.equal '\"') <* string "\"" - ; string "{|" *> take_till (Char.equal '|') <* string "|}" - ] - >>| fun str_value -> String str_value -;; - -let parse_const_unit = string "()" >>| fun _ -> Unit - -let parse_const_bool = - string "true" >>| (fun _ -> Bool true) <|> (string "false" >>| fun _ -> Bool false) -;; - -let parse_constant = - ws - *> choice - [ parse_const_int - ; parse_const_char - ; parse_const_string - ; parse_const_bool - ; parse_const_unit - ] -;; - -(* ==================== ident ==================== *) - -let parse_ident = - ws - *> - let* fst_char = - satisfy (function - | 'a' .. 'z' | '_' -> true - | _ -> false) - >>| String.of_char - in - let* rest_str = - take_while (function - | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' -> true - | _ -> false) - in - let id = fst_char ^ rest_str in - if is_keyword id then fail (Printf.sprintf "Impossible name: %S." id) else return id -;; - -(* --------------------- type ---------------------- *) - -let parse_base_type = - choice - [ keyword "unit" *> return TypUnit - ; keyword "int" *> return TypInt - ; keyword "char" *> return TypChar - ; keyword "string" *> return TypStr - ; keyword "bool" *> return TypBool - ] -;; - -let parse_tuple_type parse_type = - let* fst_type = parse_type in - let* snd_type = token "*" *> parse_type in - let* type_list = many (token "*" *> parse_type) in - return (TypTuple (fst_type, snd_type, type_list)) -;; - -let parse_list_type parse_type = - let f acc_ty = function - | "list" -> TypList acc_ty - | _ -> TypUnit - in - let rec go acc_ty = - let* ty = keyword "list" in - go (f acc_ty ty) <|> return acc_ty - in - let* fst_ty = parse_type in - go fst_ty -;; - -let parse_core_type = - ws - *> fix (fun parse_full_type -> - let parse_type = parse_base_type <|> skip_round_par parse_full_type in - let parse_type = parse_list_type parse_type <|> parse_type in - parse_tuple_type parse_type <|> parse_type) -;; - -(* -------------------- pattern -------------------- *) - -let parse_pat_with_type parse_pat = - let* pat = ws *> token "(" *> parse_pat in - let* constr = ws *> token ":" *> ws *> parse_core_type <* ws <* token ")" in - return (PatWithTyp (constr, pat)) -;; - -let parse_pat_any = keyword "_" *> return PatAny -let parse_pat_var = parse_ident >>| fun var -> PatVar var -let parse_pat_constant = parse_constant >>| fun const -> PatConst const - -let parse_tuple parse tuple = - let* fst = parse in - let* snd = token "," *> parse in - let* tail = many (token "," *> parse) in - return (tuple (fst, snd, tail)) -;; - -let parse_pat_tuple parse_pat = - parse_tuple parse_pat (fun (fst_pat, snd_pat, pat_list) -> - PatTup (fst_pat, snd_pat, pat_list)) -;; - -let parse_pattern_option parse_pat = - lift - (fun e -> PatOption e) - (keyword "Some" *> parse_pat - >>| (fun e -> Some e) - <|> (keyword "None" >>| fun _ -> None)) -;; - -let parse_list_construct_case_pattern parse_pat = - let* first = parse_pat in - let* rest = many1 @@ (token "::" *> parse_pat) in - return (PatListConstructor (first :: rest)) -;; - -let parse_pattern_list parse_pat = - let empty_list_parser = - let* _ = token "[" *> token "]" in - return (PatList []) - in - let list_parser = - let* _ = token "[" in - let* first = parse_pat in - let* rest = many (token ";" *> parse_pat) in - let* _ = token "]" in - return (PatList (first :: rest)) - in - empty_list_parser <|> list_parser -;; - -let parse_pattern = - ws - *> fix (fun parse_full_pat -> - let parse_pat = - choice - [ parse_pat_var - ; parse_pat_with_type parse_full_pat - ; parse_pat_any - ; parse_pat_constant - ; parse_pattern_list parse_full_pat - ; skip_round_par parse_full_pat - ; parse_pattern_option parse_full_pat - ] - in - let parse_pat = parse_pat_tuple parse_pat <|> parse_pat in - let parse_pat = parse_pattern_list parse_pat <|> parse_pat in - let parse_pat = parse_list_construct_case_pattern parse_pat <|> parse_pat in - parse_pat) -;; - -(* -------------------- operator -------------------- *) - -let cmp = - choice - [ token "=" *> return Equals - ; token "<>" *> return NotEquals - ; token "<=" *> return LessEquals - ; token ">=" *> return GreaterEquals - ; token "<" *> return LessThan - ; token ">" *> return GreaterThan - ] -;; - -let logical = choice [ token "&&" *> return And; token "||" *> return Or ] -let add_sub = choice [ token "+" *> return Add; token "-" *> return Sub ] -let mult_div = choice [ token "/" *> return Div; token "*" *> return Mult ] - -let bin_op chain1 parse_exp parse_fun_op = - chain1 parse_exp (parse_fun_op >>| fun opr exp1 exp2 -> ExpBinOper (opr, exp1, exp2)) -;; - -let parse_left_bin_op = bin_op parse_chain_left_associative -let parse_right_bin_op = bin_op parse_chain_right_associative -let parse_un_oper = choice [ token "-" *> return Neg; keyword "not" *> return Not ] - -(* -------------------- expression -------------------- *) - -let parse_exp_with_type parse_exp = - let* expr = ws *> token "(" *> parse_exp in - let* constr = ws *> token ":" *> ws *> parse_core_type <* ws <* token ")" in - return (ExpWithTyp (constr, expr)) -;; - -let parse_exp_ident = parse_ident >>| fun id -> ExpVar id -let parse_exp_constant = parse_constant >>| fun const -> ExpConst const - -let parse_exp_tuple parse_exp = - parse_tuple parse_exp (fun (fst_exp, snd_exp, exp_list) -> - ExpTup (fst_exp, snd_exp, exp_list)) -;; - -let parse_list_construct_case_exp parse_exp = - let* first = parse_exp in - let* rest = many1 (token "::" *> parse_exp) in - return (ExpListConstructor (first :: rest)) -;; - -let parse_exp_list parse_exp = - let empty_list_parser = - let* _ = token "[" *> token "]" in - return (ExpList []) - in - let list_parser = - let* _ = token "[" in - let* first = parse_exp in - let* rest = many (token ";" *> parse_exp) in - let* _ = token "]" in - return (ExpList (first :: rest)) - in - empty_list_parser <|> list_parser -;; - -let parse_exp_fun parse_exp = - keyword "fun" - *> - let* pat = parse_pattern in - let* params = many parse_pattern in - token "->" - *> - let* body_exp = parse_exp in - let exp = - match params with - | [] -> body_exp - | _ -> List.fold_right ~f:(fun par acc -> ExpFun (par, acc)) params ~init:body_exp - in - return (ExpFun (pat, exp)) -;; - -let parse_exp_ifthenelse parse_expr = - lift3 - (fun cond t f -> ExpIfThenElse (cond, t, f)) - (keyword "if" *> parse_expr) - (keyword "then" *> parse_expr) - (option None (keyword "else" *> parse_expr >>| Option.some)) -;; - -let parse_match_case parse_exp = - ws - *> option () (token "|" *> return ()) - *> - let* pat = parse_pattern in - let* exp = token "->" *> parse_exp in - return { case_pat = pat; case_expr = exp } -;; - -let parse_exp_match parse_exp = - let* exp = keyword "match" *> parse_exp <* keyword "with" in - let* case_list = sep_by1 (token "|") (parse_match_case parse_exp) in - return (ExpMatch (exp, List.hd_exn case_list, safe_tl case_list)) -;; - -let parse_exp_function parse_exp = - keyword "function" - *> - let* case_list = sep_by1 (token "|") (parse_match_case parse_exp) in - return (ExpFunction (List.hd_exn case_list, safe_tl case_list)) -;; - -let parse_exp_bin_op parse_exp = - let parse_exp = parse_left_bin_op parse_exp mult_div in - let parse_exp = parse_left_bin_op parse_exp add_sub in - let parse_exp = parse_left_bin_op parse_exp cmp in - parse_right_bin_op parse_exp logical -;; - -let parse_exp_un_oper parse_exp = - parse_un_oper >>= fun op -> parse_exp >>= fun expr -> return (ExpUnOper (op, expr)) -;; - -let parse_exp_option parse_exp = - choice - [ keyword "None" *> return (ExpOption None) - ; (keyword "Some" *> choice [ skip_round_par parse_exp; parse_exp ] - >>| fun e -> ExpOption (Some e)) - ] -;; - -let parse_binding parse_exp = - let* pattern = parse_pattern in - let* xs = many parse_pattern in - let+ parse_exp = token "=" *> parse_exp in - { pat = pattern - ; expr = - (match xs with - | [] -> parse_exp - | _ -> List.fold_right ~f:(fun f p -> ExpFun (f, p)) xs ~init:parse_exp) - } -;; - -let parse_exp_let parse_exp = - keyword "let" - *> - let* rec_flag = keyword "rec" *> return Rec <|> return NonRec in - let* vb = parse_binding parse_exp in - let* value_bindings = many (keyword "and" *> parse_binding parse_exp) in - let+ expr = keyword "in" *> parse_exp in - ExpLet (rec_flag, vb, value_bindings, expr) -;; - -let parse_exp_apply parse_exp = - parse_chain_left_associative parse_exp (return (fun exp1 exp2 -> ExpApp (exp1, exp2))) -;; - -let parse_expression = - ws - *> fix (fun expr -> - let expr_const = - choice - [ skip_round_par expr - ; parse_exp_option expr - ; parse_exp_constant - ; parse_exp_with_type expr - ; parse_exp_ident - ; parse_exp_ifthenelse expr - ] - in - let expr_fun = parse_exp_fun expr <|> expr_const in - let expr_list = parse_exp_list expr <|> expr_fun in - let expr_apply = parse_exp_apply expr_list <|> expr_list in - let expr_bin_op = parse_exp_bin_op expr_apply <|> expr_apply in - let expr_un_op = parse_exp_un_oper expr_bin_op <|> expr_bin_op in - let expr_cons = parse_list_construct_case_exp expr_un_op <|> expr_un_op in - let expr_let_in = parse_exp_let expr <|> expr_cons in - let expr_function = parse_exp_function expr <|> expr_let_in in - let expr_match = parse_exp_match expr <|> expr_function in - let expr_tuple = parse_exp_tuple expr_match <|> expr_match in - expr_tuple) -;; - -(* ==================== structure ==================== *) - -let parse_structure_value parse_exp = - keyword "let" - *> - let* rec_flag = keyword "rec" *> return Rec <|> return NonRec in - let* vb = parse_binding parse_exp in - let+ value_bindings = many (keyword "and" *> parse_binding parse_exp) in - Binding (rec_flag, vb, value_bindings) -;; - -let parse_structure = - ws - *> - let str_value = parse_structure_value parse_expression in - let str_eval = str_value <|> (parse_expression >>| fun ex -> EvalExp ex) in - let semicolons = many (token ";;") in - sep_by semicolons str_eval <* semicolons <* ws -;; - -(* ==================== execute ==================== *) - -let parse = parse_string ~consume:All parse_structure diff --git a/ETenyaeva/lib/parser.mli b/ETenyaeva/lib/parser.mli deleted file mode 100644 index e2cc1fcac..000000000 --- a/ETenyaeva/lib/parser.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> (Ast.structure, string) result diff --git a/ETenyaeva/tests/.gitignore b/ETenyaeva/tests/.gitignore deleted file mode 100644 index 26685e795..000000000 --- a/ETenyaeva/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -lam*.txt \ No newline at end of file diff --git a/ETenyaeva/tests/dune b/ETenyaeva/tests/dune deleted file mode 100644 index 6dcce80de..000000000 --- a/ETenyaeva/tests/dune +++ /dev/null @@ -1,41 +0,0 @@ -(include_subdirs no) - -(library - (name tests) - (libraries ETenyaeva_lib) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to *) - (deps - ../bin/REPL.exe - manytests/typed/001fac.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/006partial.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml)) diff --git a/ETenyaeva/tests/inferencer.ml b/ETenyaeva/tests/inferencer.ml deleted file mode 100644 index d65793b49..000000000 --- a/ETenyaeva/tests/inferencer.ml +++ /dev/null @@ -1,142 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open ETenyaeva_lib.Parser - -(* open ETenyaeva_lib.Ast *) -open ETenyaeva_lib.Inferencer - -let run input = - match parse input with - | Ok ast -> - (match run_inferencer empty_env ast with - | Ok (_, out_list) -> - List.iter - (function - | Some id, type' -> Format.printf "val %s : %a\n" id pp_type type' - | None, type' -> Format.printf "- : %a\n" pp_type type') - out_list - | Error e -> Format.printf "Inferencer error: %a\n" pp_error e) - | Error _ -> Format.printf "Parsing error\n" -;; - -let%expect_test "parsing error" = - run {| - let a = ;; - |}; - [%expect {| - Parsing error - |}] -;; - -let%expect_test "const" = - run {| - 1;; - |}; - [%expect {| - - : int - |}] -;; - -let%expect_test "const list" = - run {| - [1; 2; 3; 4];; - |}; - [%expect {| - - : int list - |}] -;; - -let%expect_test "binary oper with const" = - run {| - 1 + 3 - 400 / 3 * 2;; - |}; - [%expect {| - - : int - |}] -;; - -let%expect_test "unary oper with const" = - run {| - not false;; -2 - |}; - [%expect {| - - : bool - - : int - |}] -;; - -let%expect_test "match" = - run {| - match 1 + 2 with - | 3 -> 4 - | _ -> 3 - ;; - |}; - [%expect {| - - : int - |}] -;; - -let%expect_test "type check negative expression" = - run {| - let f a q = -(if a then q else -q) - |}; - [%expect {| - val f : bool -> int -> int - |}] -;; - -let%expect_test "type check definition tuple" = - run {| - let (a, b) = (1, 2);; - |}; - [%expect {| - val a : int - val b : int - |}] -;; - -let%expect_test "type check several definition variable" = - run {| - let f = 1 and r = "qwe";; let q = 2 - |}; - [%expect {| - val f : int - val r : string - val q : int - |}] -;; - -let%expect_test "type check several recursive definition" = - run {| - let rec f1 a = a + 1 and f2 b = f1 b;; - |}; - [%expect {| - val f1 : int -> int - val f2 : int -> int - |}] -;; - -let%expect_test "type check lenght" = - run {| - let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl - |}; - [%expect {| - val length : 'a list -> int - |}] -;; - -let%expect_test "type check let and" = - run {| - let rec f1 a = a + 1 and f2 b = f1 b;; - |}; - [%expect {| - val f1 : int -> int - val f2 : int -> int - |}] -;; diff --git a/ETenyaeva/tests/inferencer.mli b/ETenyaeva/tests/inferencer.mli deleted file mode 100644 index 72580acbb..000000000 --- a/ETenyaeva/tests/inferencer.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/ETenyaeva/tests/inferencer_mantests_typed.t b/ETenyaeva/tests/inferencer_mantests_typed.t deleted file mode 100644 index 5566f0c3f..000000000 --- a/ETenyaeva/tests/inferencer_mantests_typed.t +++ /dev/null @@ -1,79 +0,0 @@ - $ cat manytests/typed/001fac.ml | ../bin/REPL.exe --dinference - val fac : int -> int - val main : int - - $ cat manytests/typed/002fac.ml | ../bin/REPL.exe --dinference - val fac_cps : int -> (int -> 'a) -> 'a - val main : int - - $ cat manytests/typed/003fib.ml | ../bin/REPL.exe --dinference - val fib_acc : int -> int -> int -> int - val fib : int -> int - val main : int - - $ cat manytests/typed/004manyargs.ml | ../bin/REPL.exe --dinference - val wrap : 'a -> 'a - val test3 : int -> int -> int -> int - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val main : int - - $ cat manytests/typed/005fix.ml | ../bin/REPL.exe --dinference - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val fac : (int -> int) -> int -> int - val main : int - - $ cat manytests/typed/006partial.ml | ../bin/REPL.exe --dinference - val foo : int -> int - val main : int - - $ cat manytests/typed/006partial2.ml | ../bin/REPL.exe --dinference - val foo : int -> int -> int -> int - val main : int - - $ cat manytests/typed/006partial3.ml | ../bin/REPL.exe --dinference - val foo : int -> int -> int -> unit - val main : int - - $ cat manytests/typed/007order.ml | ../bin/REPL.exe --dinference - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main : unit - - $ cat manytests/typed/008ascription.ml | ../bin/REPL.exe --dinference - val addi : ('a -> bool -> int) -> ('a -> bool) -> 'a -> int - val main : int - - $ cat manytests/typed/009let_poly.ml | ../bin/REPL.exe --dinference - val temp : int * bool - - $ cat manytests/typed/010sukharev.ml | ../bin/REPL.exe --dinference - val _1 : int -> int -> int * 'a -> bool - val _2 : int - val _3 : (int * string) option - val _4 : int -> 'a - val _5 : int - val _6 : 'a option -> 'a - val int_of_option : int option -> int - val _42 : int -> bool - val id1 : 'a -> 'a - val id2 : 'b -> 'b - - $ cat manytests/typed/015tuples.ml | ../bin/REPL.exe --dinference - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val map : ('b -> 'a) -> 'b * 'b -> 'a * 'a - val fixpoly : (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) * (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) -> ('a -> 'b) * ('a -> 'b) - val feven : 'a * (int -> int) -> int -> int - val fodd : (int -> int) * 'a -> int -> int - val tie : (int -> int) * (int -> int) - val meven : int -> int - val modd : int -> int - val main : int - - $ cat manytests/typed/016lists.ml | ../bin/REPL.exe --dinference - val length : 'a list -> int - val length_tail : 'a list -> int - val map : ('a -> 'b) -> 'a list -> 'b list - val append : 'a list -> 'a list -> 'a list - val concat : ('a list) list -> 'a list - val iter : ('a -> unit) -> 'a list -> unit - val cartesian : 'b list -> 'a list -> ('b * 'a) list - val main : int diff --git a/ETenyaeva/tests/inferencer_manytests_do_not_type.t b/ETenyaeva/tests/inferencer_manytests_do_not_type.t deleted file mode 100644 index f55aa0425..000000000 --- a/ETenyaeva/tests/inferencer_manytests_do_not_type.t +++ /dev/null @@ -1,39 +0,0 @@ - $ cat ./manytests/do_not_type/001.ml | ../bin/REPL.exe --dinference - Inferencer error: Unbound variable fac'. - - $ cat ./manytests/do_not_type/002if.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: int and bool - - - $ cat ./manytests/do_not_type/003occurs.ml | ../bin/REPL.exe --dinference - Inferencer error: Occurs check failed. Type variable 'ty1 occurs inside 'ty1 -> 'ty3 - - - $ cat ./manytests/do_not_type/004let_poly.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: int and bool - - - $ cat ./manytests/do_not_type/005.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: string and int - - - $ cat ./manytests/do_not_type/015tuples.ml | ../bin/REPL.exe --dinference - Inferencer error: Only variables are allowed as left-hand side of `let rec' - - $ cat ./manytests/do_not_type/016tuples_mismatch.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: int * int * int and 'ty0 * 'ty1 - - - $ cat ./manytests/do_not_type/097fun_vs_list.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: 'ty0 -> 'ty0 and 'ty2 list - - - $ cat ./manytests/do_not_type/097fun_vs_unit.ml | ../bin/REPL.exe --dinference - Inferencer error: Failed to unify types: 'ty0 -> 'ty0 and unit - - - $ cat ./manytests/do_not_type/098rec_int.ml | ../bin/REPL.exe --dinference - Inferencer error: This kind of expression is not allowed as right-hand side of `let rec' - - $ cat ./manytests/do_not_type/099.ml | ../bin/REPL.exe --dinference - Inferencer error: Only variables are allowed as left-hand side of `let rec' diff --git a/ETenyaeva/tests/interpreter.ml b/ETenyaeva/tests/interpreter.ml deleted file mode 100644 index 4386cc7a9..000000000 --- a/ETenyaeva/tests/interpreter.ml +++ /dev/null @@ -1,117 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open ETenyaeva_lib.Parser -open ETenyaeva_lib.Interpreter - -let run input = - match parse input with - | Ok ast -> - (match run_interpreter env_with_print_funs ast with - | Ok (_, out_list) -> - List.iter - (function - | Some id, val' -> Format.printf "val %s = %a\n" id pp_value val' - | None, val' -> Format.printf "- = %a\n" pp_value val') - out_list - | Error e -> Format.printf "Interpreter error: %a\n" pp_error e) - | Error err -> Stdlib.Format.printf "%s\n" err -;; - -let%expect_test "eval simple let binding" = - run {| - let a = -(4 + 4) - and b = true;; - |}; - [%expect {| - val a = -8 - val b = true - |}] -;; - -let%expect_test "eval tuple and list let bindings" = - run {| - let a, b = 1, (2, 3);; - let [ c; d ] = 3::4::[] - |}; - [%expect {| - val a = 1 - val b = (2, 3) - val c = 3 - val d = 4 - |}] -;; - -let%expect_test "eval `let in'" = - run {| - let f = - let x = "abc" in - let y = "qwerty" in - x <> y - ;; - |}; - [%expect {| - val f = true - |}] -;; - -let%expect_test "eval 'Struct_eval'" = - run {| - 1;; - |}; - [%expect {| - - = 1 - |}] -;; - -let%expect_test "eval 'Exp_fun'" = - run {| - let foo x y = x * y - let q = foo 1 6 - let w = foo 2 (-5) - |}; - [%expect {| - val foo = - val q = 6 - val w = -10 - |}] -;; - -let%expect_test "eval recursive value binding 1" = - run {| - let rec x = 21 and y = x + 1;; - |}; - [%expect {| - val x = 21 - val y = 22 - |}] -;; - -let%expect_test "eval recursive value binding 2" = - run - {| - let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1);; - factorial 5 - |}; - [%expect {| - val factorial = - - = 120 - |}] -;; - -let%expect_test "eval pattern-matching" = - run - {| - let f = - match [ 1; 2; 3 ] with - | a :: [] -> a - | a :: b :: [] -> a + b - | a :: b :: c :: [] -> a + b + c - | _ -> 0 - ;; - |}; - [%expect {| - val f = 6 - |}] -;; diff --git a/ETenyaeva/tests/interpreter.mli b/ETenyaeva/tests/interpreter.mli deleted file mode 100644 index 72580acbb..000000000 --- a/ETenyaeva/tests/interpreter.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/ETenyaeva/tests/interpreter_mantests_typed.t b/ETenyaeva/tests/interpreter_mantests_typed.t deleted file mode 100644 index cb5d7a180..000000000 --- a/ETenyaeva/tests/interpreter_mantests_typed.t +++ /dev/null @@ -1,112 +0,0 @@ - $ cat manytests/typed/001fac.ml | ../bin/REPL.exe - 24 - val fac = - val main = 0 - - $ cat manytests/typed/002fac.ml | ../bin/REPL.exe - 24 - val fac_cps = - val main = 0 - - $ cat manytests/typed/003fib.ml | ../bin/REPL.exe - 3 - 3 - val fib_acc = - val fib = - val main = 0 - - $ cat manytests/typed/004manyargs.ml | ../bin/REPL.exe - 1111111111 - 1 - 10 - 100 - val wrap = - val test3 = - val test10 = - val main = 0 - - $ cat manytests/typed/005fix.ml | ../bin/REPL.exe - 720 - val fix = - val fac = - val main = 0 - - $ cat manytests/typed/006partial.ml | ../bin/REPL.exe - 1122 - val foo = - val main = 0 - - $ cat manytests/typed/006partial2.ml | ../bin/REPL.exe - 1 - 2 - 3 - 7 - val foo = - val main = 0 - - $ cat manytests/typed/006partial3.ml | ../bin/REPL.exe - 4 - 8 - 9 - val foo = - val main = 0 - - $ cat manytests/typed/007order.ml | ../bin/REPL.exe - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - val _start = - val main = () - - $ cat manytests/typed/008ascription.ml | ../bin/REPL.exe - 8 - val addi = - val main = 0 - - $ cat manytests/typed/009let_poly.ml | ../bin/REPL.exe - val temp = (1, true) - - $ cat manytests/typed/010sukharev.ml | ../bin/REPL.exe - val _1 = - val _2 = 1 - val _3 = Some (1, "hi") - val _4 = - val _5 = 42 - val _6 = - val int_of_option = - val _42 = - val id1 = - val id2 = - - $ cat manytests/typed/015tuples.ml | ../bin/REPL.exe - 1 - 1 - 1 - 1 - val fix = - val map = - val fixpoly = - val feven = - val fodd = - val tie = (, ) - val meven = - val modd = - val main = 0 - - $ cat manytests/typed/016lists.ml | ../bin/REPL.exe - 1 - 2 - 3 - 8 - val length = - val length_tail = - val map = - val append = - val concat = - val iter = - val cartesian = - val main = 0 diff --git a/ETenyaeva/tests/manytests b/ETenyaeva/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/ETenyaeva/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/ETenyaeva/tests/parser.ml b/ETenyaeva/tests/parser.ml deleted file mode 100644 index 6b39ec6d0..000000000 --- a/ETenyaeva/tests/parser.ml +++ /dev/null @@ -1,459 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open ETenyaeva_lib.Parser -open ETenyaeva_lib.Ast - -let run input = - match parse input with - | Ok structure -> Stdlib.Format.printf "%s\n" (show_structure structure) - | Error err -> Stdlib.Format.printf "%s\n" err -;; - -let%expect_test "parse_multiple_bindings" = - run "let x = 10;; let y = x + 5;;"; - [%expect - {| - [(Binding (NonRec, { pat = (PatVar "x"); expr = (ExpConst (Int 10)) }, [])); - (Binding (NonRec, - { pat = (PatVar "y"); - expr = (ExpBinOper (Add, (ExpVar "x"), (ExpConst (Int 5)))) }, - [])) - ]|}] -;; - -let%expect_test "parse_list_construct_case" = - run "a::b::c::[];;"; - [%expect - {| - [(EvalExp - (ExpListConstructor - [(ExpVar "a"); (ExpVar "b"); (ExpVar "c"); (ExpList [])])) - ] -|}] -;; - -let%expect_test "parse_application" = - run "fact (n - 1);;"; - [%expect - {| - [(EvalExp - (ExpApp ((ExpVar "fact"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 1))))))) - ] |}] -;; - -let%expect_test "parse_multiple_evaluations" = - run "1 + 1;; 2 + 2;;"; - [%expect - {| - [(EvalExp (ExpBinOper (Add, (ExpConst (Int 1)), (ExpConst (Int 1))))); - (EvalExp (ExpBinOper (Add, (ExpConst (Int 2)), (ExpConst (Int 2)))))] |}] -;; - -let%expect_test "parse_case_expression" = - run "match x with | 1 -> \"one\" | 2 -> \"two\";;"; - [%expect - {| - [(EvalExp - (ExpMatch ((ExpVar "x"), - { case_pat = (PatConst (Int 1)); case_expr = (ExpConst (String "one")) - }, - [{ case_pat = (PatConst (Int 2)); - case_expr = (ExpConst (String "two")) } - ] - ))) - ] |}] -;; - -let%expect_test "parse_tuple" = - run "(1, 2, 3);;"; - [%expect - {| - [(EvalExp - (ExpTup ((ExpConst (Int 1)), (ExpConst (Int 2)), [(ExpConst (Int 3))]))) - ] |}] -;; - -let%expect_test "parse_eval;;" = - run "1 + 1"; - [%expect - {| - [(EvalExp (ExpBinOper (Add, (ExpConst (Int 1)), (ExpConst (Int 1)))))] |}] -;; - -let%expect_test "parse_sub_without_ws" = - run "n-1;;"; - [%expect {| - [(EvalExp (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 1)))))]|}] -;; - -let%expect_test "parse_brackets" = - run "(((1 + 2) * 3));;"; - [%expect - {| - [(EvalExp - (ExpBinOper (Mult, - (ExpBinOper (Add, (ExpConst (Int 1)), (ExpConst (Int 2)))), - (ExpConst (Int 3))))) - ] |}] -;; - -let%expect_test "parse_factorial" = - run "let rec fact n = if n <= 1 then 1 else n * fact (n - 1);;"; - [%expect - {| - [(Binding (Rec, - { pat = (PatVar "fact"); - expr = - (ExpFun ((PatVar "n"), - (ExpIfThenElse ( - (ExpBinOper (LessEquals, (ExpVar "n"), (ExpConst (Int 1)))), - (ExpConst (Int 1)), - (Some (ExpBinOper (Mult, (ExpVar "n"), - (ExpApp ((ExpVar "fact"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 1)))) - )) - ))) - )) - )) - }, - [])) - ] |}] -;; - -let%expect_test "parse_arithmetic" = - run "1 + 2 * 3;;"; - [%expect - {| - [(EvalExp - (ExpBinOper (Add, (ExpConst (Int 1)), - (ExpBinOper (Mult, (ExpConst (Int 2)), (ExpConst (Int 3))))))) - ] |}] -;; - -let%expect_test "parse_ifthen" = - run "let ifthen n = if n > 0 then 1"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "ifthen"); - expr = - (ExpFun ((PatVar "n"), - (ExpIfThenElse ( - (ExpBinOper (GreaterThan, (ExpVar "n"), (ExpConst (Int 0)))), - (ExpConst (Int 1)), None)) - )) - }, - [])) - ] |}] -;; - -let%expect_test "parse_ifthen_without_else" = - run "if x > 0 then x + 4 "; - [%expect - {| - [(EvalExp - (ExpIfThenElse ( - (ExpBinOper (GreaterThan, (ExpVar "x"), (ExpConst (Int 0)))), - (ExpBinOper (Add, (ExpVar "x"), (ExpConst (Int 4)))), None))) - ] |}] -;; - -let%expect_test "parse_list" = - run "let lst = [1; 2; 3]"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "lst"); - expr = - (ExpList [(ExpConst (Int 1)); (ExpConst (Int 2)); (ExpConst (Int 3))]) - }, - [])) - ] |}] -;; - -let%expect_test "parse_with_type" = - run "let (x : int) = 5;;"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatWithTyp (TypInt, (PatVar "x"))); expr = (ExpConst (Int 5)) }, - [])) - ] |}] -;; - -let%expect_test "parse_with_type2" = - run "let add (a : int) (b : int) =\n a + b;;"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "add"); - expr = - (ExpFun ((PatWithTyp (TypInt, (PatVar "a"))), - (ExpFun ((PatWithTyp (TypInt, (PatVar "b"))), - (ExpBinOper (Add, (ExpVar "a"), (ExpVar "b"))))) - )) - }, - [])) - ] |}] -;; - -let%expect_test "fibonacci" = - run "let rec fibo n = if n < 2 then 1 else fibo(n - 1) + fibo(n - 2) ;;"; - [%expect - {| - [(Binding (Rec, - { pat = (PatVar "fibo"); - expr = - (ExpFun ((PatVar "n"), - (ExpIfThenElse ( - (ExpBinOper (LessThan, (ExpVar "n"), (ExpConst (Int 2)))), - (ExpConst (Int 1)), - (Some (ExpBinOper (Add, - (ExpApp ((ExpVar "fibo"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 1)))) - )), - (ExpApp ((ExpVar "fibo"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 2)))) - )) - ))) - )) - )) - }, - [])) - ] -|}] -;; - -let%expect_test "lambda_test" = - run "let add x = fun y -> x + y;;"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "add"); - expr = - (ExpFun ((PatVar "x"), - (ExpFun ((PatVar "y"), - (ExpBinOper (Add, (ExpVar "x"), (ExpVar "y"))))) - )) - }, - [])) - ] -|}] -;; - -let%expect_test "lambda_test_2" = - run "let add x = fun y -> y b;;"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "add"); - expr = - (ExpFun ((PatVar "x"), - (ExpFun ((PatVar "y"), (ExpApp ((ExpVar "y"), (ExpVar "b"))))))) - }, - [])) - ] -|}] -;; - -let%expect_test "lambda_test_3" = - run - "let foo a =\n\ - \ let () = print_int a in fun b ->\n\ - \ let () = print_int b in fun c ->\n\ - \ print_int c\n"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "foo"); - expr = - (ExpFun ((PatVar "a"), - (ExpLet (NonRec, - { pat = (PatConst Unit); - expr = (ExpApp ((ExpVar "print_int"), (ExpVar "a"))) }, - [], - (ExpFun ((PatVar "b"), - (ExpLet (NonRec, - { pat = (PatConst Unit); - expr = (ExpApp ((ExpVar "print_int"), (ExpVar "b"))) }, - [], - (ExpFun ((PatVar "c"), - (ExpApp ((ExpVar "print_int"), (ExpVar "c"))))) - )) - )) - )) - )) - }, - [])) - ] -|}] -;; - -let%expect_test "test_tuple" = - run "let x = (1, 2, true);;"; - [%expect - {| - [(Binding (NonRec, - { pat = (PatVar "x"); - expr = - (ExpTup ((ExpConst (Int 1)), (ExpConst (Int 2)), - [(ExpConst (Bool true))])) - }, - [])) - ] -|}] -;; - -let%expect_test "test_annotate_type" = - run "let (a : int list) = [] "; - [%expect - {| -[(Binding (NonRec, - { pat = (PatWithTyp (TypInt, (PatVar "a"))); expr = (ExpList []) }, - [])) - ] -|}] -;; - -let%expect_test "test_arithmetic2" = - run "-1 -2 - (-1) -(3)"; - [%expect - {| -[(EvalExp - (ExpUnOper (Neg, - (ExpBinOper (Sub, - (ExpBinOper (Sub, - (ExpBinOper (Sub, (ExpConst (Int 1)), (ExpConst (Int 2)))), - (ExpUnOper (Neg, (ExpConst (Int 1)))))), - (ExpConst (Int 3)))) - ))) - ] - |}] -;; - -let%expect_test "test_let-match" = - run - "let _5 =\n\ - \ let id x = x in\n\ - \ match Some id with\n\ - \ | Some f -> let _ = f \"42\" in f 42\n\ - \ | None -> 0"; - [%expect - {| -[(Binding (NonRec, - { pat = (PatVar "_5"); - expr = - (ExpLet (NonRec, - { pat = (PatVar "id"); expr = (ExpFun ((PatVar "x"), (ExpVar "x"))) - }, - [], - (ExpMatch ((ExpOption (Some (ExpVar "id"))), - { case_pat = (PatOption (Some (PatVar "f"))); - case_expr = - (ExpLet (NonRec, - { pat = PatAny; - expr = (ExpApp ((ExpVar "f"), (ExpConst (String "42")))) }, - [], (ExpApp ((ExpVar "f"), (ExpConst (Int 42)))))) - }, - [{ case_pat = (PatOption None); case_expr = (ExpConst (Int 0)) }] - )) - )) - }, - [])) - ] - |}] -;; - -let%expect_test "test_fib" = - run "let rec fib n =\n if n<2\n then n\n else fib (n - 1) + fib (n - 2)"; - [%expect - {| -[(Binding (Rec, - { pat = (PatVar "fib"); - expr = - (ExpFun ((PatVar "n"), - (ExpIfThenElse ( - (ExpBinOper (LessThan, (ExpVar "n"), (ExpConst (Int 2)))), - (ExpVar "n"), - (Some (ExpBinOper (Add, - (ExpApp ((ExpVar "fib"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 1)))) - )), - (ExpApp ((ExpVar "fib"), - (ExpBinOper (Sub, (ExpVar "n"), (ExpConst (Int 2)))) - )) - ))) - )) - )) - }, - [])) - ] - |}] -;; - -let%expect_test "test_partial" = - run - "let foo a b c =\n\ - \ let () = print_int a in\n\ - \ let () = print_int b in\n\ - \ let () = print_int c in\n\ - \ a + b * c"; - [%expect - {| -[(Binding (NonRec, - { pat = (PatVar "foo"); - expr = - (ExpFun ((PatVar "a"), - (ExpFun ((PatVar "b"), - (ExpFun ((PatVar "c"), - (ExpLet (NonRec, - { pat = (PatConst Unit); - expr = (ExpApp ((ExpVar "print_int"), (ExpVar "a"))) }, - [], - (ExpLet (NonRec, - { pat = (PatConst Unit); - expr = (ExpApp ((ExpVar "print_int"), (ExpVar "b"))) }, - [], - (ExpLet (NonRec, - { pat = (PatConst Unit); - expr = - (ExpApp ((ExpVar "print_int"), (ExpVar "c"))) }, - [], - (ExpBinOper (Add, (ExpVar "a"), - (ExpBinOper (Mult, (ExpVar "b"), (ExpVar "c"))))) - )) - )) - )) - )) - )) - )) - }, - [])) - ] - |}] -;; - -let%expect_test "parse_let_and" = - run {| - let x = 10 and y = 3 + 5 and z = (1, true, ("katya", "nastya"));; - |}; - [%expect - {| - [(Binding (NonRec, { pat = (PatVar "x"); expr = (ExpConst (Int 10)) }, - [{ pat = (PatVar "y"); - expr = (ExpBinOper (Add, (ExpConst (Int 3)), (ExpConst (Int 5)))) }; - { pat = (PatVar "z"); - expr = - (ExpTup ((ExpConst (Int 1)), (ExpConst (Bool true)), - [(ExpTup ((ExpConst (String "katya")), - (ExpConst (String "nastya")), [])) - ] - )) - } - ] - )) - ] |}] -;; diff --git a/ETenyaeva/tests/parser.mli b/ETenyaeva/tests/parser.mli deleted file mode 100644 index 72580acbb..000000000 --- a/ETenyaeva/tests/parser.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Ekaterina Tenyaeva *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EUsoltsev/.envrc b/EUsoltsev/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/EUsoltsev/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/EUsoltsev/.gitignore b/EUsoltsev/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/EUsoltsev/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/EUsoltsev/.ocamlformat b/EUsoltsev/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/EUsoltsev/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/EUsoltsev/.zanuda b/EUsoltsev/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/EUsoltsev/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/EUsoltsev/COPYING b/EUsoltsev/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/EUsoltsev/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/EUsoltsev/COPYING.CC0 b/EUsoltsev/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/EUsoltsev/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/EUsoltsev/COPYING.LESSER b/EUsoltsev/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/EUsoltsev/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/EUsoltsev/DONT_REMOVE_THIS_DIRECTORY.md b/EUsoltsev/DONT_REMOVE_THIS_DIRECTORY.md deleted file mode 100644 index e0530079f..000000000 --- a/EUsoltsev/DONT_REMOVE_THIS_DIRECTORY.md +++ /dev/null @@ -1,3 +0,0 @@ -This file should be contained in template directoty `Lambda`. -You should remove it when you copy `Lambda` for your -personal pet project. diff --git a/EUsoltsev/EUsoltsev.opam b/EUsoltsev/EUsoltsev.opam deleted file mode 100644 index 96c01087a..000000000 --- a/EUsoltsev/EUsoltsev.opam +++ /dev/null @@ -1,37 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for MiniML language" -description: - "FIXME. A longer description, for example, which are the most interesing features being supported, etc." -maintainer: ["Danil Usoltsev"] -authors: ["Danil Usoltsev"] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Kakadu/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Kakadu/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "base" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/EUsoltsev/Makefile b/EUsoltsev/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/EUsoltsev/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/EUsoltsev/bin/dune b/EUsoltsev/bin/dune deleted file mode 100644 index 1bccdb570..000000000 --- a/EUsoltsev/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name main) - (public_name main) - (libraries EUsoltsev_lib) - (instrumentation - (backend bisect_ppx))) diff --git a/EUsoltsev/bin/main.ml b/EUsoltsev/bin/main.ml deleted file mode 100644 index 3073e6861..000000000 --- a/EUsoltsev/bin/main.ml +++ /dev/null @@ -1,82 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EUsoltsev_lib -open Inferencer -open Interpreter -open Parser -open Printf -open Ast - -let run_inference input = - match parse input with - | Ok parsed -> - (match run_infer parsed with - | Ok env -> - let filtered_env = - Base.Map.filter_keys env ~f:(fun key -> - not (List.mem key [ "print_int"; "print_endline"; "print_bool" ])) - in - Base.Map.iteri filtered_env ~f:(fun ~key ~data:(S (_, ty)) -> - Format.printf "val %s: %a\n" key pp_ty ty) - | Error e -> Format.printf "Infer error. %a\n" pp_error e) - | Error e -> Format.printf "Parsing error. %s\n" e -;; - -let run_interpreter s = - let open Stdlib.Format in - match Parser.parse s with - | Ok parsed -> - (match Inter.eval_structure parsed with - | Ok _ -> () - | Error e -> printf "Interpreter error: %a\n" pp_value_error e) - | Error e -> printf "Parsing error: %s\n" e -;; - -let read_file filename = - let channel = open_in filename in - let content = really_input_string channel (in_channel_length channel) in - close_in channel; - content -;; - -type config = - { infer_flag : bool - ; interpret_flag : bool - ; file : string option - ; input : string option - } - -let parse_arguments () = - let rec parse_args args config = - match args with - | [] -> config - | "-infer" :: rest -> parse_args rest { config with infer_flag = true } - | "-interpret" :: rest -> parse_args rest { config with interpret_flag = true } - | "-file" :: filename :: rest -> parse_args rest { config with file = Some filename } - | arg :: rest -> parse_args rest { config with input = Some arg } - in - parse_args - (Array.to_list Sys.argv |> List.tl) - { infer_flag = false; interpret_flag = false; file = None; input = None } -;; - -let main () = - let config = parse_arguments () in - let input_content = - match config.file with - | Some filename -> read_file filename - | None -> - (match config.input with - | Some s -> s - | None -> "") - in - if config.infer_flag - then run_inference input_content - else if config.interpret_flag - then run_interpreter input_content - else printf "Please specify either -infer or -interpret flag.\n" -;; - -let () = main () diff --git a/EUsoltsev/dune b/EUsoltsev/dune deleted file mode 100644 index 0ef8774ec..000000000 --- a/EUsoltsev/dune +++ /dev/null @@ -1,16 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - -; (executable -; (name REPL) -; (public_name REPL) -; (modules REPL) -; (libraries lambda_lib stdio)) - -; (cram -; (deps ./REPL.exe %{bin:REPL})) diff --git a/EUsoltsev/dune-project b/EUsoltsev/dune-project deleted file mode 100644 index 754811a92..000000000 --- a/EUsoltsev/dune-project +++ /dev/null @@ -1,35 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Danil Usoltsev") - -(maintainers "Danil Usoltsev") - -(bug_reports "https://github.com/Kakadu/fp2024") - -(homepage "https://github.com/Kakadu/fp2024") - -(package - (name EUsoltsev) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for MiniML language") - (description - "FIXME. A longer description, for example, which are the most interesing features being supported, etc.") - (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - base - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/EUsoltsev/lib/ast.ml b/EUsoltsev/lib/ast.ml deleted file mode 100644 index 1c23fe76d..000000000 --- a/EUsoltsev/lib/ast.ml +++ /dev/null @@ -1,103 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Format - -type ident = string [@@deriving show { with_path = false }] -type is_rec = bool [@@deriving show { with_path = false }] - -type bin_oper = - | Plus (* [+] *) - | Minus (* [-] *) - | Multiply (* [*] *) - | Division (* [/] *) - | And (* [&&] *) - | Or (* [||] *) - | GretestEqual (* [>=] *) - | LowestEqual (* [<=] *) - | GreaterThan (* [>] *) - | LowerThan (* [<] *) - | Equal (* [=] *) - | NotEqual (* [<>] *) -[@@deriving show { with_path = false }] - -type unar_oper = - | Negative (* [-x] *) - | Not (* [not x]*) -[@@deriving show { with_path = false }] - -type const = - | ConstInt of int (* Integer constant: Example - [21] *) - | ConstBool of bool (* Boolean constant: Example - [true] or [false] *) - | ConstString of string (* String constant: Example - "I like OCaml!" *) -[@@deriving show { with_path = false }] - -type binder = int [@@deriving show { with_path = false }] - -type ty = - | TyVar of binder - | TyPrim of string - | TyArrow of ty * ty - | TyList of ty - | TyTuple of ty list - | TyOption of ty -[@@deriving show { with_path = false }] - -type pattern = - | PatVariable of ident (* [x] *) - | PatConst of const (* [21] or [true] or [false] *) - | PatTuple of pattern * pattern * pattern list (* (x1; x2 ... xn) *) - | PatAny - | PatType of pattern * ty - | PatUnit - | PatList of pattern list - | PatOption of pattern option -[@@deriving show { with_path = false }] - -type expr = - | ExpIdent of ident (* ExpIdent "x" *) - | ExpConst of const (* ExpConst (ConstInt 666) *) - | ExpBranch of expr * expr * expr option - | ExpBinOper of bin_oper * expr * expr (* ExpBinOper(Plus, 1, 2) *) - | ExpUnarOper of unar_oper * expr (* ExpUnarOper(not, x)*) - | ExpTuple of expr * expr * expr list (* ExpTuple[x1; x2 .. xn] *) - | ExpList of expr list (* ExpList[x1; x2 .. xn] *) - | ExpLambda of pattern list * expr (* ExpLambda([x;y;z], x+y+z)*) - | ExpTypeAnnotation of expr * ty - | ExpLet of is_rec * bind * bind list * expr - | ExpFunction of expr * expr (* ExpFunction(x, y)*) - | ExpOption of expr option -[@@deriving show { with_path = false }] - -and bind = pattern * expr [@@deriving show { with_path = false }] - -type structure = - | SEval of expr - | SValue of is_rec * bind * bind list -[@@deriving show { with_path = false }] - -type program = structure list [@@deriving show { with_path = false }] - -let rec pp_ty fmt = function - | TyPrim x -> fprintf fmt "%s" x - | TyVar x -> fprintf fmt "'%d" x - | TyArrow (l, r) -> - (match l, r with - | TyArrow _, _ -> fprintf fmt "(%a) -> %a" pp_ty l pp_ty r - | _, _ -> fprintf fmt "%a -> %a" pp_ty l pp_ty r) - | TyTuple elems -> - fprintf - fmt - "(%a)" - (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt " * ") pp_ty) - elems - | TyList ty -> - (match ty with - | TyArrow _ | TyTuple _ -> fprintf fmt "(%a) list" pp_ty ty - | _ -> fprintf fmt "%a list" pp_ty ty) - | TyOption ty -> - (match ty with - | TyArrow _ | TyTuple _ -> fprintf fmt "(%a) option" pp_ty ty - | _ -> fprintf fmt "%a option" pp_ty ty) -;; diff --git a/EUsoltsev/lib/dune b/EUsoltsev/lib/dune deleted file mode 100644 index fd5a33446..000000000 --- a/EUsoltsev/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name EUsoltsev_lib) - (public_name EUsoltsev.Lib) - (modules Inferencer Ast Parser Interpreter) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/EUsoltsev/lib/inferencer.ml b/EUsoltsev/lib/inferencer.ml deleted file mode 100644 index 15e8caf16..000000000 --- a/EUsoltsev/lib/inferencer.ml +++ /dev/null @@ -1,657 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(* Template: https://gitlab.com/Kakadu/fp2020course-materials/-/tree/master/code/miniml?ref_type=heads*) - -open Base -open Ast -open Stdlib.Format - -type error = - | OccursCheck of int * ty - | NoVariable of string - | UnificationFailed of ty * ty - | SeveralBounds of string - | LHS of string - | RHS of string - | UnexpectedFunction of ty - -let pp_error fmt = function - | OccursCheck (id, ty) -> - fprintf fmt "Occurs check failed. Type variable '%d occurs inside %a." id pp_ty ty - | NoVariable name -> fprintf fmt "Unbound variable '%s'." name - | UnificationFailed (ty1, ty2) -> - fprintf fmt "Failed to unify types: %a and %a." pp_ty ty1 pp_ty ty2 - | SeveralBounds name -> fprintf fmt "Multiple bounds for variable '%s'." name - | LHS msg -> fprintf fmt "Left-hand side error: %s." msg - | RHS msg -> fprintf fmt "Right-hand side error: %s." msg - | UnexpectedFunction ty1 -> fprintf fmt "UnexpectedFunction error: %a" pp_ty ty1 -;; - -module IntSet = struct - include Stdlib.Set.Make (Int) -end - -module ResultMonad : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - - include Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - val fresh : int t - val run : 'a t -> ('a, error) Result.t - - module RMap : sig - val fold : ('a, 'b, 'c) Map.t -> init:'d t -> f:('a -> 'b -> 'd -> 'd t) -> 'd t - end -end = struct - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) m f state = - let last, r = m state in - match r with - | Result.Error x -> last, Result.fail x - | Result.Ok a -> f a last - ;; - - let return x last = last, Result.return x - let fail e st = st, Result.fail e - - let ( >>| ) m f st = - match m st with - | st, Ok x -> st, Result.return (f x) - | st, Result.Error e -> st, Result.fail e - ;; - - module Syntax = struct - let ( let* ) = ( >>= ) - end - - module RMap = struct - let fold map ~init ~f = - Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - let fresh : int t = fun last -> last + 1, Result.return last - let run monad = snd (monad 0) -end - -module Type = struct - let rec occurs_in var = function - | TyVar b -> b = var - | TyArrow (left, right) -> occurs_in var left || occurs_in var right - | TyTuple types -> List.exists types ~f:(occurs_in var) - | TyList ty -> occurs_in var ty - | TyOption ty -> occurs_in var ty - | TyPrim _ -> false - ;; - - let free_vars = - let rec helper acc = function - | TyVar b -> IntSet.add b acc - | TyArrow (left, right) -> helper (helper acc left) right - | TyTuple types -> List.fold_left types ~init:acc ~f:helper - | TyList ty -> helper acc ty - | TyOption ty -> helper acc ty - | TyPrim _ -> acc - in - helper IntSet.empty - ;; -end - -module Substitution : sig - type t - - val empty : t - val singleton : int -> ty -> t ResultMonad.t - val remove : t -> int -> t - val apply : t -> ty -> ty - val unify : ty -> ty -> t ResultMonad.t - val compose : t -> t -> t ResultMonad.t - val compose_all : t list -> t ResultMonad.t -end = struct - open ResultMonad - open ResultMonad.Syntax - - type t = (int, ty, Int.comparator_witness) Map.t - - let empty = Map.empty (module Int) - - let mapping key value = - if Type.occurs_in key value - then fail (OccursCheck (key, value)) - else return (key, value) - ;; - - let singleton key value = - let* key, value = mapping key value in - return (Map.singleton (module Int) key value) - ;; - - let find = Map.find - let remove = Map.remove - - let apply subst = - let rec helper = function - | TyPrim x -> TyPrim x - | TyVar b as ty -> - (match find subst b with - | None -> ty - | Some x -> x) - | TyArrow (left, right) -> TyArrow (helper left, helper right) - | TyList ty -> TyList (helper ty) - | TyOption ty -> TyOption (helper ty) - | TyTuple types -> TyTuple (List.map ~f:helper types) - in - helper - ;; - - let rec unify left right = - match left, right with - | TyPrim l, TyPrim r when String.equal l r -> return empty - | TyPrim _, TyPrim _ -> fail (UnificationFailed (left, right)) - | TyVar l, TyVar r when l = r -> return empty - | TyVar b, ty | ty, TyVar b -> singleton b ty - | TyArrow (left1, right1), TyArrow (left2, right2) -> - let* subst1 = unify left1 left2 in - let* subst2 = unify (apply subst1 right1) (apply subst1 right2) in - compose subst1 subst2 - | TyTuple types1, TyTuple types2 -> - if List.length types1 <> List.length types2 - then fail (UnificationFailed (left, right)) - else ( - let rec unify_tuples subst types1 types2 = - match types1, types2 with - | [], [] -> return subst - | t1 :: rest1, t2 :: rest2 -> - let* subst' = unify (apply subst t1) (apply subst t2) in - let* composed_subst = compose subst subst' in - unify_tuples composed_subst rest1 rest2 - | _, _ -> fail (UnificationFailed (left, right)) - in - unify_tuples empty types1 types2) - | TyList ty1, TyList ty2 -> unify ty1 ty2 - | TyOption ty1, TyOption ty2 -> unify ty1 ty2 - | _ -> fail (UnificationFailed (left, right)) - - and extend key value subst = - match find subst key with - | None -> - let value = apply subst value in - let* subst2 = singleton key value in - RMap.fold subst ~init:(return subst2) ~f:(fun key value acc -> - let value = apply subst2 value in - let* key, value = mapping key value in - return (Map.update acc key ~f:(fun _ -> value))) - | Some value2 -> - let* subst2 = unify value value2 in - compose subst subst2 - - and compose subst1 subst2 = RMap.fold subst2 ~init:(return subst1) ~f:extend - - let compose_all = - List.fold_left ~init:(return empty) ~f:(fun acc subst -> - let* acc = acc in - compose acc subst) - ;; -end - -module Scheme = struct - type t = S of IntSet.t * ty - - let free_vars (S (vars, ty)) = IntSet.diff (Type.free_vars ty) vars - - let apply subst (S (vars, ty)) = - let subst2 = - IntSet.fold (fun key subst -> Substitution.remove subst key) vars subst - in - S (vars, Substitution.apply subst2 ty) - ;; -end - -module TypeEnv = struct - type t = (ident, Scheme.t, String.comparator_witness) Map.t - - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let free_vars : t -> IntSet.t = - Map.fold ~init:IntSet.empty ~f:(fun ~key:_ ~data:scheme acc -> - IntSet.union acc (Scheme.free_vars scheme)) - ;; - - let apply subst env = Map.map env ~f:(Scheme.apply subst) - let find = Map.find - - let initial_env = - let open Base.Map in - empty (module String) - |> set - ~key:"print_int" - ~data:(Scheme.S (IntSet.empty, TyArrow (TyPrim "int", TyPrim "unit"))) - |> set - ~key:"print_endline" - ~data:(Scheme.S (IntSet.empty, TyArrow (TyPrim "string", TyPrim "unit"))) - |> set - ~key:"print_bool" - ~data:(Scheme.S (IntSet.empty, TyArrow (TyPrim "bool", TyPrim "unit"))) - ;; -end - -open ResultMonad -open ResultMonad.Syntax - -let fresh_var = fresh >>| fun n -> TyVar n - -let instantiate : Scheme.t -> ty ResultMonad.t = - fun (S (vars, ty)) -> - IntSet.fold - (fun var typ -> - let* typ = typ in - let* fresh_ty = fresh_var in - let* subst = Substitution.singleton var fresh_ty in - return (Substitution.apply subst typ)) - vars - (return ty) -;; - -let generalize env ty = - let free = IntSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - Scheme.S (free, ty) -;; - -let infer_const = function - | ConstInt _ -> TyPrim "int" - | ConstBool _ -> TyPrim "bool" - | ConstString _ -> TyPrim "string" -;; - -let rec infer_pattern env = function - | PatAny -> - let* fresh = fresh_var in - return (Substitution.empty, fresh, env) - | PatConst const -> return (Substitution.empty, infer_const const, env) - | PatVariable var -> - let* fresh = fresh_var in - let env = TypeEnv.extend env var (Scheme.S (IntSet.empty, fresh)) in - return (Substitution.empty, fresh, env) - | PatTuple (first_pat, second_pat, rest_pats) -> - let* sub_first, type_first, env_first = infer_pattern env first_pat in - let updated_env_second = TypeEnv.apply sub_first env_first in - let* sub_second, type_second, env_second = - infer_pattern updated_env_second second_pat - in - let process_remaining_patterns acc pat = - let open ResultMonad.Syntax in - let* current_sub, types, current_env = acc in - let* sub_new, type_new, env_new = infer_pattern current_env pat in - let* combined_sub = Substitution.compose current_sub sub_new in - return (combined_sub, type_new :: types, env_new) - in - let initial_state = return (sub_second, [ type_second; type_first ], env_second) in - let* final_sub, collected_types, final_env = - List.fold_left rest_pats ~init:initial_state ~f:process_remaining_patterns - in - let tuple_type = TyTuple (List.rev collected_types) in - return (final_sub, tuple_type, final_env) - | PatList pats -> - let* fresh_el_type = fresh_var in - let* final_sub, final_env = - List.fold_left - pats - ~init:(return (Substitution.empty, env)) - ~f:(fun acc pat -> - let open ResultMonad.Syntax in - let* sub_acc, env_acc = acc in - let* sub_cur, el_type, env_cur = infer_pattern env_acc pat in - let* unified_sub = Substitution.compose sub_acc sub_cur in - let* final_sub = - Substitution.unify (Substitution.apply sub_cur fresh_el_type) el_type - in - let* combined_sub = Substitution.compose unified_sub final_sub in - return (combined_sub, TypeEnv.apply final_sub env_cur)) - in - return (final_sub, TyList (Substitution.apply final_sub fresh_el_type), final_env) - | PatOption opt -> - let* sub, typ, env = - match opt with - | None -> - let* fresh = fresh_var in - return (Substitution.empty, fresh, env) - | Some p -> infer_pattern env p - in - return (sub, TyOption typ, env) - | PatType (pat, annotated_ty) -> - let* subst, inferred_ty, env = infer_pattern env pat in - let* unified_subst = Substitution.unify inferred_ty annotated_ty in - let* total_subst = Substitution.compose subst unified_subst in - return - ( total_subst - , Substitution.apply total_subst annotated_ty - , TypeEnv.apply total_subst env ) - | PatUnit -> return (Substitution.empty, TyPrim "unit", env) -;; - -let infer_binop_type = function - | Equal | NotEqual | GreaterThan | GretestEqual | LowerThan | LowestEqual -> - fresh_var >>| fun fresh_ty -> fresh_ty, fresh_ty, TyPrim "bool" - | Plus | Minus | Multiply | Division -> return (TyPrim "int", TyPrim "int", TyPrim "int") - | And | Or -> return (TyPrim "bool", TyPrim "bool", TyPrim "bool") -;; - -let rec infer_expr env = function - | ExpConst const -> return (Substitution.empty, infer_const const) - | ExpIdent var -> - (match TypeEnv.find env var with - | Some scheme -> - let* ty = instantiate scheme in - return (Substitution.empty, ty) - | None -> fail (NoVariable var)) - | ExpUnarOper (operation, expr) -> - let* subst, ty = infer_expr env expr in - let* operation_type = - match operation with - | Negative -> return (TyArrow (TyPrim "int", TyPrim "int")) - | Not -> return (TyArrow (TyPrim "bool", TyPrim "bool")) - in - let* subst2 = - match operation_type with - | TyArrow (arg, _) -> Substitution.unify ty arg - | ty -> fail (UnexpectedFunction ty) - in - let* subst2 = Substitution.compose_all [ subst2; subst ] in - (match operation_type with - | TyArrow (_, x) -> return (subst2, Substitution.apply subst2 x) - | ty -> fail (UnexpectedFunction ty)) - | ExpBinOper (op, expr1, expr2) -> - let* subst1, ty = infer_expr env expr1 in - let* subst2, ty' = infer_expr (TypeEnv.apply subst1 env) expr2 in - let* ty1_op, ty2_op, ty_res = infer_binop_type op in - let* subst3 = Substitution.unify (Substitution.apply subst2 ty) ty1_op in - let* subst4 = Substitution.unify (Substitution.apply subst3 ty') ty2_op in - let* subst = Substitution.compose_all [ subst1; subst2; subst3; subst4 ] in - return (subst, Substitution.apply subst ty_res) - | ExpBranch (cond, then_expr, else_expr) -> - let* subst1, ty1 = infer_expr env cond in - let* subst2, ty2 = infer_expr (TypeEnv.apply subst1 env) then_expr in - let* ty3 = - match else_expr with - | Some el -> - let* _, ty3 = infer_expr (TypeEnv.apply subst2 env) el in - return ty3 - | None -> return (TyPrim "unit") - in - let* subst4 = Substitution.unify ty1 (TyPrim "bool") in - let* subst5 = Substitution.unify ty2 ty3 in - let* total_subst = - match else_expr with - | Some el -> - let* subst3, _ = infer_expr (TypeEnv.apply subst2 env) el in - Substitution.compose_all [ subst5; subst4; subst3; subst2; subst1 ] - | None -> Substitution.compose_all [ subst5; subst4; subst2; subst1 ] - in - return (total_subst, Substitution.apply total_subst ty2) - | ExpTuple (expr1, expr2, exprs) -> - let* subst1, ty1 = infer_expr env expr1 in - let* subst2, ty2 = infer_expr (TypeEnv.apply subst1 env) expr2 in - let infer_tuple_elements env es = - let rec aux env = function - | [] -> return ([], []) - | e :: es' -> - let* s, t = infer_expr env e in - let* s', ts = aux (TypeEnv.apply s env) es' in - return (s' @ [ s ], t :: ts) - in - aux env es - in - let* subst3, tys = infer_tuple_elements (TypeEnv.apply subst2 env) exprs in - let* subst = Substitution.compose_all (subst3 @ [ subst2; subst1 ]) in - return (subst, TyTuple (ty1 :: ty2 :: tys)) - | ExpList exprs -> - (match exprs with - | [] -> - let* fresh = fresh_var in - return (Substitution.empty, TyList fresh) - | _ :: _ -> - let infer_list_elements env es = - let rec aux env = function - | [] -> return ([], []) - | e :: es' -> - let* s, t = infer_expr env e in - let* s', ts = aux (TypeEnv.apply s env) es' in - return (s' @ [ s ], t :: ts) - in - aux env es - in - let* subst, tys = infer_list_elements env exprs in - let* total_subst = Substitution.compose_all subst in - (match tys with - | [] -> fail (SeveralBounds "inferred empty list type") - | ty :: _ -> return (total_subst, TyList ty))) - | ExpLet (false, (PatVariable x, expr1), _, expr2) -> - let* subst1, ty1 = infer_expr env expr1 in - let env2 = TypeEnv.apply subst1 env in - let ty_gen = generalize env2 ty1 in - let env3 = TypeEnv.extend env x ty_gen in - let* subst2, ty2 = infer_expr (TypeEnv.apply subst1 env3) expr2 in - let* total_subst = Substitution.compose subst1 subst2 in - return (total_subst, ty2) - | ExpLet (false, (pattern, expr1), bindings, expr2) -> - let* subst1, ty1 = infer_expr env expr1 in - let* subst2, ty_pat, env1 = infer_pattern env pattern in - let* subst = Substitution.compose subst1 subst2 in - let* unified_subst = Substitution.unify (Substitution.apply subst ty_pat) ty1 in - let initial_env = TypeEnv.apply unified_subst env1 in - let* extended_env = - List.fold_left - ~f:(fun acc_env (pattern, expr) -> - let* acc_env = acc_env in - let* subst_bind, ty_bind = infer_expr acc_env expr in - let* subst_pattern, _, env_pattern = infer_pattern acc_env pattern in - let* combined_subst = Substitution.compose subst_bind subst_pattern in - let* final_subst = - Substitution.unify (Substitution.apply combined_subst ty_pat) ty_bind - in - let updated_env = - Map.fold - ~init:(TypeEnv.apply final_subst acc_env) - ~f:(fun ~key ~data acc_env -> TypeEnv.extend acc_env key data) - (TypeEnv.apply final_subst env_pattern) - in - return updated_env) - ~init:(return initial_env) - bindings - in - let* subst3, ty2 = infer_expr extended_env expr2 in - let* total_subst = Substitution.compose_all [ subst3; unified_subst; subst ] in - return (total_subst, ty2) - | ExpLet (true, (PatVariable x, expr1), [], expr2) -> - let* expr1 = - match expr1 with - | ExpLambda _ -> return expr1 - | _ -> fail (RHS "Right-hand side of let rec must be a lambda expression") - in - let* tv = fresh_var in - let env2 = TypeEnv.extend env x (S (IntSet.empty, tv)) in - let* subst1, ty1 = infer_expr env2 expr1 in - let* subst2 = Substitution.unify (Substitution.apply subst1 tv) ty1 in - let* subst_total = Substitution.compose subst1 subst2 in - let env3 = TypeEnv.apply subst_total env in - let env4 = TypeEnv.apply subst1 env3 in - let ty_gen = generalize env4 (Substitution.apply subst_total tv) in - let* subst3, ty2 = infer_expr (TypeEnv.extend env4 x ty_gen) expr2 in - let* subst_total = Substitution.compose subst_total subst3 in - return (subst_total, ty2) - | ExpLet (true, value_binding, value_bindings, expr2) -> - let* env_ext, subst_acc = - List.fold_left - ~f:(fun acc_env (pat, expr) -> - let* expr = - match expr with - | ExpLambda _ -> return expr - | _ -> fail (RHS "Right-hand side of let rec must be a lambda expression") - in - let* pat = - match pat with - | PatVariable _ -> return pat - | _ -> - fail (LHS "Only variables are allowed on the left-hand side of let rec") - in - let* env_acc, _ = acc_env in - let* subst_expr, ty_expr = infer_expr env_acc expr in - let* subst_pattern, ty_pat, env_pat = infer_pattern env_acc pat in - let* subst = Substitution.compose subst_expr subst_pattern in - let* unified_subst = Substitution.unify ty_expr ty_pat in - let* combined_subst = Substitution.compose subst unified_subst in - let extended_env = TypeEnv.apply combined_subst env_pat in - return (extended_env, combined_subst)) - ~init:(return (env, Substitution.empty)) - (value_binding :: value_bindings) - in - let* subst2, ty2 = infer_expr env_ext expr2 in - let* total_subst = Substitution.compose subst_acc subst2 in - return (total_subst, ty2) - | ExpLambda (patterns, body) -> - let* env, pat_types = - List.fold_left - patterns - ~init:(return (env, [])) - ~f:(fun acc pat -> - let* env, pat_types = acc in - let* _, typ, env = infer_pattern env pat in - return (env, typ :: pat_types)) - in - let* subst_body, ty_body = infer_expr env body in - let arrow_type = - List.fold_right - ~f:(fun pat_type acc -> TyArrow (Substitution.apply subst_body pat_type, acc)) - ~init:ty_body - (List.rev pat_types) - in - return (subst_body, arrow_type) - | ExpFunction (param, body) -> - let* subst1, ty1 = infer_expr env param in - let* subst2, ty2 = infer_expr (TypeEnv.apply subst1 env) body in - let* tv = fresh_var in - let* subst3 = - Substitution.unify (Substitution.apply subst2 ty1) (TyArrow (ty2, tv)) - in - let* total_subst = Substitution.compose_all [ subst3; subst2; subst1 ] in - return (total_subst, Substitution.apply total_subst tv) - | ExpOption opt_expr -> - (match opt_expr with - | Some expr -> - let* subst, ty = infer_expr env expr in - return (subst, TyOption ty) - | None -> - let* tv = fresh_var in - return (Substitution.empty, TyOption tv)) - | ExpTypeAnnotation (expr, t) -> - let* subst1, ty1 = infer_expr env expr in - let* subst2 = Substitution.unify ty1 (Substitution.apply subst1 t) in - let* total_subst = Substitution.compose subst1 subst2 in - return (total_subst, Substitution.apply subst2 ty1) -;; - -let infer_structure_item env = function - | SEval expr -> - let* subst, _ = infer_expr env expr in - let updated_env = TypeEnv.apply subst env in - return (subst, updated_env) - | SValue (true, (PatVariable x, expr), []) -> - let* expr = - match expr with - | ExpLambda _ -> return expr - | _ -> fail (RHS "Right-hand side of let rec must be a lambda expression") - in - let* tv = fresh_var in - let env = TypeEnv.extend env x (S (IntSet.empty, tv)) in - let* subst, ty = infer_expr env expr in - let* subst2 = Substitution.unify (Substitution.apply subst tv) ty in - let* composed_subst = Substitution.compose subst subst2 in - let env2 = TypeEnv.apply composed_subst env in - let generalized_ty = generalize env2 (Substitution.apply composed_subst ty) in - let env = TypeEnv.extend env2 x generalized_ty in - return (composed_subst, env) - | SValue (true, value_binding, value_bindings) -> - let all_bindings = value_binding :: value_bindings in - let* env_with_placeholders = - List.fold_left - ~f:(fun acc_env (pat, _) -> - let* pat = - match pat with - | PatVariable _ -> return pat - | _ -> - fail (LHS "Only variables are allowed on the left-hand side of let rec") - in - let* env_acc = acc_env in - let* subst_pat, _, env_pat = infer_pattern env_acc pat in - let extended_env = TypeEnv.apply subst_pat env_pat in - return extended_env) - ~init:(return env) - all_bindings - in - let* env_ext, subst_acc = - List.fold_left - ~f:(fun acc_env (ty_pattern, expr) -> - let* expr = - match expr with - | ExpLambda _ -> return expr - | _ -> fail (RHS "Right-hand side of let rec must be a lambda expression") - in - let* env_acc, _ = acc_env in - let* subst_expr, ty_expr = infer_expr env_acc expr in - let* subst_pat, ty_pat, env_pat = infer_pattern env_acc ty_pattern in - let* subst = Substitution.compose subst_expr subst_pat in - let* unified_subst = Substitution.unify ty_expr ty_pat in - let* combined_subst = Substitution.compose subst unified_subst in - let extended_env = TypeEnv.apply combined_subst env_pat in - return (extended_env, combined_subst)) - ~init:(return (env_with_placeholders, Substitution.empty)) - all_bindings - in - return (subst_acc, env_ext) - | SValue (false, (PatVariable x, expr), _) -> - let* subst, ty = infer_expr env expr in - let env2 = TypeEnv.apply subst env in - let generalized_ty = generalize env2 ty in - let env = TypeEnv.extend (TypeEnv.apply subst env) x generalized_ty in - return (subst, env) - | SValue (false, (pattern, expr), _) -> - let* subst_expr, ty = infer_expr env expr in - let* subst_pat, ty_pat, env_pat = infer_pattern env pattern in - let* combined_subst = Substitution.compose subst_expr subst_pat in - let* unified_subst = - Substitution.unify (Substitution.apply combined_subst ty_pat) ty - in - let updated_env = TypeEnv.apply unified_subst env_pat in - let* final_subst = Substitution.compose unified_subst combined_subst in - return (final_subst, updated_env) -;; - -let infer_structure env structure = - let rec process_structure env subst = function - | [] -> return (subst, env) - | item :: rest -> - let* subst1, env1 = infer_structure_item env item in - let* composed_subst = Substitution.compose subst subst1 in - process_structure env1 composed_subst rest - in - process_structure env Substitution.empty structure -;; - -let infer_simple_expression expr = - Result.map ~f:snd (run (infer_expr TypeEnv.initial_env expr)) -;; - -let run_infer str = Result.map ~f:snd (run (infer_structure TypeEnv.initial_env str)) diff --git a/EUsoltsev/lib/inferencer.mli b/EUsoltsev/lib/inferencer.mli deleted file mode 100644 index bd19629ab..000000000 --- a/EUsoltsev/lib/inferencer.mli +++ /dev/null @@ -1,32 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base - -module IntSet : sig - type t = Stdlib.Set.Make(Int).t -end - -type error = - | OccursCheck of int * ty - | NoVariable of string - | UnificationFailed of ty * ty - | SeveralBounds of string - | LHS of string - | RHS of string - | UnexpectedFunction of ty - -val pp_error : Stdlib.Format.formatter -> error -> unit - -module Scheme : sig - type t = S of IntSet.t * ty -end - -module TypeEnv : sig - type t = (ident, Scheme.t, String.comparator_witness) Map.t -end - -val infer_simple_expression : expr -> (ty, error) Result.t -val run_infer : Ast.program -> (TypeEnv.t, error) Result.t diff --git a/EUsoltsev/lib/interpreter.ml b/EUsoltsev/lib/interpreter.ml deleted file mode 100644 index 2928fcd49..000000000 --- a/EUsoltsev/lib/interpreter.ml +++ /dev/null @@ -1,414 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Stdlib.Format - -type env = (ident, value, String.comparator_witness) Map.t - -and value = - | ValueInt of int - | ValueBool of bool - | ValueString of string - | ValueUnit - | ValueClosure of is_rec * pattern * pattern list * expr * env - | ValueTuple of value * value * value list - | ValueList of value list - | ValueOption of value option - | ValueBuiltin of (value -> (value, value_error) Result.t) - -and value_error = - | UnboundVariable of ident - | TypeError - | DivisionByZeroError - | PatternMatchingError - | LHS - -let pp_value_error fmt = function - | UnboundVariable ident -> fprintf fmt "UnboundVariable: %S" ident - | TypeError -> fprintf fmt "TypeError" - | DivisionByZeroError -> fprintf fmt "DivisionByZeroError" - | PatternMatchingError -> fprintf fmt "PatternMatchingError" - | LHS -> fprintf fmt "LeftHandSide" -;; - -module type Monad = sig - type ('a, 'e) t - - val return : 'a -> ('a, 'e) t - val fail : 'e -> ('a, 'e) t - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -module Env (M : Monad) = struct - open M - - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let find map key = - match Map.find map key with - | Some value -> return value - | None -> fail (UnboundVariable key) - ;; -end - -module Eval (M : Monad) : sig - val eval_structure : program -> (env, value_error) M.t -end = struct - open M - open Env (M) - - let initial_env = - let open Base.Map in - empty (module String) - |> set - ~key:"print_int" - ~data: - (ValueBuiltin - (function - | ValueInt i -> - Stdlib.print_int i; - Stdlib.print_newline (); - Result.return ValueUnit - | _ -> Result.fail TypeError)) - |> set - ~key:"print_endline" - ~data: - (ValueBuiltin - (function - | ValueString s -> - Stdlib.print_endline s; - Result.return ValueUnit - | _ -> Result.fail TypeError)) - |> set - ~key:"print_bool" - ~data: - (ValueBuiltin - (function - | ValueBool b -> - Stdlib.print_string (Bool.to_string b); - Stdlib.print_newline (); - Result.return ValueUnit - | _ -> Result.fail TypeError)) - ;; - - let rec check_match env = function - | PatAny, _ -> Some env - | PatUnit, ValueUnit -> Some env - | PatConst (ConstInt i1), ValueInt i2 when i1 = i2 -> Some env - | PatConst (ConstBool b1), ValueBool b2 when Bool.equal b1 b2 -> Some env - | PatConst (ConstString s1), ValueString s2 when String.equal s1 s2 -> Some env - | PatVariable x, v -> Some (extend env x v) - | PatType (pat, _), v -> check_match env (pat, v) - | PatTuple (p1, p2, pl), ValueTuple (v1, v2, vl) -> - (match check_match env (p1, v1) with - | None -> None - | Some env1 -> - (match check_match env1 (p2, v2) with - | None -> None - | Some env2 -> - (match - List.fold2 pl vl ~init:(Some env2) ~f:(fun acc_env p v -> - match acc_env with - | Some env' -> check_match env' (p, v) - | None -> None) - with - | Ok result -> result - | Unequal_lengths -> None))) - | PatList patterns, ValueList values when List.length patterns = List.length values -> - let rec match_lists env pat_list val_list = - match pat_list, val_list with - | [], [] -> Some env - | p :: ps, v :: vs -> - (match check_match env (p, v) with - | Some new_env -> match_lists new_env ps vs - | None -> None) - | _ -> None - in - match_lists env patterns values - | PatOption p, ValueOption v -> - (match p, v with - | Some p, Some v -> check_match env (p, v) - | None, None -> Some env - | _ -> None) - | _ -> None - ;; - - let eval_un_op = function - | Negative, ValueInt i -> return (ValueInt (-i)) - | Not, ValueBool b -> return (ValueBool (not b)) - | _ -> fail TypeError - ;; - - let eval_binop (bop, v1, v2) = - match bop, v1, v2 with - | Multiply, ValueInt x, ValueInt y -> return (ValueInt (x * y)) - | Division, ValueInt _, ValueInt y when y = 0 -> fail DivisionByZeroError - | Division, ValueInt x, ValueInt y -> return (ValueInt (x / y)) - | Plus, ValueInt x, ValueInt y -> return (ValueInt (x + y)) - | Minus, ValueInt x, ValueInt y -> return (ValueInt (x - y)) - | Equal, ValueInt x, ValueInt y -> return (ValueBool (x = y)) - | NotEqual, ValueInt x, ValueInt y -> return (ValueBool (x <> y)) - | LowerThan, ValueInt x, ValueInt y -> return (ValueBool (x < y)) - | LowestEqual, ValueInt x, ValueInt y -> return (ValueBool (x <= y)) - | GreaterThan, ValueInt x, ValueInt y -> return (ValueBool (x > y)) - | GretestEqual, ValueInt x, ValueInt y -> return (ValueBool (x >= y)) - | And, ValueBool x, ValueBool y -> return (ValueBool (x && y)) - | Or, ValueBool x, ValueBool y -> return (ValueBool (x || y)) - | _ -> fail TypeError - ;; - - let rec eval_expr env = function - | ExpConst c -> - (match c with - | ConstInt i -> return (ValueInt i) - | ConstBool b -> return (ValueBool b) - | ConstString s -> return (ValueString s)) - | ExpIdent x -> find env x - | ExpUnarOper (op, e) -> - let* v = eval_expr env e in - eval_un_op (op, v) - | ExpBinOper (op, e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - eval_binop (op, v1, v2) - | ExpBranch (cond, then_expr, else_expr_opt) -> - let* cond_value = eval_expr env cond in - (match cond_value with - | ValueBool true -> eval_expr env then_expr - | ValueBool false -> - (match else_expr_opt with - | Some else_expr -> eval_expr env else_expr - | None -> return ValueUnit) - | _ -> fail TypeError) - | ExpLet (false, (PatList patterns, e1), _, e2) -> - let check_list_pattern = function - | PatVariable _ | PatAny | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not (List.for_all patterns ~f:check_list_pattern) - then fail LHS - else - let* v = eval_expr env e1 in - (match check_match env (PatList patterns, v) with - | Some env' -> eval_expr env' e2 - | None -> fail PatternMatchingError) - | ExpLet (false, (PatTuple (p1, p2, rest), e1), _, e2) -> - let check_tuple_pattern = function - | PatVariable _ | PatAny | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not (List.for_all ~f:check_tuple_pattern (p1 :: p2 :: rest)) - then fail LHS - else - let* v = eval_expr env e1 in - (match check_match env (PatTuple (p1, p2, rest), v) with - | Some env' -> eval_expr env' e2 - | None -> fail PatternMatchingError) - | ExpLet (false, (pat, e1), _, e2) -> - let check_simple_pattern = - match pat with - | PatAny | PatVariable _ | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not check_simple_pattern - then fail LHS - else - let* v = eval_expr env e1 in - (match check_match env (pat, v) with - | Some env' -> eval_expr env' e2 - | None -> fail PatternMatchingError) - | ExpLet (true, (pat, e1), [], e2) -> - (match pat with - | PatVariable _ -> - let* v = eval_expr env e1 in - let* rec_env = - match check_match env (pat, v) with - | Some new_env -> return new_env - | None -> fail PatternMatchingError - in - let* recursive_value = - match v with - | ValueClosure (_, p, pl, e, _) -> - return (ValueClosure (true, p, pl, e, rec_env)) - | _ -> fail TypeError - in - let* final_env = - match check_match env (pat, recursive_value) with - | Some updated_env -> return updated_env - | None -> fail PatternMatchingError - in - eval_expr final_env e2 - | _ -> fail LHS) - | ExpLet (true, value_binding, value_bindings, e2) -> - let bindings = List.map ~f:(fun (p, e) -> p, e) (value_binding :: value_bindings) in - let rec update_env acc_env = function - | [] -> return acc_env - | (PatVariable name, expr) :: tl -> - let* value = - match expr with - | ExpLambda (patterns, e) -> - let head = Option.value_exn (List.hd patterns) in - let tail = Option.value_exn (List.tl patterns) in - return (ValueClosure (true, head, tail, e, acc_env)) - | _ -> eval_expr acc_env expr - in - let updated_env = extend acc_env name value in - update_env updated_env tl - | _ -> fail LHS - in - let* final_env = update_env env bindings in - eval_expr final_env e2 - | ExpTuple (e1, e2, es) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - let* vs = - List.fold_right es ~init:(return []) ~f:(fun e acc -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - in - return (ValueTuple (v1, v2, vs)) - | ExpLambda (patterns, e) -> - let head = Option.value_exn (List.hd patterns) in - let tail = Option.value_exn (List.tl patterns) in - return (ValueClosure (false, head, tail, e, env)) - | ExpTypeAnnotation (e, _) -> eval_expr env e - | ExpFunction (e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - (match v1 with - | ValueBuiltin f -> - (match f v2 with - | Ok result -> return result - | Error err -> fail err) - | ValueClosure (_, pat, pats, body, func_env) -> - (match check_match func_env (pat, v2) with - | Some extended_env -> - let env' = - Map.fold extended_env ~init:env ~f:(fun ~key ~data acc_env -> - Map.update acc_env key ~f:(fun _ -> data)) - in - (match pats with - | [] -> eval_expr env' body - | p :: pl -> return (ValueClosure (false, p, pl, body, env'))) - | None -> fail PatternMatchingError) - | _ -> fail TypeError) - | ExpList el -> - let rec eval_list_elements env = function - | [] -> return [] - | e :: es -> - let* v = eval_expr env e in - let* vs = eval_list_elements env es in - return (v :: vs) - in - let* vl = eval_list_elements env el in - return (ValueList vl) - | ExpOption opt -> - let* value = - match opt with - | Some expr -> - let* v = eval_expr env expr in - return (Some v) - | None -> return None - in - return (ValueOption value) - ;; - - let eval_str_item env = function - | SEval expr -> - let* _ = eval_expr env expr in - return env - | SValue (false, (PatList patterns, e), _) -> - let check_list_pattern = function - | PatVariable _ | PatAny | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not (List.for_all ~f:check_list_pattern patterns) - then fail LHS - else - let* v = eval_expr env e in - (match check_match env (PatList patterns, v) with - | Some env' -> return env' - | None -> fail PatternMatchingError) - | SValue (false, (PatTuple (p1, p2, rest), e), _) -> - let check_tuple_pattern = function - | PatVariable _ | PatAny | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not (List.for_all ~f:check_tuple_pattern (p1 :: p2 :: rest)) - then fail LHS - else - let* v = eval_expr env e in - (match check_match env (PatTuple (p1, p2, rest), v) with - | Some env' -> return env' - | None -> fail PatternMatchingError) - | SValue (false, (pattern, expr), _) -> - let check_simple_pattern = - match pattern with - | PatAny | PatVariable _ | PatUnit | PatOption (Some (PatVariable _)) -> true - | _ -> false - in - if not check_simple_pattern - then fail LHS - else - let* v = eval_expr env expr in - (match check_match env (pattern, v) with - | Some env' -> return env' - | None -> fail PatternMatchingError) - | SValue (true, ((PatVariable _ as pattern), expr), []) -> - let* v = eval_expr env expr in - let* rec_env = - match check_match env (pattern, v) with - | Some new_env -> return new_env - | None -> fail PatternMatchingError - in - let* recursive_value = - match v with - | ValueClosure (_, p, pl, expr, _) -> - return (ValueClosure (true, p, pl, expr, rec_env)) - | _ -> fail TypeError - in - let* final_env = - match check_match env (pattern, recursive_value) with - | Some updated_env -> return updated_env - | None -> fail PatternMatchingError - in - return final_env - | SValue (true, _, []) -> fail LHS - | SValue (true, value_binding, value_bindings) -> - let bindings = value_binding :: value_bindings in - let rec update_env acc_env = function - | [] -> return acc_env - | (PatVariable name, expr) :: tl -> - let* value = - match expr with - | ExpLambda (patterns, expr) -> - let head = Option.value_exn (List.hd patterns) in - let tail = Option.value_exn (List.tl patterns) in - return (ValueClosure (true, head, tail, expr, acc_env)) - | _ -> eval_expr acc_env expr - in - let updated_env = extend acc_env name value in - update_env updated_env tl - | _ -> fail LHS - in - let* final_env = update_env env bindings in - return final_env - ;; - - let eval_structure structure = - List.fold_left structure ~init:(return initial_env) ~f:(fun env str_item -> - let* env = env in - let* env = eval_str_item env str_item in - return env) - ;; -end - -module Inter = Eval (struct - include Result - - let ( let* ) m f = bind m ~f - end) diff --git a/EUsoltsev/lib/interpreter.mli b/EUsoltsev/lib/interpreter.mli deleted file mode 100644 index f130cf5e6..000000000 --- a/EUsoltsev/lib/interpreter.mli +++ /dev/null @@ -1,32 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base - -type env = (ident, value, String.comparator_witness) Map.t - -and value = - | ValueInt of int - | ValueBool of bool - | ValueString of string - | ValueUnit - | ValueClosure of is_rec * pattern * pattern list * expr * env - | ValueTuple of value * value * value list - | ValueList of value list - | ValueOption of value option - | ValueBuiltin of (value -> (value, value_error) Result.t) - -and value_error = - | UnboundVariable of ident - | TypeError - | DivisionByZeroError - | PatternMatchingError - | LHS - -val pp_value_error : Stdlib.Format.formatter -> value_error -> unit - -module Inter : sig - val eval_structure : program -> (env, value_error) Result.t -end diff --git a/EUsoltsev/lib/parser.ml b/EUsoltsev/lib/parser.ml deleted file mode 100644 index e79a4f74d..000000000 --- a/EUsoltsev/lib/parser.ml +++ /dev/null @@ -1,313 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Angstrom - -let is_keyword = function - | "let" - | "match" - | "in" - | "if" - | "then" - | "else" - | "fun" - | "rec" - | "true" - | "false" - | "Some" - | "and" -> true - | _ -> false -;; - -let is_lowercase = function - | 'a' .. 'z' -> true - | _ -> false -;; - -let is_uppercase = function - | 'A' .. 'Z' -> true - | _ -> false -;; - -let is_digit = function - | '0' .. '9' -> true - | _ -> false -;; - -let white_space = take_while Char.is_whitespace -let token s = white_space *> string s -let token1 s = white_space *> s -let parse_parens p = token "(" *> p <* token ")" - -let parse_const_int = - let sign = choice [ token "" ] in - let num = take_while1 Char.is_digit in - lift2 (fun s n -> ConstInt (Int.of_string (s ^ n))) sign num -;; - -let parse_const_bool = - choice - [ token "true" *> return (ConstBool true); token "false" *> return (ConstBool false) ] -;; - -let parse_const_string = - token "\"" *> take_till (Char.equal '\"') <* token "\"" >>| fun s -> ConstString s -;; - -let parse_const = choice [ parse_const_int; parse_const_bool; parse_const_string ] -let parse_unar_oper = choice [ token "-" *> return Negative; token "not" *> return Not ] - -let parse_ident = - let parse_first_char = - satisfy (fun ch -> is_lowercase ch || is_uppercase ch || Char.equal ch '_') - >>| Char.escaped - in - let parse_other_chars = - take_while (fun ch -> - is_lowercase ch || is_uppercase ch || is_digit ch || Char.equal ch '_') - in - token1 @@ lift2 ( ^ ) parse_first_char parse_other_chars - >>= fun s -> if is_keyword s then fail "It is not identifier" else return s -;; - -let parse_base_type = - choice - [ token "int" *> return (TyPrim "int") - ; token "bool" *> return (TyPrim "bool") - ; token "string" *> return (TyPrim "string") - ; token "unit" *> return (TyPrim "unit") - ] -;; - -let rec parse_type_list t = - let* base = t in - white_space - *> token "list" - *> (parse_type_list (return (TyList base)) <|> return (TyList base)) -;; - -let parse_type = - let base_type = parse_base_type in - let list_type = parse_type_list base_type <|> base_type in - list_type -;; - -let parse_pattern_with_type parse_pattern = - let* pat = white_space *> token "(" *> parse_pattern in - let* constr = - white_space *> token ":" *> white_space *> parse_type <* white_space <* token ")" - in - return (PatType (pat, constr)) -;; - -let parse_pattern_var = parse_ident >>| fun id -> PatVariable id -let parse_pattern_const = parse_const >>| fun c -> PatConst c -let parse_pattern_any = token "_" *> return PatAny - -let parse_pattern_tuple parse_pattern = - let parse_unparenthesized = - lift3 - (fun p1 p2 rest -> PatTuple (p1, p2, rest)) - parse_pattern - (token "," *> parse_pattern) - (many (token "," *> parse_pattern)) - <* white_space - in - parse_parens parse_unparenthesized <|> parse_unparenthesized -;; - -let parse_pattern_list parse_pattern = - let semicols = token ";" in - token "[" *> (sep_by semicols parse_pattern >>| fun patterns -> PatList patterns) - <* token "]" -;; - -let parse_pattern_empty = token "()" *> return PatUnit - -let parse_pattern_option parse_pattern = - lift - (fun e -> PatOption e) - (token "Some" *> parse_pattern - >>| (fun e -> Some e) - <|> (token "None" >>| fun _ -> None)) -;; - -let parse_pattern = - fix (fun pat -> - let atom = - choice - [ parse_pattern_var - ; parse_pattern_any - ; parse_pattern_const - ; parse_pattern_empty - ; parse_pattern_with_type pat - ; parse_parens pat - ; parse_pattern_option pat - ] - in - let tuple = parse_pattern_tuple atom <|> atom in - let lst = parse_pattern_list tuple <|> tuple in - lst) -;; - -let parse_left_associative expr oper = - let rec go acc = lift2 (fun f x -> f acc x) oper expr >>= go <|> return acc in - expr >>= go -;; - -let parse_expr_bin_oper parse_bin_op tkn = - token tkn *> return (fun e1 e2 -> ExpBinOper (parse_bin_op, e1, e2)) -;; - -let multiply = parse_expr_bin_oper Multiply "*" -let division = parse_expr_bin_oper Division "/" -let plus = parse_expr_bin_oper Plus "+" -let minus = parse_expr_bin_oper Minus "-" - -let compare = - choice - [ parse_expr_bin_oper Equal "=" - ; parse_expr_bin_oper NotEqual "<>" - ; parse_expr_bin_oper LowestEqual "<=" - ; parse_expr_bin_oper LowerThan "<" - ; parse_expr_bin_oper GretestEqual ">=" - ; parse_expr_bin_oper GreaterThan ">" - ] -;; - -let and_op = parse_expr_bin_oper And "&&" -let or_op = parse_expr_bin_oper Or "||" -let parse_expr_ident = parse_ident >>| fun x -> ExpIdent x -let parse_expr_const = parse_const >>| fun c -> ExpConst c - -let parse_expr_with_type parse_expr = - let parse_annotated_type = token ":" *> parse_type in - lift2 (fun expr t -> ExpTypeAnnotation (expr, t)) parse_expr parse_annotated_type -;; - -let parse_expr_branch parse_expr = - lift3 - (fun cond t f -> ExpBranch (cond, t, f)) - (token "if" *> parse_expr) - (token "then" *> parse_expr) - (option None (token "else" *> parse_expr >>| Option.some)) -;; - -let parse_expr_option parse_expr = - choice - [ token "None" *> return (ExpOption None) - ; (token "Some" *> choice [ parse_parens parse_expr; parse_expr ] - >>| fun e -> ExpOption (Some e)) - ] -;; - -let parse_expr_unar_oper parse_expr = - parse_unar_oper >>= fun op -> parse_expr >>= fun expr -> return (ExpUnarOper (op, expr)) -;; - -let parse_expr_list parse_expr = - let parse_elements = sep_by (token ";") parse_expr in - token "[" *> parse_elements <* token "]" >>| fun elements -> ExpList elements -;; - -let parse_expr_function e = - parse_left_associative e (return (fun e1 e2 -> ExpFunction (e1, e2))) -;; - -let parse_expr_lambda parse_expr = - token "fun" *> sep_by1 white_space parse_pattern - <* token "->" - >>= fun params -> parse_expr >>| fun body -> ExpLambda (params, body) -;; - -let parse_expr_tuple parse_expr = - let commas = token "," in - let tuple = - lift3 - (fun e1 e2 rest -> ExpTuple (e1, e2, rest)) - (parse_expr <* commas) - parse_expr - (many (commas *> parse_expr)) - <* white_space - in - parse_parens tuple <|> tuple -;; - -let parse_body parse_expr = - many1 parse_pattern - >>= fun patterns -> token "=" *> parse_expr >>| fun body -> ExpLambda (patterns, body) -;; - -let parse_expr_let parse_expr = - token "let" - *> lift4 - (fun rec_flag value_bindings and_bindings body -> - ExpLet (rec_flag, value_bindings, and_bindings, body)) - (token "rec" *> (take_while1 Char.is_whitespace *> return true) <|> return false) - (lift2 - (fun pat expr -> pat, expr) - parse_pattern - (token "=" *> parse_expr <|> parse_body parse_expr)) - (many - (token "and" - *> lift2 - (fun pat expr -> pat, expr) - parse_pattern - (token "=" *> parse_expr <|> parse_body parse_expr))) - (token "in" *> parse_expr) -;; - -let parse_expr = - fix (fun expr -> - let term = - choice - [ parse_expr_ident - ; parse_expr_const - ; parse_expr_list expr - ; parse_parens expr - ; parse_parens (parse_expr_with_type expr) - ] - in - let func = parse_expr_function term in - let cons = parse_expr_option func <|> func in - let ife = parse_expr_branch expr <|> cons in - let unops = parse_expr_unar_oper ife <|> ife in - let ops1 = parse_left_associative unops (multiply <|> division) in - let ops2 = parse_left_associative ops1 (plus <|> minus) in - let cmp = parse_left_associative ops2 compare in - let boolean = parse_left_associative cmp (and_op <|> or_op) in - let tuple = parse_expr_tuple boolean <|> boolean in - let lambda = parse_expr_lambda expr <|> tuple in - choice [ parse_expr_let expr; parse_expr_lambda expr; lambda ]) -;; - -let parse_structure = - let parse_eval = parse_expr >>| fun e -> SEval e in - let parse_value = - token "let" - *> lift3 - (fun r id id_list -> SValue (r, id, id_list)) - (token "rec" *> (take_while1 Char.is_whitespace *> return true) <|> return false) - (lift2 - (fun pat expr -> pat, expr) - parse_pattern - (token "=" *> parse_expr <|> parse_body parse_expr)) - (many - (token "and" - *> lift2 - (fun pat expr -> pat, expr) - parse_pattern - (token "=" *> parse_expr <|> parse_body parse_expr))) - in - choice [ parse_eval; parse_value ] -;; - -let parse_program = - let definitions_or_exprs = many parse_structure <* option () (token ";;" >>| ignore) in - definitions_or_exprs <* white_space -;; - -let parse input = parse_string ~consume:All parse_program input diff --git a/EUsoltsev/lib/parser.mli b/EUsoltsev/lib/parser.mli deleted file mode 100644 index 2236c1979..000000000 --- a/EUsoltsev/lib/parser.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> (Ast.program, string) result diff --git a/EUsoltsev/tests/.gitignore b/EUsoltsev/tests/.gitignore deleted file mode 100644 index 26685e795..000000000 --- a/EUsoltsev/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -lam*.txt \ No newline at end of file diff --git a/EUsoltsev/tests/dune b/EUsoltsev/tests/dune deleted file mode 100644 index 4e481bc8c..000000000 --- a/EUsoltsev/tests/dune +++ /dev/null @@ -1,38 +0,0 @@ -(library - (name tests) - (libraries EUsoltsev_lib) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to tests) - (deps - ../bin/main.exe - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml)) diff --git a/EUsoltsev/tests/inferencer_tests.ml b/EUsoltsev/tests/inferencer_tests.ml deleted file mode 100644 index 73f040cd6..000000000 --- a/EUsoltsev/tests/inferencer_tests.ml +++ /dev/null @@ -1,166 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EUsoltsev_lib -open Inferencer -open Ast - -let pretty_printer_parse_and_infer s = - match Parser.parse s with - | Ok parsed -> - (match run_infer parsed with - | Ok env -> - let filtered_env = - Base.Map.filter_keys env ~f:(fun key -> - not (List.mem key [ "print_int"; "print_endline"; "print_bool" ])) - in - Base.Map.iteri filtered_env ~f:(fun ~key ~data:(S (_, ty)) -> - Format.printf "val %s: %a\n" key pp_ty ty) - | Error e -> Format.printf "Infer error. %a\n" pp_error e) - | Error e -> Format.printf "Parsing error. %s\n" e -;; - -let pretty_printer_parse_and_infer_simple s = - match Parser.parse s with - | Ok parsed -> - (match parsed with - | [ SEval expr ] -> - (match infer_simple_expression expr with - | Ok ty -> Format.printf "%a\n" pp_ty ty - | Error e -> Format.printf "Infer error. %a\n" pp_error e) - | _ -> - Format.printf - "Expected a single expression, but got a program with multiple structures.\n") - | Error e -> Format.printf "Parsing error. %s\n" e -;; - -let%expect_test "test_binary_oper" = - pretty_printer_parse_and_infer_simple "10/2 + 56*2 - 10 / 10 / 20 + 666 - 777 + 1"; - [%expect {|int|}] -;; - -let%expect_test "test_bool" = - pretty_printer_parse_and_infer_simple "false"; - [%expect {|bool|}] -;; - -let%expect_test "test_string" = - pretty_printer_parse_and_infer_simple "\"I like OCaml\" "; - [%expect {|string|}] -;; - -let%expect_test "test_option" = - pretty_printer_parse_and_infer_simple "Some 10"; - [%expect {|int option|}] -;; - -let%expect_test "test_binary_oper_and_arg" = - pretty_printer_parse_and_infer_simple "fun x -> x * 69 + 100 - 201 / 777"; - [%expect {|int -> int|}] -;; - -let%expect_test "test_rec" = - pretty_printer_parse_and_infer "let rec func arg = func arg"; - [%expect {|val func: '1 -> '2|}] -;; - -let%expect_test "test_func_apply_some_args" = - pretty_printer_parse_and_infer "let func a1 a2 a3 = a1 a2 a3"; - [%expect {|val func: ('1 -> '2 -> '4) -> '1 -> '2 -> '4|}] -;; - -let%expect_test "test_tuple" = - pretty_printer_parse_and_infer_simple "fun x y z -> (x + 10, y / 2 , z)"; - [%expect {|int -> int -> '2 -> (int * int * '2)|}] -;; - -let%expect_test "test_list" = - pretty_printer_parse_and_infer "let arr = [1;2;3]"; - [%expect {|val arr: int list|}] -;; - -let%expect_test "test_binary_oper" = - pretty_printer_parse_and_infer "let is_above_10 x = if x > 10 then true else false "; - [%expect {|val is_above_10: int -> bool|}] -;; - -let%expect_test "test_binary_oper" = - pretty_printer_parse_and_infer "let is_above_10 x = x > 10"; - [%expect {|val is_above_10: int -> bool|}] -;; - -let%expect_test "test_factorial" = - pretty_printer_parse_and_infer "let rec fac n = if n < 2 then 1 else n * fac (n - 1)"; - [%expect {|val fac: int -> int|}] -;; - -let%expect_test "test_nested_list_function" = - pretty_printer_parse_and_infer "let f x = [ [x; x]; [x] ]"; - [%expect {|val f: '0 -> '0 list list|}] -;; - -let%expect_test "test_nested_option_function" = - pretty_printer_parse_and_infer "let f x = Some x"; - [%expect {|val f: '0 -> '0 option|}] -;; - -let%expect_test "test_fibonacci" = - pretty_printer_parse_and_infer - "let rec fibo n = if n < 2 then 1 else fibo(n - 1) + fibo(n - 2)"; - [%expect {|val fibo: int -> int|}] -;; - -let%expect_test "test_unbound_var" = - pretty_printer_parse_and_infer "let f = x"; - [%expect {|Infer error. Unbound variable 'x'.|}] -;; - -let%expect_test "test_annotate" = - pretty_printer_parse_and_infer "let sum = fun (x : int) (y : int) -> x + y"; - [%expect {|val sum: int -> int -> int|}] -;; - -let%expect_test "test_annotate_fac" = - pretty_printer_parse_and_infer - "let rec fac = fun (n : int) (acc : int) -> if n < 2 then acc else fac (n-1) (acc * \ - n);;"; - [%expect {|val fac: int -> int -> int|}] -;; - -let%expect_test "test_program_1" = - pretty_printer_parse_and_infer - "let div = fun x y -> x / y \n\ - \ let sum = fun x y -> x + y\n\ - \ let res = fun x y z -> div x (sum y z)"; - [%expect - {| - val div: int -> int -> int - val res: int -> int -> int -> int - val sum: int -> int -> int|}] -;; - -let%expect_test "test_program_2" = - pretty_printer_parse_and_infer - "let square = fun x -> x * x\n\ - \ let result = square 10"; - [%expect {| - val result: int - val square: int -> int|}] -;; - -let%expect_test "test_annotate_error" = - pretty_printer_parse_and_infer "let sum (x : int) (y : string) = x + y"; - [%expect {|Infer error. Failed to unify types: string and int.|}] -;; - -let%expect_test "test_unification_types" = - pretty_printer_parse_and_infer "fun x -> x + true"; - [%expect {|Infer error. Failed to unify types: bool and int.|}] -;; - -let%expect_test "test_option_type_error" = - pretty_printer_parse_and_infer - "let f x = Some (x + 1) in let g y = Some (y && true) in f = g"; - [%expect {|Infer error. Failed to unify types: bool and int.|}] -;; diff --git a/EUsoltsev/tests/inferencer_tests.mli b/EUsoltsev/tests/inferencer_tests.mli deleted file mode 100644 index 54e45fa8d..000000000 --- a/EUsoltsev/tests/inferencer_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EUsoltsev/tests/interpreter_tests.ml b/EUsoltsev/tests/interpreter_tests.ml deleted file mode 100644 index c3207d4ab..000000000 --- a/EUsoltsev/tests/interpreter_tests.ml +++ /dev/null @@ -1,241 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EUsoltsev_lib -open Interpreter - -let test_interpret s = - let open Stdlib.Format in - match Parser.parse s with - | Ok parsed -> - (match Inter.eval_structure parsed with - | Ok _ -> () - | Error e -> printf "Interpreter error: %a\n" pp_value_error e) - | Error e -> printf "Parsing error: %s\n" e -;; - -let%expect_test "test_unit" = - test_interpret "let () = print_int(10 / 10 + 2 * 50 + 89 - 89)"; - [%expect {|101|}] -;; - -let%expect_test "test_bool" = - test_interpret - "let () = print_bool(true) in\n\ - \ let () = print_bool(false) in\n\ - \ let () = print_bool(not true) in \n\ - \ let () = print_bool(not false) in\n\ - \ let () = print_bool(true && false) in\n\ - \ let () = print_bool(true || false ) in 9"; - [%expect {| - true - false - false - true - false - true|}] -;; - -let%expect_test "test_bin_oper" = - test_interpret - "let a = 1\n\ - \ let b = 2\n\ - \ let () = print_bool(a = a)\n\ - \ let () = print_bool(b > a)\n\ - \ let () = print_bool(a < b)\n\ - \ let () = print_bool(a <> b)\n\ - \ let () = print_bool(a <> a)\n\ - \ let () = print_bool(a <= a)\n\ - \ let () = print_bool(a >= a)\n\ - \ let () = print_bool(a <= b)\n\ - \ let () = print_bool(a >= b)"; - [%expect - {| - true - true - true - true - false - true - true - true - false|}] -;; - -let%expect_test "test_adder" = - test_interpret - "let create_adder x =\n\ - \ let adder y = x + y in\n\ - \ adder\n\ - \ let sum_two_arg = print_int(create_adder 10 20)"; - [%expect {|30|}] -;; - -let%expect_test "test_lambda" = - test_interpret - "let create_adder = fun x -> fun y -> x + y\n\ - \ let () = print_int(create_adder 7 8)"; - [%expect {|15|}] -;; - -let%expect_test "test_print_string" = - test_interpret "let () = print_endline \"I like OCaml\""; - [%expect {|I like OCaml|}] -;; - -let%expect_test "test_not_print" = - test_interpret - "let create_adder x =\n\ - \ let adder y = x + y in\n\ - \ adder\n\ - \ let fac n = if n < 2 then 1 else n * fac(n-1) \n\ - \ let x = 1\n\ - \ let y = true"; - [%expect {||}] -;; - -let%expect_test "test_factorial" = - test_interpret - "let rec fac n = if n < 2 then 1 else n * fac(n-1) \n\ - \ let result = print_int(fac 5)"; - [%expect {|120|}] -;; - -let%expect_test "test_factorial_cps" = - test_interpret - "let rec fac_cps n k =\n\ - \ if n=1 then k 1 else\n\ - \ fac_cps (n-1) (fun p -> k (p*n))\n\ - \ let result = print_int(fac_cps 5 (fun x -> x))"; - [%expect {|120|}] -;; - -let%expect_test "test_fibonacci" = - test_interpret - "let rec fibo n = if n < 2 then 1 else fibo(n-1) + fibo(n-2)\n\ - \ let result = print_int(fibo 5)"; - [%expect {|8|}] -;; - -let%expect_test "test_fix" = - test_interpret - "let rec fix f x = f (fix f) x\n\ - \ let fac self n = if n<=1 then 1 else n * self (n-1)\n\ - \ let f = print_int (fix fac 5)"; - [%expect {|120|}] -;; - -let%expect_test "test_nested_recursive_closure" = - test_interpret - "\n\ - \ let rec outer x =\n\ - \ let rec inner y = x + y in\n\ - \ inner\n\ - \ let inner = outer 10\n\ - \ let () = print_int (inner 5)"; - [%expect {|15|}] -;; - -let%expect_test "test_annotate_sum" = - test_interpret "let sum (x : int) (y : int) = x + y let res = print_int(sum 10 20)"; - [%expect {|30|}] -;; - -let%expect_test "test_annotate_fac" = - test_interpret - "let rec fac (n : int) (acc : int) = if n < 2 then acc else fac (n-1) (acc * n)\n\ - \ let res = print_int (fac 5 1)"; - [%expect {|120|}] -;; - -let%expect_test "test_tuple" = - test_interpret - "let (a,b) = (1 + 1 * 10,2 - 1 * 5)\n\ - \ let () = print_int a \n\ - \ let () = print_int b"; - [%expect {| - 11 - -3|}] -;; - -let%expect_test "test_nested_tuple" = - test_interpret - "\n\ - \ let (a, b) = (1 + 2, 3 * 4)\n\ - \ let (c, d) = (a + b, b - a)\n\ - \ let () = print_int c\n\ - \ let () = print_int d"; - [%expect {| - 15 - 9|}] -;; - -let%expect_test "test_pattern_list" = - test_interpret - "let lst = [1;2;3]\n\ - \ let [a; b; c] = lst in \n\ - \ let () = print_int(a) in\n\ - \ let () = print_int(b) in \n\ - \ let () = print_int(c) in 0"; - [%expect {| - 1 - 2 - 3|}] -;; - -let%expect_test "test_closure" = - test_interpret - "let x = \n\ - \ let y = \n\ - \ let z = \n\ - \ let w = 1\n\ - \ in w\n\ - \ in z\n\ - \ in y\n\ - \ \n\ - \ let () = print_int x"; - [%expect {|1|}] -;; - -let%expect_test "test_let_and_fac" = - test_interpret - {| - let rec factorial n = if n <= 1 then 1 else n * helper (n - 1) - and helper x = factorial x in - let () = print_int (factorial 5) in 0 - |}; - [%expect {| - 120 - |}] -;; - -let%expect_test "test_div_error" = - test_interpret "let div = fun x y -> x / y\n let res = div 10 0"; - [%expect {|Interpreter error: DivisionByZeroError|}] -;; - -let%expect_test "test_div_error" = - test_interpret "let div = fun x y -> x / y \n let res = div 10 0"; - [%expect {|Interpreter error: DivisionByZeroError|}] -;; - -let%expect_test "test_pm_error" = - test_interpret "let (a, b) = (1,2,3)"; - [%expect {|Interpreter error: PatternMatchingError|}] -;; - -let%expect_test "test_pm_error" = - test_interpret "let x = x + 1"; - [%expect {|Interpreter error: UnboundVariable: "x"|}] -;; - -let%expect_test "test_type_error_addition" = - test_interpret "let x = 10 + true"; - [%expect {|Interpreter error: TypeError|}] -;; - -let%expect_test "test_type_error_addition" = - test_interpret "let rec (a, b) = (1,2)"; - [%expect {|Interpreter error: LeftHandSide|}] -;; diff --git a/EUsoltsev/tests/interpreter_tests.mli b/EUsoltsev/tests/interpreter_tests.mli deleted file mode 100644 index 54e45fa8d..000000000 --- a/EUsoltsev/tests/interpreter_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EUsoltsev/tests/manytests b/EUsoltsev/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/EUsoltsev/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/EUsoltsev/tests/parser_tests.ml b/EUsoltsev/tests/parser_tests.ml deleted file mode 100644 index 7cc349880..000000000 --- a/EUsoltsev/tests/parser_tests.ml +++ /dev/null @@ -1,181 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open EUsoltsev_lib -open Ast -open Parser -open Printf - -let parse_test input = - match parse input with - | Ok ast -> printf "%s\n" (show_program ast) - | Error fail -> printf "Ошибка: %s\n" fail -;; - -let%expect_test "factorial" = - parse_test "let rec factorial n = if n < 2 then 1 else n * factorial(n - 1);;"; - [%expect - {| - [(SValue (true, - ((PatVariable "factorial"), - (ExpLambda ([(PatVariable "n")], - (ExpBranch ( - (ExpBinOper (LowerThan, (ExpIdent "n"), (ExpConst (ConstInt 2)))), - (ExpConst (ConstInt 1)), - (Some (ExpBinOper (Multiply, (ExpIdent "n"), - (ExpFunction ((ExpIdent "factorial"), - (ExpBinOper (Minus, (ExpIdent "n"), - (ExpConst (ConstInt 1)))) - )) - ))) - )) - ))), - [])) - ] -|}] -;; - -let%expect_test "fibonacci" = - parse_test "let rec fibo n = if n < 2 then 1 else fibo(n - 1) + fibo(n - 2) ;;"; - [%expect - {| - [(SValue (true, - ((PatVariable "fibo"), - (ExpLambda ([(PatVariable "n")], - (ExpBranch ( - (ExpBinOper (LowerThan, (ExpIdent "n"), (ExpConst (ConstInt 2)))), - (ExpConst (ConstInt 1)), - (Some (ExpBinOper (Plus, - (ExpFunction ((ExpIdent "fibo"), - (ExpBinOper (Minus, (ExpIdent "n"), - (ExpConst (ConstInt 1)))) - )), - (ExpFunction ((ExpIdent "fibo"), - (ExpBinOper (Minus, (ExpIdent "n"), - (ExpConst (ConstInt 2)))) - )) - ))) - )) - ))), - [])) - ] -|}] -;; - -let%expect_test "lambda_test" = - parse_test "let add x = fun y -> x + y;;"; - [%expect - {| - [(SValue (false, - ((PatVariable "add"), - (ExpLambda ([(PatVariable "x")], - (ExpLambda ([(PatVariable "y")], - (ExpBinOper (Plus, (ExpIdent "x"), (ExpIdent "y"))))) - ))), - [])) - ] -|}] -;; - -let%expect_test "test_tuple" = - parse_test "let x = (1, 2, true) in x;;"; - [%expect - {| - [(SEval - (ExpLet (false, - ((PatVariable "x"), - (ExpTuple ((ExpConst (ConstInt 1)), (ExpConst (ConstInt 2)), - [(ExpConst (ConstBool true))]))), - [], (ExpIdent "x")))) - ] -|}] -;; - -let%expect_test "test_list" = - parse_test "let arr = [1;2;true]"; - [%expect - {| - [(SValue (false, - ((PatVariable "arr"), - (ExpList - [(ExpConst (ConstInt 1)); (ExpConst (ConstInt 2)); - (ExpConst (ConstBool true))])), - [])) - ] -|}] -;; - -let%expect_test "test_one_element_in_tuple" = - parse_test "let x = (666)"; - [%expect - {| - [(SValue (false, ((PatVariable "x"), (ExpConst (ConstInt 666))), []))] -|}] -;; - -let%expect_test "test_sum_two_args" = - parse_test "let sum x y = x + y"; - [%expect - {| -[(SValue (false, - ((PatVariable "sum"), - (ExpLambda ([(PatVariable "x"); (PatVariable "y")], - (ExpBinOper (Plus, (ExpIdent "x"), (ExpIdent "y")))))), - [])) - ] -|}] -;; - -let%expect_test "test_annotate_type_1" = - parse_test "let sum (x:int) (y:int) = x + y"; - [%expect - {| -[(SValue (false, - ((PatVariable "sum"), - (ExpLambda ( - [(PatType ((PatVariable "x"), (TyPrim "int"))); - (PatType ((PatVariable "y"), (TyPrim "int")))], - (ExpBinOper (Plus, (ExpIdent "x"), (ExpIdent "y")))))), - [])) - ] -|}] -;; - -let%expect_test "test_annotate_type_2" = - parse_test "let (a : int list) = [] "; - [%expect - {| -[(SValue (false, - ((PatType ((PatVariable "a"), (TyList (TyPrim "int")))), (ExpList [])), - [])) - ] -|}] -;; - -let%expect_test "test_minus" = - parse_test "-1 -2 - (-1) -(3)"; - [%expect - {| -[(SEval - (ExpBinOper (Minus, - (ExpBinOper (Minus, - (ExpBinOper (Minus, - (ExpUnarOper (Negative, (ExpConst (ConstInt 1)))), - (ExpConst (ConstInt 2)))), - (ExpUnarOper (Negative, (ExpConst (ConstInt 1)))))), - (ExpConst (ConstInt 3))))) - ] - |}] -;; - -let%expect_test "test_unit" = - parse_test "let () = print_int 5"; - [%expect - {| -[(SValue (false, - (PatUnit, (ExpFunction ((ExpIdent "print_int"), (ExpConst (ConstInt 5))))), - [])) - ] - |}] -;; diff --git a/EUsoltsev/tests/parser_tests.mli b/EUsoltsev/tests/parser_tests.mli deleted file mode 100644 index 54e45fa8d..000000000 --- a/EUsoltsev/tests/parser_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/EUsoltsev/tests/tests.t b/EUsoltsev/tests/tests.t deleted file mode 100644 index a68929689..000000000 --- a/EUsoltsev/tests/tests.t +++ /dev/null @@ -1,143 +0,0 @@ -(** Copyright 2024-2025, Danil Usoltsev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ../bin/main.exe -interpret -file manytests/typed/001fac.ml - 24 - - $ ../bin/main.exe -interpret -file manytests/typed/002fac.ml - 24 - - $ ../bin/main.exe -interpret -file manytests/typed/003fib.ml - 3 - 3 - - $ ../bin/main.exe -interpret -file manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - - $ ../bin/main.exe -interpret -file manytests/typed/005fix.ml - 720 - - $ ../bin/main.exe -interpret -file manytests/typed/006partial.ml - 1122 - - $ ../bin/main.exe -interpret -file manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - - $ ../bin/main.exe -interpret -file manytests/typed/006partial3.ml - 4 - 8 - 9 - - $ ../bin/main.exe -interpret -file manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - - $ ../bin/main.exe -interpret -file manytests/typed/008ascription.ml - 8 - - $ ../bin/main.exe -interpret -file manytests/typed/009let_poly.ml - - $ ../bin/main.exe -interpret -file manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - - $ ../bin/main.exe -infer -file manytests/typed/001fac.ml - val fac: int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/002fac.ml - val fac_cps: int -> (int -> int) -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/003fib.ml - val fib: int -> int - val fib_acc: int -> int -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/004manyargs.ml - val main: int - val test10: int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val test3: int -> int -> int -> int - val wrap: '0 -> '0 - - $ ../bin/main.exe -infer -file manytests/typed/005fix.ml - val fac: (int -> int) -> int -> int - val fix: ((int -> int) -> int -> int) -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial.ml - val foo: int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial2.ml - val foo: int -> int -> int -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/006partial3.ml - val foo: int -> int -> int -> unit - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/007order.ml - val _start: unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main: unit - - $ ../bin/main.exe -infer -file manytests/typed/008ascription.ml - val addi: ('2 -> bool -> int) -> ('2 -> bool) -> '2 -> int - val main: int - - $ ../bin/main.exe -infer -file manytests/typed/009let_poly.ml - val temp: (int * bool) - - $ ../bin/main.exe -infer -file manytests/typed/015tuples.ml - val feven: ('29 * int -> '33) -> int -> int - val fix: ((((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int)) -> ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int)) -> ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int) - val fixpoly: ((int -> int * int -> int) -> int -> int * (int -> int * int -> int) -> int -> int) -> (int -> int * int -> int) - val fodd: (int -> '40 * '37) -> int -> int - val main: int - val map: ('9 -> '11) -> ('9 * '9) -> ('10 * '11) - val meven: int -> int - val modd: int -> int - val tie: (int -> int * int -> int) - - - $ ../bin/main.exe -infer -file manytests/do_not_type/001.ml - Infer error. Unbound variable 'fac'. - - $ ../bin/main.exe -infer -file manytests/do_not_type/002if.ml - Infer error. Failed to unify types: int and bool. - - $ ../bin/main.exe -infer -file manytests/do_not_type/003occurs.ml - Infer error. Occurs check failed. Type variable '1 occurs inside '1 -> '3. - - $ ../bin/main.exe -infer -file manytests/do_not_type/004let_poly.ml - Infer error. Failed to unify types: int and bool. - - $ ../bin/main.exe -infer -file manytests/do_not_type/015tuples.ml - Infer error. Left-hand side error: Only variables are allowed on the left-hand side of let rec. - - $ ../bin/main.exe -infer -file manytests/do_not_type/016tuples_mismatch.ml - Infer error. Failed to unify types: ('0 * '1) and (int * int * int). - - $ ../bin/main.exe -infer -file manytests/do_not_type/097fun_vs_list.ml - Infer error. Failed to unify types: '2 list and '0 -> '0. - - $ ../bin/main.exe -infer -file manytests/do_not_type/097fun_vs_unit.ml - Infer error. Failed to unify types: unit and '0 -> '0. - - $ ../bin/main.exe -infer -file manytests/do_not_type/098rec_int.ml - Infer error. Right-hand side error: Right-hand side of let rec must be a lambda expression. - diff --git a/FSharpActivePatterns/.envrc b/FSharpActivePatterns/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/FSharpActivePatterns/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/FSharpActivePatterns/.gitignore b/FSharpActivePatterns/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/FSharpActivePatterns/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/FSharpActivePatterns/.ocamlformat b/FSharpActivePatterns/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/FSharpActivePatterns/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/FSharpActivePatterns/.zanuda b/FSharpActivePatterns/.zanuda deleted file mode 100644 index 43cfa2792..000000000 --- a/FSharpActivePatterns/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore exec.ml diff --git a/FSharpActivePatterns/COPYING b/FSharpActivePatterns/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/FSharpActivePatterns/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/FSharpActivePatterns/COPYING.CC0 b/FSharpActivePatterns/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/FSharpActivePatterns/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/FSharpActivePatterns/COPYING.LESSER b/FSharpActivePatterns/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/FSharpActivePatterns/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/FSharpActivePatterns/FSharpActivePatterns.opam b/FSharpActivePatterns/FSharpActivePatterns.opam deleted file mode 100644 index bb90632fe..000000000 --- a/FSharpActivePatterns/FSharpActivePatterns.opam +++ /dev/null @@ -1,38 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for F# with active patterns" -description: - "An interpreter for F# with supported active patterns feature (mb fix later)" -maintainer: ["Ksenia Kotelnikova, Gleb Nasretdinov"] -authors: ["Ksenia Kotelnikova, Gleb Nasretdinov"] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Ycyken/fp2024" -doc: "FIX LATER https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Ycyken/fp2024" -depends: [ - "dune" {>= "3.7"} - "qcheck-core" - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "ppx_deriving_qcheck" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/FSharpActivePatterns/Makefile b/FSharpActivePatterns/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/FSharpActivePatterns/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/FSharpActivePatterns/abc.txt b/FSharpActivePatterns/abc.txt deleted file mode 100644 index 7b28e9a78..000000000 --- a/FSharpActivePatterns/abc.txt +++ /dev/null @@ -1,11 +0,0 @@ -;; -;; -;; -;; -1;; -;; -2;; - - - - diff --git a/FSharpActivePatterns/bin/REPL.ml b/FSharpActivePatterns/bin/REPL.ml deleted file mode 100644 index f7f0260c0..000000000 --- a/FSharpActivePatterns/bin/REPL.ml +++ /dev/null @@ -1,31 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open FSharpActivePatterns.REPLUtils - -type opts = - { mutable dump_parsetree : bool - ; mutable input_file : string option - } - -let () = - let opts = { dump_parsetree = false; input_file = None } in - let open Stdlib.Arg in - let speclist = - [ ( "-dparsetree" - , Unit (fun _ -> opts.dump_parsetree <- true) - , "Dump parse tree, don't evaluate anything" ) - ; ( "-fromfile" - , String (fun filename -> opts.input_file <- Some filename) - , "Input file name" ) - ] - in - let anon_func _ = - Stdlib.Format.eprintf "Positioned arguments are not supported\n"; - Stdlib.exit 1 - in - let usage_msg = "Read-Eval-Print-Loop for F# with Active Patterns" in - let () = parse speclist anon_func usage_msg in - run_repl opts.dump_parsetree opts.input_file -;; diff --git a/FSharpActivePatterns/bin/dune b/FSharpActivePatterns/bin/dune deleted file mode 100644 index 1e10d57b2..000000000 --- a/FSharpActivePatterns/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (public_name repl) - (name REPL) - (libraries FSharpActivePatterns stdlib str) - (instrumentation - (backend bisect_ppx))) diff --git a/FSharpActivePatterns/bin/input.txt b/FSharpActivePatterns/bin/input.txt deleted file mode 100644 index 707522f2c..000000000 --- a/FSharpActivePatterns/bin/input.txt +++ /dev/null @@ -1,9 +0,0 @@ -let (|Even|Odd|) v = - if v+2 = 0 then Even (v+10) - else Odd (v) - -let res = match 1 with - | Even val -> val - | Odd val -> val - in print_int res - diff --git a/FSharpActivePatterns/dune b/FSharpActivePatterns/dune deleted file mode 100644 index 98e54536a..000000000 --- a/FSharpActivePatterns/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/FSharpActivePatterns/dune-project b/FSharpActivePatterns/dune-project deleted file mode 100644 index d26478070..000000000 --- a/FSharpActivePatterns/dune-project +++ /dev/null @@ -1,34 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Ksenia Kotelnikova, Gleb Nasretdinov") - -(maintainers "Ksenia Kotelnikova, Gleb Nasretdinov") - -(bug_reports "https://github.com/Ycyken/fp2024") - -(homepage "https://github.com/Ycyken/fp2024") - -(package - (name FSharpActivePatterns) - (synopsis "An interpreter for F# with active patterns") - (description - "An interpreter for F# with supported active patterns feature (mb fix later)") - (documentation "FIX LATER https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - qcheck-core - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - ppx_deriving_qcheck - bisect_ppx - (odoc :with-doc) - (ocamlformat :build))) diff --git a/FSharpActivePatterns/lib/REPLUtils.ml b/FSharpActivePatterns/lib/REPLUtils.ml deleted file mode 100644 index c58438bba..000000000 --- a/FSharpActivePatterns/lib/REPLUtils.ml +++ /dev/null @@ -1,163 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open AstPrinter -open Parser -open Inferencer -open TypesPp -open Ast -open Interpreter -open Stdlib - -type input = - | Input of string - | EOF - -type run_result = - | Result of (construction, string) result - | Empty - | End - -let input_upto_sep sep ic = - let sep_len = String.length sep in - let take_line () = In_channel.input_line ic in - let rec fill_buffer b = - let line = take_line () in - match line with - | None -> EOF - | Some line -> - let line = String.trim line in - let len = String.length line in - if String.ends_with ~suffix:sep line - then ( - Buffer.add_substring b line 0 (len - sep_len); - Buffer.add_string b "\n"; - Input (Buffer.contents b)) - else ( - Buffer.add_string b line; - Buffer.add_string b "\n"; - fill_buffer b) - in - let buffer = Buffer.create 1024 in - fill_buffer buffer -;; - -let input_with_indents ic = - let take_line () = In_channel.input_line ic in - let rec fill_buffer b = - let start_pos = pos_in ic in - let line = take_line () in - match line with - | None -> Input (Buffer.contents b) - | Some line -> - let is_empty = String.length line = 0 in - let is_continue = - List.exists (fun pref -> String.starts_with ~prefix:pref line) [ " "; "\t"; "\n" ] - || is_empty - || String.starts_with ~prefix:"and" (String.trim line) - in - if is_continue - then ( - Buffer.add_string b (line ^ "\n"); - fill_buffer b) - else ( - seek_in ic start_pos; - Buffer.add_string b "\n"; - Input (Buffer.contents b)) - in - let buffer = Buffer.create 1024 in - let first_line = take_line () in - match first_line with - | None -> EOF - | Some first_line -> - Buffer.add_string buffer (first_line ^ "\n"); - fill_buffer buffer -;; - -type in_channel = - | File of Stdlib.in_channel - | Stdin - -let run_single ic = - let input = - match ic with - | Stdin -> input_upto_sep ";;" Stdlib.stdin - | File ic -> input_with_indents ic - in - match input with - | EOF -> End - | Input input -> if String.trim input = "" then Empty else Result (parse input) -;; - -let run_repl dump_parsetree input_file = - let ic = - match input_file with - | Some n -> File (open_in n) - | None -> Stdin - in - let rec run_repl_helper run type_env value_env state values_acc = - let open Format in - match run ic with - | Result (Error _) -> - fprintf err_formatter "Parsing error\n"; - run_repl_helper run type_env value_env state values_acc - | Empty -> - fprintf std_formatter "\n"; - print_flush (); - run_repl_helper run type_env value_env state values_acc - | End -> type_env, value_env, values_acc - | Result (Ok ast) -> - if dump_parsetree - then ( - print_construction std_formatter ast; - run_repl_helper run type_env value_env state values_acc) - else ( - let result = run_interpreter type_env value_env state ast in - match result with - | new_state, Error err -> - fprintf err_formatter "Error occured: %a\n" pp_global_error err; - print_flush (); - run_repl_helper run type_env value_env new_state values_acc - | new_state, Ok (new_type_env, new_value_env, evaled_names) -> - (match ic with - | Stdin -> - Base.Map.iteri - ~f:(fun ~key ~data -> - let t, v = data in - fprintf - std_formatter - "val %s : %a = %a\n" - key - pp_typ - t - ValueEnv.pp_value - v) - evaled_names; - print_flush (); - run_repl_helper run new_type_env new_value_env new_state values_acc - | File _ -> - let overwrite map1 map2 = - Base.Map.fold - ~init:map1 - ~f:(fun ~key ~data map1 -> Base.Map.set map1 ~key ~data) - map2 - in - let values_acc = overwrite values_acc evaled_names in - run_repl_helper run new_type_env new_value_env new_state values_acc)) - in - let type_env = TypeEnv.default in - let value_env = ValueEnv.default in - let _, _, evaled_values = - run_repl_helper run_single type_env value_env 0 (Base.Map.empty (module Base.String)) - in - Base.Map.iteri evaled_values ~f:(fun ~key ~data:(typ, value) -> - Format.fprintf - Format.std_formatter - "val %s : %a = %a\n" - key - pp_typ - typ - ValueEnv.pp_value - value) -;; diff --git a/FSharpActivePatterns/lib/REPLUtils.mli b/FSharpActivePatterns/lib/REPLUtils.mli deleted file mode 100644 index 7ae8b592b..000000000 --- a/FSharpActivePatterns/lib/REPLUtils.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run_repl : bool -> string option -> unit diff --git a/FSharpActivePatterns/lib/ast.ml b/FSharpActivePatterns/lib/ast.ml deleted file mode 100644 index cd1c8d13a..000000000 --- a/FSharpActivePatterns/lib/ast.ml +++ /dev/null @@ -1,200 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open KeywordChecker -open TypedTree -open TypesPp - -type ident = Ident of string (** identifier *) [@@deriving show { with_path = false }] - -let gen_char_of_range l r = - QCheck.Gen.(map Char.chr (int_range (Char.code l) (Char.code r))) -;; - -let gen_varname ~uppercase = - let open QCheck.Gen in - let loop = - let gen_first_char = - if uppercase - then frequency [ 26, gen_char_of_range 'A' 'Z'; 1, return '_' ] - else frequency [ 26, gen_char_of_range 'a' 'z'; 1, return '_' ] - in - let gen_next_char = - frequency [ 26 + 26 + 1, gen_first_char; 10, gen_char_of_range '0' '9' ] - in - map2 - (fun first rest -> String.make 1 first ^ Base.String.of_char_list rest) - gen_first_char - (list_size (1 -- 3) gen_next_char) - in - loop >>= fun name -> if is_keyword name then loop else return name -;; - -let gen_ident = QCheck.Gen.map (fun s -> Ident s) (gen_varname ~uppercase:false) -let gen_ident_uppercase = QCheck.Gen.map (fun s -> Ident s) (gen_varname ~uppercase:true) - -let gen_escape_sequence = - let open QCheck.Gen in - oneofl [ "\\\""; "\\\\"; "\\n"; "\\t" ] -;; - -let gen_string_of_regular_char = - let open QCheck.Gen in - let gen_int = - frequency - [ 33 - 32 + 1, int_range 32 33 - ; 91 - 35 + 1, int_range 35 91 - ; 126 - 93 + 1, int_range 93 126 - ] - in - map (fun c -> String.make 1 c) (map Char.chr gen_int) -;; - -let gen_string = - let open QCheck.Gen in - let atom = frequency [ 1, gen_escape_sequence; 30, gen_string_of_regular_char ] in - let+ atoms = list_size (0 -- 20) atom in - String.concat "" atoms -;; - -type literal = - | Int_lt of (int[@gen QCheck.Gen.pint]) (** [0], [1], [30] *) - | Bool_lt of bool (** [false], [true] *) - | String_lt of (string[@gen gen_string]) (** ["Hello world"] *) - | Unit_lt (** [Unit] *) -[@@deriving show { with_path = false }, qcheck] - -type binary_operator = - | Binary_equal (** [=] *) - | Binary_unequal (** [<>] *) - | Binary_less (** [<] *) - | Binary_less_or_equal (** [<=] *) - | Binary_greater (** [>] *) - | Binary_greater_or_equal (** [>=] *) - | Binary_add (** [+] *) - | Binary_subtract (** [-] *) - | Binary_multiply (** [*] *) - | Logical_or (** [||] *) - | Logical_and (** [&&] *) - | Binary_divide (** [/] *) - | Binary_or_bitwise (** [|||] *) - | Binary_xor_bitwise (** [^^^] *) - | Binary_and_bitwise (** [&&&] *) - | Binary_cons (** [::] *) -[@@deriving show { with_path = false }, qcheck] - -type unary_operator = - | Unary_minus (** unary [-] *) - | Unary_not (** unary [not] *) -[@@deriving show { with_path = false }, qcheck] - -type pattern = - | Wild (** [_] *) - | PList of - (pattern list[@gen QCheck.Gen.(list_size (0 -- 3) (gen_pattern_sized (n / 20)))]) - (**[ [], [1;2;3] ] *) - | PCons of pattern * pattern (**[ hd :: tl ] *) - | PTuple of - pattern - * pattern - * (pattern list[@gen QCheck.Gen.(list_size (0 -- 2) (gen_pattern_sized (n / 20)))]) - (** | [(a, b)] -> *) - | PConst of literal (** | [4] -> *) - | PVar of ident (** pattern identifier *) - | POption of pattern option - (*| Variant of (ident list[@gen gen_ident_small_list]) (** | [Blue, Green, Yellow] -> *) *) - | PConstraint of pattern * (typ[@gen gen_typ_primitive]) - | PActive of (ident[@gen gen_ident_uppercase]) * pattern - (** | Email str -> _ | Phone [(num, country)] -> _ *) -[@@deriving show { with_path = false }, qcheck] - -type is_recursive = - | Nonrec (** let factorial n = ... *) - | Rec (** let rec factorial n = ... *) -[@@deriving show { with_path = false }, qcheck] - -type case = (pattern[@gen gen_pattern_sized n]) * (expr[@gen gen_expr_sized n]) -[@@deriving show { with_path = false }, qcheck] - -and expr = - | Const of literal (** [Int], [Bool], [String], [Unit], [Null] *) - | Tuple of - (expr[@gen gen_expr_sized (n / 4)]) - * (expr[@gen gen_expr_sized (n / 4)]) - * (expr list[@gen QCheck.Gen.(list_size (0 -- 2) (gen_expr_sized (n / 20)))]) - (** [(1, "Hello world", true)] *) - | List of (expr list[@gen QCheck.Gen.(list_size (0 -- 3) (gen_expr_sized (n / 20)))]) - (** [], [1;2;3] *) - | Variable of ident (** [x], [y] *) - | Unary_expr of unary_operator * expr (** -x *) - | Bin_expr of binary_operator * expr * expr (** [1 + 2], [3 ||| 12], hd :: tl *) - | If_then_else of - (expr[@gen gen_expr_sized (n / 4)]) - * (expr[@gen gen_expr_sized (n / 4)]) - * (expr option[@gen QCheck.Gen.option (gen_expr_sized (n / 4))]) - (** [if n % 2 = 0 then "Even" else "Odd"] *) - | Lambda of - (pattern[@gen gen_pattern_sized (n / 2)]) - * (pattern list[@gen QCheck.Gen.(list_size (0 -- 2) (gen_pattern_sized (n / 20)))]) - * expr (** fun x y -> x + y *) - | Apply of (expr[@gen gen_expr_sized (n / 4)]) * (expr[@gen gen_expr_sized (n / 4)]) - (** [sum 1 ] *) - | Function of - (case[@gen gen_case_sized (n / 4)]) - * (case list[@gen QCheck.Gen.(list_size (0 -- 2) (gen_case_sized (n / 20)))]) - (** [function | p1 -> e1 | p2 -> e2 | ... |]*) - | Match of - (expr[@gen gen_expr_sized (n / 4)]) - * (case[@gen gen_case_sized (n / 4)]) - * (case list[@gen QCheck.Gen.(list_size (0 -- 2) (gen_case_sized (n / 20)))]) - (** [match x with | p1 -> e1 | p2 -> e2 | ...] *) - | LetIn of - is_recursive - * let_bind - * (let_bind list - [@gen QCheck.Gen.(list_size (0 -- 2) (gen_let_bind_sized (n / 20)))]) - * expr (** [let rec f x = if (x <= 0) then x else g x and g x = f (x-2) in f 3] *) - | Option of expr option (** [int option] *) - | EConstraint of expr * (typ[@gen gen_typ_primitive]) - | ActPatConstructor of - (ident[@gen gen_ident_uppercase]) * (expr[@gen gen_expr_sized (n / 4)]) - (** return Phone [(num, country)] *) -[@@deriving show { with_path = false }, qcheck] - -and let_bind = - | Let_bind of - (pattern[@gen gen_pattern_sized (n / 2)]) - * (pattern list[@gen QCheck.Gen.(list_size (0 -- 3) (gen_pattern_sized (n / 4)))]) - * expr (** [let sum n m = n + m] *) -[@@deriving show { with_path = false }, qcheck] - -let gen_expr = - QCheck.Gen.( - let* n = small_nat in - gen_expr_sized n) -;; - -let gen_let_bind = - QCheck.Gen.( - let* n = small_nat in - gen_let_bind_sized n) -;; - -type statement = - | Let of - is_recursive - * let_bind - * (let_bind list[@gen QCheck.Gen.(list_size (0 -- 2) gen_let_bind)]) - (** [let name = expr] *) - | ActPat of - (ident[@gen gen_ident_uppercase]) - * (ident list[@gen QCheck.Gen.(list_size (0 -- 3) gen_ident_uppercase)]) - * (pattern list[@gen QCheck.Gen.(list_size (0 -- 2) gen_pattern)]) - * expr (** [let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd] *) -[@@deriving show { with_path = false }, qcheck] - -type construction = - | Expr of expr (** expression *) - | Statement of statement (** statement *) -[@@deriving show { with_path = false }, qcheck] diff --git a/FSharpActivePatterns/lib/astPrinter.ml b/FSharpActivePatterns/lib/astPrinter.ml deleted file mode 100644 index 7b639e9c3..000000000 --- a/FSharpActivePatterns/lib/astPrinter.ml +++ /dev/null @@ -1,217 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Format -open Ast -open TypesPp - -let print_bin_op indent fmt = function - | Binary_equal -> fprintf fmt "%s| Binary Equal\n" (String.make indent '-') - | Binary_unequal -> fprintf fmt "%s| Binary Unequal\n" (String.make indent '-') - | Binary_less -> fprintf fmt "%s| Binary Less\n" (String.make indent '-') - | Binary_less_or_equal -> - fprintf fmt "%s| Binary Less Or Equal\n" (String.make indent '-') - | Binary_greater -> fprintf fmt "%s| Binary Greater\n" (String.make indent '-') - | Binary_greater_or_equal -> - fprintf fmt "%s| Binary Greater Or Equal\n" (String.make indent '-') - | Binary_add -> fprintf fmt "%s| Binary Add\n" (String.make indent '-') - | Binary_subtract -> fprintf fmt "%s| Binary Subtract\n" (String.make indent '-') - | Binary_multiply -> fprintf fmt "%s| Binary Multiply\n" (String.make indent '-') - | Logical_or -> fprintf fmt "%s| Logical Or\n" (String.make indent '-') - | Logical_and -> fprintf fmt "%s| Logical And\n" (String.make indent '-') - | Binary_divide -> fprintf fmt "%s| Binary Divide\n" (String.make indent '-') - | Binary_or_bitwise -> fprintf fmt "%s| Binary Or Bitwise\n" (String.make indent '-') - | Binary_xor_bitwise -> fprintf fmt "%s| Binary Xor Bitwise\n" (String.make indent '-') - | Binary_and_bitwise -> fprintf fmt "%s| Binary And Bitwise\n" (String.make indent '-') - | Binary_cons -> fprintf fmt "%s| Binary Cons\n" (String.make indent '-') -;; - -let rec print_pattern indent fmt = function - | Wild -> fprintf fmt "%s| Wild\n" (String.make indent '-') - | PList l -> - fprintf fmt "%s| PList:\n" (String.make indent '-'); - List.iter (print_pattern (indent + 2) fmt) l - | PTuple (p1, p2, rest) -> - fprintf fmt "%s| PTuple:\n" (String.make indent '-'); - List.iter (print_pattern (indent + 2) fmt) (p1 :: p2 :: rest) - | PConst literal -> - fprintf fmt "%s| PConst:\n" (String.make indent '-'); - (match literal with - | Int_lt i -> fprintf fmt "%sInt: %d\n" (String.make (indent + 2) '-') i - | Bool_lt b -> fprintf fmt "%sBool: %b\n" (String.make (indent + 2) '-') b - | String_lt s -> fprintf fmt "%sString: %S\n" (String.make (indent + 2) '-') s - | Unit_lt -> fprintf fmt "%sUnit\n" (String.make (indent + 2) '-')) - | PCons (l, r) -> - fprintf fmt "%s| PCons:\n" (String.make indent '-'); - print_pattern (indent + 2) fmt l; - print_pattern (indent + 2) fmt r - | PVar (Ident name) -> fprintf fmt "%s| PVar(%s)\n" (String.make indent '-') name - | POption p -> - fprintf fmt "%s| POption " (String.make indent '-'); - (match p with - | None -> fprintf fmt "None\n" - | Some p -> - fprintf fmt "Some:\n"; - print_pattern (indent + 2) fmt p) - | PConstraint (p, t) -> - fprintf fmt "%s| PConstraint\n" (String.make indent ' '); - fprintf fmt "%sPattern:\n" (String.make (indent + 2) ' '); - print_pattern (indent + 2) fmt p; - fprintf fmt "%sType:\n" (String.make (indent + 2) ' '); - fprintf fmt "%s| %a\n" (String.make (indent + 2) '-') pp_typ t - | PActive (Ident name, p) -> - fprintf fmt "%s| PActive\n" (String.make indent ' '); - fprintf fmt "%sName: %s \n" (String.make (indent + 2) ' ') name; - fprintf fmt "%sPattern:\n" (String.make (indent + 2) ' '); - print_pattern (indent + 2) fmt p -;; - -let print_unary_op indent fmt = function - | Unary_minus -> fprintf fmt "%s| Unary minus\n" (String.make indent '-') - | Unary_not -> fprintf fmt "%s| Unary negative\n" (String.make indent '-') -;; - -let rec print_let_bind indent fmt = function - | Let_bind (name, args, body) -> - fprintf fmt "%s| Let_bind:\n" (String.make indent '-'); - fprintf fmt "%sNAME:\n" (String.make (indent + 4) ' '); - print_pattern (indent + 4) fmt name; - fprintf fmt "%sARGS:\n" (String.make (indent + 4) ' '); - List.iter (fun arg -> print_pattern (indent + 2) fmt arg) args; - fprintf fmt "%sBODY:\n" (String.make (indent + 4) ' '); - print_expr (indent + 2) fmt body - -and print_expr indent fmt expr = - match expr with - | Const (Int_lt i) -> fprintf fmt "%s| Const(Int: %d)\n" (String.make indent '-') i - | Const (Bool_lt b) -> fprintf fmt "%s| Const(Bool: %b)\n" (String.make indent '-') b - | Const (String_lt s) -> - fprintf fmt "%s| Const(String: %S)\n" (String.make indent '-') s - | Const Unit_lt -> fprintf fmt "%s| Const(Unit)\n" (String.make indent '-') - | List l -> - fprintf fmt "%s| PList:\n" (String.make indent '-'); - List.iter (print_expr (indent + 2) fmt) l - | Tuple (e1, e2, rest) -> - fprintf fmt "%s| Tuple:\n" (String.make indent '-'); - List.iter (print_expr (indent + 2) fmt) (e1 :: e2 :: rest) - | Function ((pat1, expr1), cases) -> - fprintf fmt "%s| Function:\n" (String.make indent '-'); - List.iter - (fun (pat, expr) -> - fprintf fmt "%s| Pattern:\n" (String.make (indent + 2) '-'); - print_pattern (indent + 4) fmt pat; - fprintf fmt "%s| Case expr:\n" (String.make (indent + 2) '-'); - print_expr (indent + 4) fmt expr) - ((pat1, expr1) :: cases) - | Match (value, (pat1, expr1), cases) -> - fprintf fmt "%s| Match:\n" (String.make indent '-'); - fprintf fmt "%s| Value:\n" (String.make (indent + 2) '-'); - print_expr (indent + 4) fmt value; - List.iter - (fun (pat, expr) -> - fprintf fmt "%s| Pattern:\n" (String.make (indent + 2) '-'); - print_pattern (indent + 4) fmt pat; - fprintf fmt "%s| Case expr:\n" (String.make (indent + 2) '-'); - print_expr (indent + 4) fmt expr) - ((pat1, expr1) :: cases) - | Variable (Ident name) -> - fprintf fmt "%s| Variable(%s)\n" (String.make indent '-') name - | Unary_expr (op, expr) -> - fprintf fmt "%s| Unary expr(\n" (String.make indent '-'); - print_unary_op indent fmt op; - print_expr (indent + 2) fmt expr - | Bin_expr (op, left, right) -> - fprintf fmt "%s| Binary expr(\n" (String.make indent '-'); - print_bin_op indent fmt op; - print_expr (indent + 2) fmt left; - print_expr (indent + 2) fmt right - | If_then_else (cond, then_body, else_body) -> - fprintf fmt "%s| If Then Else(\n" (String.make indent '-'); - fprintf fmt "%sCONDITION\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt cond; - fprintf fmt "%sTHEN BRANCH\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt then_body; - fprintf fmt "%sELSE BRANCH\n" (String.make (indent + 2) ' '); - (match else_body with - | Some body -> print_expr (indent + 2) fmt body - | None -> fprintf fmt "%s| No else body\n" (String.make (indent + 2) '-')) - | Lambda (arg1, args, body) -> - fprintf fmt "%s| Lambda:\n" (String.make indent '-'); - fprintf fmt "%sARGS\n" (String.make (indent + 2) ' '); - List.iter (fun pat -> print_pattern (indent + 4) fmt pat) (arg1 :: args); - fprintf fmt "%sBODY\n" (String.make (indent + 2) ' '); - print_expr (indent + 4) fmt body - | Apply (func, arg) -> - fprintf fmt "%s| Apply:\n" (String.make indent '-'); - fprintf fmt "%sFUNCTION\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt func; - fprintf fmt "%sARGS\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt arg - | LetIn (rec_flag, let_bind, let_bind_list, inner_e) -> - fprintf - fmt - "%s| %sLetIn=\n" - (String.make indent '-') - (match rec_flag with - | Nonrec -> "" - | Rec -> "Rec "); - fprintf fmt "%sLet_binds\n" (String.make (indent + 2) ' '); - List.iter (print_let_bind (indent + 2) fmt) (let_bind :: let_bind_list); - fprintf fmt "%sINNER_EXPRESSION\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt inner_e - | Option e -> - (match e with - | None -> fprintf fmt "%s| Option: None\n" (String.make indent '-') - | Some e -> - fprintf fmt "%s| Option: Some\n" (String.make indent '-'); - print_expr (indent + 2) fmt e) - | EConstraint (e, t) -> - fprintf fmt "%s| EConstraint\n" (String.make indent ' '); - fprintf fmt "%sExpr:\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt e; - fprintf fmt "%sType:\n" (String.make (indent + 2) ' '); - fprintf fmt "%s| %a\n" (String.make (indent + 2) '-') pp_typ t - | ActPatConstructor (Ident name, e) -> - fprintf fmt "%s| EActPatConstructor\n" (String.make indent ' '); - fprintf fmt "%s| %s\n" (String.make (indent + 2) ' ') name; - fprintf fmt "%sExpr:\n" (String.make (indent + 2) ' '); - print_expr (indent + 2) fmt e -;; - -let print_statement indent fmt = function - | Let (rec_flag, let_bind, let_bind_list) -> - fprintf - fmt - "%s |%s Let:\n" - (String.make indent '-') - (match rec_flag with - | Nonrec -> "" - | Rec -> "Rec "); - fprintf fmt "%s Let_binds\n" (String.make (indent + 2) ' '); - List.iter (print_let_bind (indent + 2) fmt) (let_bind :: let_bind_list) - | ActPat (Ident name, name_list, args, expr) -> - fprintf fmt "%s| Active Pattern\n" (String.make indent '-'); - fprintf fmt "%s| %s\n" (String.make (indent + 2) ' ') name; - List.iter - (fun (Ident name) -> fprintf fmt "%s| %s\n" (String.make (indent + 2) ' ') name) - name_list; - fprintf fmt "%s| ARGS\n" (String.make indent '-'); - List.iter (fun pat -> print_pattern (indent + 2) fmt pat) args; - fprintf fmt "%s| BODY\n" (String.make indent '-'); - print_expr (indent + 2) fmt expr -;; - -let print_construction fmt = function - | Expr e -> print_expr 0 fmt e - | Statement s -> print_statement 0 fmt s -;; - -let print_p_res fmt = function - | Ok ast -> print_construction fmt ast - | Error e -> fprintf fmt "%s\n" e -;; diff --git a/FSharpActivePatterns/lib/astPrinter.mli b/FSharpActivePatterns/lib/astPrinter.mli deleted file mode 100644 index c2a769e9c..000000000 --- a/FSharpActivePatterns/lib/astPrinter.mli +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Format - -val print_construction : formatter -> construction -> unit -val print_p_res : formatter -> (construction, tag) result -> unit diff --git a/FSharpActivePatterns/lib/dune b/FSharpActivePatterns/lib/dune deleted file mode 100644 index 15e328e1a..000000000 --- a/FSharpActivePatterns/lib/dune +++ /dev/null @@ -1,20 +0,0 @@ -(library - (name FSharpActivePatterns) - (public_name FSharpActivePatterns) - (modules - Ast - Parser - AstPrinter - PrettyPrinter - KeywordChecker - Inferencer - TypedTree - TypesPp - Interpreter - ExtractIdents - REPLUtils) - (libraries angstrom base) - (preprocess - (pps ppx_deriving_qcheck ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/FSharpActivePatterns/lib/extractIdents.ml b/FSharpActivePatterns/lib/extractIdents.ml deleted file mode 100644 index 94a724e33..000000000 --- a/FSharpActivePatterns/lib/extractIdents.ml +++ /dev/null @@ -1,73 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base - -module type R = sig - type 'a t - type error - - val return : 'a -> 'a t - val fail : error -> 'a t - val bound_error : error - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end -end - -module ExtractIdents (R : R) : sig - type t - - val extract_names_from_pattern : pattern -> t R.t - val extract_names_from_patterns : pattern list -> t R.t - val extract_bind_names_from_let_binds : let_bind list -> t R.t - val extract_bind_patterns_from_let_binds : let_bind list -> pattern list - val elements : t -> string list -end = struct - include Stdlib.Set.Make (String) - open R - open R.Syntax - - let union_disjoint s1 s2 = - let* s1 = s1 in - let* s2 = s2 in - if is_empty (inter s1 s2) then return (union s1 s2) else fail bound_error - ;; - - let union_disjoint_many sets = List.fold ~init:(return empty) ~f:union_disjoint sets - - let rec extract_names_from_pattern = - let extr = extract_names_from_pattern in - function - | PVar (Ident name) -> return (singleton name) - | PList l -> union_disjoint_many (List.map l ~f:extr) - | PCons (hd, tl) -> union_disjoint (extr hd) (extr tl) - | PTuple (fst, snd, rest) -> - union_disjoint_many (List.map ~f:extr (fst :: snd :: rest)) - | POption (Some p) -> extr p - | PConstraint (p, _) -> extr p - | POption None -> return empty - | Wild -> return empty - | PConst _ -> return empty - | PActive (Ident name, _) -> return (singleton name) - ;; - - let extract_names_from_patterns pats = - union_disjoint_many (List.map ~f:extract_names_from_pattern pats) - ;; - - let extract_bind_names_from_let_binds let_binds = - union_disjoint_many - (List.map let_binds ~f:(function Let_bind (pat, _, _) -> - extract_names_from_pattern pat)) - ;; - - let extract_bind_patterns_from_let_binds let_binds = - List.map let_binds ~f:(function Let_bind (pat, _, _) -> pat) - ;; -end - -module Make = ExtractIdents diff --git a/FSharpActivePatterns/lib/extractIdents.mli b/FSharpActivePatterns/lib/extractIdents.mli deleted file mode 100644 index c67bdeb79..000000000 --- a/FSharpActivePatterns/lib/extractIdents.mli +++ /dev/null @@ -1,28 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -module type R = sig - type 'a t - type error - - val return : 'a -> 'a t - val fail : error -> 'a t - val bound_error : error - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end -end - -module Make (R : R) : sig - type t - - val extract_names_from_pattern : pattern -> t R.t - val extract_names_from_patterns : pattern list -> t R.t - val extract_bind_names_from_let_binds : let_bind list -> t R.t - val extract_bind_patterns_from_let_binds : let_bind list -> pattern list - val elements : t -> string list -end diff --git a/FSharpActivePatterns/lib/inferencer.ml b/FSharpActivePatterns/lib/inferencer.ml deleted file mode 100644 index f4499906c..000000000 --- a/FSharpActivePatterns/lib/inferencer.ml +++ /dev/null @@ -1,892 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open TypedTree -open TypesPp -open Format -open Base - -module InferenceError = struct - type t = - [ `Occurs_check - | `Undef_var of string - | `Unification_failed of typ * typ - | `Not_allowed_right_hand_side_let_rec - | `Not_allowed_left_hand_side_let_rec - | `Args_after_not_variable_let - | `Bound_several_times - | `Active_pattern_are_not_determined_by_input - ] - - let bound_error = `Bound_several_times - - let pp_error fmt : t -> _ = function - | `Occurs_check -> fprintf fmt "Occurs check failed" - | `Undef_var s -> fprintf fmt "Undefined variable '%s'" s - | `Unification_failed (fst, snd) -> - fprintf fmt "unification failed on %a and %a\n" pp_typ fst pp_typ snd - | `Not_allowed_right_hand_side_let_rec -> - fprintf fmt "This kind of expression is not allowed as right-hand side of `let rec'" - | `Not_allowed_left_hand_side_let_rec -> - fprintf fmt "Only variables are allowed as left-hand side of `let rec'" - | `Args_after_not_variable_let -> - fprintf fmt "Arguments in let allowed only after variable" - | `Bound_several_times -> fprintf fmt "Variable is bound several times" - | `Active_pattern_are_not_determined_by_input -> - fprintf fmt "Some active pattern are not determined by input" - ;; -end - -(* for treating result of type inference *) -module R : sig - type 'a t - type error = InferenceError.t - - val bound_error : error - val pp_error : formatter -> error -> unit - - (* val bind : 'a t -> f:('a -> 'b t) -> 'b t *) - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - end - - val fresh : int t - val run : 'a t -> int -> int * ('a, error) Result.t - - module RMap : sig - val fold : ('a, 'b, 'c) Map.t -> init:'d t -> f:('a -> 'b -> 'd -> 'd t) -> 'd t - end -end = struct - include InferenceError - - type error = InferenceError.t - - (* takes current state, runs smth, outputs new state and success / error *) - type 'a t = int -> int * ('a, error) Result.t - - (* bind -- if applying new state to first arg is correct, then apply f to - new argument and new state, else output error and state that caused it *) - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let last, r = m st in - match r with - | Result.Error x -> last, Error x - | Ok a -> f a last - ;; - - (* is called to cover result in fail or ok constructions *) - let fail e st = st, Base.Result.fail e - let return x last = last, Base.Result.return x - let bind x ~f = x >>= f - - (* is called from x, function and state. if applying state to x is correct, - then output applying f to x in constructor Ok, otherwise output error and - state that caused it *) - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Ok x -> st, Ok (f x) - | st, Result.Error e -> st, Result.Error e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - (* for applying f to all elements x of list xs with check that everything is - correct. If it is, outputs accumulator of all applyings *) - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - end - - (* analogically to list. let* acc = acc is to extract value from type t *) - module RMap = struct - let fold map ~init ~f = - Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - (* takes current state, returns state + 1 *) - let fresh : int t = fun last -> last + 1, Result.Ok last - let run m = m -end - -type fresh = int - -(* module with all type methods *) -module Type : sig - type t = typ - - val occurs_in : fresh -> t -> bool - val free_vars : t -> binder_set -end = struct - type t = typ - - (* check that v is not inside of second type. - Runs during substitution to ensure that there are no cycles*) - let rec occurs_in v = function - | Primitive _ -> false - | Type_var b -> b = v - | Arrow (fst, snd) -> occurs_in v fst || occurs_in v snd - | Type_list typ -> occurs_in v typ - | Type_tuple (fst, snd, rest) -> List.exists (fst :: snd :: rest) ~f:(occurs_in v) - | Choice map -> List.exists ~f:(occurs_in v) (choice_to_list map) - | TOption t -> occurs_in v t - | TActPat (_, typ) -> occurs_in v typ - ;; - - (* collects all type variables *) - let free_vars = - let rec helper acc = function - | Primitive _ -> acc - | Type_var b -> VarSet.add b acc - | Arrow (fst, snd) -> helper (helper acc fst) snd - | Type_list typ -> helper acc typ - | Type_tuple (fst, snd, rest) -> List.fold (fst :: snd :: rest) ~init:acc ~f:helper - | Choice map -> List.fold (choice_to_list map) ~init:acc ~f:helper - | TOption t -> helper acc t - | TActPat (_, t) -> helper acc t - in - helper VarSet.empty - ;; -end - -(* module of substitution *) - -module Substitution : sig - type t - - val empty : t - - (* val mapping : fresh -> typ -> (fresh * typ) R.t *) - val singleton : fresh -> typ -> t R.t - - (* val find : t -> fresh -> typ option *) - val remove : t -> fresh -> t - val apply : t -> typ -> typ - val unify : typ -> typ -> t R.t - val compose : t -> t -> t R.t - val compose_all : t list -> t R.t - (* val pp : formatter -> t -> unit *) -end = struct - open R - open R.Syntax - - (* t in this module is map of key fresh to value typ. last arg specifies - keys as int values (see fresh def) *) - type t = (fresh, typ, Int.comparator_witness) Map.t - - (* empty map *) - let empty = Map.empty (module Int) - (* let pp fmt s = Map.iteri s ~f:(fun ~key ~data -> fprintf fmt "%d: %a" key pp_typ data) *) - - (* perform mapping of fresh var to typ with occurs check, if correct, - output new pair *) - let mapping k v = if Type.occurs_in k v then fail `Occurs_check else return (k, v) - - (* perform mapping, if correct, create map w 1 element as described in type t *) - let singleton k v = - let* k, v = mapping k v in - return (Map.singleton (module Int) k v) - ;; - - (* aliases for Map actions *) - let find = Map.find - let remove = Map.remove - - (* search for input in given map, if there is no match, output - input type, else output found typ value associated w this key. - Basically narrow given type to conditions given in substitution *) - let apply map = - let rec helper = function - | Type_var b as typ -> - (match find map b with - | None -> typ - | Some x -> x) - | Arrow (fst, snd) -> Arrow (helper fst, helper snd) - | Type_list t -> Type_list (helper t) - | Type_tuple (fst, snd, rest) -> - Type_tuple (helper fst, helper snd, List.map rest ~f:helper) - | Primitive t -> Primitive t - | TOption t -> TOption (helper t) - | TActPat (name, t) -> TActPat (name, helper t) - | Choice map -> Choice (Map.map map ~f:helper) - in - helper - ;; - - (* check that two types are compatible. in third case put new pair of type_var - and type into context (map) *) - let rec unify fst snd = - match fst, snd with - | Primitive fst, Primitive snd when String.equal fst snd -> return empty - | Type_var f, Type_var s when Int.equal f s -> return empty - | Type_var b, t | t, Type_var b -> singleton b t - | Arrow (f1, s1), Arrow (f2, s2) -> - let* subst1 = unify f1 f2 in - let* subst2 = unify s1 s2 in - compose subst1 subst2 - | Type_list t1, Type_list t2 -> unify t1 t2 - | TOption t1, TOption t2 -> unify t1 t2 - | Type_tuple (t1_1, t1_2, t1_rest), Type_tuple (t2_1, t2_2, t2_rest) - when List.length t1_rest = List.length t2_rest -> - let type_pairs = List.zip_exn (t1_1 :: t1_2 :: t1_rest) (t2_1 :: t2_2 :: t2_rest) in - let* substitutions = - List.fold type_pairs ~init:(return []) ~f:(fun acc (t1, t2) -> - let* acc = acc in - let* subst = unify t1 t2 in - return (subst :: acc)) - in - let substitution_result = compose_all substitutions in - substitution_result - | TActPat (name1, _), TActPat (name2, _) when not (phys_equal name1 name2) -> - return empty - | TActPat (name1, t1), TActPat (name2, t2) when not (phys_equal name1 name2) -> - unify t1 t2 - | Choice map, TActPat (name, t) | TActPat (name, t), Choice map -> - unify (Choice map) (Choice (Map.singleton (module String) name t)) - | Choice map1, Choice map2 -> - Map.fold map1 ~init:(return empty) ~f:(fun ~key ~data subst -> - let* subst = subst in - let* new_subst = - match Map.find map2 key with - | Some t -> unify data t - | None -> return empty - in - compose subst new_subst) - | _ -> fail (`Unification_failed (fst, snd)) - - (* if value associated w this key exists in map, try to unify them, otherwise - get old substitution, form new singleton, update map so in contains new info *) - and extend key value map = - match find map key with - | Some value2 -> - let* map2 = unify value value2 in - compose map map2 - | None -> - let value = apply map value in - let* map2 = singleton key value in - RMap.fold map ~init:(return map2) ~f:(fun key value acc -> - let value = apply map2 value in - let* key, value = mapping key value in - return (Map.update acc key ~f:(fun _ -> value))) - - (* compose two maps together *) - and compose map1 map2 = RMap.fold map2 ~init:(return map1) ~f:extend - - (* compose list of maps together *) - and compose_all maps = RList.fold_left maps ~init:(return empty) ~f:compose -end - -(* module for scheme treatment *) -module Scheme : sig - type t = scheme - - (* val occurs_in : fresh -> t -> bool *) - val apply : Substitution.t -> t -> t - val free_vars : t -> binder_set - - (* val pp : formatter -> t -> unit *) -end = struct - type t = scheme - - (* take all vars that are not bound in typ *) - let free_vars = function - | Scheme (vars, t) -> VarSet.diff (Type.free_vars t) vars - ;; - - (* take substitution and scheme, remove its free vars from substitution, - form new scheme according to substitution (apply it to typ) *) - let apply subst (Scheme (vars, t)) = - let subst2 = VarSet.fold (fun key s -> Substitution.remove s key) vars subst in - Scheme (vars, Substitution.apply subst2 t) - ;; - - (* let pp = pp_scheme *) -end - -module TypeEnv : sig - type t - - val free_vars : t -> VarSet.t - val extend : t -> string -> scheme -> t - val extend_many : t -> (string * scheme) list -> t - val apply : Substitution.t -> t -> t - val default : t - val find : t -> string -> scheme option - val find_exn : t -> string -> scheme - val find_typ_exn : t -> string -> typ - val find_typ : t -> string -> typ option - val remove : t -> string -> t - val remove_many : t -> string list -> t - val iteri : t -> f:(name:string -> typ:typ -> unit) -> unit - (* val pp : formatter -> t -> unit *) -end = struct - open Base - - (* environment (context?) -- pairs of names and their types list *) - type t = (string, scheme, String.comparator_witness) Map.t - - (* if pair (key, some old value) exists in map env, then replace old value - with new, else add pair (key, value) into map *) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let extend_many env list = - List.fold list ~init:env ~f:(fun env (k, v) -> extend env k v) - ;; - - let remove = Map.remove - let remove_many t keys = List.fold ~init:t keys ~f:remove - - let default = - Map.set - (Map.empty (module String)) - ~key:"print_int" - ~data:(Scheme (VarSet.empty, Arrow (int_typ, unit_typ))) - ;; - - (* apply given substitution to all elements of environment *) - let apply subst env = Map.map env ~f:(Scheme.apply subst) - let find = Map.find - let find_exn = Map.find_exn - - let find_typ env key = - match find env key with - | Some (Scheme (_, typ)) -> Some typ - | None -> None - ;; - - let find_typ_exn env key = - match find_exn env key with - | Scheme (_, typ) -> typ - ;; - - let iteri env ~f = - Map.iteri env ~f:(fun ~key ~data -> - (function - | Scheme (_, typ) -> f ~name:key ~typ) - data) - ;; - - (* collect all free vars from environment *) - let free_vars : t -> VarSet.t = - Map.fold ~init:VarSet.empty ~f:(fun ~key:_ ~data:s acc -> - VarSet.union acc (Scheme.free_vars s)) - ;; -end - -include R -open R.Syntax -module ExtractIdents = ExtractIdents.Make (R) -open ExtractIdents - -let unify = Substitution.unify -let make_fresh_var = fresh >>| fun n -> Type_var n - -(* replace all type vars with fresh ones *) -let instantiate : scheme -> typ R.t = - fun (Scheme (vars, t)) -> - VarSet.fold - (fun name typ -> - let* typ = typ in - let* fr_var = make_fresh_var in - let* subst = Substitution.singleton name fr_var in - return (Substitution.apply subst typ)) - vars - (return t) -;; - -(* take free vars of type t and environment, put difference between them - in S constructor so all vars are context independent *) -let generalize env typ = - let free = VarSet.diff (Type.free_vars typ) (TypeEnv.free_vars env) in - Scheme (free, typ) -;; - -let rec find_args_type = function - | Arrow (a, Arrow (b, rest)) -> Arrow (a, find_args_type (Arrow (b, rest))) - | Arrow (a, _) -> a - | t -> t -;; - -let rec decompose_arrow typ = - match typ with - | Arrow (fst, snd) -> - let args, final_return_type = decompose_arrow snd in - fst :: args, final_return_type - | _ -> [], typ -;; - -let find_return_type typ = - let _, return_t = decompose_arrow typ in - return_t -;; - -let infer_lt = function - | Int_lt _ -> return int_typ - | Bool_lt _ -> return bool_typ - | String_lt _ -> return string_typ - | Unit_lt -> return unit_typ -;; - -let rec infer_pattern env ~shadow = function - | Wild -> - let* fresh_var = make_fresh_var in - return (env, fresh_var) - | PConst lt -> - let* t = infer_lt lt in - return (env, t) - | PVar (Ident name) -> - let* fresh = make_fresh_var in - let scheme = Scheme (VarSet.empty, fresh) in - let env, typ = - if shadow - then TypeEnv.extend env name scheme, fresh - else ( - let typ = TypeEnv.find_typ env name in - env, Option.value typ ~default:fresh) - in - return (env, typ) - | POption None -> - let* fresh_var = make_fresh_var in - return (env, TOption fresh_var) - | POption (Some p) -> - let* env, typ = infer_pattern env ~shadow p in - return (env, TOption typ) - | PList [] -> - let* fresh_var = make_fresh_var in - return (env, Type_list fresh_var) - | PList (hd :: tl) -> - let* env, typ1 = infer_pattern env ~shadow hd in - let* env, typ2 = infer_pattern env ~shadow (PList tl) in - let* subst = Substitution.unify typ2 (Type_list typ1) in - let env = TypeEnv.apply subst env in - return (env, Substitution.apply subst typ2) - | PCons (hd, tl) -> - let* env, typ1 = infer_pattern env ~shadow hd in - let* env, typ2 = infer_pattern env ~shadow tl in - let* subst = Substitution.unify typ2 (Type_list typ1) in - let env = TypeEnv.apply subst env in - return (env, Substitution.apply subst typ2) - | PTuple (fst, snd, rest) -> - let* env, typ1 = infer_pattern env ~shadow fst in - let* env, typ2 = infer_pattern env ~shadow snd in - let* env, typs_rest = - List.fold_right - rest - ~f:(fun p acc -> - let* env, types = acc in - let* env, typ = infer_pattern env ~shadow p in - return (env, typ :: types)) - ~init:(return (env, [])) - in - return (env, Type_tuple (typ1, typ2, typs_rest)) - | PConstraint (p, t) -> - let* env, inferred_typ = infer_pattern env ~shadow p in - let* subst = unify t inferred_typ in - return (TypeEnv.apply subst env, Substitution.apply subst t) - | PActive (Ident name, p) -> - let* env, typ = infer_pattern env ~shadow p in - let pat_typ = - match TypeEnv.find_exn env name with - | Scheme (_, typ) -> typ - in - let pat_return_typ = find_return_type pat_typ in - let* subst = unify typ pat_return_typ in - return (TypeEnv.apply subst env, Substitution.apply subst pat_typ) -;; - -let infer_patterns env ~shadow patterns = - List.fold_right - patterns - ~init:(return (env, [])) - ~f:(fun pat acc -> - let* old_env, typs = acc in - let* new_env, typ = infer_pattern old_env ~shadow pat in - return (new_env, typ :: typs)) -;; - -let infer_match_pattern env ~shadow pattern match_type = - let* env, pat_typ = infer_pattern env ~shadow pattern in - let pat_input_typ = find_args_type pat_typ in - let* subst = unify pat_input_typ match_type in - let env = TypeEnv.apply subst env in - let* pat_names = extract_names_from_pattern pattern >>| elements in - let generalized_schemes = - List.map pat_names ~f:(fun name -> - let typ = TypeEnv.find_typ_exn env name in - let env = TypeEnv.remove env name in - let generalized_typ = generalize env typ in - name, generalized_typ) - in - let env = TypeEnv.extend_many env generalized_schemes in - return (env, subst) -;; - -let extend_env_with_bind_names env let_binds = - let bind_names = extract_bind_patterns_from_let_binds let_binds in - let* env, _ = infer_patterns env ~shadow:true bind_names in - return env -;; - -let check_let_bind_correctness is_rec let_bind = - match let_bind, is_rec with - | Let_bind (PVar _, _, _), _ -> return let_bind - | Let_bind _, Rec -> fail `Not_allowed_left_hand_side_let_rec - | Let_bind (_, args, _), _ when List.length args <> 0 -> - fail `Args_after_not_variable_let - | _ -> return let_bind -;; - -let unify_act_pat = function - | TActPat (n1, t1), TActPat (n2, t2) -> - Choice (choice_set_many (Map.empty (module String)) [ n1, t1; n2, t2 ]) - | TActPat (name, t), Choice map | Choice map, TActPat (name, t) -> - Choice (Map.set map ~key:name ~data:t) - | Choice map1, Choice map2 -> - Choice (Map.fold ~init:map1 map2 ~f:(fun ~key ~data map1 -> Map.set map1 ~key ~data)) - | fst, _ -> fst -;; - -let rec infer_expr env = function - | Const lt -> - let* t = infer_lt lt in - return (Substitution.empty, t) - | Variable (Ident varname) -> - (match TypeEnv.find env varname with - | Some s -> - let* t = instantiate s in - return (Substitution.empty, t) - | None -> fail (`Undef_var varname)) - | Unary_expr (op, e) -> - let* op_typ = - match op with - | Unary_minus -> return int_typ - | Unary_not -> return bool_typ - in - let* e_subst, e_typ = infer_expr env e in - let* subst = unify op_typ (Substitution.apply e_subst e_typ) in - let* subst_result = Substitution.compose_all [ e_subst; subst ] in - return (subst_result, Substitution.apply subst e_typ) - | Bin_expr (op, e1, e2) -> - let* subst1, typ1 = infer_expr env e1 in - let* subst2, typ2 = infer_expr (TypeEnv.apply subst1 env) e2 in - let* e1typ, e2typ, etyp = - match op with - | Logical_and | Logical_or -> return (bool_typ, bool_typ, bool_typ) - | Binary_add - | Binary_subtract - | Binary_multiply - | Binary_divide - | Binary_and_bitwise - | Binary_or_bitwise - | Binary_xor_bitwise -> return (int_typ, int_typ, int_typ) - | Binary_greater | Binary_greater_or_equal | Binary_less | Binary_less_or_equal -> - return (int_typ, int_typ, bool_typ) - | Binary_equal | Binary_unequal -> - let* fresh_var = make_fresh_var in - return (fresh_var, fresh_var, bool_typ) - | Binary_cons -> - let* fresh_var = make_fresh_var in - return (fresh_var, Type_list fresh_var, Type_list fresh_var) - in - let* subst3 = Substitution.unify (Substitution.apply subst2 typ1) e1typ in - let* subst4 = Substitution.unify (Substitution.apply subst3 typ2) e2typ in - let* subst_res = Substitution.compose_all [ subst1; subst2; subst3; subst4 ] in - return (subst_res, Substitution.apply subst_res etyp) - | Option None -> - let* fresh_typ = make_fresh_var in - return (Substitution.empty, TOption fresh_typ) - | Option (Some e) -> - let* subst, typ = infer_expr env e in - return (subst, TOption typ) - | Tuple (fst, snd, rest) -> - let* subst1, typ1 = infer_expr env fst in - let* subst2, typ2 = infer_expr env snd in - let* subst_rest, typs_rest = - List.fold_right - rest - ~f:(fun e acc -> - let* subst_acc, typs = acc in - let* subst, typ = infer_expr env e in - let* subst_acc = Substitution.compose subst_acc subst in - return (subst_acc, typ :: typs)) - ~init:(return (Substitution.empty, [])) - in - let* subst_result = Substitution.compose_all [ subst1; subst2; subst_rest ] in - return (subst_result, Type_tuple (typ1, typ2, typs_rest)) - | List [] -> - let* fresh_var = make_fresh_var in - return (Substitution.empty, Type_list fresh_var) - | List (hd :: tl) -> - let* subst1, typ1 = infer_expr env hd in - let typ1 = Substitution.apply subst1 typ1 in - let* subst_unify, typ_unified = - List.fold - tl - ~f:(fun acc e -> - let* subst_acc, typ_acc = acc in - let* subst, typ = infer_expr env e in - let* subst_unify = unify typ_acc typ in - let typ_acc = Substitution.apply subst_unify typ_acc in - let* subst_acc = Substitution.compose_all [ subst; subst_acc; subst_unify ] in - return (subst_acc, typ_acc)) - ~init:(return (subst1, typ1)) - in - return (subst_unify, Type_list typ_unified) - | If_then_else (c, th, Some el) -> - let* subst1, typ1 = infer_expr env c in - let* subst2, typ2 = infer_expr (TypeEnv.apply subst1 env) th in - let* subst3, typ3 = infer_expr (TypeEnv.apply subst2 env) el in - let* subst4 = unify typ1 bool_typ in - let* subst5 = unify typ2 typ3 in - let* subst_result = - Substitution.compose_all [ subst1; subst2; subst3; subst4; subst5 ] - in - return (subst_result, Substitution.apply subst5 (unify_act_pat (typ2, typ3))) - | If_then_else (c, th, None) -> - let* subst1, typ1 = infer_expr env c in - let* subst2, typ2 = infer_expr (TypeEnv.apply subst1 env) th in - let* subst3 = unify typ1 bool_typ in - let* subst_result = Substitution.compose_all [ subst1; subst2; subst3 ] in - return (subst_result, Substitution.apply subst2 typ2) - | Apply (f, arg) -> - let* subst1, typ1 = infer_expr env f in - let* subst2, typ2 = infer_expr (TypeEnv.apply subst1 env) arg in - let typ1 = Substitution.apply subst2 typ1 in - let* fresh_var = make_fresh_var in - let* subst3 = unify typ1 (Arrow (typ2, fresh_var)) in - let* subst_result = Substitution.compose_all [ subst1; subst2; subst3 ] in - return (subst_result, Substitution.apply subst3 fresh_var) - | Lambda (arg, args, e) -> - let* env, arg_types = infer_patterns env ~shadow:true (arg :: args) in - let* subst, e_type = infer_expr env e in - return (subst, Substitution.apply subst (arrow_of_types arg_types e_type)) - | LetIn (Rec, let_bind, let_binds, e) -> - let let_binds = let_bind :: let_binds in - let* env = extend_env_with_bind_names env let_binds in - let* env, subst1 = extend_env_with_let_binds env Rec let_binds in - let* subst2, typ = infer_expr env e in - let* subst_final = Substitution.compose subst1 subst2 in - return (subst_final, typ) - | LetIn (Nonrec, let_bind, let_binds, e) -> - let* env, subst1 = extend_env_with_let_binds env Nonrec (let_bind :: let_binds) in - let* subst2, typ = infer_expr env e in - let* subst_final = Substitution.compose subst1 subst2 in - return (subst_final, typ) - | Function ((p1, e1), rest) -> - let* match_t = make_fresh_var in - let* return_t = make_fresh_var in - infer_matching_expr - env - ((p1, e1) :: rest) - Substitution.empty - match_t - return_t - ~with_arg:true - | Match (e, (p1, e1), rest) -> - let* subst_init, match_t = infer_expr env e in - let env = TypeEnv.apply subst_init env in - let* return_t = make_fresh_var in - infer_matching_expr env ((p1, e1) :: rest) subst_init match_t return_t ~with_arg:false - | EConstraint (e, t) -> - let* subst1, e_type = infer_expr env e in - let* subst2 = unify e_type (Substitution.apply subst1 t) in - let* subst_result = Substitution.compose subst1 subst2 in - return (subst_result, Substitution.apply subst2 e_type) - | ActPatConstructor (Ident name, body) -> - let* subst1, body_type = infer_expr env body in - let (Scheme (_, existing_type)) = TypeEnv.find_exn env name in - let* subst = unify existing_type body_type in - let* subst_final = Substitution.compose subst1 subst in - return (subst_final, TActPat (name, body_type)) - -and infer_matching_expr env cases subst_init match_t return_t ~with_arg = - let* subst, return_t = - List.fold - cases - ~init:(return (subst_init, return_t)) - ~f:(fun acc (pat, expr) -> - let* subst1, return_t = acc in - let* env, subst2 = - if with_arg - then - let* env, pat = infer_pattern env ~shadow:true pat in - let* subst2 = unify match_t pat in - return (env, subst2) - else infer_match_pattern env ~shadow:true pat match_t - in - let* subst12 = Substitution.compose subst1 subst2 in - let env = TypeEnv.apply subst12 env in - let* subst3, expr_typ = infer_expr env expr in - let* subst4 = unify return_t expr_typ in - let return_type = unify_act_pat (return_t, expr_typ) in - let* subst = Substitution.compose_all [ subst12; subst3; subst4 ] in - return (subst, Substitution.apply subst return_type)) - in - let final_typ = - if with_arg then Arrow (Substitution.apply subst match_t, return_t) else return_t - in - return (subst, final_typ) - -and extend_env_with_let_binds env is_rec let_binds = - List.fold - let_binds - ~init:(return (env, Substitution.empty)) - ~f:(fun acc let_bind -> - let* env, subst_acc = acc in - let* subst, names_schemes_list = infer_let_bind env is_rec let_bind in - let env = TypeEnv.extend_many env names_schemes_list in - let env = TypeEnv.apply subst env in - let* subst_acc = Substitution.compose subst_acc subst in - return (env, subst_acc)) - -and infer_let_bind env is_rec let_bind = - let* (Let_bind (name, args, e)) = check_let_bind_correctness is_rec let_bind in - let* env, args_types = infer_patterns env ~shadow:true args in - let* subst1, rvalue_type = infer_expr env e in - let bind_type = Substitution.apply subst1 (arrow_of_types args_types rvalue_type) in - (* If let_bind is recursive, then name was already in environment *) - let* env, name_type = - match is_rec with - | Nonrec -> infer_pattern env ~shadow:true name - | Rec -> infer_pattern env ~shadow:false name - in - let* subst2 = unify (Substitution.apply subst1 name_type) bind_type in - let* subst = Substitution.compose subst1 subst2 in - let env = TypeEnv.apply subst env in - let* names = extract_names_from_pattern name >>| elements in - let* arg_names = extract_names_from_patterns args >>| elements in - let names_types = List.map names ~f:(fun n -> n, TypeEnv.find_typ_exn env n) in - let env = TypeEnv.remove_many env (List.concat [ names; arg_names ]) in - let names_schemes_list = - List.map names_types ~f:(fun (name, name_type) -> name, generalize env name_type) - in - return (subst, names_schemes_list) -;; - -let add_ident env ident ~shadow = - let* fresh = make_fresh_var in - let scheme = Scheme (VarSet.empty, fresh) in - let env, typ = - if shadow - then TypeEnv.extend env ident scheme, fresh - else ( - let typ = TypeEnv.find_typ env ident in - env, Option.value typ ~default:fresh) - in - return (env, typ) -;; - -let reconstruct_arrow args return_type = - List.fold_right args ~init:return_type ~f:(fun arg acc -> Arrow (arg, acc)) -;; - -let update_pat_types_with_expr_type arg_types names_with_types_list = - List.map names_with_types_list ~f:(fun (name, return_type) -> - let new_type = reconstruct_arrow arg_types return_type in - name, new_type) -;; - -let infer_statement env = function - | Let (rec_flag, let_bind, let_binds) -> - let let_binds = let_bind :: let_binds in - let* env = - match rec_flag with - | Rec -> extend_env_with_bind_names env let_binds - | Nonrec -> return env - in - let* env, _ = extend_env_with_let_binds env rec_flag let_binds in - let* bind_names = extract_bind_names_from_let_binds let_binds >>| elements in - let bind_names_with_types = - List.fold - bind_names - ~init:(Map.empty (module String)) - ~f:(fun map name -> - match TypeEnv.find_exn env name with - | Scheme (_, typ) -> Map.set map ~key:name ~data:typ) - in - return (env, bind_names_with_types) - | ActPat (fst, rest, args, body) -> - (* input all idents and infer args, expr, find type of act pat definition *) - let* env, _ = - List.fold_right - (fst :: rest) - ~init:(return (env, [])) - ~f:(fun (Ident name) acc -> - let* old_env, typs = acc in - let* new_env, typ = add_ident old_env ~shadow:true name in - return (new_env, typ :: typs)) - in - let* env, args_types = infer_patterns env ~shadow:true args in - let* subst1, expr_type = infer_expr env body in - let env = TypeEnv.apply subst1 env in - let apat_type = Substitution.apply subst1 (arrow_of_types args_types expr_type) in - (* form (name, type) pairs for variants and change types so they content args *) - let variant_names = List.map (fst :: rest) ~f:(function Ident str -> str) in - let variants_with_types_list = - List.map variant_names ~f:(fun name -> - match TypeEnv.find_exn env name with - | Scheme (_, typ) -> name, typ) - in - let arg_types, return_typ = decompose_arrow apat_type in - (* check that all variants are determined in output *) - let* _ = - match return_typ with - | Choice map - when Map.length map = List.length variant_names - && List.exists variant_names ~f:(fun name -> Map.mem map name) -> return () - | _ -> fail `Active_pattern_are_not_determined_by_input - in - let updated_variants_w_types_list = - update_pat_types_with_expr_type arg_types variants_with_types_list - in - let env = - List.fold updated_variants_w_types_list ~init:env ~f:(fun env (name, new_typ) -> - let scheme = generalize env new_typ in - TypeEnv.extend env name scheme) - in - (* delete args from context *) - let* arg_names = extract_names_from_patterns args >>| elements in - let env = TypeEnv.remove_many env arg_names in - (* form result map for printing *) - let result_name = "|" ^ String.concat ~sep:"|" variant_names ^ "|" in - let new_res_map = Map.empty (module String) in - let new_res_map = Map.set new_res_map ~key:result_name ~data:apat_type in - let names_schemes_list = - List.map updated_variants_w_types_list ~f:(fun (name, name_type) -> - name, generalize env name_type) - in - let env = TypeEnv.extend_many env names_schemes_list in - return (env, new_res_map) -;; - -let infer_construction env = function - | Expr exp -> - let* _, typ = infer_expr env exp in - return (env, Map.singleton (module String) "-" typ) - | Statement s -> - let* env, names_and_types = infer_statement env s in - return (env, names_and_types) -;; - -let infer c env state = run (infer_construction env c) state diff --git a/FSharpActivePatterns/lib/inferencer.mli b/FSharpActivePatterns/lib/inferencer.mli deleted file mode 100644 index be6f83f9d..000000000 --- a/FSharpActivePatterns/lib/inferencer.mli +++ /dev/null @@ -1,38 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open TypedTree -open Format - -module TypeEnv : sig - type t - - val default : t - val extend : t -> string -> scheme -> t - val remove : t -> string -> t - val iteri : t -> f:(name:string -> typ:typ -> unit) -> unit -end - -type error = - [ `Occurs_check - | `Undef_var of string - | `Unification_failed of typ * typ - | `Not_allowed_right_hand_side_let_rec - | `Not_allowed_left_hand_side_let_rec - | `Args_after_not_variable_let - | `Bound_several_times - | `Active_pattern_are_not_determined_by_input - ] - -val pp_error : formatter -> error -> unit - -val infer - : construction - -> TypeEnv.t - -> int - -> int - * ( TypeEnv.t * (string, typ, Base.String.comparator_witness) Base.Map.t - , error ) - result diff --git a/FSharpActivePatterns/lib/interpreter.ml b/FSharpActivePatterns/lib/interpreter.ml deleted file mode 100644 index 3b54fd9c9..000000000 --- a/FSharpActivePatterns/lib/interpreter.ml +++ /dev/null @@ -1,506 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Stdlib - -module EvalError = struct - type error = - [ `Division_by_zero - | `Match_failure - | `Type_mismatch - | `Unbound_variable of string - | `Args_after_not_variable_let - | `Bound_several_times - ] - - let pp_error fmt = - let open Format in - function - | `Division_by_zero -> fprintf fmt "Division by zero\n" - | `Match_failure -> fprintf fmt "Match failure\n" - | `Type_mismatch -> - fprintf fmt "Not possible scenario: type mismatch after type check\n" - | `Unbound_variable name -> fprintf fmt "Unbound variable : %s\n" name - | `Args_after_not_variable_let -> fprintf fmt "Args are allowed only after variable\n" - | `Bound_several_times -> fprintf fmt "Variable is bound several times\n" - ;; - - let bound_error : error = `Bound_several_times -end - -module R : sig - type 'a t - type error = EvalError.error - - val pp_error : Format.formatter -> error -> unit - val bound_error : error - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - val ( <|> ) : 'a t -> 'a t -> 'a t - val run : 'a t -> ('a, error) Result.t -end = struct - open Base - include Result - include EvalError - - type 'a t = ('a, error) Result.t - - let ( <|> ) x y = - match x with - | Ok x -> Ok x - | Error _ -> y - ;; - - module Syntax = struct - let ( let* ) = ( >>= ) - end - - let run c = c -end - -module ValueEnv : sig - type t - - type value = - | VUnit - | VInt of int - | VString of string - | VBool of bool - | VTuple of value * value * value list - | VList of value list - | VFun of pattern * pattern list * expr * t - | VFunction of case * case list * t - | VOption of value option - | VActPatCase of string * value - | Print_int - - val find_err : t -> string -> value R.t - val extend : t -> string -> value -> t - val update_exn : t -> string -> f:(value -> value) -> t - val find : t -> string -> value option - val find_exn : t -> string -> value - val pp_value : Format.formatter -> value -> unit - - (* val pp_env : Format.formatter -> t -> unit *) - val set_many : t -> t -> t - val default : t -end = struct - open Base - - (* overwrite values of map1 with values of map2 *) - let set_many map1 map2 = - Map.fold ~init:map1 ~f:(fun ~key ~data map1 -> Map.set map1 ~key ~data) map2 - ;; - - type value = - | VUnit - | VInt of int - | VString of string - | VBool of bool - | VTuple of value * value * value list - | VList of value list - | VFun of pattern * pattern list * expr * t - | VFunction of case * case list * t - | VOption of value option - | VActPatCase of string * value - | Print_int - - and t = (string, value, Base.String.comparator_witness) Base.Map.t - - let rec pp_value fmt = - let open Stdlib.Format in - function - | VUnit -> fprintf fmt "() " - | VInt i -> fprintf fmt "%d " i - | VString s -> fprintf fmt "%S " s - | VBool b -> fprintf fmt "%a " pp_print_bool b - | VTuple (fst, snd, rest) -> - fprintf - fmt - "(%a) " - (pp_print_list pp_value ~pp_sep:(fun fmt () -> fprintf fmt ", ")) - (fst :: snd :: rest) - | VList l -> - fprintf - fmt - "[%a] " - (pp_print_list pp_value ~pp_sep:(fun fmt () -> fprintf fmt "; ")) - l - | VFun _ | Print_int -> fprintf fmt " " - | VFunction _ -> fprintf fmt " " - | VOption (Some v) -> fprintf fmt "Some %a " pp_value v - | VOption None -> fprintf fmt "None " - | VActPatCase (name, v) -> fprintf fmt "%s (%a)" name pp_value v - ;; - - let extend mp key data = Map.set mp ~key ~data - - let update_exn env k ~f = - let v = Map.find_exn env k in - extend env k (f v) - ;; - - let find_err env name = - let open R in - match Map.find env name with - | Some v -> return v - | None -> - let x = fail (`Unbound_variable name) in - x - ;; - - let default = Map.set (Map.empty (module String)) ~key:"print_int" ~data:Print_int - let find = Map.find - let find_exn = Map.find_exn - - (* let pp_env fmt t = - Map.iteri t ~f:(fun ~key ~data -> - Stdlib.Format.fprintf fmt "%s : %a\n" key pp_value data) - ;; *) -end - -include R -open R.Syntax -open ValueEnv -module ExtractIdents = ExtractIdents.Make (R) -open ExtractIdents - -let check_act_pat_correctness env name = - match ValueEnv.find env name with - | Some _ -> return name - | None -> fail (`Unbound_variable name) -;; - -let rec eval_binequal = - let eval_binequal_list l1 l2 = - Base.List.fold2_exn - ~init:(return (VBool true)) - ~f:(fun acc left right -> - let* acc = acc in - let* eq_res = eval_binequal (left, right) in - match acc, eq_res with - | VBool b1, VBool b2 -> return (VBool (b1 && b2)) - | _ -> fail `Type_mismatch) - l1 - l2 - in - function - | VInt i1, VInt i2 -> return (VBool (i1 = i2)) - | VString s1, VString s2 -> return (VBool (s1 = s2)) - | VBool b1, VBool b2 -> return (VBool (b1 = b2)) - | VUnit, VUnit -> return (VBool true) - | VList l1, VList l2 when List.length l1 = List.length l2 -> eval_binequal_list l1 l2 - | VTuple (fst1, snd1, rest1), VTuple (fst2, snd2, rest2) - when List.length rest1 = List.length rest2 -> - eval_binequal_list (fst1 :: snd1 :: rest1) (fst2 :: snd2 :: rest2) - | _ -> fail `Type_mismatch -;; - -let eval_binexpr op v1 v2 = - match op, v1, v2 with - | Binary_equal, v1, v2 -> eval_binequal (v1, v2) - | Binary_unequal, v1, v2 -> - let* b = eval_binequal (v1, v2) in - (match b with - | VBool b -> return (VBool (not b)) - | _ -> fail `Type_mismatch) - | Binary_less, VInt v1, VInt v2 -> return (VBool (v1 < v2)) - | Binary_less_or_equal, VInt v1, VInt v2 -> return (VBool (v1 <= v2)) - | Binary_greater, VInt v1, VInt v2 -> return (VBool (v1 > v2)) - | Binary_greater_or_equal, VInt v1, VInt v2 -> return (VBool (v1 >= v2)) - | Binary_add, VInt v1, VInt v2 -> return (VInt (v1 + v2)) - | Binary_subtract, VInt v1, VInt v2 -> return (VInt (v1 - v2)) - | Binary_multiply, VInt v1, VInt v2 -> return (VInt (v1 * v2)) - | Binary_divide, VInt v1, VInt v2 -> return (VInt (v1 / v2)) - | Logical_or, VBool v1, VBool v2 -> return (VBool (v1 || v2)) - | Logical_and, VBool v1, VBool v2 -> return (VBool (v1 && v2)) - | Binary_or_bitwise, VInt v1, VInt v2 -> return (VInt (v1 lor v2)) - | Binary_xor_bitwise, VInt v1, VInt v2 -> return (VInt (v1 lxor v2)) - | Binary_and_bitwise, VInt v1, VInt v2 -> return (VInt (v1 land v2)) - | Binary_cons, v, VList vl -> return (VList (v :: vl)) - | _ -> fail `Type_mismatch -;; - -let rec match_pattern env = - let match_pattern_list env pl vl = - Base.List.fold2_exn - ~init:(return env) - ~f:(fun acc pat value -> - let* acc = acc in - match_pattern acc (pat, value)) - pl - vl - in - function - | Wild, _ -> return env - | PList pl, VList vl when List.length pl = List.length vl -> - match_pattern_list env pl vl - | PCons (hd, tl), VList (vhd :: vtl) -> - match_pattern_list env [ hd; tl ] [ vhd; VList vtl ] - | PTuple (pfst, psnd, prest), VTuple (vfst, vsnd, vrest) -> - match_pattern_list env (pfst :: psnd :: prest) (vfst :: vsnd :: vrest) - | PConst (Int_lt p), VInt v when p = v -> return env - | PConst (Bool_lt p), VBool v when p = v -> return env - | PConst (String_lt p), VString v when p = v -> return env - | PConst Unit_lt, VUnit -> return env - | PVar (Ident name), v -> return (ValueEnv.extend env name v) - | POption (Some p), VOption (Some v) -> match_pattern env (p, v) - | POption None, VOption None -> return env - | PConstraint (p, _), v -> match_pattern env (p, v) - | PActive (Ident name, p), v -> - (* find func that contains variant in case *) - let act_pat_def = ValueEnv.find env name in - (match act_pat_def with - | Some (VFun (arg, args, body, f_env)) -> - (* match arg of func and match hat, if correct, eval func into value *) - let* f_env = match_pattern f_env (arg, v) in - let* value_after_applying = - match args with - | [] -> - let env = ValueEnv.set_many env f_env in - eval_expr env body - | arg1 :: args -> return (VFun (arg1, args, body, f_env)) - in - (* match pattern in case (p) and value *) - (match value_after_applying with - | VActPatCase (name_evaluated, value) when name_evaluated = name -> - match_pattern env (p, value) - | _ -> fail `Type_mismatch) - | _ -> fail `Type_mismatch) - | _ -> fail `Match_failure - -and eval_expr env = function - | Const c -> - (match c with - | Unit_lt -> return VUnit - | Int_lt i -> return (VInt i) - | String_lt s -> return (VString s) - | Bool_lt b -> return (VBool b)) - | Tuple (fst, snd, rest) -> - let* fst_value = eval_expr env fst in - let* snd_value = eval_expr env snd in - let* rest_values = eval_expr_fold env rest in - return (VTuple (fst_value, snd_value, rest_values)) - | List l -> - let* l_values = eval_expr_fold env l in - return (VList l_values) - | Variable (Ident n) -> find_err env n - | Unary_expr (op, e) -> - let* v = eval_expr env e in - (match op, v with - | Unary_minus, VInt i -> return (VInt (-i)) - | Unary_not, VBool b -> return (VBool (not b)) - | _ -> fail `Type_mismatch) - | Bin_expr (op, e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - eval_binexpr op v1 v2 - | If_then_else (c, t, e) -> - let* c_value = eval_expr env c in - (match c_value with - | VBool true -> eval_expr env t - | VBool false -> - (match e with - | None -> return VUnit - | Some e -> eval_expr env e) - | _ -> fail `Type_mismatch) - | Lambda (arg, args, body) -> return (VFun (arg, args, body, env)) - | Apply (f, applying_arg) -> - let* f_value = eval_expr env f in - let* applying_arg_value = eval_expr env applying_arg in - (match f_value, applying_arg_value with - | VFun (arg, args, body, f_env), _ -> - let* f_env = match_pattern f_env (arg, applying_arg_value) in - (match args with - | [] -> - let env = ValueEnv.set_many env f_env in - let* v = eval_expr env body in - return v - | arg1 :: args -> return (VFun (arg1, args, body, f_env))) - | VFunction (c, cl, f_env), _ -> eval_match f_env applying_arg_value (c :: cl) - | Print_int, VInt i -> - Format.(fprintf std_formatter "%d\n" i); - return VUnit - | _ -> fail `Type_mismatch) - | Match (e, c, cl) -> - let* v = eval_expr env e in - eval_match env v (c :: cl) - | Function (c, cl) -> return (VFunction (c, cl, env)) - | LetIn (rec_flag, let_bind, let_binds, e) -> - let* env = extend_env_with_let_binds env rec_flag (let_bind :: let_binds) in - let* value = eval_expr env e in - return value - | Option None -> return (VOption None) - | Option (Some e) -> - let* value = eval_expr env e in - return (VOption (Some value)) - | EConstraint (e, _) -> eval_expr env e - | ActPatConstructor (Ident name, e) -> - let* value = eval_expr env e in - let* name = check_act_pat_correctness env name in - return (VActPatCase (name, value)) - -and eval_expr_fold env l = - Base.List.fold_right - ~init:(return []) - ~f:(fun e acc -> - let* acc = acc in - let* e_value = eval_expr env e in - return (e_value :: acc)) - l - -and eval_match env v = function - | [] -> fail `Match_failure - | (pat, expr) :: tl -> - (let* ext_env = match_pattern env (pat, v) in - eval_expr ext_env expr) - <|> eval_match env v tl - -(* Add name with it's value of let_bind to value environment. - If name is variable, then returns new env with Some name, else returns new env with None*) -and extend_env_with_let_bind env = function - | Let_bind (name, args, body) -> - (match name, args with - | PVar (Ident ident), arg1 :: args -> - let value = VFun (arg1, args, body, env) in - let* env = match_pattern env (name, value) in - return (Some ident, env) - | _, _ :: _ -> fail `Args_after_not_variable_let - | PVar (Ident ident), [] -> - let* value = eval_expr env body in - let* env = match_pattern env (name, value) in - return (Some ident, env) - | _, [] -> - (* If name is not variable, then let is not recursive (checked in type check)*) - let* value = eval_expr env body in - let* env = match_pattern env (name, value) in - return (None, env)) - -and extend_env_with_let_binds env rec_flag let_binds = - let* names, env = - Base.List.fold - ~init:(return ([], env)) - ~f:(fun acc let_bind -> - let* names, env = acc in - let* name, env = extend_env_with_let_bind env let_bind in - match name with - | Some name -> return (name :: names, env) - | None -> return (names, env)) - let_binds - in - let env = - match rec_flag with - | Rec -> - Base.List.fold - ~init:env - ~f:(fun env name -> - ValueEnv.update_exn env name ~f:(function - | VFun (arg, args, body, _) -> VFun (arg, args, body, env) - | other -> other)) - names - | Nonrec -> env - in - return env -;; - -let eval_statement env = - let open Base in - function - | Let (rec_flag, let_bind, let_binds) -> - let let_binds = let_bind :: let_binds in - let* env = extend_env_with_let_binds env rec_flag let_binds in - let* bind_names = extract_bind_names_from_let_binds let_binds >>| elements in - let bind_names_with_values = - List.fold - bind_names - ~init:(Map.empty (module String)) - ~f:(fun map name -> - let value = ValueEnv.find_exn env name in - Map.set map ~key:name ~data:value) - in - return (env, bind_names_with_values) - | ActPat (fst, rest, args, expr) -> - let name_list = fst :: rest in - let ident_name_list = List.map name_list ~f:(fun (Ident s) -> s) in - let* value = - match args with - | arg :: args -> return (VFun (arg, args, expr, env)) - | [] -> eval_expr env expr - in - let pat_name = "|" ^ String.concat ~sep:"|" ident_name_list ^ "|" in - let* env = match_pattern env (PVar (Ident pat_name), value) in - let* env = - List.fold_right name_list ~init:(return env) ~f:(fun fst acc_env -> - let* acc = acc_env in - let* new_env = match_pattern acc (PVar fst, value) in - return new_env) - in - let env = - Base.List.fold - ~init:env - ~f:(fun env name -> - ValueEnv.update_exn env name ~f:(function - | VFun (arg, args, body, _) -> VFun (arg, args, body, env) - | other -> other)) - ident_name_list - in - let pat_name_in_list = [ pat_name ] in - let patterns_names_with_values = - List.fold - pat_name_in_list - ~init:(Map.empty (module String)) - ~f:(fun map name -> - let value = ValueEnv.find_exn env name in - Map.set map ~key:name ~data:value) - in - return (env, patterns_names_with_values) -;; - -let eval_construction env = function - | Expr e -> - let* value = eval_expr env e in - return (env, Base.Map.singleton (module Base.String) "-" value) - | Statement s -> eval_statement env s -;; - -let eval env c = run (eval_construction env c) - -type global_error = - [ error - | Inferencer.error - ] - -let pp_global_error fmt (e : global_error) = - match e with - | #error as e -> pp_error fmt e - | #Inferencer.error as e -> Inferencer.pp_error fmt e -;; - -let run_interpreter type_env value_env state c = - let open Base in - let new_state, infer_result = Inferencer.infer c type_env state in - match infer_result with - | Error (#Inferencer.error as type_err) -> new_state, Result.fail type_err - | Ok (new_type_env, names_and_types) -> - (match eval value_env c with - | Error (#error as eval_err) -> new_state, Result.fail eval_err - | Ok (new_value_env, names_and_values) -> - let names_with_types_and_values = - Map.fold - names_and_types - ~init:(Map.empty (module String)) - ~f:(fun ~key ~data map -> - let value = Map.find_exn names_and_values key in - Map.set map ~key ~data:(data, value)) - in - new_state, Result.return (new_type_env, new_value_env, names_with_types_and_values)) -;; diff --git a/FSharpActivePatterns/lib/interpreter.mli b/FSharpActivePatterns/lib/interpreter.mli deleted file mode 100644 index e5ea553bb..000000000 --- a/FSharpActivePatterns/lib/interpreter.mli +++ /dev/null @@ -1,44 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -module ValueEnv : sig - type t - type value - - val default : t - val pp_value : Format.formatter -> value -> unit -end - -type error = - [ `Division_by_zero - | `Match_failure - | `Type_mismatch - | `Unbound_variable of string - | `Args_after_not_variable_let - | `Bound_several_times - ] - -type global_error = - [ error - | Inferencer.error - ] - -val pp_global_error : Format.formatter -> global_error -> unit - -val run_interpreter - : Inferencer.TypeEnv.t - -> ValueEnv.t - -> int - -> construction - -> int - * ( Inferencer.TypeEnv.t - * ValueEnv.t - * ( string - , TypedTree.typ * ValueEnv.value - , Base.String.comparator_witness ) - Base.Map.t - , global_error ) - result diff --git a/FSharpActivePatterns/lib/keywordChecker.ml b/FSharpActivePatterns/lib/keywordChecker.ml deleted file mode 100644 index ff3687d1f..000000000 --- a/FSharpActivePatterns/lib/keywordChecker.ml +++ /dev/null @@ -1,27 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -let is_keyword = function - | "if" - | "then" - | "else" - | "let" - | "in" - | "not" - | "true" - | "false" - | "fun" - | "match" - | "with" - | "and" - | "Some" - | "None" - | "function" - | "->" - | "|" - | ":" - | "::" - | "_" -> true - | _ -> false -;; diff --git a/FSharpActivePatterns/lib/keywordChecker.mli b/FSharpActivePatterns/lib/keywordChecker.mli deleted file mode 100644 index 63931a206..000000000 --- a/FSharpActivePatterns/lib/keywordChecker.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val is_keyword : string -> bool diff --git a/FSharpActivePatterns/lib/parser.ml b/FSharpActivePatterns/lib/parser.ml deleted file mode 100644 index a50110b51..000000000 --- a/FSharpActivePatterns/lib/parser.ml +++ /dev/null @@ -1,461 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast -open Base -open KeywordChecker -open TypedTree - -(* TECHNICAL FUNCTIONS *) - -let is_ws = function - | ' ' -> true - | '\n' -> true - | '\t' -> true - | _ -> false -;; - -let skip_ws = skip_while is_ws - -let peek_sep1 = - peek_char - >>= fun c -> - match c with - | None -> return None - | Some c -> - (match c with - | '(' | ')' | ']' | ';' | ':' | ',' -> return (Some c) - | _ -> if is_ws c then return (Some c) else fail "need a delimiter") -;; - -let skip_ws_sep1 = peek_sep1 *> skip_ws - -let chainl1 e op = - let rec go acc = lift2 (fun f x -> f acc x) op e >>= go <|> return acc in - e >>= go -;; - -let rec chainr1 e op = - let* left = e in - (let* f = op in - let* right = chainr1 e op in - return (f left right)) - <|> return left -;; - -let rec unary_chain op e = - op >>= (fun unexpr -> unary_chain op e >>= fun expr -> return (unexpr expr)) <|> e -;; - -(* SIMPLE PARSERS *) -let expr_const_factory parser = parser >>| fun lit -> Const lit -let pat_const_factory parser = parser >>| fun lit -> PConst lit - -let p_int = - skip_ws - *> let* sign = string "+" <|> string "-" <|> string "" in - let* number = take_while1 Char.is_digit in - return (Int_lt (Int.of_string (sign ^ number))) -;; - -let p_int_expr = expr_const_factory p_int -let p_int_pat = pat_const_factory p_int - -let p_bool = - skip_ws *> string "true" - <|> skip_ws *> string "false" - >>| fun s -> Bool_lt (Bool.of_string s) -;; - -let p_bool_expr = expr_const_factory p_bool -let p_bool_pat = pat_const_factory p_bool - -let p_escaped_char = - char '\\' - *> (any_char - >>= function - | '"' -> return '"' - | '\\' -> return '\\' - | 'n' -> return '\n' - | 't' -> return '\t' - | 'r' -> return '\r' - | other -> fail (Printf.sprintf "Unknown escape sequence: \\%c" other)) -;; - -let p_regular_char = satisfy (fun c -> Char.(c <> '"' && c <> '\\')) - -let p_string = - let+ s = skip_ws *> char '"' *> many (p_regular_char <|> p_escaped_char) <* char '"' in - String_lt (String.of_char_list s) -;; - -let p_string_expr = expr_const_factory p_string -let p_string_pat = pat_const_factory p_string - -let p_inf_oper = - let* oper = - skip_ws - *> take_while1 (function - | '+' - | '-' - | '<' - | '>' - | '*' - | '|' - | '!' - | '$' - | '%' - | '&' - | '.' - | '/' - | ':' - | '=' - | '?' - | '@' - | '^' - | '~' -> true - | _ -> false) - in - if is_keyword oper - then fail "keywords are not allowed as variable names" - else return (Ident oper) -;; - -let p_name p_fst_letter = - let* name = - skip_ws - *> lift2 - ( ^ ) - p_fst_letter - (take_while (function - | 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' -> true - | _ -> false)) - in - if is_keyword name - then fail "keywords are not allowed as variable names" - else return name -;; - -let p_varname = - p_name - (take_while1 (function - | 'a' .. 'z' | '_' -> true - | _ -> false)) -;; - -let p_act_pat_name = - p_name - (take_while1 (function - | 'A' .. 'Z' -> true - | _ -> false)) -;; - -let p_ident = - let* varname = p_varname in - return (Ident varname) -;; - -let p_act_pat_ident = - let* name = p_act_pat_name in - return (Ident name) -;; - -let p_type = skip_ws *> char ':' *> skip_ws *> p_varname >>| fun s -> Primitive s -let p_var_expr = p_ident >>| fun ident -> Variable ident -let p_var_pat = p_ident >>| fun ident -> PVar ident - -let p_semicolon_list p_elem = - skip_ws - *> string "[" - *> skip_ws - *> let+ list = - fix (fun p_semi_list -> - choice - [ (let* hd = p_elem <* skip_ws <* string ";" in - let* tl = p_semi_list in - return (hd :: tl)) - ; (let* hd = p_elem <* skip_ws <* string "]" in - return [ hd ]) - ; skip_ws *> string "]" *> return [] - ]) - in - list -;; - -let p_semicolon_list_expr p_expr = p_semicolon_list p_expr >>| fun l -> List l -let p_semicolon_list_pat p_pat = p_semicolon_list p_pat >>| fun l -> PList l -let p_unit = skip_ws *> string "(" *> skip_ws *> string ")" *> return Unit_lt -let p_unit_expr = expr_const_factory p_unit -let p_unit_pat = pat_const_factory p_unit - -(* EXPR PARSERS *) -let p_parens p = skip_ws *> char '(' *> skip_ws *> p <* skip_ws <* char ')' -let make_binexpr op expr1 expr2 = Bin_expr (op, expr1, expr2) [@@inline always] -let make_unexpr op expr = Unary_expr (op, expr) [@@inline always] -let make_tuple_expr e1 e2 rest = Tuple (e1, e2, rest) [@@inline always] -let make_tuple_pat p1 p2 rest = PTuple (p1, p2, rest) -let p_binexpr binop_str binop = skip_ws *> string binop_str *> return (make_binexpr binop) -let p_unexpr unop_str unop = skip_ws *> string unop_str *> return (make_unexpr unop) -let p_not = p_unexpr "not" Unary_not -let unminus = p_unexpr "-" Unary_minus -let add = p_binexpr "+" Binary_add -let sub = p_binexpr "-" Binary_subtract -let mul = p_binexpr "*" Binary_multiply -let div = p_binexpr "/" Binary_divide -let equal = p_binexpr "=" Binary_equal -let unequal = p_binexpr "<>" Binary_unequal -let less = p_binexpr "<" Binary_less -let less_or_equal = p_binexpr "<=" Binary_less_or_equal -let greater = p_binexpr ">" Binary_greater -let greater_or_equal = p_binexpr ">=" Binary_greater_or_equal -let log_or = p_binexpr "||" Logical_or -let log_and = p_binexpr "&&" Logical_and -let bitwise_or = p_binexpr "|||" Binary_or_bitwise -let bitwise_and = p_binexpr "&&&" Binary_and_bitwise -let bitwise_xor = p_binexpr "^^^" Binary_xor_bitwise -let cons = p_binexpr "::" Binary_cons - -let p_cons_list_pat p_pat = - chainr1 p_pat (skip_ws *> string "::" *> return (fun l r -> PCons (l, r))) -;; - -let p_tuple make p = - let tuple = - let* fst = p <* skip_ws <* string "," in - let* snd = p in - let* rest = many (skip_ws *> string "," *> p) in - return (make fst snd rest) - in - p_parens tuple <|> tuple -;; - -let p_tuple_pat p_pat = p_tuple make_tuple_pat p_pat - -let p_if p_expr = - lift3 - (fun cond th el -> If_then_else (cond, th, el)) - (skip_ws *> string "if" *> peek_sep1 *> p_expr) - (skip_ws *> string "then" *> peek_sep1 *> p_expr) - (skip_ws - *> string "else" - *> peek_sep1 - *> (p_expr <* peek_sep1 >>= fun e -> return (Some e)) - <|> return None) -;; - -let p_option p make_option = - skip_ws *> string "None" *> peek_sep1 *> return (make_option None) - <|> let+ inner = skip_ws *> string "Some" *> peek_sep1 *> p in - make_option (Some inner) -;; - -let make_option_expr expr = Option expr -let make_option_pat pat = POption pat -let p_wild_pat = skip_ws *> string "_" *> return Wild - -let p_pat_const = - choice [ p_int_pat; p_bool_pat; p_unit_pat; p_string_pat; p_var_pat; p_wild_pat ] -;; - -let p_constraint_pat p_pat = - let* pat = p_pat in - let* typ = p_type in - return (PConstraint (pat, typ)) -;; - -let p_act_pat_case p_pat = - let* case = p_act_pat_ident in - let* pat = - peek_sep1 *> (p_pat <* peek_sep1) - <|> (p_parens p_pat <* peek_sep1) - <|> return (PConst Unit_lt) - in - return (PActive (case, pat)) -;; - -let p_pat = - skip_ws - *> fix (fun self -> - let atom = choice [ p_pat_const; p_parens self; p_parens (p_constraint_pat self) ] in - let semicolon_list = p_semicolon_list_pat (self <|> atom) <|> atom in - let opt = p_option semicolon_list make_option_pat <|> semicolon_list in - let cons = p_cons_list_pat opt in - let tuple = p_tuple_pat cons <|> cons in - let active = p_act_pat_case tuple <|> tuple in - active) -;; - -let p_let_bind p_expr = - let* name = p_pat <|> (p_parens p_inf_oper >>| fun oper -> PVar oper) in - let* args = many p_pat in - let* body = skip_ws *> string "=" *> p_expr in - return (Let_bind (name, args, body)) -;; - -let p_letin p_expr = - skip_ws - *> string "let" - *> skip_ws_sep1 - *> - let* rec_flag = string "rec" *> peek_sep1 *> return Rec <|> return Nonrec in - let* let_bind1 = p_let_bind p_expr in - let* let_binds = many (skip_ws *> string "and" *> peek_sep1 *> p_let_bind p_expr) in - let* in_expr = skip_ws *> string "in" *> peek_sep1 *> p_expr in - return (LetIn (rec_flag, let_bind1, let_binds, in_expr)) -;; - -let p_let p_expr = - skip_ws - *> string "let" - *> skip_ws_sep1 - *> - let* rec_flag = string "rec" *> peek_sep1 *> return Rec <|> return Nonrec in - let* let_bind1 = p_let_bind p_expr in - let* let_binds = many (skip_ws *> string "and" *> peek_sep1 *> p_let_bind p_expr) in - return (Let (rec_flag, let_bind1, let_binds)) -;; - -let p_apply p_expr = - chainl1 - (p_parens p_expr <|> (p_expr <* peek_sep1)) - (return (fun expr1 expr2 -> Apply (expr1, expr2))) -;; - -let p_lambda p_expr = - skip_ws - *> string "fun" - *> peek_sep1 - *> - let* arg1 = p_pat in - let* args = many p_pat <* skip_ws <* string "->" in - let* body = p_expr in - return (Lambda (arg1, args, body)) -;; - -let p_case p_expr = - let* pat = skip_ws *> string "|" *> p_pat <* skip_ws <* string "->" in - let* expr = p_expr in - return (pat, expr) -;; - -let p_first_case p_expr = - let* pat = skip_ws *> (string "|" *> p_pat <|> p_pat) <* skip_ws <* string "->" in - let* expr = p_expr in - return (pat, expr) -;; - -let p_match p_expr = - let* value = skip_ws *> string "match" *> p_expr <* skip_ws <* string "with" in - let* pat1, expr1 = p_first_case p_expr in - let* cases = many (p_case p_expr) in - return (Match (value, (pat1, expr1), cases)) -;; - -let p_function p_expr = - skip_ws - *> string "function" - *> - let* pat1, expr1 = p_first_case p_expr in - let* cases = many (p_case p_expr) in - return (Function ((pat1, expr1), cases)) -;; - -let p_inf_oper_expr p_expr = - skip_ws - *> chainl1 - p_expr - (p_inf_oper - >>= fun op -> - return (fun expr1 expr2 -> Apply (Apply (Variable op, expr1), expr2))) -;; - -let p_constraint_expr p_expr = - let* expr = p_expr in - let* typ = p_type in - return (EConstraint (expr, typ)) -;; - -let p_act_pat p_expr = - skip_ws - *> string "let" - *> skip_ws_sep1 - *> - let* fst_name = - skip_ws *> string "(" *> skip_ws *> string "|" *> skip_ws *> p_act_pat_ident - in - let* names = - many (skip_ws *> string "|" *> p_act_pat_ident) - <* skip_ws - <* string "|" - <* skip_ws - <* string ")" - in - let* args = many p_pat in - let* expr = skip_ws *> string "=" *> skip_ws *> p_expr in - return (ActPat (fst_name, names, args, expr)) -;; - -let p_act_pat_constructor p_expr = - skip_ws - *> - let* name = p_act_pat_ident in - let* expr = - peek_sep1 *> (p_expr <* peek_sep1) - <|> (p_parens p_expr <* peek_sep1) - <|> return (Const Unit_lt) - in - return (ActPatConstructor (name, expr)) -;; - -let p_expr = - skip_ws - *> fix (fun p_expr -> - let atom = - choice - [ p_var_expr - ; p_int_expr - ; p_string_expr - ; p_unit_expr - ; p_bool_expr - ; p_parens p_expr - ; p_semicolon_list_expr p_expr - ; p_parens (p_constraint_expr p_expr) - ] - in - let if_expr = p_if (p_expr <|> atom) <|> atom in - let letin_expr = p_letin (p_expr <|> if_expr) <|> if_expr in - let option = p_option letin_expr make_option_expr <|> letin_expr in - let apply = p_apply option <|> option in - let unary = choice [ unary_chain p_not apply; unary_chain unminus apply ] in - let factor = chainl1 unary (mul <|> div) in - let term = chainl1 factor (add <|> sub) in - let cons_op = chainr1 term cons in - let comp_eq = chainl1 cons_op (equal <|> unequal) in - let comp_less = chainl1 comp_eq (less_or_equal <|> less) in - let comp_gr = chainl1 comp_less (greater_or_equal <|> greater) in - let bit_xor = chainl1 comp_gr bitwise_xor in - let bit_and = chainl1 bit_xor bitwise_and in - let bit_or = chainl1 bit_and bitwise_or in - let comp_and = chainl1 bit_or log_and in - let comp_or = chainl1 comp_and log_or in - let inf_oper = p_inf_oper_expr comp_or <|> comp_or in - let tuple = p_tuple make_tuple_expr inf_oper <|> inf_oper in - let p_function = p_function (p_expr <|> tuple) <|> tuple in - let ematch = p_match (p_expr <|> p_function) <|> p_function in - let efun = p_lambda (p_expr <|> ematch) <|> ematch in - let apat_c = p_act_pat_constructor efun <|> efun in - apat_c) -;; - -let p_statement = p_act_pat p_expr <|> p_let p_expr - -let p_construction = - p_expr >>= (fun e -> return (Expr e)) <|> (p_statement >>= fun s -> return (Statement s)) -;; - -(* MAIN PARSE FUNCTION *) -let parse (str : string) = - parse_string ~consume:All (skip_ws *> p_construction <* skip_ws) str -;; diff --git a/FSharpActivePatterns/lib/parser.mli b/FSharpActivePatterns/lib/parser.mli deleted file mode 100644 index 6d0484176..000000000 --- a/FSharpActivePatterns/lib/parser.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val parse : string -> (construction, string) result diff --git a/FSharpActivePatterns/lib/prettyPrinter.ml b/FSharpActivePatterns/lib/prettyPrinter.ml deleted file mode 100644 index 1af856045..000000000 --- a/FSharpActivePatterns/lib/prettyPrinter.ml +++ /dev/null @@ -1,168 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Format -open TypesPp - -let pp_bin_op fmt = function - | Binary_equal -> fprintf fmt "= " - | Binary_unequal -> fprintf fmt "<> " - | Binary_less -> fprintf fmt "< " - | Binary_less_or_equal -> fprintf fmt "<= " - | Binary_greater -> fprintf fmt "> " - | Binary_greater_or_equal -> fprintf fmt ">= " - | Binary_add -> fprintf fmt "+ " - | Binary_subtract -> fprintf fmt "- " - | Binary_multiply -> fprintf fmt "* " - | Logical_or -> fprintf fmt "|| " - | Logical_and -> fprintf fmt "&& " - | Binary_divide -> fprintf fmt "/ " - | Binary_or_bitwise -> fprintf fmt "||| " - | Binary_xor_bitwise -> fprintf fmt "^^^ " - | Binary_and_bitwise -> fprintf fmt "&&& " - | Binary_cons -> fprintf fmt "::" -;; - -let pp_unary_op fmt = function - | Unary_minus -> fprintf fmt "-" - | Unary_not -> fprintf fmt "not " -;; - -let pp_rec_flag fmt = function - | Rec -> fprintf fmt "rec" - | Nonrec -> () -;; - -let rec pp_pattern fmt = function - | Wild -> fprintf fmt "_ " - | PList l -> - fprintf fmt "["; - pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt "; ") pp_pattern fmt l; - fprintf fmt "]" - | PCons (l, r) -> fprintf fmt "(%a) :: (%a) " pp_pattern l pp_pattern r - | PTuple (p1, p2, rest) -> - fprintf fmt "("; - pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt ", ") - pp_pattern - fmt - (p1 :: p2 :: rest); - fprintf fmt ")" - | PConst literal -> fprintf fmt "%a " pp_expr (Const literal) - | PVar (Ident name) -> fprintf fmt "%s " name - | POption p -> - (match p with - | None -> fprintf fmt "None " - | Some p -> fprintf fmt "Some (%a) " pp_pattern p) - | PConstraint (p, t) -> fprintf fmt "(%a : %a) " pp_pattern p pp_typ t - | PActive (Ident name, p) -> fprintf fmt "%s %a" name pp_pattern p - -and pp_expr fmt expr = - match expr with - | Const (Int_lt i) -> fprintf fmt "%d " i - | Const (Bool_lt b) -> fprintf fmt "%b " b - | Const (String_lt s) -> fprintf fmt "%S" s - | Const Unit_lt -> fprintf fmt "() " - | List l -> - fprintf fmt "["; - pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt "; ") pp_expr fmt l; - fprintf fmt "]" - | Tuple (e1, e2, rest) -> - fprintf fmt "("; - pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt ", ") - pp_parens_expr - fmt - (e1 :: e2 :: rest); - fprintf fmt ")" - | Function ((pat1, expr1), cases) -> - fprintf fmt "function "; - List.iter - (fun (pat, expr) -> fprintf fmt "| %a -> (%a) \n" pp_pattern pat pp_expr expr) - ((pat1, expr1) :: cases) - | Match (value, (pat1, expr1), cases) -> - fprintf fmt "match (%a) with \n" pp_expr value; - List.iter - (fun (pat, expr) -> fprintf fmt "| %a -> (%a) \n" pp_pattern pat pp_expr expr) - ((pat1, expr1) :: cases) - | Variable (Ident name) -> fprintf fmt "%s " name - | Unary_expr (op, expr) -> fprintf fmt "%a (%a)" pp_unary_op op pp_expr expr - | Bin_expr (op, left, right) -> - fprintf fmt "(%a) %a (%a)" pp_expr left pp_bin_op op pp_expr right - | If_then_else (cond, then_body, else_body) -> - fprintf fmt "if (%a) then (%a) " pp_expr cond pp_expr then_body; - (match else_body with - | Some body -> fprintf fmt "else %a " pp_expr body - | None -> ()) - | Lambda (arg1, args, body) -> - fprintf fmt "fun "; - List.iter (fun pat -> fprintf fmt "(%a) " pp_pattern pat) (arg1 :: args); - fprintf fmt "-> %a " pp_expr body - | Apply (Apply (Variable (Ident op), left), right) - when String.for_all (fun c -> String.contains "!$%&*+-./:<=>?@^|~" c) op -> - fprintf fmt "(%a) %s (%a)" pp_expr left op pp_expr right - | Apply (func, arg) -> fprintf fmt "(%a) %a" pp_expr func pp_expr arg - | LetIn (rec_flag, let_bind, let_bind_list, in_expr) -> - fprintf fmt "let %a " pp_rec_flag rec_flag; - pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt "\n\nand ") - pp_let_bind - fmt - (let_bind :: let_bind_list); - fprintf fmt "in\n"; - fprintf fmt "%a " pp_expr in_expr - | Option e -> - (match e with - | None -> fprintf fmt "None " - | Some e -> fprintf fmt "Some (%a)" pp_expr e) - | EConstraint (e, t) -> fprintf fmt "(%a : %a) " pp_expr e pp_typ t - | ActPatConstructor (Ident name, e) -> - fprintf fmt " %s " name; - fprintf fmt "(%a)" pp_expr e - -and pp_args fmt args = - let open Format in - pp_print_list - ~pp_sep:pp_print_space - (fun fmt arg -> fprintf fmt "%a" pp_pattern arg) - fmt - args - -and pp_let_bind fmt = function - | Let_bind (name, args, body) -> - fprintf fmt "%a %a = %a " pp_pattern name pp_args args pp_expr body - -and pp_parens_expr fmt expr = fprintf fmt "(%a)" pp_expr expr - -let pp_statement fmt = function - | Let (rec_flag, let_bind, let_bind_list) -> - fprintf fmt "let %a " pp_rec_flag rec_flag; - pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt "\n\nand ") - pp_let_bind - fmt - (let_bind :: let_bind_list) - | ActPat (Ident name, names, args, expr) -> - fprintf fmt "let (|%s|" name; - pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt "|") - (fun fmt (Ident name) -> fprintf fmt "%s" name) - fmt - names; - fprintf fmt "|) "; - pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt " ") pp_pattern fmt args; - fprintf fmt " =\n"; - pp_expr fmt expr -;; - -let pp_construction fmt = function - | Expr e -> fprintf fmt "%a\n" pp_expr e - | Statement s -> fprintf fmt "%a\n" pp_statement s -;; - -let pp_p_res fmt = function - | Some c -> pp_construction fmt c - | None -> fprintf fmt "Error occured\n" -;; diff --git a/FSharpActivePatterns/lib/prettyPrinter.mli b/FSharpActivePatterns/lib/prettyPrinter.mli deleted file mode 100644 index 428b94b3d..000000000 --- a/FSharpActivePatterns/lib/prettyPrinter.mli +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Format - -val pp_construction : formatter -> construction -> unit -val pp_p_res : formatter -> construction option -> unit diff --git a/FSharpActivePatterns/lib/tests/ast_printer.ml b/FSharpActivePatterns/lib/tests/ast_printer.ml deleted file mode 100644 index b713bc9ad..000000000 --- a/FSharpActivePatterns/lib/tests/ast_printer.ml +++ /dev/null @@ -1,279 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -let%expect_test "print Ast factorial" = - let open FSharpActivePatterns.Ast in - let open FSharpActivePatterns.AstPrinter in - let open Format in - let factorial = - Lambda - ( PConst (Int_lt 4) - , [] - , If_then_else - ( Bin_expr - ( Logical_or - , Bin_expr (Binary_equal, Variable (Ident "n"), Const (Int_lt 0)) - , Bin_expr (Binary_equal, Variable (Ident "n"), Const (Int_lt 1)) ) - , Const (Int_lt 1) - , Some - (Bin_expr - ( Binary_multiply - , Variable (Ident "n") - , Apply - ( Variable (Ident "factorial") - , Bin_expr (Binary_subtract, Variable (Ident "n"), Const (Int_lt 1)) - ) )) ) ) - in - let program = - [ Statement (Let (Nonrec, Let_bind (PVar (Ident "a"), [], Const (Int_lt 10)), [])) - ; Expr factorial - ; Expr (Apply (factorial, Variable (Ident "a"))) - ] - in - List.iter (print_construction std_formatter) program; - [%expect - {| - | Let: - Let_binds - --| Let_bind: - NAME: - ------| PVar(a) - ARGS: - BODY: - ----| Const(Int: 10) - | Lambda: - ARGS - ----| PConst: - ------Int: 4 - BODY - ----| If Then Else( - CONDITION - ------| Binary expr( - ------| Logical Or - --------| Binary expr( - --------| Binary Equal - ----------| Variable(n) - ----------| Const(Int: 0) - --------| Binary expr( - --------| Binary Equal - ----------| Variable(n) - ----------| Const(Int: 1) - THEN BRANCH - ------| Const(Int: 1) - ELSE BRANCH - ------| Binary expr( - ------| Binary Multiply - --------| Variable(n) - --------| Apply: - FUNCTION - ----------| Variable(factorial) - ARGS - ----------| Binary expr( - ----------| Binary Subtract - ------------| Variable(n) - ------------| Const(Int: 1) - | Apply: - FUNCTION - --| Lambda: - ARGS - ------| PConst: - --------Int: 4 - BODY - ------| If Then Else( - CONDITION - --------| Binary expr( - --------| Logical Or - ----------| Binary expr( - ----------| Binary Equal - ------------| Variable(n) - ------------| Const(Int: 0) - ----------| Binary expr( - ----------| Binary Equal - ------------| Variable(n) - ------------| Const(Int: 1) - THEN BRANCH - --------| Const(Int: 1) - ELSE BRANCH - --------| Binary expr( - --------| Binary Multiply - ----------| Variable(n) - ----------| Apply: - FUNCTION - ------------| Variable(factorial) - ARGS - ------------| Binary expr( - ------------| Binary Subtract - --------------| Variable(n) - --------------| Const(Int: 1) - ARGS - --| Variable(a) |}] -;; - -let%expect_test "print Ast double func" = - let open FSharpActivePatterns.Ast in - let open FSharpActivePatterns.AstPrinter in - let open Format in - let ident = Ident "n" in - let pat = PConst (Int_lt 4) in - let args = [] in - let binary_expr = Bin_expr (Binary_multiply, Const (Int_lt 2), Variable ident) in - let double = Lambda (pat, args, binary_expr) in - print_construction std_formatter @@ Expr double; - [%expect - {| - | Lambda: - ARGS - ----| PConst: - ------Int: 4 - BODY - ----| Binary expr( - ----| Binary Multiply - ------| Const(Int: 2) - ------| Variable(n)|}] -;; - -let%expect_test "print Ast tuple of binary operators" = - let open FSharpActivePatterns.Ast in - let open FSharpActivePatterns.AstPrinter in - let open Format in - let first = Const (Int_lt 3) in - let second = Const (Int_lt 10) in - let operators = - [ Binary_unequal - ; Binary_less - ; Binary_less_or_equal - ; Binary_greater - ; Binary_greater_or_equal - ; Binary_add - ; Logical_and - ; Binary_divide - ; Binary_or_bitwise - ; Binary_xor_bitwise - ; Binary_and_bitwise - ] - in - let print_binary_constr operator = - print_construction std_formatter @@ Expr (Bin_expr (operator, first, second)) - in - List.iter print_binary_constr operators; - [%expect - {| - | Binary expr( - | Binary Unequal - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Less - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Less Or Equal - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Greater - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Greater Or Equal - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Add - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Logical And - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Divide - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Or Bitwise - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary Xor Bitwise - --| Const(Int: 3) - --| Const(Int: 10) - | Binary expr( - | Binary And Bitwise - --| Const(Int: 3) - --| Const(Int: 10) |}] -;; - -let%expect_test "print Ast of LetIn" = - let open FSharpActivePatterns.Ast in - let open FSharpActivePatterns.AstPrinter in - let open Format in - let sum = - Expr - (LetIn - ( Nonrec - , Let_bind (PVar (Ident "x"), [], Const (Int_lt 5)) - , [] - , Bin_expr (Binary_add, Variable (Ident "x"), Const (Int_lt 5)) )) - in - print_construction std_formatter sum; - [%expect - {| - | LetIn= - Let_binds - --| Let_bind: - NAME: - ------| PVar(x) - ARGS: - BODY: - ----| Const(Int: 5) - INNER_EXPRESSION - --| Binary expr( - --| Binary Add - ----| Variable(x) - ----| Const(Int: 5) |}] -;; - -let%expect_test "print Ast of match_expr" = - let open FSharpActivePatterns.Ast in - let open FSharpActivePatterns.AstPrinter in - let open Format in - let patterns = - [ PConst (Int_lt 5) - ; PConst (String_lt " bar foo") - ; PList [ Wild; PVar (Ident "xs") ] - ] - in - let pattern_values = List.map (fun p -> p, Const (Int_lt 4)) patterns in - let match_expr = - Match (Variable (Ident "x"), (PConst (Int_lt 4), Const (Int_lt 4)), pattern_values) - in - print_construction std_formatter (Expr match_expr); - [%expect - {| - | Match: - --| Value: - ----| Variable(x) - --| Pattern: - ----| PConst: - ------Int: 4 - --| Case expr: - ----| Const(Int: 4) - --| Pattern: - ----| PConst: - ------Int: 5 - --| Case expr: - ----| Const(Int: 4) - --| Pattern: - ----| PConst: - ------String: " bar foo" - --| Case expr: - ----| Const(Int: 4) - --| Pattern: - ----| PList: - ------| Wild - ------| PVar(xs) - --| Case expr: - ----| Const(Int: 4) |}] -;; diff --git a/FSharpActivePatterns/lib/tests/ast_printer.mli b/FSharpActivePatterns/lib/tests/ast_printer.mli deleted file mode 100644 index 98fe2e874..000000000 --- a/FSharpActivePatterns/lib/tests/ast_printer.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/FSharpActivePatterns/lib/tests/dune b/FSharpActivePatterns/lib/tests/dune deleted file mode 100644 index e03244be9..000000000 --- a/FSharpActivePatterns/lib/tests/dune +++ /dev/null @@ -1,14 +0,0 @@ -(library - (name tests) - (inline_tests) - (modules Ast_printer Parser Qcheck_utils) - (libraries FSharpActivePatterns qcheck-core qcheck-core.runner) - (preprocess - (pps ppx_expect ppx_inline_test ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) - -(executable - (name run_qcheck) - (modules run_qcheck) - (libraries tests FSharpActivePatterns qcheck-core.runner)) diff --git a/FSharpActivePatterns/lib/tests/parser.ml b/FSharpActivePatterns/lib/tests/parser.ml deleted file mode 100644 index d7c173b00..000000000 --- a/FSharpActivePatterns/lib/tests/parser.ml +++ /dev/null @@ -1,345 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -let%expect_test "binary subtract" = - let input = {| a - 3|} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Binary Subtract - --| Variable(a) - --| Const(Int: 3) |}] -;; - -let%expect_test "function apply of letIn" = - let input = {| f let x = false in true || x|} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Apply: - FUNCTION - --| Variable(f) - ARGS - --| LetIn= - Let_binds - ----| Let_bind: - NAME: - --------| PVar(x) - ARGS: - BODY: - ------| Const(Bool: false) - INNER_EXPRESSION - ----| Binary expr( - ----| Logical Or - ------| Const(Bool: true) - ------| Variable(x) |}] -;; - -let%expect_test "arithmetic with unary operations and variables" = - let input = {| - a - - b + 4|} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Binary Add - --| Binary expr( - --| Binary Subtract - ----| Unary expr( - ----| Unary minus - ------| Variable(a) - ----| Unary expr( - ----| Unary minus - ------| Variable(b) - --| Const(Int: 4) |}] -;; - -let%expect_test "sum of function applying" = - let input = {| f 4 + g 3|} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Binary Add - --| Apply: - FUNCTION - ----| Variable(f) - ARGS - ----| Const(Int: 4) - --| Apply: - FUNCTION - ----| Variable(g) - ARGS - ----| Const(Int: 3) |}] -;; - -let%expect_test "order of logical expressions and function applying" = - let input = {| let x = true in not x || true && f 12|} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | LetIn= - Let_binds - --| Let_bind: - NAME: - ------| PVar(x) - ARGS: - BODY: - ----| Const(Bool: true) - INNER_EXPRESSION - --| Binary expr( - --| Logical Or - ----| Unary expr( - ----| Unary negative - ------| Variable(x) - ----| Binary expr( - ----| Logical And - ------| Const(Bool: true) - ------| Apply: - FUNCTION - --------| Variable(f) - ARGS - --------| Const(Int: 12) |}] -;; - -let%expect_test "FSharpActivePatterns.Parser.parse logical expression" = - let input = {| (3 + 5) >= 8 || true && (5 <> 4) |} in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Logical Or - --| Binary expr( - --| Binary Greater Or Equal - ----| Binary expr( - ----| Binary Add - ------| Const(Int: 3) - ------| Const(Int: 5) - ----| Const(Int: 8) - --| Binary expr( - --| Logical And - ----| Const(Bool: true) - ----| Binary expr( - ----| Binary Unequal - ------| Const(Int: 5) - ------| Const(Int: 4) |}] -;; - -let%expect_test "FSharpActivePatterns.Parser.parse integer expression" = - let input = " (3 + 5) - (12 / 7)" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Binary Subtract - --| Binary expr( - --| Binary Add - ----| Const(Int: 3) - ----| Const(Int: 5) - --| Binary expr( - --| Binary Divide - ----| Const(Int: 12) - ----| Const(Int: 7) |}] -;; - -let%expect_test "FSharpActivePatterns.Parser.parse_unary_chain" = - let input = "not not ( not true && false || 3 > 5)" in - let result = FSharpActivePatterns.Parser.parse input in - FSharpActivePatterns.AstPrinter.print_p_res Format.std_formatter result; - [%expect - {| - | Unary expr( - | Unary negative - --| Unary expr( - --| Unary negative - ----| Binary expr( - ----| Logical Or - ------| Binary expr( - ------| Logical And - --------| Unary expr( - --------| Unary negative - ----------| Const(Bool: true) - --------| Const(Bool: false) - ------| Binary expr( - ------| Binary Greater - --------| Const(Int: 3) - --------| Const(Int: 5) |}] -;; - -let%expect_test "FSharpActivePatterns.Parser.parse if with comparison" = - let input = "if 3 > 2 && false then 5 + 7 else 12" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | If Then Else( - CONDITION - --| Binary expr( - --| Logical And - ----| Binary expr( - ----| Binary Greater - ------| Const(Int: 3) - ------| Const(Int: 2) - ----| Const(Bool: false) - THEN BRANCH - --| Binary expr( - --| Binary Add - ----| Const(Int: 5) - ----| Const(Int: 7) - ELSE BRANCH - --| Const(Int: 12) |}] -;; - -let%expect_test "sum with if" = - let input = "a + if 3 > 2 then 2 else 1" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Binary expr( - | Binary Add - --| Variable(a) - --| If Then Else( - CONDITION - ----| Binary expr( - ----| Binary Greater - ------| Const(Int: 3) - ------| Const(Int: 2) - THEN BRANCH - ----| Const(Int: 2) - ELSE BRANCH - ----| Const(Int: 1) |}] -;; - -let%expect_test "inner expressions with LetIn and If" = - let input = - "if let x = true in let y = false in x || y then 3 else if 5 > 3 then 2 else 1" - in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | If Then Else( - CONDITION - --| LetIn= - Let_binds - ----| Let_bind: - NAME: - --------| PVar(x) - ARGS: - BODY: - ------| Const(Bool: true) - INNER_EXPRESSION - ----| LetIn= - Let_binds - ------| Let_bind: - NAME: - ----------| PVar(y) - ARGS: - BODY: - --------| Const(Bool: false) - INNER_EXPRESSION - ------| Binary expr( - ------| Logical Or - --------| Variable(x) - --------| Variable(y) - THEN BRANCH - --| Const(Int: 3) - ELSE BRANCH - --| If Then Else( - CONDITION - ----| Binary expr( - ----| Binary Greater - ------| Const(Int: 5) - ------| Const(Int: 3) - THEN BRANCH - ----| Const(Int: 2) - ELSE BRANCH - ----| Const(Int: 1) |}] -;; - -let%expect_test "factorial" = - let input = "let factorial n = if n = 0 then 1 else factorial (n - 1) in factorial b" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | LetIn= - Let_binds - --| Let_bind: - NAME: - ------| PVar(factorial) - ARGS: - ----| PVar(n) - BODY: - ----| If Then Else( - CONDITION - ------| Binary expr( - ------| Binary Equal - --------| Variable(n) - --------| Const(Int: 0) - THEN BRANCH - ------| Const(Int: 1) - ELSE BRANCH - ------| Apply: - FUNCTION - --------| Variable(factorial) - ARGS - --------| Binary expr( - --------| Binary Subtract - ----------| Variable(n) - ----------| Const(Int: 1) - INNER_EXPRESSION - --| Apply: - FUNCTION - ----| Variable(factorial) - ARGS - ----| Variable(b) |}] -;; - -let%expect_test "fail in ITE with incorrect else expression" = - let input = "if true then 1 else 2c" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect {| : end_of_input |}] -;; - -let%expect_test "call if with parentheses" = - let input = "(if(false)then(a) else(b))c" in - FSharpActivePatterns.AstPrinter.print_p_res - Format.std_formatter - (FSharpActivePatterns.Parser.parse input); - [%expect - {| - | Apply: - FUNCTION - --| If Then Else( - CONDITION - ----| Const(Bool: false) - THEN BRANCH - ----| Variable(a) - ELSE BRANCH - ----| Variable(b) - ARGS - --| Variable(c) |}] -;; diff --git a/FSharpActivePatterns/lib/tests/parser.mli b/FSharpActivePatterns/lib/tests/parser.mli deleted file mode 100644 index 98fe2e874..000000000 --- a/FSharpActivePatterns/lib/tests/parser.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/FSharpActivePatterns/lib/tests/qcheck_utils.ml b/FSharpActivePatterns/lib/tests/qcheck_utils.ml deleted file mode 100644 index 4ea2c879a..000000000 --- a/FSharpActivePatterns/lib/tests/qcheck_utils.ml +++ /dev/null @@ -1,193 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open FSharpActivePatterns.Ast -open FSharpActivePatterns.AstPrinter -open FSharpActivePatterns.Parser -open FSharpActivePatterns.PrettyPrinter - -let bin_e op e1 e2 = Bin_expr (op, e1, e2) - -let shrink_lt = - let open QCheck.Iter in - function - | Int_lt x -> QCheck.Shrink.int x >|= fun a' -> Int_lt a' - | Bool_lt _ -> empty - | Unit_lt -> empty - | String_lt x -> QCheck.Shrink.string x >|= fun a' -> String_lt a' -;; - -let exprs_from_let_binds let_binds = - List.map - (function - | Let_bind (_, _, e) -> e) - let_binds -;; - -let rec shrink_let_bind = - let open QCheck.Iter in - function - | Let_bind (name, args, e) -> - shrink_expr e - >|= (fun a' -> Let_bind (name, args, a')) - <+> (QCheck.Shrink.list args >|= fun a' -> Let_bind (name, a', e)) - <+> (shrink_pattern name >|= fun a' -> Let_bind (a', args, e)) - -and shrink_expr = - let open QCheck.Iter in - function - | Const lt -> shrink_lt lt >|= fun a' -> Const a' - | Tuple (e1, e2, rest) -> - of_list [ e1; e2 ] - <+> (shrink_expr e1 >|= fun a' -> Tuple (a', e2, rest)) - <+> (shrink_expr e2 >|= fun a' -> Tuple (e1, a', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_expr rest >|= fun a' -> Tuple (e1, e2, a')) - | List l -> QCheck.Shrink.list ~shrink:shrink_expr l >|= fun l' -> List l' - | Bin_expr (op, e1, e2) -> - of_list [ e1; e2 ] - <+> (shrink_expr e1 >|= fun a' -> bin_e op a' e2) - <+> (shrink_expr e2 >|= fun a' -> bin_e op e1 a') - | Unary_expr (op, e) -> return e <+> (shrink_expr e >|= fun e' -> Unary_expr (op, e')) - | If_then_else (i, t, Some e) -> - of_list [ i; t; e; If_then_else (i, e, None) ] - <+> (shrink_expr i >|= fun a' -> If_then_else (a', t, Some e)) - <+> (shrink_expr t >|= fun a' -> If_then_else (i, a', Some e)) - | If_then_else (i, t, None) -> - of_list [ i; t ] - <+> (shrink_expr i >|= fun a' -> If_then_else (a', t, None)) - <+> (shrink_expr t >|= fun a' -> If_then_else (i, a', None)) - | LetIn (rec_flag, let_bind, let_bind_list, inner_e) -> - of_list (inner_e :: exprs_from_let_binds (let_bind :: let_bind_list)) - <+> (shrink_let_bind let_bind - >|= fun a' -> LetIn (rec_flag, a', let_bind_list, inner_e)) - <+> (QCheck.Shrink.list ~shrink:shrink_let_bind let_bind_list - >|= fun a' -> LetIn (rec_flag, let_bind, a', inner_e)) - <+> (shrink_expr inner_e >|= fun a' -> LetIn (rec_flag, let_bind, let_bind_list, a')) - | Apply (f, arg) -> - of_list [ f; arg ] - <+> (shrink_expr f >|= fun a' -> Apply (a', arg)) - <+> (shrink_expr arg >|= fun a' -> Apply (f, a')) - | Lambda (pat, pat_list, body) -> - shrink_expr body - >|= (fun body' -> Lambda (pat, pat_list, body')) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern pat_list - >|= fun a' -> Lambda (pat, a', body)) - | Function ((pat1, expr1), cases) -> - of_list (expr1 :: List.map snd cases) - <+> (shrink_pattern pat1 >|= fun a' -> Function ((a', expr1), cases)) - <+> (shrink_expr expr1 >|= fun a' -> Function ((pat1, a'), cases)) - <+> (QCheck.Shrink.list - ~shrink:(fun (p, e) -> - (let* p_shr = shrink_pattern p in - return (p_shr, e)) - <+> - let* e_shr = shrink_expr e in - return (p, e_shr)) - cases - >|= fun a' -> Function ((pat1, expr1), a')) - | Match (value, (pat1, expr1), cases) -> - of_list (value :: expr1 :: List.map snd cases) - <+> (shrink_expr value >|= fun a' -> Match (a', (pat1, expr1), cases)) - <+> (shrink_pattern pat1 >|= fun a' -> Match (value, (a', expr1), cases)) - <+> (shrink_expr expr1 >|= fun a' -> Match (value, (pat1, a'), cases)) - <+> (QCheck.Shrink.list - ~shrink:(fun (p, e) -> - (let* p_shr = shrink_pattern p in - return (p_shr, e)) - <+> - let* e_shr = shrink_expr e in - return (p, e_shr)) - cases - >|= fun a' -> Match (value, (pat1, expr1), a')) - | Option (Some e) -> - of_list [ e; Option None ] <+> (shrink_expr e >|= fun a' -> Option (Some a')) - | Option None -> empty - | Variable _ -> empty - | EConstraint (e, t) -> return e <+> shrink_expr e >|= fun a' -> EConstraint (a', t) - | ActPatConstructor (ident, expr) -> - shrink_expr expr >|= fun expr' -> ActPatConstructor (ident, expr') - -and shrink_pattern = - let open QCheck.Iter in - function - | PList l -> QCheck.Shrink.list ~shrink:shrink_pattern l >|= fun l' -> PList l' - | PCons (l, r) -> - shrink_pattern l - >|= (fun l' -> PCons (l', r)) - <+> (shrink_pattern r >|= fun r' -> PCons (l, r')) - | PTuple (p1, p2, rest) -> - of_list [ p1; p2 ] - <+> (shrink_pattern p1 >|= fun p1' -> PTuple (p1', p2, rest)) - <+> (shrink_pattern p2 >|= fun p2' -> PTuple (p1, p2', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern rest - >|= fun rest' -> PTuple (p1, p2, rest')) - | PConst lt -> shrink_lt lt >|= fun lt' -> PConst lt' - | POption (Some p) -> return p - | POption None -> empty - | Wild -> empty - | PVar _ -> empty - | PConstraint (p, _) -> return p - | PActive (ident, pattern) -> - shrink_pattern pattern >|= fun pattern' -> PActive (ident, pattern') -;; - -let shrink_statement = - let open QCheck.Iter in - function - | Let (rec_flag, let_bind, let_bind_list) -> - shrink_let_bind let_bind - >|= (fun a' -> Let (rec_flag, a', let_bind_list)) - <+> (QCheck.Shrink.list ~shrink:shrink_let_bind let_bind_list - >|= fun a' -> Let (rec_flag, let_bind, a')) - <+> - (match let_bind_list with - | [] -> empty - | hd :: _ -> return (Let (rec_flag, hd, []))) - | ActPat (name, names, args, expr) -> - shrink_expr expr - >|= (fun expr' -> ActPat (name, names, args, expr')) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern args - >|= fun args' -> ActPat (name, names, args', expr)) - <+> (QCheck.Shrink.list names >|= fun names' -> ActPat (name, names', args, expr)) -;; - -let shrink_construction = - let open QCheck.Iter in - function - | Expr e -> shrink_expr e >|= fun a' -> Expr a' - | Statement s -> - shrink_statement s - >|= (fun a' -> Statement a') - <+> - (match s with - | Let (_, let_bind, let_binds) -> - of_list (exprs_from_let_binds (let_bind :: let_binds)) >|= fun a' -> Expr a' - | ActPat (_, _, _, expr) -> shrink_expr expr >|= fun e' -> Expr e') -;; - -let arbitrary_construction = - QCheck.make - gen_construction - ~print: - (let open Format in - asprintf "%a" (fun fmt c -> - let pp = print_construction in - fprintf fmt "Generated:\n%a" pp c; - match parse (Format.asprintf "%a\n" pp c) with - | Ok parsed -> fprintf fmt "Parsed:\n%a" pp parsed - | Error e -> fprintf fmt "Parsing error:\n%s\n" e)) - ~shrink:shrink_construction -;; - -let run n = - QCheck_base_runner.run_tests - [ QCheck.( - Test.make arbitrary_construction ~count:n (fun c -> - Ok c = parse (Format.asprintf "%a\n" pp_construction c))) - ] -;; diff --git a/FSharpActivePatterns/lib/tests/qcheck_utils.mli b/FSharpActivePatterns/lib/tests/qcheck_utils.mli deleted file mode 100644 index bc2e1b7aa..000000000 --- a/FSharpActivePatterns/lib/tests/qcheck_utils.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run : int -> int diff --git a/FSharpActivePatterns/lib/tests/run_qcheck.ml b/FSharpActivePatterns/lib/tests/run_qcheck.ml deleted file mode 100644 index 441c3ced5..000000000 --- a/FSharpActivePatterns/lib/tests/run_qcheck.ml +++ /dev/null @@ -1,30 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Tests.Qcheck_utils - -(* let generate n = - List.iter - Format.(fprintf std_formatter "%a\n" print_construction) - (QCheck.Gen.generate ~n gen_construction) - ;; *) - -let run_tests n = - let _ = run n in - () -;; - -let () = - Arg.parse - [ "-seed", Arg.Int QCheck_base_runner.set_seed, " Set seed" - ; "-stop", Arg.Unit (fun _ -> exit 0), " Exit" - ; "-gen", Arg.Int run_tests, " Number of runs" - ] - (fun _ -> assert false) - "help" -;; diff --git a/FSharpActivePatterns/lib/typedTree.ml b/FSharpActivePatterns/lib/typedTree.ml deleted file mode 100644 index cb70142f8..000000000 --- a/FSharpActivePatterns/lib/typedTree.ml +++ /dev/null @@ -1,53 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type binder = int [@@deriving show { with_path = false }, qcheck] - -type typ = - | Primitive of (string[@gen gen_primitive]) - | Type_var of binder - | Arrow of typ * typ - | Type_list of typ - | Type_tuple of typ * typ * typ list - | TOption of typ - | TActPat of string * typ (** [Even(int)] *) - | Choice of (string, typ, Base.String.comparator_witness) Base.Map.t - (** [Choice] *) -(* Map of Name/typ is Choice of , Name/typ is equiavalent to TActPat *) - -let choice_to_list ch = - Base.List.map (Base.Map.to_alist ch) ~f:(fun (name, typ) -> TActPat (name, typ)) -;; - -let choice_set_many map list = - Base.List.fold ~init:map list ~f:(fun map (name, typ) -> - Base.Map.set map ~key:name ~data:typ) -;; - -let gen_typ_primitive = - QCheck.Gen.(oneofl [ "string"; "int"; "unit"; "bool" ] >|= fun t -> Primitive t) -;; - -let arrow_of_types first_types last_type = - let open Base in - List.fold_right first_types ~init:last_type ~f:(fun left right -> Arrow (left, right)) -;; - -module VarSet = struct - include Stdlib.Set.Make (Int) - - let pp fmt s = - Format.fprintf fmt "[ "; - iter (Format.fprintf fmt "%d; ") s; - Format.fprintf fmt "]" - ;; -end - -type binder_set = VarSet.t [@@deriving show { with_path = false }] -type scheme = Scheme of binder_set * typ - -let int_typ = Primitive "int" -let bool_typ = Primitive "bool" -let string_typ = Primitive "string" -let unit_typ = Primitive "unit" diff --git a/FSharpActivePatterns/lib/typedTree.mli b/FSharpActivePatterns/lib/typedTree.mli deleted file mode 100644 index 791a8c647..000000000 --- a/FSharpActivePatterns/lib/typedTree.mli +++ /dev/null @@ -1,40 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type binder = int - -type typ = - | Primitive of string - | Type_var of binder - | Arrow of typ * typ - | Type_list of typ - | Type_tuple of typ * typ * typ list - | TOption of typ - | TActPat of string * typ (** [Even(int)] *) - | Choice of (string, typ, Base.String.comparator_witness) Base.Map.t - (** [Choice] *) -(* Map of Name/typ is Choice of , Name/typ is equiavalent to TActPat *) - -val gen_typ_primitive : typ QCheck.Gen.t -val arrow_of_types : typ list -> typ -> typ -val choice_to_list : (string, typ, 'a) Base.Map.t -> typ list - -val choice_set_many - : (string, typ, 'a) Base.Map.t - -> (string * typ) list - -> (string, typ, 'a) Base.Map.t - -module VarSet : sig - include module type of Stdlib.Set.Make (Int) - - val pp : Format.formatter -> t -> unit -end - -type binder_set = VarSet.t -type scheme = Scheme of binder_set * typ - -val int_typ : typ -val bool_typ : typ -val string_typ : typ -val unit_typ : typ diff --git a/FSharpActivePatterns/lib/typesPp.ml b/FSharpActivePatterns/lib/typesPp.ml deleted file mode 100644 index 67a9628c9..000000000 --- a/FSharpActivePatterns/lib/typesPp.ml +++ /dev/null @@ -1,35 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open TypedTree -open Format - -let rec pp_typ fmt = function - | Primitive s -> fprintf fmt "%s" s - | Type_var var -> fprintf fmt "'%d" var - | Arrow (fst, snd) -> - (match fst with - | Arrow _ -> fprintf fmt "(%a) -> %a" pp_typ fst pp_typ snd - | _ -> fprintf fmt "%a -> %a" pp_typ fst pp_typ snd) - | Type_list typ -> fprintf fmt "%a list" pp_typ typ - | Type_tuple (first, second, rest) -> - Format.pp_print_list - ~pp_sep:(fun fmt () -> fprintf fmt " * ") - (fun fmt typ -> - match typ with - | Arrow _ -> fprintf fmt "(%a)" pp_typ typ - | _ -> pp_typ fmt typ) - fmt - (first :: second :: rest) - | TOption t -> - (match t with - | Type_tuple _ | Arrow _ -> fprintf fmt "(%a) option" pp_typ t - | t -> fprintf fmt "%a option" pp_typ t) - | TActPat (name, t) -> fprintf fmt "%s (%a)" name pp_typ t - | Choice map -> - fprintf fmt "Choice<"; - (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt ", ") pp_typ fmt) - (choice_to_list map); - fprintf fmt ">" -;; diff --git a/FSharpActivePatterns/lib/typesPp.mli b/FSharpActivePatterns/lib/typesPp.mli deleted file mode 100644 index 3b4a29818..000000000 --- a/FSharpActivePatterns/lib/typesPp.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2025, Ksenia Kotelnikova , Gleb Nasretdinov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open TypedTree -open Format - -val pp_typ : formatter -> typ -> unit diff --git a/FSharpActivePatterns/tests/activePatterns.t b/FSharpActivePatterns/tests/activePatterns.t deleted file mode 100644 index d70dba74f..000000000 --- a/FSharpActivePatterns/tests/activePatterns.t +++ /dev/null @@ -1,9 +0,0 @@ - $ ../bin/REPL.exe -fromfile activepatterns/choices.fs - 200 - val - : unit = () - val |A|B|C|D| : int * int -> Choice = - - $ ../bin/REPL.exe -fromfile activepatterns/simple.fs - 1 - val - : unit = () - val |MinusTwo|Not| : int -> Choice = diff --git a/FSharpActivePatterns/tests/activepatterns/choices.fs b/FSharpActivePatterns/tests/activepatterns/choices.fs deleted file mode 100644 index 954411ae7..000000000 --- a/FSharpActivePatterns/tests/activepatterns/choices.fs +++ /dev/null @@ -1,9 +0,0 @@ -let (|A|B|C|D|) (a,b) = - if a > 0 then (if b > 0 then A a else B a ) else (if b > 0 then C b else D) - -let res = match (-3, 2) with - | A x -> x - | B x -> x * 10 - | C b -> b * 100 - | D -> 1 - in print_int res diff --git a/FSharpActivePatterns/tests/activepatterns/simple.fs b/FSharpActivePatterns/tests/activepatterns/simple.fs deleted file mode 100644 index 2808a607c..000000000 --- a/FSharpActivePatterns/tests/activepatterns/simple.fs +++ /dev/null @@ -1,8 +0,0 @@ -let (|MinusTwo|Not|) v = - if v+2 = 0 then MinusTwo (v+10) - else Not (v) - -let res = match 1 with - | MinusTwo val -> val - | Not val -> val - in print_int res diff --git a/FSharpActivePatterns/tests/dune b/FSharpActivePatterns/tests/dune deleted file mode 100644 index bbdab9d51..000000000 --- a/FSharpActivePatterns/tests/dune +++ /dev/null @@ -1,39 +0,0 @@ -(cram - (applies_to qcheck) - (deps ../lib/tests/run_qcheck.exe)) - -(cram - (applies_to interpret_manytests) - (deps - ../bin/REPL.exe - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/099.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml)) - -(cram - (applies_to activePatterns) - (deps ../bin/REPL.exe activepatterns/choices.fs activepatterns/simple.fs)) - -(cram - (applies_to interpret) - (deps - ../bin/REPL.exe - interpreter_tests/rev_list.fs - interpreter_tests/fmap.fs)) diff --git a/FSharpActivePatterns/tests/interpret.t b/FSharpActivePatterns/tests/interpret.t deleted file mode 100644 index 59150baf5..000000000 --- a/FSharpActivePatterns/tests/interpret.t +++ /dev/null @@ -1,8 +0,0 @@ - $ ../bin/REPL.exe -fromfile interpreter_tests/rev_list.fs - val - : int list = [3 ; 2 ; 1 ] - val rev_list : '13 list -> '13 list = - - $ ../bin/REPL.exe -fromfile interpreter_tests/fmap.fs - val a : int option = None - val b : int option = Some 24 - val fmap : ('3 -> '6) -> '3 option -> '6 option = diff --git a/FSharpActivePatterns/tests/interpret_manytests.t b/FSharpActivePatterns/tests/interpret_manytests.t deleted file mode 100644 index 5a81086a1..000000000 --- a/FSharpActivePatterns/tests/interpret_manytests.t +++ /dev/null @@ -1,113 +0,0 @@ - $ ../bin/REPL.exe -fromfile manytests/do_not_type/001.ml - Error occured: Undefined variable 'fac' - $ ../bin/REPL.exe -fromfile manytests/do_not_type/002if.ml - Error occured: unification failed on int and bool - - $ ../bin/REPL.exe -fromfile manytests/do_not_type/003occurs.ml - Error occured: Occurs check failed - $ ../bin/REPL.exe -fromfile manytests/do_not_type/004let_poly.ml - Error occured: unification failed on bool and int - - $ ../bin/REPL.exe -fromfile manytests/do_not_type/015tuples.ml - Error occured: Only variables are allowed as left-hand side of `let rec' - $ ../bin/REPL.exe -fromfile manytests/do_not_type/099.ml - Error occured: Only variables are allowed as left-hand side of `let rec' - $ ../bin/REPL.exe -fromfile manytests/typed/001fac.ml - 24 - val fac : int -> int = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/002fac.ml - 24 - val fac_cps : int -> (int -> '7) -> '7 = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/003fib.ml - 3 - 3 - val fib : int -> int = - val fib_acc : int -> int -> int -> int = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - val main : int = 0 - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int = - val test3 : int -> int -> int -> int = - val wrap : '0 -> '0 = - $ ../bin/REPL.exe -fromfile manytests/typed/005fix.ml - 720 - val fac : (int -> int) -> int -> int = - val fix : (('1 -> '5) -> '1 -> '5) -> '1 -> '5 = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/006partial.ml - 1122 - val foo : int -> int = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - val foo : int -> int -> int -> int = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/006partial3.ml - 4 - 8 - 9 - val foo : int -> int -> int -> unit = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int = - val main : unit = () - $ ../bin/REPL.exe -fromfile manytests/typed/008ascription.ml - 8 - val addi : ('0 -> bool -> int) -> ('0 -> bool) -> '0 -> int = - val main : int = 0 - $ ../bin/REPL.exe -fromfile manytests/typed/009let_poly.ml - val temp : int * bool = (1 , true ) - $ ../bin/REPL.exe -fromfile manytests/typed/010sukharev.ml - val _1 : int -> int -> int * '1 -> bool = - val _2 : int = 1 - val _3 : (int * string) option = Some (1 , "hi" ) - val _4 : int -> '14 = - val _42 : int -> bool = - val _5 : int = 42 - val _6 : '30 option -> '30 = - val id1 : '44 -> '44 = - val id2 : '45 -> '45 = - val int_of_option : int option -> int = - $ ../bin/REPL.exe -fromfile manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - val feven : '33 * (int -> int) -> int -> int = - val fix : (('1 -> '5) -> '1 -> '5) -> '1 -> '5 = - val fixpoly : (('21 -> '25) * ('21 -> '25) -> '21 -> '25) * (('21 -> '25) * ('21 -> '25) -> '21 -> '25) -> ('21 -> '25) * ('21 -> '25) = - val fodd : (int -> int) * '41 -> int -> int = - val main : int = 0 - val map : ('9 -> '11) -> '9 * '9 -> '11 * '11 = - val meven : int -> int = - val modd : int -> int = - val tie : (int -> int) * (int -> int) = ( , ) - $ ../bin/REPL.exe -fromfile manytests/typed/016lists.ml - 1 - 2 - 3 - 8 - val append : '67 list -> '67 list -> '67 list = - val cartesian : '98 list -> '105 list -> '98 * '105 list = - val concat : '81 list list -> '81 list = - val iter : ('87 -> unit) -> '87 list -> unit = - val length : '3 list -> int = - val length_tail : '18 list -> int = - val main : int = 0 - val map : ('25 -> '56) -> '25 list -> '56 list = diff --git a/FSharpActivePatterns/tests/interpreter_tests/fmap.fs b/FSharpActivePatterns/tests/interpreter_tests/fmap.fs deleted file mode 100644 index 82c00a43c..000000000 --- a/FSharpActivePatterns/tests/interpreter_tests/fmap.fs +++ /dev/null @@ -1,7 +0,0 @@ -let fmap f = function - | None -> None - | Some x -> Some (f x) - -let a = fmap (fun x -> x + 2) None - -let b = fmap (fun x -> x * 2) (Some 12) diff --git a/FSharpActivePatterns/tests/interpreter_tests/rev_list.fs b/FSharpActivePatterns/tests/interpreter_tests/rev_list.fs deleted file mode 100644 index 102b8425f..000000000 --- a/FSharpActivePatterns/tests/interpreter_tests/rev_list.fs +++ /dev/null @@ -1,8 +0,0 @@ -let rev_list l = - let rec helper acc = function - | [] -> acc - | hd::tl -> helper (hd::acc) tl - in - helper [] l - -rev_list [1;2;3] diff --git a/FSharpActivePatterns/tests/manytests b/FSharpActivePatterns/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/FSharpActivePatterns/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/FSharpActivePatterns/tests/qcheck.t b/FSharpActivePatterns/tests/qcheck.t deleted file mode 100644 index f49c8de5f..000000000 --- a/FSharpActivePatterns/tests/qcheck.t +++ /dev/null @@ -1,4 +0,0 @@ - $ ../lib/tests/run_qcheck.exe -seed 461 -gen 1 -stop - random seed: 461 - ================================================================================ - success (ran 1 tests) diff --git a/FSharpUnitsOfMeasure/FSharpUnitsOfMeasure.opam b/FSharpUnitsOfMeasure.opam similarity index 100% rename from FSharpUnitsOfMeasure/FSharpUnitsOfMeasure.opam rename to FSharpUnitsOfMeasure.opam diff --git a/FSharpUnitsOfMeasure/.envrc b/FSharpUnitsOfMeasure/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/FSharpUnitsOfMeasure/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/FSharpUnitsOfMeasure/.gitignore b/FSharpUnitsOfMeasure/.gitignore deleted file mode 100644 index c78fb0e40..000000000 --- a/FSharpUnitsOfMeasure/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Lambda template -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs - -# Fsharp -test -*.fs -*.fsi - -# Fsharp Ionide -.fake diff --git a/FSharpUnitsOfMeasure/.ocamlformat b/FSharpUnitsOfMeasure/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/FSharpUnitsOfMeasure/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/FSharpUnitsOfMeasure/.zanuda b/FSharpUnitsOfMeasure/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/FSharpUnitsOfMeasure/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/FSharpUnitsOfMeasure/dune b/FSharpUnitsOfMeasure/dune deleted file mode 100644 index 98e54536a..000000000 --- a/FSharpUnitsOfMeasure/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/FSharpUnitsOfMeasure/tests/manytests b/FSharpUnitsOfMeasure/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/FSharpUnitsOfMeasure/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/Go/.gitignore b/Go/.gitignore deleted file mode 100644 index f42283c13..000000000 --- a/Go/.gitignore +++ /dev/null @@ -1,60 +0,0 @@ -# Created by https://www.toptal.com/developers/gitignore/api/linux,ocaml -# Edit at https://www.toptal.com/developers/gitignore?templates=linux,ocaml - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### OCaml ### -*.annot -*.cmo -*.cma -*.cmi -*.a -*.o -*.cmx -*.cmxs -*.cmxa - -# ocamlbuild working directory -_build/ - -# ocamlbuild targets -*.byte -*.native - -# oasis generated files -setup.data -setup.log - -# Merlin configuring file for Vim and Emacs -.merlin - -# Dune generated files -*.install - -# Local OPAM switch -_opam/ - -# End of https://www.toptal.com/developers/gitignore/api/linux,ocaml - -# direnv -.envrc - -# notes -*.notes -*.txt - -# git patch -*.patch \ No newline at end of file diff --git a/Go/.ocamlformat b/Go/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/Go/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/Go/Go.opam b/Go/Go.opam deleted file mode 100644 index 33cb911fd..000000000 --- a/Go/Go.opam +++ /dev/null @@ -1,50 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for a subset of Go" -description: """ -Our interpeter supports: - - int, bool and string data types - - for cycles - - if operator - - arrays - - functions (including recursive and closures) - - channels - - goroutines""" -maintainer: [ - "Karim Shakirov " - "Alexei Dmitrievtsev " -] -authors: [ - "Karim Shakirov " - "Alexei Dmitrievtsev " -] -license: "MIT" -homepage: "https://github.com/kar1mgh/go-interpreter" -bug-reports: "https://github.com/kar1mgh/go-interpreter" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "angstrom" - "qcheck" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "base" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/Go/LICENSE b/Go/LICENSE deleted file mode 100644 index e11e2d37a..000000000 --- a/Go/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Karim Shakirov, Alexei Dmitrievtsev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Go/Makefile b/Go/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/Go/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/Go/bin/dune b/Go/bin/dune deleted file mode 100644 index 8bc6078bf..000000000 --- a/Go/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name interpret) - (public_name repl) - (libraries ast parse typecheck eval errors) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/bin/interpret.ml b/Go/bin/interpret.ml deleted file mode 100644 index f7b33a0f3..000000000 --- a/Go/bin/interpret.ml +++ /dev/null @@ -1,144 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Parse -open Typecheck -open Eval - -type options = - { mutable show_ast : bool - ; mutable run_typecheck : bool - ; mutable file_string : string option - } - -let usage_msg = - "Go subset interpreter\n\n\ - Usage: interpret.exe \n\n\ - If filepath isn't specified, REPL will start running and the program will be read \ - from stdin\n\ - In REPL mode type:\n\n\ - \t\"guit\" - to quit REPL mode\n\ - \t\"help\" - to display this message\n\n\ - Options are:\n\n\ - \t--ast Dump abstract syntax tree of a program\n\ - \t--typecheck Typecheck the program and print result" -;; - -let parse_word word = - let open Angstrom in - let ws = skip_while Base.Char.is_whitespace in - ws *> string word *> ws -;; - -let rec read_repl_input inp_chan = - match In_channel.input_line inp_chan with - | None -> Some (Ok []) - | Some input -> - (match parse (parse_word "help") input with - | Ok () -> - print_endline usage_msg; - flush stdout; - read_repl_input inp_chan - | Error _ -> - (match parse (parse_word "quit") input with - | Ok () -> None - | Error _ -> - (match parse parse_file input with - | Error _ -> Some (Error ()) - | Ok [] -> read_repl_input inp_chan - | Ok ast -> Some (Ok ast)))) -;; - -let run_repl options = - let inp_chan = stdin in - let rec helper read_repl_input = - match read_repl_input inp_chan with - | None -> () - | Some (Error ()) -> - print_endline "Syntax error"; - helper read_repl_input - | Some (Ok ast) -> - print_string "Running..."; - flush stdout; - print_string "\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b"; - if options.show_ast - then ( - print_endline "AST dump:"; - print_endline (show_file ast); - print_newline ()); - let typecheck_result = - match type_check ast with - | Result.Ok _ -> "result: correct" - | Result.Error (Runtime_error _) -> "error: wtf runtime error while typecheck" - | Result.Error (Type_check_error err) -> "error: " ^ Errors.pp_typecheck_error err - in - if options.run_typecheck then print_endline ("Typecheck " ^ typecheck_result); - (match typecheck_result with - | "result: correct" -> - (match eval ast with - | Error (Runtime_error err) -> print_endline (Errors.pp_runtime_error err) - | Ok _ | Error (Type_check_error _) -> ()) - | _ -> - if not options.run_typecheck then print_endline ("Typecheck " ^ typecheck_result)); - flush stdout; - Format.pp_print_flush Format.std_formatter (); - helper read_repl_input - in - helper read_repl_input -;; - -let run_file options string = - match parse parse_file string with - | Error _ -> print_endline "Syntax error" - | Ok ast -> - print_string "Running..."; - flush stdout; - print_string "\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b"; - if options.show_ast - then ( - print_endline "AST dump:"; - print_endline (show_file ast); - print_newline ()); - let typecheck_result = - match type_check ast with - | Result.Ok _ -> "result: correct" - | Result.Error (Runtime_error _) -> "error: wtf runtime error while typecheck" - | Result.Error (Type_check_error err) -> "error: " ^ Errors.pp_typecheck_error err - in - if options.run_typecheck then print_endline ("Typecheck " ^ typecheck_result); - (match typecheck_result with - | "result: correct" -> - (match eval ast with - | Error (Runtime_error err) -> print_endline (Errors.pp_runtime_error err) - | Ok _ | Error (Type_check_error _) -> ()) - | _ -> - if not options.run_typecheck then print_endline ("Typecheck " ^ typecheck_result)); - flush stdout; - Format.pp_print_flush Format.std_formatter () -;; - -let () = - let options = { show_ast = false; run_typecheck = false; file_string = None } in - let arg_list = - [ "--ast", Arg.Unit (fun () -> options.show_ast <- true), "" - ; "--typecheck", Arg.Unit (fun () -> options.run_typecheck <- true), "" - ] - in - let read_file path = - if Sys.file_exists path - then ( - let ch = open_in_bin path in - let string = really_input_string ch (in_channel_length ch) in - close_in ch; - options.file_string <- Some string) - else ( - Printf.eprintf "File %s not found\n" path; - Stdlib.exit 255) - in - Arg.parse arg_list read_file usage_msg; - match options.file_string with - | Some string -> run_file options string - | None -> run_repl options -;; diff --git a/Go/dune b/Go/dune deleted file mode 100644 index 98e54536a..000000000 --- a/Go/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/Go/dune-project b/Go/dune-project deleted file mode 100644 index d5ed3e9ef..000000000 --- a/Go/dune-project +++ /dev/null @@ -1,37 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license MIT) - -(authors - "Karim Shakirov " - "Alexei Dmitrievtsev ") - -(maintainers - "Karim Shakirov " - "Alexei Dmitrievtsev ") - -(bug_reports "https://github.com/kar1mgh/go-interpreter") - -(homepage "https://github.com/kar1mgh/go-interpreter") - -(package - (name Go) - (synopsis "An interpreter for a subset of Go") - (description - "Our interpeter supports:\n - int, bool and string data types\n - for cycles\n - if operator\n - arrays\n - functions (including recursive and closures)\n - channels\n - goroutines") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - angstrom - qcheck - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - base)) diff --git a/Go/lib/ast/ast.ml b/Go/lib/ast/ast.ml deleted file mode 100644 index 478cb7440..000000000 --- a/Go/lib/ast/ast.ml +++ /dev/null @@ -1,227 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -(** Data types *) -type type' = - | Type_int (** Integer type: [int] *) - | Type_string (** String type: [string] *) - | Type_bool (** Boolean type: [bool] *) - | Type_array of int * type' (** Array types such as [[6]int], [[0]string] *) - | Type_func of type' list * type' list - (** Function types such as [func()], [func(string) (bool, int)]. - Empty lists mean that there is no arguments or return values *) - | Type_chan of type' (** chanel type such as [chan int] *) -[@@deriving show { with_path = false }, eq] - -type ident = string [@@deriving show { with_path = false }] - -(** Binary operators *) -type bin_oper = - | Bin_sum (** Binary sum: [+] *) - | Bin_multiply (** Binary multiplication: [*] *) - | Bin_subtract (** Binary subtraction: [-] *) - | Bin_divide (** Binary divison: [/] *) - | Bin_modulus (** Binary division by modulus: [%] *) - | Bin_equal (** Binary check for equality: [==] *) - | Bin_not_equal (** Binary check for inequlity: [!=] *) - | Bin_greater (** Binary "greater than": [>] *) - | Bin_greater_equal (** Binary "greater than or equal": [>=] *) - | Bin_less (** Binary "less than": [<] *) - | Bin_less_equal (** Binary "less than or equal": [<=] *) - | Bin_and (** Binary "and": [&&] *) - | Bin_or (** Binary "or": [||] *) -[@@deriving show { with_path = false }] - -(** Unary operators *) -type unary_oper = - | Unary_not (** Unary negation: [!] *) - | Unary_plus (** Unary plus: [+] *) - | Unary_minus (** Unary minus: [-]*) -[@@deriving show { with_path = false }] - -(** Expressions that can be assigned to a variable or put in "if" statement *) -type expr = - | Expr_const of const (** Constants such as [5], ["hi"], [func()] *) - | Expr_ident of ident (** An identificator for a variable such as [x] *) - | Expr_index of expr * expr - (** An access to an array element by its index such as: [my_array[i]], [get_array(1)[0]]*) - | Expr_bin_oper of bin_oper * expr * expr - (** Binary operations such as [a + b], [x || y] *) - | Expr_un_oper of unary_oper * expr (** Unary operations such as [!z], [-f] *) - | Expr_chan_receive of chan_receive (** See chan_receive type *) - | Expr_call of func_call (** See func_call type *) -[@@deriving show { with_path = false }] - -(** Constants, a.k.a. literals *) -and const = - | Const_int of int (** Integer constants such as [0], [123] *) - | Const_string of string (** Constant strings such as ["my_string"] *) - | Const_array of int * type' * expr list - (** Const arrays such as [[3]int{3, get()}]. - Empty list means that there is no initializers. *) - | Const_func of anon_func (** See anon_func type *) -[@@deriving show { with_path = false }] - -(** An anonymous functions such as: - [func() {}], - [func(a, b int) (int) { sum = a + b; return sum}] - [func(s1 string, s2 string) [2]string { return [2]string{s1,s2} }] *) -and anon_func = - { args : (ident * type') list - (** Function arguments constructions such as: - [func(a int, b string) ...], - [func(a, b int, c string) ...]. - Empty list means that function doesn't take any arguments. - The second example will be processed at parsing - as [func(a int, b int, c string) ...] *) - ; returns : type' list (** Function return types *) - ; body : block (** function body *) - } -[@@deriving show { with_path = false }] - -(** Function arguments, can be either expression or a type *) -and func_arg = - | Arg_expr of expr - | Arg_type of type' -[@@deriving show { with_path = false }] - -(** function calls such as: - [my_func(arg1, arg2)], - [c()()()], - [func() { println("hello") }()]. - Empty list means that function doesn't take any arguments *) -and func_call = expr * func_arg list [@@deriving show { with_path = false }] - -(** chanel receive such as: [<-c], [<-<-get_chan()] *) -and chan_receive = expr [@@deriving show { with_path = false }] - -(** chanel send such as [c <- true] *) -and chan_send = ident * expr [@@deriving show { with_path = false }] - -(** Lvalue in assignments *) -and lvalue = - | Lvalue_ident of ident (** Lvalue of ident such as [my_var] *) - | Lvalue_array_index of lvalue * expr - (** Lvalue of array and index such as: - [array[get_index()]], [array[i][j][k]] *) -[@@deriving show { with_path = false }] - -(** Variable assignments *) -and assign = - | Assign_mult_expr of (lvalue * expr) * (lvalue * expr) list - (** Assignment to a variable with equal number of identifiers and initializers - such as [a = 3], [a, b[0] = 4, 5]. *) - | Assign_one_expr of lvalue * lvalue * lvalue list * func_call - (** Assignment to a variable with multiple lvalues and - one initializer that is a function call such as - [a, b, c[i] = get_three()] *) -[@@deriving show { with_path = false }] - -(** Variable declarations with [var] keyword *) -and long_var_decl = - | Long_decl_no_init of type' * ident * ident list - (** Declarations without initialization such as [var my_int1, my_int2 int] *) - | Long_decl_mult_init of type' option * (ident * expr) * (ident * expr) list - (** Declarations with initializer for each identifier such as: - [var my_func func() = func() {}], - [var a, b int = 1, 2], - [var a, b = 1 + 2, "3"] *) - | Long_decl_one_init of type' option * ident * ident * ident list * func_call - (** Declarations with one initializer that is a function call - for multiple identifiers such as [var a, b, c = get_three()] *) -[@@deriving show { with_path = false }] - -(** Short variable declarations withous [var] keyword - such as [flag, count := true, 0], [a, b := get_two()]. *) -and short_var_decl = - | Short_decl_mult_init of (ident * expr) * (ident * expr) list - (** Declarations with initializer for each identifier such as [flag, count := true, 0] *) - | Short_decl_one_init of ident * ident * ident list * func_call - (** Declarations with one initializer that is a function call - for multiple identifiers such as [a, b := get_two()] *) -[@@deriving show { with_path = false }] - -(** Statements that can be used in if init and for init and post *) -and if_for_init = - | Init_assign of assign (** [a = 0] *) - | Init_decl of short_var_decl (** [a := 0] *) - | Init_incr of ident (** [a++] *) - | Init_decr of ident (** [a--] *) - | Init_call of func_call (** [a()] *) - | Init_send of chan_send (** [c <- 1] *) - | Init_receive of chan_receive (** [<-c] *) -[@@deriving show { with_path = false }] - -(** An if statement such as: - [if a := 5; a >= 4 { - do() - } else { - do_else() - }] *) -and if' = - { if_init : if_for_init option - ; if_cond : expr - ; if_body : block - ; else_body : else_body option (* block or if statement or None *) - } -[@@deriving show { with_path = false }] - -(** Variants of else body in if statement *) -and else_body = - | Else_block of block (** Else body of statement block such as [else {}] *) - | Else_if of if' (** Else body of another if statement such as [else if true {}] *) -[@@deriving show { with_path = false }] - -(** A for statement such as [for i := 0; i < n; i++ { do() }] *) -and for' = - { for_init : if_for_init option - ; for_cond : expr option - ; for_post : if_for_init option - ; for_body : block - } -[@@deriving show { with_path = false }] - -(** Statement, a syntactic unit of imperative programming *) -and stmt = - | Stmt_long_var_decl of long_var_decl (** See long_var_decl type *) - | Stmt_short_var_decl of short_var_decl (** See short_var_decl type *) - | Stmt_assign of assign (** See assign type *) - | Stmt_incr of ident (** An increment of a variable: [a++] *) - | Stmt_decr of ident (** A decrement of a variable: [a--] *) - | Stmt_break (** Break statement: [break] *) - | Stmt_continue (** Continue statement: [continue] *) - | Stmt_return of expr list - (** Return statement such as - [return], [return some_expr], [return expr1, expr2] *) - | Stmt_block of block (** See block type *) - | Stmt_chan_send of chan_send (** chanel send statement such as [c <- true] *) - | Stmt_chan_receive of chan_receive (** See chan_receive type *) - | Stmt_call of func_call (** See func_call type *) - | Stmt_defer of func_call (** Defer statement such as [defer clean()] *) - | Stmt_go of func_call (** Go statement such as [go call()] *) - | Stmt_if of if' (** If statement, see if' type *) - | Stmt_for of for' -[@@deriving show { with_path = false }] - -(** Block of statements in curly braces *) -and block = stmt list [@@deriving show { with_path = false }] - -(** Function declarations such as: - [func sum_and_diff(a, b int) (sum, diff int) { - sum = a + b - diff = a - b - return - }] *) -type func_decl = ident * anon_func [@@deriving show { with_path = false }] - -(** Top-level declarations *) -type top_decl = - | Decl_var of long_var_decl - (** Top level variable declaration such as: [var a int], [var a, b = 1, "hi"] *) - | Decl_func of func_decl - (** Top level function declaration such as: [func f() {}], [func f(a, b int) string {}] *) -[@@deriving show { with_path = false }] - -(** The whole interpreted file, the root of the abstract syntax tree *) -type file = top_decl list [@@deriving show { with_path = false }] diff --git a/Go/lib/ast/dune b/Go/lib/ast/dune deleted file mode 100644 index aa42248a0..000000000 --- a/Go/lib/ast/dune +++ /dev/null @@ -1,6 +0,0 @@ -(library - (name ast) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_deriving.show ppx_deriving.eq))) diff --git a/Go/lib/baseMonad/baseMonad.ml b/Go/lib/baseMonad/baseMonad.ml deleted file mode 100644 index 627b519c0..000000000 --- a/Go/lib/baseMonad/baseMonad.ml +++ /dev/null @@ -1,49 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -type ('st, 'a) t = 'st -> 'st * ('a, Errors.error) Result.t - -let return x st = st, Result.Ok x -let fail e st = st, Result.Error e - -let ( >>= ) x f st = - let st1, x1 = x st in - match x1 with - | Result.Ok x -> f x st1 - | Result.Error x -> fail x st1 -;; - -let ( let* ) = ( >>= ) -let ( *> ) x1 x2 = x1 >>= fun _ -> x2 - -let ( >>| ) x f st = - let st, x = x st in - match x with - | Result.Ok x -> return (f x) st - | Result.Error er -> fail er st -;; - -let iter f = - let f acc el = acc *> f el *> return () in - List.fold_left f (return ()) -;; - -let iter2 f = - let f acc el1 el2 = acc *> f el1 el2 *> return () in - List.fold_left2 f (return ()) -;; - -let map f list = - let f acc el = acc >>= fun acc -> f el >>= fun el -> return (el :: acc) in - List.fold_left f (return []) list >>| List.rev -;; - -let fold_left f acc l = - let f' acc a = acc >>= fun acc -> f acc a >>= return in - List.fold_left f' (return acc) l -;; - -let read st = return st st -let write st_new _ = st_new, Result.Ok () -let run f = f diff --git a/Go/lib/baseMonad/baseMonad.mli b/Go/lib/baseMonad/baseMonad.mli deleted file mode 100644 index cdf7957a9..000000000 --- a/Go/lib/baseMonad/baseMonad.mli +++ /dev/null @@ -1,19 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -type ('st, 'a) t - -val return : 'a -> ('st, 'a) t -val fail : Errors.error -> ('st, 'b) t -val ( >>= ) : ('st, 'a) t -> ('a -> ('st, 'b) t) -> ('st, 'b) t -val ( let* ) : ('st, 'a) t -> ('a -> ('st, 'b) t) -> ('st, 'b) t -val ( *> ) : ('st, 'a) t -> ('st, 'b) t -> ('st, 'b) t -val ( >>| ) : ('st, 'a) t -> ('a -> 'b) -> ('st, 'b) t -val iter : ('a -> ('st, unit) t) -> 'a list -> ('st, unit) t -val iter2 : ('a -> 'b -> ('st, unit) t) -> 'a list -> 'b list -> ('st, unit) t -val map : ('a -> ('st, 'b) t) -> 'a list -> ('st, 'b list) t -val fold_left : ('a -> 'b -> ('st, 'a) t) -> 'a -> 'b list -> ('st, 'a) t -val read : ('st, 'st) t -val write : 'st -> ('st, unit) t -val run : ('st, 'a) t -> 'st -> 'st * ('a, Errors.error) Result.t diff --git a/Go/lib/baseMonad/dune b/Go/lib/baseMonad/dune deleted file mode 100644 index ba8391dba..000000000 --- a/Go/lib/baseMonad/dune +++ /dev/null @@ -1,5 +0,0 @@ -(library - (name baseMonad) - (libraries errors) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/lib/errors/dune b/Go/lib/errors/dune deleted file mode 100644 index 40b031fa4..000000000 --- a/Go/lib/errors/dune +++ /dev/null @@ -1,4 +0,0 @@ -(library - (name errors) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/lib/errors/errors.ml b/Go/lib/errors/errors.ml deleted file mode 100644 index 6a8da7bcd..000000000 --- a/Go/lib/errors/errors.ml +++ /dev/null @@ -1,55 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -type type_check_error = - | Incorrect_main of string - | Multiple_declaration of string - | Undefined_ident of string - | Mismatched_types of string - | Cannot_assign of string - | Missing_return of string - | Go_make - | Invalid_operation of string - | Unexpected_operation of string - -type runtime_error = - | Division_by_0 - | Array_index_out_of_bound - | Negative_array_index - | Uninited_func - | Deadlock of string - | Close_of_closed_chan - | Close_of_nil_chan - | Panic of string - | TypeCheckFailed of string - | Dev of string - -type error = - | Type_check_error of type_check_error - | Runtime_error of runtime_error - -let pp_typecheck_error = function - | Multiple_declaration msg -> "Multiple declaration error: " ^ msg - | Incorrect_main msg -> "Incorrect main error: " ^ msg - | Undefined_ident msg -> "Undefined ident error: " ^ msg - | Mismatched_types msg -> "Mismatched types: " ^ msg - | Cannot_assign msg -> "Cannot assign: " ^ msg - | Missing_return msg -> "Missing return: " ^ msg - | Invalid_operation msg -> "Invalid operation: " ^ msg - | Go_make -> "Go discards result of make builtin function" - | Unexpected_operation msg -> "Unexpected operation: " ^ msg -;; - -let pp_runtime_error = function - | Division_by_0 -> "division by zero" - | Array_index_out_of_bound -> "array index out of bounds" - | Negative_array_index -> "negative array index call" - | Uninited_func -> "uninitialized function call" - | Close_of_closed_chan -> "close of closed chanel" - | Close_of_nil_chan -> "close of uninitialized chanel" - | Deadlock msg -> "Deadlock: " ^ msg - | Panic msg -> "Panic: " ^ msg - | TypeCheckFailed msg -> "Type error in runtime: " ^ msg - | Dev msg -> "Dev: " ^ msg -;; diff --git a/Go/lib/errors/errors.mli b/Go/lib/errors/errors.mli deleted file mode 100644 index 3f4bf75f2..000000000 --- a/Go/lib/errors/errors.mli +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -type type_check_error = - | Incorrect_main of string (** No main/main with returns or args *) - | Multiple_declaration of string (** Multiple declaration of ident *) - | Undefined_ident of string (** No declaration of ident in current sapce *) - | Mismatched_types of string (** Mismatched types in binoper/assign/return... *) - | Cannot_assign of string (** Error with assigning a multiple-return value *) - | Missing_return of string (** Error with missing return of values in func *) - | Go_make (** trying to run [make] builtin func as a goroutine ([go make(chan int)]) *) - | Invalid_operation of string (**Error with doing some invalid operation *) - | Unexpected_operation of string (**Return/continue not inside for body *) - -type runtime_error = - | Division_by_0 - | Array_index_out_of_bound - | Negative_array_index - | Uninited_func - | Deadlock of string - | Close_of_closed_chan - | Close_of_nil_chan - | Panic of string - | TypeCheckFailed of string - | Dev of string - -type error = - | Type_check_error of type_check_error - | Runtime_error of runtime_error - -val pp_typecheck_error : type_check_error -> string -val pp_runtime_error : runtime_error -> string diff --git a/Go/lib/eval/dune b/Go/lib/eval/dune deleted file mode 100644 index 8118a3276..000000000 --- a/Go/lib/eval/dune +++ /dev/null @@ -1,5 +0,0 @@ -(library - (name eval) - (libraries base ast baseMonad ppType) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/lib/eval/eval.ml b/Go/lib/eval/eval.ml deleted file mode 100644 index 998956829..000000000 --- a/Go/lib/eval/eval.ml +++ /dev/null @@ -1,713 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open EvalMonad -open EvalMonad.Monad -open Ast -open Format - -let rec pp_value = function - | Value_int n -> asprintf "%d" n - | Value_bool b -> asprintf "%b" b - | Value_nil Nil -> "" - | Value_array (_, values) -> asprintf "[%s]" (PpType.sep_by_comma values pp_value) - | Value_chan chan -> - (match chan with - | Chan_uninitialized Nil -> "" - | Chan_initialized id -> asprintf "" id) - | Value_func func -> - (match func with - | Func_uninitialized Nil -> "" - | _ -> "") - | Value_string s -> s - | Value_tuple values -> PpType.sep_by_comma values pp_value -;; - -let rpf lst = List.map (fun (y, _) -> y) lst - -(** Executes next statement, returns [Some ()] if there was statement to execute, - and [None] if the end of current execution block was reached *) -let exec_stmt eval_stmt = - pop_next_statement - >>= function - | Some st -> eval_stmt st *> return (Some ()) - | None -> return None -;; - -let rec replace_list list index elem = - match list with - | [] -> list - | h :: t -> - if index = 0 - then elem :: replace_list t (index - 1) elem - else h :: replace_list t (index - 1) elem -;; - -(** Executes current execution block. Stops when its end reached, or when [return] - statement was executed, when some chanel started to be used - and when current goroutine is panicking *) -let rec exec eval_stmt = - exec_stmt eval_stmt - >>= function - | None -> return () - | Some () -> - is_using_chanel - >>= (function - | Some _ -> return () - | None -> - read_returns - >>= (function - | Some _ -> return () - | None -> - read_panics - >>= (function - | Some _ -> return () - | None -> exec eval_stmt))) -;; - -let rec skip_local_env (hd, tl) = - match hd.env_type with - | For -> return (hd :: tl) - | Default -> - skip_local_env (List.hd tl, List.tl tl) - >>= fun sk -> return ({ hd with exec_block = [] } :: sk) -;; - -(** Runs all ready to run goroutines, after it returns it is guaranteed that all existing goroutines - are working with chanels. If main goroutine finishes executing here, the whole program finishes running *) -let run_ready_goroutines eval_stmt = - let rec runner () = - run_ready_goroutine - >>= function - | None -> return () - | Some () -> - exec eval_stmt *> is_using_chanel - >>= (function - | Some _ -> - return () - (* chanel is being used, so we need to return to receiver to receive the value *) - | None -> - (* goroutine finished executing *) - (read_panics - >>= function - | Some pnc -> fail (Runtime_error (Panic (pp_value (Value_tuple pnc)))) - | None -> return ()) - *> read_running_fail - >>= (function - | { go_id = 1; _ } -> - (* main goroutine finished working and doesn't wait for others to finish *) - return () - | _ -> - (* some secondary goroutine finished working, don't stop until main finished *) - delete_running_goroutine *> runner ())) - in - runner () -;; - -(** [attempt_chan_interaction id] attempts to use chanel with given id. If both - sender and receiver are ready, starts using the chanel. Doesn't do anything otherwise *) -let attempt_chan_interaction id inited_by = - let* ready_to_send = is_send_queue_not_empty id in - let* ready_to_receive = is_receive_queue_not_empty id in - match ready_to_send, ready_to_receive with - | Some (), Some () -> - let* sending_goroutine, value = pop_from_send_queue id in - let* receiving_goroutine = pop_from_receive_queue id in - start_using_chanel { sending_goroutine; receiving_goroutine; value; inited_by } - (* receiving goroutine will run after return from a function *) - | _ -> return () -;; - -let rec eval_expr = function - | Expr_const (Const_int n) -> return (Value_int n) - | Expr_const (Const_string s) -> return (Value_string s) - | Expr_const (Const_array (size, _, exprs)) -> - map eval_expr exprs >>= fun values -> return (Value_array (size, values)) - | Expr_const (Const_func afunc) -> - return (Value_func (Func_initialized (FuncLit, afunc))) - | Expr_bin_oper (op, a1, a2) -> eval_binop op a1 a2 - | Expr_un_oper (op, a) -> eval_unop op a - | Expr_ident id -> read_ident id - | Expr_index (array, index) -> eval_index array index - | Expr_call (func, args) -> - eval_expr func - >>= (function - | Value_func (Func_initialized (Closure _, afc)) -> - eval_closure (func, args) - >>= fun (ret, vmp) -> - (match func with - | Expr_ident id -> - update_ident id (Value_func (Func_initialized (Closure vmp, afc))) - | _ -> return ()) - *> - (match ret with - | Some lst -> return lst - | _ -> fail (Runtime_error (TypeCheckFailed "expr"))) - | _ -> - eval_func_call (func, args) - >>= (function - | Some lst -> return lst - | _ -> fail (Runtime_error (TypeCheckFailed "expr")))) - | Expr_chan_receive receive -> eval_chan_receive receive - -and eval_func_call (func, args) = - eval_expr func - >>= function - | Value_func (Func_uninitialized _) -> fail (Runtime_error Uninited_func) - | Value_func (Func_builtin ftype) -> eval_builtin args ftype - | Value_func (Func_initialized (Default, afc)) -> - create_args_map args (rpf afc.args) - >>= fun map -> - add_stack_frame - { local_envs = { exec_block = afc.body; var_map = map; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - *> exec eval_stmt - *> read_returns - >>= fun x -> - (read_deferred >>= iter eval_deferred_func) *> read_panics - >>= fun panics -> delete_stack_frame *> write_panics panics *> return x - | Value_func (Func_initialized (FuncLit, afc)) -> - let* local_envs = read_local_envs >>= fun (fl, lstl) -> return (fl :: lstl) in - create_args_map args (rpf afc.args) - >>= fun map -> - add_stack_frame - { local_envs = - { exec_block = afc.body; var_map = map; env_type = Default }, local_envs - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - *> exec eval_stmt - *> read_returns - >>= fun x -> - read_local_envs - >>= fun (_, lenv) -> - (read_deferred >>= iter eval_deferred_func) *> read_panics - >>= fun panics -> - delete_stack_frame - *> write_panics panics - *> write_local_envs (List.hd lenv, List.tl lenv) - *> return x - | _ -> fail (Runtime_error (TypeCheckFailed "defer func_call")) - -and eval_closure (func, args) = - eval_expr func - >>= function - | Value_func (Func_initialized (Closure vmap, afc)) -> - let* local_envs = read_local_envs >>= fun (fl, lstl) -> return (fl :: lstl) in - create_args_map args (rpf afc.args) - >>= fun map -> - add_stack_frame - { local_envs = - ( { exec_block = afc.body; var_map = map; env_type = Default } - , { exec_block = []; var_map = vmap; env_type = Default } :: local_envs ) - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - *> exec eval_stmt - *> read_panics - >>= fun panics -> - write_panics panics *> read_returns - >>= fun x -> - read_local_envs - >>= fun (_, lenv) -> - (read_deferred >>= iter eval_deferred_func) *> read_panics - >>= fun panics -> - delete_stack_frame - *> write_panics panics - *> write_local_envs (List.hd (List.tl lenv), List.tl (List.tl lenv)) - *> return (x, (List.hd lenv).var_map) - | _ -> fail (Runtime_error (TypeCheckFailed "closure_call")) - -and eval_deferred_func (vfunc, vargs) = - match vfunc with - | Value_func (Func_uninitialized _) -> fail (Runtime_error Uninited_func) *> return () - | Value_func (Func_builtin ftype) -> prepare_builtin_eval vargs ftype *> return () - | Value_func (Func_initialized (Default, afc)) -> - let rec save_args map = function - | [] -> return map - | (vl, id) :: tl -> save_args (MapIdent.add id vl map) tl - in - let* panics = read_panics in - save_args MapIdent.empty (List.combine vargs (rpf afc.args)) - >>= fun map -> - add_stack_frame - { local_envs = { exec_block = afc.body; var_map = map; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics - } - *> exec eval_stmt - *> read_returns - *> read_panics - >>= fun panics -> delete_stack_frame *> write_panics panics *> return () - | Value_func (Func_initialized (FuncLit, afc)) -> - let* local_envs = read_local_envs >>= fun (fl, lstl) -> return (fl :: lstl) in - let rec save_args map = function - | [] -> return map - | (vl, id) :: tl -> save_args (MapIdent.add id vl map) tl - in - let* panics = read_panics in - save_args MapIdent.empty (List.combine vargs (rpf afc.args)) - >>= fun map -> - add_stack_frame - { local_envs = - { exec_block = afc.body; var_map = map; env_type = Default }, local_envs - ; deferred_funcs = [] - ; returns = None - ; panics - } - *> exec eval_stmt - *> read_returns - *> read_local_envs - >>= fun (_, lenv) -> - read_panics - >>= fun panics -> - delete_stack_frame - *> write_panics panics - *> write_local_envs (List.hd lenv, List.tl lenv) - *> return () - | _ -> fail (Runtime_error (TypeCheckFailed "func_call")) - -and retrieve_arg_value = function - | Arg_expr e -> eval_expr e - | Arg_type _ -> fail (Runtime_error (TypeCheckFailed "arg_value")) - -and create_args_map args idents = - let rec save_args map = function - | [] -> return map - | (expr, id) :: tl -> - retrieve_arg_value expr >>= fun vl -> save_args (MapIdent.add id vl map) tl - in - save_args MapIdent.empty (List.combine args idents) - -and eval_builtin args func = - match func with - | Make -> prepare_builtin_eval [] Make - | _ -> map retrieve_arg_value args >>= fun vlst -> prepare_builtin_eval vlst func - -and prepare_builtin_eval vlist = function - | Print -> - let list = List.map pp_value vlist in - return (print_string (String.concat " " list)) *> return None - | Println -> - let list = List.map pp_value vlist in - return (print_string (String.concat " " list ^ "\n")) *> return None - | Make -> - let* chan_id = create_chanel in - return (Some (Value_chan (Chan_initialized chan_id))) - | Close -> - (match vlist with - | [ Value_chan chan ] -> close_chanel chan *> return None - | _ -> fail (Runtime_error (TypeCheckFailed "close"))) - | Len -> - (match vlist with - | [ Value_array (len, _) ] -> return (Some (Value_int len)) - | [ Value_string s ] -> return (Some (Value_int (String.length s))) - | _ -> fail (Runtime_error (TypeCheckFailed "len"))) - | Panic -> write_panics (Some vlist) *> return None - | Recover -> - read_panics - >>= fun pnc -> - write_panics None - *> - (match pnc with - | Some [ single_srg ] -> return (Some single_srg) - | Some lst -> return (Some (Value_tuple lst)) - | None -> return (Some (Value_nil Nil))) - -and eval_index array index = - let* array = eval_expr array in - let* index = eval_expr index in - match array, index with - | Value_array (_, values), Value_int index -> - (try return (List.nth values index) with - | Invalid_argument _ -> fail (Runtime_error Negative_array_index) - | Failure _ -> fail (Runtime_error Array_index_out_of_bound)) - | _ -> fail (Runtime_error (TypeCheckFailed "index")) - -and eval_unop op expr = - let* value = eval_expr expr in - match op, value with - | Unary_minus, Value_int a -> return (Value_int (-a)) - | Unary_plus, Value_int a -> return (Value_int a) - | Unary_not, Value_bool a -> return (Value_bool (not a)) - | _ -> fail (Runtime_error (TypeCheckFailed "unop")) - -and eval_equal = function - | Value_nil Nil, Value_nil Nil - | Value_nil Nil, Value_func (Func_uninitialized Nil) - | Value_nil Nil, Value_chan (Chan_uninitialized Nil) - | Value_func (Func_uninitialized Nil), Value_nil Nil - | Value_chan (Chan_uninitialized Nil), Value_nil Nil -> true - | Value_nil Nil, _ | _, Value_nil Nil -> false - | v1, v2 -> v1 = v2 - -and eval_binop op a1 a2 = - let* a1 = eval_expr a1 in - let* a2 = eval_expr a2 in - match op, a1, a2 with - | Bin_sum, Value_int a1, Value_int a2 -> return (Value_int (a1 + a2)) - | Bin_subtract, Value_int a1, Value_int a2 -> return (Value_int (a1 - a2)) - | Bin_multiply, Value_int a1, Value_int a2 -> return (Value_int (a1 * a2)) - | Bin_divide, Value_int a1, Value_int a2 -> - (try return (Value_int (a1 / a2)) with - | Division_by_zero -> fail (Runtime_error Division_by_0)) - | Bin_modulus, Value_int a1, Value_int a2 -> - (try return (Value_int (a1 mod a2)) with - | Division_by_zero -> fail (Runtime_error Division_by_0)) - | Bin_and, Value_bool a1, Value_bool a2 -> return (Value_bool (a1 && a2)) - | Bin_or, Value_bool a1, Value_bool a2 -> return (Value_bool (a1 || a2)) - | Bin_equal, a1, a2 -> return (Value_bool (eval_equal (a1, a2))) - | Bin_not_equal, a1, a2 -> return (Value_bool (not (eval_equal (a1, a2)))) - | Bin_less, Value_int a1, Value_int a2 -> return (Value_bool (a1 < a2)) - | Bin_less_equal, Value_int a1, Value_int a2 -> return (Value_bool (a1 <= a2)) - | Bin_greater, Value_int a1, Value_int a2 -> return (Value_bool (a1 > a2)) - | Bin_greater_equal, Value_int a1, Value_int a2 -> return (Value_bool (a1 >= a2)) - | _ -> fail (Runtime_error (TypeCheckFailed "binop")) - -and update_lvalue value = function - | Lvalue_ident id -> update_ident id value - | lvalue -> - let* lvalue_value, indicies = collect_lvalue_indicies [] lvalue in - let* new_lvalue = change_lvalue_index lvalue_value indicies value in - update_ident (retrieve_lvalue_ident lvalue) new_lvalue - -and collect_lvalue_indicies acc = function - | Lvalue_ident id -> - let* lvalue_value = read_ident id in - return (lvalue_value, acc) - | Lvalue_array_index (array, index) -> - eval_expr index - >>= (function - | Value_int i -> collect_lvalue_indicies (i :: acc) array - | _ -> fail (Runtime_error (TypeCheckFailed "prepare lvalue"))) - -and retrieve_lvalue_ident = function - | Lvalue_ident id -> id - | Lvalue_array_index (lv, _) -> retrieve_lvalue_ident lv - -and change_lvalue_index target indicies value = - match target with - | Value_array (size, values) -> - (match indicies with - | [ i ] -> return (Value_array (i, replace_list values i value)) - | _ -> - (try - change_lvalue_index - (List.nth values (List.hd indicies)) - (List.tl indicies) - value - >>= fun ls -> - return (Value_array (size, replace_list values (List.hd indicies) ls)) - with - | Failure _ -> fail (Runtime_error Array_index_out_of_bound) - | Invalid_argument _ -> fail (Runtime_error Negative_array_index))) - | _ -> return target - -and eval_init = function - | Some init -> - (match init with - | Init_assign asgn -> eval_stmt (Stmt_assign asgn) - | Init_call call -> eval_stmt (Stmt_call call) - | Init_decl decl -> eval_stmt (Stmt_short_var_decl decl) - | Init_decr decr -> eval_stmt (Stmt_decr decr) - | Init_incr incr -> eval_stmt (Stmt_incr incr) - | Init_receive recv -> eval_chan_receive recv *> return () - | Init_send send -> eval_chan_send send) - | None -> return () - -and eval_stmt = function - | Stmt_call call -> eval_stmt_call call - | Stmt_long_var_decl lvd -> eval_long_var_decl save_local_id lvd - | Stmt_decr id -> - read_ident id - >>= (function - | Value_int v -> update_ident id (Value_int (v - 1)) *> return () - | _ -> fail (Runtime_error (TypeCheckFailed "stmt"))) - | Stmt_incr id -> - read_ident id - >>= (function - | Value_int v -> update_ident id (Value_int (v + 1)) *> return () - | _ -> fail (Runtime_error (TypeCheckFailed "stmt"))) - | Stmt_assign asgn -> eval_assign asgn - | Stmt_short_var_decl decl -> eval_short_var_decl decl - | Stmt_if if' -> eval_if if' - | Stmt_go call -> eval_go call - | Stmt_block body -> add_env body Default *> exec eval_stmt *> delete_env - | Stmt_break -> exec eval_stmt *> delete_env - | Stmt_continue -> - (read_local_envs - >>= skip_local_env - >>= fun lst -> write_local_envs (List.hd lst, List.tl lst)) - *> return () - | Stmt_for for' -> eval_for for' - | Stmt_return exprs -> eval_return exprs - | Stmt_chan_send send -> eval_chan_send send - | Stmt_chan_receive recv -> eval_chan_receive recv *> return () - | Stmt_defer (func, args) -> - eval_expr func - >>= fun func_value -> - map retrieve_arg_value args >>= fun arg_values -> add_deferred (func_value, arg_values) - -and eval_stmt_call (func, args) = - eval_expr func - >>= function - | Value_func (Func_initialized (Closure _, afc)) -> - eval_closure (func, args) - >>= fun (_, vmp) -> - (match func with - | Expr_ident id -> update_ident id (Value_func (Func_initialized (Closure vmp, afc))) - | _ -> return ()) - | _ -> eval_func_call (func, args) *> return () - -and eval_short_var_decl = function - | Short_decl_mult_init (sfirst, lst) -> - iter (fun (ident, expr) -> eval_expr expr >>= save_local_id ident) (sfirst :: lst) - | Short_decl_one_init (idnt1, idnt2, idntlst, fcall) -> - eval_func_call fcall - >>= (function - | Some (Value_tuple tup) -> iter2 save_local_id (idnt1 :: idnt2 :: idntlst) tup - | _ -> fail (Runtime_error (TypeCheckFailed "short decl"))) - -and eval_if { if_init; if_cond; if_body; else_body } = - eval_init if_init *> eval_expr if_cond - >>= function - | Value_bool true -> add_env if_body Default *> exec eval_stmt *> delete_env - | Value_bool false -> - (match else_body with - | Some (Else_block body) -> add_env body Default *> exec eval_stmt *> delete_env - | Some (Else_if if') -> eval_stmt (Stmt_if if') - | None -> return ()) - | _ -> fail (Runtime_error (TypeCheckFailed "if")) - -and eval_long_var_decl save_to_env = function - | Long_decl_mult_init (_, hd, tl) -> - iter (fun (ident, expr) -> eval_expr expr >>= save_to_env ident) (hd :: tl) - | Long_decl_one_init (_, idnt1, idnt2, idntlst, fcall) -> - eval_func_call fcall - >>= (function - | Some (Value_tuple tup) -> iter2 save_to_env (idnt1 :: idnt2 :: idntlst) tup - | _ -> fail (Runtime_error (TypeCheckFailed "short decl"))) - | Long_decl_no_init (typ, id, id_list) -> - iter (fun idnt -> save_to_env idnt (default_init typ)) (id :: id_list) - -and eval_assign = function - | Assign_mult_expr (fst, lst) -> - iter - (fun (lvalue, expr) -> eval_expr expr >>= fun ex -> update_lvalue ex lvalue) - (fst :: lst) - | Assign_one_expr (fst, snd, lst, fcall) -> - eval_func_call fcall - >>= (function - | Some (Value_tuple tup) -> - iter2 (fun v lv -> update_lvalue v lv *> return ()) tup (fst :: snd :: lst) - | _ -> fail (Runtime_error (TypeCheckFailed "short decl"))) - -and eval_for { for_init; for_cond; for_post; for_body } = - let one_iter = - match for_cond with - | Some cond -> - eval_expr cond - >>= (function - | Value_bool true -> - add_env for_body Default - *> exec eval_stmt - *> eval_init for_post - *> delete_env - *> return true - | Value_bool false -> delete_env *> return false - | _ -> fail (Runtime_error (TypeCheckFailed "for cond"))) - | None -> - add_env for_body Default - *> exec eval_stmt - *> eval_init for_post - *> delete_env - *> return true - in - let rec cycle rfor = - rfor - >>= function - | true -> - read_local_envs - >>= fun ({ env_type; _ }, _) -> - (match env_type with - | For -> cycle rfor - | Default -> return ()) - | false -> return () - in - add_env [] For *> eval_init for_init *> cycle one_iter - -and eval_return = function - | [ Expr_const (Const_func afc) ] -> - read_local_envs - >>= (fun (hd, _) -> return (Value_func (Func_initialized (Closure hd.var_map, afc)))) - >>= fun vfun -> write_returns (Some vfun) - | [ expr ] -> eval_expr expr >>= fun ret -> write_returns (Some ret) - | exprs -> - map eval_expr exprs >>= fun values -> write_returns (Some (Value_tuple values)) - -and default_init = function - | Type_int -> Value_int 0 - | Type_bool -> Value_bool false - | Type_string -> Value_string "" - | Type_func _ -> Value_func (Func_uninitialized Nil) - | Type_chan _ -> Value_chan (Chan_uninitialized Nil) - | Type_array (size, t) -> Value_array (size, List.init size (fun _ -> default_init t)) - -and eval_chan_send (ident, expr) = - let* value = eval_expr expr in - read_ident ident - >>= function - | Value_chan chan -> - let* chan_id = find_chanel_fail chan in - let* sending_goroutine = read_running_fail in - delete_running_goroutine - *> push_to_send_queue chan_id sending_goroutine value - *> attempt_chan_interaction chan_id Sender - *> (is_using_chanel - >>= function - | Some _ -> return () - | None -> - check_ready_goroutine - >>= (function - | None -> - fail - (Runtime_error - (Deadlock - (asprintf - "goroutine %d trying to send to chan %d" - sending_goroutine.go_id - chan_id))) - | Some _ -> run_ready_goroutines eval_stmt)) - | _ -> fail (Runtime_error (TypeCheckFailed "chan send")) - -and eval_chan_receive expr = - eval_expr expr - >>= function - | Value_chan chan -> - let* chan_id = find_chanel_fail chan in - let* receiving_goroutine = read_running_fail in - delete_running_goroutine - *> push_to_receive_queue chan_id receiving_goroutine - *> attempt_chan_interaction chan_id Receiver - *> (is_using_chanel - >>= function - | Some _ -> return () - | None -> - run_ready_goroutines eval_stmt *> is_using_chanel - >>= (function - | Some _ -> return () - | None -> - fail - (Runtime_error - (Deadlock - (asprintf - "goroutine %d trying to receive from chan %d" - receiving_goroutine.go_id - chan_id))))) - *> - let* { receiving_goroutine; sending_goroutine; value; inited_by } = use_chanel in - (match inited_by with - | Receiver -> - add_ready sending_goroutine *> run_goroutine receiving_goroutine *> return value - | Sender -> run_goroutine receiving_goroutine *> return value) - | _ -> fail (Runtime_error (TypeCheckFailed "chan receive")) - -and eval_go (func, arg_exprs) = - eval_expr func - >>= function - | Value_func (Func_uninitialized Nil) -> fail (Runtime_error Uninited_func) - | Value_func (Func_builtin _) -> eval_func_call (func, arg_exprs) *> return () - | Value_func (Func_initialized (Default, { args; body; _ })) - | Value_func (Func_initialized (FuncLit, { args; body; _ })) -> - let* var_map = create_args_map arg_exprs (rpf args) in - create_goroutine - { local_envs = { exec_block = body; var_map; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - | Value_func (Func_initialized (Closure closure_map, { args; body; _ })) -> - let* var_map = create_args_map arg_exprs (rpf args) in - let var_map = MapIdent.union (fun _key v1 _v2 -> Some v1) var_map closure_map in - create_goroutine - { local_envs = { exec_block = body; var_map; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - | _ -> fail (Runtime_error (TypeCheckFailed "func call")) -;; - -let save_builtins = - save_global_id "true" (Value_bool true) - *> save_global_id "false" (Value_bool false) - *> save_global_id "nil" (Value_nil Nil) - *> save_global_id "print" (Value_func (Func_builtin Print)) - *> save_global_id "println" (Value_func (Func_builtin Println)) - *> save_global_id "make" (Value_func (Func_builtin Make)) - *> save_global_id "close" (Value_func (Func_builtin Close)) - *> save_global_id "len" (Value_func (Func_builtin Len)) - *> save_global_id "recover" (Value_func (Func_builtin Recover)) - *> save_global_id "panic" (Value_func (Func_builtin Panic)) -;; - -let save_global_vars_and_funcs file = - save_builtins - *> create_goroutine (* goroutine for global variables evaluating *) - { local_envs = - { exec_block = []; var_map = MapIdent.empty; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - *> run_ready_goroutine - *> iter - (function - | Decl_var decl -> eval_long_var_decl save_global_id decl - | Decl_func (ident, afc) -> - save_global_id ident (Value_func (Func_initialized (Default, afc)))) - file - *> delete_running_goroutine -;; - -let add_main_goroutine = - iter (function - | Decl_func ("main", { body; _ }) -> - create_goroutine - { local_envs = - { exec_block = body; var_map = MapIdent.empty; env_type = Default }, [] - ; deferred_funcs = [] - ; returns = None - ; panics = None - } - | _ -> return ()) -;; - -let init_state = - { global_env = MapIdent.empty - ; running = None - ; ready = ReadySet.empty - ; sending = SendingSet.empty - ; receiving = ReceivingSet.empty - ; chanels = ChanSet.empty, 1 - ; is_using_chanel = None - ; next_go_id = 0 - } -;; - -let eval file = - run - (save_global_vars_and_funcs file - *> add_main_goroutine file - *> run_ready_goroutines eval_stmt) - init_state - |> function - | _, res -> res -;; diff --git a/Go/lib/eval/eval.mli b/Go/lib/eval/eval.mli deleted file mode 100644 index aef6de240..000000000 --- a/Go/lib/eval/eval.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val eval : Ast.file -> (unit, Errors.error) result diff --git a/Go/lib/eval/evalMonad.ml b/Go/lib/eval/evalMonad.ml deleted file mode 100644 index 04cebe568..000000000 --- a/Go/lib/eval/evalMonad.ml +++ /dev/null @@ -1,662 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -module Ident = struct - type t = ident - - let compare = compare -end - -module MapIdent = struct - include Map.Make (Ident) -end - -type nil = Nil - -type chan_value = - | Chan_initialized of int (** Initialized chanel, identified by id *) - | Chan_uninitialized of nil - -type builtin = - | Print - | Println - | Make - | Close - | Recover - | Len - | Panic - -type value = - | Value_int of int - | Value_string of string - | Value_bool of bool - | Value_array of int * value list - | Value_func of func_value - | Value_chan of chan_value - | Value_tuple of value list - | Value_nil of nil - -and func_type = - | Closure of value MapIdent.t - | FuncLit - | Default - -and func_value = - | Func_initialized of func_type * anon_func - | Func_uninitialized of nil - | Func_builtin of builtin - -type is_for_env = - | For - | Default - -type local_env = - { exec_block : block - ; var_map : value MapIdent.t - ; env_type : is_for_env - } - -type defered_frame = value * value list - -type stack_frame = - { local_envs : local_env * local_env list - ; deferred_funcs : defered_frame list - ; returns : value option - ; panics : value list option - } - -type goroutine = - { stack : stack_frame * stack_frame list - ; go_id : int - } - -module Goroutine = struct - type t = goroutine - - let compare = compare -end - -module SendingGoroutines = struct - type t = - { send_queue : (goroutine * value) list - ; chan_id : int - } - - let compare = compare -end - -module ReceivingGoroutines = struct - type t = - { receive_queue : goroutine list - ; chan_id : int - } - - let compare = compare -end - -module Chan = struct - type t = - { chan_id : int - ; value : value option - } - - let compare = compare -end - -module ReadySet = Set.Make (Goroutine) -module SendingSet = Set.Make (SendingGoroutines) -module ReceivingSet = Set.Make (ReceivingGoroutines) -module ChanSet = Set.Make (Chan) - -type inited_by = - | Sender - | Receiver - -type chanel_using_state = - { sending_goroutine : goroutine - ; receiving_goroutine : goroutine - ; value : value - ; inited_by : inited_by - } - -type eval_state = - { global_env : value MapIdent.t - ; running : goroutine option - ; ready : ReadySet.t - ; sending : SendingSet.t - ; receiving : ReceivingSet.t - ; chanels : ChanSet.t * int - ; is_using_chanel : chanel_using_state option - ; next_go_id : int - } - -module Monad = struct - include BaseMonad - - type 'a t = (eval_state, 'a) BaseMonad.t - - (* global env *) - - let read_global = - read - >>= function - | { global_env; _ } -> return global_env - ;; - - let write_global global_env = read >>= fun state -> write { state with global_env } - - let save_global_id ident value = - let* global = read_global in - write_global (MapIdent.add ident value global) - ;; - - (* goroutines *) - - let read_running = - read - >>= function - | { running; _ } -> return running - ;; - - let read_running_fail = - read - >>= function - | { running = Some goroutine; _ } -> return goroutine - | { running = None; _ } -> fail (Runtime_error (Dev "no goroutine running")) - ;; - - let write_running running = read >>= fun state -> write { state with running } - - let read_ready = - read - >>= function - | { ready; _ } -> return ready - ;; - - let write_ready ready = read >>= fun state -> write { state with ready } - - let add_ready goroutine = - let* goroutines = read_ready in - write_ready (ReadySet.add goroutine goroutines) - ;; - - let delete_ready { go_id; _ } = - let* goroutines = read_ready in - match - ReadySet.find_first_opt - (function - | { go_id = id; _ } -> go_id = id) - goroutines - with - | Some waiting_goroutine -> write_ready (ReadySet.remove waiting_goroutine goroutines) - | _ -> return () - ;; - - let check_ready_goroutine = - let* goroutines = read_ready in - return (if ReadySet.is_empty goroutines then None else Some ()) - ;; - - let read_sending = - read - >>= function - | { sending; _ } -> return sending - ;; - - let write_sending sending = read >>= fun state -> write { state with sending } - - let push_to_send_queue id goroutine value = - let* sending = read_sending in - match - SendingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - sending - with - | None -> - fail (Runtime_error (Deadlock "trying to send to closed or uninitialized chanel")) - | Some { chan_id; send_queue; _ } -> - let sending = SendingSet.remove { chan_id; send_queue } sending in - let sending = - SendingSet.add { chan_id; send_queue = send_queue @ [ goroutine, value ] } sending - in - write_sending sending - ;; - - let pop_from_send_queue id = - let* sending = read_sending in - match - SendingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - sending - with - | None -> - fail (Runtime_error (Deadlock "trying to send to closed or uninitialized chanel")) - | Some { send_queue = []; _ } -> - fail (Runtime_error (Deadlock "trying to send to closed or uninitialized chanel")) - | Some { chan_id; send_queue = hd :: tl } -> - let sending = SendingSet.remove { chan_id; send_queue = hd :: tl } sending in - let sending = SendingSet.add { chan_id; send_queue = tl } sending in - write_sending sending *> return hd - ;; - - let is_send_queue_not_empty id = - let* sending = read_sending in - match - SendingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - sending - with - | None -> - fail (Runtime_error (Deadlock "trying to send to closed or uninitialized chanel")) - | Some { send_queue = []; _ } -> return None - | Some { send_queue = _ :: _; _ } -> return (Some ()) - ;; - - let read_receiving = - read - >>= function - | { receiving; _ } -> return receiving - ;; - - let write_receiving receiving = read >>= fun state -> write { state with receiving } - - let push_to_receive_queue id goroutine = - let* receiving = read_receiving in - match - ReceivingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - receiving - with - | None -> - fail - (Runtime_error (Deadlock "trying to receive from closed or uninitialized chanel")) - | Some { chan_id; receive_queue } -> - let receiving = ReceivingSet.remove { chan_id; receive_queue } receiving in - let receiving = - ReceivingSet.add - { chan_id; receive_queue = receive_queue @ [ goroutine ] } - receiving - in - write_receiving receiving - ;; - - let pop_from_receive_queue id = - let* receiving = read_receiving in - match - ReceivingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - receiving - with - | None -> - fail - (Runtime_error (Deadlock "trying to receive from closed or uninitialized chanel")) - | Some { receive_queue = []; _ } -> - fail - (Runtime_error (Deadlock "trying to receive from closed or uninitialized chanel")) - | Some { chan_id; receive_queue = hd :: tl } -> - let receiving = - ReceivingSet.remove { chan_id; receive_queue = hd :: tl } receiving - in - let receiving = ReceivingSet.add { chan_id; receive_queue = tl } receiving in - write_receiving receiving *> return hd - ;; - - let is_receive_queue_not_empty id = - let* receiving = read_receiving in - match - ReceivingSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - receiving - with - | None -> - fail - (Runtime_error (Deadlock "trying to receive from closed or uninitialized chanel")) - | Some { receive_queue = []; _ } -> return None - | Some { receive_queue = _ :: _; _ } -> return (Some ()) - ;; - - let read_next_go_id = - read - >>= function - | { next_go_id; _ } -> return next_go_id - ;; - - let write_next_go_id next_go_id = read >>= fun state -> write { state with next_go_id } - - let create_goroutine stack_frame = - let* go_id = read_next_go_id in - add_ready { stack = stack_frame, []; go_id } *> write_next_go_id (go_id + 1) - ;; - - let run_goroutine goroutine = - read_running - >>= function - | Some _ -> fail (Runtime_error (Dev "two goroutine running")) - | None -> write_running (Some goroutine) - ;; - - let run_ready_goroutine = - let* ready = read_ready in - match ReadySet.choose_opt ready with - | None -> return None - | Some goroutine -> - delete_ready goroutine *> run_goroutine goroutine *> return (Some ()) - ;; - - let delete_running_goroutine = write_running None - - (* chanels *) - - let read_chanels = - read - >>= function - | { chanels; _ } -> return chanels - ;; - - let write_chanels chanels = read >>= fun state -> write { state with chanels } - - let find_chanel_fail = function - | Chan_uninitialized Nil -> - fail (Runtime_error (Deadlock "sending to or receiving from uninitialized chanel")) - | Chan_initialized id -> - let* chanels, _ = read_chanels in - (match - ChanSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - chanels - with - | None -> - fail (Runtime_error (Deadlock "sending to or receiving from closed chanel")) - | Some { chan_id; _ } -> return chan_id) - ;; - - let create_chanel = - let* chanels, id = read_chanels in - write_chanels (ChanSet.add { chan_id = id; value = None } chanels, id + 1) - *> - let* sending = read_sending in - write_sending (SendingSet.add { chan_id = id; send_queue = [] } sending) - *> - let* receiving = read_receiving in - write_receiving (ReceivingSet.add { chan_id = id; receive_queue = [] } receiving) - *> return id - ;; - - let close_chanel = function - | Chan_uninitialized Nil -> fail (Runtime_error Close_of_nil_chan) - | Chan_initialized id -> - let* chanels, next_id = read_chanels in - (match - ChanSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - chanels - with - | None -> fail (Runtime_error Close_of_closed_chan) - | Some chan -> write_chanels (ChanSet.remove chan chanels, next_id)) - ;; - - let push_chan_value id value = - let* chanels, next_id = read_chanels in - match - ChanSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - chanels - with - | Some { chan_id; value = None } -> - write_chanels - ( ChanSet.add - { chan_id; value = Some value } - (ChanSet.remove { chan_id; value = None } chanels) - , next_id ) - *> return None - | Some { value = Some _; _ } -> return (Some ()) - | _ -> fail (Runtime_error (Deadlock "trying to push value to a closed chanel")) - ;; - - let pop_chan_value id = - let* chanels, next_id = read_chanels in - match - ChanSet.find_first_opt - (function - | { chan_id; _ } -> chan_id = id) - chanels - with - | Some { chan_id; value = Some v } -> - write_chanels - ( chanels - |> ChanSet.remove { chan_id; value = Some v } - |> ChanSet.add { chan_id; value = None } - , next_id ) - *> return v - | _ -> - fail - (Runtime_error - (Deadlock "trying to read value from closed chanel (or there is no value)")) - ;; - - (* sending state *) - - let read_is_using_chanel = - read - >>= function - | { is_using_chanel; _ } -> return is_using_chanel - ;; - - let write_is_using_chanel is_using_chanel = - read >>= fun state -> write { state with is_using_chanel } - ;; - - let start_using_chanel sender_receiver_and_value = - read_is_using_chanel - >>= function - | Some _ -> fail (Runtime_error (Dev "trying to use chanel which is still used")) - | None -> write_is_using_chanel (Some sender_receiver_and_value) - ;; - - let use_chanel = - read_is_using_chanel - >>= function - | Some sender_receiver_and_value -> - write_is_using_chanel None *> return sender_receiver_and_value - | None -> - fail - (Runtime_error - (Deadlock "trying to leave sending state while not in sending state")) - ;; - - let is_using_chanel = read_is_using_chanel - - (* single goroutine's stack *) - - let read_stack = - read_running_fail - >>= function - | { stack; _ } -> return stack - ;; - - let write_stack new_stack = - read_running_fail - >>= function - | { go_id; _ } -> write_running (Some { go_id; stack = new_stack }) - ;; - - let read_stack_frame = - read_stack - >>= function - | hd, _ -> return hd - ;; - - let write_stack_frame new_frame = - read_stack - >>= function - | _, tl -> write_stack (new_frame, tl) - ;; - - let add_stack_frame new_frame = - read_stack - >>= function - | hd, tl -> write_stack (new_frame, hd :: tl) - ;; - - let delete_stack_frame = - read_stack - >>= function - | _, hd :: tl -> write_stack (hd, tl) - | _, [] -> fail (Runtime_error (Dev "trying to delete last stack frame")) - ;; - - (* local env *) - - let read_local_envs = - read_stack_frame - >>= function - | { local_envs; _ } -> return local_envs - ;; - - let write_local_envs local_envs = - read_stack_frame - >>= function - | stack_frame -> write_stack_frame { stack_frame with local_envs } - ;; - - let add_env block env_type = - let* hd, tl = read_local_envs in - write_local_envs ({ exec_block = block; env_type; var_map = MapIdent.empty }, hd :: tl) - ;; - - let delete_env = - read_local_envs - >>= function - | _, hd :: tl -> write_local_envs (hd, tl) - | _, [] -> fail (Runtime_error (Dev "trying to delete last local env")) - ;; - - let read_env_type = - let* { env_type; _ }, _ = read_local_envs in - return env_type - ;; - - let save_local_id ident value = - let* { exec_block; env_type; var_map }, tl = read_local_envs in - let new_map = MapIdent.add ident value var_map in - write_local_envs ({ exec_block; env_type; var_map = new_map }, tl) - ;; - - let update_local_id ident value = - let* hd, tl = read_local_envs in - let local_envs = - List.rev - (List.fold_left - (fun lst env -> - match List.find_opt (fun x -> MapIdent.mem ident x.var_map) lst with - | Some _ -> env :: lst - | None when MapIdent.mem ident env.var_map -> - { env with var_map = MapIdent.add ident value env.var_map } :: lst - | None -> env :: lst) - [] - (hd :: tl)) - in - write_local_envs (List.hd local_envs, List.tl local_envs) - ;; - - (* deferred funcs *) - - let read_deferred = - read_stack_frame - >>= function - | { deferred_funcs; _ } -> return deferred_funcs - ;; - - let write_deferred deferred_funcs = - read_stack_frame - >>= fun stack_frame -> write_stack_frame { stack_frame with deferred_funcs } - ;; - - let add_deferred new_frame = - let* deferred_funcs = read_deferred in - write_deferred (new_frame :: deferred_funcs) - ;; - - (* panic *) - - let read_panics = - read_stack_frame - >>= function - | { panics; _ } -> return panics - ;; - - let write_panics panics = - read_stack_frame >>= fun stack_frame -> write_stack_frame { stack_frame with panics } - ;; - - (*returns*) - - let read_returns = - read_stack_frame - >>= function - | { returns; _ } -> return returns - ;; - - let write_returns returns = - read_stack_frame >>= fun stack_frame -> write_stack_frame { stack_frame with returns } - ;; - - (* exec block (processing statements) *) - - let read_exec_block = - read_local_envs - >>= function - | { exec_block; _ }, _ -> return exec_block - ;; - - let write_exec_block new_block = - let* { env_type; var_map; _ }, tl = read_local_envs in - write_local_envs ({ env_type; var_map; exec_block = new_block }, tl) - ;; - - let pop_next_statement = - read_exec_block - >>= function - | hd :: tl -> write_exec_block tl *> return (Some hd) - | [] -> return None - ;; - - (* reading ident *) - - let read_ident ident = - let* hd, tl = read_local_envs in - let* global_map = read_global in - let var_maps = List.map (fun { var_map; _ } -> var_map) (hd :: tl) @ [ global_map ] in - match List.find_opt (fun map -> MapIdent.mem ident map) var_maps with - | None -> fail (Runtime_error (TypeCheckFailed ("undefined ident " ^ ident))) - | Some map -> - (match MapIdent.find_opt ident map with - | Some value -> return value - | None -> fail (Runtime_error (TypeCheckFailed ("undefined ident " ^ ident)))) - ;; - - let update_ident ident t = - let* hd, tl = read_local_envs in - let* global_map = read_global in - let var_map = List.map (fun { var_map; _ } -> var_map) (hd :: tl) in - match List.find_opt (fun map -> MapIdent.mem ident map) var_map with - | Some _ -> update_local_id ident t - | None -> - let var_map = [ global_map ] in - (match List.find_opt (fun map -> MapIdent.mem ident map) var_map with - | Some _ -> save_global_id ident t - | None -> fail (Runtime_error (TypeCheckFailed ("undefined ident " ^ ident)))) - ;; -end diff --git a/Go/lib/eval/evalMonad.mli b/Go/lib/eval/evalMonad.mli deleted file mode 100644 index 1b9f935d4..000000000 --- a/Go/lib/eval/evalMonad.mli +++ /dev/null @@ -1,292 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -module Ident : sig - type t = ident - - val compare : t -> t -> int -end - -module MapIdent : Map.S with type key = Ident.t - -(** Value for [nil] identifier and unitialized functions and chanels *) -type nil = Nil - -type builtin = - | Print - | Println - | Make - | Close - | Recover - | Len - | Panic - -(** Value for chanels *) -type chan_value = - | Chan_initialized of int - (** Initialized chanel, identified by id (basically a link to a chanel) *) - | Chan_uninitialized of nil - -(** Values that can be stored in a variables *) -type value = - | Value_int of int (** [3], [-100] *) - | Value_string of string (** ["my_string"] *) - | Value_bool of bool (** [true], [false] *) - | Value_array of int * value list - (** Array of values, invariant: number of values matches the size *) - | Value_func of func_value - | Value_chan of chan_value - | Value_tuple of value list - | Value_nil of nil - (** Untyped [] value that is stored in [nil] predeclared identifier *) - -and func_type = - | Closure of value MapIdent.t - | FuncLit - | Default - -and func_value = - | Func_initialized of func_type * anon_func - | Func_uninitialized of nil - | Func_builtin of builtin - -type is_for_env = - | For - | Default - -(** Local environment, [{}] block of statements with local variables *) -type local_env = - { exec_block : block - ; var_map : value MapIdent.t - ; env_type : is_for_env - } - -type defered_frame = value * value list - -type stack_frame = - { local_envs : local_env * local_env list - (** Storage for local variables, new [{}] block creates new environment *) - ; deferred_funcs : defered_frame list - ; returns : value option - ; panics : value list option - } - -type goroutine = - { stack : stack_frame * stack_frame list - (** Stack of separate goroutine's local func calls. Is a tuple because there is always a root func *) - ; go_id : int - } - -module Goroutine : sig - type t = goroutine - - val compare : t -> t -> int -end - -module SendingGoroutines : sig - type t = - { send_queue : (goroutine * value) list - ; chan_id : int - } - - val compare : t -> t -> int -end - -module ReceivingGoroutines : sig - type t = - { receive_queue : goroutine list - ; chan_id : int - } - - val compare : t -> t -> int -end - -module Chan : sig - type t = - { chan_id : int - ; value : value option - } - - val compare : t -> t -> int -end - -module ReadySet : Set.S with type elt = Goroutine.t -module SendingSet : Set.S with type elt = SendingGoroutines.t -module ReceivingSet : Set.S with type elt = ReceivingGoroutines.t -module ChanSet : Set.S with type elt = Chan.t - -type inited_by = - | Sender - | Receiver - -type chanel_using_state = - { sending_goroutine : goroutine - ; receiving_goroutine : goroutine - ; value : value - ; inited_by : inited_by - } - -(** The whole executing program state *) -type eval_state = - { global_env : value MapIdent.t - (** Stores values for predeclared identifiers and global variables and functions *) - ; running : goroutine option - (** Goroutine that is currently running, stored separately for time efficiency *) - ; ready : ReadySet.t (** Set of all ready to run goroutines *) - ; sending : SendingSet.t (** Set of opened chanels' send queues *) - ; receiving : ReceivingSet.t (** Set of opened chanels' receive queues *) - ; chanels : ChanSet.t * int (** Set of opened chanels and id for next chanel *) - ; is_using_chanel : chanel_using_state option - (** The state indicates that value was sent through chanel, but not received yet *) - ; next_go_id : int (** An id that will be given to the next created goroutine *) - } - -(** Monad for evaluating the program state *) -module Monad : sig - (** ['a t] is an interpreter that stores current state - and the result of evaluation - ['a] (['a] or runtime error) *) - type 'a t - - val return : 'a -> 'a t - val fail : Errors.error -> 'b t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - val ( *> ) : 'a t -> 'b t -> 'b t - val iter : ('a -> unit t) -> 'a list -> unit t - val iter2 : ('a -> 'b -> unit t) -> 'a list -> 'b list -> unit t - val map : ('a -> 'b t) -> 'a list -> 'b list t - val run : 'a t -> eval_state -> eval_state * ('a, Errors.error) Result.t - - (** Takes ident and value and saves the pair to global varibles map *) - val save_global_id : ident -> value -> unit t - - (** Takes ident and returns value assigned to it. - Fails if there is no such ident visible from current stack frame *) - val read_ident : ident -> value t - - (** Takes ident and value and assigns the value to the ident. - Fails if there is no such ident visible from current stack frame *) - val update_ident : ident -> value -> unit t - - (** Returns set of all ready to run goroutines *) - val read_ready : ReadySet.t t - - (** Takes a goroutine and adds it to the set of ready goroutines *) - val add_ready : goroutine -> unit t - - (** [push_to_send_queue id go v] tries to push goroutine [go] that is trying to send value - [v] to chanel with id [id] to its send queue. Fails if chanel is unitialized or closed *) - val push_to_send_queue : int -> goroutine -> value -> unit t - - (** [pop_from_send_queue id] tries to pop sending goroutine with value it is sending - from chanel's with given [id] send queue. Fails if chanel is unitialized or closed *) - val pop_from_send_queue : int -> (goroutine * value) t - - (** [is_send_queue_not_empty id] returns [Some ()] if chanel's with given [id] send queue - is not empty, or [None] otherwise. Fails if chanel is unitialized or closed *) - val is_send_queue_not_empty : int -> unit option t - - (** [push_to_receive_queue id go] tries to push goroutine [go] to - chanel's with id [id] receive queue. Fails if chanel is unitialized or closed *) - val push_to_receive_queue : int -> goroutine -> unit t - - (** [pop_from_receive_queue id] tries to pop receiving goroutine from chanel's - with given [id] receive queue. Fails if chanel is unitialized or closed *) - val pop_from_receive_queue : int -> goroutine t - - (** [is_receive_queue_not_empty id] returns [Some ()] if chanel's with given [id] receive queue - is not empty, or [None] otherwise. Fails if chanel is unitialized or closed *) - val is_receive_queue_not_empty : int -> unit option t - - (** Takes stack frame and creates new goroutine with it. - Adds its to waiting goroutines set with [Ready] waiting state *) - val create_goroutine : stack_frame -> unit t - - (** Takes goroutine and assignes it [running] field. - Doesn't execute the goroutine. Fails if another goroutine is already running *) - val run_goroutine : goroutine -> unit t - - (** Runs random ready to run goroutine. Returns [Some ()] if there were some ready - goroutines, [None] otherwise. Fails if another goroutine is already running *) - val run_ready_goroutine : unit option t - - (** Deletes currently running goroutine and assigns [running] to [None]. - Should be called when goroutine finished executing *) - val delete_running_goroutine : unit t - - (** Returns currently running goroutine's, fails if there is no running goroutine *) - val read_running_fail : goroutine t - - (** Returns [Some ()] if there is ready to run goroutine, [None otherwise] *) - val check_ready_goroutine : unit option t - - (* Global environment *) - val read_returns : value option t - val write_returns : value option -> unit t - - (** Takes chanel value and returns [chan_id] of a chanel it points to. - Fails if there is no such chanel or it is uninitialized *) - val find_chanel_fail : chan_value -> int t - - (** Tries to push value [v] to the chanel. Returns [None] if pushed sucessfully, [Some ()] if there is already a value *) - val push_chan_value : int -> value -> unit option t - - (** Takes chanel id and pops value from the chanel with given id. - Fails if there is no such chanel or no value in the chanel *) - val pop_chan_value : int -> value t - - (** Creates new chanel and returns it's id *) - val create_chanel : int t - - (** Closes chanel. Fails if it is already closed or uninitialized *) - val close_chanel : chan_value -> unit t - - (** Enters chanel using state, accepts sending and receiving goroutines and sent value. - Fails if already in chanel using state *) - val start_using_chanel : chanel_using_state -> unit t - - (** Exits chanel using state, returns receiving goroutine and sent value. Fails if not in chanel using state *) - val use_chanel : chanel_using_state t - - (** Returns state of using a chanel (sender, receiver and value) if in chanel using state, [None] otherwise *) - val is_using_chanel : chanel_using_state option t - - (** Takes stack frame and pushes it to currently running goroutine's call stack *) - val add_stack_frame : stack_frame -> unit t - - (** Pops stack frame from currently running goroutine's call stack *) - val delete_stack_frame : unit t - - (** Takes ident and value and saves the pair to local varibles map *) - val save_local_id : ident -> value -> unit t - - (** Takes block of statements and is_for_env flag, adds new local environment - to currently running goroutine's last stack frame *) - val add_env : block -> is_for_env -> unit t - - (** Returns stack of local environments of currently running goroutine's last stack frame *) - val read_local_envs : (local_env * local_env list) t - - val write_local_envs : local_env * local_env list -> unit t - - (** Deletes last local environment of currently running goroutine's last stack frame *) - val delete_env : unit t - - (** Return whether current local environment is a for loop or not *) - val read_env_type : is_for_env t - - (** Takes stack frame and adds it to currently running goroutine's - current stack frame's deferred functions stack *) - val add_deferred : defered_frame -> unit t - - val read_deferred : defered_frame list t - val write_panics : value list option -> unit t - val read_panics : value list option t - - (** Returns next statement from currently running goroutine's - current stack frame's execution block. [None] if the block is empty *) - val pop_next_statement : stmt option t -end diff --git a/Go/lib/parser/common.ml b/Go/lib/parser/common.ml deleted file mode 100644 index 330d03ccb..000000000 --- a/Go/lib/parser/common.ml +++ /dev/null @@ -1,104 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Base -open Ast -open Angstrom - -let fail = fail "" -let fail_if cond = if cond then fail else return () -let skip_whitespace = skip_many1 (satisfy Char.is_whitespace) -let skip_line_whitespace = skip_many1 (char ' ' <|> char '\t') -let parse_line_comment = string "//" *> many_till any_char (char '\n') *> return () -let parse_block_comment = string "/*" *> many_till any_char (string "*/") *> return () -let parse_comment = parse_line_comment <|> parse_block_comment -let ws = skip_many (parse_comment <|> skip_whitespace) -let ws_line = skip_many (parse_block_comment <|> skip_line_whitespace) -let token s = ws_line *> string s <* ws -let parens p = char '(' *> ws *> p <* ws_line <* char ')' -let square_brackets p = char '[' *> ws *> p <* ws_line <* char ']' -let curly_braces p = char '{' *> ws *> p <* ws_line <* char '}' -let sep_by_comma p = sep_by (token ",") p -let sep_by_comma1 p = sep_by1 (token ",") p -let parse_stmt_sep = ws_line *> (char '\n' <|> char ';') *> ws - -let parse_int = - take_while1 Char.is_digit - >>= fun str -> - match Stdlib.int_of_string_opt str with - | Some num -> return num - | None -> fail -;; - -let is_keyword = function - | "break" - | "func" - | "defer" - | "go" - | "chan" - | "if" - | "else" - | "continue" - | "for" - | "return" - | "var" -> true - | _ -> false -;; - -let parse_ident = - let is_first_char = function - | 'a' .. 'z' | 'A' .. 'Z' | '_' -> true - | _ -> false - in - let is_valid_char = function - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' -> true - | _ -> false - in - let* first_char = satisfy is_first_char >>| Char.to_string in - let* rest = take_while is_valid_char in - let ident = first_char ^ rest in - fail_if (is_keyword ident) *> return ident -;; - -(** [parse_simple_type] parses [int], [bool] and [string] types *) -let parse_simple_type = - choice - [ string "int" *> return Type_int - ; string "string" *> return Type_string - ; string "bool" *> return Type_bool - ] -;; - -let parse_func_type ptype = - let* _ = string "func" *> ws in - let* args = parens (sep_by_comma ptype) in - let* returns = - ws_line - *> choice - [ (ptype >>| fun type' -> [ type' ]); parens (sep_by_comma ptype); return [] ] - in - return (Type_func (args, returns)) -;; - -let parse_array_type ptype = - let* size = square_brackets parse_int in - let* type' = ws_line *> ptype in - return (Type_array (size, type')) -;; - -let parse_chan_type ptype = - let* chan_type = string "chan" *> ws *> ptype in - return (Type_chan chan_type) -;; - -let parse_type = - fix (fun ptype -> - parens ptype - <|> choice - [ parse_simple_type - ; parse_func_type ptype - ; parse_array_type ptype - ; parse_chan_type ptype - ]) -;; diff --git a/Go/lib/parser/common.mli b/Go/lib/parser/common.mli deleted file mode 100644 index 7241bed0d..000000000 --- a/Go/lib/parser/common.mli +++ /dev/null @@ -1,63 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open! Base -open Ast -open Angstrom - -(** [fail] creates a parser that will always fail without message *) -val fail : 'a t - -(** [fail_if cond] creates a parser that will fail without message if [cond] is [true] *) -val fail_if : bool -> unit t - -(** [ws] accepts whitespace ([' '], ['\t'], ['\n'], ['\r']) or comments such as - [/* block comment */] and [// line comment \n] - {i zero} or more times, discarding the results. *) -val ws : unit t - -(** [ws_line] accepts spaces or tabs ([' '], ['\t']) or block comments - [/* block comment */] {i zero} or more times, discarding the results. *) -val ws_line : unit t - -(** [token string] creates parser that skips [ws_line], parses [string] - skips [ws] and returns string *) -val token : string -> string t - -(** [parens p] creates parser that parses ['('], runs [p], - parses [')'] and returns result of a [p] *) -val parens : 'a t -> 'a t - -(** [square_brackets p] creates parser that parses ['['], runs [p], - parses [']'] and returns result of a [p] *) -val square_brackets : 'a t -> 'a t - -(** [curly_braces p] creates parser that parses one ['{'], runs [p], - parses ['}'] and returns result of a [p] *) -val curly_braces : 'a t -> 'a t - -(** [sep_by_comma p] runs [p] {i zero} or more times, - interspersing runs of [char ','] in between. *) -val sep_by_comma : 'a t -> 'a list t - -(** [sep_by_comma p] runs [p] {i one} or more times, - interspersing runs of [char ','] in between. *) -val sep_by_comma1 : 'a t -> 'a list t - -(** [parse_int] parses {i one} or more digits and returns non-negative integer number *) -val parse_int : int t - -(** [parse_stmt_sep ] parses separator for the statements, - it runs [ws_line], then parses [;] or [\n], the runs [ws], and discards the results *) -val parse_stmt_sep : unit t - -(** [parse_ident] parses identifiers that can be used as veriables and function names. - Identifiers has to start with latin letter or ['_'] - and consist only of latin letters, digits and ['_'] *) -val parse_ident : ident t - -(** [parse_type] parses integer, boolean, string, array, function and channel types sucn as: - [int], [bool], [string], [[3]int], [func()], [func(int) (string, bool)], - [chan int], [<-chan int], [chan<- int], [chan chan bool] *) -val parse_type : type' t diff --git a/Go/lib/parser/dune b/Go/lib/parser/dune deleted file mode 100644 index 27b8862d6..000000000 --- a/Go/lib/parser/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name parse) - (libraries base angstrom ast) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) diff --git a/Go/lib/parser/expr.ml b/Go/lib/parser/expr.ml deleted file mode 100644 index 26a9c05cb..000000000 --- a/Go/lib/parser/expr.ml +++ /dev/null @@ -1,232 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom -open Common - -let chainl1 e op = - let rec go acc = lift2 (fun f x -> f acc x) op e >>= go <|> return acc in - e >>= go -;; - -let rec chainr1 e op = e >>= fun a -> op >>= (fun f -> chainr1 e op >>| f a) <|> return a - -let parse_unary_not = - char '!' *> ws *> return (fun expr -> Expr_un_oper (Unary_not, expr)) -;; - -let parse_unary_minus = - char '-' *> ws *> return (fun expr -> Expr_un_oper (Unary_minus, expr)) -;; - -let parse_unary_plus = - char '+' *> ws *> return (fun expr -> Expr_un_oper (Unary_plus, expr)) -;; - -let parse_chan_receive = string "<-" *> ws *> return (fun expr -> Expr_chan_receive expr) - -(** [parse_mult_unary_op pexpr] parses expressions with multiple unary operators such as: - [-+-+a[0]], [<-<-<-c()] *) -let parse_mult_unary_op pexpr = - let rec helper acc = - choice [ parse_unary_not; parse_unary_minus; parse_unary_plus; parse_chan_receive ] - >>= (fun new_oper -> helper (fun expr -> acc @@ new_oper expr)) - <|> return acc - in - let* unary_operators = helper Fun.id in - let* expr = pexpr in - return (unary_operators expr) -;; - -let parse_sum = token "+" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_sum, exp1, exp2)) - -let parse_mult = - token "*" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_multiply, exp1, exp2)) -;; - -let parse_subtraction = - token "-" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_subtract, exp1, exp2)) -;; - -let parse_division = - token "/" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_divide, exp1, exp2)) -;; - -let parse_modulus = - token "%" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_modulus, exp1, exp2)) -;; - -let parse_equal = - token "==" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_equal, exp1, exp2)) -;; - -let parse_not_equal = - token "!=" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_not_equal, exp1, exp2)) -;; - -let parse_greater = - token ">" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_greater, exp1, exp2)) -;; - -let parse_greater_equal = - token ">=" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_greater_equal, exp1, exp2)) -;; - -let parse_less = - token "<" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_less, exp1, exp2)) -;; - -let parse_less_equal = - token "<=" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_less_equal, exp1, exp2)) -;; - -let parse_and = - token "&&" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_and, exp1, exp2)) -;; - -let parse_or = token "||" *> return (fun exp1 exp2 -> Expr_bin_oper (Bin_or, exp1, exp2)) -let parse_const_int = parse_int >>| fun num -> Const_int num - -let parse_const_string = - let escaped_char = - char '\\' - *> choice - [ char '\'' *> return '\'' - ; char '\"' *> return '\"' - ; char '\\' *> return '\\' - ; char 'n' *> return '\n' - ; char 't' *> return '\t' - ; char 'r' *> return '\r' - ] - in - let string_char = escaped_char <|> satisfy (fun c -> c <> '"' && c <> '\\') in - char '\"' *> many string_char - <* char '\"' - >>| fun chars -> Const_string (String.of_seq (List.to_seq chars)) -;; - -(* let parse_const_string = - char '"' *> take_till (Char.equal '"') <* char '"' >>| fun string -> Const_string string - ;; *) - -(** [parse_idents_with_types] parses {i one} or more identificators with types, - separated by comma such as: [a int], [a int, b string], [a, b int, c, d bool] *) -let parse_idents_with_types = - let* args_lists = - sep_by_comma - (let* idents = sep_by_comma1 parse_ident in - let* t = ws_line *> parse_type in - return (Base.List.map ~f:(fun id -> id, t) idents)) - in - return (List.concat args_lists) -;; - -(** [parse_func_args_returns_and_body pblock] returns - parser for arguments, return values and body of a function such as: - [() {}], [(a int) string { return "" }], - [(a, b int, c string) (d, e bool) { - d, e := true, false; - return - }] *) -let parse_func_args_returns_and_body pblock = - let* args = parens parse_idents_with_types <* ws_line in - let* returns = - parens (sep_by_comma parse_type) <|> (parse_type >>| fun t -> [ t ]) <|> return [] - in - let* body = ws_line *> pblock in - return { args; returns; body } -;; - -(** [parse_const_func pblock] parses anonymous function suc as: - [func() {}], [func(a int), (b string) { return "" }] *) -let parse_const_func pblock = - string "func" *> ws *> parse_func_args_returns_and_body pblock - >>| fun anon_func -> Const_func anon_func -;; - -(** [parse_const_array pexpr] parses constant arrays such as - [[3]string{}], [[3]int{1, 2}] *) -let parse_const_array pexpr = - let* size = - square_brackets (parse_int >>| Option.some <|> string "..." *> return None) - in - let* type' = ws *> parse_type in - let* inits = - curly_braces (sep_by_comma pexpr <* (ws_line <* char ',' <* ws <|> return ())) - in - let size = - match size with - | Some size -> size - | None -> List.length inits - in - return (Const_array (size, type', inits)) -;; - -let parse_const pexpr pblock = - choice - [ parse_const_int - ; parse_const_string - ; parse_const_array pexpr - ; parse_const_func pblock - ] - >>| fun const -> Expr_const const -;; - -let parse_expr_ident = parse_ident >>| fun ident -> Expr_ident ident - -let parse_expr_func_call pexpr func = - let parse_arg = - pexpr >>| (fun e -> Arg_expr e) <|> (parse_type >>| fun t -> Arg_type t) - in - let* args = parens (sep_by_comma parse_arg) in - return (Expr_call (func, args)) -;; - -let parse_index pexpr array = - let* index = square_brackets pexpr in - return (array, index) -;; - -(** [parse_expr_index pexpr array] takes [array] and parses array index call for [array] - such as [a[i]], where array in [Expr_ident "a"] *) -let parse_expr_index pexpr array = - let* array, index = parse_index pexpr array in - return (Expr_index (array, index)) -;; - -(** [parse_nested_calls_and_indices pexpr parse_func_or_array] parses nested function - and array index calls such as [a(2, 3)[0]()()[1][2]] *) -let parse_nested_calls_and_indices pexpr parse_func_or_array = - let rec helper acc = - parse_expr_func_call pexpr acc - <|> parse_expr_index pexpr acc - >>= helper - <|> return acc - in - parse_func_or_array >>= helper -;; - -let parse_expr pblock = - fix (fun pexpr -> - let arg = parens pexpr <|> parse_const pexpr pblock <|> parse_expr_ident in - let arg = parse_nested_calls_and_indices pexpr arg in - let arg = parse_mult_unary_op arg in - let arg = chainl1 arg (parse_mult <|> parse_modulus <|> parse_division) in - let arg = chainl1 arg (parse_sum <|> parse_subtraction) in - let arg = - chainl1 - arg - (choice - [ parse_greater_equal - ; parse_less_equal - ; parse_greater - ; parse_less - ; parse_equal - ; parse_not_equal - ]) - in - let arg = chainr1 arg parse_and in - chainr1 arg parse_or) -;; diff --git a/Go/lib/parser/expr.mli b/Go/lib/parser/expr.mli deleted file mode 100644 index 3ac6b88eb..000000000 --- a/Go/lib/parser/expr.mli +++ /dev/null @@ -1,23 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom - -(** [parse_expr pblock] returns parser for any expressions - such as [2], [var], [-(2 + var)], [<-call[0]()]*) -val parse_expr : block t -> expr t - -(** [parse_func_args_returns_and_body pblock] returns - parser for arguments, return values and body of a function such as: - [() {}], [(a int) string { return "" }], - [(a, b int, c string) (d, e bool) { - d, e := true, false; - return - }] *) -val parse_func_args_returns_and_body : block t -> anon_func t - -(** [parse_index pexpr array] creates a parser that runs [square_brackets pexpr], - gets its result as [index] and returns [array, index]*) -val parse_index : 'a t -> 'b -> ('b * 'a) t diff --git a/Go/lib/parser/parse.ml b/Go/lib/parser/parse.ml deleted file mode 100644 index e256a6499..000000000 --- a/Go/lib/parser/parse.ml +++ /dev/null @@ -1,32 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Common -open Expr -open Stmt -open TopLevel - -(** [parse_ident] parses identifiers that can be used as veriables and function names. - Identifiers has to start with latin letter or ['_'] - and consist only of latin letters, digits and ['_'] *) -let parse_ident = parse_ident - -(** [parse_type] parses integer, boolean, string, array, function and channel types sucn as: - [int], [bool], [string], [[3]int], [func()], [func(int) (string, bool)], - [chan int], [<-chan int], [chan<- int], [chan chan bool] *) -let parse_type = parse_type - -(** [parse_expr ] parses any expressions such as [2], [var], [-(2 + var)], [<-call[0]()]*) -let parse_expr = parse_expr parse_block - -(** [parse_stmt] parses any statements such as - [call()], [i++], [c := 9], [if true {} else {}], etc. *) -let parse_stmt = parse_stmt parse_block - -(** [parse_file] parses the whole program *) -let parse_file = parse_file - -(** [parse parser str] runs [parser] on [str] and returns [Ok result] if it succeds, - where [result] is an AST, or [Error msg] if not *) -let parse parser str = Angstrom.parse_string ~consume:Angstrom.Consume.All parser str diff --git a/Go/lib/parser/parse.mli b/Go/lib/parser/parse.mli deleted file mode 100644 index e7edd75d3..000000000 --- a/Go/lib/parser/parse.mli +++ /dev/null @@ -1,13 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom - -val parse_ident : ident t -val parse_type : type' t -val parse_expr : expr t -val parse_stmt : stmt t -val parse_file : file t -val parse : 'a t -> string -> ('a, string) result diff --git a/Go/lib/parser/stmt.ml b/Go/lib/parser/stmt.ml deleted file mode 100644 index b9f98c64a..000000000 --- a/Go/lib/parser/stmt.ml +++ /dev/null @@ -1,219 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom -open Common -open Expr - -let rec combine_lists l1 l2 = - match l1, l2 with - | [], [] -> [] - | x :: xs, y :: ys -> (x, y) :: combine_lists xs ys - | _, _ -> [] -;; - -let parse_lvalues = sep_by_comma1 parse_ident -let parse_rvalues pblock = sep_by_comma1 (parse_expr pblock) - -let parse_long_var_decl pblock = - let* () = string "var" *> ws in - let* lvalues = parse_lvalues <* ws_line in - let* vars_type = parse_type >>| (fun t -> Some t) <|> return None in - let* with_init = ws_line *> char '=' *> ws *> return true <|> return false in - if not with_init - then ( - match vars_type, lvalues with - | Some t, hd :: tl -> return (Long_decl_no_init (t, hd, tl)) - | _ -> fail) - else - let* rvalues = parse_rvalues pblock in - let* () = fail_if (Base.List.is_empty lvalues) in - match lvalues, rvalues, List.length lvalues = List.length rvalues with - | lhd :: ltl, rhd :: rtl, true -> - return (Long_decl_mult_init (vars_type, (lhd, rhd), combine_lists ltl rtl)) - | lfst :: lsnd :: ltl, rhd :: _, false -> - let* () = fail_if (List.length rvalues <> 1) in - (match rhd with - | Expr_call call -> return (Long_decl_one_init (vars_type, lfst, lsnd, ltl, call)) - | _ -> fail) - | _ -> fail -;; - -let parse_short_var_decl pblock = - let* lvalues = parse_lvalues in - let* () = ws_line *> string ":=" *> ws in - let* rvalues = parse_rvalues pblock in - match lvalues, rvalues, List.length lvalues = List.length rvalues with - | lhd :: ltl, rhd :: rtl, true -> - return (Short_decl_mult_init ((lhd, rhd), combine_lists ltl rtl)) - | lfst :: lsnd :: ltl, rhd :: _, false -> - let* () = fail_if (List.length rvalues <> 1) in - (match rhd with - | Expr_call call -> return (Short_decl_one_init (lfst, lsnd, ltl, call)) - | _ -> fail) - | _ -> fail -;; - -(** [parse_assign_lvalues pblock] parses {i one} or more assign lvalues - separated by comma such as: [a], [a, b], [a[][]], [a[], b] *) -let parse_assign_lvalues pblock = - let parse_lvalue = - let rec helper acc = - parse_index (parse_expr pblock) acc - >>= (fun (array, index) -> helper (Lvalue_array_index (array, index))) - <|> return acc - in - parse_ident >>= fun ident -> helper (Lvalue_ident ident) - in - sep_by_comma1 parse_lvalue -;; - -let parse_assign pblock = - let* lvalues = parse_assign_lvalues pblock in - let* () = ws_line *> char '=' *> ws in - let* rvalues = parse_rvalues pblock in - match lvalues, rvalues, List.length lvalues = List.length rvalues with - | lhd :: ltl, rhd :: rtl, true -> - return (Assign_mult_expr ((lhd, rhd), combine_lists ltl rtl)) - | lfst :: lsnd :: ltl, rhd :: _, false -> - let* () = fail_if (List.length rvalues <> 1) in - (match rhd with - | Expr_call call -> return (Assign_one_expr (lfst, lsnd, ltl, call)) - | _ -> fail) - | _ -> fail -;; - -let parse_incr = parse_ident <* ws_line <* string "++" -let parse_decr = parse_ident <* ws_line <* string "--" - -let parse_func_call pblock = - parse_expr pblock - >>= function - | Expr_call call -> return call - | _ -> fail -;; - -let parse_defer pblock = - string "defer" *> ws *> parse_func_call pblock >>| fun call -> Stmt_defer call -;; - -let parse_go pblock = - string "go" *> ws *> parse_func_call pblock >>| fun call -> Stmt_go call -;; - -let parse_chan_send pblock = - let* chan = parse_ident in - let* expr = token "<-" *> parse_expr pblock in - return (chan, expr) -;; - -let parse_chan_receive pblock = - let* chan = string "<-" *> ws *> parse_expr pblock in - return chan -;; - -let parse_return pblock = - string "return" *> ws_line *> sep_by_comma (parse_expr pblock) - >>| fun expr_list -> Stmt_return expr_list -;; - -let parse_if_for_init pblock = - choice - [ (parse_short_var_decl pblock >>| fun s -> Init_decl s) - ; (parse_assign pblock >>| fun s -> Init_assign s) - ; (parse_incr >>| fun s -> Init_incr s) - ; (parse_decr >>| fun s -> Init_decr s) - ; (parse_func_call pblock >>| fun s -> Init_call s) - ; (parse_chan_send pblock >>| fun s -> Init_send s) - ; (parse_chan_receive pblock >>| fun s -> Init_receive s) - ] -;; - -let parse_if pblock = - fix (fun parse_if -> - let* () = string "if" *> ws in - let* if_init = - parse_if_for_init pblock >>| Option.some <* parse_stmt_sep <|> return None - in - let* () = - match if_init with - | None -> parse_stmt_sep <|> return () - | Some _ -> return () - in - let* if_cond = ws *> parse_expr pblock in - let* if_body = ws_line *> pblock <* ws_line in - let* else_body = - let* else_body_exists = string "else" *> ws *> return true <|> return false in - if else_body_exists - then - pblock - >>| (fun block -> Some (Else_block block)) - <|> (parse_if >>| fun block -> Some (Else_if block)) - else return None - in - return { if_init; if_cond; if_body; else_body }) -;; - -let parse_default_for pblock = - let* for_init = parse_if_for_init pblock >>| Option.some <|> return None in - let* () = parse_stmt_sep in - let* for_cond = parse_expr pblock >>| Option.some <|> return None in - let* () = parse_stmt_sep in - let* for_post = - let* next_char = peek_char_fail in - match next_char with - | '{' -> return None - | _ -> parse_if_for_init pblock >>| Option.some - in - let* for_body = ws_line *> pblock in - return (Stmt_for { for_init; for_cond; for_post; for_body }) -;; - -let parse_for_only_cond pblock = - let* next_char = peek_char_fail in - let* for_cond = - match next_char with - | '{' -> return None - | _ -> parse_expr pblock >>| Option.some - in - let* for_body = ws_line *> pblock in - return (Stmt_for { for_init = None; for_cond; for_post = None; for_body }) -;; - -let parse_for pblock = - string "for" *> ws *> (parse_default_for pblock <|> parse_for_only_cond pblock) -;; - -let parse_stmt pblock = - choice - [ (parse_long_var_decl pblock >>| fun s -> Stmt_long_var_decl s) - ; (parse_short_var_decl pblock >>| fun s -> Stmt_short_var_decl s) - ; (parse_incr >>| fun s -> Stmt_incr s) - ; (parse_decr >>| fun s -> Stmt_decr s) - ; (parse_if pblock >>| fun s -> Stmt_if s) - ; (parse_chan_send pblock >>| fun s -> Stmt_chan_send s) - ; (parse_chan_receive pblock >>| fun s -> Stmt_chan_receive s) - ; string "break" *> return Stmt_break - ; string "continue" *> return Stmt_continue - ; parse_return pblock - ; (parse_func_call pblock >>| fun s -> Stmt_call s) - ; (parse_assign pblock >>| fun s -> Stmt_assign s) - ; parse_defer pblock - ; parse_go pblock - ; (pblock >>| fun block -> Stmt_block block) - ; parse_for pblock - ] -;; - -let parse_block : block t = - fix (fun pblock -> - char '{' - *> ws - *> skip_many (parse_stmt_sep *> ws) - *> sep_by (many1 parse_stmt_sep) (parse_stmt pblock) - <* ws - <* skip_many (parse_stmt_sep *> ws) - <* char '}') -;; diff --git a/Go/lib/parser/stmt.mli b/Go/lib/parser/stmt.mli deleted file mode 100644 index b95920df2..000000000 --- a/Go/lib/parser/stmt.mli +++ /dev/null @@ -1,21 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom - -(** [parse_stmt pblock] returns parser for any statement such as - [call()], [i++], [c := 9], [if true {} else {}], etc. *) -val parse_stmt : block t -> stmt t - -(** [parse_block] parses block of statements such as: [{}] - [{ - a := 0 - call(a) - }] *) -val parse_block : block t - -(** [parse_long_var_decl pblock] returns parser for long variable declaration such as: - [var a int], [var a = 5], [var a, b, c = 1, "str", call()] *) -val parse_long_var_decl : block t -> long_var_decl t diff --git a/Go/lib/parser/topLevel.ml b/Go/lib/parser/topLevel.ml deleted file mode 100644 index 1d0e0d2a6..000000000 --- a/Go/lib/parser/topLevel.ml +++ /dev/null @@ -1,24 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom -open Common -open Expr -open Stmt - -let parse_func_decl : func_decl t = - let* () = string "func" *> ws in - let* func_name = parse_ident <* ws_line in - let* args_returns_and_body = parse_func_args_returns_and_body parse_block in - return (func_name, args_returns_and_body) -;; - -let parse_top_decl = - parse_long_var_decl parse_block - >>| (fun decl -> Decl_var decl) - <|> (parse_func_decl >>| fun decl -> Decl_func decl) -;; - -let parse_file : file t = ws *> sep_by parse_stmt_sep parse_top_decl <* ws diff --git a/Go/lib/parser/topLevel.mli b/Go/lib/parser/topLevel.mli deleted file mode 100644 index 95d255a34..000000000 --- a/Go/lib/parser/topLevel.mli +++ /dev/null @@ -1,22 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Angstrom - -(** [parse_file] parses the whole program such as - [ -func my_print(a int) { - println(a) -} -func get() int { - return 1 -} -var a int -func main() { - a = get() - my_print(a) -} -] *) -val parse_file : file t diff --git a/Go/lib/ppType/dune b/Go/lib/ppType/dune deleted file mode 100644 index 56ff2853a..000000000 --- a/Go/lib/ppType/dune +++ /dev/null @@ -1,5 +0,0 @@ -(library - (name ppType) - (libraries ast) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/lib/ppType/ppType.ml b/Go/lib/ppType/ppType.ml deleted file mode 100644 index 5a19cec21..000000000 --- a/Go/lib/ppType/ppType.ml +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Format - -let sep_by_comma list print = - let rec helper acc = function - | fst :: snd :: tl -> - let acc = String.concat "" [ acc; print fst; ", " ] in - helper acc (snd :: tl) - | fst :: _ -> acc ^ print fst - | [] -> acc - in - helper "" list -;; - -let rec print_type = function - | Type_int -> "int" - | Type_string -> "string" - | Type_bool -> "bool" - | Type_array (size, type') -> asprintf "[%i]%s" size (print_type type') - | Type_func (arg_types, return_types) -> - let print_returns = - match return_types with - | _ :: _ :: _ -> asprintf " (%s)" (sep_by_comma return_types print_type) - | type' :: _ -> " " ^ print_type type' - | [] -> "" - in - asprintf "func(%s)%s" (sep_by_comma arg_types print_type) print_returns - | Type_chan t -> asprintf "chan %s" (print_type t) -;; diff --git a/Go/lib/ppType/ppType.mli b/Go/lib/ppType/ppType.mli deleted file mode 100644 index bdfeeee6e..000000000 --- a/Go/lib/ppType/ppType.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val sep_by_comma : 'a list -> ('a -> string) -> string -val print_type : Ast.type' -> string diff --git a/Go/lib/typecheck/dune b/Go/lib/typecheck/dune deleted file mode 100644 index e0bcb78af..000000000 --- a/Go/lib/typecheck/dune +++ /dev/null @@ -1,5 +0,0 @@ -(library - (name typecheck) - (libraries base ast baseMonad ppType) - (instrumentation - (backend bisect_ppx))) diff --git a/Go/lib/typecheck/typeCheckMonad.ml b/Go/lib/typecheck/typeCheckMonad.ml deleted file mode 100644 index ba052e10d..000000000 --- a/Go/lib/typecheck/typeCheckMonad.ml +++ /dev/null @@ -1,101 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -module Ident = struct - type t = ident - - let compare = compare -end - -module MapIdent = Map.Make (Ident) - -type polymorphic_call = - | Make - | Print - | Println - | Panic - | Len - | Close - | Nil - | Recover - -type ctype = - | Ctype of type' - | Ctuple of type' list - | CgenT of type' - | Cpolymorphic of polymorphic_call - -type env = ctype MapIdent.t list -type funcs_returns = ctype list -type typecheck_state = env * funcs_returns - -module Monad = struct - open Errors - include BaseMonad - - type 'a t = (typecheck_state, 'a) BaseMonad.t - - let read_env = - read - >>= function - | env, _ -> return env - ;; - - let write_env new_env = - read - >>= function - | _, funcs -> write (new_env, funcs) - ;; - - let save_func func = - read - >>= function - | env, funcs -> write (env, func :: funcs) - ;; - - let delete_func = - read - >>= function - | env, funcs -> write (env, List.tl funcs) - ;; - - let save_ident ident t = - let* env = read_env in - match MapIdent.find_opt ident (List.hd env) with - | None -> write_env (MapIdent.add ident t (List.hd env) :: List.tl env) - | Some _ -> - fail - (Type_check_error (Multiple_declaration (Printf.sprintf "%s is redeclared" ident))) - ;; - - let read_ident ident = - let* env = read_env in - match List.find_opt (MapIdent.mem ident) env with - | None -> return None - | Some map -> return (MapIdent.find_opt ident map) - ;; - - let retrieve_ident ident = - read_ident ident - >>= function - | Some t -> return t - | None -> - fail (Type_check_error (Undefined_ident (Printf.sprintf "%s is not defined" ident))) - ;; - - let get_func_return_type = - read - >>= function - | _, [] -> - fail - (Type_check_error - (Mismatched_types "this func has no returns but they was requested")) - | _, funcs -> return (List.hd funcs) - ;; - - let add_env = read_env >>= fun x -> write_env (MapIdent.empty :: x) - let delete_env = read_env >>= fun x -> write_env (List.tl x) -end diff --git a/Go/lib/typecheck/typeCheckMonad.mli b/Go/lib/typecheck/typeCheckMonad.mli deleted file mode 100644 index 5736eaf9d..000000000 --- a/Go/lib/typecheck/typeCheckMonad.mli +++ /dev/null @@ -1,83 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -module Ident : sig - type t = ident - - val compare : 'a -> 'a -> int -end - -module MapIdent : sig - type key = Ident.t - type 'a t = 'a Stdlib__Map.Make(Ident).t - - val empty : 'a t -end - -type polymorphic_call = - | Make - | Print - | Println - | Panic - | Len - | Close - | Nil - | Recover - -type ctype = - | Ctype of type' - | Ctuple of type' list (** Used to check multiple returns of a function *) - | CgenT of type' - | Cpolymorphic of polymorphic_call - -(** list of MapIdent is used to map ident and it's type in local space. - Add MapIdent if you enter in if/for body or func literal and then delete it after checking block of statements - If we didn't find ident in Map, we will seek it in next 'till we find it or not find it even in global space - and fail with undefined ident error *) -type env = ctype MapIdent.t list - -(** List of ctype that stores function return types, used to check returns in nested functions *) -type funcs_returns = ctype list - -(** Current typechecker state *) -type typecheck_state = env * funcs_returns - -module Monad : sig - (** ['a t] is a typecheker that stores current state (idents and their types, external function return type) - and the result of typechecking - ['a] (['a] or typecheck error)*) - type 'a t = (typecheck_state, 'a) BaseMonad.t - - val return : 'a -> 'a t - val fail : Errors.error -> 'b t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - val ( *> ) : 'a t -> 'b t -> 'b t - val iter : ('a -> unit t) -> 'a list -> unit t - val iter2 : ('a -> 'b -> unit t) -> 'a list -> 'b list -> unit t - val map : ('a -> 'b t) -> 'a list -> 'b list t - val run : 'a t -> typecheck_state -> typecheck_state * ('a, Errors.error) Result.t - - (** Saves current func's return type to the state (called when moving into func body) *) - val save_func : ctype -> unit t - - (** Deletes current func's return type from the state (called when moving out of func body) *) - val delete_func : unit t - - (** Saves ident's type to env's last map in state *) - val save_ident : ident -> ctype -> unit t - - (** Searches for given ident's type, fails if it is not found *) - val retrieve_ident : ident -> ctype t - - (** Returns current func return type. Used to check if it matches exprs in return stmt *) - val get_func_return_type : ctype t - - (** Add new Map to env while entering a new block/anon_func/if body/for body*) - val add_env : unit t - - (** Remove Map from env while leaving block/anon_func/if body/for body*) - val delete_env : unit t -end diff --git a/Go/lib/typecheck/typecheck.ml b/Go/lib/typecheck/typecheck.ml deleted file mode 100644 index b17888397..000000000 --- a/Go/lib/typecheck/typecheck.ml +++ /dev/null @@ -1,530 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open TypeCheckMonad -open TypeCheckMonad.Monad -open Errors -open Format -open Ast - -let get_afunc_type afunc = - Ctype (Type_func (List.map (fun (_, snd) -> snd) afunc.args, afunc.returns)) -;; - -let print_type = function - | Ctype t -> PpType.print_type t - | Ctuple x -> asprintf "(%s)" (String.concat ", " (List.map PpType.print_type x)) - | _ -> "" -;; - -let fail_if_break_continue = - iter (function - | Stmt_break -> fail (Type_check_error (Unexpected_operation "break")) - | Stmt_continue -> fail (Type_check_error (Unexpected_operation "continue")) - | _ -> return ()) -;; - -let check_return body = - let rec find_return_rec body = - List.mem - true - (List.map - (function - | Stmt_return _ -> true - | Stmt_if if' -> - find_return_rec if'.if_body - && (function - | Some (Else_block body) -> find_return_rec body - | Some (Else_if if') -> find_return_rec [ Stmt_if if' ] - | None -> false) - if'.else_body - | Stmt_for for' -> find_return_rec for'.for_body - | Stmt_block block -> find_return_rec block - | _ -> false) - body) - in - if find_return_rec body - then return () - else fail (Type_check_error (Missing_return "Missing return")) -;; - -let check_anon_func afunc cstmt = - let save_args = iter (fun (id, t) -> save_ident id (Ctype t)) afunc.args in - add_env - *> (match afunc.returns with - | _ :: _ -> check_return afunc.body - | [] -> return ()) - *> save_func (Ctuple afunc.returns) - *> save_args - *> fail_if_break_continue afunc.body - *> iter cstmt afunc.body - *> delete_func - *> delete_env - *> return (get_afunc_type afunc) -;; - -let eq_type t1 t2 = - match t1, t2 with - | Cpolymorphic Recover, t -> return t - | t, Cpolymorphic Recover -> return t - | t1, t2 -> - if t1 = t2 - then return t1 - else - fail - (Type_check_error - (Mismatched_types (Printf.sprintf "%s and %s" (print_type t1) (print_type t2)))) -;; - -let check_eq t1 t2 = - if t1 = t2 - then return () - else - fail - (Type_check_error - (Mismatched_types (Printf.sprintf "%s and %s" (print_type t1) (print_type t2)))) -;; - -let retrieve_const cstmt rexpr = function - | Const_array (size, type', inits) when List.length inits <= size -> - iter - (fun init -> - rexpr init - >>= function - | Ctuple _ -> fail (Type_check_error (Mismatched_types "Expected single type")) - | t -> check_eq t (Ctype type')) - inits - *> return (Ctype (Type_array (size, type'))) - | Const_array _ -> - fail (Type_check_error (Mismatched_types "Array's size less thai it's inits count")) - | Const_int _ -> return (Ctype Type_int) - | Const_string _ -> return (Ctype Type_string) - | Const_func anon_func -> check_anon_func anon_func cstmt -;; - -let check_generic_type = function - | CgenT _ -> fail (Type_check_error (Mismatched_types "Generic type in wrong place")) - | _ -> return () -;; - -let check_func_call rexpr rarg (func, args) = - let* actual_arg_types = - map - (fun arg -> - rarg arg - >>= function - | Ctuple _ -> fail (Type_check_error (Mismatched_types "Expected single type")) - | t -> return t) - args - in - let* ftype = - rexpr func - >>= function - | Ctype (Type_func (lst, _)) -> map (fun t -> return (Ctype t)) lst - | Cpolymorphic Print | Cpolymorphic Println | Cpolymorphic Panic -> - iter check_generic_type actual_arg_types *> return actual_arg_types - | Cpolymorphic Make -> - (match actual_arg_types with - | [] -> - fail - (Type_check_error (Invalid_operation "Make should take at least 1 argument")) - | lst -> - (match List.hd lst with - | CgenT _ -> iter check_generic_type (List.tl lst) *> return actual_arg_types - | _ -> - fail - (Type_check_error - (Invalid_operation "Make should take some type as 1st argument")))) - | Cpolymorphic Close -> - (match actual_arg_types with - | [] -> - fail - (Type_check_error (Invalid_operation "Make should take at least 1 argument")) - | [ x ] -> - (match x with - | Ctype (Type_chan t) -> return [ Ctype (Type_chan t) ] - | _ -> - fail - (Type_check_error - (Invalid_operation "Close should take chan type as 1st argument"))) - | _ -> - fail (Type_check_error (Mismatched_types "Close should take only 1 argument"))) - | Cpolymorphic Len -> - (match actual_arg_types with - | [ Ctype Type_string ] -> return [ Ctype Type_string ] - | [ Ctype (Type_array (x, y)) ] -> return [ Ctype (Type_array (x, y)) ] - | _ -> - fail (Type_check_error (Mismatched_types "len takes only string and array args"))) - | Cpolymorphic Recover -> - (match actual_arg_types with - | [] -> return [] - | _ -> fail (Type_check_error (Mismatched_types "recover takes no args"))) - | _ -> fail (Type_check_error (Mismatched_types "Expected func type")) - in - try iter2 check_eq ftype actual_arg_types with - | Invalid_argument _ -> - fail (Type_check_error (Mismatched_types "Number of given args mismatched")) -;; - -let rec nested_array t depth = - match t, depth with - | t, 0 -> return t - | Ctype (Type_array (_, t)), depth -> nested_array (Ctype t) (depth - 1) - | _, _ -> - fail - (Type_check_error - (Mismatched_types "Number of indicies in array element assigment is incorrect")) -;; - -let rec check_expr cstmt rarg = function - | Expr_const const -> retrieve_const cstmt (check_expr cstmt rarg) const - | Expr_un_oper (Unary_minus, expr) | Expr_un_oper (Unary_plus, expr) -> - check_expr cstmt rarg expr >>= eq_type (Ctype Type_int) - | Expr_un_oper (Unary_not, expr) -> - check_expr cstmt rarg expr >>= fun t -> eq_type t (Ctype Type_bool) - | Expr_ident id -> retrieve_ident id - | Expr_bin_oper (op, left, right) -> - let compare_arg_typ left right = - let* ltype = check_expr cstmt rarg left in - let* rtype = check_expr cstmt rarg right in - eq_type ltype rtype - in - let compare_operation_typ left right t = compare_arg_typ left right >>= eq_type t in - (match op with - | Bin_sum | Bin_divide | Bin_modulus | Bin_multiply | Bin_subtract -> - compare_operation_typ left right (Ctype Type_int) - | Bin_less | Bin_greater | Bin_greater_equal | Bin_less_equal -> - compare_operation_typ left right (Ctype Type_int) *> return (Ctype Type_bool) - | Bin_or | Bin_and -> - compare_operation_typ left right (Ctype Type_bool) *> return (Ctype Type_bool) - | Bin_equal | Bin_not_equal -> compare_arg_typ left right *> return (Ctype Type_bool)) - | Expr_call (func, args) -> - check_func_call (check_expr cstmt rarg) rarg (func, args) - *> map rarg args - *> (check_expr cstmt rarg) func - >>= (function - | Ctype (Type_func (_, fst :: snd :: tl)) -> return (Ctuple (fst :: snd :: tl)) - | Ctype (Type_func (_, hd :: _)) -> return (Ctype hd) - | Cpolymorphic Print | Cpolymorphic Close | Cpolymorphic Println -> - fail - (Type_check_error (Invalid_operation "print/println/close func makes no return")) - | Cpolymorphic Len -> return (Ctype Type_int) - | Cpolymorphic Make -> - (match List.hd args with - | Arg_type t -> return (Ctype t) - | _ -> - fail - (Type_check_error - (Mismatched_types "make should be used like make(T, arg) when T is a type"))) - | Cpolymorphic Recover -> return (Cpolymorphic Recover) - | _ -> - fail (Type_check_error (Mismatched_types "Function without returns in expression"))) - | Expr_chan_receive chan -> - check_expr cstmt rarg chan - >>= (function - | Ctype (Type_chan t) -> return (Ctype t) - | _ -> fail (Type_check_error (Mismatched_types "Chan type mismatch"))) - | Expr_index (array, index) -> - (check_expr cstmt rarg index >>= check_eq (Ctype Type_int)) - *> (check_expr cstmt rarg array - >>= function - | Ctype (Type_array (_, t)) -> return (Ctype t) - | _ -> - fail (Type_check_error (Mismatched_types "Non-array type in array index call")) - ) -;; - -let rec retrieve_arg cstmt = function - | Arg_expr exp -> check_expr cstmt (retrieve_arg cstmt) exp - | Arg_type t -> return (CgenT t) -;; - -let check_nil arg possible_nil = - match possible_nil with - | Cpolymorphic Nil -> - (match arg with - | Ctype (Type_chan t) -> return (Ctype (Type_chan t)) - | Ctype (Type_func (args, returns)) -> return (Ctype (Type_func (args, returns))) - | t -> - fail - (Type_check_error - (Mismatched_types - (Printf.sprintf "nil type cannot be assigned to %s" (print_type t))))) - | _ -> return possible_nil -;; - -let fail_if_nil = function - | Cpolymorphic Nil -> - fail - (Type_check_error (Mismatched_types (Printf.sprintf "nil type cannot be used here"))) - | x -> return x -;; - -let check_long_var_decl cstmt save_ident = function - | Long_decl_no_init (t, hd, tl) -> iter (fun id -> save_ident id (Ctype t)) (hd :: tl) - | Long_decl_mult_init (Some type', hd, tl) -> - iter - (fun (id, expr) -> - (check_expr cstmt (retrieve_arg cstmt) expr - >>= (fun t -> check_nil (Ctype type') t) - >>= check_eq (Ctype type')) - *> save_ident id (Ctype type')) - (hd :: tl) - | Long_decl_mult_init (None, hd, tl) -> - iter - (fun (id, expr) -> - check_expr cstmt (retrieve_arg cstmt) expr >>= fail_if_nil >>= save_ident id) - (hd :: tl) - | Long_decl_one_init (Some type', fst, snd, tl, call) -> - (check_expr cstmt (retrieve_arg cstmt) (Expr_call call) - >>= check_eq (Ctuple (List.init (List.length (fst :: snd :: tl)) (fun _ -> type')))) - *> iter (fun id -> save_ident id (Ctype type')) (fst :: snd :: tl) - | Long_decl_one_init (None, fst, snd, tl, call) -> - check_expr cstmt (retrieve_arg cstmt) (Expr_call call) - >>= (function - | Ctype _ -> - fail - (Type_check_error - (Mismatched_types "function returns only one element in multiple var decl")) - | Ctuple types -> - (try iter2 save_ident (fst :: snd :: tl) (List.map (fun t -> Ctype t) types) with - | Invalid_argument _ -> - fail - (Type_check_error - (Mismatched_types - "function returns wrong number of elements in multiple var assign"))) - | _ -> - fail - (Type_check_error - (Mismatched_types "simple type or built-in func cannot be used as return"))) -;; - -let check_short_var_decl cstmt = function - | Short_decl_mult_init (hd, tl) -> - iter - (fun (id, expr) -> - check_expr cstmt (retrieve_arg cstmt) expr - >>= (function - | Ctype t -> return (Ctype t) - | Cpolymorphic Nil -> - fail - (Type_check_error - (Invalid_operation "Cannot assign nil in short var declaration")) - | Cpolymorphic Recover -> return (Cpolymorphic Recover) - | _ -> - fail - (Type_check_error - (Mismatched_types "Incorrect assignment in short var decl"))) - >>= save_ident id) - (hd :: tl) - | Short_decl_one_init (fst, snd, tl, call) -> - check_expr cstmt (retrieve_arg cstmt) (Expr_call call) - >>= (function - | Ctype _ -> - fail - (Type_check_error - (Mismatched_types - "function returns wrong number of elements in multiple var decl")) - | Ctuple types -> - (try - iter - (fun (id, tp) -> save_ident id (Ctype tp)) - (List.combine (fst :: snd :: tl) types) - with - | Invalid_argument _ -> - fail - (Type_check_error - (Mismatched_types - "function returns wrong number of elements in multiple var decl"))) - | Cpolymorphic Nil -> - fail - (Type_check_error - (Invalid_operation "Cannot assign nil in short var declaration")) - | CgenT _ | Cpolymorphic _ -> - fail - (Type_check_error - (Mismatched_types "simple type or built-in func cannot be used as return"))) -;; - -let rec retrieve_lvalue ind cstmt = function - | Lvalue_ident id -> retrieve_ident id - | Lvalue_array_index (Lvalue_ident array, index) -> - (check_expr cstmt (retrieve_arg cstmt) index >>= check_eq (Ctype Type_int)) - *> retrieve_ident array - >>= (function - | Ctype (Type_array (_, t)) -> nested_array (Ctype t) ind - | _ -> - fail (Type_check_error (Mismatched_types "Non-array type in array index call"))) - | Lvalue_array_index (lvalue_array_index, index) -> - (check_expr cstmt (retrieve_arg cstmt) index >>= check_eq (Ctype Type_int)) - *> retrieve_lvalue (ind + 1) cstmt lvalue_array_index -;; - -let check_assign cstmt = function - | Assign_mult_expr (hd, tl) -> - iter - (fun (lvalue, expr) -> - let* expected_type = retrieve_lvalue 0 cstmt lvalue in - let* actual_type = check_expr cstmt (retrieve_arg cstmt) expr in - let* actual_type = check_nil expected_type actual_type in - check_eq expected_type actual_type) - (hd :: tl) - | Assign_one_expr (fst, snd, tl, call) -> - check_expr cstmt (retrieve_arg cstmt) (Expr_call call) - >>= (function - | Ctype _ -> fail (Type_check_error (Cannot_assign "Multiple return assign failed")) - | Ctuple types -> - (try - iter2 - (fun lvalue t -> retrieve_lvalue 0 cstmt lvalue >>= check_eq (Ctype t)) - (fst :: snd :: tl) - types - with - | Invalid_argument _ -> - fail (Type_check_error (Cannot_assign "Multiple return assign failed"))) - | _ -> - fail - (Type_check_error - (Mismatched_types "simple type or built-in func cannot be used as return"))) -;; - -let check_chan_send cstmt (id, expr) = - let* expr_type = check_expr cstmt (retrieve_arg cstmt) expr in - retrieve_ident id - >>= function - | Ctype (Type_chan t) -> check_eq expr_type (Ctype t) - | _ -> fail (Type_check_error (Mismatched_types "expected chan type")) *> return () -;; - -let check_init cstmt = function - | Some (Init_assign assign) -> check_assign cstmt assign - | Some (Init_call call) -> - check_func_call (check_expr cstmt (retrieve_arg cstmt)) (retrieve_arg cstmt) call - | Some (Init_decl decl) -> check_short_var_decl cstmt decl *> return () - | Some (Init_decr id) -> retrieve_ident id >>= check_eq (Ctype Type_int) - | Some (Init_incr id) -> retrieve_ident id >>= check_eq (Ctype Type_int) - | Some (Init_receive chan) -> check_expr cstmt (retrieve_arg cstmt) chan *> return () - | Some (Init_send send) -> check_chan_send cstmt send - | None -> return () -;; - -let rec check_stmt = function - | Stmt_long_var_decl long_decl -> check_long_var_decl check_stmt save_ident long_decl - | Stmt_short_var_decl short_decl -> check_short_var_decl check_stmt short_decl - | Stmt_incr id -> retrieve_ident id >>= check_eq (Ctype Type_int) - | Stmt_decr id -> retrieve_ident id >>= check_eq (Ctype Type_int) - | Stmt_assign assign -> check_assign check_stmt assign - | Stmt_call call -> - check_func_call - (check_expr check_stmt (retrieve_arg check_stmt)) - (retrieve_arg check_stmt) - call - | Stmt_defer call -> - check_func_call - (check_expr check_stmt (retrieve_arg check_stmt)) - (retrieve_arg check_stmt) - call - | Stmt_go (func, args) -> - ((check_expr check_stmt (retrieve_arg check_stmt)) func - >>= function - | Cpolymorphic Make -> fail (Type_check_error Go_make) - | _ -> return ()) - *> check_func_call - (check_expr check_stmt (retrieve_arg check_stmt)) - (retrieve_arg check_stmt) - (func, args) - | Stmt_chan_send send -> check_chan_send check_stmt send - | Stmt_block block -> add_env *> iter check_stmt block *> delete_env - | Stmt_break -> return () - | Stmt_chan_receive chan -> - check_expr check_stmt (retrieve_arg check_stmt) chan *> return () - | Stmt_continue -> return () - | Stmt_return exprs -> - (get_func_return_type - >>= (function - | Ctuple rtv -> - (try return (List.combine exprs (List.map (fun t -> Ctype t) rtv)) with - | Invalid_argument _ -> - fail (Type_check_error (Mismatched_types "func return types mismatch"))) - | _ -> - fail - (Type_check_error - (Mismatched_types - "simple type or built-in func cannot be used as return"))) - >>= iter (fun (expr, return_type) -> - check_expr check_stmt (retrieve_arg check_stmt) expr >>= check_eq return_type)) - *> return () - | Stmt_if { if_init; if_cond; if_body; else_body } -> - add_env - *> check_init check_stmt if_init - *> (check_expr check_stmt (retrieve_arg check_stmt) if_cond - >>= check_eq (Ctype Type_bool)) - *> iter check_stmt if_body - *> delete_env - *> - (match else_body with - | Some (Else_block block) -> iter check_stmt block - | Some (Else_if if') -> check_stmt (Stmt_if if') - | None -> return ()) - | Stmt_for { for_init; for_cond; for_post; for_body } -> - add_env - *> check_init check_stmt for_init - *> (match for_cond with - | Some expr -> - check_expr check_stmt (retrieve_arg check_stmt) expr - >>= check_eq (Ctype Type_bool) - | None -> return ()) - *> check_init check_stmt for_post - *> iter check_stmt for_body - *> delete_env -;; - -let save_top_decl_funcs = function - | Decl_func (id, args_returns_and_body) -> - save_ident id (get_afunc_type args_returns_and_body) - | Decl_var _ -> return () -;; - -let check_and_save_top_decl_vars = function - | Decl_func _ -> return () - | Decl_var decl -> check_long_var_decl check_stmt save_ident decl -;; - -let check_top_decl_funcs = function - | Decl_func (_, afunc) -> check_anon_func afunc check_stmt *> return () - | Decl_var _ -> return () -;; - -let check_main = - retrieve_ident "main" - >>= function - | Ctype (Type_func ([], [])) -> return () - | Ctype (Type_func _) -> - fail - (Type_check_error - (Incorrect_main "func main must have no arguments and no return values")) - | _ -> fail (Type_check_error (Incorrect_main "main func not found")) -;; - -let type_check file = - run - (save_ident "true" (Ctype Type_bool) - *> save_ident "false" (Ctype Type_bool) - *> save_ident "make" (Cpolymorphic Make) - *> save_ident "print" (Cpolymorphic Print) - *> save_ident "panic" (Cpolymorphic Panic) - *> save_ident "len" (Cpolymorphic Len) - *> save_ident "recover" (Cpolymorphic Recover) - *> save_ident "close" (Cpolymorphic Close) - *> save_ident "println" (Cpolymorphic Println) - *> save_ident "nil" (Cpolymorphic Nil) - *> add_env - *> iter save_top_decl_funcs file - *> iter check_and_save_top_decl_vars file - *> iter check_top_decl_funcs file - *> check_main) - ([ MapIdent.empty ], []) - |> function - | _, res -> res -;; diff --git a/Go/lib/typecheck/typecheck.mli b/Go/lib/typecheck/typecheck.mli deleted file mode 100644 index f8209331e..000000000 --- a/Go/lib/typecheck/typecheck.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val type_check : Ast.file -> (unit, Errors.error) result diff --git a/Go/tests/eval/dune b/Go/tests/eval/dune deleted file mode 100644 index bdfc36315..000000000 --- a/Go/tests/eval/dune +++ /dev/null @@ -1,12 +0,0 @@ -(library - (name evalUnitTest) - (libraries ast parse eval typecheck pprinter errors) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) - -(cram - (applies_to examples) - (deps ../../bin/interpret.exe ./examples.go)) diff --git a/Go/tests/eval/evalTest.ml b/Go/tests/eval/evalTest.ml deleted file mode 100644 index 5147c7fd8..000000000 --- a/Go/tests/eval/evalTest.ml +++ /dev/null @@ -1,981 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Eval -open Typecheck - -let pp str = - match parse parse_file str with - | Error _ -> print_endline ": syntax error" - | Ok ast -> - (match type_check ast with - | Result.Error (Runtime_error _) -> () - | Result.Error (Type_check_error err) -> - prerr_endline ("Typecheck error: " ^ Errors.pp_typecheck_error err) - | Result.Ok _ -> - (match eval ast with - | Result.Error (Type_check_error _) -> () - | Result.Error (Runtime_error err) -> - prerr_endline ("Runtime error: " ^ Errors.pp_runtime_error err) - | Result.Ok _ -> prerr_endline "Correct evaluating")) -;; - -let%expect_test "ok: empty main" = - pp {| - func main() {} - |}; - [%expect {| - Correct evaluating |}] -;; - -let%expect_test "ok: simple main with prints" = - pp - {| - func main() { - print("kill OCaml ") - print("kill OCaml ") - print("kill OCaml ") - } - |}; - [%expect {| - Correct evaluating - kill OCaml kill OCaml kill OCaml |}] -;; - -let%expect_test "ok: single long_var_init" = - pp {| - var x = "kill OCaml" - func main() { print(x) } - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "ok: multiple long_var_init" = - pp {| - var x, y = "kill ", "OCaml" - func main() {print(x, y)} - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "err: division by zero" = - pp {| - func main() { a := 1 / 0 } - |}; - [%expect {| - Runtime error: division by zero |}] -;; - -let%expect_test "err: by zero modulus" = - pp {| - func main() { a := 1 % 0 } - |}; - [%expect {| - Runtime error: division by zero |}] -;; - -let%expect_test "ok: func call in global var decl" = - pp {| - var a = len("asd") - func main() { - print(a) - } - |}; - [%expect {| - Correct evaluating - 3 |}] -;; - -let%expect_test "ok: simple func_call with args" = - pp - {| - var x, y = "kill ", "OCaml" - func foo(x string, y string) { - print(x, y) - } - - func main() {foo(x, y)} - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "ok: simple value func call" = - pp - {| - var x = "kill " - func foo(x string, y string) { - print(x, y) - } - - func main() { - foo(x, "OCaml") - } - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "ok: local var decl func call" = - pp - {| - var x = "kill " - - func main() { - var y = "OCaml" - print(x, y) - } - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "ok: func args init" = - pp - {| - var x = "kill" - func foo(x string, k string) { - var z = "OCaml" - print(x, k, z) - } - - func main() { - var y = "OCaml" - foo(x, y) - } - |}; - [%expect {| - Correct evaluating - kill OCaml OCaml |}] -;; - -let%expect_test "ok: assignment check" = - pp - {| - var x = "kill " - func foo(x string, k string) { - var z = "OCaml" - print(x, k, z) - } - - func main() { - x = "OCaml " - var y = "OCaml" - foo(x, y) - } - |}; - [%expect {| - Correct evaluating - OCaml OCaml OCaml |}] -;; - -let%expect_test "ok: simple arithmetic check" = - pp - {| - var x int = 1 - func foo(k int) { - z := 1 - z++ - print(k + 1 + z) - } - - func main() { - x = 100 - x++ - foo(x + 1) - } - |}; - [%expect {| - Correct evaluating - 105 |}] -;; - -let%expect_test "ok: short var init" = - pp - {| - func foo(k int) { - z := k - z = z + 1 - print(k + 1 + z) - } - - func main() { - x := 100 - x++ - foo(x + 1) - } - |}; - [%expect {| - Correct evaluating - 206 |}] -;; - -let%expect_test "ok: simple if" = - pp - {| - func foo(k int) { - var z = k - if k < 100 { - print("Error") - } else{ - print("Correct") - } - if k >= 100 { - print(" Correct") - } else{ - print(" Error") - } - if k < 10 { - print("Error") - } else if k < 20 { - print("Error") - } else { - print(" Correct") - } - if k < 20 { - print("Error") - } - } - - func main() { - x := 100 - x++ - foo(x + 1) - } - |}; - [%expect {| - Correct evaluating - Correct Correct Correct |}] -;; - -let%expect_test "ok: nested if decl" = - pp - {| - func foo(k int) { - z := k - if k >= 100 { - o := 1 - z = 1 - print(o) - print(z) - } - print(z) - } - - func main() { - x := 100 - x++ - foo(x + 1) - x = 1 - print(x) - print(x) - } - |}; - [%expect {| - Correct evaluating - 11111 |}] -;; - -let%expect_test "ok: if with init" = - pp - {| - func main() { - if a := true; a { - println("норм") - } - } - |}; - [%expect {| - Correct evaluating - норм |}] -;; - -let%expect_test "ok: simple for" = - pp - {| - - func main() { - i := 1 - for i <= 3 { - println(i) - i = i + 1 - } - for j := 0; j < 3; j++ { - println(j) - } - } - |}; - [%expect {| - Correct evaluating - 1 - 2 - 3 - 0 - 1 - 2 |}] -;; - -let%expect_test "ok: break" = - pp - {| - func main() { - a := 0 - for { - a++ - println(a) - if a == 5 { - if true { - break - } - } - } - } - |}; - [%expect {| - Correct evaluating - 1 - 2 - 3 - 4 - 5 |}] -;; - -let%expect_test "ok: continue" = - pp - {| - func main() { - for i := 0; i < 5; i++ { - if i == 3 { - continue - } - println(i) - } - } - |}; - [%expect {| - Correct evaluating - 0 - 1 - 2 - 4 |}] -;; - -let%expect_test "ok: function returns on return" = - pp - {| - var x = "kill " - - func foo(){ - return - x = "XXXXXXERRROR" - } - - func main() { - var y = "OCaml" - foo() - print(x, y) - } - |}; - [%expect {| - Correct evaluating - kill OCaml |}] -;; - -let%expect_test "ok: simple return check" = - pp - {| - var x = "kill " - func foo() string { - return "CORRECT" - } - func main() { - var y = "OCaml" - print(x, y, foo()) - print(x, y, foo()) - } - |}; - [%expect {| - Correct evaluating - kill OCaml CORRECTkill OCaml CORRECT |}] -;; - -let%expect_test "ok: factorial check" = - pp - {| - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } - func main() { - print(fac(5)) - } - |}; - [%expect {| - Correct evaluating - 120 |}] -;; - -let%expect_test "ok: funclit check" = - pp - {| - func main() { - a := 0 - f := func(x int) { - a = a + x - } - a = a + 1 - f(1) - print(a) - } - |}; - [%expect {| - Correct evaluating - 2 |}] -;; - -let%expect_test "ok: closure check" = - pp - {| - func adder(x int) func(int) int { - sum := 0 - return func(x int) int { - sum = sum + x - return sum - } - } - - func main() { - pos, neg := adder(1), adder(1) - for i := 0; i < 10; i++ { - println(pos(i), neg(-2 * i)) - } - } - |}; - [%expect - {| - Correct evaluating - 0 0 - 1 -2 - 3 -6 - 6 -12 - 10 -20 - 15 -30 - 21 -42 - 28 -56 - 36 -72 - 45 -90 |}] -;; - -(* arrays *) - -let%expect_test "ok: simple array assignment and call" = - pp - {| - func main() { - var a = [2]string{"a", "a"} - a[0] = "Kill" - a[1] = "Ocaml" - println(a[0], a[1]) - } - |}; - [%expect {| - Correct evaluating - Kill Ocaml |}] -;; - -let%expect_test "ok: full array printing" = - pp - {| - func main() { - a := [...]int{0, 1, 2, 3, 4} - for i := 0; i < len(a); i++ { - print(a[i]) - } - } - |}; - [%expect {| - Correct evaluating - 01234 |}] -;; - -let%expect_test "ok: array of functions with auto size" = - pp - {| - func main() { - funcs := [...]func(){ - func() { print(1) }, - func() { print(2) }, - func() { print(3) }, - } - - for i := 0; i < len(funcs); i++ { - funcs[i]() - } - } - |}; - [%expect {| - Correct evaluating - 123 |}] -;; - -let%expect_test "ok: multidimensional array test & vlong_var_decl no init" = - pp - {| - func main() { - var a [2][3][4][5]string - a[0][1][2][1] = "Kill" - a[1][0][0][3] = "Ocaml" - println(a[0][1][2][1], a[1][0][0][3]) - } - - |}; - [%expect {| - Correct evaluating - Kill Ocaml |}] -;; - -let%expect_test "err: array index out of bounds in expr" = - pp - {| - func main() { - var a [2][3][4][5]string - a[0][1][2][1] = "Kill" - a[1][0][0][3] = "Ocaml" - println(a[0][1][10][1], a[1][0][0][3]) - } - - |}; - [%expect {| - Runtime error: array index out of bounds |}] -;; - -let%expect_test "err: array index out of bounds in lvalue" = - pp - {| - func main() { - var a [2][3][4][5]string - a[0][1][2][1] = "Kill" - a[1][0][10][3] = "Ocaml" - println(a[0][1][2][1], a[1][0][0][3]) - } - - |}; - [%expect {| - Runtime error: array index out of bounds |}] -;; - -(* defer, panic, recover *) - -let%expect_test "ok: simple defer check change local value & return not chenged local \ - value" - = - pp - {| - func foo() int{ - a := 0 panic - defer func (h int){ - a++ - print(a) - }(a) - a = a + 1 - print(a) - return a - } - - func main() { - print(foo()) - } - |}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "ok: defer check function reassignment value" = - pp - {| - func foo() int{ - a := 0 - - f := func (){ - a++ - println(a) - } - - defer f() - - f = func (){ - a = a + 100 - println(a) - } - - a = a + 1 - print(a) - return a - } - - func main() { - println(foo()) - } - |}; - [%expect {| - Correct evaluating - 12 - 1 |}] -;; - -let%expect_test "ok: defer check function example" = - pp - {| - -func main() { - f() - println("Returned normally from f.") -} - -func f() { - println("Calling g.") - g(0) - println("Returned normally from g.") - } - - func g(i int) { - if i > 3 { - println("Stop!") - return - } - defer println("Defer in g", i) - println("Printing in g", i) - g(i + 1) - } - |}; - [%expect - {| - Correct evaluating - Calling g. - Printing in g 0 - Printing in g 1 - Printing in g 2 - Printing in g 3 - Stop! - Defer in g 3 - Defer in g 2 - Defer in g 1 - Defer in g 0 - Returned normally from g. - Returned normally from f. |}] -;; - -let%expect_test "ok: panic does not impact on goroutine without chanels" = - pp - {| - - func main() { - println("Creating new goroutine") - go f() - println("Finish") - } - - func f() { - println("Calling g.") - g(0) - println("Returned normally from g.") - } - - func g(i int) { - if i > 3 { - println("Panicking!") - panic(i) - } - - defer println("Defer in g", i) - println("Printing in g", i) - g(i + 1) - } - |}; - [%expect {| - Correct evaluating - Creating new goroutine - Finish |}] -;; - -let%expect_test "ok: panic with recover" = - pp - {| - - func main() { - f() - println("Returned normally from f.") - } - - func f() { - defer func() { - r := recover() - println("Recovered in f with value:", r) - - }() - println("Calling g.") - g(0) - println("Returned normally from g.") - } - - func g(i int) { - if i > 3 { - println("Panicking!") - panic(i) - } - defer println("Defer in g", i) - println("Printing in g", i) - g(i + 1) - - } - |}; - [%expect - {| - Correct evaluating - Calling g. - Printing in g 0 - Printing in g 1 - Printing in g 2 - Printing in g 3 - Panicking! - Defer in g 3 - Defer in g 2 - Defer in g 1 - Defer in g 0 - Recovered in f with value: 4 - Returned normally from f. |}] -;; - -let%expect_test "err: not recovered panic" = - pp - {| - func main() { - f() - println("Returned normally from f.") - } - - func f() { - println("Calling g.") - g(0) - println("Returned normally from g.") - } - - func g(i int) { - if i > 3 { - println("Panicking!") - panic(i) - } - defer println("Defer in g", i) - println("Printing in g", i) - g(i + 1) - } - |}; - [%expect - {| - Runtime error: Panic: 4 - Calling g. - Printing in g 0 - Printing in g 1 - Printing in g 2 - Printing in g 3 - Panicking! - Defer in g 3 - Defer in g 2 - Defer in g 1 - Defer in g 0 |}] -;; - -(* goroutines *) - -let%expect_test "ok: two goroutine sync with unbuffered chanel" = - pp - {| - func goroutine2(c chan int) { - println("go2: trying to receive") - a := <-c - println("go2: receive success. Value:", a) - } - - func main() { - c := make(chan int) - - v := 0 - - go goroutine2(c) - - println("go1: trying to send. Value:", v) - c <- v - println("go1: send success") - } - |}; - [%expect - {| - Correct evaluating - go1: trying to send. Value: 0 - go2: trying to receive - go2: receive success. Value: 0 - go1: send success |}] -;; - -let%expect_test "ok: receive and send back" = - pp - {| - func goroutine2(c chan int) { - println("go2: trying to receive") - a := <-c - println("go2: receive success. Value:", a) - - println("go2: trying to send. Value:", a) - c <- a - println("go2: send success") // this doesn't execute - } - - func main() { - c := make(chan int) - - v := 0 - - go goroutine2(c) - - println("go1: trying to send. Value:", v) - c <- v - println("go1: send success") - - println("go1: trying to receive") - a := <-c - println("go1: receive success. Value:", a) - } - |}; - [%expect - {| - Correct evaluating - go1: trying to send. Value: 0 - go2: trying to receive - go2: receive success. Value: 0 - go2: trying to send. Value: 0 - go1: send success - go1: trying to receive - go1: receive success. Value: 0 |}] -;; - -let%expect_test "err: sender without receiver" = - pp {| - func main() { - c := make(chan int) - c <- 0 - } - |}; - [%expect {| - Runtime error: Deadlock: goroutine 1 trying to send to chan 1 |}] -;; - -let%expect_test "err: receiver without sender" = - pp {| - func main() { - c := make(chan int) - <-c - } - |}; - [%expect {| - Runtime error: Deadlock: goroutine 1 trying to receive from chan 1 |}] -;; - -let%expect_test "ok: save goroutine receiving two times" = - pp - {| - var a = 0 - - func sender(c chan int) { - a++ - c <- a - } - - func main() { - c := make(chan int) - go sender(c) - go sender(c) - - println(<-c, <-c) - } - |}; - [%expect {| - Correct evaluating - 1 2 |}] -;; - -let%expect_test "ok: simple goroutine test" = - pp - {| - func sum(s [6]int, c chan int) { - sum := 0 - for v := 0; v < 6; v++{ - sum = sum + v - } - c <- sum - } - - func main() { - s := [6]int{7, 2, 8, -9, 4, 0} - - c := make(chan int) - go sum(s, c) - - println("Waiting for channel receive") - x := <-c - - println(x) - } - - |}; - [%expect {| - Correct evaluating - Waiting for channel receive - 15 |}] -;; - -let%expect_test "ok: two goroutines sending to the same chanel before value received" = - pp - {| - func main2(c chan int) { - println("go2: sending value 2") - c <- 2 - println("go2: value 2 sent successfully") - } - - func main3(c chan int) { - println("go3: received value:", <-c) - println("go3: received value:", <-c) - } - - func main() { - c := make(chan int) - - go main2(c) - go main3(c) - - println("go1: sending value 1") - c <- 1 - println("go1: value 1 sent successfully") - } - |}; - [%expect - {| - Correct evaluating - go1: sending value 1 - go2: sending value 2 - go3: received value: 1 - go3: received value: 2 - go1: value 1 sent successfully |}] -;; diff --git a/Go/tests/eval/evalTest.mli b/Go/tests/eval/evalTest.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/eval/evalTest.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/eval/examples.go b/Go/tests/eval/examples.go deleted file mode 100644 index d1550e2a5..000000000 --- a/Go/tests/eval/examples.go +++ /dev/null @@ -1,124 +0,0 @@ -func standardTypes() { - var i int = 42 - var b bool = true - var s string = "Hello, Go!" - - println("Standard types:") - println("int:", i) - println("bool:", b) - println("string:", s) -} - -func loops() { - println("\nLoops (For, Break, Continue):") - - for i := 0; i < 5; i++ { - println(i) - if i == 3 { - break - } - } - - for i := 0; i < 5; i++ { - if i == 2 { - continue - } - println(i) - } -} - -func if_else() { - println("\nIf-Else:") - x := 10 - if x > 5 { - println("x больше 5") - } else { - println("x не больше 5") - } -} - -func arrays() { - println("\nArrays:") - var arr [5]int - - for i := 0; i < len(arr); i++ { - print(arr[i]) - } - - arr[2] = 5 - println() - println(arr) -} - -func sum2(a, b int) int { - return a + b -} - -func factorial(n int) int { - if n == 1 { - return 1 - } else { - return n * factorial(n-1) - } -} - -func closureExample() { - println("\nClosure Example:") - - counter := func() func() int { - var count int - return func() int { - count++ - return count - } - } - - inc := counter() - println(inc()) - println(inc()) - println(inc()) -} - -func goroutinesAndChannels() { - println("\nGoroutines and Channels:") - - ch := make(chan string) - - go func(ch chan string) { - ch <- "Hello from goroutine!" - }(ch) - - println(<-ch) - - close(ch) -} - -func deferExample() { - println("\nDefer Example:") - - defer println("This is printed last.") - - println("This is printed first.") - - defer func() { - if r := recover(); r != nil { - println("Recovered from panic:", r) - } - }() - - panic("Something went wrong!") -} - -func main() { - standardTypes() - loops() - if_else() - arrays() - - println("\n5 + 10 =", sum2(5, 10)) - println("factorial of 5:", factorial(5)) - - closureExample() - goroutinesAndChannels() - deferExample() -} diff --git a/Go/tests/eval/examples.t b/Go/tests/eval/examples.t deleted file mode 100644 index c3adb3995..000000000 --- a/Go/tests/eval/examples.t +++ /dev/null @@ -1,41 +0,0 @@ -Copyright 2024, Karim Shakirov, Alexei Dmitrievtsev -SPDX-License-Identifier: MIT - - $ ../../bin/interpret.exe ./examples.go - Running...          Standard types: - int: 42 - bool: true - string: Hello, Go! - - Loops (For, Break, Continue): - 0 - 1 - 2 - 3 - 0 - 1 - 3 - 4 - - If-Else: - x больше 5 - - Arrays: - 00000 - [0, 0, 5, 0, 0] - - 5 + 10 = 15 - factorial of 5: 120 - - Closure Example: - 1 - 2 - 3 - - Goroutines and Channels: - Hello from goroutine! - - Defer Example: - This is printed first. - This is printed last. - Recovered from panic: Something went wrong! diff --git a/Go/tests/parser/pp/dune b/Go/tests/parser/pp/dune deleted file mode 100644 index 1da2b9eda..000000000 --- a/Go/tests/parser/pp/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name pprinter) - (libraries ast str ppType) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) diff --git a/Go/tests/parser/pp/ppUnitTests.ml b/Go/tests/parser/pp/ppUnitTests.ml deleted file mode 100644 index d521c854e..000000000 --- a/Go/tests/parser/pp/ppUnitTests.ml +++ /dev/null @@ -1,936 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Printer - -let%expect_test "ident" = - print_endline (print_ident "therain17"); - [%expect {| therain17 |}] -;; - -(********** type **********) - -let%expect_test "type int" = - print_endline (print_type Type_int); - [%expect {| int |}] -;; - -let%expect_test "type string" = - print_endline (print_type Type_string); - [%expect {| string |}] -;; - -let%expect_test "type bool" = - print_endline (print_type Type_bool); - [%expect {| bool |}] -;; - -let%expect_test "type simple array" = - print_endline (print_type (Type_array (5, Type_int))); - [%expect {| [5]int |}] -;; - -let%expect_test "type array of arrays" = - print_endline (print_type (Type_array (5, Type_array (5, Type_int)))); - [%expect {|[5][5]int|}] -;; - -let%expect_test "type simple func" = - print_endline (print_type (Type_func ([], []))); - [%expect {| func() |}] -;; - -let%expect_test "type complex func" = - print_endline - (print_type - (Type_func - ([ Type_bool; Type_func ([], []) ], [ Type_array (0, Type_string); Type_int ]))); - [%expect {| func(bool, func()) ([0]string, int) |}] -;; - -let%expect_test "type bidirectional chanel" = - print_endline (print_type (Type_chan Type_int)); - [%expect {| chan int |}] -;; - -(********** expr **********) - -(*** Const ***) - -let%expect_test "expr const int" = - print_endline (print_expr (Expr_const (Const_int 10))); - [%expect {| 10 |}] -;; - -let%expect_test "expr const string" = - print_endline (print_expr (Expr_const (Const_string "hello"))); - [%expect {| "hello" |}] -;; - -let%expect_test "expr const empty string" = - print_endline (print_expr (Expr_const (Const_string ""))); - [%expect {| "" |}] -;; - -let%expect_test "expr const with escaped backslash" = - print_endline (print_expr (Expr_const (Const_string "\\"))); - [%expect {| "\\" |}] -;; - -let%expect_test "expr const with escaped quote" = - print_endline (print_expr (Expr_const (Const_string "\""))); - [%expect {| "\"" |}] -;; - -let%expect_test "expr const with newline" = - print_endline (print_expr (Expr_const (Const_string "\n"))); - [%expect {| "\n" |}] -;; - -let%expect_test "expr const empty array" = - print_endline (print_expr (Expr_const (Const_array (3, Type_int, [])))); - [%expect {| [3]int{} |}] -;; - -let%expect_test "expr const array with init" = - print_endline - (print_expr - (Expr_const - (Const_array - (3, Type_int, [ Expr_const (Const_int 1); Expr_const (Const_int 2) ])))); - [%expect {| [3]int{1, 2} |}] -;; - -let%expect_test "expr empty anon func" = - print_endline - (print_expr (Expr_const (Const_func { args = []; returns = []; body = [] }))); - [%expect {| func() {} |}] -;; - -let%expect_test "expr anon func with one arg and one return value" = - print_endline - (print_expr - (Expr_const - (Const_func - { args = [ "a", Type_int ] - ; returns = [ Type_int ] - ; body = [ Stmt_return [ Expr_ident "a" ] ] - }))); - [%expect {| - func(a int) int { - return a - } |}] -;; - -let%expect_test "expr anon func with mult args and return values" = - print_endline - (print_expr - (Expr_const - (Const_func - { args = [ "a", Type_int; "b", Type_string ] - ; returns = [ Type_int; Type_string ] - ; body = [ Stmt_return [ Expr_ident "a"; Expr_ident "b" ] ] - }))); - [%expect {| - func(a int, b string) (int, string) { - return a, b - } |}] -;; - -(*** unary op ***) - -let%expect_test "expr unary plus" = - print_endline (print_expr (Expr_un_oper (Unary_plus, Expr_const (Const_int 5)))); - [%expect {| +5 |}] -;; - -let%expect_test "expr unary minus" = - print_endline (print_expr (Expr_un_oper (Unary_minus, Expr_const (Const_int 5)))); - [%expect {| -5 |}] -;; - -let%expect_test "expr unary not" = - print_endline (print_expr (Expr_un_oper (Unary_not, Expr_ident "t"))); - [%expect {| !t |}] -;; - -let%expect_test "expr chan receive" = - print_endline (print_expr (Expr_chan_receive (Expr_ident "c"))); - [%expect {| <-c |}] -;; - -let%expect_test "expr chan receive from complex expr" = - print_endline - (print_expr - (Expr_chan_receive (Expr_bin_oper (Bin_sum, Expr_ident "a", Expr_ident "b")))); - [%expect {| <-(a + b) |}] -;; - -let%expect_test "expr multiple unary operators" = - print_endline - (print_expr - (Expr_un_oper - ( Unary_minus - , Expr_un_oper - ( Unary_plus - , Expr_un_oper - ( Unary_not - , Expr_un_oper - ( Unary_minus - , Expr_un_oper - ( Unary_minus - , Expr_un_oper - (Unary_not, Expr_un_oper (Unary_plus, Expr_ident "t")) ) ) - ) ) ))); - [%expect {| -+!--!+t |}] -;; - -(*** bin op ***) - -let%expect_test "expr bin sum" = - print_endline - (print_expr (Expr_bin_oper (Bin_sum, Expr_const (Const_int 4), Expr_ident "i"))); - [%expect {| 4 + i |}] -;; - -let%expect_test "expr bin subtraction" = - print_endline - (print_expr (Expr_bin_oper (Bin_subtract, Expr_ident "a", Expr_const (Const_int 5)))); - [%expect {| a - 5 |}] -;; - -let%expect_test "expr bin multiplication" = - print_endline - (print_expr (Expr_bin_oper (Bin_multiply, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t * 5 |}] -;; - -let%expect_test "expr bin division" = - print_endline - (print_expr (Expr_bin_oper (Bin_divide, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t / 5 |}] -;; - -let%expect_test "expr bin equality" = - print_endline - (print_expr (Expr_bin_oper (Bin_equal, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t == 5 |}] -;; - -let%expect_test "expr bin unequality" = - print_endline - (print_expr (Expr_bin_oper (Bin_not_equal, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t != 5 |}] -;; - -let%expect_test "expr bin greater" = - print_endline - (print_expr (Expr_bin_oper (Bin_greater, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t > 5 |}] -;; - -let%expect_test "expr bin greater or equal" = - print_endline - (print_expr - (Expr_bin_oper (Bin_greater_equal, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t >= 5 |}] -;; - -let%expect_test "expr bin less" = - print_endline - (print_expr (Expr_bin_oper (Bin_greater, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t > 5 |}] -;; - -let%expect_test "expr bin less or equal" = - print_endline - (print_expr - (Expr_bin_oper (Bin_less_equal, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t <= 5 |}] -;; - -let%expect_test "expr bin and" = - print_endline - (print_expr (Expr_bin_oper (Bin_and, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t && 5 |}] -;; - -let%expect_test "expr bin or" = - print_endline - (print_expr (Expr_bin_oper (Bin_or, Expr_ident "t", Expr_const (Const_int 5)))); - [%expect {| t || 5 |}] -;; - -let%expect_test "expr arithmetic expression" = - print_endline - (print_expr - (Expr_bin_oper - ( Bin_divide - , Expr_un_oper - ( Unary_minus - , Expr_bin_oper (Bin_sum, Expr_const (Const_int 5), Expr_const (Const_int 2)) - ) - , Expr_un_oper - ( Unary_plus - , Expr_un_oper - ( Unary_minus - , Expr_bin_oper - (Bin_sum, Expr_const (Const_int 2), Expr_const (Const_int 5)) ) ) ))); - [%expect {| -(5 + 2) / +-(2 + 5) |}] -;; - -(*** func call ***) - -let%expect_test "expr simple func call" = - print_endline (print_expr (Expr_call (Expr_ident "a", []))); - [%expect {| a() |}] -;; - -let%expect_test "expr func call with multiple complex arguments" = - print_endline - (print_expr - (Expr_call - ( Expr_ident "three" - , [ Arg_expr (Expr_ident "abc") - ; Arg_expr - (Expr_bin_oper - (Bin_sum, Expr_const (Const_int 2), Expr_const (Const_int 3))) - ; Arg_expr - (Expr_call (Expr_ident "fac", [ Arg_expr (Expr_const (Const_int 25)) ])) - ] ))); - [%expect {| three(abc, 2 + 3, fac(25)) |}] -;; - -let%expect_test "expr func call with array as a function" = - print_endline - (print_expr - (Expr_call - ( Expr_index (Expr_ident "funcs", Expr_const (Const_int 1)) - , [ Arg_expr (Expr_ident "a"); Arg_expr (Expr_ident "b") ] ))); - [%expect {| funcs[1](a, b) |}] -;; - -let%expect_test "expr nested func call" = - print_endline - (print_expr (Expr_call (Expr_call (Expr_call (Expr_ident "a", []), []), []))); - [%expect {| a()()() |}] -;; - -(*** array index ***) - -let%expect_test "expr index with constant array" = - print_endline - (print_expr - (Expr_index - ( Expr_const - (Const_array - ( 3 - , Type_int - , [ Expr_const (Const_int 1) - ; Expr_const (Const_int 2) - ; Expr_const (Const_int 3) - ] )) - , Expr_const (Const_int 0) ))); - [%expect {| [3]int{1, 2, 3}[0] |}] -;; - -let%expect_test "expr index with function call as an array" = - print_endline - (print_expr - (Expr_index - ( Expr_call - ( Expr_ident "get_array" - , [ Arg_expr (Expr_ident "a"); Arg_expr (Expr_ident "b") ] ) - , Expr_const (Const_int 1) ))); - [%expect {| get_array(a, b)[1] |}] -;; - -let%expect_test "expr nested indicies" = - print_endline - (print_expr - (Expr_index - ( Expr_index - ( Expr_index (Expr_ident "a", Expr_const (Const_int 1)) - , Expr_const (Const_int 2) ) - , Expr_const (Const_int 3) ))); - [%expect {| a[1][2][3] |}] -;; - -let%expect_test "expr check bin operators precedence" = - print_endline - (print_expr - (Expr_bin_oper - ( Bin_or - , Expr_bin_oper - ( Bin_greater_equal - , Expr_bin_oper - ( Bin_sum - , Expr_const (Const_int 1) - , Expr_bin_oper - (Bin_multiply, Expr_const (Const_int 2), Expr_const (Const_int 3)) - ) - , Expr_bin_oper - ( Bin_subtract - , Expr_un_oper (Unary_minus, Expr_const (Const_int 1)) - , Expr_bin_oper - ( Bin_divide - , Expr_chan_receive (Expr_ident "a") - , Expr_const (Const_int 2) ) ) ) - , Expr_bin_oper (Bin_and, Expr_ident "true", Expr_call (Expr_ident "check", [])) - ))); - [%expect {| 1 + 2 * 3 >= -1 - <-a / 2 || true && check() |}] -;; - -let%expect_test "expr check bin operators precedence with parens" = - print_endline - (print_expr - (Expr_bin_oper - ( Bin_multiply - , Expr_bin_oper (Bin_sum, Expr_const (Const_int 1), Expr_const (Const_int 2)) - , Expr_un_oper - ( Unary_plus - , Expr_bin_oper - ( Bin_equal - , Expr_bin_oper - ( Bin_or - , Expr_const (Const_int 3) - , Expr_bin_oper - ( Bin_subtract - , Expr_const (Const_int 2) - , Expr_bin_oper - ( Bin_divide - , Expr_call (Expr_ident "a", []) - , Expr_const (Const_int 4) ) ) ) - , Expr_bin_oper (Bin_and, Expr_ident "true", Expr_ident "false") ) ) ))); - [%expect {| (1 + 2) * +((3 || 2 - a() / 4) == (true && false)) |}] -;; - -(********** stmt **********) - -(*** break and continue ***) - -let%expect_test "stmt break" = - print_endline (print_stmt Stmt_break); - [%expect {| break |}] -;; - -let%expect_test "stmt continue" = - print_endline (print_stmt Stmt_continue); - [%expect {| continue |}] -;; - -(*** chan send and receive ***) - -let%expect_test "stmt chan send" = - print_endline - (print_stmt - (Stmt_chan_send - ("c", Expr_bin_oper (Bin_sum, Expr_ident "sum", Expr_const (Const_int 1))))); - [%expect {| c <- sum + 1 |}] -;; - -let%expect_test "stmt chan receive" = - print_endline (print_stmt (Stmt_chan_receive (Expr_ident "c"))); - [%expect {| <-c |}] -;; - -(*** incr and decr ***) - -let%expect_test "stmt incr" = - print_endline (print_stmt (Stmt_incr "a")); - [%expect {| a++ |}] -;; - -let%expect_test "stmt decr" = - print_endline (print_stmt (Stmt_decr "a")); - [%expect {| a-- |}] -;; - -(*** return ***) - -let%expect_test "stmt empty return" = - print_endline (print_stmt (Stmt_return [])); - [%expect {| return |}] -;; - -let%expect_test "stmt return with one expr" = - print_endline (print_stmt (Stmt_return [ Expr_const (Const_int 5) ])); - [%expect {| return 5 |}] -;; - -let%expect_test "stmt return with multiple exprs" = - print_endline - (print_stmt - (Stmt_return - [ Expr_bin_oper - ( Bin_sum - , Expr_bin_oper - ( Bin_multiply - , Expr_un_oper (Unary_minus, Expr_const (Const_int 5)) - , Expr_ident "_r" ) - , Expr_const (Const_int 8) ) - ; Expr_bin_oper - ( Bin_and - , Expr_un_oper (Unary_not, Expr_ident "a") - , Expr_bin_oper (Bin_or, Expr_ident "b", Expr_ident "c") ) - ])); - [%expect {| return -5 * _r + 8, !a && (b || c) |}] -;; - -(*** func call, go, defer ***) - -let%expect_test "stmt func call" = - print_endline (print_stmt (Stmt_call (Expr_ident "a", [ Arg_expr (Expr_ident "b") ]))); - [%expect {| a(b) |}] -;; - -let%expect_test "stmt go" = - print_endline (print_stmt (Stmt_go (Expr_ident "a", [ Arg_expr (Expr_ident "b") ]))); - [%expect {| go a(b) |}] -;; - -let%expect_test "stmt defer" = - print_endline (print_stmt (Stmt_defer (Expr_ident "a", [ Arg_expr (Expr_ident "b") ]))); - [%expect {| defer a(b) |}] -;; - -(*** long decl ***) - -let%expect_test "stmt long decl single var no init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_no_init - (Type_array (2, Type_array (3, Type_array (1, Type_bool))), "a", [])))); - [%expect {| var a [2][3][1]bool |}] -;; - -let%expect_test "stmt long decl mult var no init" = - print_endline - (print_stmt (Stmt_long_var_decl (Long_decl_no_init (Type_string, "a", [ "b"; "c" ])))); - [%expect {| var a, b, c string |}] -;; - -let%expect_test "stmt long decl single var no type with init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_mult_init (None, ("a", Expr_const (Const_int 5)), [])))); - [%expect {| var a = 5 |}] -;; - -let%expect_test "stmt long decl multiple var no type with init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_mult_init - ( None - , ("a", Expr_const (Const_int 5)) - , [ "b", Expr_ident "nil"; "c", Expr_const (Const_string "hi") ] )))); - [%expect {| var a, b, c = 5, nil, "hi" |}] -;; - -let%expect_test "stmt long decl one var with type with init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_mult_init - ( Some (Type_func ([], [])) - , ("a", Expr_const (Const_func { args = []; returns = []; body = [] })) - , [] )))); - [%expect {| var a func() = func() {} |}] -;; - -let%expect_test "stmt long decl mult var with type with init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_mult_init - ( Some Type_int - , ("a", Expr_const (Const_int 2)) - , [ "b", Expr_const (Const_int 3) ] )))); - [%expect {| var a, b int = 2, 3 |}] -;; - -let%expect_test "stmt long decl mult var no type with one init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_one_init - ( None - , "a" - , "b" - , [ "c" ] - , ( Expr_ident "get_three" - , [ Arg_expr (Expr_const (Const_int 1)) - ; Arg_expr (Expr_const (Const_int 2)) - ; Arg_expr (Expr_const (Const_int 3)) - ] ) )))); - [%expect {| var a, b, c = get_three(1, 2, 3) |}] -;; - -let%expect_test "stmt long decl mult var with type with one init" = - print_endline - (print_stmt - (Stmt_long_var_decl - (Long_decl_one_init - ( Some (Type_chan (Type_array (5, Type_int))) - , "a" - , "b" - , [ "c" ] - , (Expr_ident "get", []) )))); - [%expect {| var a, b, c chan [5]int = get() |}] -;; - -(*** short decl ***) - -let%expect_test "stmt short single var decl" = - print_endline - (print_stmt - (Stmt_short_var_decl (Short_decl_mult_init (("a", Expr_const (Const_int 7)), [])))); - [%expect {| a := 7 |}] -;; - -let%expect_test "stmt short mult var decl" = - print_endline - (print_stmt - (Stmt_short_var_decl - (Short_decl_mult_init - ( ("a", Expr_ident "true") - , [ "b", Expr_const (Const_int 567) - ; "c", Expr_const (Const_string "string") - ] )))); - [%expect {| a, b, c := true, 567, "string" |}] -;; - -let%expect_test "stmt short var decl mult var and one init" = - print_endline - (print_stmt - (Stmt_short_var_decl - (Short_decl_one_init - ( "a" - , "b" - , [ "c" ] - , ( Expr_ident "three" - , [ Arg_expr (Expr_ident "abc") - ; Arg_expr - (Expr_bin_oper - (Bin_sum, Expr_const (Const_int 2), Expr_const (Const_int 3))) - ; Arg_expr - (Expr_call - (Expr_ident "fac", [ Arg_expr (Expr_const (Const_int 25)) ])) - ] ) )))); - [%expect {| a, b, c := three(abc, 2 + 3, fac(25)) |}] -;; - -(*** assign ***) - -let%expect_test "stmt assign one ident lvalue, one rvalue" = - print_endline - (print_stmt - (Stmt_assign (Assign_mult_expr ((Lvalue_ident "a", Expr_const (Const_int 5)), [])))); - [%expect {| a = 5 |}] -;; - -let%expect_test "stmt assign one lvalue that is an array index, one rvalue" = - print_endline - (print_stmt - (Stmt_assign - (Assign_mult_expr - ( ( Lvalue_array_index - ( Lvalue_array_index (Lvalue_ident "a", Expr_ident "i") - , Expr_bin_oper - (Bin_sum, Expr_const (Const_int 2), Expr_const (Const_int 3)) ) - , Expr_const (Const_int 5) ) - , [] )))); - [%expect {| a[i][2 + 3] = 5 |}] -;; - -let%expect_test "stmt assign with mult lvalues and rvalues" = - print_endline - (print_stmt - (Stmt_assign - (Assign_mult_expr - ( (Lvalue_ident "a", Expr_const (Const_int 5)) - , [ Lvalue_ident "b", Expr_ident "true" - ; ( Lvalue_array_index - (Lvalue_ident "c", Expr_call (Expr_ident "get_index", [])) - , Expr_const (Const_string "hello") ) - ] )))); - [%expect {| a, b, c[get_index()] = 5, true, "hello" |}] -;; - -let%expect_test "stmt assign mult lvalues and one rvalue" = - print_endline - (print_stmt - (Stmt_assign - (Assign_one_expr - ( Lvalue_ident "a" - , Lvalue_array_index (Lvalue_ident "b", Expr_const (Const_int 0)) - , [ Lvalue_ident "c" ] - , (Expr_ident "get_three", []) )))); - [%expect {| a, b[0], c = get_three() |}] -;; - -(*** if ***) - -let%expect_test "stmt simple if no init" = - print_endline - (print_stmt - (Stmt_if - { if_init = None; if_cond = Expr_ident "true"; if_body = []; else_body = None })); - [%expect {| if true {} |}] -;; - -let%expect_test "stmt if with init" = - print_endline - (print_stmt - (Stmt_if - { if_init = - Some - (Init_decl (Short_decl_mult_init (("k", Expr_const (Const_int 0)), []))) - ; if_cond = Expr_bin_oper (Bin_equal, Expr_ident "k", Expr_ident "test") - ; if_body = [] - ; else_body = None - })); - [%expect {| if k := 0; k == test {} |}] -;; - -let%expect_test "stmt if with else that is a block" = - print_endline - (print_stmt - (Stmt_if - { if_init = None - ; if_cond = Expr_ident "cond" - ; if_body = [] - ; else_body = Some (Else_block []) - })); - [%expect {| if cond {} else {} |}] -;; - -let%expect_test "stmt if with else that is another if" = - print_endline - (print_stmt - (Stmt_if - { if_init = None - ; if_cond = Expr_ident "cond" - ; if_body = [] - ; else_body = - Some - (Else_if - { if_init = None - ; if_cond = Expr_ident "cond2" - ; if_body = [] - ; else_body = None - }) - })); - [%expect {| if cond {} else if cond2 {} |}] -;; - -(*** for ***) - -let%expect_test "stmt empty for" = - print_endline - (print_stmt - (Stmt_for { for_init = None; for_cond = None; for_post = None; for_body = [] })); - [%expect {| for {} |}] -;; - -let%expect_test "stmt for with only condition" = - print_endline - (print_stmt - (Stmt_for - { for_init = None - ; for_cond = - Some (Expr_bin_oper (Bin_greater, Expr_ident "a", Expr_const (Const_int 0))) - ; for_post = None - ; for_body = [] - })); - [%expect {| for a > 0 {} |}] -;; - -let%expect_test "stmt for with init, cond and post" = - print_endline - (print_stmt - (Stmt_for - { for_init = - Some - (Init_decl (Short_decl_mult_init (("i", Expr_const (Const_int 0)), []))) - ; for_cond = - Some (Expr_bin_oper (Bin_less, Expr_ident "i", Expr_const (Const_int 10))) - ; for_post = Some (Init_incr "i") - ; for_body = [] - })); - [%expect {| for i := 0; i < 10; i++ {} |}] -;; - -(*** block ***) - -let%expect_test "stmt empty block" = - print_endline (print_stmt (Stmt_block [])); - [%expect {| {} |}] -;; - -let%expect_test "stmt block of one stmt" = - print_endline - (print_stmt - (Stmt_block - [ Stmt_short_var_decl - (Short_decl_mult_init (("a", Expr_const (Const_int 5)), [])) - ])); - [%expect {| - { - a := 5 - } |}] -;; - -let%expect_test "stmt block of mult stmts" = - print_endline - (print_stmt - (Stmt_block - [ Stmt_short_var_decl - (Short_decl_mult_init (("a", Expr_const (Const_int 5)), [])) - ; Stmt_incr "a" - ; Stmt_call (Expr_ident "println", [ Arg_expr (Expr_ident "a") ]) - ])); - [%expect {| - { - a := 5 - a++ - println(a) - } |}] -;; - -(********** file **********) - -let%expect_test "file with simple func decl" = - print_endline - (print_file - [ Decl_func - ("main", { args = [ "a", Type_int ]; returns = [ Type_bool ]; body = [] }) - ]); - [%expect {| func main(a int) bool {} |}] -;; - -let%expect_test "file with multiple declarations" = - print_endline - (print_file - [ Decl_var (Long_decl_no_init (Type_int, "x", [])) - ; Decl_func ("main", { args = []; returns = []; body = [] }) - ]); - [%expect {| - var x int - - func main() {} |}] -;; - -let%expect_test "file with factorial func" = - print_endline - (print_file - [ Decl_func - ( "fac" - , { args = [ "n", Type_int ] - ; returns = [ Type_int ] - ; body = - [ Stmt_if - { if_init = None - ; if_cond = - Expr_bin_oper - (Bin_equal, Expr_ident "n", Expr_const (Const_int 1)) - ; if_body = [ Stmt_return [ Expr_const (Const_int 1) ] ] - ; else_body = - Some - (Else_block - [ Stmt_return - [ Expr_bin_oper - ( Bin_multiply - , Expr_ident "n" - , Expr_call - ( Expr_ident "fac" - , [ Arg_expr - (Expr_bin_oper - ( Bin_subtract - , Expr_ident "n" - , Expr_const (Const_int 1) )) - ] ) ) - ] - ]) - } - ] - } ) - ]); - [%expect - {| - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } |}] -;; - -let%expect_test "file with factorial func" = - print_endline - (print_file - [ Decl_func - ( "main" - , { args = [] - ; returns = [] - ; body = - [ Stmt_block - [ Stmt_call - (Expr_ident "fac", [ Arg_expr (Expr_const (Const_int 6)) ]) - ] - ] - } ) - ; Decl_func - ( "fac" - , { args = [ "n", Type_int ] - ; returns = [ Type_int ] - ; body = - [ Stmt_if - { if_init = None - ; if_cond = - Expr_bin_oper - (Bin_equal, Expr_ident "n", Expr_const (Const_int 1)) - ; if_body = [ Stmt_return [ Expr_const (Const_int 1) ] ] - ; else_body = - Some - (Else_block - [ Stmt_return - [ Expr_bin_oper - ( Bin_multiply - , Expr_ident "n" - , Expr_call - ( Expr_ident "fac" - , [ Arg_expr - (Expr_bin_oper - ( Bin_subtract - , Expr_ident "n" - , Expr_const (Const_int 1) )) - ] ) ) - ] - ]) - } - ] - } ) - ]); - [%expect - {| - func main() { - { - fac(6) - } - } - - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } |}] -;; diff --git a/Go/tests/parser/pp/ppUnitTests.mli b/Go/tests/parser/pp/ppUnitTests.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/parser/pp/ppUnitTests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/parser/pp/printer.ml b/Go/tests/parser/pp/printer.ml deleted file mode 100644 index 7888ca170..000000000 --- a/Go/tests/parser/pp/printer.ml +++ /dev/null @@ -1,328 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Format - -let concat = String.concat "" - -let sep_by sep list print = - let rec helper acc = function - | fst :: snd :: tl -> - let acc = concat [ acc; print fst; sep ] in - helper acc (snd :: tl) - | fst :: _ -> acc ^ print fst - | [] -> acc - in - helper "" list -;; - -let sep_by_comma list print = sep_by ", " list print -let print_ident ident = ident -let print_type = PpType.print_type - -let print_idents_with_types list = - let rec helper acc = function - | (id, t) :: snd :: tl -> - let acc = concat [ acc; id; " "; print_type t; ", " ] in - helper acc (snd :: tl) - | (id, t) :: _ -> concat [ acc; id; " "; print_type t ] - | [] -> acc - in - helper "" list -;; - -let print_func_args_returns_and_body pblock anon_func = - let { args; returns; body } = anon_func in - let print_returns = - match returns with - | [] -> "" - | [ t ] -> " " ^ print_type t - | types -> asprintf " (%s)" (sep_by_comma types print_type) - in - asprintf "(%s)%s %s" (print_idents_with_types args) print_returns (pblock body) -;; - -let print_const pexpr pblock = function - | Const_int num -> asprintf "%i" num - | Const_string str -> - let rec string_builder acc = function - | char :: tl -> - let new_piece = - match char with - | '\"' -> "\\\"" - | _ -> Char.escaped char - in - string_builder (acc ^ new_piece) tl - | [] -> acc - in - let chars = List.of_seq (String.to_seq str) in - concat [ "\""; string_builder "" chars; "\"" ] - | Const_array (size, type', inits) -> - asprintf "[%i]%s{%s}" size (print_type type') (sep_by_comma inits pexpr) - | Const_func anon_func -> "func" ^ print_func_args_returns_and_body pblock anon_func -;; - -let print_bin_op = function - | Bin_sum -> "+" - | Bin_multiply -> "*" - | Bin_subtract -> "-" - | Bin_divide -> "/" - | Bin_modulus -> "%" - | Bin_equal -> "==" - | Bin_not_equal -> "!=" - | Bin_greater -> ">" - | Bin_greater_equal -> ">=" - | Bin_less -> "<" - | Bin_less_equal -> "<=" - | Bin_and -> "&&" - | Bin_or -> "||" -;; - -let print_un_op = function - | Unary_not -> "!" - | Unary_plus -> "+" - | Unary_minus -> "-" -;; - -let precedence = function - | Expr_const _ | Expr_ident _ -> 8 - | Expr_call _ | Expr_index _ -> 7 - | Expr_un_oper _ | Expr_chan_receive _ -> 6 - | Expr_bin_oper (op, _, _) -> - (match op with - | Bin_multiply | Bin_divide | Bin_modulus -> 5 - | Bin_sum | Bin_subtract -> 4 - | Bin_equal - | Bin_not_equal - | Bin_greater - | Bin_greater_equal - | Bin_less - | Bin_less_equal -> 3 - | Bin_and -> 2 - | Bin_or -> 1) -;; - -type assoc = - | Left - | Right - -let assoc = function - | Bin_and | Bin_or -> Right - | _ -> Left -;; - -let print_func_call pexpr call = - let func, args = call in - let print_func = - if 7 > precedence func then asprintf "(%s)" (pexpr func) else pexpr func - in - let print_arg = function - | Arg_expr e -> pexpr e - | Arg_type t -> print_type t - in - asprintf "%s(%s)" print_func (sep_by_comma args print_arg) -;; - -let rec print_expr pblock = function - | Expr_const const -> print_const (print_expr pblock) pblock const - | Expr_ident id -> id - | Expr_index (array, index) as expr -> - let print_array = - if precedence expr > precedence array - then asprintf "(%s)" ((print_expr pblock) array) - else (print_expr pblock) array - in - asprintf "%s[%s]" print_array ((print_expr pblock) index) - | Expr_bin_oper (operator, left_operand, right_operand) as expr -> - let print_left = - if precedence expr > precedence left_operand - then asprintf "(%s)" ((print_expr pblock) left_operand) - else if precedence expr = precedence left_operand && assoc operator = Right - then asprintf "(%s)" ((print_expr pblock) left_operand) - else (print_expr pblock) left_operand - in - let print_oper = print_bin_op operator in - let print_right = - if precedence expr > precedence right_operand - then asprintf "(%s)" ((print_expr pblock) right_operand) - else if precedence expr = precedence right_operand && assoc operator = Left - then asprintf "(%s)" ((print_expr pblock) right_operand) - else (print_expr pblock) right_operand - in - asprintf "%s %s %s" print_left print_oper print_right - | Expr_un_oper (operator, operand) as expr -> - let print_operand = - if precedence expr > precedence operand - then asprintf "(%s)" ((print_expr pblock) operand) - else (print_expr pblock) operand - in - print_un_op operator ^ print_operand - | Expr_chan_receive operand as expr -> - let print_operand = - if precedence expr > precedence operand - then asprintf "(%s)" ((print_expr pblock) operand) - else (print_expr pblock) operand - in - asprintf "<-%s" print_operand - | Expr_call call -> print_func_call (print_expr pblock) call -;; - -let print_long_decl pblock = function - | Long_decl_no_init (type', hd, tl) -> - asprintf "var %s %s" (sep_by_comma (hd :: tl) print_ident) (print_type type') - | Long_decl_mult_init (type', hd, tl) -> - let print_type = - match type' with - | Some t -> " " ^ print_type t - | None -> "" - in - let idents, inits = List.split (hd :: tl) in - asprintf - "var %s%s = %s" - (sep_by_comma idents print_ident) - print_type - (sep_by_comma inits (print_expr pblock)) - | Long_decl_one_init (type', fst, snd, tl, init) -> - let print_type = - match type' with - | Some t -> print_type t - | None -> "" - in - asprintf - "var %s %s = %s" - (sep_by_comma (fst :: snd :: tl) print_ident) - print_type - (print_func_call (print_expr pblock) init) -;; - -let print_short_decl pblock = function - | Short_decl_mult_init (hd, tl) -> - let idents, inits = List.split (hd :: tl) in - asprintf - "%s := %s" - (sep_by_comma idents print_ident) - (sep_by_comma inits (print_expr pblock)) - | Short_decl_one_init (fst, snd, tl, init) -> - asprintf - "%s := %s" - (sep_by_comma (fst :: snd :: tl) print_ident) - (print_func_call (print_expr pblock) init) -;; - -let rec print_lvalue pblock = function - | Lvalue_ident id -> id - | Lvalue_array_index (lvalue, index) -> - asprintf "%s[%s]" (print_lvalue pblock lvalue) (print_expr pblock index) -;; - -let print_assign pblock = function - | Assign_mult_expr (hd, tl) -> - let lvalues, inits = List.split (hd :: tl) in - asprintf - "%s = %s" - (sep_by_comma lvalues (print_lvalue pblock)) - (sep_by_comma inits (print_expr pblock)) - | Assign_one_expr (fst, snd, tl, init) -> - asprintf - "%s = %s" - (sep_by_comma (fst :: snd :: tl) (print_lvalue pblock)) - (print_func_call (print_expr pblock) init) -;; - -let print_if_for_init pblock = function - | Init_assign assign -> print_assign pblock assign - | Init_decl decl -> print_short_decl pblock decl - | Init_incr id -> asprintf "%s++" id - | Init_decr id -> asprintf "%s--" id - | Init_call call -> print_func_call (print_expr pblock) call - | Init_send (chan, expr) -> asprintf "%s <- %s" chan (print_expr pblock expr) - | Init_receive chan -> asprintf "<-%s" (print_expr pblock chan) -;; - -let rec print_if pblock { if_init; if_cond; if_body; else_body } = - let print_init = - match if_init with - | Some init -> print_if_for_init pblock init ^ "; " - | None -> "" - in - let print_else_body = - match else_body with - | Some (Else_block block) -> "else " ^ pblock block - | Some (Else_if if') -> "else " ^ print_if pblock if' - | None -> "" - in - asprintf - "if %s%s %s %s" - print_init - (print_expr pblock if_cond) - (pblock if_body) - print_else_body -;; - -let print_for pblock { for_init; for_cond; for_post; for_body } = - let print_init = - match for_init with - | Some init -> print_if_for_init pblock init - | None -> "" - in - let print_cond = - match for_cond with - | Some cond -> " " ^ print_expr pblock cond - | None -> "" - in - let print_post = - match for_post with - | Some post -> " " ^ print_if_for_init pblock post - | None -> "" - in - match for_init, for_cond, for_post with - | None, None, None -> asprintf "for %s" (pblock for_body) - | None, Some _, None -> asprintf "for%s %s" print_cond (pblock for_body) - | _ -> asprintf "for %s;%s;%s %s" print_init print_cond print_post (pblock for_body) -;; - -let print_stmt pblock = function - | Stmt_long_var_decl decl -> print_long_decl pblock decl - | Stmt_short_var_decl decl -> print_short_decl pblock decl - | Stmt_assign assign -> print_assign pblock assign - | Stmt_incr id -> asprintf "%s++" id - | Stmt_decr id -> asprintf "%s--" id - | Stmt_break -> "break" - | Stmt_continue -> "continue" - | Stmt_return exprs -> "return " ^ sep_by_comma exprs (print_expr pblock) - | Stmt_block block -> pblock block - | Stmt_call call -> print_func_call (print_expr pblock) call - | Stmt_defer call -> "defer " ^ print_func_call (print_expr pblock) call - | Stmt_go call -> "go " ^ print_func_call (print_expr pblock) call - | Stmt_chan_send (chan, expr) -> asprintf "%s <- %s" chan (print_expr pblock expr) - | Stmt_chan_receive chan -> asprintf "<-%s" (print_expr pblock chan) - | Stmt_if if' -> print_if pblock if' - | Stmt_for for' -> print_for pblock for' -;; - -let rec print_block block = - match block with - | [] -> "{}" - | _ :: _ -> - Str.global_replace - (Str.regexp "\n") - "\n " - (asprintf "{\n%s" (sep_by "\n" block (print_stmt print_block))) - ^ "\n}" -;; - -let print_top_decl = function - | Decl_var decl -> print_long_decl print_block decl - | Decl_func decl -> - let ident, args_returns_and_body = decl in - asprintf - "func %s%s" - ident - (print_func_args_returns_and_body print_block args_returns_and_body) -;; - -let print_expr = print_expr print_block -let print_stmt = print_stmt print_block -let print_file file = sep_by "\n\n" file print_top_decl ^ "\n" diff --git a/Go/tests/parser/pp/printer.mli b/Go/tests/parser/pp/printer.mli deleted file mode 100644 index e92a8c2c9..000000000 --- a/Go/tests/parser/pp/printer.mli +++ /dev/null @@ -1,11 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -val print_type : type' -> string -val print_ident : ident -> string -val print_expr : expr -> string -val print_stmt : stmt -> string -val print_file : file -> string diff --git a/Go/tests/parser/qCheck/astGenerator.ml b/Go/tests/parser/qCheck/astGenerator.ml deleted file mode 100644 index 418125bff..000000000 --- a/Go/tests/parser/qCheck/astGenerator.ml +++ /dev/null @@ -1,373 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open QCheck.Gen -open Ast - -let size4 = int_range 0 4 -let list4 gen = list_size size4 gen - -let is_keyword = function - | "break" - | "func" - | "defer" - | "go" - | "chan" - | "if" - | "else" - | "continue" - | "for" - | "return" - | "var" -> true - | _ -> false -;; - -let gen_ident = - let* first_char = oneof [ char_range 'a' 'z'; char_range 'A' 'Z'; return '_' ] in - let* rest_chars = - small_string - ~gen: - (oneof [ char_range 'a' 'z'; char_range 'A' 'Z'; return '_'; char_range '0' '9' ]) - in - let ident = Base.Char.to_string first_char ^ rest_chars in - return (if is_keyword ident then "_" ^ ident else ident) -;; - -(********** types **********) - -let gen_array_type gtype = - let* size = size4 in - let* type' = gtype in - return (Type_array (size, type')) -;; - -let gen_func_type gtype = - let* arg_types = list4 gtype in - let* return_types = list4 gtype in - return (Type_func (arg_types, return_types)) -;; - -let gen_chan_type gtype = - let* type' = gtype in - return (Type_chan type') -;; - -let gen_type = - sized_size size4 - @@ fix (fun self -> - function - | 0 -> oneofl [ Type_int; Type_string; Type_bool ] - | n -> - oneof - [ return Type_int - ; return Type_string - ; return Type_bool - ; gen_array_type (self (n - 1)) - ; gen_func_type (self (n - 1)) - ; gen_chan_type (self (n - 1)) - ]) -;; - -(********** const **********) - -let gen_const_int = - let* num = big_nat in - return (Const_int num) -;; - -let gen_const_string = - let* str = small_string ~gen:printable in - return (Const_string str) -;; - -let gen_const_array gexpr = - let* size = size4 in - let* type' = gen_type in - let* inits = list4 gexpr in - return (Const_array (size, type', inits)) -;; - -let gen_anon_func gblock = - let* args = list4 (pair gen_ident gen_type) in - let* returns = list4 gen_type in - let* body = gblock in - return { args; returns; body } -;; - -let gen_const_func gblock = - let* anon_func = gen_anon_func gblock in - return (Const_func anon_func) -;; - -let gen_const gexpr gblock = - oneof [ gen_const_int; gen_const_string; gen_const_array gexpr; gen_const_func gblock ] -;; - -(********** expr **********) - -let gen_bin_op = - oneofl - [ Bin_sum - ; Bin_multiply - ; Bin_subtract - ; Bin_divide - ; Bin_modulus - ; Bin_equal - ; Bin_not_equal - ; Bin_greater - ; Bin_greater_equal - ; Bin_less - ; Bin_less_equal - ; Bin_and - ; Bin_or - ] -;; - -let gen_un_op = oneofl [ Unary_not; Unary_plus; Unary_minus ] - -let gen_expr_const gexpr gblock = - let* const = gen_const gexpr gblock in - return (Expr_const const) -;; - -let gen_expr_ident = - let* ident = gen_ident in - return (Expr_ident ident) -;; - -let gen_expr_index gexpr = - let* array = gexpr in - let* index = gexpr in - return (Expr_index (array, index)) -;; - -let gen_expr_bin_oper gexpr = - let* bin_op = gen_bin_op in - let* left_operand = gexpr in - let* right_operand = gexpr in - return (Expr_bin_oper (bin_op, left_operand, right_operand)) -;; - -let gen_expr_un_oper gexpr = - let* operator = gen_un_op in - let* operand = gexpr in - return (Expr_un_oper (operator, operand)) -;; - -let upd_func_call (e, lst) = e, List.map (fun x -> Arg_expr x) lst - -let gen_func_call gexpr upd_fcall = - let* func = gexpr in - let* args = list4 gexpr in - return (upd_fcall (func, args)) -;; - -let gen_expr_func_call gexpr = - let* call = gen_func_call gexpr upd_func_call in - return (Expr_call call) -;; - -let gen_expr gblock = - sized_size (int_range 0 10) - @@ fix (fun self -> - function - | 0 -> gen_expr_ident - | n -> - oneof - [ gen_expr_ident - ; gen_expr_const (self (n - 1)) gblock - ; gen_expr_index (self (n - 1)) - ; gen_expr_bin_oper (self (n - 1)) - ; gen_expr_un_oper (self (n - 1)) - ; map (fun chan -> Expr_chan_receive chan) (self (n - 1)) - ; gen_expr_func_call (self (n - 1)) - ]) -;; - -(********** stmt **********) - -let gen_long_decl gblock = - let* type' = gen_type in - let* first_id = gen_ident in - let* second_id = gen_ident in - let* rest_ids = list4 gen_ident in - oneof - [ return (Long_decl_no_init (type', first_id, second_id :: rest_ids)) - ; (let* first_assign = pair gen_ident (gen_expr gblock) in - let* rest_assigns = list4 (pair gen_ident (gen_expr gblock)) in - return (Long_decl_mult_init (Option.some type', first_assign, rest_assigns))) - ; (let* call = gen_func_call (gen_expr gblock) upd_func_call in - return - (Long_decl_one_init (Option.some type', first_id, second_id, rest_ids, call))) - ] -;; - -let gen_stmt_long_decl gblock = - let* decl = gen_long_decl gblock in - return (Stmt_long_var_decl decl) -;; - -let gen_short_decl gblock = - oneof - [ (let* first_assign = pair gen_ident (gen_expr gblock) in - let* rest_assigns = list4 (pair gen_ident (gen_expr gblock)) in - return (Short_decl_mult_init (first_assign, rest_assigns))) - ; (let* first_id = gen_ident in - let* second_id = gen_ident in - let* rest_ids = list4 gen_ident in - let* call = gen_func_call (gen_expr gblock) upd_func_call in - return (Short_decl_one_init (first_id, second_id, rest_ids, call))) - ] -;; - -let gen_stmt_break_continue = oneofl [ Stmt_break; Stmt_continue ] - -let gen_assign_lvalue gblock = - let gen_lvalue_ident = - let* ident = gen_ident in - return (Lvalue_ident ident) - in - sized_size size4 - @@ fix (fun self -> - function - | 0 -> gen_lvalue_ident - | n -> - oneof - [ gen_lvalue_ident - ; (let* array = self (n - 1) in - let* index = gen_expr gblock in - return (Lvalue_array_index (array, index))) - ]) -;; - -let gen_assign gblock = - oneof - [ (let* fisrt_assign = pair (gen_assign_lvalue gblock) (gen_expr gblock) in - let* rest_assigns = list4 (pair (gen_assign_lvalue gblock) (gen_expr gblock)) in - return (Assign_mult_expr (fisrt_assign, rest_assigns))) - ; (let* first_lvalue = gen_assign_lvalue gblock in - let* second_lvalue = gen_assign_lvalue gblock in - let* rest_lvalues = list4 (gen_assign_lvalue gblock) in - let* call = gen_func_call (gen_expr gblock) upd_func_call in - return (Assign_one_expr (first_lvalue, second_lvalue, rest_lvalues, call))) - ] -;; - -let gen_stmt_return gblock = - let* exprs = list4 (gen_expr gblock) in - return (Stmt_return exprs) -;; - -let gen_chan_send gblock = - let* chan = gen_ident in - let* expr = gen_expr gblock in - return (chan, expr) -;; - -let gen_stmt_call gblock = - let* call = gen_func_call (gen_expr gblock) upd_func_call in - return (Stmt_call call) -;; - -let gen_stmt_defer_go gblock = - let* call = gen_func_call (gen_expr gblock) upd_func_call in - oneofl [ Stmt_defer call; Stmt_go call ] -;; - -let gen_block gstmt = list4 gstmt - -let gen_stmt_block gstmt = - let* block = gen_block gstmt in - return (Stmt_block block) -;; - -(* for if and for init and post *) -let gen_if_for_init gstmt = - oneof - [ map (fun decl -> Init_decl decl) (gen_short_decl (gen_block gstmt)) - ; map (fun assign -> Init_assign assign) (gen_assign (gen_block gstmt)) - ; map (fun id -> Init_incr id) gen_ident - ; map (fun id -> Init_decr id) gen_ident - ; map - (fun id -> Init_call id) - (gen_func_call (gen_expr (gen_block gstmt)) upd_func_call) - ; map (fun send -> Init_send send) (gen_chan_send (gen_block gstmt)) - ; map (fun chan -> Init_receive chan) (gen_expr (gen_block gstmt)) - ] -;; - -let gen_if gstmt = - sized_size size4 - @@ fix (fun self n -> - let* if_init = option (gen_if_for_init gstmt) in - let* if_cond = gen_expr (gen_block gstmt) in - let* if_body = gen_block gstmt in - let* else_body = - match n with - | 0 -> return None - | n -> - oneof - [ return None - ; option - (oneof - [ map (fun if' -> Else_if if') (self (n - 1)) - ; map (fun block -> Else_block block) (gen_block gstmt) - ]) - ] - in - return { if_init; if_cond; if_body; else_body }) -;; - -let gen_stmt_for gstmt = - let* for_init = option (gen_if_for_init gstmt) in - let* for_cond = option (gen_expr (gen_block gstmt)) in - let* for_post = option (gen_if_for_init gstmt) in - let* for_body = gen_block gstmt in - return (Stmt_for { for_init; for_cond; for_post; for_body }) -;; - -let gen_stmt = - sized_size size4 - @@ fix (fun self -> - function - | 0 -> - oneof - [ map (fun id -> Stmt_incr id) gen_ident - ; map (fun id -> Stmt_decr id) gen_ident - ; gen_stmt_break_continue - ] - | n -> - let gblock = gen_block (self (n - 1)) in - oneof - [ map (fun id -> Stmt_incr id) gen_ident - ; map (fun id -> Stmt_decr id) gen_ident - ; gen_stmt_break_continue - ; gen_stmt_long_decl gblock - ; map (fun decl -> Stmt_short_var_decl decl) (gen_short_decl gblock) - ; map (fun assign -> Stmt_assign assign) (gen_assign gblock) - ; gen_stmt_return gblock - ; gen_stmt_block (self (n - 1)) - ; map (fun chan_send -> Stmt_chan_send chan_send) (gen_chan_send gblock) - ; map (fun chan -> Stmt_chan_receive chan) (gen_expr gblock) - ; gen_stmt_call gblock - ; gen_stmt_defer_go gblock - ; map (fun if' -> Stmt_if if') (gen_if (self (n - 1))) - ; gen_stmt_for (self (n - 1)) - ]) -;; - -(********** top decl **********) - -let gen_var_top_decl = - let* decl = gen_long_decl (gen_block gen_stmt) in - return (Decl_var decl) -;; - -let gen_func_top_decl = - let* ident = gen_ident in - let* func = gen_anon_func (gen_block gen_stmt) in - return (Decl_func (ident, func)) -;; - -let gen_file = list_size (int_range 0 10) (oneof [ gen_var_top_decl; gen_func_top_decl ]) diff --git a/Go/tests/parser/qCheck/astGenerator.mli b/Go/tests/parser/qCheck/astGenerator.mli deleted file mode 100644 index 91c1d81e6..000000000 --- a/Go/tests/parser/qCheck/astGenerator.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val gen_file : Ast.file QCheck.Gen.t diff --git a/Go/tests/parser/qCheck/astShrinker.ml b/Go/tests/parser/qCheck/astShrinker.ml deleted file mode 100644 index 0b021d912..000000000 --- a/Go/tests/parser/qCheck/astShrinker.ml +++ /dev/null @@ -1,544 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open QCheck.Shrink -open QCheck.Iter -open Ast - -let list ~shrink l = - match l with - | _ :: _ :: _ -> of_list ([ [] ] @ List.map (fun elem -> [ elem ]) l) <+> list ~shrink l - | elem :: _ -> return [] <+> (shrink elem >|= fun elem -> [ elem ]) - | [] -> empty -;; - -let shrink_ident = function - | "a" -> empty - | _ -> return "a" -;; - -let rec shrink_type = function - | Type_int | Type_string | Type_bool -> empty - | Type_array (_, type') -> - return Type_int - <+> (shrink_type type' >|= fun t -> Type_array (0, t)) - <+> return type' - | Type_func (arg_types, return_types) -> - return Type_int - <+> (list ~shrink:shrink_type arg_types - >|= fun new_arg_types -> Type_func (new_arg_types, return_types)) - <+> (list ~shrink:shrink_type return_types - >|= fun new_return_types -> Type_func (arg_types, new_return_types)) - | Type_chan type' -> - return Type_int <+> (shrink_type type' >|= fun t -> Type_chan t) <+> return type' -;; - -let shrink_id_and_type id_and_t = - let ident, type' = id_and_t in - (let* new_id = shrink_ident ident in - return (new_id, type')) - <+> let* new_type = shrink_type type' in - return (ident, new_type) -;; - -let shrink_anon_func shblock anon_func = - if anon_func = { args = []; returns = []; body = [] } - then empty - else - return { args = []; returns = []; body = [] } - <+> - let { args; returns; body } = anon_func in - (let* new_args = list ~shrink:shrink_id_and_type args in - return { args = new_args; returns; body }) - <+> (let* new_returns = - match returns with - | [ type' ] -> - let* new_type = shrink_type type' in - of_list [ []; [ new_type ] ] - | [] -> empty - | types -> - let* new_types = list ~shrink:shrink_type types in - return new_types - in - return { args; returns = new_returns; body }) - <+> - let* new_body = shblock body in - return { args; returns; body = new_body } -;; - -let shrink_const shexpr shblock = function - | Const_int num -> - (match num with - | 0 -> empty - | _ -> return (Const_int 0)) - | Const_string str -> - (match str with - | "" -> empty - | _ -> return (Const_string "")) - | Const_array (_, type', inits) -> - return (Const_int 0) - <+> (let* new_type = shrink_type type' in - return (Const_array (0, new_type, inits))) - <+> - let* new_inits = list ~shrink:shexpr inits in - return (Const_array (0, type', new_inits)) - | Const_func anon_func -> - return (Const_int 0) - <+> let* new_anon_func = shrink_anon_func shblock anon_func in - return (Const_func new_anon_func) -;; - -let shrink_func_call shexpr sharg call = - let func, args = call in - return (Expr_ident "a", []) - <+> (let* new_func = shexpr func in - return (new_func, args)) - <+> let* new_args = list ~shrink:sharg args in - return (func, new_args) -;; - -let rec shrink_expr shblock sharg = function - | Expr_ident id -> shrink_ident id >|= fun id -> Expr_ident id - | Expr_const const -> - return (Expr_ident "a") - <+> (shrink_const (shrink_expr shblock sharg) shblock const >|= fun c -> Expr_const c) - | Expr_index (array, index) -> - return (Expr_ident "a") - <+> (let* new_array = (shrink_expr shblock sharg) array in - return (Expr_index (new_array, index))) - <+> - let* new_index = (shrink_expr shblock sharg) index in - return (Expr_index (array, new_index)) - | Expr_bin_oper (op, left, right) -> - return (Expr_ident "a") - <+> return left - <+> return right - <+> (let* new_right = shrink_expr shblock sharg right in - return (Expr_bin_oper (op, left, new_right))) - <+> - let* new_left = shrink_expr shblock sharg left in - return (Expr_bin_oper (op, new_left, right)) - | Expr_un_oper (op, expr) -> - return (Expr_ident "a") - <+> return expr - <+> let* new_expr = shrink_expr shblock sharg expr in - return (Expr_un_oper (op, new_expr)) - | Expr_chan_receive expr -> - return (Expr_ident "a") - <+> return expr - <+> let* new_expr = shrink_expr shblock sharg expr in - return (Expr_chan_receive new_expr) - | Expr_call call -> - return (Expr_ident "a") - <+> let* new_call = shrink_func_call (shrink_expr shblock sharg) sharg call in - return (Expr_call new_call) -;; - -let rec shrink_args shblock = function - | Arg_expr x -> - let* new_arg = shrink_expr shblock (shrink_args shblock) x in - return (Arg_expr new_arg) - | Arg_type x -> - let* new_arg = shrink_type x in - return (Arg_type new_arg) -;; - -let shrink_id_with_expr shblock id_and_expr = - let id, expr = id_and_expr in - return ("a", Expr_ident "a") - <+> (let* new_id = shrink_ident id in - return (new_id, expr)) - <+> let* new_expr = shrink_expr shblock (shrink_args shblock) expr in - return (id, new_expr) -;; - -let shrink_type_option = function - | Some t -> return None <+> (shrink_type t >|= Option.some) - | None -> empty -;; - -let shrink_long_decl shblock = function - | Long_decl_no_init (type', first, hd :: tl) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> (let* new_type = shrink_type type' in - return (Long_decl_no_init (new_type, first, hd :: tl))) - <+> - let* new_first, new_rest = - let* new_idents = list ~shrink:shrink_ident (first :: hd :: tl) in - match new_idents with - | hd :: tl -> return (hd, tl) - | [] -> of_list [ first, []; hd, [] ] - in - return (Long_decl_no_init (type', new_first, new_rest)) - | Long_decl_no_init (type', first, []) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> (let* new_type = shrink_type type' in - return (Long_decl_no_init (new_type, first, []))) - <+> - let* new_id = shrink_ident first in - return (Long_decl_no_init (type', new_id, [])) - | Long_decl_mult_init (type', first, hd :: tl) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> (let* new_type = shrink_type_option type' in - return (Long_decl_mult_init (new_type, first, hd :: tl))) - <+> - let* new_first, new_rest = - let* new_assigns = list ~shrink:(shrink_id_with_expr shblock) (first :: hd :: tl) in - match new_assigns with - | hd :: tl -> return (hd, tl) - | [] -> of_list [ first, []; hd, [] ] - in - return (Long_decl_mult_init (type', new_first, new_rest)) - | Long_decl_mult_init (type', first, []) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> (let* new_type = shrink_type_option type' in - return (Long_decl_mult_init (new_type, first, []))) - <+> - let* new_assign = shrink_id_with_expr shblock first in - return (Long_decl_mult_init (type', new_assign, [])) - | Long_decl_one_init (type', first, second, hd :: tl, call) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> of_list - [ Long_decl_mult_init (type', (first, Expr_call call), []) - ; Long_decl_mult_init (type', (second, Expr_call call), []) - ] - <+> (let* new_type = shrink_type_option type' in - return (Long_decl_one_init (new_type, first, second, hd :: tl, call))) - <+> (let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Long_decl_one_init (type', first, second, hd :: tl, new_call))) - <+> - let* new_first, new_second, new_rest = - let* new_idents = list ~shrink:shrink_ident (first :: second :: hd :: tl) in - match new_idents with - | fst :: snd :: tl -> return (fst, snd, tl) - | _ :: [] | [] -> return (first, second, []) - in - return (Long_decl_one_init (type', new_first, new_second, new_rest, call)) - | Long_decl_one_init (type', first, second, [], call) -> - return (Long_decl_no_init (Type_int, "a", [])) - <+> of_list - [ Long_decl_mult_init (type', (first, Expr_call call), []) - ; Long_decl_mult_init (type', (second, Expr_call call), []) - ] - <+> (let* new_type = shrink_type_option type' in - return (Long_decl_one_init (new_type, first, second, [], call))) - <+> let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Long_decl_one_init (type', first, second, [], new_call)) -;; - -let shrink_short_decl shblock = function - | Short_decl_mult_init (first, hd :: tl) -> - return (Short_decl_mult_init (("a", Expr_ident "a"), [])) - <+> - let* new_first, new_rest = - let* new_assigns = list ~shrink:(shrink_id_with_expr shblock) (first :: hd :: tl) in - match new_assigns with - | hd :: tl -> return (hd, tl) - | [] -> of_list [ first, []; hd, [] ] - in - return (Short_decl_mult_init (new_first, new_rest)) - | Short_decl_mult_init (first, []) -> - return (Short_decl_mult_init (("a", Expr_ident "a"), [])) - <+> - let* new_pair = shrink_id_with_expr shblock first in - return (Short_decl_mult_init (new_pair, [])) - | Short_decl_one_init (first, second, hd :: tl, call) -> - return (Short_decl_mult_init (("a", Expr_ident "a"), [])) - <+> (let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Short_decl_one_init (first, second, hd :: tl, new_call))) - <+> of_list - [ Short_decl_mult_init ((first, Expr_call call), []) - ; Short_decl_mult_init ((second, Expr_call call), []) - ] - <+> - let* new_first, new_second, new_rest = - let* new_idents = list ~shrink:shrink_ident (first :: second :: hd :: tl) in - match new_idents with - | fst :: snd :: tl -> return (fst, snd, tl) - | _ :: [] | [] -> return (first, second, []) - in - return (Short_decl_one_init (new_first, new_second, new_rest, call)) - | Short_decl_one_init (first, second, [], call) -> - return (Short_decl_mult_init (("a", Expr_ident "a"), [])) - <+> of_list - [ Short_decl_mult_init ((first, Expr_call call), []) - ; Short_decl_mult_init ((second, Expr_call call), []) - ] - <+> let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Short_decl_one_init (first, second, [], new_call)) -;; - -let rec shrink_lvalue shblock = function - | Lvalue_ident id -> shrink_ident id >|= fun id -> Lvalue_ident id - | Lvalue_array_index (array, index) -> - return (Lvalue_ident "a") - <+> return array - <+> (let* new_array = shrink_lvalue shblock array in - return (Lvalue_array_index (new_array, index))) - <+> - let* new_index = shrink_expr shblock (shrink_args shblock) index in - return (Lvalue_array_index (array, new_index)) -;; - -let shrink_lvalue_with_expr shblock pair = - let lvalue, expr = pair in - return (Lvalue_ident "a", Expr_ident "a") - <+> (let* new_lvalue = shrink_lvalue shblock lvalue in - return (new_lvalue, expr)) - <+> - let* new_expr = shrink_expr shblock (shrink_args shblock) expr in - return (lvalue, new_expr) -;; - -let shrink_assign shblock = function - | Assign_mult_expr (first, hd :: tl) -> - return (Assign_mult_expr ((Lvalue_ident "a", Expr_ident "a"), [])) - <+> - let* new_first, new_rest = - let* new_assigns = - list ~shrink:(shrink_lvalue_with_expr shblock) (first :: hd :: tl) - in - match new_assigns with - | hd :: tl -> return (hd, tl) - | [] -> of_list [ first, []; hd, [] ] - in - return (Assign_mult_expr (new_first, new_rest)) - | Assign_mult_expr (first, []) -> - return (Assign_mult_expr ((Lvalue_ident "a", Expr_ident "a"), [])) - <+> let* new_pair = shrink_lvalue_with_expr shblock first in - return (Assign_mult_expr (new_pair, [])) - | Assign_one_expr (first, second, hd :: tl, call) -> - return (Assign_mult_expr ((Lvalue_ident "a", Expr_ident "a"), [])) - <+> return (Assign_mult_expr ((first, Expr_call call), [])) - <+> return (Assign_mult_expr ((second, Expr_call call), [])) - <+> (let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Assign_one_expr (first, second, hd :: tl, new_call))) - <+> - let* new_first, new_second, new_rest = - let* new_lvalues = - list ~shrink:(shrink_lvalue shblock) (first :: second :: hd :: tl) - in - match new_lvalues with - | fst :: snd :: tl -> return (fst, snd, tl) - | _ :: [] | [] -> return (first, second, []) - in - return (Assign_one_expr (new_first, new_second, new_rest, call)) - | Assign_one_expr (first, second, [], call) -> - return (Assign_mult_expr ((Lvalue_ident "a", Expr_ident "a"), [])) - <+> return (Assign_mult_expr ((first, Expr_call call), [])) - <+> return (Assign_mult_expr ((second, Expr_call call), [])) - <+> let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Assign_one_expr (first, second, [], new_call)) -;; - -let shrink_chan_send shblock send = - let chan, expr = send in - return ("a", Expr_ident "a") - <+> (let* new_chan = shrink_ident chan in - return (new_chan, expr)) - <+> - let* new_expr = shrink_expr shblock (shrink_args shblock) expr in - return (chan, new_expr) -;; - -let shrink_if_for_init shblock = function - | Init_decl decl -> - return (Init_incr "a") - <+> let* new_decl = shrink_short_decl shblock decl in - return (Init_decl new_decl) - | Init_assign ass -> - return (Init_incr "a") - <+> let* new_ass = shrink_assign shblock ass in - return (Init_assign new_ass) - | Init_call call -> - return (Init_incr "a") - <+> let* new_call = - shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - in - return (Init_call new_call) - | Init_decr id -> - return (Init_incr "a") - <+> let* new_id = shrink_ident id in - return (Init_decr new_id) - | Init_incr id -> - return (Init_incr "a") - <+> let* new_id = shrink_ident id in - return (Init_incr new_id) - | Init_send send -> - return (Init_incr "a") - <+> let* new_send = shrink_chan_send shblock send in - return (Init_send new_send) - | Init_receive chan -> - return (Init_incr "a") - <+> let* new_chan = shrink_expr shblock (shrink_args shblock) chan in - return (Init_receive new_chan) -;; - -let rec shrink_if shblock { if_init; if_cond; if_body; else_body } = - return { if_init = None; if_cond = Expr_ident "a"; if_body = []; else_body = None } - <+> (let* new_init = - return None - <+> - match if_init with - | Some if_init -> - return None <+> (shrink_if_for_init shblock if_init >|= Option.some) - | None -> empty - in - return { if_init = new_init; if_cond; if_body; else_body }) - <+> (let* new_cond = shrink_expr shblock (shrink_args shblock) if_cond in - return { if_init; if_cond = new_cond; if_body; else_body }) - <+> (let* new_if_body = shblock if_body in - return { if_init; if_cond; if_body = new_if_body; else_body }) - <+> let* new_else_body = - return None - <+> - match else_body with - | Some (Else_block block) -> - return None <+> (shblock block >|= fun block -> Some (Else_block block)) - | Some (Else_if if') -> - return None <+> (shrink_if shblock if' >|= fun if' -> Some (Else_if if')) - | None -> empty - in - return { if_init; if_cond; if_body; else_body = new_else_body } -;; - -let shrink_stmt shblock = function - | Stmt_break -> empty - | Stmt_continue -> empty - | Stmt_incr id -> return Stmt_break <+> (shrink_ident id >|= fun id -> Stmt_incr id) - | Stmt_decr id -> return Stmt_break <+> (shrink_ident id >|= fun id -> Stmt_decr id) - | Stmt_long_var_decl decl -> - return Stmt_break - <+> (shrink_long_decl shblock decl >|= fun decl -> Stmt_long_var_decl decl) - | Stmt_short_var_decl decl -> - return Stmt_break - <+> (shrink_short_decl shblock decl >|= fun decl -> Stmt_short_var_decl decl) - | Stmt_assign ass -> - return Stmt_break <+> (shrink_assign shblock ass >|= fun ass -> Stmt_assign ass) - | Stmt_call call -> - return Stmt_break - <+> (shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - >|= fun call -> Stmt_call call) - | Stmt_go call -> - return Stmt_break - <+> (shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - >|= fun call -> Stmt_go call) - | Stmt_defer call -> - return Stmt_break - <+> (shrink_func_call - (shrink_expr shblock (shrink_args shblock)) - (shrink_args shblock) - call - >|= fun call -> Stmt_defer call) - | Stmt_chan_send send -> - return Stmt_break - <+> (shrink_chan_send shblock send >|= fun send -> Stmt_chan_send send) - | Stmt_chan_receive chan -> - return Stmt_break - <+> (shrink_expr shblock (shrink_args shblock) chan - >|= fun chan -> Stmt_chan_receive chan) - | Stmt_return exprs -> - return Stmt_break - <+> (list ~shrink:(shrink_expr shblock (shrink_args shblock)) exprs - >|= fun exprs -> Stmt_return exprs) - | Stmt_if if' -> return Stmt_break <+> (shrink_if shblock if' >|= fun if' -> Stmt_if if') - | Stmt_for { for_init; for_cond; for_post; for_body } -> - return Stmt_break - <+> (let* new_init = - return None - <+> - match for_init with - | Some if_init -> - return None <+> (shrink_if_for_init shblock if_init >|= Option.some) - | None -> empty - in - return (Stmt_for { for_init = new_init; for_cond; for_post; for_body })) - <+> (let* new_cond = - return None - <+> - match for_cond with - | Some if_cond -> - return None - <+> (shrink_expr shblock (shrink_args shblock) if_cond >|= Option.some) - | None -> empty - in - return (Stmt_for { for_init; for_cond = new_cond; for_post; for_body })) - <+> (let* new_post = - return None - <+> - match for_post with - | Some for_post -> - return None <+> (shrink_if_for_init shblock for_post >|= Option.some) - | None -> empty - in - return (Stmt_for { for_init; for_cond; for_post = new_post; for_body })) - <+> - let* new_body = shblock for_body in - return (Stmt_for { for_init; for_cond; for_post; for_body = new_body }) - | Stmt_block block -> - return Stmt_break <+> (shblock block >|= fun block -> Stmt_block block) -;; - -let rec shrink_block block = list ~shrink:(shrink_stmt shrink_block) block - -let shrink_func_decl decl = - let ident, args_returns_and_body = decl in - return ("a", { args = []; returns = []; body = [] }) - <+> (let* new_ident = shrink_ident ident in - return (new_ident, args_returns_and_body)) - <+> let* new_args_returns_and_body = - shrink_anon_func shrink_block args_returns_and_body - in - return (ident, new_args_returns_and_body) -;; - -let shrink_top_decl = function - | Decl_func decl -> - return (Decl_var (Long_decl_no_init (Type_int, "a", []))) - <+> (shrink_func_decl decl >|= fun decl -> Decl_func decl) - | Decl_var decl -> - return (Decl_var (Long_decl_no_init (Type_int, "a", []))) - <+> (shrink_long_decl shrink_block decl >|= fun decl -> Decl_var decl) -;; - -let shrink_file file = list ~shrink:shrink_top_decl file diff --git a/Go/tests/parser/qCheck/astShrinker.mli b/Go/tests/parser/qCheck/astShrinker.mli deleted file mode 100644 index d0517f069..000000000 --- a/Go/tests/parser/qCheck/astShrinker.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val shrink_file : Ast.file -> Ast.file QCheck.Iter.t diff --git a/Go/tests/parser/qCheck/dune b/Go/tests/parser/qCheck/dune deleted file mode 100644 index 2e3058efb..000000000 --- a/Go/tests/parser/qCheck/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name qCheckRun) - (libraries parse pprinter qcheck)) - -(cram - (applies_to qCheck) - (deps ./qCheckRun.exe)) diff --git a/Go/tests/parser/qCheck/qCheck.t b/Go/tests/parser/qCheck/qCheck.t deleted file mode 100644 index c8fea8a36..000000000 --- a/Go/tests/parser/qCheck/qCheck.t +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2024, Karim Shakirov, Alexei Dmitrievtsev -SPDX-License-Identifier: MIT - - $ ./qCheckRun.exe --seed 9999999999 - seed: 9999999999 - ================================================================================ - success (ran 1 tests) diff --git a/Go/tests/parser/qCheck/qCheckRun.ml b/Go/tests/parser/qCheck/qCheckRun.ml deleted file mode 100644 index 2aac07feb..000000000 --- a/Go/tests/parser/qCheck/qCheckRun.ml +++ /dev/null @@ -1,25 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Pprinter.Printer -open Parse - -let print_file_with_ast file = - Format.asprintf "Program:\n\n%s\nAST:\n\n%s" (print_file file) (Ast.show_file file) -;; - -let arbitrary_file_manual = - QCheck.make - AstGenerator.gen_file - ~shrink:AstShrinker.shrink_file - ~print:print_file_with_ast -;; - -let manual_test = - QCheck.( - Test.make ~name:"QCheck test" ~count:10 arbitrary_file_manual (fun file -> - Result.ok file = parse parse_file (print_file file))) -;; - -let () = QCheck_base_runner.run_tests_main [ manual_test ] diff --git a/Go/tests/parser/unitTests/commonTest.ml b/Go/tests/parser/unitTests/commonTest.ml deleted file mode 100644 index bbb1f16d3..000000000 --- a/Go/tests/parser/unitTests/commonTest.ml +++ /dev/null @@ -1,181 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Pprinter.Printer -open Pp - -(********** ident **********) - -let%expect_test "ident with only letters" = - pp print_ident parse_ident {|myIdent|}; - [%expect {| myIdent |}] -;; - -let%expect_test "ident with first capital letter and underscore" = - pp print_ident parse_ident {|My_ident|}; - [%expect {| My_ident |}] -;; - -let%expect_test "blank ident" = - pp print_ident parse_ident {|_|}; - [%expect {| _ |}] -;; - -let%expect_test "ident with numbers" = - pp print_ident parse_ident {|a1b2c3|}; - [%expect {| a1b2c3 |}] -;; - -let%expect_test "ident with first char that is digit" = - pp print_ident parse_ident {|1abc|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword break" = - pp print_ident parse_ident {|break|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword func" = - pp print_ident parse_ident {|func|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword defer" = - pp print_ident parse_ident {|defer|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword go" = - pp print_ident parse_ident {|go|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword chan" = - pp print_ident parse_ident {|chan|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword if" = - pp print_ident parse_ident {|if|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword else" = - pp print_ident parse_ident {|else|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword continue" = - pp print_ident parse_ident {|continue|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword for" = - pp print_ident parse_ident {|for|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword return" = - pp print_ident parse_ident {|return|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "ident keyword var" = - pp print_ident parse_ident {|var|}; - [%expect {| : syntax error |}] -;; - -(********** type **********) - -let%expect_test "incorrect type" = - pp print_type parse_type {|blablablablabla|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "type int" = - pp print_type parse_type {|int|}; - [%expect {| int |}] -;; - -let%expect_test "type bool" = - pp print_type parse_type {|bool|}; - [%expect {| bool |}] -;; - -let%expect_test "type string" = - pp print_type parse_type {|string|}; - [%expect {| string |}] -;; - -let%expect_test "type array of arrays" = - pp print_type parse_type {|[4][0]string|}; - [%expect {| [4][0]string |}] -;; - -let%expect_test "type array of functions" = - pp print_type parse_type {|[4]func()|}; - [%expect {| [4]func() |}] -;; - -let%expect_test "type simple func" = - pp print_type parse_type {|func()|}; - [%expect {| func() |}] -;; - -let%expect_test "type simple func with brackets" = - pp print_type parse_type {|func()()|}; - [%expect {| func() |}] -;; - -let%expect_test "type simple func with brackets and ws" = - pp print_type parse_type {|func() /* some comment */ ()|}; - [%expect {| func() |}] -;; - -let%expect_test "type func with one arg and without returns" = - pp print_type parse_type {|func(int)|}; - [%expect {| func(int) |}] -;; - -let%expect_test "type func with mult args and without returns" = - pp print_type parse_type {|func(int, string, bool, [4]int)|}; - [%expect {| - func(int, string, bool, [4]int) |}] -;; - -let%expect_test "type func with one return" = - pp print_type parse_type {|func() int|}; - [%expect {| func() int |}] -;; - -let%expect_test "type func with multiple returns" = - pp print_type parse_type {|func() (int, string)|}; - [%expect {| func() (int, string) |}] -;; - -let%expect_test "type func that gets func and returns func" = - pp print_type parse_type {|func(func(int) string) func([4][5]int)|}; - [%expect {| - func(func(int) string) func([4][5]int) |}] -;; - -let%expect_test "type func that returns func that returns func..." = - pp print_type parse_type {|func() func() func() func() func() func()|}; - [%expect {| - func() func() func() func() func() func() |}] -;; - -let%expect_test "type bidirectional chanel" = - pp print_type parse_type {|chan int|}; - [%expect {| - chan int |}] -;; - -let%expect_test "type with parens" = - pp print_type parse_type {|[3]([2]((func())))|}; - [%expect {| - [3][2]func() |}] -;; diff --git a/Go/tests/parser/unitTests/commonTest.mli b/Go/tests/parser/unitTests/commonTest.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/parser/unitTests/commonTest.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/parser/unitTests/dune b/Go/tests/parser/unitTests/dune deleted file mode 100644 index 03e3bdc82..000000000 --- a/Go/tests/parser/unitTests/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name parserUnitTest) - (libraries ast parse pprinter) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) diff --git a/Go/tests/parser/unitTests/exprTest.ml b/Go/tests/parser/unitTests/exprTest.ml deleted file mode 100644 index 2873ff0fc..000000000 --- a/Go/tests/parser/unitTests/exprTest.ml +++ /dev/null @@ -1,410 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Pprinter.Printer -open Pp - -(********** const int and string **********) - -let%expect_test "const int" = - pp print_expr parse_expr {|256|}; - [%expect {| 256 |}] -;; - -let%expect_test "zero" = - pp print_expr parse_expr {|0|}; - [%expect {| 0 |}] -;; - -let%expect_test "not digit in int" = - pp print_expr parse_expr {|123,321|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "very big int" = - pp print_expr parse_expr {|9999999999999999999999999999999999999999|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "const string" = - pp print_expr parse_expr {|"my_string"|}; - [%expect {| "my_string" |}] -;; - -let%expect_test "const empty string" = - pp print_expr parse_expr {|""|}; - [%expect {| "" |}] -;; - -let%expect_test "string with '\n'" = - pp print_expr parse_expr {|"Hello\n"|}; - [%expect {| "Hello\n" |}] -;; - -let%expect_test "const string with escaped backslash" = - pp print_expr parse_expr {|"\\"|}; - [%expect {| "\\" |}] -;; - -let%expect_test "const string with escaped quote" = - pp print_expr parse_expr {|"\""|}; - [%expect {| "\"" |}] -;; - -(********** arithmetics **********) - -let%expect_test "unary plus" = - pp print_expr parse_expr {|+5|}; - [%expect {| +5 |}] -;; - -let%expect_test "unary minus" = - pp print_expr parse_expr {|-5|}; - [%expect {| -5 |}] -;; - -let%expect_test "unary not" = - pp print_expr parse_expr {|!t|}; - [%expect {| !t |}] -;; - -let%expect_test "unary receive" = - pp print_expr parse_expr {|<-t|}; - [%expect {| <-t |}] -;; - -let%expect_test "multiple unary operators" = - pp print_expr parse_expr {|-+!--!+t|}; - [%expect {| - -+!--!+t |}] -;; - -let%expect_test "sum binop test" = - pp print_expr parse_expr {|4 + i|}; - [%expect {| 4 + i |}] -;; - -let%expect_test "sub binop test" = - pp print_expr parse_expr {|a - 5|}; - [%expect {| a - 5 |}] -;; - -let%expect_test "mul binop test" = - pp print_expr parse_expr {|t * 5|}; - [%expect {| t * 5 |}] -;; - -let%expect_test "div binop test" = - pp print_expr parse_expr {|t / 5|}; - [%expect {| t / 5 |}] -;; - -let%expect_test "modulus binop test" = - pp print_expr parse_expr {|t % 5|}; - [%expect {| t % 5 |}] -;; - -let%expect_test "equality binop test" = - pp print_expr parse_expr {|t == 5|}; - [%expect {| t == 5 |}] -;; - -let%expect_test "non equality binop test" = - pp print_expr parse_expr {|t != 5|}; - [%expect {| t != 5 |}] -;; - -let%expect_test "less binop test" = - pp print_expr parse_expr {|t < 5|}; - [%expect {| t < 5 |}] -;; - -let%expect_test "greater binop test" = - pp print_expr parse_expr {|t > 5|}; - [%expect {| t > 5 |}] -;; - -let%expect_test "greater or equal binop test" = - pp print_expr parse_expr {|t >= 5|}; - [%expect {| - t >= 5 |}] -;; - -let%expect_test "less or equal binop test" = - pp print_expr parse_expr {|t <= 5|}; - [%expect {| - t <= 5 |}] -;; - -let%expect_test "and binop test" = - pp print_expr parse_expr {|t && 5|}; - [%expect {| - t && 5 |}] -;; - -let%expect_test "or binop test" = - pp print_expr parse_expr {|t || 5|}; - [%expect {| - t || 5 |}] -;; - -let%expect_test "expr with multiple unary minuses with parens" = - pp print_expr parse_expr {|+(+(+1))|}; - [%expect {| - +++1|}] -;; - -let%expect_test "expr with multiple unary minuses with parens" = - pp print_expr parse_expr {|-(-(-1))|}; - [%expect {| - ---1|}] -;; - -let%expect_test "unary and binary exprs combined" = - pp print_expr parse_expr {|-(5 + 2) / +-(2 + 5)|}; - [%expect {| - -(5 + 2) / +-(2 + 5)|}] -;; - -(********** const array **********) - -let%expect_test "expr simple array" = - pp print_expr parse_expr {|[3]int{}|}; - [%expect {| [3]int{} |}] -;; - -let%expect_test "expr array with init" = - pp print_expr parse_expr {|[3]int{1, 2}|}; - [%expect {| - [3]int{1, 2} |}] -;; - -let%expect_test "expr array with ..." = - pp print_expr parse_expr {|[...]int{1, 2, 3, 4}|}; - [%expect {| - [4]int{1, 2, 3, 4} |}] -;; - -let%expect_test "expr const array with very big size" = - pp print_expr parse_expr {|[9999999999999999999999999999999]int{}|}; - [%expect {| : syntax error |}] -;; - -(********** ident **********) - -let%expect_test "expr ident false" = - pp print_expr parse_expr {|false|}; - [%expect {| - false|}] -;; - -let%expect_test "expr ident nil" = - pp print_expr parse_expr {|nil|}; - [%expect {| - nil|}] -;; - -let%expect_test "expr ident" = - pp print_expr parse_expr {|abcdefg__|}; - [%expect {| - abcdefg__|}] -;; - -let%expect_test "expr ident in parens" = - pp print_expr parse_expr {|(abc)|}; - [%expect {| - abc|}] -;; - -let%expect_test "expr ident in multiple parens" = - pp print_expr parse_expr {|(((abc)))|}; - [%expect {| - abc|}] -;; - -(********** func call **********) - -let%expect_test "simple func call" = - pp print_expr parse_expr "a()"; - [%expect {| - a()|}] -;; - -let%expect_test "func call with multiple complex arguments" = - pp print_expr parse_expr "three(abc, 2 + 3, fac(25))"; - [%expect {| - three(abc, 2 + 3, fac(25))|}] -;; - -let%expect_test "nested func call" = - pp print_expr parse_expr "a()()()"; - [%expect {| - a()()()|}] -;; - -(********** index **********) - -let%expect_test "index with idents" = - pp print_expr parse_expr {|array[i]|}; - [%expect {| array[i] |}] -;; - -let%expect_test "index with int" = - pp print_expr parse_expr {|array[1]|}; - [%expect {| array[1] |}] -;; - -let%expect_test "index with constant array" = - pp print_expr parse_expr {|[3]int{1, 2, 3}[0]|}; - [%expect {| - [3]int{1, 2, 3}[0] |}] -;; - -let%expect_test "index with function call in index" = - pp print_expr parse_expr {|array[get_index(a, b)]|}; - [%expect {| - array[get_index(a, b)] |}] -;; - -let%expect_test "index with function call as an array" = - pp print_expr parse_expr {|get_array(a, b)[1]|}; - [%expect {| - get_array(a, b)[1] |}] -;; - -let%expect_test "nested indicies" = - pp print_expr parse_expr {|a[1][2][3]|}; - [%expect {| - a[1][2][3] |}] -;; - -(********** complex exprs **********) - -let%expect_test "bin operators precedence test" = - pp print_expr parse_expr "1 + 2 * 3 >= -1 - <-a / 2 || true && check()"; - [%expect {| - 1 + 2 * 3 >= -1 - <-a / 2 || true && check()|}] -;; - -let%expect_test "bin operators with parens precedence test" = - pp print_expr parse_expr "(1 + 2) * +((3 || 2 - a() / 4) == (true && false))"; - [%expect {| - (1 + 2) * +((3 || 2 - a() / 4) == (true && false))|}] -;; - -let%expect_test "expr right associativity test 1" = - pp print_expr parse_expr {|(a || b) || c|}; - [%expect {| (a || b) || c |}] -;; - -let%expect_test "expr right associativity test 2" = - pp print_expr parse_expr {|a || (b || c)|}; - [%expect {| a || b || c |}] -;; - -let%expect_test "expr left associativity test 1" = - pp print_expr parse_expr {|a + (b + c)|}; - [%expect {| a + (b + c) |}] -;; - -let%expect_test "expr left associativity test 2" = - pp print_expr parse_expr {|(a + b) + c|}; - [%expect {| a + b + c |}] -;; - -let%expect_test "expr logical operations" = - pp print_expr parse_expr {|a && (b || c)|}; - [%expect {| - a && (b || c)|}] -;; - -let%expect_test "expr logical operations with binops" = - pp print_expr parse_expr {|a > b + 1 && (b + 2 <= c)|}; - [%expect {| - a > b + 1 && b + 2 <= c|}] -;; - -let%expect_test "expr with multiple redundant parens" = - pp print_expr parse_expr {|((((((((4)) + i * ((5) + ((8) + p))))))))|}; - [%expect {| - 4 + i * (5 + (8 + p))|}] -;; - -let%expect_test "expr bin mult and sum" = - pp print_expr parse_expr {|-5 * _r + 8|}; - [%expect {| - -5 * _r + 8|}] -;; - -let%expect_test "expr un and bin opers" = - pp print_expr parse_expr {|5 - -4|}; - [%expect {| - 5 - -4|}] -;; - -let%expect_test "expr_call test" = - pp print_expr parse_expr "fac(4 + fac(4 + 4))"; - [%expect {| - fac(4 + fac(4 + 4))|}] -;; - -let%expect_test "fac_piece1 test" = - pp print_expr parse_expr "n * fac(n-1)"; - [%expect {| - n * fac(n - 1)|}] -;; - -let%expect_test "unary_min test" = - pp print_expr parse_expr "-n + 2 + -1"; - [%expect {| - -n + 2 + -1|}] -;; - -let%expect_test "chanel receive test" = - pp print_expr parse_expr "<-c"; - [%expect {| - <-c|}] -;; - -let%expect_test "chanel receive with unop test" = - pp print_expr parse_expr "-<-c"; - [%expect {| - -<-c|}] -;; - -let%expect_test "chanel receive with binop test" = - pp print_expr parse_expr "-<-c + 1"; - [%expect {| - -<-c + 1|}] -;; - -let%expect_test "chanel neseted receive test" = - pp print_expr parse_expr "<-<-<-c"; - [%expect {| - <-<-<-c|}] -;; - -(********** anon func **********) - -let%expect_test "empty anon func" = - pp print_expr parse_expr {|func() {}|}; - [%expect {| func() {} |}] -;; - -let%expect_test "anon func with one arg and one return value" = - pp print_expr parse_expr {|func(a int) int { return a }|}; - [%expect {| - func(a int) int { - return a - } |}] -;; - -let%expect_test "anon func with mult args and return values" = - pp print_expr parse_expr {|func(a int, b string) (int, string) { return a, b }|}; - [%expect {| - func(a int, b string) (int, string) { - return a, b - } |}] -;; diff --git a/Go/tests/parser/unitTests/exprTest.mli b/Go/tests/parser/unitTests/exprTest.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/parser/unitTests/exprTest.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/parser/unitTests/pp.ml b/Go/tests/parser/unitTests/pp.ml deleted file mode 100644 index 421daf305..000000000 --- a/Go/tests/parser/unitTests/pp.ml +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -let pp printer parser str = - match Angstrom.parse_string ~consume:Angstrom.Consume.All parser str with - | Ok res -> print_endline (printer res) - | Error _ -> print_endline ": syntax error" -;; diff --git a/Go/tests/parser/unitTests/pp.mli b/Go/tests/parser/unitTests/pp.mli deleted file mode 100644 index 6a6d9d422..000000000 --- a/Go/tests/parser/unitTests/pp.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -val pp : ('a -> string) -> 'a Angstrom.t -> string -> unit diff --git a/Go/tests/parser/unitTests/stmtTest.ml b/Go/tests/parser/unitTests/stmtTest.ml deleted file mode 100644 index d76a0df27..000000000 --- a/Go/tests/parser/unitTests/stmtTest.ml +++ /dev/null @@ -1,518 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Pprinter.Printer -open Pp - -(********** break, continue, go, defer, chanel send and receive **********) - -let%expect_test "break stmt" = - pp print_stmt parse_stmt {|break|}; - [%expect {| break |}] -;; - -let%expect_test "continue stmt" = - pp print_stmt parse_stmt {|continue|}; - [%expect {| continue |}] -;; - -let%expect_test "stmt defer with func" = - pp print_stmt parse_stmt {|defer - call(abc)|}; - [%expect {| - defer call(abc) |}] -;; - -let%expect_test "stmt defer with expr that is not a func" = - pp print_stmt parse_stmt {|defer 2 + 2 * 5|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt go with func" = - pp print_stmt parse_stmt {|go - call(abc)|}; - [%expect {| - go call(abc) |}] -;; - -let%expect_test "stmt go with expr that is not a func" = - pp print_stmt parse_stmt {|go 2 + 2 * 5|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt chan send" = - pp print_stmt parse_stmt {|c <- sum + 1|}; - [%expect {| - c <- sum + 1 |}] -;; - -let%expect_test "stmt chan receive" = - pp print_stmt parse_stmt {|<-c|}; - [%expect {| - <-c |}] -;; - -(********** incr and decr **********) - -let%expect_test "incr stmt" = - pp print_stmt parse_stmt {|a++|}; - [%expect {| a++ |}] -;; - -let%expect_test "incr stmt with ws_line" = - pp print_stmt parse_stmt {|a /* some comment */ ++|}; - [%expect {| a++ |}] -;; - -let%expect_test "incr stmt with blank ident" = - pp print_stmt parse_stmt {|_++|}; - [%expect {| _++ |}] -;; - -let%expect_test "decr stmt" = - pp print_stmt parse_stmt {|a--|}; - [%expect {| a-- |}] -;; - -let%expect_test "decr stmt with ws_line" = - pp print_stmt parse_stmt {|a /* some comment */ --|}; - [%expect {| a-- |}] -;; - -let%expect_test "decr stmt with blank ident" = - pp print_stmt parse_stmt {|_--|}; - [%expect {| _-- |}] -;; - -(********** return **********) - -let%expect_test "return without anything" = - pp print_stmt parse_stmt {|return|}; - [%expect {| return |}] -;; - -let%expect_test "return with one expr" = - pp print_stmt parse_stmt {|return 5|}; - [%expect {| return 5 |}] -;; - -let%expect_test "return with multiple exprs and ws" = - pp - print_stmt - parse_stmt - {|return 3 , - a , // some comment - true /* RARAVARV */ , nil|}; - [%expect {| - return 3, a, true, nil |}] -;; - -let%expect_test "return with multiple complex exprs" = - pp print_stmt parse_stmt {|return -5 * _r + 8, !a && (b || c)|}; - [%expect {| - return -5 * _r + 8, !a && (b || c) |}] -;; - -(********** func call **********) - -let%expect_test "stmt func call with one simple arg" = - pp print_stmt parse_stmt {|my_func(5)|}; - [%expect {| my_func(5) |}] -;; - -let%expect_test "stmt func callmultiple args" = - pp print_stmt parse_stmt {|my_func(5, a, nil)|}; - [%expect {| - my_func(5, a, nil) |}] -;; - -let%expect_test "stmt func call with complex expressions and comments" = - pp print_stmt parse_stmt {|fac( fac(2 + 2), - 34 * 75, - // aovnervo - !a)|}; - [%expect {| - fac(fac(2 + 2), 34 * 75, !a) |}] -;; - -(********** assign **********) - -let%expect_test "stmt assign one lvalue, one rvalue" = - pp print_stmt parse_stmt {|a = 5|}; - [%expect {| - a = 5 |}] -;; - -let%expect_test "stmt assign one lvalue, no rvalue" = - pp print_stmt parse_stmt {|a =|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt assign no lvalue, one rvalue" = - pp print_stmt parse_stmt {|= 5|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt assign one lvalue that is an array index, one rvalue" = - pp print_stmt parse_stmt {|a[i][2 + 3] = 5|}; - [%expect {| - a[i][2 + 3] = 5 |}] -;; - -let%expect_test "stmt assign with mult equal number of lvalues and rvalues and ws" = - pp - print_stmt - parse_stmt - {|a, - b , // comment - c[get_index()] = - - 5, /* comment////// */true, - "hello"|}; - [%expect {| - a, b, c[get_index()] = 5, true, "hello" |}] -;; - -let%expect_test "stmt assign mult lvalues and one rvalue that is a func call" = - pp print_stmt parse_stmt {|a, b[0] ,c = get_three()|}; - [%expect {| - a, b[0], c = get_three() |}] -;; - -let%expect_test "stmt assign mult lvalues and one rvalue that is not a func call" = - pp print_stmt parse_stmt {|a, b ,c = abc|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "stmt assign mult unequal lvalues and rvalues" = - pp print_stmt parse_stmt {|a, b ,c = 2, 3, 4, 5 , 6|}; - [%expect {| : syntax error |}] -;; - -(********** long var decl **********) - -let%expect_test "stmt long single var decl without init" = - pp print_stmt parse_stmt {|var a string|}; - [%expect {| - var a string |}] -;; - -let%expect_test "stmt long single var decl without init and type" = - pp print_stmt parse_stmt {|var a|}; - [%expect {| : syntax error |}] -;; - -let%expect_test "stmt long single var decl with type, without vars and init" = - pp print_stmt parse_stmt {|var [0]int |}; - [%expect {| : syntax error |}] -;; - -let%expect_test "stmt long single var decl without init with mult array type" = - pp print_stmt parse_stmt {|var a [2][3][1]bool|}; - [%expect {| - var a [2][3][1]bool |}] -;; - -let%expect_test "stmt long single var decl no type" = - pp print_stmt parse_stmt {|var a = 5|}; - [%expect {| - var a = 5 |}] -;; - -let%expect_test "stmt long decl no type and var" = - pp print_stmt parse_stmt {|var = 5|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt long mult var decl no type" = - pp print_stmt parse_stmt {|var a, b, c = 5, nil, "hi"|}; - [%expect {| - var a, b, c = 5, nil, "hi" |}] -;; - -let%expect_test "stmt long single var decl with type" = - pp print_stmt parse_stmt {|var a func() = func() {}|}; - [%expect {| - var a func() = func() {} |}] -;; - -let%expect_test "stmt long mult var decl with type" = - pp print_stmt parse_stmt {|var a, b int = 2, 3|}; - [%expect {| - var a, b int = 2, 3 |}] -;; - -let%expect_test "stmt long mult var decl with type" = - pp print_stmt parse_stmt {|var a, b, c [2]int = [2]int{1, 2}, [2]int{}, [2]int{10, 20}|}; - [%expect {| - var a, b, c [2]int = [2]int{1, 2}, [2]int{}, [2]int{10, 20} |}] -;; - -let%expect_test "stmt long mult var decl without type" = - pp print_stmt parse_stmt {|var a, b, c = 5, nil, "hi"|}; - [%expect {| - var a, b, c = 5, nil, "hi" |}] -;; - -let%expect_test "stmt long var decl mult lvalues and one rvalue that is a func call" = - pp print_stmt parse_stmt {|var a, b, c = get_three(1, 2, 3)|}; - [%expect {| - var a, b, c = get_three(1, 2, 3) |}] -;; - -let%expect_test "stmt long var decl mult lvalues and one rvalue that is not a func call" = - pp print_stmt parse_stmt {|var a, b, c = true|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt long var decl unequal lvalues and rvalues" = - pp print_stmt parse_stmt {|var a, b, c = 1, 2, 3, 4|}; - [%expect {| - : syntax error |}] -;; - -(********** short var decl **********) - -let%expect_test "stmt short single var decl" = - pp print_stmt parse_stmt {|a := 7|}; - [%expect {| - a := 7 |}] -;; - -let%expect_test "stmt short decl without init" = - pp print_stmt parse_stmt {|a :=|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt short decl with init, without var" = - pp print_stmt parse_stmt {|:= 5|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt short mult var decl" = - pp print_stmt parse_stmt {|a, b, c := true, 567, "string"|}; - [%expect {| - a, b, c := true, 567, "string" |}] -;; - -let%expect_test "stmt short var decl mult lvalues and one rvalue that is a func call" = - pp print_stmt parse_stmt {|a, b, c := three(abc, 2 + 3, fac(25))|}; - [%expect {| - a, b, c := three(abc, 2 + 3, fac(25)) |}] -;; - -let%expect_test "stmt short var decl mult lvalues and one rvalue that is not a func call" = - pp print_stmt parse_stmt {|a, b, c := abcdefg"|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt short var decl unequal lvalues and rvalues" = - pp print_stmt parse_stmt {|a, b, c := 1, 2, 3, 4|}; - [%expect {| - : syntax error |}] -;; - -(********** block **********) - -let%expect_test "stmt empty block" = - pp print_stmt parse_stmt {|{}|}; - [%expect {| - {} |}] -;; - -let%expect_test "stmt block of one stmt" = - pp print_stmt parse_stmt {|{ a := 5 }|}; - [%expect {| - { - a := 5 - } |}] -;; - -let%expect_test "stmt block of mult stmts, separated by semicolon" = - pp print_stmt parse_stmt {|{ a := 5; a++; println(a) }|}; - [%expect {| - { - a := 5 - a++ - println(a) - } |}] -;; - -let%expect_test "stmt block of mult stmts, separated by newlines" = - pp - print_stmt - parse_stmt - {|{ var hi string = "hi" - // string that says hi - go get_int(hi)}|}; - [%expect {| - { - var hi string = "hi" - go get_int(hi) - } |}] -;; - -(********** if **********) - -let%expect_test "stmt simple if" = - pp print_stmt parse_stmt {|if true {}|}; - [%expect {| - if true {} |}] -;; - -let%expect_test "stmt if with empty init" = - pp print_stmt parse_stmt {|if ; call() {}|}; - [%expect {| - if call() {} |}] -;; - -let%expect_test "stmt if with short decl init" = - pp print_stmt parse_stmt {|if k := 0; k == test {}|}; - [%expect {| - if k := 0; k == test {} |}] -;; - -let%expect_test "stmt if with assign init" = - pp print_stmt parse_stmt {|if k = 0; k == test {}|}; - [%expect {| - if k = 0; k == test {} |}] -;; - -let%expect_test "stmt if with incr init" = - pp print_stmt parse_stmt {|if k++; k == test {}|}; - [%expect {| - if k++; k == test {} |}] -;; - -let%expect_test "stmt if with decr init" = - pp print_stmt parse_stmt {|if k--; k == test {}|}; - [%expect {| - if k--; k == test {} |}] -;; - -let%expect_test "stmt if with call init" = - pp print_stmt parse_stmt {|if run_test(); true {}|}; - [%expect {| - if run_test(); true {} |}] -;; - -let%expect_test "stmt if with chan send init" = - pp print_stmt parse_stmt {|if c <- 5; true {}|}; - [%expect {| - if c <- 5; true {} |}] -;; - -let%expect_test "stmt if with chan receive init" = - pp print_stmt parse_stmt {|if <-c; true {}|}; - [%expect {| - if <-c; true {} |}] -;; - -let%expect_test "stmt if with wrong init" = - pp print_stmt parse_stmt {|if var a = 5; cond {}|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt if with else that is a block" = - pp print_stmt parse_stmt {|if cond {} else {}|}; - [%expect {| - if cond {} else {} |}] -;; - -let%expect_test "stmt if with else that is another if" = - pp print_stmt parse_stmt {|if cond {} else if cond2 {}|}; - [%expect {| - if cond {} else if cond2 {} |}] -;; - -let%expect_test "stmt if with wrong else" = - pp print_stmt parse_stmt {|if cond {} else do_smth()|}; - [%expect {| - : syntax error |}] -;; - -(********** for **********) - -let%expect_test "stmt empty for" = - pp print_stmt parse_stmt {|for {}|}; - [%expect {| - for {} |}] -;; - -let%expect_test "stmt for with only conition" = - pp print_stmt parse_stmt {|for a > 0 {}|}; - [%expect {| - for a > 0 {} |}] -;; - -let%expect_test "stmt empty for with semicolons" = - pp print_stmt parse_stmt {|for ;; {}|}; - [%expect {| - for {} |}] -;; - -let%expect_test "stmt default for with short decl in init and post" = - pp print_stmt parse_stmt {|for i := 0;; j := i + 1 {}|}; - [%expect {| - for i := 0;; j := i + 1 {} |}] -;; - -let%expect_test "stmt default for with assign in init and post" = - pp print_stmt parse_stmt {|for i = call();; i = i + 1 {}|}; - [%expect {| - for i = call();; i = i + 1 {} |}] -;; - -let%expect_test "stmt default for with call in init and post" = - pp print_stmt parse_stmt {|for start();; finish() {}|}; - [%expect {| - for start();; finish() {} |}] -;; - -let%expect_test "stmt default for with incr in init and post" = - pp print_stmt parse_stmt {|for i++;; i++ {}|}; - [%expect {| - for i++;; i++ {} |}] -;; - -let%expect_test "stmt default for with decr in init and post" = - pp print_stmt parse_stmt {|for i--;; i-- {}|}; - [%expect {| - for i--;; i-- {} |}] -;; - -let%expect_test "stmt default for with chan send in init and post" = - pp print_stmt parse_stmt {|for c <- 5;; c <- 5 {}|}; - [%expect {| - for c <- 5;; c <- 5 {} |}] -;; - -let%expect_test "stmt default for with chan receive in init and post" = - pp print_stmt parse_stmt {|for <-c;; <-c {}|}; - [%expect {| - for <-c;; <-c {} |}] -;; - -let%expect_test "stmt default for with invalid stmt in init and post" = - pp print_stmt parse_stmt {|for go call(); i > 0; return {}|}; - [%expect {| - : syntax error |}] -;; - -let%expect_test "stmt default for with valid init and invalid post" = - pp print_stmt parse_stmt {|for call(); i > 0; break|}; - [%expect {| - : syntax error |}] -;; diff --git a/Go/tests/parser/unitTests/stmtTest.mli b/Go/tests/parser/unitTests/stmtTest.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/parser/unitTests/stmtTest.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/parser/unitTests/topLevelTest.ml b/Go/tests/parser/unitTests/topLevelTest.ml deleted file mode 100644 index 27f522c7c..000000000 --- a/Go/tests/parser/unitTests/topLevelTest.ml +++ /dev/null @@ -1,140 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Pprinter.Printer -open Pp - -let%expect_test "file with one var decl with ws" = - pp print_file parse_file {| - - /* hello */ var a int -// hey - -|}; - [%expect {|var a int |}] -;; - -let%expect_test "file with multiple var decls separated by semicolon" = - pp print_file parse_file {|var a, b int;var c = "hello"|}; - [%expect {| - var a, b int - - var c = "hello" |}] -;; - -let%expect_test "file with one simple func decl" = - pp print_file parse_file {|func _() {}|}; - [%expect {| - func _() {} |}] -;; - -let%expect_test "file with one default func decl" = - pp print_file parse_file {|func sum3(a, b, c int) int { - return a + b + c - }|}; - [%expect {| - func sum3(a int, b int, c int) int { - return a + b + c - } |}] -;; - -let%expect_test "file with mixed func and var decls" = - pp - print_file - parse_file - {| - -var a = 5 - -func test ( -// hey -) ( - -/* hello */ ) { - return -} - -func id(a int) (int) { - return a -} - -var f int - -func main() { - defer test() - -go println(id(10)) -} - -|}; - [%expect - {| - var a = 5 - - func test() { - return - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - go println(id(10)) - } |}] -;; - -let%expect_test "file with factorial func" = - pp - print_file - parse_file - {| - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - }|}; - [%expect - {| - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } |}] -;; - -let%expect_test "tmp" = - pp - print_file - parse_file - {| - var a, b, c chan [5]int = get() - - var x int - - func main(a2 int) bool { - var x int - } - - func main1(a1 int, c int, b int) bool {} |}; - [%expect - {| - var a, b, c chan [5]int = get() - - var x int - - func main(a2 int) bool { - var x int - } - - func main1(a1 int, c int, b int) bool {} |}] -;; diff --git a/Go/tests/parser/unitTests/topLevelTest.mli b/Go/tests/parser/unitTests/topLevelTest.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/parser/unitTests/topLevelTest.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Go/tests/repl/dune b/Go/tests/repl/dune deleted file mode 100644 index 3989c3061..000000000 --- a/Go/tests/repl/dune +++ /dev/null @@ -1,3 +0,0 @@ -(cram - (applies_to repl) - (deps ../../bin/interpret.exe)) diff --git a/Go/tests/repl/repl.t b/Go/tests/repl/repl.t deleted file mode 100644 index 862cefa36..000000000 --- a/Go/tests/repl/repl.t +++ /dev/null @@ -1,37 +0,0 @@ -Copyright 2024, Karim Shakirov, Alexei Dmitrievtsev -SPDX-License-Identifier: MIT - - $ ../../bin/interpret.exe --help - Go subset interpreter - - Usage: interpret.exe - - If filepath isn't specified, REPL will start running and the program will be read from stdin - In REPL mode type: - - "guit" - to quit REPL mode - "help" - to display this message - - Options are: - - --ast Dump abstract syntax tree of a program - --typecheck Typecheck the program and print result - -help Display this list of options - --help Display this list of options - - $ echo 'func main() { println("Hello, world!") }' > example.go - $ ../../bin/interpret.exe --ast --typecheck example.go - Running...          AST dump: - [(Decl_func - ("main", - { args = []; returns = []; - body = - [(Stmt_call - ((Expr_ident "println"), - [(Arg_expr (Expr_const (Const_string "Hello, world!")))])) - ] - })) - ] - - Typecheck result: correct - Hello, world! diff --git a/Go/tests/typecheck/dune b/Go/tests/typecheck/dune deleted file mode 100644 index 130a4b4e2..000000000 --- a/Go/tests/typecheck/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name typecheckUnitTest) - (libraries parse typecheck errors) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_expect))) diff --git a/Go/tests/typecheck/unitTests.ml b/Go/tests/typecheck/unitTests.ml deleted file mode 100644 index 6021757b1..000000000 --- a/Go/tests/typecheck/unitTests.ml +++ /dev/null @@ -1,1422 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) - -open Parse -open Typecheck - -let pp str = - match parse parse_file str with - | Error _ -> print_endline ": syntax error" - | Ok ast -> - (match type_check ast with - | Result.Ok _ -> print_endline "CORRECT" - | Result.Error (Runtime_error _) -> () - | Result.Error (Type_check_error err) -> - prerr_string ("Typecheck error: " ^ Errors.pp_typecheck_error err)) -;; - -(********** main func **********) - -let%expect_test "ok: single main" = - pp {| - func main() {} - |}; - [%expect {| - CORRECT |}] -;; - -let%expect_test "err: multiple main" = - pp {| - func main() {} - func main() {} - |}; - [%expect {| - Typecheck error: Multiple declaration error: main is redeclared |}] -;; - -let%expect_test "err: main with returns" = - pp {| - func main() bool { return true } - |}; - [%expect - {| Typecheck error: Incorrect main error: func main must have no arguments and no return values |}] -;; - -let%expect_test "err: main with args" = - pp {| - func main(a int) {} - |}; - [%expect - {| Typecheck error: Incorrect main error: func main must have no arguments and no return values |}] -;; - -let%expect_test "err: no main" = - pp {| - var a int - func foo(b int) {} - |}; - [%expect {| Typecheck error: Undefined ident error: main is not defined |}] -;; - -let%expect_test "ok: main call" = - pp {| - func foo() { - main() - } - - func main() {} - |}; - [%expect {| - CORRECT |}] -;; - -(********** top var decl **********) - -let%expect_test "ok: single var decl no type with simple init " = - pp {| - var a = 5 - - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: single var decl with type and right init " = - pp {| - var a int = 5 - - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: single var decl with type and wrong init " = - pp {| - var a int = "" - - func main() {} - |}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: func call init with right number of elements" = - pp - {| - var a, b, c = get3() - - func get3() (int, int, int) { - return 1, 2, 3 - } - - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: func call one init with mismatched number of elements" = - pp {| - var a, b, c = get0() - - func get0() {} - - func main() {} - |}; - [%expect - {| Typecheck error: Mismatched types: Function without returns in expression |}] -;; - -let%expect_test "err: func call one init with mismathced types" = - pp - {| - var a, b, c bool = get3() - - func get3() (int, int, int) { - return 1, 2, 3 - } - - func main() {} - |}; - [%expect - {| Typecheck error: Mismatched types: (bool, bool, bool) and (int, int, int) |}] -;; - -let%expect_test "err: func call one init with mismathced range" = - pp - {| - var a, b = get3() - - func get3() (int, int, int) { - return 1, 2, 3 - } - - func main() {} - |}; - [%expect - {| Typecheck error: Mismatched types: function returns wrong number of elements in multiple var assign |}] -;; - -let%expect_test "err: var redeclaration" = - pp {| - var a = 0 - - var a = "" - - func main() {} - |}; - [%expect {| Typecheck error: Multiple declaration error: a is redeclared |}] -;; - -(********** top func decl **********) - -let%expect_test "ok: simple func" = - pp {| - func foo() {} - - func main() {} - |}; - [%expect {| - CORRECT |}] -;; - -let%expect_test "ok: id func " = - pp {| - func id(a int) int { - return a - } - - func main() {} - |}; - [%expect {| - CORRECT |}] -;; - -let%expect_test "err: repeated idents in args" = - pp {| - func foo(a, a int) {} - - func main() {} - |}; - [%expect {| - Typecheck error: Multiple declaration error: a is redeclared |}] -;; - -let%expect_test "err: func redeclaration" = - pp - {| - func foo(a int) {} - - func foo() int { - return 5 - } - - func main() {} - |}; - [%expect {| - Typecheck error: Multiple declaration error: foo is redeclared |}] -;; - -let%expect_test "err: func arg redeclaration" = - pp {| - func foo(a int) { - var a int - } - - func main() {} - |}; - [%expect {| - Typecheck error: Multiple declaration error: a is redeclared |}] -;; - -let%expect_test "ok: correct var multiple returns short_decl" = - pp - {| - func foo(a int) (int, int){ - return a, 5 - } - - func main() { - a, b := foo(4) - } - |}; - [%expect {| - CORRECT |}] -;; - -let%expect_test "err: incorrect var multiple assign" = - pp - {| - func foo(a int) (int, int){ - return a, 5 - } - func foo2(a int) (int, int, int){ - return a, 5, 4 - } - - func main() { - a, b := foo(4) - a, b = foo2(4) - } - |}; - [%expect {| - Typecheck error: Cannot assign: Multiple return assign failed |}] -;; - -let%expect_test "ok: correct var multiple assign" = - pp - {| - func foo(a int) (int, int){ - return a, 5 - } - func foo2(a int) (int, int){ - return a, 5 - } - - func main() { - a, b := foo(4) - a, b = foo2(4) - } - |}; - [%expect {| - CORRECT |}] -;; - -let%expect_test "err: incorrect var multiple assign after multiple decl with wrong types" = - pp - {| - func foo(a int) (int, string){ - return a, "g" - } - func foo2(a int) (int, int){ - return a, 5 - } - - func main() { - a, b := foo(4) - a, b = foo2(4) - } - |}; - [%expect {| - Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: var and func with the same name" = - pp {| - var foo int - - func foo() {} - - func main() {} - |}; - [%expect {| - Typecheck error: Multiple declaration error: foo is redeclared |}] -;; - -let%expect_test "ok: correct declarations #1" = - pp - {| - func main() {} - - func foo(a int, b int, c int) {} - - func foo1(a int, b int, c int) {} |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: factorial func" = - pp - {| - func main() { - fac(6) - } - - func fac(n int) int { - if n == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } - |}; - [%expect {| CORRECT |}] -;; - -(********** stmt **********) - -let%expect_test "err: incorrect call in stmt" = - pp - {| - - func main() { - println(1, 1, "k", 3) - } - - func swap() (string, string) { - return "a", "b" - } - func println(a string, b string, c string) (string, string, string) { - return a, b, c - } - -|}; - [%expect {| Typecheck error: Mismatched types: Number of given args mismatched |}] -;; - -let%expect_test "err: undefined var inc" = - pp - {| - var x int - - func main() {} - - func foo(a1 int, c int, b int) { - a2++ - } - |}; - [%expect {| Typecheck error: Undefined ident error: a2 is not defined |}] -;; - -let%expect_test "ok: global var decl before it's use in code" = - pp - {| - var x int - - func foo(a1 int, c int, b int){ - x++ - } - - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: redefined int example" = - pp {| - var int string - func main() {} - - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: global var decl after it's use in code" = - pp - {| - func foo(a1 int, c int, b int) { - x++ - } - - var x int - - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "fail: missing return statement" = - pp - {| - func foo(a1 int, c int, b int) bool { - x++ - } - - var x int - - func main() {} - |}; - [%expect {| Typecheck error: Missing return: Missing return |}] -;; - -let%expect_test "ok: correct returns in different branches of if" = - pp - {| - func foo(a1 int, c int, b int) int { - if c == 1 { - return 1 - } else { - if c == 2 { - return 3 - } else { - return 2 - } - } - } - func main() {} - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "fail: missing return in nested branch of if" = - pp - {| - var x int - func foo(a1 int, c int, b int) int { - if c == 1 { - return 1 - } else { - if c == 2 { - return 3 - } else { - x++ - } - } - } - func main() {} - |}; - [%expect {| Typecheck error: Missing return: Missing return |}] -;; - -let%expect_test "err: undefined func call" = - pp - {| - var x int - - func main() { - foo2() - } - - func foo(a1 int, c int, b int) bool {} |}; - [%expect {| Typecheck error: Undefined ident error: foo2 is not defined |}] -;; - -let%expect_test "err: arg not declared" = - pp {| - func main() { - println(a) - } - - func println(a int) {} - |}; - [%expect {| Typecheck error: Undefined ident error: a is not defined |}] -;; - -let%expect_test "err: unknown var in if cond" = - pp - {| - func main() { - { - fac(6) - } - } - - func fac(n int) int { - if a == 1 { - return 1 - } else { - return n * fac(n - 1) - } - } - |}; - [%expect {| Typecheck error: Undefined ident error: a is not defined |}] -;; - -let%expect_test "err: mismatched types in binop" = - pp - {| - var a = 5 - - var b = "st" - - func test() { - return - } - - func pritln(a int) int { - return a - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - var c = a + b - go println(id(10)) - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: mismatched type in decl # 1" = - pp - {| - var a = 5 - - var b = "st" - - func test() { - return - } - - func pritln(a int) int { - return a - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - var c = a + b - go println(id(10)) - } - |}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: mismatched type in decl # 2" = - pp - {| - var a = "s" - - var b = 5 - - func test() { - return - } - - func println(a int) int { - return a - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - var c = a + b - go println(id(10)) - } -|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -let%expect_test "err: mismatched type in func_call" = - pp - {| - var a = 5 - - var b = 5 - - func test() { - return - } - - func println(a int) int { - return a - } - - func id(a string) string { - return a - } - - var f int - - func main() { - defer test() - var c = a + id("st") - go println(id(10)) - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: correct example #3" = - pp - {| - var a = 5 - - var b int = 5 - - func test() { - return - } - - func println(a int) int { - return a - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - var c = a + b - go println(id(10)) - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: return type of func mismatch" = - pp - {| - var a = 5 - - var b int = 5 - - func test() { - return - } - - func println(a string) int { - return a - } - - func id(a int) int { - return a - } - - var f int - - func main() { - defer test() - var c = a + b - go println(id(10)) - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: return with empty func returns" = - pp {| - func main() {} - - func foo(a int, b int) { - return 5 - } -|}; - [%expect {| Typecheck error: Mismatched types: func return types mismatch |}] -;; - -let%expect_test "ok: single correct return with no func args" = - pp {| - func main() {} - - func foo(a int, b int) { - return - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: multiple returns type mismatch" = - pp - {| - func main() {} - func foo(a int, b int) (int, string){ - return 5, 5 - } -|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -let%expect_test "err: incorrect anon_func return in nested func" = - pp - {| - func s(a string) int { return 1 } - - func main() { - value := func(a string) { - g := func(a string) string { - return s("Test") - } - s("Test") - g("2") - } - value("4") - } -|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -let%expect_test "err: incorrect anon_func local redeclaration nested func" = - pp - {| - -func s(a string) string { return "g" } - -func main() { - value := func(a int) int{ - g := func(b string) string { - return a - } - s("Test") - g("2") - return a - } - value(1) -} -|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -let%expect_test "ok: correct anon_func local redeclaration nested func" = - pp - {| - -func s(a string) string { return "g" } - -func main() { - value := func(a int) int{ - g := func(a string) string { - return a - } - s("Test") - g("2") - return a - } - value(1) -} -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: incorrect multiple returns in single-value context" = - pp - {| - - func main() { - println(swap(), "j") - } - - func swap() (string, string) { - return "a", "b" - } - func println(a string, b string, c string) (string, string, string) { - return a, b, c - } - -|}; - [%expect {| Typecheck error: Mismatched types: Expected single type |}] -;; - -let%expect_test "ok: correct chans return context" = - pp - {| - func sum(c chan int) { - c <- 5 - } - - func main() { - var c chan int - go sum(c) - x, y := <-c, <-c - x = 5 - } - -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: incorrect chans return context" = - pp - {| - func sum(c chan int) { - c <- 5 - } - - func main() { - var c chan int - go sum(c) - x, y := <-c, <-c - x = "g" - } - -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: incorrect chan send type" = - pp - {| - func sum(c chan int) { - c <- "5" - } - - func main() { - var c chan int - go sum(c) - x, y := <-c, <-c - x = 5 - } - -|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -(********** expr **********) - -let%expect_test "ok: right types in bin sum" = - pp {| - func main() { - c := 2 + 2 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: mismatched types in bin sum" = - pp {| - var a = 5 - - var b = "st" - - func main() { - var c = a + b - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: right type in unary minus" = - pp {| - func main() { - c := -7 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: wrong type in unary minus" = - pp {| - var a bool - - func main() { - c := -a - } -|}; - [%expect {| Typecheck error: Mismatched types: int and bool |}] -;; - -let%expect_test "ok: right types in const array inits" = - pp {| - - func main() { - a := 7 - - c := [2]int{1, a} - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: wrong types in const array inits" = - pp {| - func main() { - c := [2]int{1, func() {}} - } -|}; - [%expect {| Typecheck error: Mismatched types: func() and int |}] -;; - -let%expect_test "ok: too much const array inits" = - pp {| - func main() { - c := [2]string{"", "a", "123"} - } -|}; - [%expect - {| Typecheck error: Mismatched types: Array's size less thai it's inits count |}] -;; - -let%expect_test "ok: simple array index call" = - pp - {| - var arr = [4]int{} - - func main() { - c := arr[func() int {return 0}()] - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: array index call with non int index" = - pp {| - var arr = [4]int{} - - func main() { - c := arr["0"] - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: array index assignment" = - pp {| - var arr = [4]int{} - - func main() { - arr[2] = 7 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: array index assignment with non-int index" = - pp {| - var arr = [4]int{} - - func main() { - arr[func() {}] = 7 - } -|}; - [%expect {| Typecheck error: Mismatched types: int and func() |}] -;; - -let%expect_test "err: array index assignment with wrong expr" = - pp {| - var arr = [4]int{} - - func main() { - arr[10] = "" - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: multidimensional array index assignment" = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - arr[i][j] = 10000 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: correct for break" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x int) int { - sum = sum + x - return sum - } - } - - func f(a int) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(a) - f(neg(-2 * i)) - break - } - }|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: multidimensional array index assignment with wrong index less than \ - needed" - = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - arr[i] = 10000 - } -|}; - [%expect {| Typecheck error: Mismatched types: [7]int and int |}] -;; - -let%expect_test "err: multidimensional array index assignment with wrong index more than \ - it needed" - = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - arr[i][i][8] = 10000 - } -|}; - [%expect - {| Typecheck error: Mismatched types: Number of indicies in array element assigment is incorrect |}] -;; - -let%expect_test "ok: multidimensional array index binoper" = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - i = arr[1][0] + 1 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: multidimensional array index returns array" = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - i = arr[1] + 1 - } -|}; - [%expect {| Typecheck error: Mismatched types: [7]int and int |}] -;; - -let%expect_test "err: multidimensional array index more than it's dimension " = - pp - {| - var arr = [4][7]int{} - - func main() { - i := 3 - j := 2 - - i = arr[1][0][0] + 1 - } -|}; - [%expect {| Typecheck error: Mismatched types: Non-array type in array index call |}] -;; - -let%expect_test "ok: multiple nested index inside nested index" = - pp - {| - var arr = [4][7][1][4][5]int{} - - var t1 = [4][3]int{} - func main() { - i := 3 - j := 2 - - i = arr[1][0][0][t1[2][1]][8] + 1 - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: wrong not integer multiple nested index inside nested index" = - pp - {| - var arr = [4][7][1][4][5]int{} - - var t1 = [4][3]string{} - func main() { - i := 3 - j := 2 - - i = arr[1][0][0][t1[2][1]][8] + 1 - } -|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: predeclared true and false" = - pp {| - func main() { - a := true && false - } -|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: correct closure" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x int) int { - sum = sum + x - return sum - } - } - - func f(a int) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(a) - f(neg(-2 * i)) - } - }|}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: mismatched type in closure" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x string) int { - return x - } - } - - func f(a int) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(a) - f(neg(-2 * i)) - } - }|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: mismatched type in closure func return" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x string) int { - return sum + 1 - } - } - - func f(a int) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(a) - f(neg(-2 * i)) - } - }|}; - [%expect {| Typecheck error: Mismatched types: func(int) int and func(string) int |}] -;; - -let%expect_test "err: mismatched type inside return of func in closure" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x int) int { - return "t" - } - } - - func f(a int) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(a) - f(neg(-2 * i)) - } - }|}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "err: mismatched func returns of created func" = - pp - {| - - func adder() func(int) int { - sum := 0 - return func(x int) int { - return sum + x - } - } - - func f(a string) { return } - - func main() { - pos, neg := adder(), adder() - for i := 0; i < 10; i++ { - a := pos(i) - f(4) - f(neg(-2 * i)) - } - }|}; - [%expect {| Typecheck error: Mismatched types: string and int |}] -;; - -let%expect_test "ok: predeclared make, close & print usage" = - pp - {| - func sum(c chan int) { - sum := 1 - c <- sum - } - - func main() { - c := make(chan int) - sum(c) - x, y := <-c, <-c - close(c) - print(x,y) - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: predeclared panic & recover" = - pp {| - func main() { - defer func() { recover() }() - panic("") - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: predeclared nil, true, false" = - pp - {| - func main() { - var a chan int = nil - var b func() = nil - - cond := true - if cond { - cond = false - } - } - |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: untyped nil" = - pp {| - func main() { - a := nil - } - |}; - [%expect - {| Typecheck error: Invalid operation: Cannot assign nil in short var declaration |}] -;; - -let%expect_test "ok: incorrect send after make" = - pp - {| - func sum(c chan string) { - sum := 1 - c <- sum - } - - func main() { - c := make(chan string) - sum(c) - x, y := <-c, <-c - print(x,y) - } |}; - [%expect {| Typecheck error: Mismatched types: int and string |}] -;; - -let%expect_test "ok: redeclaration of predeclared print" = - pp - {| - func print(a int) int { - return a - } - - func main() { - print(5) - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: redeclaration of predeclared make" = - pp - {| - func make(a int) int { - return a - } - - func main() { - make(5) - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: assignment to toplevel function" = - pp {| - func foo() {} - func main() { - foo = nil - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "ok: nil assignment to global variable with a function type" = - pp {| - var foo = func() {} - func main() { - foo = nil - } |}; - [%expect {| CORRECT |}] -;; - -let%expect_test "err: trying to run make builtin func as a goroutine" = - pp {| - func main() { - go make(chan int) - } |}; - [%expect {| Typecheck error: Go discards result of make builtin function |}] -;; - -let%expect_test "err: break outside for" = - pp {| - var foo = func() {} - func main() { - break - foo = nil - } |}; - [%expect {| Typecheck error: Unexpected operation: break |}] -;; - -let%expect_test "err: continue outside for" = - pp {| - func main() { continue } |}; - [%expect {| Typecheck error: Unexpected operation: continue |}] -;; - -let%expect_test "err: return in unreachable code" = - pp - {| - func foo() { - for true {} - return - } - - func main() { foo() } |}; - [%expect {| CORRECT |}] -;; diff --git a/Go/tests/typecheck/unitTests.mli b/Go/tests/typecheck/unitTests.mli deleted file mode 100644 index 76c46116a..000000000 --- a/Go/tests/typecheck/unitTests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Karim Shakirov, Alexei Dmitrievtsev *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Haskell/.envrc b/Haskell/.envrc deleted file mode 100644 index 9aeb3bbc4..000000000 --- a/Haskell/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) \ No newline at end of file diff --git a/Haskell/.gitignore b/Haskell/.gitignore deleted file mode 100644 index 7487aa72d..000000000 --- a/Haskell/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs \ No newline at end of file diff --git a/Haskell/.ocamlformat b/Haskell/.ocamlformat deleted file mode 100644 index 7fd0ea01c..000000000 --- a/Haskell/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 \ No newline at end of file diff --git a/Haskell/.zanuda b/Haskell/.zanuda deleted file mode 100644 index 04e859f26..000000000 --- a/Haskell/.zanuda +++ /dev/null @@ -1,3 +0,0 @@ -forward mutability_check ignore REPL.ml -forward physical_equality ignore lib/eval.ml - diff --git a/Haskell/Haskell.opam b/Haskell/Haskell.opam deleted file mode 100644 index 340dd23ab..000000000 --- a/Haskell/Haskell.opam +++ /dev/null @@ -1,45 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for Haskell" -description: - "An interpreter for Haskell language with standard types and lazy evaluations" -maintainer: [ - "Kostya Oreshin " - "Nikita Shchutskii " -] -authors: [ - "Kostya Oreshin " - "Nikita Shchutskii " -] -license: "MIT" -homepage: "https://github.com/TerrMen/Haskell" -bug-reports: "https://github.com/TerrMen/Haskell" -depends: [ - "qcheck-core" - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "ppx_deriving_qcheck" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "zarith" - "base" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/Haskell/LICENSE b/Haskell/LICENSE deleted file mode 100644 index b7927c4a4..000000000 --- a/Haskell/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2024 Kostya Oreshin, Nikita Shchutskii - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Haskell/Makefile b/Haskell/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/Haskell/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/Haskell/bin/REPL.ml b/Haskell/bin/REPL.ml deleted file mode 100644 index 01c4acf4a..000000000 --- a/Haskell/bin/REPL.ml +++ /dev/null @@ -1,68 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Haskell_lib - -type opts = - { mutable dump_parsetree : bool - ; mutable print_types : bool - ; mutable read_from_file : string - } - -let () = - let opts = { dump_parsetree = false; print_types = false; read_from_file = "" } in - let _ = - let open Stdlib.Arg in - parse - [ "-dparsetree", Unit (fun () -> opts.dump_parsetree <- true), "Dump parse tree" - ; "-ptypes", Unit (fun () -> opts.print_types <- true), "Print types" - ] - (fun file -> - if Sys.file_exists file - then opts.read_from_file <- file - else ( - Stdlib.Format.eprintf "File doesn't exist\n"; - Stdlib.exit 1)) - "Parse and print ast and types" - in - let is_stdin = - match opts.read_from_file with - | "" -> true - | _ -> false - in - if not is_stdin - then - Interpreter.interpret - ~dump_parsetree:opts.dump_parsetree - ~print_types:opts.print_types - (String.split_on_char - '\n' - (In_channel.with_open_text opts.read_from_file In_channel.input_all)) - Inferencer.initial_env - Eval.init_env - Eval.init_fresh - else ( - let rec helper inf_env st eval_env fresh = - let line = - try input_line stdin with - | End_of_file -> ":quit" - in - match line with - | ":quit" -> () - | "" -> helper inf_env st eval_env fresh - | _ -> - let inf_env, st, eval_env, fresh = - Interpreter.interpret_line - line - inf_env - st - ~dump_parsetree:opts.dump_parsetree - ~print_types:opts.print_types - eval_env - fresh - in - helper inf_env st eval_env fresh - in - helper Inferencer.initial_env 2 Eval.init_env Eval.init_fresh) -;; diff --git a/Haskell/bin/dune b/Haskell/bin/dune deleted file mode 100644 index b9544d42d..000000000 --- a/Haskell/bin/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (modules REPL) - (libraries haskell_lib) - (instrumentation - (backend bisect_ppx))) diff --git a/Haskell/dune b/Haskell/dune deleted file mode 100644 index 98e54536a..000000000 --- a/Haskell/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/Haskell/dune-project b/Haskell/dune-project deleted file mode 100644 index 8c929199c..000000000 --- a/Haskell/dune-project +++ /dev/null @@ -1,40 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license MIT) - -(authors - "Kostya Oreshin " - "Nikita Shchutskii ") - -(maintainers - "Kostya Oreshin " - "Nikita Shchutskii ") - -(bug_reports "https://github.com/TerrMen/Haskell") - -(homepage "https://github.com/TerrMen/Haskell") - -(package - (name Haskell) - (synopsis "An interpreter for Haskell") - (description - "An interpreter for Haskell language with standard types and lazy evaluations") - (version 0.1) - (depends - qcheck-core - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - ppx_deriving_qcheck - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - zarith - base - )) diff --git a/Haskell/lib/ast.ml b/Haskell/lib/ast.ml deleted file mode 100644 index a180f9fb4..000000000 --- a/Haskell/lib/ast.ml +++ /dev/null @@ -1,226 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -type const = - | Int of (int[@gen QCheck.Gen.(0 -- Int.max_int)]) (** e.g. [18] *) - | Bool of bool (** e.g. [True] *) - | Unit (** () *) -[@@deriving qcheck, show { with_path = false }] - -type 'a maybe = - | Nothing (** Nothing *) - | Just of 'a (** e.g. [Just 5] *) -[@@deriving qcheck, show { with_path = false }] - -(** explicit type indication*) -type tp = - | TUnit (** () *) - | TInt (** Int *) - | TBool (** Bool *) - | MaybeParam of tp (** e.g. [Maybe Int]*) - | TreeParam of tp (** e.g. [{Int}] *) - | ListParam of tp (** e.g. [[Int]] *) - | TupleParams of tp * tp * tp_list (** e.g. [(Int, Bool)] *) - | FunctionType of functype -[@@deriving qcheck, show { with_path = false }] - -and functype = FuncT of tp * tp * tp_list (** e.g. [Int-> Bool -> (Int,Bool)] *) - -and tp_list = - (tp list - [@gen QCheck.Gen.(list_size (return (Int.min 2 (n / 10))) (gen_tp_sized (n / 10)))]) -[@@deriving qcheck, show { with_path = false }] - -type binop = - | And (** [&&]*) - | Or (** [||] *) - | Plus (** [+] *) - | Minus (** [-] *) - | Divide (** [`div`] *) - | Mod (** [`mod`]*) - | Cons (** [:] *) - | Multiply (** [*] *) - | Equality (** [==] *) - | Pow (** [^] *) - | Inequality (** [/=] *) - | Less (** [<] *) - | Greater (** [>] *) - | EqualityOrLess (** [<=] *) - | EqualityOrGreater (** [>=] *) -[@@deriving qcheck, show { with_path = false }] - -let gen_first_symbol = - QCheck.Gen.( - map - Char.chr - (oneof [ int_range (Char.code 'a') (Char.code 'z'); return (Char.code '_') ])) -;; - -let gen_char = - QCheck.Gen.( - map - Char.chr - (oneof - [ int_range (Char.code 'a') (Char.code 'z') - ; int_range (Char.code 'A') (Char.code 'Z') - ; int_range (Char.code '0') (Char.code '9') - ; return (Char.code '_') - ; return (Char.code '\'') - ])) -;; - -let is_keyword_or_underscore = function - | "case" | "of" | "if" | "then" | "else" | "let" | "in" | "where" | "_" -> true - | _ -> false -;; - -let varname = - QCheck.Gen.( - map2 - (fun x y -> Printf.sprintf "%c%s" x y) - gen_first_symbol - (string_size ~gen:gen_char (1 -- 7))) -;; - -let correct_varname x = QCheck.Gen.map (fun y -> Printf.sprintf "%s%c" x y) gen_char - -let gen_string = - let open QCheck.Gen in - let x = varname in - map is_keyword_or_underscore x - >>= fun y -> if y then map correct_varname x >>= fun y -> y else x -;; - -(** variable's / function's name*) -type ident = Ident of (string[@gen gen_string]) -[@@deriving qcheck, show { with_path = false }] -(** e.g. [(a@my_list@lst@(_:xs) :: [Int]) :: [Bool]] *) - -type pconst = - | OrdinaryPConst of const (** e.g [True]*) - | NegativePInt of (int[@gen QCheck.Gen.(0 -- Int.max_int)]) (** e.g [-12]*) -[@@deriving qcheck, show { with_path = false }] - -type pattern = - (ident list[@gen QCheck.Gen.(list_size (return (Int.min 2 (n / 7))) gen_ident)]) - * pat - * tp_list -[@@deriving qcheck, show { with_path = false }] - -and pattern_list = - (pattern list - [@gen QCheck.Gen.(list_size (return (Int.min 2 (n / 7))) (gen_pattern_sized (n / 7)))]) - -and listpat = - | PCons of pattern * pattern (** e.g. [x:xs] *) - | PEnum of pattern_list (** e.g. [[x, y, z]] *) - -and treepat = - | PNul (** nul tree i.e. [$] *) - | PNode of pattern * pattern * pattern (** tree's node e.g [(x; y; z)]*) - -and pat = - | PWildcard (** _ *) - | PConst of pconst - | PIdentificator of ident (** e.g. [x] *) - | PList of listpat - | PTuple of pattern * pattern * pattern_list (** e.g. [(x, y, z)]*) - | PMaybe of pattern maybe (** e.g. [Just x] *) - | PTree of treepat - -type comprehension = - | Condition of expr (** e.g. [x < 2] *) - | Generator of (pattern * expr) (** e.g. [x <- [1 ..]] *) -[@@deriving qcheck, show { with_path = false }] - -(* and comprehension_list = - (comprehension list - [@gen - QCheck.Gen.(list_size (return (Int.min 2 (n / 7))) (gen_comprehension_sized (n / 7)))]) *) -and ordinarylistbld = - (* | ComprehensionList of expr * comprehension * comprehension_list - (** e.g [[x * y | x <- [1, 2, 20], y <- [2, 3], y `mod` 2 == 0]] *) *) - | IncomprehensionlList of expr_list (**e.g. [[1,2]] *) - -and listbld = - | LazyList of expr * expr option * expr option - (** e.g. [[1.. ] or [1..2] or [1, 2 .. 2] or [1, 3..]] *) - | OrdList of ordinarylistbld - -and def = - | VarsDef of pattern * bindingbody * binding_list - (** e.g [x = let y = 12 in y * z where z = 5] *) - | FunDef of ident * pattern * pattern_list * bindingbody * binding_list - (** e.g [f x y = x + y + z where z = 2 ]*) - -and binding = - | Def of def - | Decl of ident * tp (** e.g [f :: Int -> Int]*) - -(* had to do such a manual generator because of where shadowing*) -and binding_list = - (binding list - [@gen - QCheck.Gen.( - list_size - (return (Int.min 2 (n / 7))) - (map - (function - | Def (VarsDef (p, b, _)) -> Def (VarsDef (p, b, [])) - | Def (FunDef (i, p, pp, b, _)) -> Def (FunDef (i, p, pp, b, [])) - | x -> x) - (gen_binding_sized (n / 7))))]) - -and pattern_bindinbody_list = - ((pattern * bindingbody) list - [@gen - QCheck.Gen.( - list_size - (return (Int.min 2 (n / 7))) - (pair (gen_pattern_sized (n / 7)) (gen_bindingbody_sized (n / 7))))]) - -(** examples below are for function binding with due body *) -and bindingbody = - | Guards of (expr * expr) * expr_expr_list - (** (condition, branch) pairs e.g [f x | x > 0 = x | otherwise = -1] *) - | OrdBody of expr (** e.g [f x = if x > 0 then x else -1] *) - -and binary_tree_bld = - | Nul (** node that not exists (notation: [$]) *) - | Node of expr * expr * expr - (** node is data and two 'sons' e.g [(x^y; $; (2; $; $))] *) - -and expression = - | Const of const - | Identificator of ident (** e.g [x] *) - | TupleBld of expr * expr * expr_list (** e.g [(1+3, f x)] *) - | EJust (** Maybe constructor Just*) - | ENothing (*Maybe constructor Nothing*) - | ListBld of listbld (** e.g [[(2 ^ 2 - 3) ..]] *) - | Binop of expr * binop * expr (** e.g [1 > 0] *) - | Neg of expr (** e.g [(-1)] *) - | IfThenEsle of expr * expr * expr (** e.g [if x >= 0 then x else (-x)] *) - | FunctionApply of expr * expr * expr_list (** e.g. [sum 1 2 or \x -> x + 1) 1] *) - | Lambda of pattern * pattern_list * expr (** e.g. [\x y -> x + y] *) - | BinTreeBld of binary_tree_bld - | Case of expr * (pattern * bindingbody) * pattern_bindinbody_list - (** e.g [case l of (x:xs) -> x; [] -> 0] *) - (* had to do such a manual generator because of where shadowing*) - | InnerBindings of binding * (binding_list[@gen QCheck.Gen.return []]) * expr - (** e.g. [let x = 1; y = 2 in x + y] *) - -(** e.g. [((x + 1) :: Int ) :: Bool]*) -and expr = expression * tp_list [@@deriving qcheck, show { with_path = false }] - -and expr_list = - (expr list - [@gen QCheck.Gen.(list_size (return (Int.min 2 (n / 7))) (gen_expr_sized (n / 7)))]) - -and expr_expr_list = - ((expr * expr) list - [@gen - QCheck.Gen.( - list_size - (return (Int.min 2 (n / 7))) - (pair (gen_expr_sized (n / 7)) (gen_expr_sized (n / 7))))]) diff --git a/Haskell/lib/dune b/Haskell/lib/dune deleted file mode 100644 index d7d0619e5..000000000 --- a/Haskell/lib/dune +++ /dev/null @@ -1,28 +0,0 @@ -(library - (name haskell_lib) - (public_name Haskell.Lib) - (libraries angstrom qcheck-core.runner zarith) - (inline_tests) - (modules - Parser - Ast - Pprintast - Qcheck - Typedtree - Inferencer - Pprint - Pai - Interpreter - Eval) - (preprocess - (pps ppx_deriving.show ppx_inline_test ppx_expect ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx))) - -(executable - (name run_binding) - (modules run_binding) - (libraries haskell_lib qcheck-core.runner)) - -(cram - (deps ./qcheck.exe)) diff --git a/Haskell/lib/eval.ml b/Haskell/lib/eval.ml deleted file mode 100644 index fc52fdd63..000000000 --- a/Haskell/lib/eval.ml +++ /dev/null @@ -1,1875 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Base.Result - -type key = int -type fresh = int - -let ( --| ) x f = map_error x ~f - -let ( --= ) x f = - match x with - | Ok ok -> Ok ok - | Error e -> f e -;; - -let ( let+ ) = ( >>| ) -let ( let- ) = ( --| ) -let ( let* ) = ( >>= ) - -(** name Map*) -module NMap = Map.Make (String) - -(** key Map *) -module KMap = Map.Make (Int) - -type dfs_key = key -type pe_exprs_key = key -type keys = dfs_key option * pe_exprs_key -type ident_ext = ident * pe_exprs_key - -type 'a bintree = - | Node of 'a * 'a * 'a - | Nul - -type ord = - | G - | L - | Eq - -type pattern_ext = - | Lnk of pe_exprs_key - (** key for the due entry in the expresions (see pe_expr) storage. Ident and wildcard patterns are converted into Lnk. - Additional names (e.g. a@b@c or a@_) get the same key. *) - | P of pe_exprs_key option * pat_ext - (** pat and optional key. Patterns that neither idents nor wildcards converted into P. Key exists if there are additional names. *) - -and pat_ext = - | PEConst of pconst - | PECons of pattern_ext * pattern_ext - | PEEnum of pattern_ext list - | PETuple of pattern_ext * pattern_ext * pattern_ext list - | PEMaybe of pattern_ext maybe - | PETree of pattern_ext bintree - -type df_ext = - | VarsD of pattern_ext * bindingbody * binding list - (** definition of vars but the pattern was converted into pattern ext. *) - | FunDs of ident_ext * (pattern * pattern list * bindingbody * binding list) list - (** definition of a function: ident (with a due key) and some variants e.g. f in [f 1 = 0; f _ = 1] has two variants*) - -(** completely evaled exression (see pe_exprs) *) -type value = - | VConst of const - | VMaybe of value maybe - | VList of value list - | VTuple of value * value * value list - | VClosures of keys NMap.t * (pattern * pattern list * bindingbody * binding list) list - (** Type for former function bodieS and lambdas. Consist of bodies and a name-keys map (see env) that - should be used in eval of bodies.*) - | VTree of value bintree - -type intern_p = pat_ext - -(** errors that should cause stooping of vb eval*) -type crit_err = - [ `Typing_err - | `Not_exh - | `Div_by_zero - | `Negative_exponent - ] - -type df = - | Df of keys NMap.t * df_ext - (** The thunk for definition. i.e. Definition and a name-keys map (see env) that - should be used in its eval. *) - | Err of crit_err - -type lazy_list = - | IntLL of int * Z.t * int (** (start, step, fin) *) - | BoolLL of bool (** infinite list of true / infinite list of false*) - | UnitLL (** infinite list of () *) - -(** representation of an expression in some evaluation stage*) -type pe_expr = - | V of value - (** completely evaled expr. - e.g. one associated with x after [seq (x + y) e] *) - | ThTree of intern_p - (** the divided expression, some parts of which could be evaled separately. - e.g. one assocaited with k after [ main = let k@(None, _,x ) = ((1, f 1, 2) in x] would be - PETuple such that the first element is P of (None, PEConst 1), the second is Lnk k1 (k1 is associated with ThLeaf (..., f 1)) - , the third element is Lnk k2 (k2 is associated with value 2 *) - | ThLeaf of keys NMap.t * expression - (** The thunk-leaf, i, e the expression that not evalled full and not divided, and a name-keys map (see env) that - should be used in eval of expression*) - | Link of pe_exprs_key - (** redirection to another expression. - e.g. one associated with k after [main = let x = (15, 32) in let k@(z,_) = x in z)] *) - | Er of crit_err - | LazyLst of lazy_list (** invariant: non empty*) - -module Triple = struct - let fst (x, _, _) = x - let snd (_, x, _) = x - let thrd (_, _, x) = x -end - -type level = - | TopLevel - | Inner - -(** the enviroment consists of three maps: - kk (keys NMap.t) — maps name of var and keys for other two maps. Scope specific. - dfs (df KMap.t) — maps special key with a thunk for definition or with due error if one was faced before in pattern match attempt. - pe_exprs (pe_expr) — maps special key with a pe_expr (see pe_expr) - - e.g. consider the program: - [ main = - (1) let k@(x,y) = (1,2) in - (2) y - + - (3) x - ] - after (1) kk consists: - k -> (Some df_key1, pe_exprs_key1) - x -> (Some df_key1, pe_exprs_key2) - y -> (Some df_key1, pe_exprs_key3) - and dfs consists the df associated with df_key1 - but pe_exprs has no entry for pe_exprs_key1/2/3 - - in (2) y must be found. We get keys from kk and try to use pe_exprs_key but fail, so then we - use dfs_key to find definition thunk. After successful pattern match - pe_exprs for k, x and y are added and we can use it in (2),(3) and any futher*) - -type env = df KMap.t * pe_expr KMap.t * keys NMap.t - -open Triple -open KMap - -let ext_pe_exprs_opt pe_expr pe_exprs = function - | None -> pe_exprs - | Some k -> add k pe_expr pe_exprs -;; - -let init_env, init_fresh = - let arg fresh = - let name = Int.to_string fresh in - name, ([], PIdentificator (Ident name), []), (Identificator (Ident name), []) - in - let dfs, pe_exprs, kk, fresh = empty, empty, NMap.empty, 0 in - let prnt, fresh = - let name, p, e = arg fresh in - let kk' = NMap.add name (None, fresh) kk in - let bd = - OrdBody (FunctionApply ((Identificator (Ident "print_int"), []), e, []), []) - in - V (VClosures (kk', [ p, [], bd, [] ])), fresh + 1 - in - let sq, fresh = - let (name1, p1, e1), (name2, p2, e2) = arg fresh, arg (fresh + 1) in - let kk' = NMap.add name2 (None, fresh + 1) (NMap.add name1 (None, fresh) kk) in - let bd = - OrdBody (FunctionApply ((Identificator (Ident "print_int"), []), e1, [ e2 ]), []) - in - V (VClosures (kk', [ p1, [ p2 ], bd, [] ])), fresh + 2 - in - let kk = NMap.add "print_int" (None, fresh + 1) (NMap.add "seq" (None, fresh) kk) in - let pe_exprs = add fresh sq (add (fresh + 1) prnt pe_exprs) in - (dfs, pe_exprs, kk), fresh + 2 -;; - -let fm_add_many = List.fold_left (fun m (k, el) -> add k el m) - -let new_th kk fresh pe_exprs (e, _) = - (add fresh (ThLeaf (kk, e)) pe_exprs, fresh + 1), Lnk fresh -;; - -let enode_to_pat pe_exprs fresh kk e1 e2 e3 = - let (pe_exprs, fresh), p1' = new_th kk fresh pe_exprs e1 in - let (pe_exprs, fresh), p2' = new_th kk fresh pe_exprs e2 in - let (pe_exprs, fresh), p3' = new_th kk fresh pe_exprs e3 in - PETree (Node (p1', p2', p3')), pe_exprs, fresh -;; - -let etuple_to_pat pe_exprs fresh kk e1 e2 ee = - let (pe_exprs, fresh), p1' = new_th kk fresh pe_exprs e1 in - let pf, p2' = new_th kk fresh pe_exprs e2 in - let (pe_exprs, fresh), pp' = List.fold_left_map (fun (pe, f) -> new_th kk f pe) pf ee in - PETuple (p1', p2', pp'), pe_exprs, fresh -;; - -let econs_to_pat pe_exprs fresh kk e1 e2 = - let (pe_exprs, fresh), p1' = new_th kk fresh pe_exprs e1 in - let (pe_exprs, fresh), p2' = new_th kk fresh pe_exprs e2 in - PECons (p1', p2'), pe_exprs, fresh -;; - -let conv_res = function - | fst, `V v -> fst, V v - | fst, `Th (kk, (e, _)) -> fst, ThLeaf (kk, e) - | fst, `LazyLst ll -> fst, LazyLst ll -;; - -let from_crit_err = function - | #crit_err as e -> e -;; - -let rec lazylst_to_cons = function - | BoolLL b as bb -> VConst (Bool b), `LazyLst bb - | UnitLL as uu -> VConst Unit, `LazyLst uu - | IntLL (start, step, fin) -> - let open Z in - let start' = of_int start + step in - let pe = - if step >= zero <> (of_int fin - start' >= zero) - then `V (VList []) - else `LazyLst (IntLL (Z.to_int start', step, fin)) - in - VConst (Int start), pe - -and lazylst_to_pat pe_exprs fresh ll = - let v21, pe22 = lazylst_to_cons ll |> conv_res in - let p21, pe_exprs, fresh = Lnk fresh, add fresh (V v21) pe_exprs, fresh + 1 in - let p22, pe_exprs, fresh = Lnk fresh, add fresh pe22 pe_exprs, fresh + 1 in - PECons (p21, p22), pe_exprs, fresh -;; - -let pm_key ((dfs, pe_exprs, kk) as env) fresh helper ok_lnk ok k ff = - let pattern_match_v, pattern_match, patpat_match, ptrnll_match = ff in - let pm_res_hndl = function - | Ok (to_pe_ex, (dfs, pe_exprs, fresh)) -> - let pe_exprs = fm_add_many pe_exprs to_pe_ex in - ok (dfs, pe_exprs, thrd env) fresh - | Error (`Not_match, (dfs, pe_exprs, fresh)) -> helper (dfs, pe_exprs, thrd env) fresh - | Error ((#crit_err as er), (dfs, pe_exprs, fresh)) -> - Error (er, (dfs, pe_exprs, fresh)) - in - function - | Lnk k' -> ok_lnk env fresh k k' - | P (k0, pat) as p -> - let rec helper_key k = - match KMap.find k pe_exprs with - | Er er -> Error (er, (dfs, pe_exprs, fresh)) - | Link k -> helper_key k - | V v -> - (match pattern_match_v p v [] with - | Ok to_pe_ex -> - let pe_exprs = fm_add_many pe_exprs to_pe_ex in - ok (dfs, pe_exprs, kk) fresh - | Error `Not_match -> helper env fresh - | Error ((`Not_exh | `Typing_err | `Div_by_zero | `Negative_exponent) as er) -> - Error (er, (dfs, pe_exprs, fresh))) - | ThLeaf (kk, e) -> - pattern_match [] (dfs, pe_exprs, kk) fresh (Some k) p e |> pm_res_hndl - | ThTree pat' -> - let to_pe_ex = - match k0 with - | Some k0 -> [ k0, Link k ] - | None -> [] - in - (match patpat_match to_pe_ex env fresh pat pat' with - | Error (`Not_match, ((dfs, pe_exprs, fresh), pat'')) -> - helper (dfs, add k (ThTree pat'') pe_exprs, kk) fresh - | Error ((#crit_err as er), ((dfs, pe_exprs, fresh), pat'')) -> - Error (er, (dfs, add k (ThTree pat'') pe_exprs, fresh)) - | Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pat'') -> - let pe_exprs = fm_add_many pe_exprs ((k, ThTree pat'') :: to_pe_ex) in - ok (dfs, pe_exprs, kk) fresh) - | LazyLst ll -> ptrnll_match env fresh [] (Some k) ll p |> pm_res_hndl - in - helper_key k -;; - -let rec prep_p ?(dfs_key = None) (kk, main, fresh) (alias, p, _) = - let prep_p = prep_p ~dfs_key in - let helper_list = List.fold_left_map prep_p in - let com_key = - match alias with - | [] -> None - | _ -> Some fresh - in - let kk, main = - List.fold_left - (fun (kk, main) (Ident i) -> - ( NMap.add i (dfs_key, fresh) kk - , if String.equal i "main" then Some (dfs_key, fresh) else main )) - (kk, main) - alias - in - let stf = kk, main, fresh + 1 in - match p with - | PWildcard -> stf, Lnk fresh - | PIdentificator (Ident i) -> - ( ( NMap.add i (dfs_key, fresh) kk - , (if String.equal i "main" then Some (dfs_key, fresh) else main) - , fresh + 1 ) - , Lnk fresh ) - | PConst c -> stf, P (com_key, PEConst c) - | PMaybe Nothing -> stf, P (com_key, PEMaybe Nothing) - | PTree PNul -> stf, P (com_key, PETree Nul) - | PMaybe (Just p) -> - let stf, pe = prep_p stf p in - stf, P (com_key, PEMaybe (Just pe)) - | PTuple (p1, p2, pp) -> - let stf, pe1 = prep_p stf p1 in - let stf, pe2 = prep_p stf p2 in - let stf, pes = helper_list stf pp in - stf, P (com_key, PETuple (pe1, pe2, pes)) - | PList (PEnum pp) -> - let stf, pes = helper_list stf pp in - stf, P (com_key, PEEnum pes) - | PList (PCons (p1, p2)) -> - let stf, pe1 = prep_p stf p1 in - let stf, pe2 = prep_p stf p2 in - stf, P (com_key, PECons (pe1, pe2)) - | PTree (PNode (p1, p2, p3)) -> - let stf, pe1 = prep_p stf p1 in - let stf, pe2 = prep_p stf p2 in - let stf, pe3 = prep_p stf p3 in - stf, P (com_key, PETree (Node (pe1, pe2, pe3))) -;; - -let rec pattern_match_v ptrn v to_pe_ex = - let pattern_match_v_list = - List.fold_left2 (fun acc p v -> acc >>= pattern_match_v p v) (Ok to_pe_ex) - in - match ptrn with - | Lnk k -> Ok ((k, V v) :: to_pe_ex) - | P (k, pat) -> - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, V v) :: to_pe_ex - in - (match pat, v with - | PETree Nul, VTree Nul | PEMaybe Nothing, VMaybe Nothing -> Ok to_pe_ex - | PEMaybe (Just p), VMaybe (Just v) -> pattern_match_v p v to_pe_ex - | PEConst (OrdinaryPConst c), VConst c' when c = c' -> Ok to_pe_ex - | PEConst (NegativePInt i), VConst (Int i') when i = -i' -> Ok to_pe_ex - | PETuple (p1, p2, pp), VTuple (v1, v2, vv) -> - (try pattern_match_v_list (p1 :: p2 :: pp) (v1 :: v2 :: vv) with - | Invalid_argument _ -> Error `Typing_err) - | PETree (Node (p1, p2, p3)), VTree (Node (v1, v2, v3)) -> - pattern_match_v_list [ p1; p2; p3 ] [ v1; v2; v3 ] - | PETree _, VTree _ | PEMaybe _, VMaybe _ -> Error `Not_match - | PEConst (OrdinaryPConst (Int _) | NegativePInt _), VConst (Int _) - | PEConst (OrdinaryPConst (Bool _)), VConst (Bool _) -> Error `Not_match - | PEEnum pp, VList vv -> - (try pattern_match_v_list pp vv with - | Invalid_argument _ -> Error `Typing_err) - | PECons _, VList [] -> Error `Not_match - | PECons (p1, p2), VList (v :: vv) -> pattern_match_v_list [ p1; p2 ] [ v; VList vv ] - | _ -> Error `Typing_err) -;; - -let rec eval_bnds level env fresh bnds = - let to_dfs, (kk, main, fresh) = - let prep_eval_bnd ((to_dfs, (kk0, main, fresh)) as init) = function - | Decl _ -> init - | Def (FunDef ((Ident i as id), p, pp, bd, bb)) -> - (match - List.fold_left_map - (fun fl -> function - | dk, FunDs ((i, pek), defs) when id = i -> - true, (dk, FunDs ((i, pek), (p, pp, bd, bb) :: defs)) - | el -> fl, el) - false - to_dfs - with - | true, to_dfs' -> to_dfs', Stdlib.snd init - | _ -> - ( (fresh, FunDs ((id, fresh + 1), [ p, pp, bd, bb ])) :: to_dfs - , (NMap.add i (Some fresh, fresh + 1) kk0, main, fresh + 2) )) - | Def (VarsDef (p, bd, bb)) -> - let dfs_key, fresh = fresh, fresh + 1 in - let ((kk, _, _) as stf), pe = - prep_p ~dfs_key:(Some dfs_key) (kk0, main, fresh) p - in - (if kk == kk0 then to_dfs else (dfs_key, VarsD (pe, bd, bb)) :: to_dfs), stf - in - List.fold_left prep_eval_bnd ([], (thrd env, None, fresh)) bnds - in - let dfs = - List.fold_left (fun dfs (k, d) -> KMap.add k (Df (kk, d)) dfs) (fst env) to_dfs - in - match level, main with - | TopLevel, Some keys -> - (match eval_var_full keys (dfs, snd env, fresh) with - | Ok ((dfs, pe_exprs, fresh), _) -> Ok ((dfs, pe_exprs, kk), fresh) - | Error (e, (dfs, pe_exprs, fresh)) -> Error (e, ((dfs, pe_exprs, kk), fresh))) - | _ -> Ok ((dfs, snd env, kk), fresh) - -and find_expr ((dfs, pe_exprs, fresh) as dpf) = function - | None, pe_exprs_key -> Ok (dpf, find pe_exprs_key pe_exprs) - | Some dfs_key, pe_exprs_key -> - (try Ok (dpf, find pe_exprs_key pe_exprs) with - | Not_found -> - (match find dfs_key dfs with - | Err e -> Error (e, dpf) - | Df (kk, FunDs ((_, pe_exprs_key), defs)) -> - let v = VClosures (kk, defs) in - Ok ((dfs, add pe_exprs_key (V v) pe_exprs, fresh), V v) - | Df (kk, VarsD (p, bd, bb)) -> - let pm (e, _) env fresh = - match pattern_match [] env fresh None p e with - | Ok (to_pe_ex, (dfs, pe_exprs, fresh)) -> - let pe_exprs = fm_add_many pe_exprs to_pe_ex in - Ok (dfs, pe_exprs, fresh) - | Error (`Not_match, (dfs, pe_exprs, fresh)) -> - let dfs = add dfs_key (Err `Not_exh) dfs in - Error (`Not_exh, (dfs, pe_exprs, fresh)) - | Error ((#crit_err as er), (dfs, pe_exprs, fresh)) -> - let dfs = add dfs_key (Err er) dfs in - Error (er, (dfs, pe_exprs, fresh)) - in - let- e, (dfs, pe_exprs_key, fresh) = - match eval_bnds Inner (dfs, pe_exprs, kk) fresh bb with - | Error (e, ((dfs, pe_exprs, _), fresh)) -> Error (e, (dfs, pe_exprs, fresh)) - | Ok (((_, _, kk) as env), fresh) -> - let+ dpf = - match bd with - | OrdBody e -> pm e env fresh - | Guards (cb, cbs) -> - let* (dfs, pe_exprs, fresh), e = - eval_step_guards env fresh (cb :: cbs) - in - pm e (dfs, pe_exprs, kk) fresh - in - dpf, find pe_exprs_key (snd dpf) - in - e, (add dfs_key (Err e) dfs, pe_exprs_key, fresh))) - -and eval_var_full ((_, pe_exprs_key) as keys) dpf = - let* ((dfs, pe_exprs, fresh) as dpf), pe_expr = find_expr dpf keys in - let result_hndl = function - | Ok ((dfs, pe_exprs, fresh), v) -> - Ok ((dfs, add pe_exprs_key (V v) pe_exprs, fresh), v) - | Error (e, (dfs, pe_exprs, fresh)) -> - Error (e, (dfs, add pe_exprs_key (Er e) pe_exprs, fresh)) - in - match pe_expr with - | Er e -> Error (e, dpf) - | V v -> Ok (dpf, v) - | Link pk -> eval_var_full (None, pk) dpf |> result_hndl - | ThLeaf (kk, e) -> eval_expr_full (dfs, pe_exprs, kk) fresh (e, []) |> result_hndl - | LazyLst ll -> eval_lazylst dpf ll |> return |> result_hndl - | ThTree ip -> - let rec helper_ip ip dpf = - let helper_pattern = function - | P (Some k, _) | Lnk k -> eval_var_full (None, k) - | P (_, ip) -> helper_ip ip - in - let helper_pattern_list dpf pp = - let+ dpf, vv = - Base.List.fold_result - ~f:(fun (dpf, vv) p -> - let+ dpf, v = helper_pattern p dpf in - dpf, v :: vv) - ~init:(dpf, []) - pp - in - dpf, List.rev vv - in - match ip with - | PEConst (OrdinaryPConst c) -> Ok (dpf, VConst c) - | PEConst (NegativePInt i) -> Ok (dpf, VConst (Int (-i))) - | PETree Nul -> Ok (dpf, VTree Nul) - | PEMaybe Nothing -> Ok (dpf, VMaybe Nothing) - | PECons (p1, p2) -> - let* dpf, v1 = helper_pattern p1 dpf in - let* dpf, v2 = helper_pattern p2 dpf in - (match v2 with - | VList vl -> Ok (dpf, VList (v1 :: vl)) - | _ -> Error (`Typing_err, dpf)) - | PEMaybe (Just p) -> - let+ dpf, v = helper_pattern p dpf in - dpf, VMaybe (Just v) - | PEEnum pp -> - let+ dpf, vv = helper_pattern_list dpf pp in - dpf, VList vv - | PETuple (p1, p2, pp) -> - let* dpf, v1 = helper_pattern p1 dpf in - let* dpf, v2 = helper_pattern p2 dpf in - let+ dpf, vv = helper_pattern_list dpf pp in - dpf, VTuple (v1, v2, vv) - | PETree (Node (p1, p2, p3)) -> - let* dpf, v1 = helper_pattern p1 dpf in - let* dpf, v2 = helper_pattern p2 dpf in - let+ dpf, v3 = helper_pattern p3 dpf in - dpf, VTree (Node (v1, v2, v3)) - in - helper_ip ip dpf |> result_hndl - -and eval_lazylst dpf ll = - let rec helper v_list ll = - let h, tl = lazylst_to_cons ll in - match tl with - | `LazyLst ll -> helper (h :: v_list) ll - | _ -> VList (List.rev v_list) - in - dpf, helper [] ll - -and eval_expr_full_list (dfs, pe_exprs, kk) fresh ee = - let+ dpf, vv = - Base.List.fold_result - ~f:(fun ((dfs, pe_exprs, fresh), vv) e -> - let+ dpf, v = eval_expr_full (dfs, pe_exprs, kk) fresh e in - dpf, v :: vv) - ~init:((dfs, pe_exprs, fresh), []) - ee - in - dpf, List.rev vv - -and eval_expr_full ((dfs, pe_exprs, kk) as env) fresh = - let dpf0 = dfs, pe_exprs, fresh in - function - | Const c, _ -> Ok (dpf0, VConst c) - | ENothing, _ -> Ok (dpf0, VMaybe Nothing) - | BinTreeBld Nul, _ -> Ok (dpf0, VTree Nul) - | Identificator (Ident n), _ -> - let keys = NMap.find n kk in - eval_var_full keys dpf0 - | TupleBld (e1, e2, ee), _ -> - let* (dfs, pe_exprs, fresh), v1 = eval_expr_full env fresh e1 in - let* (dfs, pe_exprs, fresh), v2 = eval_expr_full (dfs, pe_exprs, kk) fresh e2 in - let+ dpf, vv = eval_expr_full_list (dfs, pe_exprs, kk) fresh ee in - dpf, VTuple (v1, v2, vv) - | IfThenEsle (c, th, el), _ -> - let* (dfs, pe_exprs, fresh), e = eval_step_ite c th el env fresh in - eval_expr_full (dfs, pe_exprs, kk) fresh e - | InnerBindings (b, bb, e), _ -> - let* env, fresh = eval_step_inner_bb (b :: bb) env fresh in - eval_expr_full env fresh e - | BinTreeBld (Node (e1, e2, e3)), _ -> - let* (dfs, pe_exprs, fresh), v1 = eval_expr_full env fresh e1 in - let* (dfs, pe_exprs, fresh), v2 = eval_expr_full (dfs, pe_exprs, kk) fresh e2 in - let+ dpf, v3 = eval_expr_full (dfs, pe_exprs, kk) fresh e3 in - dpf, VTree (Node (v1, v2, v3)) - | ListBld (LazyList (e1, e2, e3)), _ -> - let+ dpf, pe = elazylist_hndl e1 e2 e3 env fresh in - (match pe with - | `V v -> dpf, v - | `LazyLst ll -> eval_lazylst dpf ll) - | ListBld (OrdList (IncomprehensionlList ee)), _ -> - eval_expr_full_list env fresh ee >>| fun (dpf, vv) -> dpf, VList vv - | Binop (e1, Cons, e2), _ -> - let* (dfs, pe_exprs, fresh), v1 = eval_expr_full env fresh e1 in - let* dpf, v2 = eval_expr_full (dfs, pe_exprs, kk) fresh e2 in - (match v2 with - | VList vl -> Ok (dpf, VList (v1 :: vl)) - | _ -> Error (`Typing_err, dpf)) - | Case (e, br, brs), _ -> - let* env, fresh, e = eval_step_case e env fresh (br :: brs) in - eval_expr_full env fresh e - | Neg e, _ -> eval_neg env fresh e - | Binop (e1, op, e2), _ -> eval_arlog env fresh e1 e2 op - | Lambda (p, pp, e), _ -> - Ok ((dfs, pe_exprs, fresh), VClosures (kk, [ p, pp, OrdBody e, [] ])) - | EJust, _ -> - let (Ident n as id) = Ident (Int.to_string fresh) in - let bd = OrdBody (FunctionApply ((EJust, []), (Identificator id, []), []), []) in - Ok - ( (dfs, pe_exprs, fresh + 1) - , VClosures - ( NMap.add n (None, fresh) (thrd env) - , [ ([], PIdentificator id, []), [], bd, [] ] ) ) - | FunctionApply ((EJust, _), a, []), _ -> - let+ dpf, v = eval_expr_full (dfs, pe_exprs, kk) fresh a in - dpf, VMaybe (Just v) - | FunctionApply ((EJust, _), _, _ :: _), _ -> Error (`Typing_err, dpf0) - | FunctionApply (f, a, aa), _ -> - eval_step_funapp env fresh (f, a :: aa) - >>= (function - | (dfs, pe_exprs, fresh), `Th (kk, e) -> eval_expr_full (dfs, pe_exprs, kk) fresh e - | dpf, `V v -> Ok (dpf, v)) - -and elazylist_hndl fst snd lst ((_, _, kk) as env) fresh = - let typing_err dpf = Error ((`Typing_err : crit_err), dpf) in - let e_to_val v_hndl ((dfs, pe_exprs, fresh) as dpf) = function - | None -> Ok (dpf, None) - | Some e -> eval_expr_full (dfs, pe_exprs, kk) fresh e >>= v_hndl - in - let int_ll dpf start = - let e_to_val = - e_to_val - @@ function - | dpf, VConst (Int i) -> Ok (dpf, Some i) - | dpf, _ -> typing_err dpf - in - let* dpf, snd_opt = e_to_val dpf snd in - let+ dpf, fin_opt = e_to_val dpf lst in - let open Z in - ( dpf - , match snd_opt with - | Some snd -> - let step = of_int snd - of_int start in - let incr = step >= zero in - (match fin_opt with - | Some fin -> - if of_int fin - of_int start >= zero <> incr - then `V (VList []) - else `LazyLst (IntLL (start, step, fin)) - | None -> - let fin = if incr then Int.max_int else Int.min_int in - `LazyLst (IntLL (start, step, fin))) - | None -> - let incr, fin = - match fin_opt with - | None -> true, Int.max_int - | Some fin -> of_int fin - of_int start >= zero, fin - in - let step = if incr then Z.one else -Z.one in - `LazyLst (IntLL (start, step, fin)) ) - in - let bool_ll dpf start = - let t, f = VConst (Bool true), VConst (Bool false) in - let e_to_val = - e_to_val - @@ function - | dpf, VConst (Bool b) -> Ok (dpf, Some b) - | dpf, _ -> typing_err dpf - in - let* dpf, snd_opt = e_to_val dpf snd in - let+ dpf, fin_opt = e_to_val dpf lst in - ( dpf - , match start, snd_opt, fin_opt with - | true, None, (None | Some true) | true, Some false, Some true -> `V (VList [ t ]) - | false, (None | Some true), Some false -> `V (VList [ f ]) - | false, (None | Some true), (None | Some true) -> `V (VList [ f; t ]) - | true, Some false, (None | Some false) | true, None, Some false -> - `V (VList [ t; f ]) - | true, Some true, (None | Some true) -> `LazyLst (BoolLL true) - | false, Some false, _ -> `LazyLst (BoolLL false) - | true, Some true, Some false -> `V (VList []) ) - in - let unit_ll dpf = - let e_to_val = - e_to_val - @@ function - | dpf, VConst Unit -> Ok (dpf, Some Unit) - | dpf, _ -> typing_err dpf - in - let* dpf, snd_opt = e_to_val dpf snd in - let+ dpf, _ = e_to_val dpf lst in - ( dpf - , match snd_opt with - | None -> `V (VList [ VConst Unit ]) - | Some _ -> `LazyLst UnitLL ) - in - eval_expr_full env fresh fst - >>= function - | dpf, VConst (Int i) -> int_ll dpf i - | dpf, VConst (Bool b) -> bool_ll dpf b - | dpf, VConst Unit -> unit_ll dpf - | dpf, _ -> typing_err dpf - -and eval_step_ite cond th el env fresh = - let* dpf, v = eval_expr_full env fresh cond in - match v with - | VConst (Bool true) -> Ok (dpf, th) - | VConst (Bool false) -> Ok (dpf, el) - | _ -> Error (`Typing_err, (fst env, snd env, fresh)) - -and eval_step_inner_bb bb env fresh = - eval_bnds Inner env fresh bb - --| fun (e, ((dfs, pe_exprs, _), fresh)) -> e, (dfs, pe_exprs, fresh) - -and eval_step_guards (dfs, pe_exprs, kk) fresh = - Base.List.fold_until - ~f:(fun (dfs, pe_exprs, fresh) (c, br) -> - match eval_expr_full (dfs, pe_exprs, kk) fresh c with - | Error _ as er -> Stop er - | Ok (dpf, v) -> - (match v with - | VConst (Bool true) -> Stop (Ok (dpf, br)) - | VConst (Bool false) -> Continue dpf - | _ -> Stop (Error (`Typing_err, dpf)))) - ~finish:(fun dpf -> Error (`Not_exh, dpf)) - ~init:(dfs, pe_exprs, fresh) - -and eval_step_case (e, _) (dfs, pe_exprs, kk) fresh brs = - let k, fresh, pe_exprs = fresh, fresh + 1, add fresh (ThLeaf (kk, e)) pe_exprs in - let rec helper brs k ((dfs, pe_exprs, kk) as env) fresh = - match brs with - | [] -> Error (`Not_exh, (fst env, snd env, fresh)) - | (p, b) :: brs -> - let b_hndl b env fresh = - match b with - | OrdBody e -> Ok (env, fresh, e) - | Guards (cb, cbs) -> - let+ (dfs, pe_exprs, fresh), e = eval_step_guards env fresh (cb :: cbs) in - (dfs, pe_exprs, kk), fresh, e - in - let (kk, _, fresh), p = prep_p (kk, None, fresh) p in - let ok_lnk (dfs, pe_exprs, kk) fresh k k' = - b_hndl b (dfs, add k' (Link k) pe_exprs, kk) fresh - in - let ok env fresh = b_hndl b env fresh in - let helper = helper brs k in - let ff = pattern_match_v, pattern_match, patpat_match ~k:None, ptrnll_match in - pm_key (dfs, pe_exprs, kk) fresh helper ok_lnk ok k ff p - in - helper brs k (dfs, pe_exprs, kk) fresh - -and eval_step_funapp ((dfs, pe_exprs, kk0) as env0) fresh = function - | (Identificator (Ident "seq"), _), [ a1; a2 ] -> - let+ dpf, _ = eval_expr_full env0 fresh a1 in - dpf, `Th (kk0, a2) - | (Identificator (Ident "seq"), _), a1 :: a2 :: a3 :: aa -> - let+ dpf, _ = eval_expr_full env0 fresh a1 in - dpf, `Th (kk0, (FunctionApply (a2, a3, aa), [])) - | (Identificator (Ident "print_int"), _), a :: [] -> - let* dpf, v = eval_expr_full env0 fresh a in - (match v with - | VConst (Int x) -> - Printf.printf "%d\n" x; - Ok (dpf, `V (VConst Unit)) - | _ -> Error (`Typing_err, dpf)) - | f, aa -> - let (fresh, pe_exprs), aa' = - List.fold_left_map - (fun (fresh, pe_exprs) (a, _) -> - (fresh + 1, add fresh (ThLeaf (kk0, a)) pe_exprs), fresh) - (fresh, pe_exprs) - aa - in - let rec es_ord_funcapp f aa' env fresh = - let* ((dfs, pe_exprs, fresh) as dpf), v = eval_expr_full env fresh f in - match v with - | VClosures (kk, dd) -> - let rec helper dd ((dfs, pe_exprs, _) as env) fresh = - match dd with - | [] -> Error (`Not_exh, (dfs, pe_exprs, fresh)) - | (p, pp, bd, bb) :: dd -> - let rec helper_def ((dfs, pe_exprs, kk) as env) fresh = function - | [], aa' -> - (match eval_bnds Inner env fresh bb with - | Error (e, ((dfs, pe_exprs, _), fresh)) -> - Error (e, (dfs, pe_exprs, fresh)) - | Ok (env, fresh) -> - let* ((dfs, pe_exprs, fresh) as dpf), e = - match bd with - | OrdBody e -> Ok ((fst env, snd env, fresh), e) - | Guards (cb, cbs) -> eval_step_guards env fresh (cb :: cbs) - in - (match aa' with - | [] -> Ok (dpf, `Th (thrd env, e)) - | aa' -> es_ord_funcapp e aa' (dfs, pe_exprs, thrd env) fresh)) - | p :: pp, [] -> - Ok ((dfs, pe_exprs, fresh), `V (VClosures (kk, [ p, pp, bd, bb ]))) - | p :: pp, a' :: aa' -> - let (kk, _, fresh), p' = prep_p (kk, None, fresh) p in - let ok_lnk (dfs, pe_exprs, kk) fresh k k' = - helper_def (dfs, add k' (Link k) pe_exprs, kk) fresh (pp, aa') - in - let ok env fresh = helper_def env fresh (pp, aa') in - let helper = helper dd in - let ff = - pattern_match_v, pattern_match, patpat_match ~k:None, ptrnll_match - in - pm_key (dfs, pe_exprs, kk) fresh helper ok_lnk ok a' ff p' - in - helper_def env fresh (p :: pp, aa') - in - helper dd (dfs, pe_exprs, kk) fresh - | _ -> Error (`Typing_err, dpf) - in - es_ord_funcapp f aa' (dfs, pe_exprs, kk0) fresh - -and eval_neg env fresh e = - let* dpf, v = eval_expr_full env fresh e in - match v with - | VConst (Int x) -> Ok (dpf, VConst (Int (-x))) - | _ -> Error (`Typing_err, dpf) - -and eval_arlog ((dfs, pe_exprs, kk) as env) fresh e1 e2 = - let arithm res snd_arg_check = - let* (dfs, pe_exprs, fresh), v1 = eval_expr_full env fresh e1 in - let* dpf, v2 = eval_expr_full (dfs, pe_exprs, kk) fresh e2 in - match v1, v2 with - | VConst (Int x), VConst (Int y) -> - snd_arg_check (y, dpf) >>| fun _ -> dpf, VConst (Int (res x y)) - | _ -> Error (`Typing_err, dpf) - in - let log res = - let* (dfs, pe_exprs, fresh), v1 = eval_expr_full env fresh e1 in - let* dpf, v2 = eval_expr_full (dfs, pe_exprs, kk) fresh e2 in - match v1, v2 with - | VConst (Bool x), VConst (Bool y) -> Ok (dpf, VConst (Bool (res x y))) - | _ -> Error (`Typing_err, dpf) - in - let rec ord ((dfs, pe_exprs, fresh) as dpf) src1 src2 ~ac1 ~ac2 pe1 pe2 = - let cmpr_to_constr = function - | 0 -> Eq - | cmpr when cmpr < 0 -> L - | _ -> G - in - let neg = function - | L, dpf -> G, dpf - | G, dpf -> L, dpf - | oth -> oth - in - let rev () = ord dpf src2 src1 ~ac1:ac2 ~ac2:ac1 pe2 pe1 >>| neg in - let src_hnd pe_e src pe_exprs = ext_pe_exprs_opt pe_e pe_exprs src in - let ord_const dpf = function - | Int x, Int y -> Ok (Int.compare x y |> cmpr_to_constr, dpf) - | Bool x, Bool y -> Ok (Bool.compare x y |> cmpr_to_constr, dpf) - | Unit, Unit -> Ok (Eq, dpf) - | _ -> Error ((`Typing_err : crit_err), dpf) - in - let pattern_hnd_l ((_, pe_exprs, _) as dpf) = function - | Lnk k | P (Some k, _) -> ord dpf (Some k) None ~ac1:false ~ac2 (find k pe_exprs) - | P (None, pat) -> ord dpf None None ~ac1 ~ac2 (ThTree pat) - in - let econst_before c = src_hnd (V (VConst c)) in - let enothing_before = src_hnd (V (VMaybe Nothing)) in - let enul_before = src_hnd (V (VTree Nul)) in - let eempty_before = src_hnd (V (VList [])) in - let ac_hnd src ~ac pe_ex = - match src, ac with - | Some k, true -> - fun (fst, (dfs, pe_exprs, fresh)) -> fst, (dfs, add k pe_ex pe_exprs, fresh) - | _ -> Fun.id - in - let ord_list ?(strict_len = true) inner_call = - let rec helper dpf = function - | hd1 :: tl1, hd2 :: tl2 -> - inner_call dpf hd1 hd2 - >>= (function - | Eq, dpf -> helper dpf (tl1, tl2) - | res -> return res) - | [], [] -> return (Eq, dpf) - | ([], _ :: _ | _ :: _, []) when strict_len -> fail ((`Typing_err : crit_err), dpf) - | [], _ :: _ -> return (L, dpf) - | _ :: _, [] -> return (G, dpf) - in - helper - in - let inner_call_ee kk1 kk2 dpf (e1, _) (e2, _) = - ord dpf None None ~ac1 ~ac2 (ThLeaf (kk1, e1)) (ThLeaf (kk2, e2)) - in - let inner_call_ev kk dpf (e, _) v = - ord dpf None None ~ac1 ~ac2 (ThLeaf (kk, e)) (V v) - in - let inner_call_pe kk dpf p (e, _) = pattern_hnd_l dpf p (ThLeaf (kk, e)) in - let inner_call_vv dpf v1 v2 = ord dpf None None ~ac1 ~ac2 (V v1) (V v2) in - let inner_call_pv dpf p v = pattern_hnd_l dpf p (V v) in - let inner_call_pp ((_, pe_exprs, _) as dpf) p1 p2 = - let pattern_hnd ac = function - | Lnk k | P (Some k, _) -> Some k, false, find k pe_exprs - | P (None, pat) -> None, ac, ThTree pat - in - let src1, ac1, pe1 = pattern_hnd ac1 p1 in - let src2, ac2, pe2 = pattern_hnd ac2 p2 in - ord dpf src1 src2 ~ac1 ~ac2 pe1 pe2 - in - let ll_none_hnd_r inner_call1 inner_call2 ll = - let hd, tl = lazylst_to_cons ll |> conv_res in - inner_call1 dpf (V hd) - >>= function - | Eq, dpf -> inner_call2 dpf tl - | res -> return res - in - let ord_e_ll kk e1 e2 = - let inner_call_e e dpf = ord dpf None None ~ac1 ~ac2 (ThLeaf (kk, e)) in - ll_none_hnd_r (inner_call_e e1) (inner_call_e e2) - in - let ord_p_ll p1 p2 = - ll_none_hnd_r (fun dpf -> pattern_hnd_l dpf p1) (fun dpf -> pattern_hnd_l dpf p2) - in - let inner_call_v v dpf = ord dpf None None ~ac1 ~ac2 (V v) in - let ord_v_ll v1 v2 = ll_none_hnd_r (inner_call_v v1) (inner_call_v v2) in - let ord_ll_ll ll = - let hd, tl = lazylst_to_cons ll |> conv_res in - ll_none_hnd_r (inner_call_v hd) (fun dpf -> ord dpf None None ~ac1 ~ac2 tl) - in - let err_hnd = function - | Ok ok -> ok - | Error (e, (dfs, pe_exprs, fresh)) -> - (dfs, src_hnd (Er e) src1 pe_exprs, fresh), Er e - in - let complex_hnd res = - let dpf, pe1' = err_hnd res in - ord dpf src1 src2 ~ac1:true ~ac2 pe1' pe2 - in - match (pe1, src1), (src2, pe2) with - | (Link k, _), _ -> ord dpf (Some k) src2 ~ac1:false ~ac2 (find k pe_exprs) pe2 - | (Er e, _), (_, ThLeaf (_, Const c)) -> - fail (e, (dfs, econst_before c src2 pe_exprs, fresh)) - | (Er e, _), (_, ThLeaf (_, ENothing)) -> - fail (e, (dfs, enothing_before src2 pe_exprs, fresh)) - | (Er e, _), (_, ThLeaf (_, BinTreeBld Nul)) -> - fail (e, (dfs, enul_before src2 pe_exprs, fresh)) - | (Er e, _), (_, ThLeaf (_, ListBld (OrdList (IncomprehensionlList [])))) -> - fail (e, (dfs, eempty_before src2 pe_exprs, fresh)) - | (Er e, _), (_, (ThLeaf (_, _) | LazyLst _)) -> - (e, dpf) |> ac_hnd src2 ~ac:ac2 pe2 |> fail - | (Er e, _), _ -> fail (e, dpf) - | ( (ThTree (PEConst (NegativePInt x)), _) - , (_, (ThLeaf (_, Const _) | ThTree (PEConst _) | V (VConst _))) ) -> - ord dpf src1 src2 ~ac1 ~ac2 (ThTree (PEConst (OrdinaryPConst (Int (-x))))) pe2 - | (ThLeaf (_, Const c1), _), (_, ThLeaf (_, Const c2)) -> - ord_const - (dfs, econst_before c1 src1 @@ econst_before c2 src2 pe_exprs, fresh) - (c1, c2) - | ( (ThLeaf (_, Const c1), _) - , (_, (V (VConst c2) | ThTree (PEConst (OrdinaryPConst c2)))) ) -> - ord_const (dfs, econst_before c1 src1 pe_exprs, fresh) (c1, c2) - | ( ((V (VConst c1) | ThTree (PEConst (OrdinaryPConst c1))), _) - , (_, (V (VConst c2) | ThTree (PEConst (OrdinaryPConst c2)))) ) -> - ord_const (dfs, pe_exprs, fresh) (c1, c2) - | ( (ThLeaf (_, FunctionApply ((EJust, _), _, [])), _) - , (_, (V (VMaybe Nothing) | ThTree (PEMaybe Nothing))) ) - | (ThLeaf (_, BinTreeBld (Node _)), _), (_, (V (VTree Nul) | ThTree (PETree Nul))) - | ( ( ( ThLeaf - (_, (ListBld (OrdList (IncomprehensionlList (_ :: _))) | Binop (_, Cons, _))) - | LazyLst _ ) - , _ ) - , (_, (ThTree (PEEnum []) | V (VList []))) ) -> - (G, dpf) |> ac_hnd src1 ~ac:ac1 pe1 |> return - | (ThLeaf (_, FunctionApply ((EJust, _), _, [])), _), (_, ThLeaf (_, ENothing)) -> - (G, (dfs, enothing_before src2 pe_exprs, fresh)) - |> ac_hnd src1 ~ac:ac1 pe1 - |> return - | (ThLeaf (_, BinTreeBld (Node _)), _), (_, ThLeaf (_, BinTreeBld Nul)) -> - (G, (dfs, enul_before src2 pe_exprs, fresh)) |> ac_hnd src1 ~ac:ac1 pe1 |> return - | ( ( ( ThLeaf - (_, (ListBld (OrdList (IncomprehensionlList (_ :: _))) | Binop (_, Cons, _))) - | LazyLst _ ) - , _ ) - , (_, ThLeaf (_, ListBld (OrdList (IncomprehensionlList [])))) ) -> - (G, (dfs, eempty_before src2 pe_exprs, fresh)) |> ac_hnd src1 ~ac:ac1 pe1 |> return - | ( (ThLeaf (_, FunctionApply ((EJust, _), e, [])), Some k) - , ( _ - , ( ThLeaf (_, FunctionApply ((EJust, _), _, [])) - | ThTree (PEMaybe (Just _)) - | V (VMaybe (Just _)) ) ) ) -> - let (pe_exprs, fresh), p1' = new_th kk fresh pe_exprs e in - let pe1' = ThTree (PEMaybe (Just p1')) in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ( (ThLeaf (_, BinTreeBld (Node (e1, e2, e3))), Some k) - , ( _ - , (ThLeaf (_, BinTreeBld (Node _)) | V (VTree (Node _)) | ThTree (PETree (Node _))) - ) ) -> - let pat', pe_exprs, fresh = enode_to_pat pe_exprs fresh kk e1 e2 e3 in - let pe1' = ThTree pat' in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ( (ThLeaf (_, ListBld (OrdList (IncomprehensionlList (_ :: _ as ee)))), Some k) - , ( _ - , ( ThLeaf - (_, (ListBld (OrdList (IncomprehensionlList (_ :: _))) | Binop (_, Cons, _))) - | LazyLst _ - | ThTree (PECons _ | PEEnum (_ :: _)) - | V (VList (_ :: _)) ) ) ) -> - let (pe_exprs, fresh), pp' = - List.fold_left_map (fun (pe, f) -> new_th kk f pe) (pe_exprs, fresh) ee - in - let pe1' = ThTree (PEEnum pp') in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ( (LazyLst ll, Some k) - , ( _ - , ( ThLeaf - (_, (ListBld (OrdList (IncomprehensionlList (_ :: _))) | Binop (_, Cons, _))) - | LazyLst _ - | ThTree (PECons _ | PEEnum (_ :: _)) - | V (VList (_ :: _)) ) ) ) -> - let pat', pe_exprs, fresh = lazylst_to_pat pe_exprs fresh ll in - let pe1' = ThTree pat' in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ( (ThLeaf (_, Binop (e1, Cons, e2)), Some k) - , ( _ - , ( ThLeaf - (_, (ListBld (OrdList (IncomprehensionlList (_ :: _))) | Binop (_, Cons, _))) - | LazyLst _ - | ThTree (PECons _ | PEEnum (_ :: _)) - | V (VList (_ :: _)) ) ) ) -> - let pat', pe_exprs, fresh = econs_to_pat pe_exprs fresh kk e1 e2 in - let pe1' = ThTree pat' in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ( (ThLeaf (_, TupleBld (e1, e2, ee)), Some k) - , (_, (ThLeaf (_, TupleBld _) | V (VTuple _) | ThTree (PETuple _))) ) -> - let pat', pe_exprs, fresh = etuple_to_pat pe_exprs fresh kk e1 e2 ee in - let pe1' = ThTree pat' in - let dpf = dfs, add k pe1' pe_exprs, fresh in - ord dpf None src2 ~ac1 ~ac2 pe1' pe2 - | ((ThTree (PEMaybe (Just _)) | V (VMaybe (Just _))), _), (_, ThLeaf (_, ENothing)) -> - return (G, (dfs, enothing_before src2 pe_exprs, fresh)) - | ((V (VTree (Node _)) | ThTree (PETree (Node _))), _), (_, ThLeaf (_, BinTreeBld Nul)) - -> return (G, (dfs, enul_before src2 pe_exprs, fresh)) - | ( ((ThTree (PECons _ | PEEnum (_ :: _)) | V (VList (_ :: _))), _) - , (_, ThLeaf (_, ListBld (OrdList (IncomprehensionlList [])))) ) -> - return (G, (dfs, eempty_before src2 pe_exprs, fresh)) - | (ThLeaf (_, ENothing), _), (_, ThLeaf (_, ENothing)) -> - return (Eq, (dfs, enothing_before src2 @@ enothing_before src1 pe_exprs, fresh)) - | (ThLeaf (_, BinTreeBld Nul), _), (_, ThLeaf (_, BinTreeBld Nul)) -> - return (Eq, (dfs, enul_before src2 @@ enul_before src1 pe_exprs, fresh)) - | ( (ThLeaf (_, ListBld (OrdList (IncomprehensionlList []))), _) - , (_, ThLeaf (_, ListBld (OrdList (IncomprehensionlList [])))) ) -> - return (Eq, (dfs, eempty_before src2 @@ eempty_before src1 pe_exprs, fresh)) - | ( ((ThTree (PEMaybe (Just _)) | V (VMaybe (Just _))), _) - , (_, (ThTree (PEMaybe Nothing) | V (VMaybe Nothing))) ) - | ( ((V (VTree (Node _)) | ThTree (PETree (Node _))), _) - , (_, (V (VTree Nul) | ThTree (PETree Nul))) ) - | ( ((ThTree (PECons _ | PEEnum (_ :: _)) | V (VList (_ :: _))), _) - , (_, (ThTree (PEEnum []) | V (VList []))) ) -> return (G, dpf) - | ((ThTree (PEMaybe Nothing) | V (VMaybe Nothing)), _), (_, ThLeaf (_, ENothing)) -> - return (Eq, (dfs, enothing_before src2 pe_exprs, fresh)) - | ((V (VTree Nul) | ThTree (PETree Nul)), _), (_, ThLeaf (_, BinTreeBld Nul)) -> - return (Eq, (dfs, enul_before src2 pe_exprs, fresh)) - | ( ((ThTree (PEEnum []) | V (VList [])), _) - , (_, ThLeaf (_, ListBld (OrdList (IncomprehensionlList [])))) ) -> - return (Eq, (dfs, eempty_before src2 pe_exprs, fresh)) - | ( ((ThTree (PEMaybe Nothing) | V (VMaybe Nothing)), _) - , (_, (ThTree (PEMaybe Nothing) | V (VMaybe Nothing))) ) - | ( ((V (VTree Nul) | ThTree (PETree Nul)), _) - , (_, (V (VTree Nul) | ThTree (PETree Nul))) ) - | ((ThTree (PEEnum []) | V (VList [])), _), (_, (ThTree (PEEnum []) | V (VList []))) - -> return (Eq, dpf) - | ( (ThLeaf (kk1, FunctionApply ((EJust, _), e1, [])), None) - , (None, ThLeaf (kk2, FunctionApply ((EJust, _), e2, []))) ) -> - inner_call_ee kk1 kk2 dpf e1 e2 - | ( (ThLeaf (kk1, BinTreeBld (Node (e11, e12, e13))), None) - , (None, ThLeaf (kk2, BinTreeBld (Node (e21, e22, e23)))) ) -> - ord_list (inner_call_ee kk1 kk2) dpf ([ e11; e12; e13 ], [ e21; e22; e23 ]) - | ( (ThLeaf (kk1, ListBld (OrdList (IncomprehensionlList (_ :: _ as ee1)))), None) - , (None, ThLeaf (kk2, ListBld (OrdList (IncomprehensionlList (_ :: _ as ee2))))) ) - -> ord_list ~strict_len:false (inner_call_ee kk1 kk2) dpf (ee1, ee2) - | (LazyLst ll1, None), (None, LazyLst ll2) -> ord_ll_ll ll1 ll2 - | ( (ThLeaf (kk1, Binop (e11, Cons, e12)), None) - , (None, ThLeaf (kk2, Binop (e21, Cons, e22))) ) -> - ord_list (inner_call_ee kk1 kk2) dpf ([ e11; e12 ], [ e21; e22 ]) - | (ThLeaf (kk, Binop ((e1, _), Cons, (e2, _))), None), (None, LazyLst ll) -> - ord_e_ll kk e1 e2 ll - | ( (ThLeaf (kk1, Binop (e11, Cons, e12)), None) - , (None, ThLeaf (kk2, ListBld (OrdList (IncomprehensionlList (e21 :: ee2))))) ) -> - let e22 = ListBld (OrdList (IncomprehensionlList ee2)), [] in - ord_list (inner_call_ee kk1 kk2) dpf ([ e11; e12 ], [ e21; e22 ]) - | ( (ThLeaf (kk, ListBld (OrdList (IncomprehensionlList ((e, _) :: ee)))), None) - , (None, LazyLst ll) ) -> - ord_e_ll kk e (ListBld (OrdList (IncomprehensionlList ee))) ll - | ( (ThLeaf (kk1, TupleBld (e11, e12, ee1)), None) - , (None, ThLeaf (kk2, TupleBld (e21, e22, ee2))) ) -> - ord_list (inner_call_ee kk1 kk2) dpf (e11 :: e12 :: ee1, e21 :: e22 :: ee2) - | (ThLeaf (kk, FunctionApply ((EJust, _), (e, _), [])), None), (_, V (VMaybe (Just v))) - -> ord dpf None None ~ac1 ~ac2 (ThLeaf (kk, e)) (V v) - | ( (ThLeaf (kk, BinTreeBld (Node (e1, e2, e3))), None) - , (_, V (VTree (Node (v1, v2, v3)))) ) -> - ord_list (inner_call_ev kk) dpf ([ e1; e2; e3 ], [ v1; v2; v3 ]) - | ( (ThLeaf (kk, ListBld (OrdList (IncomprehensionlList (_ :: _ as ee)))), None) - , (_, V (VList (_ :: _ as vv))) ) -> - ord_list ~strict_len:false (inner_call_ev kk) dpf (ee, vv) - | (LazyLst ll, None), (_, V (VList (v :: vv))) -> ord_v_ll v (VList vv) ll - | (ThLeaf (kk, Binop (e1, Cons, e2)), None), (_, V (VList (v :: vv))) -> - ord_list (inner_call_ev kk) dpf ([ e1; e2 ], [ v; VList vv ]) - | (ThLeaf (kk, TupleBld (e1, e2, ee)), None), (_, V (VTuple (v1, v2, vv))) -> - ord_list (inner_call_ev kk) dpf (e1 :: e2 :: ee, v1 :: v2 :: vv) - | (V (VMaybe (Just v1)), _), (_, V (VMaybe (Just v2))) -> inner_call_vv dpf v1 v2 - | (V (VTree (Node (v11, v12, v13))), _), (_, V (VTree (Node (v21, v22, v23)))) -> - ord_list inner_call_vv dpf ([ v11; v12; v13 ], [ v21; v22; v23 ]) - | (V (VList (_ :: _ as vv1)), _), (_, V (VList (_ :: _ as vv2))) -> - ord_list ~strict_len:false inner_call_vv dpf (vv1, vv2) - | (V (VTuple (v11, v12, vv1)), _), (_, V (VTuple (v21, v22, vv2))) -> - ord_list inner_call_vv dpf (v11 :: v12 :: vv1, v21 :: v22 :: vv2) - | ( (ThTree (PEMaybe (Just p)), _) - , (None, ThLeaf (kk, FunctionApply ((EJust, _), e, []))) ) -> - inner_call_pe kk dpf p e - | ( (ThTree (PETree (Node (p1, p2, p3))), _) - , (None, ThLeaf (kk, BinTreeBld (Node (e1, e2, e3)))) ) -> - ord_list (inner_call_pe kk) dpf ([ p1; p2; p3 ], [ e1; e2; e3 ]) - | (ThTree (PECons (p1, p2)), _), (None, ThLeaf (kk, Binop (e1, Cons, e2))) -> - ord_list (inner_call_pe kk) dpf ([ p1; p2 ], [ e1; e2 ]) - | ( (ThTree (PECons (p1, p2)), _) - , (None, ThLeaf (kk, ListBld (OrdList (IncomprehensionlList (e1 :: ee))))) ) -> - let e2 = ListBld (OrdList (IncomprehensionlList ee)), [] in - ord_list (inner_call_pe kk) dpf ([ p1; p2 ], [ e1; e2 ]) - | (ThTree (PECons (p1, p2)), _), (None, LazyLst ll) -> ord_p_ll p1 p2 ll - | ( (ThTree (PEEnum (_ :: _ as pp)), _) - , (None, ThLeaf (kk, ListBld (OrdList (IncomprehensionlList (_ :: _ as ee))))) ) -> - ord_list ~strict_len:false (inner_call_pe kk) dpf (pp, ee) - | (ThTree (PEEnum (p :: pp)), _), (None, LazyLst ll) -> - ord_p_ll p (P (None, PEEnum pp)) ll - | (ThTree (PEEnum (p1 :: pp)), _), (None, ThLeaf (kk, Binop (e1, Cons, e2))) -> - ord_list (inner_call_pe kk) dpf ([ p1; P (None, PEEnum pp) ], [ e1; e2 ]) - | (ThTree (PETuple (p1, p2, pp)), _), (None, ThLeaf (kk, TupleBld (e1, e2, ee))) -> - ord_list (inner_call_pe kk) dpf (p1 :: p2 :: pp, e1 :: e2 :: ee) - | (ThTree (PEMaybe (Just p1)), _), (_, ThTree (PEMaybe (Just p2))) -> - inner_call_pp dpf p1 p2 - | ( (ThTree (PETree (Node (p11, p12, p13))), _) - , (_, ThTree (PETree (Node (p21, p22, p23)))) ) -> - ord_list inner_call_pp dpf ([ p11; p12; p13 ], [ p21; p22; p23 ]) - | (ThTree (PECons (p11, p12)), _), (_, ThTree (PECons (p21, p22))) -> - ord_list inner_call_pp dpf ([ p11; p12 ], [ p21; p22 ]) - | (ThTree (PECons (p1, p2)), _), (_, ThTree (PEEnum (p :: pp))) -> - ord_list inner_call_pp dpf ([ p1; p2 ], [ p; P (None, PEEnum pp) ]) - | (ThTree (PEEnum (_ :: _ as pp1)), _), (_, ThTree (PEEnum (_ :: _ as pp2))) -> - ord_list ~strict_len:false inner_call_pp dpf (pp1, pp2) - | (ThTree (PETuple (p11, p12, pp1)), _), (_, ThTree (PETuple (p21, p22, pp2))) -> - ord_list inner_call_pp dpf (p11 :: p12 :: pp1, p21 :: p22 :: pp2) - | (ThTree (PEMaybe (Just p)), _), (_, V (VMaybe (Just v))) -> inner_call_pv dpf p v - | (ThTree (PETree (Node (p1, p2, p3))), _), (_, V (VTree (Node (v1, v2, v3)))) -> - ord_list inner_call_pv dpf ([ p1; p2; p3 ], [ v1; v2; v3 ]) - | (ThTree (PEEnum (_ :: _ as pp)), _), (_, V (VList (_ :: _ as vv))) -> - ord_list ~strict_len:false inner_call_pv dpf (pp, vv) - | (ThTree (PECons (p1, p2)), _), (_, V (VList (v :: vv))) -> - ord_list inner_call_pv dpf ([ p1; p2 ], [ v; VList vv ]) - | (ThTree (PETuple (p1, p2, pp)), _), (_, V (VTuple (v1, v2, vv))) -> - ord_list inner_call_pv dpf (p1 :: p2 :: pp, v1 :: v2 :: vv) - | ( (ThLeaf (kk, ListBld (LazyList (e1, e2, e3))), _) - , ( _ - , ( ThLeaf (_, (ListBld _ | Binop (_, Cons, _))) - | LazyLst _ - | ThTree (PECons _ | PEEnum _) - | V (VList _) ) ) ) -> - let (dfs, pe_exprs, fresh), pe1' = - elazylist_hndl e1 e2 e3 (dfs, pe_exprs, kk) fresh >>| conv_res |> err_hnd - in - let pe_exprs = - match pe1' with - | V _ -> src_hnd pe1' src1 pe_exprs - | _ -> pe_exprs - in - ord (dfs, pe_exprs, fresh) src1 src2 ~ac1:true ~ac2 pe1' pe2 - | _, (_, Er _) - | _, (_, Link _) - | ( ((ThLeaf (_, Const _) | ThTree (PEConst _) | V (VConst _)), _) - , (_, (ThLeaf (_, Const _) | ThTree (PEConst _))) ) - | ( ( ( ThLeaf (_, (FunctionApply ((EJust, _), _, []) | ENothing)) - | V (VMaybe _) - | ThTree (PEMaybe _) ) - , _ ) - , ( _ - , ( ThLeaf (_, FunctionApply ((EJust, _), _, [])) - | V (VMaybe _) - | ThTree (PEMaybe _) ) ) ) - | ( ((ThLeaf (_, BinTreeBld _) | V (VTree _) | ThTree (PETree _)), _) - , (_, (ThLeaf (_, BinTreeBld _) | V (VTree _) | ThTree (PETree _))) ) - | ( ((ThLeaf (_, TupleBld _) | V (VTuple _) | ThTree (PETuple _)), _) - , (_, (ThLeaf (_, TupleBld _) | ThTree (PETuple _))) ) - | ( ( ( ThLeaf (_, (ListBld _ | Binop (_, Cons, _))) - | LazyLst _ - | V (VList _) - | ThTree (PECons _ | PEEnum _) ) - , _ ) - , ( _ - , ( ThLeaf (_, (ListBld _ | Binop (_, Cons, _))) - | LazyLst _ - | V (VList _) - | ThTree (PECons _ | PEEnum _) ) ) ) -> rev () - | (ThLeaf (kk, Identificator (Ident n)), _), _ -> - let ((_, pe_exprs_key) as keys) = NMap.find n kk in - let dpf, pe1' = - find_expr dpf keys - >>| (fun ((dfs, pe_exprs, fresh), pe1') -> - (dfs, src_hnd (Link pe_exprs_key) src1 pe_exprs, fresh), pe1') - |> err_hnd - in - ord dpf (Some pe_exprs_key) src2 ~ac1:false ~ac2 pe1' pe2 - | (ThLeaf (kk, IfThenEsle (c, th, el)), _), _ -> - eval_step_ite c th el (dfs, pe_exprs, kk) fresh - >>| (fun (dpf, (e, _)) -> dpf, ThLeaf (kk, e)) - |> complex_hnd - | (ThLeaf (kk, Case (e, br, brs)), _), _ -> - eval_step_case e (dfs, pe_exprs, kk) fresh (br :: brs) - >>| (fun ((dfs, pe_exprs, kk), fresh, (e, _)) -> - (dfs, pe_exprs, fresh), ThLeaf (kk, e)) - |> complex_hnd - | (ThLeaf (kk, FunctionApply (f, a, aa)), _), _ -> - eval_step_funapp (dfs, pe_exprs, kk) fresh (f, a :: aa) >>| conv_res |> complex_hnd - | (ThLeaf (kk, InnerBindings (b, bb, (e, _))), _), _ -> - eval_step_inner_bb (b :: bb) (dfs, pe_exprs, kk) fresh - >>| (fun ((dfs, pe_exprs, kk), fresh) -> (dfs, pe_exprs, fresh), ThLeaf (kk, e)) - |> complex_hnd - | (ThLeaf (kk, Binop (e1, op, e2)), _), _ when op <> Cons -> - eval_arlog (dfs, pe_exprs, kk) fresh e1 e2 op - >>| (fun (dpf, v) -> dpf, V v) - |> complex_hnd - | (ThLeaf (kk, Neg e), _), _ -> - eval_neg (dfs, pe_exprs, kk) fresh e >>| (fun (dpf, v) -> dpf, V v) |> complex_hnd - | ( _ - , ( _ - , ThLeaf - ( _ - , ( IfThenEsle _ - | Case _ - | FunctionApply _ - | InnerBindings _ - | Binop _ - | Neg _ - | Identificator _ ) ) ) ) -> rev () - | _ -> - ord dpf src1 src2 ~ac1 ~ac2 (Er `Typing_err) pe1 - --= fun (_, dpf) -> ord dpf src2 src1 ~ac2 ~ac1 (Er `Typing_err) pe2 - in - let tru dpf = dpf, VConst (Bool true) in - let fls dpf = dpf, VConst (Bool false) in - let ord () = - ord - (dfs, pe_exprs, fresh) - None - None - ~ac1:false - ~ac2:false - (ThLeaf (kk, Stdlib.fst e1)) - (ThLeaf (kk, Stdlib.fst e2)) - in - function - | Plus -> arithm ( + ) return - | Minus -> arithm ( - ) return - | Divide -> - arithm ( / ) (function - | 0, dpf -> Error (`Div_by_zero, dpf) - | _ -> Ok ()) - | Mod -> - arithm Int.rem (function - | 0, dpf -> Error (`Div_by_zero, dpf) - | _ -> Ok ()) - | Multiply -> arithm ( * ) return - | Pow -> - arithm Base.Int.pow (fun (y, dpf) -> - if y < 0 then Error (`Negative_exponent, dpf) else Ok ()) - | And -> log ( && ) - | Or -> log ( || ) - | Less -> - ord () - >>| (function - | L, dpf -> tru dpf - | _, dpf -> fls dpf) - | Greater -> - ord () - >>| (function - | G, dpf -> tru dpf - | _, dpf -> fls dpf) - | EqualityOrLess -> - ord () - >>| (function - | G, dpf -> fls dpf - | _, dpf -> tru dpf) - | EqualityOrGreater -> - ord () - >>| (function - | L, dpf -> fls dpf - | _, dpf -> tru dpf) - | Equality -> - ord () - >>| (function - | Eq, dpf -> tru dpf - | _, dpf -> fls dpf) - | Inequality -> - ord () - >>| (function - | Eq, dpf -> fls dpf - | _, dpf -> tru dpf) - | Cons -> Error ((`Typing_err : crit_err), (dfs, pe_exprs, fresh)) - -and pattern_match to_pe_ex ((dfs, pe_exprs, kk) as env) fresh src ptrn e = - match ptrn with - | Lnk k -> Ok ((k, ThLeaf (kk, e)) :: to_pe_ex, (dfs, pe_exprs, fresh)) - | P (k, pat) -> - let pmv_call_tr k to_pe_ex v dpf = - match pattern_match_v (P (k, pat)) v to_pe_ex with - | Ok to_pe_ex -> Ok (to_pe_ex, dpf) - | Error e -> Error (e, dpf) - in - let pmv_call_lf v dpf = - match pattern_match_v (P (None, pat)) v [] with - | Ok _ -> Ok dpf - | Error e -> Error (e, dpf) - in - let ppm_call to_pe_ex k pk env fresh pat2 = - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, Link pk) :: to_pe_ex - in - match patpat_match to_pe_ex env fresh pat pat2 with - | Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pat2') -> - Ok (to_pe_ex, (dfs, add pk (ThTree pat2') pe_exprs, fresh)) - | Error (e, ((dfs, pe_exprs, fresh), pat2')) -> - Error (e, (dfs, add pk (ThTree pat2') pe_exprs, fresh)) - in - let from_crit_full src ((e : crit_err), ((dfs, pe_exprs, fresh) as dpf)) = - let dpf = - match src with - | None -> dpf - | Some k -> dfs, add k (Er e) pe_exprs, fresh - in - from_crit_err e, dpf - in - let other_exprs typing_err src cont ((_, _, kk) as env) fresh v_call ac = - let v_call ((dfs, pe_exprs, fresh), v) = - let pe_exprs = ext_pe_exprs_opt (V v) pe_exprs src in - v_call v (dfs, pe_exprs, fresh) - in - function - | IfThenEsle (c, th, el) -> - let* (dfs, pe_exprs, fresh), (e, _) = - eval_step_ite c th el env fresh --| from_crit_full src - in - cont ~after_complex:true src (dfs, pe_exprs, kk) fresh e - | Case (e, br, brs) -> - let* env, fresh, (e, _) = - eval_step_case e env fresh (br :: brs) --| from_crit_full src - in - cont ~after_complex:true src env fresh e - | FunctionApply (f, a, aa) -> - eval_step_funapp env fresh (f, a :: aa) --| from_crit_full src - >>= (function - | (dfs, pe_exprs, fresh), `Th (kk, (e, _)) -> - cont ~after_complex:true src (dfs, pe_exprs, kk) fresh e - | dpf, `V v -> v_call (dpf, v)) - | InnerBindings (b, bb, (e, _)) -> - let* env, fresh = eval_step_inner_bb (b :: bb) env fresh --| from_crit_full src in - cont ~after_complex:true src env fresh e - | Binop (e1, op, e2) when op <> Cons -> - eval_arlog env fresh e1 e2 op --| from_crit_full src >>= v_call - | Neg e -> eval_neg env fresh e --| from_crit_full src >>= v_call - | e -> typing_err env fresh src ac e - in - let rec helper_keys_tr helper to_pe_ex src k ((_, pk) as keys) env fresh = - let dfs, pe_exprs, kk = env in - let helper_keys_tr = helper_keys_tr helper to_pe_ex src k in - let* ((dfs, pe_exprs, fresh) as dpf), e = - find_expr (dfs, pe_exprs, fresh) keys --| from_crit_full src - in - match e with - | Link k -> helper_keys_tr (None, k) (dfs, pe_exprs, kk) fresh - | _ -> - let ((dfs, pe_exprs, fresh) as dpf) = - match src with - | Some k -> dfs, add k (Link pk) pe_exprs, fresh - | None -> dpf - in - (match e with - | Er er -> Error (from_crit_err er, dpf) - | V v -> pmv_call_tr k to_pe_ex v dpf - | ThLeaf (kk, e) -> - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, Link pk) :: to_pe_ex - in - helper to_pe_ex None (Some pk) (dfs, pe_exprs, kk) fresh e - | ThTree pat2 -> ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh pat2 - | LazyLst ll -> ptrnll_match env fresh to_pe_ex (Some pk) ll (P (k, pat)) - | Link k -> helper_keys_tr (None, k) (dfs, pe_exprs, kk) fresh (*недостижимо *)) - in - let rec helper_keys_lf helper src k ((_, pk) as keys) (dfs, pe_exprs, kk) fresh = - let helper_keys_lf = helper_keys_lf helper src k in - let* ((dfs, pe_exprs, fresh) as dpf), e = - find_expr (dfs, pe_exprs, fresh) keys --| from_crit_full src - in - match e with - | Link k -> helper_keys_lf (None, k) (dfs, pe_exprs, kk) fresh - | _ -> - let ((dfs, pe_exprs, fresh) as dpf) = - match src with - | None -> dpf - | Some k -> dfs, add k (Link (Stdlib.snd keys)) pe_exprs, fresh - in - (match e with - | Er e -> Error (from_crit_err e, dpf) - | V v -> pmv_call_lf v dpf - | ThLeaf (kk, e) -> helper (Some pk) (dfs, pe_exprs, kk) fresh e - | ThTree pat2 -> - (match patpat_match ~k:(Some pk) [] (dfs, pe_exprs, kk) fresh pat pat2 with - | Ok ((_, dpf), _) -> Ok dpf - | Error (e, (dpf, _)) -> Error (e, dpf)) - | LazyLst _ -> Error (`Typing_err, dpf) - | Link k -> helper_keys_lf (None, k) (dfs, pe_exprs, kk) fresh (*недостижимо *)) - in - let k_hndl_lf v dpf = - match k with - | None -> to_pe_ex, dpf - | Some k -> (k, V v) :: to_pe_ex, dpf - in - let k_hndl_tr to_pe_ex = function - | Some k -> (k, ThTree pat) :: to_pe_ex - | None -> to_pe_ex - in - let ok_lf v (dfs, pe_exprs, fresh) src = - let pe_exprs = ext_pe_exprs_opt (V v) pe_exprs src in - Ok (dfs, pe_exprs, fresh) - in - let not_match_th e (dfs, pe_exprs, kk) fresh src after_complex = - let pe_exprs = - match src, after_complex with - | None, _ | _, false -> pe_exprs - | Some k, true -> add k (ThLeaf (kk, e)) pe_exprs - in - Error (`Not_match, (dfs, pe_exprs, fresh)) - in - let not_match_v v (dfs, pe_exprs, fresh) src after_complex = - let pe_exprs = - match src, after_complex with - | None, _ | _, false -> pe_exprs - | Some k, true -> add k (V v) pe_exprs - in - Error (`Not_match, (dfs, pe_exprs, fresh)) - in - let typing_err (dfs, pe_exprs, kk) fresh src after_complex e = - let pe_exprs = - match src, after_complex with - | None, _ | _, false -> pe_exprs - | Some k, true -> add k (ThLeaf (kk, e)) pe_exprs - in - Error (`Typing_err, (dfs, pe_exprs, fresh)) - in - let elazylist_hndl e1 e2 e3 ((_, _, kk) as env) k src = - elazylist_hndl e1 e2 e3 env fresh --| from_crit_full src - >>= function - | (dfs, pe_exprs, fresh), `LazyLst ll -> - ptrnll_match (dfs, pe_exprs, kk) fresh to_pe_ex src ll (P (k, pat)) - | (dfs, pe_exprs, fresh), `V v -> - let pe_exprs = ext_pe_exprs_opt (V v) pe_exprs src in - pmv_call_tr k to_pe_ex v (dfs, pe_exprs, fresh) - in - (match pat with - | PETree Nul -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = function - | BinTreeBld Nul -> ok_lf (VTree Nul) (dfs, pe_exprs, fresh) src - | BinTreeBld _ as e -> not_match_th e (dfs, pe_exprs, kk) fresh src after_complex - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VTree Nul) - | PEMaybe Nothing -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = function - | ENothing -> ok_lf (VMaybe Nothing) (dfs, pe_exprs, fresh) src - | FunctionApply ((EJust, _), _, []) as e -> - not_match_th e (dfs, pe_exprs, kk) fresh src after_complex - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VMaybe Nothing) - | PEConst (OrdinaryPConst Unit) -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = - let _ = after_complex in - function - | Const Unit -> ok_lf (VConst Unit) (dfs, pe_exprs, fresh) src - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VConst Unit) - | PEConst (OrdinaryPConst (Bool _ as c)) -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = function - | Const c' when c = c' -> ok_lf (VConst c) (dfs, pe_exprs, fresh) src - | Const (Bool b') -> - not_match_v (VConst (Bool b')) (dfs, pe_exprs, fresh) src after_complex - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VConst c) - | PEConst (OrdinaryPConst (Int _ as c)) -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = function - | Const c' when c = c' -> ok_lf (VConst c) (dfs, pe_exprs, fresh) src - | Const (Int x) -> - not_match_v (VConst (Int x)) (dfs, pe_exprs, fresh) src after_complex - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VConst c) - | PEConst (NegativePInt i) -> - let rec helper ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = function - | Const (Int x) when x = -i -> ok_lf (VConst (Int x)) (dfs, pe_exprs, fresh) src - | Const (Int x) -> - not_match_v (VConst (Int x)) (dfs, pe_exprs, fresh) src after_complex - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_lf (helper ~after_complex:false) src k keys env fresh - | e -> other_exprs typing_err src helper env fresh pmv_call_lf after_complex e - in - helper ~after_complex:false src env fresh e >>| k_hndl_lf (VConst (Int (-i))) - | PETree (Node (p1, p2, p3)) -> - let rec helper to_pe_ex k ~after_complex src ((dfs, pe_exprs, kk) as env) fresh - = function - | BinTreeBld Nul -> - not_match_v (VTree Nul) (dfs, pe_exprs, fresh) src after_complex - | BinTreeBld (Node (e1, e2, e3)) -> - (match src with - | None -> - pattern_match_list - ~strict_len:true - (k_hndl_tr to_pe_ex k) - env - fresh - [ p1; p2; p3 ] - [ e1; e2; e3 ] - | Some pk -> - let pat', pe_exprs, fresh = enode_to_pat pe_exprs fresh kk e1 e2 e3 in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh pat') - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_tr (helper ~after_complex:false) to_pe_ex src k keys env fresh - | e -> - let cont = helper to_pe_ex k in - let pmv_call = pmv_call_tr k to_pe_ex in - other_exprs typing_err src cont env fresh pmv_call after_complex e - in - helper ~after_complex:false to_pe_ex k src env fresh e - | PEEnum pp -> - let rec helper to_pe_ex k ~after_complex src ((dfs, pe_exprs, kk) as env) fresh - = function - | ListBld (LazyList (e1, e2, e3)) -> elazylist_hndl e1 e2 e3 env k src - | ListBld (OrdList (IncomprehensionlList ee)) -> - (match src with - | None -> - let to_pe_ex = k_hndl_tr to_pe_ex k in - pattern_match_list ~strict_len:false to_pe_ex env fresh pp ee - | Some pk -> - let (pe_exprs, fresh), pp' = - List.fold_left_map (fun (pe, f) -> new_th kk f pe) (pe_exprs, fresh) ee - in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh (PEEnum pp')) - | Binop (((e1, _) as ex1), Cons, ((e2, _) as ex2)) as e -> - (match pp with - | [] -> not_match_th e (dfs, pe_exprs, kk) fresh src after_complex - | p :: pp -> - (match src with - | None -> - let* to_pe_ex, (dfs, pe_exprs, fresh) = - pattern_match to_pe_ex (dfs, pe_exprs, kk) fresh None p e1 - in - let p2 = P (None, PEEnum pp) in - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, ThTree (PECons (p, p2))) :: to_pe_ex - in - pattern_match to_pe_ex (dfs, pe_exprs, kk) fresh None p2 e2 - | Some pk -> - let pat', pe_exprs, fresh = econs_to_pat pe_exprs fresh kk ex1 ex2 in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh pat')) - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_tr (helper ~after_complex:false) to_pe_ex src k keys env fresh - | e -> - let cont = helper to_pe_ex k in - let pmv_call = pmv_call_tr k to_pe_ex in - other_exprs typing_err src cont env fresh pmv_call after_complex e - in - helper ~after_complex:false to_pe_ex k src env fresh e - | PECons (p1, p2) -> - let rec helper to_pe_ex k ~after_complex src ((dfs, pe_exprs, kk) as env) fresh - = function - | ListBld (LazyList (e1, e2, e3)) -> elazylist_hndl e1 e2 e3 env k src - | Binop (ex1, Cons, ex2) -> - (match src with - | None -> - pattern_match_list - ~strict_len:true - (k_hndl_tr to_pe_ex k) - env - fresh - [ p1; p2 ] - [ ex1; ex2 ] - | Some pk -> - let pat', pe_exprs, fresh = econs_to_pat pe_exprs fresh kk ex1 ex2 in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh pat') - | ListBld (OrdList (IncomprehensionlList [])) -> - not_match_v (VList []) (dfs, pe_exprs, fresh) src after_complex - | ListBld (OrdList (IncomprehensionlList (e :: ee))) -> - (match src with - | None -> - pattern_match_list - ~strict_len:true - (k_hndl_tr to_pe_ex k) - env - fresh - [ p1; p2 ] - [ e; ListBld (OrdList (IncomprehensionlList ee)), [] ] - | Some pk -> - let (pe_exprs, fresh), pp' = - List.fold_left_map - (fun (pe, f) -> new_th kk f pe) - (pe_exprs, fresh) - (e :: ee) - in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh (PEEnum pp')) - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_tr (helper ~after_complex:false) to_pe_ex src k keys env fresh - | e -> - let cont = helper to_pe_ex k in - let pmv_call = pmv_call_tr k to_pe_ex in - other_exprs typing_err src cont env fresh pmv_call after_complex e - in - helper ~after_complex:false to_pe_ex k src env fresh e - | PEMaybe (Just p) -> - let rec helper to_pe_ex k ~after_complex src ((dfs, pe_exprs, kk) as env) fresh - = function - | ENothing -> - not_match_v (VMaybe Nothing) (dfs, pe_exprs, fresh) src after_complex - | FunctionApply ((EJust, _), ((e, _) as ex), []) -> - (match src with - | None -> - let to_pe_ex = k_hndl_tr to_pe_ex k in - pattern_match to_pe_ex (dfs, pe_exprs, kk) fresh None p e - | Some pk -> - let (pe_exprs, fresh), p1' = new_th kk fresh pe_exprs ex in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh (PEMaybe (Just p1'))) - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_tr (helper ~after_complex:false) to_pe_ex src k keys env fresh - | e -> - let cont = helper to_pe_ex k in - let pmv_call = pmv_call_tr k to_pe_ex in - other_exprs typing_err src cont env fresh pmv_call after_complex e - in - helper ~after_complex:false to_pe_ex k src env fresh e - | PETuple (p1, p2, pp) -> - let rec helper to_pe_ex k ~after_complex src ((dfs, pe_exprs, kk) as env) fresh = - let _ = after_complex in - function - | TupleBld (e1, e2, ee) -> - (match src with - | None -> - pattern_match_list - ~strict_len:true - (k_hndl_tr to_pe_ex k) - env - fresh - (p1 :: p2 :: pp) - (e1 :: e2 :: ee) - | Some pk -> - let pat', pe_exprs, fresh = etuple_to_pat pe_exprs fresh kk e1 e2 ee in - ppm_call to_pe_ex k pk (dfs, pe_exprs, kk) fresh pat') - | Identificator (Ident n) -> - let keys = NMap.find n kk in - helper_keys_tr (helper ~after_complex:false) to_pe_ex src k keys env fresh - | e -> - let cont = helper to_pe_ex k in - let pmv_call = pmv_call_tr k to_pe_ex in - other_exprs typing_err src cont env fresh pmv_call after_complex e - in - helper ~after_complex:false to_pe_ex k src env fresh e) - -and pattern_match_list ~strict_len to_pe_ex (dfs, pe_exprs, kk) fresh pp ee = - let rec helper pp ee (to_pe_ex, ((dfs, pe_exprs, fresh) as dpf)) = - match pp, ee with - | [], [] -> Ok (to_pe_ex, dpf) - | p :: pp, (e, _) :: ee -> - pattern_match to_pe_ex (dfs, pe_exprs, kk) fresh None p e >>= helper pp ee - | _ -> Error ((if strict_len then `Typing_err else `Not_match), dpf) - in - helper pp ee (to_pe_ex, (dfs, pe_exprs, fresh)) - -and patpat_match ?(k = None) to_pe_ex ((dfs, pe_exprs, kk) as env) fresh pat1 pat2 = - let suc_default = Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pat2) in - let suc_with_k k v = Ok ((to_pe_ex, (dfs, add k (V v) pe_exprs, fresh)), pat2) in - let not_match_default = Error (`Not_match, ((dfs, pe_exprs, fresh), pat2)) in - let not_match_with_k k v = - Error (`Not_match, ((dfs, add k (V v) pe_exprs, fresh), pat2)) - in - let typing_error = - Error (`Typing_err, ((dfs, ext_pe_exprs_opt (ThTree pat2) pe_exprs k, fresh), pat2)) - in - let ptrnptrn_match' to_pe_ex env fresh p1 p2 err_p ok = - match ptrnptrn_match to_pe_ex env fresh p1 p2 with - | Error (e, (dpf, p2')) -> Error (e, (dpf, err_p p2')) - | Ok (td, p2') -> ok td p2' - in - let helper_conscons env fresh p11 p12 p21 p22 = - let ok1 (to_pe_ex, (d, p, f)) p21' = - let err_p p22' = PECons (p21', p22') in - ptrnptrn_match' to_pe_ex (d, p, kk) f p12 p22 err_p - @@ fun td p22' -> Ok (td, PECons (p21', p22')) - in - ptrnptrn_match' to_pe_ex env fresh p11 p21 (fun p21' -> PECons (p21', p22)) ok1 - in - match pat1, pat2, k with - | PETree (Node (p11, p12, p13)), PETree (Node (p21, p22, p23)), _ -> - let node p1 p2 p3 = PETree (Node (p1, p2, p3)) in - let ok2 p21' (to_pe_ex, (d, p, f)) p22' = - let err_p = node p21' p22' in - ptrnptrn_match' to_pe_ex (d, p, kk) f p13 p23 err_p - @@ fun td p23' -> Ok (td, node p21' p22' p23') - in - let ok1 (to_pe_ex, (d, p, f)) p21' = - let err_p p22' = node p21' p22' p23 in - ptrnptrn_match' to_pe_ex (d, p, kk) f p12 p22 err_p (ok2 p21') - in - ptrnptrn_match' to_pe_ex env fresh p11 p21 (fun p21' -> node p21' p22 p23) ok1 - | PETree Nul, PETree Nul, None | PEMaybe Nothing, PEMaybe Nothing, None -> suc_default - | PETree Nul, PETree Nul, Some k -> suc_with_k k (VTree Nul) - | PEMaybe Nothing, PEMaybe Nothing, Some k -> suc_with_k k (VMaybe Nothing) - | PEConst c, PEConst c', None when c = c' -> suc_default - | PEConst (OrdinaryPConst c), PEConst (OrdinaryPConst c'), Some k when c = c' -> - suc_with_k k (VConst c) - | PEConst (NegativePInt i), PEConst (NegativePInt i'), Some k when i = i' -> - suc_with_k k (VConst (Int (-i))) - | PEMaybe (Just p1), PEMaybe (Just p2), _ -> - let ok td p2' = Ok (td, PEMaybe (Just p2')) in - let env = dfs, pe_exprs, kk in - ptrnptrn_match' to_pe_ex env fresh p1 p2 (fun p2' -> PEMaybe (Just p2')) ok - | PEMaybe _, PEMaybe _, _ - | PETree _, PETree _, _ - | PEConst (OrdinaryPConst (Bool _)), PEConst (OrdinaryPConst (Bool _)), None - | ( PEConst (OrdinaryPConst (Int _) | NegativePInt _) - , PEConst (OrdinaryPConst (Int _) | NegativePInt _) - , None ) - | PECons _, PEEnum [], _ - | PEEnum [], PECons _, _ -> not_match_default - | PEConst (OrdinaryPConst (Bool _)), PEConst (OrdinaryPConst (Bool _ as c)), Some k - | PEConst (OrdinaryPConst (Int _)), PEConst (OrdinaryPConst (Int _ as c)), Some k -> - not_match_with_k k (VConst c) - | PEConst (OrdinaryPConst (Int _)), PEConst (NegativePInt i), Some k -> - not_match_with_k k (VConst (Int (-i))) - | PEConst (NegativePInt _), PEConst (OrdinaryPConst (Int i)), Some k -> - not_match_with_k k (VConst (Int i)) - | PETuple (p11, p12, pp1), PETuple (p21, p22, pp2), _ -> - let ok2 p21' td p22' = - match ptrnptrn_match_list ~strict_len:true kk (td, []) pp1 pp2 with - | Ok (td, pp2') -> Ok (td, PETuple (p21', p22', pp2')) - | Error (e, (dpf, pp2')) -> Error (e, (dpf, PETuple (p21', p22', pp2'))) - in - let ok1 (to_pe_ex, (d, p, f)) p21' = - let err_p p22' = PETuple (p21', p22', pp2) in - ptrnptrn_match' to_pe_ex (d, p, kk) f p12 p22 err_p (ok2 p21') - in - ptrnptrn_match' to_pe_ex env fresh p11 p21 (fun p21' -> PETuple (p21', p22, pp2)) ok1 - | PEEnum pp1, PEEnum pp2, _ -> - let init = (to_pe_ex, (dfs, pe_exprs, fresh)), [] in - (match ptrnptrn_match_list ~strict_len:false kk init pp1 pp2 with - | Ok (td, pp2') -> Ok (td, PEEnum pp2') - | Error (e, (dpf, pp2')) -> Error (e, (dpf, PEEnum pp2'))) - | PECons (p11, p12), PECons (p21, p22), _ -> helper_conscons env fresh p11 p12 p21 p22 - | PECons (p11, p12), PEEnum (p21 :: pp), _ -> - let pe_exprs, fresh = add fresh (ThTree (PEEnum pp)) pe_exprs, fresh + 1 in - helper_conscons (dfs, pe_exprs, kk) fresh p11 p12 p21 (Lnk (fresh - 1)) - | PEEnum (p11 :: pp), PECons (p21, p22), _ -> - (helper_conscons (dfs, pe_exprs, kk) fresh p11 @@ P (None, PEEnum pp)) p21 p22 - | _ -> typing_error - -and ptrnptrn_match_list ~strict_len kk init pp1 pp2 = - let rec helper = function - | Ok (td, pp'), [], [] -> Ok (td, List.rev pp') - | Ok ((_, dpf), pp'), _ :: _, [] -> - Error ((if strict_len then `Typing_err else `Not_match), (dpf, List.rev pp')) - | Error (_, (dpf, pp')), _ :: _, [] when strict_len -> - Error (`Typing_err, (dpf, List.rev pp')) - | Error (e, (dpf, pp')), _, [] -> Error (e, (dpf, List.rev pp')) - | Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pp'), p1 :: pp1, p2 :: pp2 -> - (match ptrnptrn_match to_pe_ex (dfs, pe_exprs, kk) fresh p1 p2 with - | Ok (td, p2') -> helper (Ok (td, p2' :: pp'), pp1, pp2) - | Error (e, (dpf, p2')) -> helper (Error (e, (dpf, p2' :: pp')), pp1, pp2)) - | Ok ((_, dpf), pp'), [], _ :: _ when strict_len -> - helper (Error (`Typing_err, (dpf, pp')), pp1, pp2) - | Ok ((_, dpf), pp'), [], _ :: _ -> helper (Error (`Not_match, (dpf, pp')), pp1, pp2) - | Error (_, (dpf, pp')), [], p2 :: pp2 when strict_len -> - helper (Error (`Typing_err, (dpf, p2 :: pp')), pp1, pp2) - | Error (e, (dpf, pp')), [], p2 :: pp2 -> - helper (Error (e, (dpf, p2 :: pp')), pp1, pp2) - | Error (e, (dpf, pp')), _ :: pp1, p2 :: pp2 -> - helper (Error (e, (dpf, p2 :: pp')), pp1, pp2) - in - helper (Ok init, pp1, pp2) - -and ptrnptrn_match to_pe_ex ((dfs, pe_exprs, kk) as env) fresh p1 p2 = - match p1, p2 with - | Lnk k1, (Lnk k2 | P (Some k2, _)) -> - Ok (((k1, Link k2) :: to_pe_ex, (dfs, pe_exprs, fresh)), p2) - | Lnk k1, P (None, pat2) -> - let dpf = dfs, add fresh (ThTree pat2) pe_exprs, fresh + 1 in - Ok (((k1, Link fresh) :: to_pe_ex, dpf), Lnk fresh) - | P (None, pat1), P (None, pat2) -> - (match patpat_match to_pe_ex env fresh pat1 pat2 with - | Ok (td, pat2') -> Ok (td, P (None, pat2')) - | Error (e, (dpf, pat2')) -> Error (e, (dpf, P (None, pat2')))) - | (P (k1, pat1) as p), (Lnk k2 | P (Some k2, _)) -> - let rec helper_key k = - let e = find k pe_exprs in - let dpf = dfs, pe_exprs, fresh in - let pm_res_hndl = function - | Ok (to_pe_ex, dpf) -> Ok ((to_pe_ex, dpf), Lnk k) - | Error (e, dpf) -> Error (e, (dpf, Lnk k)) - in - match e with - | Er e -> Error (from_crit_err e, (dpf, Lnk k)) - | V v -> - (match pattern_match_v p1 v to_pe_ex with - | Ok to_pe_ex -> Ok ((to_pe_ex, dpf), Lnk k) - | Error e -> Error (e, (dpf, Lnk k))) - | ThLeaf (kk, e) -> - pattern_match to_pe_ex (dfs, pe_exprs, kk) fresh (Some k) p1 e |> pm_res_hndl - | Link k' -> helper_key k' - | ThTree pat2 -> - let pe_exprs = - match k1 with - | None -> pe_exprs - | Some k1 -> add k1 (Link k) pe_exprs - in - (match patpat_match ~k:k1 to_pe_ex (dfs, pe_exprs, kk) fresh pat1 pat2 with - | Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pat2') -> - Ok ((to_pe_ex, (dfs, add k (ThTree pat2') pe_exprs, fresh)), Lnk k) - | Error (e, ((dfs, pe_exprs, fresh), pat2')) -> - Error (e, ((dfs, add k (ThTree pat2') pe_exprs, fresh), Lnk k))) - | LazyLst ll -> ptrnll_match env fresh [] (Some k) ll p |> pm_res_hndl - in - helper_key k2 - | P (Some _, _), P (None, pat2) -> - let p2' = P (Some fresh, pat2) in - let dfs, pe_exprs, fresh = dfs, add fresh (ThTree pat2) pe_exprs, fresh + 1 in - ptrnptrn_match to_pe_ex (dfs, pe_exprs, kk) fresh p1 p2' - -and ptrnll_match (dfs, pe_exprs, kk) fresh = - let rec helper dpf to_pe_ex src ll = - let peconsll_match ((dfs, pe_exprs, fresh) as dpf) to_pe_ex k p11 p12 = function - | None -> - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, ThTree (PECons (p11, p12))) :: to_pe_ex - in - let v21, pe22 = lazylst_to_cons ll in - let* to_pe_ex = pattern_match_v p11 v21 to_pe_ex --| fun e -> e, dpf in - (match pe22 with - | `V v -> - (match pattern_match_v p12 v to_pe_ex with - | Ok to_pe_ex -> Ok (to_pe_ex, dpf) - | Error e -> Error (e, dpf)) - | `LazyLst ll -> helper dpf to_pe_ex None ll p12) - | Some pk -> - let pat2, pe_exprs, fresh = lazylst_to_pat pe_exprs fresh ll in - let to_pe_ex = - match k with - | None -> to_pe_ex - | Some k -> (k, Link pk) :: to_pe_ex - in - (match - patpat_match to_pe_ex (dfs, pe_exprs, kk) fresh (PECons (p11, p12)) pat2 - with - | Ok ((to_pe_ex, (dfs, pe_exprs, fresh)), pat2') -> - Ok (to_pe_ex, (dfs, add pk (ThTree pat2') pe_exprs, fresh)) - | Error (e, ((dfs, pe_exprs, fresh), pat2')) -> - Error (e, (dfs, add pk (ThTree pat2') pe_exprs, fresh))) - in - function - | Lnk k -> Ok ((k, LazyLst ll) :: to_pe_ex, dpf) - | P (k, PECons (p1, p2)) -> peconsll_match dpf to_pe_ex k p1 p2 src - | P (_, PEEnum []) -> Error (`Not_match, dpf) - | P (k, PEEnum (p :: pp)) -> peconsll_match dpf to_pe_ex k p (P (None, PEEnum pp)) src - | _ -> Error (`Typing_err, dpf) - in - helper (dfs, pe_exprs, fresh) -;; - -let eval = eval_bnds TopLevel diff --git a/Haskell/lib/eval.mli b/Haskell/lib/eval.mli deleted file mode 100644 index c57b95af0..000000000 --- a/Haskell/lib/eval.mli +++ /dev/null @@ -1,24 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Ast - -type crit_err = - [ `Typing_err - | `Not_exh - | `Div_by_zero - | `Negative_exponent - ] - -type env -type fresh - -val eval - : env - -> fresh - -> binding_list - -> (env * fresh, crit_err * (env * fresh)) Result.t - -val init_env : env -val init_fresh : fresh diff --git a/Haskell/lib/inferencer.ml b/Haskell/lib/inferencer.ml deleted file mode 100644 index 9003b09fe..000000000 --- a/Haskell/lib/inferencer.ml +++ /dev/null @@ -1,704 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Typedtree -open Ast - -module R : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - end - - val fresh : int t - - (** Running a transformer: getting the inner result value *) - val run : 'a t -> int -> int * ('a, error) Result.t -end = struct - (* A compositon: State monad after Result monad *) - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let lbindings, r = m st in - match r with - | Result.Error x -> lbindings, Error x - | Ok a -> f a lbindings - ;; - - let fail e st = st, Base.Result.fail e - let return x lbindings = lbindings, Base.Result.return x - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Ok x -> st, Ok (f x) - | st, Result.Error e -> st, Result.Error e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - let ( let+ ) = ( >>| ) - end - - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - end - - let fresh : int t = fun lbindings -> lbindings + 1, Result.Ok lbindings - let run m = m -end - -type fresh = int - -module Type = struct - type t = ty - - let rec occurs_in v = function - | Ty_var b | Ty_ord b | Ty_enum b -> b = v - | Ty_arrow (l, r) -> occurs_in v l || occurs_in v r - | Ty_prim _ -> false - | Ty_list ty | Ty_tree ty | Ty_maybe ty -> occurs_in v ty - | Ty_tuple (ty1, ty2, ty_list) -> - List.exists (fun ty -> occurs_in v ty) (ty1 :: ty2 :: ty_list) - ;; - - let free_vars = - let rec helper acc = function - | Ty_var b | Ty_ord b | Ty_enum b -> VarSet.add b acc - | Ty_arrow (l, r) -> helper (helper acc l) r - | Ty_prim _ -> acc - | Ty_list ty | Ty_tree ty | Ty_maybe ty -> helper acc ty - | Ty_tuple (ty1, ty2, ty_list) -> List.fold_left helper acc (ty1 :: ty2 :: ty_list) - in - helper VarSet.empty - ;; -end - -module Subst : sig - type t - - val empty : t - val singleton : fresh -> ty -> t R.t - val apply : t -> ty -> ty - val unify : ty -> ty -> t R.t - - (** Compositon of substitutions *) - val compose : t -> t -> t R.t - - val compose_all : t list -> t R.t - val remove : t -> fresh -> t -end = struct - open R - open R.Syntax - open Base - - (* an association list. In real world replace it by a finite map *) - type t = (fresh * ty) list - - let empty = [] - let mapping k v = if Type.occurs_in k v then fail `Occurs_check else return (k, v) - - let singleton k v = - let* mapping = mapping k v in - return [ mapping ] - ;; - - let find_exn k xs = List.Assoc.find_exn xs k ~equal:Int.equal - let remove xs k = List.Assoc.remove xs k ~equal:Int.equal - - let apply s = - let rec helper = function - | Ty_var b as ty -> - (match find_exn b s with - | exception Not_found_s _ -> ty - | x -> x) - | Ty_arrow (l, r) -> Ty_arrow (helper l, helper r) - | Ty_list ty -> Ty_list (helper ty) - | Ty_tuple (ty1, ty2, ty_list) -> - Ty_tuple (helper ty1, helper ty2, List.map ty_list ~f:helper) - | Ty_tree ty -> Ty_tree (helper ty) - | Ty_maybe ty -> Ty_maybe (helper ty) - | Ty_ord ty -> - (match helper (Ty_var ty) with - | Ty_var ty' -> Ty_ord ty' - | t' -> t') - | Ty_enum ty -> - (match helper (Ty_var ty) with - | Ty_var ty' -> Ty_enum ty' - | t' -> t') - | other -> other - in - helper - ;; - - let rec unify l r = - match l, r with - | Ty_prim l, Ty_prim r when String.equal l r -> return empty - | (Ty_var a, Ty_var b | Ty_ord a, Ty_ord b | Ty_enum a, Ty_enum b) when Int.equal a b - -> return empty - | Ty_ord a, Ty_ord b | Ty_enum a, Ty_enum b -> singleton a (Ty_var b) - | Ty_var b, t | t, Ty_var b -> singleton b t - | Ty_ord _, Ty_arrow _ | Ty_arrow _, Ty_ord _ -> fail (`Unification_failed (l, r)) - | Ty_enum b, (Ty_prim _ as t) | (Ty_prim _ as t), Ty_enum b -> singleton b t - | Ty_ord b, ((Ty_list t | Ty_maybe t | Ty_tree t) as ty) - | ((Ty_list t | Ty_maybe t | Ty_tree t) as ty), Ty_ord b -> - let* s = fresh >>= fun f -> unify (Ty_ord f) t in - let ty2 = apply s ty in - singleton b ty2 >>= fun s2 -> compose s2 s - | Ty_ord b, (Ty_tuple (t1, t2, tt) as ty) | (Ty_tuple (t1, t2, tt) as ty), Ty_ord b -> - let* s = - RList.fold_left (t1 :: t2 :: tt) ~init:(return empty) ~f:(fun s t -> - let* s2 = fresh >>= fun f -> unify (Ty_ord f) t in - compose s2 s) - in - let ty2 = apply s ty in - singleton b ty2 >>= fun s2 -> compose s2 s - | Ty_ord b, t | t, Ty_ord b -> singleton b t - | Ty_arrow (l1, r1), Ty_arrow (l2, r2) -> - let* subs1 = unify l1 l2 in - let* subs2 = unify (apply subs1 r1) (apply subs1 r2) in - compose subs2 subs1 - | Ty_list ty1, Ty_list ty2 | Ty_tree ty1, Ty_tree ty2 | Ty_maybe ty1, Ty_maybe ty2 -> - unify ty1 ty2 - | Ty_tuple (t1, t2, tt), Ty_tuple (t1', t2', tt') - when List.length tt = List.length tt' -> - RList.fold_left - (List.zip_exn (t1 :: t2 :: tt) (t1' :: t2' :: tt')) - ~init:(return empty) - ~f:(fun acc (t1, t2) -> - let* subs = unify (apply acc t1) (apply acc t2) in - compose subs acc) - | _ -> fail (`Unification_failed (l, r)) - - and extend s (k, v) = - let bind v f = - match v with - | Ty_var k' when k = k' -> return s - | _ -> f v - in - let ( let** ) = bind in - let** v = v in - match List.Assoc.find s ~equal:Int.equal k with - | None -> - let** v = apply s v in - let* s2 = singleton k v in - RList.fold_left s ~init:(return s2) ~f:(fun acc (k, v) -> - let** v = apply s2 v in - let* mapping = mapping k v in - return (mapping :: acc)) - | Some v2 -> - let* s2 = unify v v2 in - compose s2 s - - and compose s2 s1 = RList.fold_left s2 ~init:(return s1) ~f:extend - - let compose_all ss = RList.fold_left ss ~init:(return empty) ~f:compose -end - -module VarSet = struct - include VarSet - - let fold_left_m f acc set = - fold - (fun x acc -> - let open R.Syntax in - let* acc = acc in - f acc x) - acc - set - ;; -end - -module Scheme = struct - type t = scheme - - let free_vars = function - | S (bs, t) -> VarSet.diff (Type.free_vars t) bs - ;; - - let apply sub (S (names, ty)) = - let s2 = VarSet.fold (fun k s -> Subst.remove s k) names sub in - S (names, Subst.apply s2 ty) - ;; -end - -module SMap = Map.Make (String) - -module TypeEnv = struct - open Base - - type t = scheme SMap.t - - let extend : t -> string * scheme -> t = fun e (name, scheme) -> SMap.add name scheme e - let empty = SMap.empty - - let pp_some ppf names = - let open Stdlib.Format in - fprintf ppf "[ \n%a ]" (fun ppf env -> - SMap.iter - (fun name (S (bb, t)) -> - match List.find names ~f:(String.equal name) with - | Some _ -> fprintf ppf "%s: %a %a\n" name VarSet.pp bb Pprint.pp_ty t - | None -> ()) - env) - ;; - - let free_vars : t -> VarSet.t = - fun env -> - SMap.fold (fun _ s acc -> VarSet.union acc (Scheme.free_vars s)) env VarSet.empty - ;; - - let apply s = SMap.map (Scheme.apply s) - let find_exn = SMap.find -end - -type typeenv = TypeEnv.t - -let typeenv_print_int = - TypeEnv.extend - TypeEnv.empty - ("print_int", S (VarSet.empty, Ty_arrow (Ty_prim "Int", Ty_prim "()"))) -;; - -let initial_env = - TypeEnv.extend - typeenv_print_int - ( "seq" - , S - ( VarSet.add 1 (VarSet.add 0 VarSet.empty) - , Ty_arrow (Ty_var 0, Ty_arrow (Ty_var 1, Ty_var 1)) ) ) -;; - -let typeenv_empty = TypeEnv.empty -let pp_some_typeenv ppf (n, e) = TypeEnv.pp_some ppf n e - -open R -open R.Syntax - -let unify = Subst.unify -let fresh_var = fresh >>| fun n -> Ty_var n - -let instantiate : scheme -> ty R.t = - fun (S (bs, t)) -> - VarSet.fold_left_m - (fun typ name -> - let* f1 = fresh_var in - let* s = Subst.singleton name f1 in - return (Subst.apply s typ)) - bs - (return t) -;; - -let generalize : TypeEnv.t -> Type.t -> Scheme.t = - fun env ty -> - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - S (free, ty) -;; - -let lookup_env e xs = - match TypeEnv.find_exn e xs with - | exception Not_found -> fail (`No_variable e) - | scheme -> - let* ans = instantiate scheme in - return ans -;; - -let arrow3 t1 t2 t3 = Ty_arrow (t1, Ty_arrow (t2, t3)) - -let built_in_sign = - let pr_bool, pr_int = Ty_prim "Bool", Ty_prim "Int" in - function - | And | Or -> return @@ arrow3 pr_bool pr_bool pr_bool - | Cons -> - let+ t = fresh_var in - arrow3 t (Ty_list t) (Ty_list t) - | Plus | Minus | Divide | Mod | Multiply | Pow -> return @@ arrow3 pr_int pr_int pr_int - | _ -> - let+ t = fresh in - arrow3 (Ty_ord t) (Ty_ord t) (Ty_prim "Bool") -;; - -let rec tp_to_ty = function - | TUnit -> Ty_prim "()" - | TBool -> Ty_prim "Bool" - | TInt -> Ty_prim "Int" - | MaybeParam tp -> Ty_maybe (tp_to_ty tp) - | TreeParam tp -> Ty_tree (tp_to_ty tp) - | ListParam tp -> Ty_list (tp_to_ty tp) - | TupleParams (t1, t2, tt) -> Ty_tuple (tp_to_ty t1, tp_to_ty t2, List.map tp_to_ty tt) - | FunctionType (FuncT (t1, t2, [])) -> Ty_arrow (tp_to_ty t1, tp_to_ty t2) - | FunctionType (FuncT (t1, t2, hd :: tl)) -> - Ty_arrow (tp_to_ty t1, tp_to_ty (FunctionType (FuncT (t2, hd, tl)))) -;; - -let rec bindings bb env = - let f (subst, env) = function - | FunDef (_, p, pp, bd, bb), tv0 -> - let* tt, inner_env = helper_pp (p :: pp) env in - let* s1, inner_env, _ = bindings bb inner_env in - let* s2, t1 = - (match bd with - | Guards (ep, eps) -> helper_guards (ep :: eps) inner_env - | OrdBody e -> infer e inner_env) - >>| fun (s, ty) -> s, ty_arr (List.map (Subst.apply s) (List.rev tt)) ty - in - let* s = Subst.compose_all [ s2; s1; subst ] in - let* s3 = unify (Subst.apply s tv0) t1 in - let* s = Subst.compose s3 s in - Subst.compose s subst >>| fun s -> s, env - | VarsDef (_, bd, bb), tv0 -> - let* s1, inner_env, _ = bindings bb env in - let* s2, t1 = - match bd with - | Guards (ep, eps) -> helper_guards (ep :: eps) env - | OrdBody e -> infer e inner_env - in - let* s = Subst.compose_all [ s2; s1; subst ] in - let* s_p = Subst.compose s subst in - let* s3 = unify (Subst.apply s_p tv0) t1 in - let* s = Subst.compose s3 s in - Subst.compose s subst >>| fun fs -> fs, env - in - let* prep_bb, decls, delta_env, env, names = prep [] [] TypeEnv.empty env [] bb in - let init = - RList.fold_left - decls - ~init:(return (Subst.empty, env)) - ~f:(fun (s, env) (name, t1) -> - let* _ = lookup_env name delta_env in - let* t2 = lookup_env name env in - let* s1 = unify t1 t2 in - Subst.compose s1 s >>| fun fs -> fs, TypeEnv.apply s1 env) - in - let* init_env = init >>| snd in - let* s, env = RList.fold_left prep_bb ~init ~f in - let* fenv = - RList.fold_left - names - ~init:(return (TypeEnv.apply s env)) - ~f:(fun env' name -> - lookup_env name env' >>| fun t -> TypeEnv.extend env' (name, generalize init_env t)) - in - return (s, fenv, names) - -and helper_guards eps env = - let* fresh = fresh_var in - RList.fold_left - eps - ~init:(return (Subst.empty, fresh)) - ~f:(fun (s, t) (cond, e) -> - let* s2, t1 = infer cond env in - let* s3, t2 = infer e env in - let* s4 = unify t1 (Ty_prim "Bool") in - let* s5 = unify t t2 in - Subst.compose_all [ s5; s4; s3; s2; s ] >>| fun fs -> fs, Subst.apply s5 t) - -and prep prep_bb decls env1 env2 names = function - | [] -> return (prep_bb, decls, env1, env2, names) - | Decl (Ident name, t) :: tl -> - prep prep_bb ((name, tp_to_ty t) :: decls) env1 env2 names tl - | Def (FunDef (Ident name, _, _, _, _) as d) :: tl -> - let* tv = fresh_var in - let ext env = TypeEnv.extend env (name, S (VarSet.empty, tv)) in - prep ((d, tv) :: prep_bb) decls (ext env1) (ext env2) (name :: names) tl - | Def (VarsDef (p, _, _) as d) :: tl -> - let* _, env1, _ = helper_p p env1 [] in - let* t, env2, new_names = helper_p p env2 [] in - prep - ((d, t) :: prep_bb) - decls - env1 - env2 - (List.fold_left (fun nn n -> n :: nn) names new_names) - tl - -and helper_p (al, pat, type_annots) env names = - (match pat with - | PWildcard -> - let* fresh = fresh_var in - let* _, t = type_annots_hndl type_annots fresh in - return (t, env, names) - | PConst (NegativePInt _) -> - let* _, t = type_annots_hndl type_annots (Ty_prim "Int") in - return (t, env, names) - | PConst (OrdinaryPConst c) -> - let* _, t = - type_annots_hndl - type_annots - (Ty_prim - (match c with - | Int _ -> "Int" - | Bool _ -> "Bool" - | Unit -> "()")) - in - return (t, env, names) - | PIdentificator (Ident name) -> - let* fresh = fresh_var in - let* _, t = type_annots_hndl type_annots fresh in - return (t, TypeEnv.extend env (name, S (VarSet.empty, t)), name :: names) - | PMaybe Nothing -> - let* fresh = fresh_var in - let* _, t = type_annots_hndl type_annots (Ty_maybe fresh) in - return (t, env, names) - | PMaybe (Just pt) -> - let* t, env, names = helper_p pt env names in - let* s, t = type_annots_hndl type_annots (Ty_maybe t) in - return (t, TypeEnv.apply s env, names) - | PList (PCons (x, xs)) -> - let* t1, env1, names1 = helper_p x env names in - let* t2, env2, names2 = helper_p xs env1 names1 in - let* s = unify t2 (Ty_list t1) in - let t = Subst.apply s t2 in - let* s2, t' = type_annots_hndl type_annots t in - let* fs = Subst.compose s2 s in - return (t', TypeEnv.apply fs env2, names2) - | PTuple (p1, p2, pp) -> - let* t1, env1, names1 = helper_p p1 env names in - let* t2, env2, names2 = helper_p p2 env1 names1 in - let* tt, env, names = - RList.fold_left - pp - ~init:(return ([], env2, names2)) - ~f:(fun (tt, env, names) p -> - let* t, env', names = helper_p p env names in - return (t :: tt, env', names)) - in - let* s, t = type_annots_hndl type_annots (Ty_tuple (t1, t2, tt)) in - return (t, TypeEnv.apply s env, names) - | PList (PEnum pp) -> - let* fresh = fresh_var in - let* env, el_t, names = - RList.fold_left - pp - ~init:(return (env, fresh, names)) - ~f:(fun (env, t, names) p -> - let* t', env', names = helper_p p env names in - let* s = unify t t' in - return (TypeEnv.apply s env', Subst.apply s t, names)) - in - let* s, t = type_annots_hndl type_annots (Ty_list el_t) in - return (t, TypeEnv.apply s env, names) - | PTree PNul -> - let* fresh = fresh_var in - let* _, t = type_annots_hndl type_annots (Ty_tree fresh) in - return (t, env, names) - | PTree (PNode (d, l, r)) -> - let* t, env', names' = helper_p d env names >>| fun (t, e, n) -> Ty_tree t, e, n in - let* tl, env'', names'' = helper_p l env' names' in - let* tr, env''', names''' = helper_p r env'' names'' in - let* s1 = unify t tl in - let* s2 = unify (Subst.apply s1 t) tr in - let* s = Subst.compose s2 s1 in - let* _, t = type_annots_hndl type_annots (Subst.apply s t) in - return (t, TypeEnv.apply s env''', names''')) - >>| fun (t, env, names) -> - let env', names = - List.fold_left - (fun (env, names) (Ident name) -> - TypeEnv.extend env (name, S (VarSet.empty, t)), name :: names) - (env, names) - al - in - t, env', names - -and helper_pp pp env = - RList.fold_left - pp - ~init:(return ([], env)) - ~f:(fun (tt, env) p -> - let* t, env', _ = helper_p p env [] in - return (t :: tt, env')) - -and infer (e, type_annots) env = - let helper_list ee t = - RList.fold_left - ee - ~init:(return (Subst.empty, t)) - ~f:(fun (s, t) e -> - let* s2, t2 = infer e env in - let* s3 = unify t t2 in - Subst.compose_all [ s3; s2; s ] >>| fun s -> s, Subst.apply s3 t2) - >>| fun (s, t) -> s, Ty_list t - in - let ty_enum = fresh >>| fun b -> Ty_enum b in - let helper_e expr env = - match expr with - | Const const -> - (match const with - | Int _ -> return (Subst.empty, Ty_prim "Int") - | Bool _ -> return (Subst.empty, Ty_prim "Bool") - | Unit -> return (Subst.empty, Ty_prim "()")) - | Identificator (Ident i) -> lookup_env i env >>| fun t -> Subst.empty, t - | ENothing -> - let* fresh = fresh_var in - return (Subst.empty, Ty_maybe fresh) - | EJust -> - let* fresh = fresh_var in - return (Subst.empty, Ty_arrow (fresh, Ty_maybe fresh)) - | BinTreeBld Nul -> - let* fresh = fresh_var in - return (Subst.empty, Ty_tree fresh) - | BinTreeBld (Node (d, l, r)) -> - let* s1, t = infer d env >>| fun (s, t) -> s, Ty_tree t in - let* s2, t2 = infer l env in - let* s3, t3 = infer r env in - let* s4 = unify t t2 in - let* s = Subst.compose_all [ s4; s3; s2; s1 ] in - let* s5 = unify (Subst.apply s t) t3 in - Subst.compose s5 s >>| fun fs -> fs, Subst.apply s5 t - | ListBld (OrdList (IncomprehensionlList ee)) -> fresh_var >>= helper_list ee - | ListBld (LazyList (e1, Some e2, Some e3)) -> ty_enum >>= helper_list [ e1; e2; e3 ] - | ListBld (LazyList (e1, Some e2, None) | LazyList (e1, None, Some e2)) -> - ty_enum >>= helper_list [ e1; e2 ] - | ListBld (LazyList (e1, None, None)) -> ty_enum >>= helper_list [ e1 ] - | FunctionApply (f, a, aa) -> - (match aa with - | [] -> - let* s1, t1 = infer f env in - let* s2, t2 = infer a (TypeEnv.apply s1 env) in - let* tv = fresh_var in - let* s3 = unify (Subst.apply s2 t1) (Ty_arrow (t2, tv)) in - let trez = Subst.apply s3 tv in - let* final_subst = Subst.compose_all [ s3; s2; s1 ] in - return (final_subst, trez) - | hd :: tl -> - infer (FunctionApply ((FunctionApply (f, a, []), []), hd, tl), []) env) - | IfThenEsle (c, th, el) -> - let* s1, t1 = infer c env in - let* s2, t2 = infer th env in - let* s3, t3 = infer el env in - let* s4 = unify t1 (Ty_prim "Bool") in - let* s5 = unify t2 t3 in - let* final_subst = Subst.compose_all [ s5; s4; s3; s2; s1 ] in - return (final_subst, Subst.apply s5 t2) - | Neg e -> - let* s, t = infer e env in - let* s1 = unify t (Ty_prim "Int") in - let* s2 = Subst.compose s1 s in - return (s2, Subst.apply s1 t) - | TupleBld (e1, e2, ee) -> - let* s1, t1 = infer e1 env in - let* s2, t2 = infer e2 env in - let* ss, tt = - RList.fold_left - ee - ~init:(return ([], [])) - ~f:(fun (ss, tt) e -> infer e env >>| fun (s, t) -> s :: ss, t :: tt) - in - let* final_subst = Subst.compose_all (s1 :: s2 :: ss) in - return (final_subst, Ty_tuple (t1, t2, tt)) - | Binop (e1, op, e2) -> - let* sign = built_in_sign op in - let* s1, t1 = infer e1 env in - let* s2, t2 = infer e2 env in - let* tv = fresh_var in - let* s3 = unify (Ty_arrow (t1, Ty_arrow (t2, tv))) sign in - let* final_subst = Subst.compose_all [ s1; s2; s3 ] in - return (final_subst, Subst.apply s3 tv) - | Lambda (p, pp, e) -> - let* tt, env' = helper_pp (p :: pp) env in - let* s, ty = infer e env' in - let trez = ty_arr (List.map (Subst.apply s) (List.rev tt)) (Subst.apply s ty) in - return (s, trez) - | InnerBindings (b, bb, e) -> - let* s, env, _ = bindings (b :: bb) env in - let* s2, t2 = infer e env in - Subst.compose s2 s >>| fun fs -> fs, t2 - | Case (e, pb, pbs) -> - let* fresh = fresh_var in - let* s1, t1 = - RList.fold_left - (pb :: pbs) - ~init:(return (Subst.empty, fresh)) - ~f:(fun (s, t) (p, b) -> - let* s1, t1 = - match b with - | OrdBody e -> infer (Lambda (p, [], e), []) env - | Guards (ep, eps) -> - let* t, env', _ = helper_p p env [] in - let* s, ty = helper_guards (ep :: eps) env' in - let trez = Ty_arrow (Subst.apply s t, ty) in - return (s, trez) - in - let* s2 = unify t1 t in - Subst.compose_all [ s2; s1; s ] >>| fun fs -> fs, Subst.apply s2 t) - in - let* s2, t2 = infer e (TypeEnv.apply s1 env) in - let* tv = fresh_var in - let* s3 = unify (Subst.apply s2 t1) (Ty_arrow (t2, tv)) in - let trez = Subst.apply s3 tv in - let* final_subst = Subst.compose_all [ s3; s2; s1 ] in - return (final_subst, trez) - (* | ListBld (OrdList (ComprehensionList (e, c, cc))) -> - let* s1, env' = - RList.fold_left - (c :: cc) - ~init:(return (Subst.empty, env)) - ~f:(fun (s, env) cmp -> - let* s1, env = - match cmp with - | Condition x -> - let* s1, t1 = infer x env in - let* s2 = unify t1 (Ty_prim "Bool") in - let* final_subst = Subst.compose s2 s1 in - return (final_subst, env) - | Generator (p, e) -> - let* s2, t2 = infer e env in - let* t3, env', _ = helper_p p env [] in - let* s3 = unify t2 (Ty_list t3) in - let* s = Subst.compose s3 s2 in - return (s, env') - in - Subst.compose s1 s >>| fun fs -> fs, env) - in - let* s2, t2 = infer e (TypeEnv.apply s1 env') in - let* final_subst = Subst.compose s2 s1 in - return (final_subst, Ty_list t2) *) - in - match type_annots with - | [] -> helper_e e env - | type_annots -> - let* fresh = fresh_var in - let* _, t0 = type_annots_hndl type_annots fresh in - helper_e e env - >>= fun (s, t) -> - let* s' = unify t t0 in - Subst.compose s' s >>| fun fs -> fs, Subst.apply s' t - -and type_annots_hndl type_annots init = - RList.fold_left - type_annots - ~init:(return (Subst.empty, init)) - ~f:(fun (s, t) tp -> - unify t (tp_to_ty tp) - >>= fun s' -> Subst.compose s' s >>| fun fs -> fs, Subst.apply s' t) - -and ty_arr tt t = - match tt with - | [] -> t - | hd :: tl -> Ty_arrow (hd, ty_arr tl t) -;; - -let w p env st = - let st, res = run (bindings p env) st in - st, Result.map (fun (_, env, names) -> env, names) res -;; diff --git a/Haskell/lib/inferencer.mli b/Haskell/lib/inferencer.mli deleted file mode 100644 index 4c0936e5f..000000000 --- a/Haskell/lib/inferencer.mli +++ /dev/null @@ -1,19 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Typedtree - -type typeenv - -val typeenv_print_int : typeenv -val initial_env : typeenv -val typeenv_empty : typeenv -val pp_some_typeenv : Format.formatter -> string list * typeenv -> unit - -val w - : binding_list - -> typeenv - -> binder - -> binder * (typeenv * string list, error) Result.t diff --git a/Haskell/lib/interpreter.ml b/Haskell/lib/interpreter.ml deleted file mode 100644 index 578a95a4d..000000000 --- a/Haskell/lib/interpreter.ml +++ /dev/null @@ -1,62 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -let interpret ~dump_parsetree ~print_types = - let init_st = 2 in - let rec helper st names text inf_env eval_env fresh = - match text with - | [] -> - if inf_env != Inferencer.typeenv_empty - && inf_env != Inferencer.initial_env - && print_types - then Format.printf "%a\n%!" Inferencer.pp_some_typeenv (names, inf_env) - | "" :: rest -> helper st names rest inf_env eval_env fresh - | line :: rest -> - if dump_parsetree then Parser.parse_and_print_line line; - (match Parser.parse_line line with - | Result.Ok bnds -> - (match Inferencer.w bnds inf_env st with - | st, Result.Ok (inf_env', nn) -> - let eval_env', fresh' = - match Eval.eval eval_env fresh bnds with - | Result.Ok (eval_env', fresh') -> eval_env', fresh' - | Result.Error (err, (eval_env', fresh')) -> - Format.printf "%a\n%!" Pprint.pp_eval_err err; - eval_env', fresh' - in - helper - st - (List.fold_left (fun nn n -> n :: nn) names nn) - rest - inf_env' - eval_env' - fresh' - | st, Result.Error err -> - Format.printf "%a\n%!" Pprint.pp_error err; - helper st names rest inf_env eval_env fresh) - | Result.Error error -> Format.printf "%s\n%!" error) - in - helper init_st [] -;; - -let interpret_line line inf_env st ~dump_parsetree ~print_types eval_env fresh = - match Parser.parse_line line with - | Result.Ok bnds -> - if dump_parsetree then Parser.parse_and_print_line line; - (match Inferencer.w bnds inf_env st with - | st, Result.Ok (inf_env', names) -> - if print_types - then Format.printf "%a\n%!" Inferencer.pp_some_typeenv (names, inf_env'); - (match Eval.eval eval_env fresh bnds with - | Result.Ok (eval_env', fresh') -> inf_env', st, eval_env', fresh' - | Result.Error (err, (eval_env', fresh')) -> - Format.printf "%a\n%!" Pprint.pp_eval_err err; - inf_env', st, eval_env', fresh') - | st, Result.Error err -> - Format.printf "%a\n%!" Pprint.pp_error err; - inf_env, st, eval_env, fresh) - | Result.Error error -> - Format.printf "%s\n%!" error; - inf_env, st, eval_env, fresh -;; diff --git a/Haskell/lib/interpreter.mli b/Haskell/lib/interpreter.mli deleted file mode 100644 index 1d090a9ff..000000000 --- a/Haskell/lib/interpreter.mli +++ /dev/null @@ -1,22 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -val interpret - : dump_parsetree:bool - -> print_types:bool - -> string list - -> Inferencer.typeenv - -> Eval.env - -> Eval.fresh - -> unit - -val interpret_line - : string - -> Inferencer.typeenv - -> int - -> dump_parsetree:bool - -> print_types:bool - -> Eval.env - -> Eval.fresh - -> Inferencer.typeenv * int * Eval.env * Eval.fresh diff --git a/Haskell/lib/pai.ml b/Haskell/lib/pai.ml deleted file mode 100644 index 6cd2e15a9..000000000 --- a/Haskell/lib/pai.ml +++ /dev/null @@ -1,13 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -let parse_and_infer line = - match Parser.parse_line line with - | Result.Ok bnds -> - (match Inferencer.w bnds Inferencer.initial_env 2 with - | _, Result.Ok (env, names) -> - Format.printf "%a\n%!" Inferencer.pp_some_typeenv (names, env) - | _, Result.Error err -> Format.printf "%a\n%!" Pprint.pp_error err) - | Result.Error error -> Format.printf "%s\n%!" error -;; diff --git a/Haskell/lib/pai.mli b/Haskell/lib/pai.mli deleted file mode 100644 index 0a5fca324..000000000 --- a/Haskell/lib/pai.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -val parse_and_infer : string -> unit diff --git a/Haskell/lib/parser.ml b/Haskell/lib/parser.ml deleted file mode 100644 index 1c0f83610..000000000 --- a/Haskell/lib/parser.ml +++ /dev/null @@ -1,1201 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Angstrom -open Ast - -let ws1 = - many1 - @@ satisfy - @@ function - | ' ' | '\t' -> true - | _ -> false -;; - -let ws = option [] ws1 -let ( >>>= ) p f = ws *> p >>= f -let ( let** ) = ( >>>= ) -let ( <**> ) f p = f <*> ws *> p -let ( **> ) p f = ws *> p *> (ws *> f) - -let parens, sq_brackets, backticks, braces = - let bounded (ch1, ch2) p = char ch1 *> ws *> p <* (ws <* char ch2) in - ( (fun p -> bounded ('(', ')') p) - , (fun p -> bounded ('[', ']') p) - , (fun p -> bounded ('`', '`') p) - , fun p -> bounded ('{', '}') p ) -;; - -let is_alpha = function - | 'a' .. 'z' | 'A' .. 'Z' -> true - | _ -> false -;; - -let is_digit = function - | '0' .. '9' -> true - | _ -> false -;; - -let is_char_suitable_for_ident c = - is_digit c || is_alpha c || Char.equal '_' c || Char.equal '\'' c -;; - -let prs_ln ?(consume = Consume.Prefix) call str = parse_string ~consume call str - -let prs_and_prnt_ln ?(consume = Consume.Prefix) call sh str = - match prs_ln ~consume call str with - | Ok v -> print_endline (sh v) - | Error msg -> Printf.fprintf stderr "error: %s" msg -;; - -type point_handling = - | Allow_point - | Ban_point - -let word ?(point_allowed = Ban_point) req_word = - let open String in - if equal req_word empty - then return empty - else - let* fst_smb = satisfy is_alpha in - let* w = - let suitable_but_not_a_point = take_while is_char_suitable_for_ident in - match point_allowed with - | Ban_point -> suitable_but_not_a_point - | Allow_point -> - sep_by (char '.') suitable_but_not_a_point - >>| - let open String in - concat empty - in - if equal (Printf.sprintf "%c%s" fst_smb w) req_word - then return req_word - else Printf.sprintf "couldn't parse word '%s'" req_word |> fail -;; - -let%test "word_valid" = - parse_string ~consume:Prefix (word "then") "then" = Result.Ok "then" -;; - -let%test "word_invalid" = - parse_string ~consume:Prefix (word "then") "thena" - = Result.Error ": couldn't parse word 'then'" -;; - -let ident = - let keywords = [ "case"; "of"; "if"; "then"; "else"; "let"; "in"; "where" ] in - (let* x = - satisfy (function - | 'a' .. 'z' -> true - | _ -> false) - in - let* y = take_while is_char_suitable_for_ident in - return (Printf.sprintf "%c%s" x y)) - <|> (let* x = satisfy (Char.equal '_') in - let* y = take_while1 is_char_suitable_for_ident in - return (Printf.sprintf "%c%s" x y)) - >>= fun identifier -> - match List.find_opt (String.equal identifier) keywords with - | None -> return (Ident identifier) - | Some k -> fail (Printf.sprintf "keyword '%s' cannot be an identifier" k) -;; - -let%test "ident_valid_starts_with_underline" = - parse_string ~consume:Prefix ident "_123abc" = Result.Ok (Ident "_123abc") -;; - -let%test "ident_invalid" = - parse_string ~consume:Prefix ident "_" = Result.Error ": count_while1" -;; - -let%test "ident_valid_'" = - parse_string ~consume:Prefix ident "x'" = Result.Ok (Ident "x'") -;; - -let%test "ident_invalid_keyword" = - parse_string ~consume:Prefix ident "then" - = Result.Error ": keyword 'then' cannot be an identifier" -;; - -let tuple_or_parensed_item item tuple_cons item_cons = - parens (sep_by1 (ws *> char ',' *> ws) item) - >>= function - | hd :: [] -> item_cons hd - | fs :: sn :: tl -> tuple_cons fs sn tl - | [] -> fail "sep_by1 result can't be empty" -;; - -let is_char_suitable_for_oper = function - | '&' | '|' | '+' | '-' | ':' | '*' | '=' | '^' | '/' | '\\' | '<' | '>' | '.' -> true - | _ -> false -;; - -let oper expected = - let* parsed = - backticks ident - >>| (fun (Ident s) -> - let open String in - concat empty [ "`"; s; "`" ]) - <|> take_while is_char_suitable_for_oper - in - if String.equal expected parsed then return expected else fail "" -;; - -let%expect_test "oper_valid" = - prs_and_prnt_ln (oper "+-+") Fun.id "+-+awq"; - [%expect {| - +-+|}] -;; - -let%expect_test "oper_invalid" = - prs_and_prnt_ln (oper "+-+") Fun.id "+-+>"; - [%expect {| - error: :|}] -;; - -let%expect_test "oper_with_backticks" = - prs_and_prnt_ln (oper "`a`") Fun.id "`a`"; - [%expect {| - `a`|}] -;; - -let func_tp_tail hd ord_tp = - many (oper "->" **> ord_tp) - >>= function - | sn :: tl -> return (FunctionType (FuncT (hd, sn, tl))) - | _ -> fail "" -;; - -let ord_tp tp = - let w = word ~point_allowed:Allow_point in - let ord_tp = - choice - [ string "()" *> return TUnit - ; w "Int" *> return TInt - ; w "Bool" *> return TBool - ; (sq_brackets tp >>| fun x -> ListParam x) - ; (braces tp >>| fun x -> TreeParam x) - ; tuple_or_parensed_item - tp - (fun fs sn tl -> return (TupleParams (fs, sn, tl))) - return - ] - in - ord_tp <|> (w "Maybe" *> ws *> ord_tp >>| fun t -> MaybeParam t) -;; - -let tp = - let t t = ord_tp t >>= fun res -> option res (func_tp_tail res (ord_tp t)) in - fix t -;; - -let%expect_test "tp_list_of_func" = - prs_and_prnt_ln tp show_tp "[Int -> Int] "; - [%expect {| (ListParam (FunctionType (FuncT (TInt, TInt, [])))) |}] -;; - -let%expect_test "tp_maybe" = - prs_and_prnt_ln tp show_tp "Maybe Int "; - [%expect {| (MaybeParam TInt) |}] -;; - -let%expect_test "tp_tree_of_func" = - prs_and_prnt_ln tp show_tp "{Bool -> ()} "; - [%expect {| (TreeParam (FunctionType (FuncT (TBool, TUnit, [])))) |}] -;; - -let%expect_test "tp_lnested_func" = - prs_and_prnt_ln tp show_tp "Int -> ((Int -> Int)) -> Int"; - [%expect - {| - (FunctionType (FuncT (TInt, (FunctionType (FuncT (TInt, TInt, []))), [TInt]))) |}] -;; - -let%expect_test "tp_tuple" = - prs_and_prnt_ln tp show_tp "(Int, Bool, Int -> Bool)"; - [%expect - {| - (TupleParams (TInt, TBool, [(FunctionType (FuncT (TInt, TBool, [])))])) |}] -;; - -let int = - let* y = take_while1 is_digit in - match int_of_string_opt y with - | None -> fail "" - | Some x -> return x -;; - -let const = - choice - [ (let+ x = int in - Int x) - ; string "()" *> return Unit - ; string "True" *> return (Bool true) - ; string "False" *> return (Bool false) - ] -;; - -let%test "const_valid_num" = - parse_string ~consume:Prefix const "123" = Result.Ok (Int 123) -;; - -let%test "const_invalid_num" = - parse_string ~consume:Prefix const "123ab" = Result.Ok (Int 123) -;; - -let%test "const_invalid_num_negative" = - parse_string ~consume:Prefix const "-123" = Result.Error ": no more choices" -;; - -let%test "const_valid_unit" = parse_string ~consume:Prefix const "()" = Result.Ok Unit - -let%test "const_valid_true" = - parse_string ~consume:Prefix const "True" = Result.Ok (Bool true) -;; - -let%test "const_valid_false" = - parse_string ~consume:Prefix const "False" = Result.Ok (Bool false) -;; - -let%test "const_invalid" = - parse_string ~consume:Prefix const "beb" = Result.Error ": no more choices" -;; - -let nothing f = word ~point_allowed:Allow_point "Nothing" *> f -let just f = word ~point_allowed:Allow_point "Just" *> ws *> f -let list_enum item f = sq_brackets (sep_by (ws *> char ',' *> ws) item) >>= f - -let tree item nul_cons node_cons = - char '$' *> nul_cons - <|> (parens (sep_by (ws *> char ';' *> ws) item) - >>= function - | [ it1; it2; it3 ] -> node_cons it1 it2 it3 - | _ -> fail "cannot parse tree") -;; - -let pt_tp ((a, p, tps) as pt) = option pt (oper "::" **> tp >>| fun tp -> a, p, tp :: tps) -let pnegation = oper "-" *> ws *> int >>| fun a -> [], PConst (NegativePInt a), [] -let just_p ptrn = just (ptrn >>| fun p -> [], PMaybe (Just p), []) - -let pcons_tail head ptrn_ext = - let rec loop constr = function - | [] -> constr ([], PList (PEnum []), []) - | hd :: [] -> constr hd - | hd :: tl -> loop (fun y -> constr ([], PList (PCons (hd, y)), [])) tl - in - many1 (oper ":" **> ptrn_ext) - >>| List.rev - >>| loop (fun (x : pattern) -> [], PList (PCons (head, x)), []) -;; - -let pat ptrn = - let ptrn_extended ptrn_extended = - let* p = ptrn <|> pnegation <|> just_p ptrn in - option p (pcons_tail p ptrn_extended) - in - choice - [ (let* pt = const in - return (PConst (OrdinaryPConst pt))) - ; (let* pt = ident in - return (PIdentificator pt)) - ; char '_' *> return PWildcard - ; nothing (return (PMaybe Nothing)) - ; tree - (ws *> fix ptrn_extended >>= pt_tp) - (return (PTree PNul)) - (fun d t1 t2 -> return (PTree (PNode (d, t1, t2)))) - ; list_enum (fix ptrn_extended >>= pt_tp) (fun pts -> return (PList (PEnum pts))) - ] -;; - -let ptrn ptrn = - let ptrn_extended ptrn_extended = - let* p = ptrn <|> pnegation <|> just_p ptrn in - option p (pcons_tail p ptrn_extended) - in - choice - [ (let* ident = ident in - char '@' *> (ptrn >>= fun (idents, pat, tp) -> return (ident :: idents, pat, tp))) - ; (let* pat = pat ptrn in - return ([], pat, [])) - ; tuple_or_parensed_item - (fix ptrn_extended >>= pt_tp) - (fun p1 p2 pp -> return ([], PTuple (p1, p2, pp), [])) - return - ] -;; - -type unparansed_pseudoops_handling = - | Ban_p - | Allow_p - -type unparnsed_tp_handling = - | Ban_t - | Allow_t - -let pattern unp_ps_h unp_tp_h = - let p = fix ptrn in - match unp_ps_h with - | Ban_p -> p - | Allow_p -> - let ptr' ptr' = - p <|> pnegation <|> just_p p >>= fun hd -> option hd (pcons_tail hd ptr') - in - fix ptr' - >>= - (match unp_tp_h with - | Ban_t -> return - | Allow_t -> pt_tp) -;; - -let%test "pattern_valid_as" = - parse_string ~consume:Prefix (pattern Allow_p Allow_t) "adada@( x )" - = Result.Ok ([ Ident "adada" ], PIdentificator (Ident "x"), []) -;; - -let%test "pattern_valid_parens_oth" = - parse_string ~consume:Prefix (pattern Allow_p Allow_t) "( x )" - = Result.Ok ([], PIdentificator (Ident "x"), []) -;; - -let%test "pattern_valid_neg" = - parse_string ~consume:Prefix (pattern Allow_p Allow_t) "-1" - = Result.Ok ([], PConst (NegativePInt 1), []) -;; - -let%test "pattern_invalid_banned_neg" = - parse_string ~consume:Prefix (pattern Ban_p Allow_t) "-1" - = Result.Error ": no more choices" -;; - -let%test "pattern_valid_double_as" = - parse_string ~consume:Prefix (pattern Allow_p Allow_t) "a@b@2" - = Result.Ok ([ Ident "a"; Ident "b" ], PConst (OrdinaryPConst (Int 2)), []) -;; - -let%test "pattern_valid_with_parens" = - parse_string ~consume:Prefix (pattern Allow_p Allow_t) "(a@(b@(2)))" - = Result.Ok ([ Ident "a"; Ident "b" ], PConst (OrdinaryPConst (Int 2)), []) -;; - -let%expect_test "pattern_valid_tuple" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "(x, y,(x,y))"; - [%expect - {| - ([], - (PTuple (([], (PIdentificator (Ident "x")), []), - ([], (PIdentificator (Ident "y")), []), - [([], - (PTuple (([], (PIdentificator (Ident "x")), []), - ([], (PIdentificator (Ident "y")), []), [])), - [])] - )), - []) |}] -;; - -let%expect_test "pattern_valid_tuple_labeled" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "a@(x, e@y,b@(x,y))"; - [%expect - {| - ([(Ident "a")], - (PTuple (([], (PIdentificator (Ident "x")), []), - ([(Ident "e")], (PIdentificator (Ident "y")), []), - [([(Ident "b")], - (PTuple (([], (PIdentificator (Ident "x")), []), - ([], (PIdentificator (Ident "y")), []), [])), - [])] - )), - []) |}] -;; - -let%expect_test "pattern_invalid_tuple_labeled" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "(x, e@y,(x,y)@(x,y))"; - [%expect {| - error: : satisfy: '(' |}] -;; - -let%expect_test "pattern_valid_tree" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "(2; $; $)"; - [%expect - {| - ([], - (PTree - (PNode (([], (PConst (OrdinaryPConst (Int 2))), []), - ([], (PTree PNul), []), ([], (PTree PNul), [])))), - []) |}] -;; - -let%expect_test "pattern_invalid_tree" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "(2; $)"; - [%expect {| - error: : satisfy: '(' |}] -;; - -let%expect_test "pattern_just_valid" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "Just 1"; - [%expect - {| - ([], (PMaybe (Just ([], (PConst (OrdinaryPConst (Int 1))), []))), []) |}] -;; - -let%expect_test "pattern_just_invalid_ban_unparansed" = - prs_and_prnt_ln (pattern Ban_p Allow_t) show_pattern "Just 1"; - [%expect {| - error: : no more choices |}] -;; - -let%expect_test "pattern_just_invalid_neg" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "Just -1"; - [%expect {| - error: : no more choices |}] -;; - -let%expect_test "pattern_nil_valid" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "[]"; - [%expect {| ([], (PList (PEnum [])), []) |}] -;; - -let%expect_test "pattern_enum_valid" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "[1, 2,1 ,1]"; - [%expect - {| - ([], - (PList - (PEnum - [([], (PConst (OrdinaryPConst (Int 1))), []); - ([], (PConst (OrdinaryPConst (Int 2))), []); - ([], (PConst (OrdinaryPConst (Int 1))), []); - ([], (PConst (OrdinaryPConst (Int 1))), [])])), - []) - |}] -;; - -let%expect_test "pattern_listcons_invalid_ban_unparansed" = - prs_and_prnt_ln (pattern Ban_p Allow_t) show_pattern "x:xs"; - [%expect {| - ([], (PIdentificator (Ident "x")), []) |}] -;; - -let%expect_test "pattern_listcons_valid" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "x:(y:z):w"; - [%expect - {| - ([], - (PList - (PCons (([], (PIdentificator (Ident "x")), []), - ([], - (PList - (PCons ( - ([], - (PList - (PCons (([], (PIdentificator (Ident "y")), []), - ([], (PIdentificator (Ident "z")), [])))), - []), - ([], (PIdentificator (Ident "w")), [])))), - []) - ))), - []) |}] -;; - -let%expect_test "pattern_simple_valid_tp" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "x :: Int"; - [%expect {| - ([], (PIdentificator (Ident "x")), [TInt]) - |}] -;; - -let%expect_test "pattern_simple_invalid_tp_ban" = - prs_and_prnt_ln (pattern Allow_p Ban_t) show_pattern "x :: Int"; - [%expect {| - ([], (PIdentificator (Ident "x")), []) - |}] -;; - -let%expect_test "pattern_listcons_valid_with_tp" = - prs_and_prnt_ln (pattern Allow_p Allow_t) show_pattern "x:y:z :: [Int]"; - [%expect - {| - ([], - (PList - (PCons (([], (PIdentificator (Ident "x")), []), - ([], - (PList - (PCons (([], (PIdentificator (Ident "y")), []), - ([], (PIdentificator (Ident "z")), [])))), - []) - ))), - [(ListParam TInt)]) - |}] -;; - -let ex_tp ((e, tps) as ex) = option ex (oper "::" **> tp >>| fun tp -> e, tp :: tps) - -let defbody e sep = - (sep - **> let* ex = e >>= ex_tp in - return (OrdBody ex)) - <|> - let* ee_pairs = - many1 - (oper "|" - **> let* ex1 = e in - sep - **> let* ex2 = e >>= ex_tp in - return (ex1, ex2)) - in - match ee_pairs with - | [] -> fail " many1 result can't be empty" - | hd :: tl -> Guards (hd, tl) |> return -;; - -let bnd e bnd = - (let** ident = ident in - let** pt = pattern Ban_p Ban_t in - let* pts = many (ws *> pattern Ban_p Ban_t) in - return (fun bb where_binds -> Def (FunDef (ident, pt, pts, bb, where_binds)))) - <|> (let** pt = pattern Allow_p Allow_t in - return (fun bb where_binds -> Def (VarsDef (pt, bb, where_binds)))) - <**> defbody e (oper "=") - <**> option [] @@ (word "where" **> sep_by (ws *> char ';' *> ws) bnd) - <|> let** ident = ident in - oper "::" **> tp >>| fun t -> Decl (ident, t) -;; - -let binding e = fix (bnd e) - -type assoc = - | Left - | Right - | Non - -let prios_list = - [ None, [ (Right, oper "||", fun a b -> Binop (a, Or, b), []) ] - ; None, [ (Right, oper "&&", fun a b -> Binop (a, And, b), []) ] - ; ( None - , [ (Non, oper "==", fun a b -> Binop (a, Equality, b), []) - ; (Non, oper "/=", fun a b -> Binop (a, Inequality, b), []) - ; (Non, oper ">=", fun a b -> Binop (a, EqualityOrGreater, b), []) - ; (Non, oper "<=", fun a b -> Binop (a, EqualityOrLess, b), []) - ; (Non, oper ">", fun a b -> Binop (a, Greater, b), []) - ; (Non, oper "<", fun a b -> Binop (a, Less, b), []) - ] ) - ; None, [ (Right, oper ":", fun a b -> Binop (a, Cons, b), []) ] - ; ( Some (oper "-", fun a -> Neg a, []) - , [ (Left, oper "+", fun a b -> Binop (a, Plus, b), []) - ; (Left, oper "-", fun a b -> Binop (a, Minus, b), []) - ] ) - ; ( None - , [ (Left, oper "`div`", fun a b -> Binop (a, Divide, b), []) - ; (Left, oper "*", fun a b -> Binop (a, Multiply, b), []) - ; (Left, oper "`mod`", fun a b -> Binop (a, Mod, b), []) - ] ) - ; None, [ (Right, oper "^", fun a b -> Binop (a, Pow, b), []) ] - ] -;; - -let non_assoc_ops_seq_check l = - List.fold_left - (fun (prev_assoc, error_flag) (ass, _, _) -> - ass, error_flag || (prev_assoc = Non && ass = Non)) - (Left, false) - l - |> snd - |> fun error_flag -> - if error_flag - then fail "cannot mix two non-associative operators in the same infix expression" - else return l -;; - -let op expr prios_list = - let rec loop acc = function - | [] -> acc - | (Right, op, r) :: tl -> op acc (loop r tl) - | ((Left | Non), op, r) :: tl -> loop (op acc r) tl - in - let rec helper = function - | [] -> ws *> expr - | hd :: tl -> - return loop - <**> helper tl - <*> (choice - (List.map - (fun (ass, op, f) -> op **> helper tl >>= fun r -> return (ass, f, r)) - (snd hd)) - |> many - >>= non_assoc_ops_seq_check) - <|> - (match fst hd with - | Some (op, f) -> ws *> (op **> helper tl) >>= fun a -> return (f a) - | _ -> fail "") - in - helper prios_list -;; - -let const_e = - let+ c = const in - Const c, [] -;; - -let ident_e = - let+ i = ident in - Identificator i, [] -;; - -let if_then_else e = - let+ cond = word "if" **> e - and+ th_br = word "then" **> e - and+ el_br = word "else" **> e in - IfThenEsle (cond, th_br, el_br), [] -;; - -let inner_bindings e = - word "let" - **> let+ bnd = binding e - and+ bnds = many @@ (char ';' **> binding e) - and+ ex = word "in" **> e >>= ex_tp in - InnerBindings (bnd, bnds, ex), [] -;; - -let lambda e = - oper "\\" - *> let** pt = pattern Ban_p Ban_t in - let* pts = many (ws *> pattern Ban_p Ban_t) in - let* ex = string "->" **> e in - return (Lambda (pt, pts, ex), []) -;; - -let tree_e e = - tree - e - ((BinTreeBld Nul, []) |> return) - (fun ex1 ex2 ex3 -> return (BinTreeBld (Node (ex1, ex2, ex3)), [])) -;; - -let case e = - word "case" - *> let** ex = e in - word "of" - **> - let* br1, brs = - sep_by1 - (ws *> char ';' *> ws) - (both (pattern Allow_p Ban_t) (defbody e (oper "->"))) - >>= function - | [] -> fail "sep_by1 cant return empty list" - | hd :: tl -> return (hd, tl) - in - return (Case (ex, br1, brs), []) -;; - -let list_e e = - list_enum e (fun l -> return (ListBld (OrdList (IncomprehensionlList l)), [])) - <|> (* let condition = return (fun exp -> Condition exp) <*> e in - let generator = - return (fun (pat, exp) -> Generator (pat, exp)) - <*> both (pattern Allow_p Allow_t <* ws <* oper "<-" <* ws) e - in *) - ((let** ex1 = e in - choice - [ (* [ (oper "|" **> sep_by1 (ws *> char ',' *> ws) (generator <|> condition) - >>= function - | [] -> fail "" - | hd :: tl -> return (OrdList (ComprehensionList (ex1, hd, tl)))) - ; *) - (let option_ex f = option None (f >>| fun x -> Some x) in - both (option_ex (char ',' **> e)) (oper ".." **> option_ex e) - >>| fun (ex2, ex3) -> LazyList (ex1, ex2, ex3)) - ] - >>| fun l -> ListBld l, []) - |> sq_brackets) -;; - -let tuple_or_parensed_item_e e = - tuple_or_parensed_item - e - (fun ex1 ex2 exs -> return (TupleBld (ex1, ex2, exs), [])) - return -;; - -let infix_binop = - let binop_lambda op = - return - (Lambda - ( ([], PIdentificator (Ident "x"), []) - , [ [], PIdentificator (Ident "y"), [] ] - , ( Binop ((Identificator (Ident "x"), []), op, (Identificator (Ident "y"), [])) - , [] ) )) - in - choice - [ parens - (choice - [ oper "||" *> binop_lambda Or - ; oper "&&" *> binop_lambda And - ; oper "==" *> binop_lambda Equality - ; oper "/=" *> binop_lambda Inequality - ; oper ">=" *> binop_lambda EqualityOrGreater - ; oper "<=" *> binop_lambda EqualityOrLess - ; oper ">" *> binop_lambda Greater - ; oper "<" *> binop_lambda Less - ; oper ":" *> binop_lambda Cons - ; oper "-" *> binop_lambda Minus - ; oper "+" *> binop_lambda Plus - ; oper "*" *> binop_lambda Multiply - ; oper "^" *> binop_lambda Multiply - ]) - ; word "div" *> binop_lambda Divide - ; word "mod" *> binop_lambda Mod - ] - >>| fun e -> e, [] -;; - -let other_expr e fa = - let e' = e >>= ex_tp in - choice - [ const_e - ; infix_binop - ; ident_e - ; nothing (return (ENothing, [])) - ; just (return (EJust, [])) - ; if_then_else e' - ; case e' - ; inner_bindings e - ; lambda e' - ; tree_e e' - ; list_e e' - ; tuple_or_parensed_item_e e' - ] - >>= fun ex -> fa ex e <|> return ex -;; - -let oper e fa = op (other_expr e fa) prios_list - -let function_application ex e = - let e' = e >>= ex_tp in - let* r = - many1 - (ws - *> choice - [ const_e - ; infix_binop - ; ident_e - ; just (return (EJust, [])) - ; nothing (return (ENothing, [])) - ; tree_e e' - ; list_e e' - ; tuple_or_parensed_item_e e' - ]) - in - match r with - | [] -> fail "many1 result can't be empty" - | hd :: tl -> (FunctionApply (ex, hd, tl), []) |> return -;; - -let e e = - oper e function_application - <|> other_expr e function_application - >>= fun ex -> function_application ex e <|> return ex -;; - -let expr = function - | Ban_t -> fix e - | Allow_t -> fix e >>= ex_tp -;; - -let%expect_test "infix_binop" = - prs_and_prnt_ln (expr Allow_t) show_expr "(*)"; - [%expect - {| - ((Lambda (([], (PIdentificator (Ident "x")), []), - [([], (PIdentificator (Ident "y")), [])], - ((Binop (((Identificator (Ident "x")), []), Multiply, - ((Identificator (Ident "y")), []))), - []) - )), - []) |}] -;; - -let%expect_test "expr_prio" = - prs_and_prnt_ln (expr Allow_t) show_expr "(1 + 1)*2 > 1"; - [%expect - {| - ((Binop ( - ((Binop ( - ((Binop (((Const (Int 1)), []), Plus, ((Const (Int 1)), []))), []), - Multiply, ((Const (Int 2)), []))), - []), - Greater, ((Const (Int 1)), []))), - []) |}] -;; - -let%expect_test "expr_div_mod" = - prs_and_prnt_ln (expr Allow_t) show_expr "10 `div` 3 `mod` 2"; - [%expect - {| - ((Binop ( - ((Binop (((Const (Int 10)), []), Divide, ((Const (Int 3)), []))), []), - Mod, ((Const (Int 2)), []))), - []) |}] -;; - -let%expect_test "expr_right_assoc" = - prs_and_prnt_ln (expr Allow_t) show_expr "2^3^4"; - [%expect - {| - ((Binop (((Const (Int 2)), []), Pow, - ((Binop (((Const (Int 3)), []), Pow, ((Const (Int 4)), []))), []))), - []) |}] -;; - -let%expect_test "expr_with_Just" = - prs_and_prnt_ln (expr Allow_t) show_expr "Just 2 + 1"; - [%expect - {| - ((Binop (((FunctionApply ((EJust, []), ((Const (Int 2)), []), [])), []), - Plus, ((Const (Int 1)), []))), - []) |}] -;; - -let%expect_test "expr_with_func_apply" = - prs_and_prnt_ln (expr Allow_t) show_expr "f(x) g(2) + 1"; - [%expect - {| - ((Binop ( - ((FunctionApply (((Identificator (Ident "f")), []), - ((Identificator (Ident "x")), []), - [((Identificator (Ident "g")), []); ((Const (Int 2)), [])])), - []), - Plus, ((Const (Int 1)), []))), - []) |}] -;; - -let%expect_test "expr_with_func_apply_strange_but_valid1" = - prs_and_prnt_ln (expr Allow_t) show_expr "f 9a"; - [%expect - {| - ((FunctionApply (((Identificator (Ident "f")), []), ((Const (Int 9)), []), - [((Identificator (Ident "a")), [])])), - []) |}] -;; - -let%expect_test "expr_with_func_apply_strange_but_valid2" = - prs_and_prnt_ln (expr Allow_t) show_expr "f Just(1)"; - [%expect - {| - ((FunctionApply (((Identificator (Ident "f")), []), (EJust, []), - [((Const (Int 1)), [])])), - []) |}] -;; - -let%expect_test "expr_with_non-assoc_op_simple" = - prs_and_prnt_ln (expr Allow_t) show_expr "x == y"; - [%expect - {| - ((Binop (((Identificator (Ident "x")), []), Equality, - ((Identificator (Ident "y")), []))), - []) |}] -;; - -let%expect_test "expr_with_non-assoc_ops_invalid" = - prs_and_prnt_ln (expr Allow_t) show_expr "x == y + 1 >= z"; - [%expect {| - ((Identificator (Ident "x")), []) |}] -;; - -let%expect_test "expr_with_non-assoc_ops_valid" = - prs_and_prnt_ln (expr Allow_t) show_expr "x == y && z == z'"; - [%expect - {| - ((Binop ( - ((Binop (((Identificator (Ident "x")), []), Equality, - ((Identificator (Ident "y")), []))), - []), - And, - ((Binop (((Identificator (Ident "z")), []), Equality, - ((Identificator (Ident "z'")), []))), - []) - )), - []) |}] -;; - -let%expect_test "expr_case_statement" = - prs_and_prnt_ln (expr Allow_t) show_expr "case x of 1 -> 1; _ -> 2 "; - [%expect - {| - ((Case (((Identificator (Ident "x")), []), - (([], (PConst (OrdinaryPConst (Int 1))), []), - (OrdBody ((Const (Int 1)), []))), - [(([], PWildcard, []), (OrdBody ((Const (Int 2)), [])))])), - []) |}] -;; - -let%expect_test "expr_case_statement_with_guards" = - prs_and_prnt_ln - (expr Allow_t) - show_expr - "case x of y | y > 10 -> 1 | otherwise -> 2; _ -> 3 "; - [%expect - {| - ((Case (((Identificator (Ident "x")), []), - (([], (PIdentificator (Ident "y")), []), - (Guards ( - (((Binop (((Identificator (Ident "y")), []), Greater, - ((Const (Int 10)), []))), - []), - ((Const (Int 1)), [])), - [(((Identificator (Ident "otherwise")), []), ((Const (Int 2)), []))] - ))), - [(([], PWildcard, []), (OrdBody ((Const (Int 3)), [])))])), - []) |}] -;; - -let%expect_test "expr_tuple" = - prs_and_prnt_ln (expr Allow_t) show_expr " (x,1 , 2,(x, y))"; - [%expect - {| - ((TupleBld (((Identificator (Ident "x")), []), ((Const (Int 1)), []), - [((Const (Int 2)), []); - ((TupleBld (((Identificator (Ident "x")), []), - ((Identificator (Ident "y")), []), [])), - []) - ] - )), - []) |}] -;; - -let%expect_test "expr_lambda" = - prs_and_prnt_ln (expr Allow_t) show_expr " \\x -> x+1"; - [%expect - {| - ((Lambda (([], (PIdentificator (Ident "x")), []), [], - ((Binop (((Identificator (Ident "x")), []), Plus, ((Const (Int 1)), []))), - []) - )), - []) |}] -;; - -let%expect_test "expr_tree" = - prs_and_prnt_ln (expr Allow_t) show_expr "1 + (2; $; $)"; - [%expect - {| - ((Binop (((Const (Int 1)), []), Plus, - ((BinTreeBld - (Node (((Const (Int 2)), []), ((BinTreeBld Nul), []), - ((BinTreeBld Nul), [])))), - []) - )), - []) |}] -;; - -let%expect_test "expr_plus_neg" = - prs_and_prnt_ln (expr Allow_t) show_expr "1 + -1"; - [%expect {| - ((Const (Int 1)), []) |}] -;; - -let%expect_test "expr_and_neg" = - prs_and_prnt_ln (expr Allow_t) show_expr "1 && -1"; - [%expect - {| - ((Binop (((Const (Int 1)), []), And, ((Neg ((Const (Int 1)), [])), []))), []) |}] -;; - -let%expect_test "expr_tuple_neg" = - prs_and_prnt_ln (expr Allow_t) show_expr "(-1, 1)"; - [%expect - {| - ((TupleBld (((Neg ((Const (Int 1)), [])), []), ((Const (Int 1)), []), [])), - []) |}] -;; - -let%expect_test "expr_lambda_invalid_neg" = - prs_and_prnt_ln (expr Allow_t) show_expr " \\ -1 -> 1"; - [%expect {| - error: : no more choices |}] -;; - -let%expect_test "expr_case_neg" = - prs_and_prnt_ln (expr Allow_t) show_expr "case-1of-1->1"; - [%expect - {| - ((Case (((Neg ((Const (Int 1)), [])), []), - (([], (PConst (NegativePInt 1)), []), (OrdBody ((Const (Int 1)), []))), - [])), - []) |}] -;; - -let%expect_test "expr_list_incomprehensional" = - prs_and_prnt_ln (expr Allow_t) show_expr "[1, f 2, ()]"; - [%expect - {| - ((ListBld - (OrdList - (IncomprehensionlList - [((Const (Int 1)), []); - ((FunctionApply (((Identificator (Ident "f")), []), - ((Const (Int 2)), []), [])), - []); - ((Const Unit), [])]))), - []) |}] -;; - -(* let%expect_test "expr_list_comprehensional_cond" = - prs_and_prnt_ln (expr Allow_t) show_expr "[ x | x > 2]"; - [%expect - {| - ((ListBld - (OrdList - (ComprehensionList (((Identificator (Ident "x")), []), - (Condition - ((Binop (((Identificator (Ident "x")), []), Greater, - ((Const (Int 2)), []))), - [])), - [])))), - []) |}] - ;; - - let%expect_test "expr_list_comprehensional_gen" = - prs_and_prnt_ln (expr Allow_t) show_expr "[ x | x <- [1, 2, 3]]"; - [%expect - {| - ((ListBld - (OrdList - (ComprehensionList (((Identificator (Ident "x")), []), - (Generator - (([], (PIdentificator (Ident "x")), []), - ((ListBld - (OrdList - (IncomprehensionlList - [((Const (Int 1)), []); ((Const (Int 2)), []); - ((Const (Int 3)), [])]))), - []))), - [])))), - []) |}] - ;; *) - -let%expect_test "expr_list_lazy_valid" = - List.iter - (prs_and_prnt_ln (expr Allow_t) show_expr) - [ "[1..]"; "[1, 3 .. 10]"; "[1..10]"; "[1,3..]" ]; - [%expect - {| - ((ListBld (LazyList (((Const (Int 1)), []), None, None))), []) - ((ListBld - (LazyList (((Const (Int 1)), []), (Some ((Const (Int 3)), [])), - (Some ((Const (Int 10)), []))))), - []) - ((ListBld - (LazyList (((Const (Int 1)), []), None, (Some ((Const (Int 10)), []))))), - []) - ((ListBld - (LazyList (((Const (Int 1)), []), (Some ((Const (Int 3)), [])), None))), - []) |}] -;; - -let%expect_test "expr_binop_invlid_tp" = - prs_and_prnt_ln (expr Allow_t) show_expr "1 + 2 :: Int + 3"; - [%expect - {| - ((Binop (((Const (Int 1)), []), Plus, ((Const (Int 2)), []))), [TInt]) |}] -;; - -let%expect_test "expr_valid_tp" = - prs_and_prnt_ln - (expr Allow_t) - show_expr - "if x>(2::Int) :: Bool then 0::Int else 1 :: Int :: () "; - [%expect - {| - ((IfThenEsle ( - ((Binop (((Identificator (Ident "x")), []), Greater, - ((Const (Int 2)), [TInt]))), - [TBool]), - ((Const (Int 0)), [TInt]), ((Const (Int 1)), [TInt]))), - [TUnit]) |}] -;; - -let binding = binding (expr Allow_t) - -let%expect_test "var_binding_simple" = - prs_and_prnt_ln binding show_binding "x = 1"; - [%expect - {| - (Def - (VarsDef (([], (PIdentificator (Ident "x")), []), - (OrdBody ((Const (Int 1)), [])), []))) |}] -;; - -let%expect_test "var_binding_with_where" = - prs_and_prnt_ln binding show_binding "x = y where y = 1; k = 2 "; - [%expect - {| - (Def - (VarsDef (([], (PIdentificator (Ident "x")), []), - (OrdBody ((Identificator (Ident "y")), [])), - [(Def - (VarsDef (([], (PIdentificator (Ident "y")), []), - (OrdBody ((Const (Int 1)), [])), []))); - (Def - (VarsDef (([], (PIdentificator (Ident "k")), []), - (OrdBody ((Const (Int 2)), [])), []))) - ] - ))) |}] -;; - -let%expect_test "fun_binding_simple" = - prs_and_prnt_ln binding show_binding "f x = x + 1"; - [%expect - {| - (Def - (FunDef ((Ident "f"), ([], (PIdentificator (Ident "x")), []), [], - (OrdBody - ((Binop (((Identificator (Ident "x")), []), Plus, - ((Const (Int 1)), []))), - [])), - []))) |}] -;; - -let%expect_test "fun_binding_simple_strange_but_valid1" = - prs_and_prnt_ln binding show_binding "f(x)y = x + y"; - [%expect - {| - (Def - (FunDef ((Ident "f"), ([], (PIdentificator (Ident "x")), []), - [([], (PIdentificator (Ident "y")), [])], - (OrdBody - ((Binop (((Identificator (Ident "x")), []), Plus, - ((Identificator (Ident "y")), []))), - [])), - []))) |}] -;; - -let%expect_test "fun_binding_guards" = - prs_and_prnt_ln binding show_binding "f x |x > 1 = 0 | otherwise = 1"; - [%expect - {| - (Def - (FunDef ((Ident "f"), ([], (PIdentificator (Ident "x")), []), [], - (Guards ( - (((Binop (((Identificator (Ident "x")), []), Greater, - ((Const (Int 1)), []))), - []), - ((Const (Int 0)), [])), - [(((Identificator (Ident "otherwise")), []), ((Const (Int 1)), []))] - )), - []))) |}] -;; - -let%expect_test "decl" = - prs_and_prnt_ln binding show_binding "f :: Int -> Int -> Int"; - [%expect - {| - (Decl ((Ident "f"), (FunctionType (FuncT (TInt, TInt, [TInt]))))) - |}] -;; - -let bindings_list = sep_by1 (ws *> char ';' *> ws) binding - -type bl = binding list [@@deriving show { with_path = false }] - -let parse_and_print_line = prs_and_prnt_ln ~consume:Consume.All bindings_list show_bl -let parse_line str = prs_ln ~consume:Consume.All bindings_list str diff --git a/Haskell/lib/parser.mli b/Haskell/lib/parser.mli deleted file mode 100644 index 659d73ff2..000000000 --- a/Haskell/lib/parser.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -val parse_line : string -> (Ast.binding list, string) Result.t -val parse_and_print_line : string -> unit diff --git a/Haskell/lib/pprint.ml b/Haskell/lib/pprint.ml deleted file mode 100644 index 8acf974f3..000000000 --- a/Haskell/lib/pprint.ml +++ /dev/null @@ -1,50 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Format -open Typedtree - -let pp_ty = - let rec helper fmt = function - | Ty_maybe ty -> fprintf fmt "Maybe %a" helper ty - | Ty_prim s -> pp_print_string fmt s - | Ty_var b -> fprintf fmt "t%d" b - | Ty_arrow (ty1, ty2) -> - (match ty1 with - | Ty_arrow (_, _) -> fprintf fmt "(%a) -> %a" helper ty1 helper ty2 - | _ -> fprintf fmt "%a -> %a" helper ty1 helper ty2) - | Ty_list ty -> fprintf fmt "[%a]" helper ty - | Ty_tuple (ty1, ty2, ty_list) -> - fprintf - fmt - "(%a, %a%a)" - helper - ty1 - helper - ty2 - (pp_print_list (fun fmt ty -> fprintf fmt ", %a" helper ty)) - ty_list - | Ty_tree ty -> fprintf fmt "{%a}" helper ty - | Ty_ord ty -> fprintf fmt "Ord t%d" ty - | Ty_enum ty -> fprintf fmt "Enum t%d" ty - in - helper -;; - -let pp_error ppf : error -> _ = function - | `Occurs_check -> Format.fprintf ppf "Occurs check failed" - | `No_variable s -> Format.fprintf ppf "Undefined variable '%s'" s - | `Unification_failed (l, r) -> - Format.fprintf ppf "unification failed on %a and %a" pp_ty l pp_ty r -;; - -let pp_eval_err ppf err = - Format.fprintf ppf - @@ - match err with - | `Typing_err -> "Runtime typing error" - | `Not_exh -> "Not exhaustive paterns" - | `Div_by_zero -> "Division by zero" - | `Negative_exponent -> "Negative exponent" -;; diff --git a/Haskell/lib/pprint.mli b/Haskell/lib/pprint.mli deleted file mode 100644 index 83820959d..000000000 --- a/Haskell/lib/pprint.mli +++ /dev/null @@ -1,9 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Typedtree - -val pp_ty : Format.formatter -> ty -> unit -val pp_error : Format.formatter -> error -> unit -val pp_eval_err : Format.formatter -> Eval.crit_err -> unit diff --git a/Haskell/lib/pprintast.ml b/Haskell/lib/pprintast.ml deleted file mode 100644 index 4582318e1..000000000 --- a/Haskell/lib/pprintast.ml +++ /dev/null @@ -1,329 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Format - -let pp_list sep pp_item = pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf sep) pp_item - -let pp_brackets fmt list = - fprintf fmt "%s" (String.make (max 0 (List.length list - 1)) '(') -;; - -let pp_const fmt const = - fprintf - fmt - "%s" - (match const with - | Int n -> Int.to_string n - | Bool b -> if b then "True" else "False" - | Unit -> "()") -;; - -let rec pp_functype fmt (FuncT (first, second, list)) = - fprintf fmt "%a" (pp_list " -> " pp_part_of_functype) (first :: second :: list) - -and pp_part_of_functype fmt tp = - fprintf - fmt - (match tp with - | FunctionType _ -> "(%a)" - | _ -> "%a") - pp_tp - tp - -and pp_tp fmt = function - | TUnit -> fprintf fmt "()" - | TInt -> fprintf fmt "Int" - | TBool -> fprintf fmt "Bool" - | MaybeParam tp -> - fprintf - fmt - (match tp with - | MaybeParam _ | FunctionType _ -> "Maybe (%a)" - | _ -> "Maybe %a") - pp_tp - tp - | TreeParam tp -> fprintf fmt "{%a}" pp_tp tp - | ListParam tp -> fprintf fmt "[%a]" pp_tp tp - | TupleParams (first, second, list) -> - fprintf fmt "(%a)" (pp_list ", " pp_tp) (first :: second :: list) - | FunctionType functype -> pp_functype fmt functype -;; - -let pp_binop fmt = function - | And -> fprintf fmt "&&" - | Or -> fprintf fmt "||" - | Plus -> fprintf fmt "+" - | Minus -> fprintf fmt "-" - | Divide -> fprintf fmt "`div`" - | Mod -> fprintf fmt "`mod`" - | Cons -> fprintf fmt ":" - | Multiply -> fprintf fmt "*" - | Equality -> fprintf fmt "==" - | Pow -> fprintf fmt "^" - | Inequality -> fprintf fmt "/=" - | Less -> fprintf fmt "<" - | Greater -> fprintf fmt ">" - | EqualityOrLess -> fprintf fmt "<=" - | EqualityOrGreater -> fprintf fmt ">=" -;; - -let pp_ident fmt (Ident ident) = fprintf fmt "%s" ident - -type paransed_cases = - | Tp_and_some_constrs - | Tp_only - | No_cases - -let rec pp_pattern fmt ((list, pat, tp_list) : pattern) = - fprintf fmt "%a" pp_brackets tp_list; - (match list with - | [] -> () - | _ -> fprintf fmt "%a@" (pp_list "@" pp_ident) list); - fprintf - fmt - (match pat with - | PMaybe (Just _) | PList (PCons _) | PConst (NegativePInt _) -> - (match list with - | [] -> "%a" - | _ -> "(%a)") - | _ -> "%a") - pp_pat - pat; - match tp_list with - | [] -> () - | _ -> fprintf fmt " :: %a" (pp_list ") :: " pp_tp) (List.rev tp_list) - -and pp_pattern_sometimes_parensed cases fmt pattern = - fprintf - fmt - (match cases, pattern with - | ( Tp_and_some_constrs - , ([], (PMaybe (Just _) | PList (PCons _) | PConst (NegativePInt _)), _) ) - | (Tp_and_some_constrs | Tp_only), (_, _, _ :: _) -> "(%a)" - | _ -> "%a") - pp_pattern - pattern - -and pp_pat fmt = function - | PWildcard -> fprintf fmt "_" - | PConst (OrdinaryPConst const) -> pp_const fmt const - | PConst (NegativePInt n) -> fprintf fmt "-%s" (Int.to_string n) - | PIdentificator ident -> pp_ident fmt ident - | PTuple (first, second, list) -> - fprintf fmt "(%a)" (pp_list ", " pp_pattern) (first :: second :: list) - | PMaybe Nothing -> fprintf fmt "Nothing" - | PMaybe (Just pattern) -> - fprintf fmt "Just %a" (pp_pattern_sometimes_parensed Tp_and_some_constrs) pattern - | PTree PNul -> fprintf fmt "$" - | PTree (PNode (node, left_son, right_son)) -> - fprintf fmt "(%a; %a; %a)" pp_pattern node pp_pattern left_son pp_pattern right_son - | PList (PEnum list) -> fprintf fmt "[%a]" (pp_list ", " pp_pattern) list - | PList (PCons (first, second)) -> - fprintf - fmt - (match first with - | [], PList (PCons _), [] -> "(%a) : %a" - | _ -> "%a : %a") - (pp_pattern_sometimes_parensed Tp_only) - first - (pp_pattern_sometimes_parensed Tp_only) - second -;; - -let get_prior = function - | Binop (_, Or, _) -> 2 - | Binop (_, And, _) -> 3 - | Binop - (_, (Equality | Inequality | Less | EqualityOrLess | Greater | EqualityOrGreater), _) - -> 4 - | Binop (_, Cons, _) -> 5 - | Neg _ | Binop (_, (Plus | Minus), _) -> 6 - | Binop (_, (Multiply | Divide | Mod), _) -> 7 - | Binop (_, Pow, _) -> 8 - | _ -> 10 -;; - -let rec pp_comprehension fmt = function - | Condition expr -> pp_expr fmt expr - | Generator (pattern, expr) -> fprintf fmt "%a <- %a" pp_pattern pattern pp_expr expr - -and pp_ordinarylistbld fmt = function - (* | ComprehensionList (expr, comprehension, list) -> - fprintf - fmt - "[%a | %a]" - pp_expr - expr - (pp_list ", " pp_comprehension) - (comprehension :: list) *) - | IncomprehensionlList list -> fprintf fmt "[%a]" (pp_list ", " pp_expr) list - -and pp_listbld fmt = function - | LazyList (first, step, last) -> - fprintf fmt "[%a" pp_expr first; - (match step with - | None -> () - | Some step -> fprintf fmt ", %a" pp_expr step); - fprintf fmt " .. "; - (match last with - | None -> () - | Some last -> pp_expr fmt last); - fprintf fmt "]" - | OrdList ordinarylistbld -> pp_ordinarylistbld fmt ordinarylistbld - -and pp_binding fmt = function - | Def (VarsDef (pattern, bindingbody, list)) -> - pp_pattern fmt pattern; - (match bindingbody with - | Guards _ -> () - | OrdBody _ -> fprintf fmt " = "); - pp_bindingbody fmt bindingbody; - (match list with - | [] -> () - | _ -> fprintf fmt " where %a" (pp_list "; " pp_binding) list) - | Def (FunDef (name, parameter, parameters_list, bindingbody, binding_list)) -> - fprintf - fmt - "%a %a%s" - pp_ident - name - (pp_list " " (pp_pattern_sometimes_parensed Tp_and_some_constrs)) - (parameter :: parameters_list) - (match bindingbody with - | OrdBody _ -> " = " - | _ -> ""); - pp_bindingbody fmt bindingbody; - (match binding_list with - | [] -> () - | _ -> fprintf fmt " where %a" (pp_list "; " pp_binding) binding_list) - | Decl (ident, tp) -> fprintf fmt "%a :: %a" pp_ident ident pp_tp tp - -and pp_condition_branch sep fmt (condition, branch) = - fprintf fmt "%a%s%a" pp_expr_parenced_tp condition sep pp_expr branch - -and pp_bindingbody fmt = function - | Guards (cb, list) -> - fprintf fmt " | %a" (pp_list " | " (pp_condition_branch " = ")) (cb :: list) - | OrdBody expr -> pp_expr fmt expr - -and pp_binary_tree_bld fmt = function - | Nul -> fprintf fmt "$" - | Node (node, left_son, right_son) -> - fprintf fmt "(%a; %a; %a)" pp_expr node pp_expr left_son pp_expr right_son - -and pp_case_branch fmt (case, branch) = - pp_pattern_sometimes_parensed Tp_only fmt case; - match branch with - | OrdBody _ -> fprintf fmt " -> %a" pp_bindingbody branch - | Guards (cb, list) -> - fprintf fmt "| %a" (pp_list " | " (pp_condition_branch " -> ")) (cb :: list) - -and pp_expression fmt expression = - match expression with - | Const const -> pp_const fmt const - | Identificator ident -> pp_ident fmt ident - | TupleBld (first, second, list) -> - fprintf fmt "(%a)" (pp_list ", " pp_expr) (first :: second :: list) - | ENothing -> fprintf fmt "Nothing" - | EJust -> fprintf fmt "Just" - | ListBld listbld -> pp_listbld fmt listbld - | Binop (((expression1, tp1) as first), binop, ((expresion2, tp2) as second)) -> - fprintf - fmt - (match tp1, get_prior expression1 <= get_prior expression, expression1 with - | [], true, _ | [], _, (IfThenEsle _ | Lambda _ | Case _) -> "(%a) %a " - | _ -> "%a %a ") - pp_expr_parenced_tp - first - pp_binop - binop; - fprintf - fmt - (match - tp2, Int.compare (get_prior expresion2) (get_prior expression), expresion2 - with - | [], k, _ when k < 0 -> "(%a)" - | [], 0, Neg _ -> "(%a)" - | _ -> "%a") - pp_expr_parenced_tp - second - | Neg expr -> - fprintf - fmt - (match expr with - | expression1, [] when get_prior expression1 <= get_prior expression -> "- (%a)" - | _ -> "- %a") - pp_expr_parenced_tp - expr - | IfThenEsle (condition, case, else_case) -> - fprintf fmt "if %a then %a else %a" pp_expr condition pp_expr case pp_expr else_case - | FunctionApply (fn, argument, arguments) -> - fprintf - fmt - (match fn with - | Const _, _ - | Identificator _, _ - | TupleBld _, _ - | ENothing, _ - | EJust, _ - | ListBld _, _ - | BinTreeBld _, _ - | _, _ :: _ -> "%a %a" - | _ -> "(%a) %a") - pp_expr_parenced_tp - fn - (pp_list " " pp_expr_apl_arg) - (argument :: arguments) - | Lambda (argument, arguments, body) -> - fprintf - fmt - "\\ %a -> %a" - (pp_list " " (pp_pattern_sometimes_parensed Tp_and_some_constrs)) - (argument :: arguments) - pp_expr - body - | BinTreeBld binary_tree_bld -> pp_binary_tree_bld fmt binary_tree_bld - | Case (expr, cb, list) -> - fprintf fmt "case %a of %a" pp_expr expr (pp_list "; " pp_case_branch) (cb :: list) - | InnerBindings (binding, binding_list, expr) -> - fprintf fmt "let %a" (pp_list "; " pp_binding) (binding :: binding_list); - fprintf fmt " in %a" pp_expr expr - -and pp_expr_parenced_tp fmt ((_, tp) as expr) = - fprintf - fmt - (match tp with - | [] -> "%a" - | _ -> "(%a)") - pp_expr - expr - -and pp_expr_apl_arg fmt expr = - fprintf - fmt - (match expr with - | (Binop _ | Neg _ | FunctionApply _), [] -> "(%a)" - | _ -> "%a") - pp_expr_parenced_tp - expr - -and pp_expr fmt ((expression, tp_list) : expr) = - fprintf - fmt - (match expression, tp_list with - | (IfThenEsle _ | Lambda _ | Case _ | InnerBindings _), [] -> "(%a%a)" - | (IfThenEsle _ | Lambda _ | Case _ | InnerBindings _), _ -> "(%a(%a))" - | _ -> "%a%a") - pp_brackets - tp_list - pp_expression - expression; - match tp_list with - | [] -> () - | _ -> fprintf fmt " :: %a" (pp_list ") :: " pp_tp) (List.rev tp_list) -;; - -let i_const x = Const (Int x), [] diff --git a/Haskell/lib/qcheck.ml b/Haskell/lib/qcheck.ml deleted file mode 100644 index 167365159..000000000 --- a/Haskell/lib/qcheck.ml +++ /dev/null @@ -1,232 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -open Ast -open Format -open Parser - -let rec shrink_tp = - let open QCheck.Iter in - function - | TUnit | TInt | TBool -> empty - | TreeParam tp -> shrink_tp tp >|= fun a' -> TreeParam a' - | ListParam tp -> shrink_tp tp >|= fun a' -> ListParam a' - | MaybeParam tp -> shrink_tp tp >|= fun a' -> MaybeParam a' - | TupleParams (first, second, rest) -> - of_list [ first; second ] - <+> (shrink_tp first >|= fun a' -> TupleParams (a', second, rest)) - <+> (shrink_tp second >|= fun b' -> TupleParams (first, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_tp rest - >|= fun c' -> TupleParams (first, second, c')) - | FunctionType functype -> shrink_functype functype >|= fun a' -> FunctionType a' - -and shrink_functype : functype QCheck.Shrink.t = - let open QCheck.Iter in - function - | FuncT (first, second, rest) -> - shrink_tp first - >|= (fun a' -> FuncT (a', second, rest)) - <+> (shrink_tp second >|= fun b' -> FuncT (first, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_tp rest >|= fun c' -> FuncT (first, second, c')) -;; - -let rec shrink_pat = - let open QCheck.Iter in - function - | PWildcard | PConst _ | PIdentificator _ -> empty - | PList x -> shrink_listpat x >|= fun a' -> PList a' - | PTuple (first, second, rest) -> - shrink_pattern first - >|= (fun a' -> PTuple (a', second, rest)) - <+> (shrink_pattern second >|= fun b' -> PTuple (first, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern rest - >|= fun c' -> PTuple (first, second, c')) - | PMaybe Nothing -> empty - | PMaybe (Just x) -> shrink_pattern x >|= fun a' -> PMaybe (Just a') - | PTree x -> shrink_treepat x >|= fun a' -> PTree a' - -and shrink_pattern : pattern QCheck.Shrink.t = - let open QCheck.Iter in - function - | ident_list, pat, tp_list -> - QCheck.Shrink.list ident_list - >|= (fun a' -> a', pat, tp_list) - <+> (shrink_pat pat >|= fun b' -> ident_list, b', tp_list) - <+> (QCheck.Shrink.list ~shrink:shrink_tp tp_list >|= fun c' -> ident_list, pat, c') - -and shrink_listpat = - let open QCheck.Iter in - function - | PCons (x, y) -> - shrink_pattern x - >|= (fun a' -> PCons (a', y)) - <+> (shrink_pattern y >|= fun b' -> PCons (x, b')) - | PEnum list -> QCheck.Shrink.list ~shrink:shrink_pattern list >|= fun a' -> PEnum a' - -and shrink_treepat = - let open QCheck.Iter in - function - | PNul -> empty - | PNode (x, y, z) -> - shrink_pattern x - >|= (fun a' -> PNode (a', y, z)) - <+> (shrink_pattern y >|= fun b' -> PNode (x, b', z)) - <+> (shrink_pattern z >|= fun c' -> PNode (x, y, c')) -;; - -let rec shrink_expression = - let open QCheck.Iter in - function - | Const _ | Identificator _ | ENothing | EJust -> empty - | TupleBld (x, y, rest) -> - shrink_expr x - >|= (fun a' -> TupleBld (a', y, rest)) - <+> (shrink_expr y >|= fun b' -> TupleBld (x, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_expr rest >|= fun c' -> TupleBld (x, y, c')) - | ListBld x -> shrink_listbld x >|= fun a' -> ListBld a' - | Binop (x, binop, y) -> - shrink_expr x - >|= (fun a' -> Binop (a', binop, y)) - <+> (shrink_expr y >|= fun b' -> Binop (x, binop, b')) - | Neg x -> shrink_expr x >|= fun a' -> Neg a' - | IfThenEsle (x, y, z) -> - shrink_expr x - >|= (fun a' -> IfThenEsle (a', y, z)) - <+> (shrink_expr y >|= fun b' -> IfThenEsle (x, b', z)) - <+> (shrink_expr z >|= fun c' -> IfThenEsle (x, y, c')) - | FunctionApply (x, y, rest) -> - shrink_expr x - >|= (fun a' -> FunctionApply (a', y, rest)) - <+> (shrink_expr y >|= fun b' -> FunctionApply (x, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_expr rest >|= fun c' -> FunctionApply (x, y, c') - ) - | Lambda (x, list, y) -> - shrink_pattern x - >|= (fun a' -> Lambda (a', list, y)) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern list >|= fun b' -> Lambda (x, b', y)) - <+> (shrink_expr y >|= fun c' -> Lambda (x, list, c')) - | BinTreeBld x -> shrink_binary_tree_bld x >|= fun a' -> BinTreeBld a' - | Case (x, (y, z), list) -> - shrink_expr x - >|= (fun a' -> Case (a', (y, z), list)) - <+> (shrink_list (y, z) >|= fun b' -> Case (x, b', list)) - <+> (QCheck.Shrink.list ~shrink:shrink_list list >|= fun c' -> Case (x, (y, z), c')) - | InnerBindings (x, list, y) -> - shrink_binding x - >|= (fun b' -> InnerBindings (b', list, y)) - <+> (QCheck.Shrink.list ~shrink:shrink_binding list - >|= fun c' -> InnerBindings (x, c', y)) - <+> (shrink_expr y >|= fun a' -> InnerBindings (x, list, a')) - -(* and shrink_comprehension = - let open QCheck.Iter in - function - | Condition x -> shrink_expr x >|= fun a' -> Condition a' - | Generator (x, y) -> - shrink_pattern x - >|= (fun a' -> Generator (a', y)) - <+> (shrink_expr y >|= fun b' -> Generator (x, b')) *) - -and shrink_ordinarylistbld = - let open QCheck.Iter in - function - (* | ComprehensionList (x, y, rest) -> - shrink_expr x - >|= (fun a' -> ComprehensionList (a', y, rest)) - <+> (shrink_comprehension y >|= fun b' -> ComprehensionList (x, b', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_comprehension rest - >|= fun c' -> ComprehensionList (x, y, c')) *) - | IncomprehensionlList list -> - QCheck.Shrink.list ~shrink:shrink_expr list >|= fun a' -> IncomprehensionlList a' - -and shrink_listbld = - let open QCheck.Iter in - function - | LazyList (x, None, None) -> shrink_expr x >|= fun a' -> LazyList (a', None, None) - | LazyList (x, Some y, None) -> - shrink_expr x - >|= (fun a' -> LazyList (a', Some y, None)) - <+> (shrink_expr y >|= fun b' -> LazyList (x, Some b', None)) - | LazyList (x, None, Some z) -> - shrink_expr x - >|= (fun a' -> LazyList (a', None, Some z)) - <+> (shrink_expr z >|= fun b' -> LazyList (x, None, Some b')) - | LazyList (x, Some y, Some z) -> - shrink_expr x - >|= (fun a' -> LazyList (a', Some y, Some z)) - <+> (shrink_expr y >|= fun b' -> LazyList (x, Some b', Some z)) - <+> (shrink_expr z >|= fun c' -> LazyList (x, Some y, Some c')) - | OrdList x -> shrink_ordinarylistbld x >|= fun a' -> OrdList a' - -and shrink_binary_tree_bld = - let open QCheck.Iter in - function - | Nul -> empty - | Node (x, y, z) -> - shrink_expr x - >|= (fun a' -> Node (a', y, z)) - <+> (shrink_expr y >|= fun b' -> Node (x, b', z)) - <+> (shrink_expr z >|= fun c' -> Node (x, y, c')) - -and shrink_list (x, y) = - let open QCheck.Iter in - shrink_pattern x >|= (fun a' -> a', y) <+> (shrink_bindingbody y >|= fun b' -> x, b') - -and shrink_expr : expr QCheck.Shrink.t = - let open QCheck.Iter in - function - | expression, tp -> - shrink_expression expression - >|= (fun a' -> a', tp) - <+> (QCheck.Shrink.list ~shrink:shrink_tp tp >|= fun c' -> expression, c') - -and shrink_binding = - let open QCheck.Iter in - function - | Def (VarsDef (x, y, list)) -> - shrink_pattern x - >|= (fun a' -> Def (VarsDef (a', y, list))) - <+> (shrink_bindingbody y >|= fun c' -> Def (VarsDef (x, c', list))) - <+> (QCheck.Shrink.list ~shrink:shrink_binding list - >|= fun b' -> Def (VarsDef (x, y, b'))) - | Def (FunDef (x, y, pattern_list, z, binding_list)) -> - shrink_pattern y - >|= (fun b' -> Def (FunDef (x, b', pattern_list, z, binding_list))) - <+> (QCheck.Shrink.list ~shrink:shrink_pattern pattern_list - >|= fun c' -> Def (FunDef (x, y, c', z, binding_list))) - <+> (QCheck.Shrink.list ~shrink:shrink_binding binding_list - >|= fun d' -> Def (FunDef (x, y, pattern_list, z, d'))) - <+> (shrink_bindingbody z - >|= fun e' -> Def (FunDef (x, y, pattern_list, e', binding_list))) - | Decl (x, y) -> shrink_tp y >|= fun b' -> Decl (x, b') - -and shrink_bindingbody = - let open QCheck.Iter in - function - | Guards (x, rest) -> - shrink_expr_expr x - >|= (fun a' -> Guards (a', rest)) - <+> (QCheck.Shrink.list ~shrink:shrink_expr_expr rest >|= fun b' -> Guards (x, b')) - | OrdBody x -> shrink_expr x >|= fun a' -> OrdBody a' - -and shrink_expr_expr (x, y) = - let open QCheck.Iter in - shrink_expr x >|= (fun a' -> a', y) <+> (shrink_expr y >|= fun b' -> x, b') -;; - -let run n = - QCheck_base_runner.run_tests - [ QCheck.Test.make - ~name:"test" - ~count:n - (QCheck.make - gen_binding - ~print:(asprintf "%a" Pprintast.pp_binding) - ~shrink:shrink_binding) - (fun t -> - match parse_line (asprintf "%a" Pprintast.pp_binding t) with - | Result.Ok [ ast ] -> ast = t - | _ -> false) - ] -;; diff --git a/Haskell/lib/qcheck.mli b/Haskell/lib/qcheck.mli deleted file mode 100644 index e19c85675..000000000 --- a/Haskell/lib/qcheck.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -val run : int -> int diff --git a/Haskell/lib/run_binding.ml b/Haskell/lib/run_binding.ml deleted file mode 100644 index b623984fe..000000000 --- a/Haskell/lib/run_binding.ml +++ /dev/null @@ -1,18 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -let run_tests n = - let _ = Haskell_lib.Qcheck.run n in - () -;; - -let () = - Arg.parse - [ "-seed", Arg.Int QCheck_base_runner.set_seed, " Set seed" - ; "-stop", Arg.Unit (fun _ -> exit 0), " Exit" - ; "-gen", Arg.Int run_tests, " Number of tests" - ] - (fun _ -> assert false) - "help" -;; diff --git a/Haskell/lib/typedtree.ml b/Haskell/lib/typedtree.ml deleted file mode 100644 index 60b53d5d5..000000000 --- a/Haskell/lib/typedtree.ml +++ /dev/null @@ -1,34 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -type binder = int [@@deriving show { with_path = false }] - -module VarSet = struct - include Stdlib.Set.Make (Int) - - let pp ppf s = iter (Format.fprintf ppf "t%d. ") s -end - -type binder_set = VarSet.t [@@deriving show { with_path = false }] - -type ty = - | Ty_prim of string - | Ty_maybe of ty - | Ty_var of binder - | Ty_arrow of ty * ty - | Ty_list of ty - | Ty_tuple of ty * ty * ty list - | Ty_tree of ty - | Ty_ord of binder - | Ty_enum of binder -[@@deriving show { with_path = false }] - -type scheme = S of binder_set * ty [@@deriving show { with_path = false }] - -type error = - [ `Occurs_check - | `No_variable of string - | (* TODO(Kakadu): Unbound variable *) - `Unification_failed of ty * ty - ] diff --git a/Haskell/lib/typedtree.mli b/Haskell/lib/typedtree.mli deleted file mode 100644 index e5538ade0..000000000 --- a/Haskell/lib/typedtree.mli +++ /dev/null @@ -1,39 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -type binder = int [@@deriving show { with_path = false }] - -module VarSet : sig - type t - - val add : int -> t -> t - val empty : t - val fold : (int -> 'a -> 'a) -> t -> 'a -> 'a - val diff : t -> t -> t - val union : t -> t -> t - val pp : Format.formatter -> t -> unit -end - -type binder_set = VarSet.t [@@deriving show { with_path = false }] - -(** hierarchy: https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1270011 *) -type ty = - | Ty_prim of string - | Ty_maybe of ty - | Ty_var of binder - | Ty_arrow of ty * ty - | Ty_list of ty - | Ty_tuple of ty * ty * ty list - | Ty_tree of ty - | Ty_ord of binder (** i.e. [Ord a]; e.g. [(>) :: Ord a -> Ord a -> Bool] *) - | Ty_enum of binder (** i.e. [Enum a]; e.g. [ (\x -> [x..]) :: Enum a -> [Enum a]] *) -[@@deriving show { with_path = false }] - -type scheme = S of binder_set * ty [@@deriving show { with_path = false }] - -type error = - [ `Occurs_check - | `No_variable of string - | `Unification_failed of ty * ty - ] diff --git a/Haskell/tests/dune b/Haskell/tests/dune deleted file mode 100644 index a4fcf042b..000000000 --- a/Haskell/tests/dune +++ /dev/null @@ -1,25 +0,0 @@ -(cram - (applies_to repl) - (deps - ../lib/run_binding.exe - ../bin/REPL.exe - manytests/do_not_type/001.hs - manytests/do_not_type/002if.hs - manytests/do_not_type/003occurs.hs - manytests/do_not_type/004_let_poly.hs - manytests/do_not_type/099.hs - manytests/typed/001fac.hs - manytests/typed/001fac.hs - manytests/typed/002fac.hs - manytests/typed/003fib.hs - manytests/typed/004manyargs.hs - manytests/typed/005fix.hs - manytests/typed/006partial.hs - manytests/typed/006partial2.hs - manytests/typed/006partial3.hs - manytests/typed/007order.hs - manytests/typed/008ascription.hs - manytests/typed/009let_poly.hs - manytests/typed/010sukharev.hs - manytests/typed/015tuples.hs - manytests/typed/016lists.hs)) diff --git a/Haskell/tests/manytests/do_not_type/001.hs b/Haskell/tests/manytests/do_not_type/001.hs deleted file mode 100644 index 081362e28..000000000 --- a/Haskell/tests/manytests/do_not_type/001.hs +++ /dev/null @@ -1 +0,0 @@ -recfac n = if n<=1 then 1 else n * fac (n-1) diff --git a/Haskell/tests/manytests/do_not_type/002if.hs b/Haskell/tests/manytests/do_not_type/002if.hs deleted file mode 100644 index 8bde7f52b..000000000 --- a/Haskell/tests/manytests/do_not_type/002if.hs +++ /dev/null @@ -1 +0,0 @@ -main = if True then 1 else False \ No newline at end of file diff --git a/Haskell/tests/manytests/do_not_type/003occurs.hs b/Haskell/tests/manytests/do_not_type/003occurs.hs deleted file mode 100644 index 080bf93c1..000000000 --- a/Haskell/tests/manytests/do_not_type/003occurs.hs +++ /dev/null @@ -1 +0,0 @@ -fix f = (\x -> f (\f -> x x f)) (\x -> f (\f -> x x f)) diff --git a/Haskell/tests/manytests/do_not_type/004_let_poly.hs b/Haskell/tests/manytests/do_not_type/004_let_poly.hs deleted file mode 100644 index ad1602238..000000000 --- a/Haskell/tests/manytests/do_not_type/004_let_poly.hs +++ /dev/null @@ -1 +0,0 @@ -temp = (\f -> (f 1, f True)) (\x -> x) \ No newline at end of file diff --git a/Haskell/tests/manytests/do_not_type/099.hs b/Haskell/tests/manytests/do_not_type/099.hs deleted file mode 100644 index 3aa086217..000000000 --- a/Haskell/tests/manytests/do_not_type/099.hs +++ /dev/null @@ -1,3 +0,0 @@ -Just x = Just 1 -Just a = (<) -() = (\x -> x) \ No newline at end of file diff --git a/Haskell/tests/manytests/typed/001fac.hs b/Haskell/tests/manytests/typed/001fac.hs deleted file mode 100644 index 681896d3f..000000000 --- a/Haskell/tests/manytests/typed/001fac.hs +++ /dev/null @@ -1,2 +0,0 @@ -fac n = if n<=1 then 1 else n * fac (n-1) -main = print_int (fac 4) \ No newline at end of file diff --git a/Haskell/tests/manytests/typed/002fac.hs b/Haskell/tests/manytests/typed/002fac.hs deleted file mode 100644 index 303a9a3d5..000000000 --- a/Haskell/tests/manytests/typed/002fac.hs +++ /dev/null @@ -1,3 +0,0 @@ -fac_cps n k = if n==1 then k 1 else fac_cps (n-1) (\p -> k (p*n)) - -main = print_int (fac_cps 4 (\ print_int -> print_int)) \ No newline at end of file diff --git a/Haskell/tests/manytests/typed/003fib.hs b/Haskell/tests/manytests/typed/003fib.hs deleted file mode 100644 index a5140b848..000000000 --- a/Haskell/tests/manytests/typed/003fib.hs +++ /dev/null @@ -1,5 +0,0 @@ -fib_acc a b n = if n==1 then b else let n1 = n-1 in let ab = a+b in fib_acc b ab n1 - -fib n = if n<2 then n else fib (n - 1) + fib (n - 2) - -main = seq (print_int (fib_acc 0 1 4)) (seq (print_int (fib 4)) 0) \ No newline at end of file diff --git a/Haskell/tests/manytests/typed/004manyargs.hs b/Haskell/tests/manytests/typed/004manyargs.hs deleted file mode 100644 index 0730d4159..000000000 --- a/Haskell/tests/manytests/typed/004manyargs.hs +++ /dev/null @@ -1,7 +0,0 @@ -wrap f = if 1 == 1 then f else f - -test3 a b c = seq (print_int a) (seq (print_int b) (seq (print_int c) 0)) - -test10 a b c d e f g h i j = a + b + c + d + e + f + g + h + i + j - -main = let rez = (wrap test10 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000) in seq (print_int rez) (let temp2 = wrap test3 1 10 100 in 0) \ No newline at end of file diff --git a/Haskell/tests/manytests/typed/005fix.hs b/Haskell/tests/manytests/typed/005fix.hs deleted file mode 100644 index 481dfabd6..000000000 --- a/Haskell/tests/manytests/typed/005fix.hs +++ /dev/null @@ -1,5 +0,0 @@ -fix f x = f (fix f) x - -fac self n = if n<=1 then 1 else n * self (n-1) - -main = seq (print_int (fix fac 6)) 0 diff --git a/Haskell/tests/manytests/typed/006partial.hs b/Haskell/tests/manytests/typed/006partial.hs deleted file mode 100644 index da9038dc9..000000000 --- a/Haskell/tests/manytests/typed/006partial.hs +++ /dev/null @@ -1,5 +0,0 @@ -foo b = if b then (\foo -> foo+2) else (\foo -> foo*10) - -foo2 x = foo True (foo False (foo True (foo False x))) - -main = seq (print_int (foo2 11)) 0 diff --git a/Haskell/tests/manytests/typed/006partial2.hs b/Haskell/tests/manytests/typed/006partial2.hs deleted file mode 100644 index fcd5a4396..000000000 --- a/Haskell/tests/manytests/typed/006partial2.hs +++ /dev/null @@ -1,3 +0,0 @@ -foo a b c = seq (print_int a) (seq (print_int b) (seq (print_int c) (a + b * c))) - -main = let foo2 = foo 1 in let foo = foo2 2 in let foo2 = foo 3 in (seq (print_int foo2) 0) diff --git a/Haskell/tests/manytests/typed/006partial3.hs b/Haskell/tests/manytests/typed/006partial3.hs deleted file mode 100644 index b1e05be69..000000000 --- a/Haskell/tests/manytests/typed/006partial3.hs +++ /dev/null @@ -1,3 +0,0 @@ -foo a = seq (print_int a) (\b -> seq (print_int b) (\c -> print_int c)) - -main = foo 4 8 9 diff --git a/Haskell/tests/manytests/typed/007order.hs b/Haskell/tests/manytests/typed/007order.hs deleted file mode 100644 index a5050d26e..000000000 --- a/Haskell/tests/manytests/typed/007order.hs +++ /dev/null @@ -1,4 +0,0 @@ -_start () () a () b _c () d __ = seq (print_int (a+b)) (seq (print_int __) (a*b `div` _c + d)) - - -main = print_int (_start (print_int 1) (print_int 2) 3 (print_int 4) 100 1000 (print_int (-1)) 10000 (-555555)) diff --git a/Haskell/tests/manytests/typed/008ascription.hs b/Haskell/tests/manytests/typed/008ascription.hs deleted file mode 100644 index 980908da9..000000000 --- a/Haskell/tests/manytests/typed/008ascription.hs +++ /dev/null @@ -1,3 +0,0 @@ -addi = \f g x -> (f x (g x:: Bool) :: Int) - -main = seq (print_int (addi (\x b -> if b then x+1 else x*2) (\ _start -> _start `div` 2 == 0) 4)) 0 diff --git a/Haskell/tests/manytests/typed/009let_poly.hs b/Haskell/tests/manytests/typed/009let_poly.hs deleted file mode 100644 index df0bbd4e9..000000000 --- a/Haskell/tests/manytests/typed/009let_poly.hs +++ /dev/null @@ -1 +0,0 @@ -temp = let f = \x -> x in (f 1, f True) diff --git a/Haskell/tests/manytests/typed/010sukharev.hs b/Haskell/tests/manytests/typed/010sukharev.hs deleted file mode 100644 index c8736a6e0..000000000 --- a/Haskell/tests/manytests/typed/010sukharev.hs +++ /dev/null @@ -1,14 +0,0 @@ -_1 = \x y (a, _) -> (x + y - a) == 1 -_2 = let (x, Just f) = (1, Just ( ( + ) 4 )) in f x - -_3 = Just (1, True) - -_4 = let (a, _, _) = (1, 2, 3) in a - -int_of_option (Just x) = x -int_of_option Nothing = 0 - -_5 = let f x = f 5 in f - -_42 42 = True -_42 _ = False diff --git a/Haskell/tests/manytests/typed/015tuples.hs b/Haskell/tests/manytests/typed/015tuples.hs deleted file mode 100644 index 8ef62a6f2..000000000 --- a/Haskell/tests/manytests/typed/015tuples.hs +++ /dev/null @@ -1,8 +0,0 @@ -fix f x = f (fix f) x -map f p = let (a,b) = p in (f a, f b) -fixpoly l = fix (\self l -> map (\li x -> li (self l) x) l) l -feven p n = let (e, o) = p in if n == 0 then 1 else o (n - 1) -fodd p n = let (e, o) = p in if n == 0 then 0 else e (n - 1) -tie = fixpoly (feven, fodd) -meven n = if n == 0 then 1 else modd (n - 1); modd n = if n == 0 then 1 else meven (n - 1) -main = seq (print_int (modd 1)) (seq (print_int (meven 2)) (let (even,odd) = tie in seq (print_int (odd 3)) (seq (print_int (even 4)) 0))) diff --git a/Haskell/tests/manytests/typed/016lists.hs b/Haskell/tests/manytests/typed/016lists.hs deleted file mode 100644 index ed711862a..000000000 --- a/Haskell/tests/manytests/typed/016lists.hs +++ /dev/null @@ -1,15 +0,0 @@ -length xs = case xs of [] -> 0; h:tl -> 1 + length tl - -length_tail = let helper acc xs = case xs of [] -> acc; h:tl -> helper (acc + 1) tl in helper 0 - -map f xs = case xs of [] -> []; a:[] -> [f a]; a:b:[] -> [f a, f b]; a:b:c:[] -> [f a, f b, f c]; a:b:c:d:tl -> f a : f b : f c : f d : map f tl - -append xs ys = case xs of [] -> ys; x:xs -> x:(append xs ys) - -concat = let helper xs = case xs of [] -> []; h:tl -> append h (helper tl) in helper - -iter f xs = case xs of [] -> (); h:tl -> seq (f h) (iter f tl) - -cartesian xs ys = case xs of [] -> []; h:tl -> append (map (\a -> (h,a)) ys) (cartesian tl ys) - -main = seq (iter print_int [1,2,3]) (seq (print_int (length (cartesian [1,2] [1,2,3,4]))) 0) diff --git a/Haskell/tests/repl.t b/Haskell/tests/repl.t deleted file mode 100644 index 94da77d0c..000000000 --- a/Haskell/tests/repl.t +++ /dev/null @@ -1,520 +0,0 @@ -Copyright 2024, Kostya Oreshin and Nikita Shchutskii -SPDX-License-Identifier: MIT - $ ../lib/run_binding.exe -seed 67 -gen 3 -stop - random seed: 67 - ================================================================================ - success (ran 1 tests) - - $ ../bin/REPL.exe manytests/do_not_type/001.hs -ptypes - Undefined variable 'fac' - - $ ../bin/REPL.exe manytests/do_not_type/002if.hs -ptypes - unification failed on Int and Bool - - $ ../bin/REPL.exe manytests/do_not_type/003occurs.hs -ptypes - Occurs check failed - - $ ../bin/REPL.exe manytests/do_not_type/004_let_poly.hs -ptypes - unification failed on Int and Bool - - $ ../bin/REPL.exe manytests/do_not_type/099.hs -ptypes - unification failed on Maybe t7 and Ord t10 -> Ord t10 -> Bool - unification failed on () and t12 -> t12 - [ - x: Int - ] - - $ ../bin/REPL.exe manytests/typed/001fac.hs - 24 - $ ../bin/REPL.exe manytests/typed/002fac.hs - 24 - - $ ../bin/REPL.exe manytests/typed/003fib.hs - 3 - 3 - - $ ../bin/REPL.exe manytests/typed/004manyargs.hs - 1111111111 - - $ ../bin/REPL.exe manytests/typed/005fix.hs - 720 - - $ ../bin/REPL.exe manytests/typed/006partial.hs - 1122 - - $ ../bin/REPL.exe manytests/typed/006partial2.hs - 1 - 2 - 3 - 7 - - $ ../bin/REPL.exe manytests/typed/006partial3.hs - 4 - 8 - 9 - - $ ../bin/REPL.exe manytests/typed/007order.hs - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - - $ ../bin/REPL.exe manytests/typed/008ascription.hs - 8 - - $ ../bin/REPL.exe manytests/typed/009let_poly.hs -ptypes - [ - temp: (Int, Bool) - ] - - - $ ../bin/REPL.exe manytests/typed/010sukharev.hs -ptypes - [ - _1: t7. Int -> Int -> (Int, t7) -> Bool - _2: Int - _3: Maybe (Int, Bool) - _4: Int - _42: t49. t49 -> Bool - _5: t46. Int -> t46 - int_of_option: t40. Maybe t40 -> Int - ] - - $ ../bin/REPL.exe manytests/typed/016lists.hs - 1 - 2 - 3 - 8 - - - $ ../bin/REPL.exe manytests/typed/015tuples.hs - 1 - 1 - 1 - 1 - - $ ../bin/REPL.exe <<-EOF - > fac0 self n = if n<2 then n else n * self (n-1) - > fix f = f (fix f) - > fac = fix fac0 - > main = print_int (fac 3) - > EOF - 6 - -# fibonacci - $ ../bin/REPL.exe <<-EOF - > iter f xs = case xs of [] -> (); h:tl -> seq (f h) (iter f tl) - > take n xs = case xs of [] -> []; h:tl -> if n>0 then h : (take (n-1) tl) else [] - > tail xs = case xs of h:tl -> tl - > zip_with f xs ys = case (xs,ys) of ([],[]) -> []; (h:tl, h2:tl2) -> (f h h2) : zip_with f tl tl2 - > fib = 0:1:(zip_with (+) fib (tail fib)) - > main = seq (iter print_int (take 10 fib)) 0 - > EOF - 0 - 1 - 1 - 2 - 3 - 5 - 8 - 13 - 21 - 34 - -# sieve of Eratosthenes - $ ../bin/REPL.exe <<-EOF - > filter p (x:xs) | p x = x : (filter p xs) | True = filter p xs - > primes = sieve [2..] where sieve (x:xs) = x : sieve (filter (\\n -> n \`mod\` x /= 0) xs) - > iter f xs = case xs of [] -> (); h:tl -> seq (f h) (iter f tl) - > take n xs = case xs of [] -> []; h:tl -> if n > 0 then h : (take (n - 1) tl) else [] - > main = seq (iter print_int (take 10 primes)) 0 - > EOF - 2 - 3 - 5 - 7 - 11 - 13 - 17 - 19 - 23 - 29 - -# TODO(Kakadu): It would be great to call read GHCi somewhere in the tests -# rep min value in tree - $ ../bin/REPL.exe <<-EOF - > tree_example = (3; (4; (7; $; $); (11; $; $)); (0; (23; $; $); (1; $; $))) - > min x y = if x > y then y else x - > iter f $ = (); iter f (v;l;r) = seq (f v) (seq (iter f l) (iter f r)) - > repmin t = r where (r, m) = repmin1 t m; repmin1 $ m = ($, 9999999); repmin1 (v; l; r) m = let (lt, lm) = repmin1 l m; (rt, rm) = repmin1 r m in ((m; lt; rt), min v (min lm rm)) - > new_tree = repmin tree_example - > main = seq (iter print_int tree_example) (iter print_int new_tree) - > EOF - 3 - 4 - 7 - 11 - 0 - 23 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - -# 2+2 - $ ../bin/REPL.exe <<-EOF - > fac x (y,z) = x + y + z - > main = print_int (fac 6 (8 , 9)) - > EOF - 23 -] - -#func - $ ../bin/REPL.exe <<-EOF - > f x Nothing = 0; f z (Just y) = z ^ y - > main = print_int (f 2 (Just 10)) - > EOF - 1024 - -#func_reord - $ ../bin/REPL.exe <<-EOF - > f z (Just y) = z ^ y ; f x Nothing = 0 - > main = print_int (f 2 (Just 10)) - > EOF - 1024 - -# link to link - $ ../bin/REPL.exe <<-EOF - > f x = x + 2 - > g n = f n - > main = print_int (f 2) - > EOF - 4 - - -# unused var -- not evaled - $ ../bin/REPL.exe <<-EOF - > (x,y) = (seq (print_int 0) 5, seq (print_int 1) 6) - > main = print_int x - > EOF - 0 - 5 - -# not_exh -- ignored - $ ../bin/REPL.exe <<-EOF - > (x,Nothing) = (1, Just 2) - > main = print_int 0 - > EOF - 0 - -# not_exh - $ ../bin/REPL.exe <<-EOF - > (x,Nothing) = (1, Just 2) - > main = print_int x - > EOF - Not exhaustive paterns - - -# eval_once - $ ../bin/REPL.exe <<-EOF - > x = seq (print_int 0) 88 - > f y = y + y - > main = print_int (f x) - > EOF - 0 - 176 - -# eval_once (subpattern) - $ ../bin/REPL.exe <<-EOF - > a@(_, y) = (12, seq (print_int 0) 88) - > main = let (_,z) = a in print_int (y+z) - > EOF - 0 - 176 - -# link to part - $ ../bin/REPL.exe <<-EOF - > a = ( 0, (seq (print_int 0) 2, seq (print_int 1) 3)) - > (_, (_, p)) = a - > main = print_int p - > EOF - 1 - 3 - -# pat_match with val - $ ../bin/REPL.exe <<-EOF - > a = ((+) 5 6, 2) - > (1, x) = a - > main = print_int x - > EOF - Not exhaustive paterns - -#guards and where - $ ../bin/REPL.exe <<-EOF - > f x | x < y = x + y | x > y = x - y where y = x * (x \`mod\` 3) - > main = print_int (f 2) - > EOF - 6 - -#guards not exh - $ ../bin/REPL.exe <<-EOF - > f x | x < y = x + y | x > y = x - y where y = x * (x \`mod\` 3) - > main = print_int (f 1) - > EOF - Not exhaustive paterns - -#div by zero - $ ../bin/REPL.exe <<-EOF - > f x = 2 \`div\` x - > y = 1 - 1 - > main = print_int (f y) - > EOF - Division by zero - -#negative exponent - $ ../bin/REPL.exe <<-EOF - > main = print_int (5 ^ (-1)) - > EOF - Negative exponent - -# eval_once pattern_match - $ ../bin/REPL.exe <<-EOF - > x = seq (print_int 0) 88 - > f 12 = 0; f 88 = 1; f 100 = 2 - > main = print_int (f x) - > EOF - 0 - 1 - -# eval_once pattern_match - $ ../bin/REPL.exe <<-EOF - > x = seq (print_int 0) 88 - > f 12 = 0; f 88 = 1; f 100 = 2 - > main = print_int (f x) - > EOF - 0 - 1 - -# eval_once pattern_match (case) - $ ../bin/REPL.exe <<-EOF - > x = seq (print_int 0) 88 - > main = print_int (case x of 12 -> 0; z | z < 88 -> 2 | z >= 88 -> 1) - > EOF - 0 - 1 - -# class ord - $ ../bin/REPL.exe <<-EOF - > bool_to_int True = 1; bool_to_int False = 0 - > x@(_, (2, _)) = (1, (2,3)) - > a = (1, (3, 0)) > x - > b = (0; $; $) <= (0; (-1; $;$); $) - > c = [1..12] < 1:2:3:5:[] - > d = Just (1, Nothing) < Just (1, Just $) - > main = print_int (x) where x = bool_to_int (a && b && c && d) - > EOF - 1 - -# class ord eval only necessary - $ ../bin/REPL.exe <<-EOF - > bool_to_int True = 1; bool_to_int False = 0 - > a = Just (seq (print_int 10) 1) > Nothing - > b = [(seq (print_int 11) 1), (seq (print_int 12) 1), (seq (print_int 13) 1) ] < 1:((seq (print_int 14) [2,3])) - > main = print_int (x) where x = bool_to_int (a && b) - > EOF - 11 - 14 - 12 - 1 - - -# eval_once list - $ ../bin/REPL.exe <<-EOF - > lst = [(seq (print_int 0 ) 18), (seq (print_int 1 ) 19) ] - > x:xs = lst - > main = let y:ys = lst in seq (print_int x) (print_int y) - > EOF - 0 - 18 - 18 - - -# lazy lists - $ ../bin/REPL.exe <<-EOF - > (1:[], [True], x:y:tl) = ([1, 3 .. 2 ], [True .. ], [5, 3 .. ]) - > ([], z:_) = ([5, 1 .. 6], tl) - > False:False:False:False:False:False:_ = [False, False .. True] - > main = print_int (x + y + z ) - > EOF - 9 - - $ ../bin/REPL.exe <<-EOF - > main = let [x, y, z] = [1 .. 4 ] in print_int x - > EOF - Not exhaustive paterns - -# imho tests written below are less interesting - -# eval_full trees, tuples, etc - $ ../bin/REPL.exe <<-EOF - > tr@(x; $; _) = (5; $; $) - > tup@(True, Just y, q, z:[], _) = (True, Just 9, 2, ():[], 0 \`mod\` 0 ) - > main = seq tr tup - > EOF - Division by zero - -# eval_full trees, tuples, etc (expr) - $ ../bin/REPL.exe <<-EOF - > main = seq ((0, 0, 0 )) (seq ((Nothing;$;$)) (Just (9 ^ (-1))) ) - > EOF - Negative exponent - -# not_exh Nul - - $ ../bin/REPL.exe <<-EOF - > x = (0; $; $) - > z@$ = x - > main = z - > EOF - Not exhaustive paterns - -# pm Nothing - $ ../bin/REPL.exe <<-EOF - > f _ = Nothing - > z = f 0 - > main = print_int (case z of Nothing -> 0 ) - > EOF - 0 - -# pm consts, node - $ ../bin/REPL.exe <<-EOF - > ((x,y); $; $) = (((), True); $ ; $) - > i = 1 - 2 - > ((), True, z@(-1), -1) = (x, y, i, -1) - > main = print_int z - > EOF - -1 - -# not_exh bool - $ ../bin/REPL.exe <<-EOF - > z@False = True - > main = z - > EOF - Not exhaustive paterns - -# not_exh NegativePInt - $ ../bin/REPL.exe <<-EOF - > z@(-1) = 0 - > main = z - > EOF - Not exhaustive paterns - -# pm lists - $ ../bin/REPL.exe <<-EOF - > a@[_,_] = [0, 1] - > [b,_] = [1,2] - > d@[c, _] = a - > e:f:xs = 1:[2,3] - > main = print_int (b + c + e + f) - > EOF - 4 - -# not exh cons - $ ../bin/REPL.exe <<-EOF - > x:y = [] - > main = x - > EOF - Not exhaustive paterns - -# not exh just - $ ../bin/REPL.exe <<-EOF - > y = (\\ _ -> Nothing) 0 - > Just x = y - > main = x - > EOF - Not exhaustive paterns - -# pm with values - $ ../bin/REPL.exe <<-EOF - > a = Just 5 - > c = (Nothing; $;$) - > d = [() .. ] - > ( Just y, (Nothing;$;_), _:_) = let x = ( a, c, d ) in seq x x - > main = print_int y - > EOF - 5 - -# pm (patpat_match) - $ ../bin/REPL.exe <<-EOF - > a@($, $, Nothing, Nothing, 1, 1, -1) = ($, $, Nothing, Nothing, 1, 1, -1) - > ($, b@$, Nothing, c@Nothing, 1, d@1, e@(-1)) = a - > main = print_int (d + e) - > EOF - 0 - -# class ord err - $ ../bin/REPL.exe <<-EOF - > x = 5 > (if 0 \`div\` 0 == 0 then 1 else 1 ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - - $ ../bin/REPL.exe <<-EOF - > x = Nothing > (if 0 \`div\` 0 == 0 then Nothing else Nothing ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - - $ ../bin/REPL.exe <<-EOF - > x = $ > (if 0 \`div\` 0 == 0 then $ else $ ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - - $ ../bin/REPL.exe <<-EOF - > x = [] > (if 0 \`div\` 0 == 0 then [] else [] ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - - $ ../bin/REPL.exe <<-EOF - > x = ((\\ _ -> [] ) 0 ) > (if 0 \`div\` 0 == 0 then [] else [] ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - - $ ../bin/REPL.exe <<-EOF - > x = [1..] > 1 : (if 0 \`div\` 0 == 0 then [] else [] ) - > main = print_int (if x then 0 else 1) - > EOF - Division by zero - -# class ord - $ ../bin/REPL.exe <<-EOF - > not True = False; not False = True - > a = let x@[-5, _] = [-5, 0] in x /= [0,0] && not (x /= x) && seq x (x == x) - > b = let x@(Nothing, _) = (Nothing, 0) in x <= (Just x, 0) || seq x (x > (Just x, 0)) && (Just x, 0) > (Nothing, 0) - > c = let x@($, _) = ($, 0) in x /= ( (x;$;$), 0) || seq x (x >= ((x;$;$), 0)) && ((x;$;$), 0) > ($, 0) - > d = let x@([], _) = ([], 0) in x == ( [1,2], 0) || seq x (x < ([1,2], 0)) || ([1,2], 0) < ([], 0) - > e = let x@([], _) = ([], 0) in x == ( 1:[], 0) || seq x (x < (1:[], 0)) || (1:[], 0) == ([], 0) - > f = let y:ys = [1..] in let x@([], _) = ([], 0) in x == ( ys , 0) || seq x (x < (ys, 0)) && ([],0) < (ys, 0) - > main = case a && b && c && d && e && f of True -> print_int 0 - > EOF - 0 - - $ ../bin/REPL.exe <<-EOF - > a = let x = Just 3 in let y@(Nothing, _) = (Nothing, 0) in x /= Just 2 && x > Nothing || (x,0) > y || seq y (y /= (x,0)) - > b = let x = (2;$;$) in let y@($, _) = ($, 0) in x /= (1;$;$) && x > $ || (x,0) > y || seq y (y /= (x,0)) - > c = let x = [2] in let y@([], _) = ([], 0) in x /= [1] && x > [] || (x,0) > y || seq y (y /= (x,0)) - > d = let x = [2..] in let y@([], _) = ([], 0) in x /= [1] && x > [] || (x,0) > y || seq y (y /= (x,0)) - > e = let x = 1:[] in let y@([], _) = ([], 0) in x /= [1] && x > [] || (x,0) > y || seq y (y /= (x,0)) - > main = case a && b && c && d && e of True -> print_int 0 - > EOF - 0 - diff --git a/Haskell/tests/tests/dune b/Haskell/tests/tests/dune deleted file mode 100644 index 08eea4f79..000000000 --- a/Haskell/tests/tests/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name haskell_lib_test) - (public_name Haskell.Lib.Test) - (libraries haskell_lib) - (inline_tests) - (modules Pprintast_test Inferencer_test) - (preprocess - (pps ppx_inline_test ppx_expect))) diff --git a/Haskell/tests/tests/inferencer_test.ml b/Haskell/tests/tests/inferencer_test.ml deleted file mode 100644 index bc81ed389..000000000 --- a/Haskell/tests/tests/inferencer_test.ml +++ /dev/null @@ -1,1006 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -let%expect_test "min function with if" = - Haskell_lib.Pai.parse_and_infer "min x y = if x < y then x else y"; - [%expect {| - [ - min: t5. Ord t5 -> Ord t5 -> Ord t5 - ] |}] -;; - -let%expect_test "int type" = - Haskell_lib.Pai.parse_and_infer "a = 42"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "bool type" = - Haskell_lib.Pai.parse_and_infer "a = True"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "unit type" = - Haskell_lib.Pai.parse_and_infer "a = ()"; - [%expect {| - [ - a: () - ] |}] -;; - -let%expect_test "const with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = 42 :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "const with explicit correct multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (42 :: Int) :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "const with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = 42 :: Bool"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "const with explicit wrong multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (42 :: Int) :: Bool"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "tuple" = - Haskell_lib.Pai.parse_and_infer "a = (42, True)"; - [%expect {| - [ - a: (Int, Bool) - ] |}] -;; - -let%expect_test "tuple with extra types" = - Haskell_lib.Pai.parse_and_infer "a = (42, True, ())"; - [%expect {| - [ - a: (Int, Bool, ()) - ] |}] -;; - -let%expect_test "tuple with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = (42, True, ()) :: (Int, Bool, ())"; - [%expect {| - [ - a: (Int, Bool, ()) - ] |}] -;; - -let%expect_test "tuple with explicit correct multiple type" = - Haskell_lib.Pai.parse_and_infer - "a = ((42, True, ()) :: (Int, Bool, ())) :: (Int, Bool, ())"; - [%expect {| - [ - a: (Int, Bool, ()) - ] |}] -;; - -let%expect_test "tuple with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "x = (42, True, ()) :: (Bool, Bool, ())"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "tuple with explicit wrong multiple type" = - Haskell_lib.Pai.parse_and_infer - "x = ((42, True, ()) :: (Int, Bool, ())) :: (Bool, Bool, ())"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "maybe type just" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> Just x"; - [%expect {| - [ - a: t4. t4 -> Maybe t4 - ] |}] -;; - -let%expect_test "maybe type just int" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> Just (x + 1)"; - [%expect {| - [ - a: Int -> Maybe Int - ] |}] -;; - -let%expect_test "maybe type just list" = - Haskell_lib.Pai.parse_and_infer "a = \\x y -> Just (y : x)"; - [%expect {| - [ - a: t7. [t7] -> t7 -> Maybe [t7] - ] |}] -;; - -let%expect_test "maybe type nothing" = - Haskell_lib.Pai.parse_and_infer "a = Nothing"; - [%expect {| - [ - a: t4. Maybe t4 - ] |}] -;; - -let%expect_test "correct ariphmetic operation" = - Haskell_lib.Pai.parse_and_infer "a = 5 + 3"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "incorrect ariphmetic operation" = - Haskell_lib.Pai.parse_and_infer "a = 5 + ()"; - [%expect {| unification failed on () and Int |}] -;; - -let%expect_test "ariphmetic operation with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = (5 + 3) :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "ariphmetic operation with explicit correct multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((5 + 3) :: Int) :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "ariphmetic operation with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = (5 + 3) :: Bool"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "ariphmetic operation with explicit wrong multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((5 + 3) :: Int) :: Bool"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "correct logical operation" = - Haskell_lib.Pai.parse_and_infer "a = True && False"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "incorrect logical operation" = - Haskell_lib.Pai.parse_and_infer "a = True && 1"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "logical operation with correct explicit single type" = - Haskell_lib.Pai.parse_and_infer "a = True && False :: Bool"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "logical operation with correct explicit multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (True && False :: Bool) :: Bool"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "logical operation with incorrect explicit single type" = - Haskell_lib.Pai.parse_and_infer "a = True && False :: Int"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "logical operation with incorrect explicit multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (True && False :: Bool) :: Int"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "correct comparison operation with int" = - Haskell_lib.Pai.parse_and_infer "a = 1 <= 2"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "correct comparison operation with bool" = - Haskell_lib.Pai.parse_and_infer "a = False <= True"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "incorrect comparison operation with () and int" = - Haskell_lib.Pai.parse_and_infer "a = 1 <= ()"; - [%expect {| unification failed on () and Int |}] -;; - -let%expect_test "incorrect comparison operation with bool and int" = - Haskell_lib.Pai.parse_and_infer "a = 1 <= True"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "comparison operation with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = (1 <= 2) :: Bool"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "comparison operation with explicit correct multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((1 <= 2) :: Bool) :: Bool"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "comparison operation with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = (1 <= 2) :: Int"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "comparison operation with explicit wrong multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((1 <= 2) :: Int) :: Bool"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "cons correct with int" = - Haskell_lib.Pai.parse_and_infer "a = 1 : []"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "cons correct with bool" = - Haskell_lib.Pai.parse_and_infer "a = True : []"; - [%expect {| - [ - a: [Bool] - ] |}] -;; - -let%expect_test "cons incorrect with int" = - Haskell_lib.Pai.parse_and_infer "a = 1 : 2"; - [%expect {| unification failed on Int and [Int] |}] -;; - -let%expect_test "cons incorrect with bool" = - Haskell_lib.Pai.parse_and_infer "a = True : False"; - [%expect {| unification failed on Bool and [Bool] |}] -;; - -let%expect_test "cons incorrect with int and bool" = - Haskell_lib.Pai.parse_and_infer "a = 1 : [True]"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "neg type correct" = - Haskell_lib.Pai.parse_and_infer "a = -42"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "neg type incorrect" = - Haskell_lib.Pai.parse_and_infer "a = -True"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "neg type with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = -42 :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "neg type with explicit correct multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (-42 :: Int) :: Int"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "neg type with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = -42 :: Bool"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "neg type with explicit wrong multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (-42 :: Int) :: Bool"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "ord polymor" = - Haskell_lib.Pai.parse_and_infer "a = (\\f -> let g = (f True) in (f 3)) (\\x -> x)"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "if correct with int return type" = - Haskell_lib.Pai.parse_and_infer "a = if True then 1 else -1"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "if correct with tuple return type" = - Haskell_lib.Pai.parse_and_infer "a = if True then (True, 2) else (False, -1)"; - [%expect {| - [ - a: (Bool, Int) - ] |}] -;; - -let%expect_test "if incorrect with int condition" = - Haskell_lib.Pai.parse_and_infer "a = if (1 + 2) then (True, 2) else (False, -1)"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "if incorrect with tuple condition" = - Haskell_lib.Pai.parse_and_infer "a = if (True, ()) then (True, 2) else (False, -1)"; - [%expect {| unification failed on (Bool, ()) and Bool |}] -;; - -let%expect_test "if incorrect with int and bool return types" = - Haskell_lib.Pai.parse_and_infer "a = if True then 1 else False"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "if incorrect with int and tuple return types" = - Haskell_lib.Pai.parse_and_infer "a = if True then 1 else (1, False)"; - [%expect {| unification failed on Int and (Int, Bool) |}] -;; - -let%expect_test "if incorrect with bool and list return types" = - Haskell_lib.Pai.parse_and_infer "a = if True then True else [1, 4]"; - [%expect {| unification failed on Bool and [Int] |}] -;; - -let%expect_test "lambda ident" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> x"; - [%expect {| - [ - a: t4. t4 -> t4 - ] |}] -;; - -let%expect_test "lambda int return type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> 1"; - [%expect {| - [ - a: t4. t4 -> Int - ] |}] -;; - -let%expect_test "lambda narrowing to int type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> x + 1"; - [%expect {| - [ - a: Int -> Int - ] |}] -;; - -let%expect_test "lambda tuple return type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> (x, ())"; - [%expect {| - [ - a: t4. t4 -> (t4, ()) - ] |}] -;; - -let%expect_test "lambda multiple arguments" = - Haskell_lib.Pai.parse_and_infer "a = \\x y z -> x + y + z"; - [%expect {| - [ - a: Int -> Int -> Int -> Int - ] |}] -;; - -let%expect_test "lambda narrowing to list type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> 1 : x"; - [%expect {| - [ - a: [Int] -> [Int] - ] |}] -;; - -let%expect_test "lambda narrowing to arrow type" = - Haskell_lib.Pai.parse_and_infer "a = \\f -> \\y -> f y"; - [%expect {| - [ - a: t5. t6. (t5 -> t6) -> t5 -> t6 - ] |}] -;; - -let%expect_test "lambda occurs check" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> x x"; - [%expect {| Occurs check failed |}] -;; - -let%expect_test "lambda tuple return type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> x `mod` 2 == 0 && x > 5"; - [%expect {| - [ - a: Int -> Bool - ] |}] -;; - -let%expect_test "lambda correct with explicit single type" = - Haskell_lib.Pai.parse_and_infer "a = (\\x -> 1) :: (Int -> Int)"; - [%expect {| - [ - a: Int -> Int - ] |}] -;; - -let%expect_test "lambda correct with explicit multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((\\x -> 1) :: (Bool -> Int)) :: (Bool -> Int)"; - [%expect {| - [ - a: Bool -> Int - ] |}] -;; - -let%expect_test "lambda wrong with explicit single type" = - Haskell_lib.Pai.parse_and_infer "a = (\\x -> ()) :: (() -> Bool)"; - [%expect {| unification failed on () and Bool |}] -;; - -let%expect_test "lambda wrong with explicit multiple type" = - Haskell_lib.Pai.parse_and_infer "a = ((\\x -> ()) :: (() -> ())) :: (() -> [Int])"; - [%expect {| unification failed on [Int] and () |}] -;; - -let%expect_test "let id" = - Haskell_lib.Pai.parse_and_infer "a = let x = x in x"; - [%expect {| - [ - a: t5. t5 - ] |}] -;; - -let%expect_test "let narrowing to int" = - Haskell_lib.Pai.parse_and_infer "a = let x = x; y = 1 in x + y"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "let narrowing to [int]" = - Haskell_lib.Pai.parse_and_infer "a = let x = x; y = 1 in y : x"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "let narrowing to bool" = - Haskell_lib.Pai.parse_and_infer "a = let x = x; y = True in y && x"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "let function" = - Haskell_lib.Pai.parse_and_infer "a = let compose f g x = f (g x) in compose"; - [%expect - {| - [ - a: t10. t11. t12. (t11 -> t12) -> (t10 -> t11) -> t10 -> t12 - ] |}] -;; - -let%expect_test "let recursive fib" = - Haskell_lib.Pai.parse_and_infer - "a = let fib n = if (n == 0) then 0 else if (n==1) then 1 else ((fib (n-1)) + (fib \ - (n-2))) in fib"; - [%expect {| - [ - a: Int -> Int - ] |}] -;; - -let%expect_test "let recursive fac" = - Haskell_lib.Pai.parse_and_infer - "a = let factorial = \\n -> if n == 0 then 1 else n * factorial (n - 1) in factorial"; - [%expect {| - [ - a: Int -> Int - ] |}] -;; - -let%expect_test "let with explicit correct single type" = - Haskell_lib.Pai.parse_and_infer "a = let (x :: Int) = x in x"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "let with explicit correct mutliple type" = - Haskell_lib.Pai.parse_and_infer "a = let ((x :: Int) :: Int) = x in x"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "let with explicit wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = let (x :: Bool) = 1 in x"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "let with explicit wrong mutliple type" = - Haskell_lib.Pai.parse_and_infer "a = let ((x :: Int) :: Bool) = x in x"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "let wrong unification" = - Haskell_lib.Pai.parse_and_infer "a = let x = if x <= True then 1 else 0 in x + 1"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "let wrong unification" = - Haskell_lib.Pai.parse_and_infer "a = let x = if x <= True then True else False in x"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "let wrong unification" = - Haskell_lib.Pai.parse_and_infer "a = let x = if x <= True then True else False in x"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "case correct with int type" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> case x of 1 -> True; 2 -> False"; - [%expect {| - [ - a: Int -> Bool - ] |}] -;; - -let%expect_test "case correct with lists" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> case x of (x:xs) -> x; [] -> []"; - [%expect {| - [ - a: t9. [[t9]] -> [t9] - ] |}] -;; - -let%expect_test "case correct with int lists and explicit similar types" = - Haskell_lib.Pai.parse_and_infer - "a = \\x -> case x of ((x :: [Int]):(xs :: [[Int]])) -> x; [] -> []"; - [%expect {| - [ - a: [[Int]] -> [Int] - ] |}] -;; - -let%expect_test "case incorrect with int lists and explicit different types" = - Haskell_lib.Pai.parse_and_infer - "a = \\x -> case x of ((x :: [Int]):(xs :: [[Bool]])) -> x; [] -> []"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "function apply incorrect" = - Haskell_lib.Pai.parse_and_infer "a = (\\x -> x + 1) True"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "function apply list return type" = - Haskell_lib.Pai.parse_and_infer "a = (\\x -> x : []) True"; - [%expect {| - [ - a: [Bool] - ] |}] -;; - -let%expect_test "function apply with correct single type" = - Haskell_lib.Pai.parse_and_infer "a = (\\(x :: Int) -> x <= 2) 1"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "function apply return correct multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (\\((x :: Int) :: Int) -> x <= 2) 1"; - [%expect {| - [ - a: Bool - ] |}] -;; - -let%expect_test "function apply return wrong single type" = - Haskell_lib.Pai.parse_and_infer "a = (\\(x :: Bool) -> x <= 2) 1"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "function apply return wrong multiple type" = - Haskell_lib.Pai.parse_and_infer "a = (\\((x :: Int) :: Bool) -> x <= 2) 1"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "function apply return correct single type" = - Haskell_lib.Pai.parse_and_infer "a = (\\(x :: Int) -> x : []) 1"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "list int" = - Haskell_lib.Pai.parse_and_infer "a = [1, 2]"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "lazy list int" = - Haskell_lib.Pai.parse_and_infer "a = [1..]"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "lazy list wrong type" = - Haskell_lib.Pai.parse_and_infer "a = [(True, 1)..]"; - [%expect {| unification failed on Enum t4 and (Bool, Int) |}] -;; - -let%expect_test "list of list" = - Haskell_lib.Pai.parse_and_infer "a = [[True]]"; - [%expect {| - [ - a: [[Bool]] - ] |}] -;; - -let%expect_test "wrong list of different types" = - Haskell_lib.Pai.parse_and_infer "a = [True, (), 3]"; - [%expect {| unification failed on Bool and () |}] -;; - -(* let%expect_test "comprehension list with generator" = - Haskell_lib.Pai.parse_and_infer "a = [x * y | x <- [1..10], y <- [1]]"; - [%expect {| - [ - a: [Int] - ] |}] - ;; - - let%expect_test "comprehension list with simple condition" = - Haskell_lib.Pai.parse_and_infer "a = [1 * 2 | True]"; - [%expect {| - [ - a: [Int] - ] |}] - ;; - - let%expect_test "comprehension list with condition" = - Haskell_lib.Pai.parse_and_infer "a = \\x -> [ x | x < 10 ]"; - [%expect {| - [ - a: Int -> [Int] - ] |}] - ;; - - let%expect_test "comprehension list with condition and generator" = - Haskell_lib.Pai.parse_and_infer "a = \\y -> [ x * y | x <- [1..10], y <= 10 ]"; - [%expect {| - [ - a: Int -> [Int] - ] |}] - ;; - - let%expect_test "wrong comprehension list with generator condition" = - Haskell_lib.Pai.parse_and_infer "a = \\x y -> [ x * y | x < 10, y <- [True, False]]"; - [%expect {| unification failed on Bool and Int |}] - ;; - - let%expect_test "several functions" = - Haskell_lib.Pai.parse_and_infer "f x = g x; g y = y"; - [%expect {| -[ -f: t4. t4 -> t4 -g: t4. t4 -> t4 - ] |}] - ;; *) - -let%expect_test "several bindings non_poly" = - Haskell_lib.Pai.parse_and_infer "f x = x; g = f True"; - [%expect {| -[ -f: Bool -> Bool -g: Bool - ] |}] -;; - -let%expect_test "mutually recursive functions" = - Haskell_lib.Pai.parse_and_infer "f x = g x; g y = f y"; - [%expect {| - [ - f: t4. t5. t4 -> t5 - g: t4. t5. t4 -> t5 - ] |}] -;; - -let%expect_test "mutually recursive functions with guards" = - Haskell_lib.Pai.parse_and_infer - "isEven n | n == 0 = True | n > 0 = isOdd (n - 1) | True = isOdd (-n); isOdd n | n \ - == 0 = False | n > 0 = isEven (n - 1) | True = isEven (-n)"; - [%expect {| - [ - isEven: Int -> Bool - isOdd: Int -> Bool - ] |}] -;; - -let%expect_test "guards" = - Haskell_lib.Pai.parse_and_infer "f x | x > 0 = x | True = -1"; - [%expect {| - [ - f: Int -> Int - ] |}] -;; - -let%expect_test "where single statement" = - Haskell_lib.Pai.parse_and_infer "f x = x + y where y = 1"; - [%expect {| - [ - f: Int -> Int - ] |}] -;; - -let%expect_test "where single statement with explicit incorrect type" = - Haskell_lib.Pai.parse_and_infer "f x = x + y where (y :: Bool) = 1"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "where multiple statements" = - Haskell_lib.Pai.parse_and_infer "f x = x && y || z where y = False; z = True"; - [%expect {| - [ - f: Bool -> Bool - ] |}] -;; - -let%expect_test "where single statement incorrect" = - Haskell_lib.Pai.parse_and_infer "f x = x + y where y = True"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "where single statement with param shadowing incorrect" = - Haskell_lib.Pai.parse_and_infer "f x y = x + y where y = True"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "where multiple statements incorrect" = - Haskell_lib.Pai.parse_and_infer "f x = x && y || z where y = False; z = 3"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "where polymorphic argument" = - Haskell_lib.Pai.parse_and_infer "f x = y where y = False"; - [%expect {| - [ - f: t3. t3 -> Bool - ] |}] -;; - -let%expect_test "where list argument" = - Haskell_lib.Pai.parse_and_infer "f (x:xs) = y : xs where y = 2"; - [%expect {| - [ - f: [Int] -> [Int] - ] |}] -;; - -let%expect_test "function with tuple argument" = - Haskell_lib.Pai.parse_and_infer "f (x, y) = (x + 1, y && True)"; - [%expect {| - [ - f: (Int, Bool) -> (Int, Bool) - ] |}] -;; - -let%expect_test "several functions with incorrect type" = - Haskell_lib.Pai.parse_and_infer "f x = x + 1; g = f y where y = False"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "correct arrow declaration" = - Haskell_lib.Pai.parse_and_infer "f :: Int -> Int; f x = x"; - [%expect {| - [ - f: Int -> Int - ] |}] -;; - -let%expect_test "incorrect arrow declaration" = - Haskell_lib.Pai.parse_and_infer "f :: Int; f x = x"; - [%expect {| unification failed on Int and t3 -> t3 |}] -;; - -let%expect_test "incorrect arrow declaration with different types" = - Haskell_lib.Pai.parse_and_infer "f :: Int -> Bool; f x = x"; - [%expect {| - unification failed on Bool and Int |}] -;; - -let%expect_test "incorrect list declaration with different types" = - Haskell_lib.Pai.parse_and_infer "a :: [Int]; a = [False, True]"; - [%expect {| - unification failed on Int and Bool |}] -;; - -let%expect_test "correct declaration with explicit type" = - Haskell_lib.Pai.parse_and_infer "a :: [Int]; (a :: [Int]) = [1, 2]"; - [%expect {| - [ - a: [Int] - ] |}] -;; - -let%expect_test "incorrect declaration with explicit type" = - Haskell_lib.Pai.parse_and_infer "f :: Bool -> Bool; f (x :: Int) = x"; - [%expect {| - unification failed on Bool and Int |}] -;; - -let%expect_test "correct tuple declaration" = - Haskell_lib.Pai.parse_and_infer "a :: (Int, Bool, ()); a = (1, True, ())"; - [%expect {| - [ - a: (Int, Bool, ()) - ] |}] -;; - -let%expect_test "incorrect tuple declaration" = - Haskell_lib.Pai.parse_and_infer "a :: (Int, Bool, ()); a = (False, True, ())"; - [%expect {| - unification failed on Int and Bool |}] -;; - -let%expect_test "failed unification" = - Haskell_lib.Pai.parse_and_infer "a = let f = (\\id -> (id 1, id True)) (\\x -> x) in f"; - [%expect {| unification failed on Int and Bool |}] -;; - -let%expect_test "generalization" = - Haskell_lib.Pai.parse_and_infer - "a = let f = \\x -> let const = \\y -> x in const x in f"; - [%expect {| - [ - a: t12. t12 -> t12 - ] |}] -;; - -let%expect_test "compatible restrictions" = - Haskell_lib.Pai.parse_and_infer - "a = let double f z = f (f z) in (double (\\x -> x+1) 1, double (\\x -> x && x) \ - False)"; - [%expect {| - [ - a: (Int, Bool) - ] |}] -;; - -let%expect_test "y-combinator" = - Haskell_lib.Pai.parse_and_infer "a = let fix f = f (fix f) in fix"; - [%expect {| - [ - a: t8. (t8 -> t8) -> t8 - ] |}] -;; - -let%expect_test "z-combinator without recursion" = - Haskell_lib.Pai.parse_and_infer "a = let fix f eta = f (fix f) eta in fix"; - [%expect - {| - [ - a: t10. t11. ((t10 -> t11) -> t10 -> t11) -> t10 -> t11 - ] |}] -;; - -let%expect_test "occurs check" = - Haskell_lib.Pai.parse_and_infer "a = let f x = f in f"; - [%expect {| Occurs check failed |}] -;; - -let%expect_test "let poly" = - Haskell_lib.Pai.parse_and_infer "a = let f = (\\x -> x) in let g = (f True) in f 3"; - [%expect {| - [ - a: Int - ] |}] -;; - -let%expect_test "fail unification" = - Haskell_lib.Pai.parse_and_infer "a = (\\f -> let g = (f True) in (f 3)) (\\x -> x)"; - [%expect {| unification failed on Bool and Int |}] -;; - -let%expect_test "unif with ord, succ" = - Haskell_lib.Pai.parse_and_infer "f x = x > (1,2); g y = y < Just True "; - [%expect {| - [ - f: (Int, Int) -> Bool - g: Maybe Bool -> Bool - ] |}] -;; - -let%expect_test "unif with ord, fail (tuple)" = - Haskell_lib.Pai.parse_and_infer "f x = x > (1, \\ x -> x) "; - [%expect {| - unification failed on Ord t8 and t5 -> t5 |}] -;; - -let%expect_test "unif with ord, fail" = - Haskell_lib.Pai.parse_and_infer "f x = x > [\\ x -> x] "; - [%expect {| - unification failed on Ord t8 and t6 -> t6 |}] -;; - -let%expect_test "tree param valid" = - Haskell_lib.Pai.parse_and_infer " f (x; (1; $;$); $) = x "; - [%expect {| - [ - f: {Int} -> Int - ] |}] -;; - -let%expect_test "tree param invalid" = - Haskell_lib.Pai.parse_and_infer " f (x; (True; $;$); $) = x - x "; - [%expect {| - unification failed on Bool and Int |}] -;; - -let%expect_test "tree expr valid" = - Haskell_lib.Pai.parse_and_infer " f x = (x; (1; $;$); $) "; - [%expect {| - [ - f: Int -> {Int} - ] |}] -;; - -let%expect_test "tree param invalid" = - Haskell_lib.Pai.parse_and_infer " f x = ((x; (True; $;$); $), x - x) "; - [%expect {| - unification failed on Bool and Int |}] -;; diff --git a/Haskell/tests/tests/inferencer_test.mli b/Haskell/tests/tests/inferencer_test.mli deleted file mode 100644 index e06ef3aab..000000000 --- a/Haskell/tests/tests/inferencer_test.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) diff --git a/Haskell/tests/tests/pprintast_test.ml b/Haskell/tests/tests/pprintast_test.ml deleted file mode 100644 index 8e126e171..000000000 --- a/Haskell/tests/tests/pprintast_test.ml +++ /dev/null @@ -1,377 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) - -let%test "pp Int" = Format.asprintf "%a" Haskell_lib.Pprintast.pp_const (Int 18) = "18" - -let%test "pp const Bool" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_const (Bool true) = "True" -;; - -let%test "pp const Unit" = Format.asprintf "%a" Haskell_lib.Pprintast.pp_const Unit = "()" - -let%test "pp functype" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_functype - (FuncT (TInt, TBool, [ TBool; TUnit ])) - = "Int -> Bool -> Bool -> ()" -;; - -let%test "pp tp TUnit" = Format.asprintf "%a" Haskell_lib.Pprintast.pp_tp TUnit = "()" -let%test "pp tp TInt" = Format.asprintf "%a" Haskell_lib.Pprintast.pp_tp TInt = "Int" -let%test "pp tp TBool" = Format.asprintf "%a" Haskell_lib.Pprintast.pp_tp TBool = "Bool" - -let%test "pp tp TreeParam" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_tp (TreeParam TInt) = "{Int}" -;; - -let%test "pp tp ListParam" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_tp (ListParam TBool) = "[Bool]" -;; - -let%test "pp tp TupleParams" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_tp - (TupleParams (TInt, TBool, [ TBool; TInt ])) - = "(Int, Bool, Bool, Int)" -;; - -let%test "pp tp FunctionType" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_tp - (FunctionType (FuncT (TBool, TUnit, []))) - = "Bool -> ()" -;; - -let%test "pp listpat PCons" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PList - (PCons (([], PIdentificator (Ident "x"), []), ([], PIdentificator (Ident "xs"), [])))) - = "x : xs" -;; - -let%test "pp listpat PEnum" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PList - (PEnum - [ [], PIdentificator (Ident "x"), [] - ; [], PIdentificator (Ident "y"), [] - ; [], PIdentificator (Ident "z"), [] - ])) - = "[x, y, z]" -;; - -let%test "pp treepat PNul" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PTree PNul) = "$" -;; - -let%test "pp treepat PNode" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PTree - (PNode - ( ([], PIdentificator (Ident "x"), []) - , ([], PIdentificator (Ident "y"), []) - , ([], PIdentificator (Ident "z"), []) ))) - = "(x; y; z)" -;; - -let%test "pp pconst OrdinaryPConst" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PConst (OrdinaryPConst (Bool true))) - = "True" -;; - -let%test "pp pconst NegativePInt" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PConst (NegativePInt 18)) = "-18" -;; - -let%test "pp pat PWildcard" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat PWildcard = "_" -;; - -let%test "pp pat PConst" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PConst (OrdinaryPConst (Bool true))) - = "True" -;; - -let%test "pp pat PIdentificator" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PIdentificator (Ident "x")) = "x" -;; - -let%test "pp pat PList" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PList - (PCons (([], PIdentificator (Ident "x"), []), ([], PIdentificator (Ident "xs"), [])))) - = "x : xs" -;; - -let%test "pp pat PTuple" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PTuple - ( ([], PIdentificator (Ident "a"), []) - , ([], PIdentificator (Ident "b"), []) - , [ [], PIdentificator (Ident "c"), []; [], PIdentificator (Ident "d"), [] ] )) - = "(a, b, c, d)" -;; - -let%test "pp pat PMaybe Nothing" = - Format.asprintf "%a" Haskell_lib.Pprintast.pp_pat (PMaybe Nothing) = "Nothing" -;; - -let%test "pp pat PMaybe Just" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PMaybe (Just ([], PIdentificator (Ident "x"), []))) - = "Just x" -;; - -let%test "pp pat PTree" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pat - (PTree - (PNode - ( ([], PIdentificator (Ident "x"), []) - , ([], PIdentificator (Ident "y"), []) - , ([], PIdentificator (Ident "z"), []) ))) - = "(x; y; z)" -;; - -let%test "pp pattern without capture, without type" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pattern - ([], PIdentificator (Ident "x"), []) - = "x" -;; - -let%test "pp pattern with capture, without type" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pattern - ([ Ident "my"; Ident "first"; Ident "variable" ], PIdentificator (Ident "x"), []) - = "my@first@variable@x" -;; - -let%test "pp pattern with capture, with type" = - Format.asprintf - "%a" - Haskell_lib.Pprintast.pp_pattern - ([ Ident "my"; Ident "first"; Ident "variable" ], PIdentificator (Ident "x"), [ TInt ]) - = "my@first@variable@x :: Int" -;; - -let%expect_test "expr_with_prio" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Binop - ( ( Binop - ( ( Binop - ( Haskell_lib.Pprintast.i_const 1 - , Plus - , Haskell_lib.Pprintast.i_const 0 ) - , [] ) - , Multiply - , Haskell_lib.Pprintast.i_const 2 ) - , [] ) - , Greater - , Haskell_lib.Pprintast.i_const 1 ) - , [] ); - [%expect {| - (1 + 0) * 2 > 1 |}] -;; - -let%expect_test "expr_with_prio_tp" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Binop - ( ( Binop - ( ( Binop - ( Haskell_lib.Pprintast.i_const 1 - , Plus - , Haskell_lib.Pprintast.i_const 0 ) - , [ TInt ] ) - , Multiply - , Haskell_lib.Pprintast.i_const 2 ) - , [] ) - , Greater - , Haskell_lib.Pprintast.i_const 1 ) - , [ TBool ] ); - [%expect {| - (1 + 0 :: Int) * 2 > 1 :: Bool |}] -;; - -let%expect_test "expr_with_fun_app_tp" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Binop - ( ( FunctionApply - ( (Identificator (Ident "f"), [ FunctionType (FuncT (TInt, TInt, [])) ]) - , (Identificator (Ident "x"), [ TInt ]) - , [ Identificator (Ident "g"), []; Haskell_lib.Pprintast.i_const 2 ] ) - , [] ) - , Plus - , Haskell_lib.Pprintast.i_const 1 ) - , [] ); - [%expect {| - (f :: Int -> Int) (x :: Int) g 2 + 1 |}] -;; - -let%expect_test "expr_case_neg" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Case - ( (Neg (Haskell_lib.Pprintast.i_const 1), []) - , (([], PConst (NegativePInt 1), []), OrdBody (Haskell_lib.Pprintast.i_const 1)) - , [] ) - , [] ); - [%expect {| - (case - 1 of -1 -> 1) |}] -;; - -let%expect_test "expr_case_tp" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Case - ( (Neg (Haskell_lib.Pprintast.i_const 1), [ TInt ]) - , (([], PConst (NegativePInt 1), [ TInt ]), OrdBody (Const (Int 1), [ TInt ])) - , [] ) - , [ TInt ] ); - [%expect {| - ((case - 1 :: Int of (-1 :: Int) -> 1 :: Int)) :: Int |}] -;; - -let%expect_test "expr_doble_cons_and_lam" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Lambda - ( ( [] - , PList - (PCons - ( ([], PIdentificator (Ident "x"), []) - , ([], PIdentificator (Ident "xs"), []) )) - , [] ) - , [] - , ( Binop - ( ( Binop - ( (Identificator (Ident "x1"), []) - , Cons - , (Identificator (Ident "x2"), []) ) - , [] ) - , Cons - , (Identificator (Ident "xs"), []) ) - , [] ) ) - , [] ); - [%expect {| - (\ (x : xs) -> (x1 : x2) : xs) |}] -;; - -let%expect_test "expr_cons_lin" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Binop - ( (Identificator (Ident "xs"), []) - , Cons - , ( Binop - ((Identificator (Ident "x1"), []), Cons, (Identificator (Ident "x2"), [])) - , [] ) ) - , [] ); - [%expect {| - xs : x1 : x2 |}] -;; - -let%expect_test "expr_cons_lin_tp" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_expr - ( Binop - ( (Identificator (Ident "xs"), [ TUnit ]) - , Cons - , ( Binop - ((Identificator (Ident "x1"), []), Cons, (Identificator (Ident "x2"), [])) - , [] ) ) - , [ ListParam TUnit ] ); - [%expect {| - (xs :: ()) : x1 : x2 :: [()] |}] -;; - -let%expect_test "fac" = - Format.printf - "%a" - Haskell_lib.Pprintast.pp_binding - (Def - (FunDef - ( Ident "fac" - , ([], PIdentificator (Ident "n"), []) - , [] - , OrdBody - ( IfThenEsle - ( ( Binop - ( (Identificator (Ident "n"), []) - , Less - , Haskell_lib.Pprintast.i_const 0 ) - , [] ) - , (ENothing, []) - , ( FunctionApply - ( (EJust, []) - , ( FunctionApply - ( (Identificator (Ident "save_fac"), []) - , (Identificator (Ident "n"), []) - , [] ) - , [] ) - , [] ) - , [] ) ) - , [] ) - , [ Def - (FunDef - ( Ident "save_fac" - , ([], PIdentificator (Ident "y"), []) - , [] - , Guards - ( ( ( Binop - ( (Identificator (Ident "y"), []) - , Equality - , Haskell_lib.Pprintast.i_const 0 ) - , [] ) - , Haskell_lib.Pprintast.i_const 1 ) - , [ ( (Identificator (Ident "otherwise"), []) - , ( Binop - ( (Identificator (Ident "y"), []) - , Multiply - , ( FunctionApply - ( (Identificator (Ident "save_fac"), []) - , ( Binop - ( (Identificator (Ident "y"), []) - , Minus - , Haskell_lib.Pprintast.i_const 1 ) - , [] ) - , [] ) - , [] ) ) - , [] ) ) - ] ) - , [] )) - ] ))); - [%expect - {| - fac n = (if n < 0 then Nothing else Just (save_fac n)) where save_fac y | y == 0 = 1 | otherwise = y * save_fac (y - 1) |}] -;; diff --git a/Haskell/tests/tests/pprintast_test.mli b/Haskell/tests/tests/pprintast_test.mli deleted file mode 100644 index e06ef3aab..000000000 --- a/Haskell/tests/tests/pprintast_test.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024, Kostya Oreshin and Nikita Shchutskii *) - -(** SPDX-License-Identifier: MIT *) diff --git a/FSharpUnitsOfMeasure/LICENSE.md b/LICENSE.md similarity index 100% rename from FSharpUnitsOfMeasure/LICENSE.md rename to LICENSE.md diff --git a/Lambda/.envrc b/Lambda/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/Lambda/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/Lambda/.gitignore b/Lambda/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/Lambda/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/Lambda/.ocamlformat b/Lambda/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/Lambda/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/Lambda/.zanuda b/Lambda/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/Lambda/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/Lambda/COPYING b/Lambda/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/Lambda/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/Lambda/COPYING.CC0 b/Lambda/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/Lambda/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/Lambda/COPYING.LESSER b/Lambda/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/Lambda/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/Lambda/DONT_REMOVE_THIS_DIRECTORY.md b/Lambda/DONT_REMOVE_THIS_DIRECTORY.md deleted file mode 100644 index e0530079f..000000000 --- a/Lambda/DONT_REMOVE_THIS_DIRECTORY.md +++ /dev/null @@ -1,3 +0,0 @@ -This file should be contained in template directoty `Lambda`. -You should remove it when you copy `Lambda` for your -personal pet project. diff --git a/Lambda/Lambda.opam b/Lambda/Lambda.opam deleted file mode 100644 index 6468bc7d8..000000000 --- a/Lambda/Lambda.opam +++ /dev/null @@ -1,36 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "FIXME An interpreter for language" -description: - "FIXME. A longer description, for example, which are the most interesing features being supported, etc." -maintainer: ["FIXME Vasya Pupkin "] -authors: ["FIXME Vasya Pupkin "] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Kakadu/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Kakadu/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/Lambda/Makefile b/Lambda/Makefile deleted file mode 100644 index e234db4bf..000000000 --- a/Lambda/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/language dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/Lambda/bin/REPL.ml b/Lambda/bin/REPL.ml deleted file mode 100644 index c761231ef..000000000 --- a/Lambda/bin/REPL.ml +++ /dev/null @@ -1,139 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Lambda_lib - -include struct - open Ast - open Utils - - type 'a status = - | Done of 'a - | WIP of 'a - - let fin x = Done x - let wip x = WIP x - - let ao_small_step_strat = - let rec helper = function - | Var _ as l -> fin l - | Abs (x, b) -> - (match helper b with - | WIP b2 -> wip (abs x b2) - | Done b2 -> fin (abs x b2)) - | App (f, arg) -> - (match helper f with - | WIP f2 -> wip (app f2 arg) - | Done (Abs (x, body)) -> - (match helper arg with - | Done arg -> wip (Lambda.subst x ~by:arg body) - | WIP arg -> wip (app f arg)) - | Done f2 -> fin (App (f2, arg))) - in - let rec loop t = - match helper t with - | Done x -> x - | WIP x -> - Format.printf " -- %a\n%!" Pprintast.pp_hum x; - loop x - in - let on_app _ f arg = loop (app f arg) in - let on_abs _ f x = loop (abs f x) in - let on_var _ x = loop (var x) in - { Lambda.on_var; on_abs; on_app } - ;; -end - -type strategy = - | CBN - | CBV - | NO - | AO - -type strategy_kind = - | Small_step - | Big_step - -type stop_after = - | SA_parsing - | SA_never - -type opts = - { mutable dump_parsetree : bool - ; mutable mode : strategy_kind * strategy - ; mutable stop_after : stop_after - } - -let big_step_evaluator = function - | AO -> Lambda.ao_strat - | NO -> Lambda.nor_strat - | CBN -> Lambda.cbn_strat - | CBV -> Lambda.cbv_strat -;; - -let run_single dump_parsetree stop_after eval = - let text = In_channel.(input_all stdin) |> String.trim in - let ast = Parser.parse text in - match ast with - | Error e -> Format.printf "Error: %a\n%!" Parser.pp_error e - | Result.Ok ast -> - if dump_parsetree then Format.printf "Parsed result: @[%a@]\n%!" Printast.pp_named ast; - (match stop_after with - | SA_parsing -> () - | SA_never -> - let rez = eval ast in - Format.printf "Evaluated result: %a\n%!" Pprintast.pp_hum rez) -;; - -let () = - let opts = { dump_parsetree = false; mode = Big_step, NO; stop_after = SA_never } in - let pick_strategy stra () = - let kind, _ = opts.mode in - opts.mode <- kind, stra - in - let pick_step step () = - let _, stra = opts.mode in - opts.mode <- step, stra - in - let () = - let open Stdlib.Arg in - parse - [ "-cbv", Unit (pick_strategy CBV), "Call-by-value strategy" - ; "-cbn", Unit (pick_strategy CBN), "Call-by-name strategy" - ; "-no", Unit (pick_strategy NO), "Normal Order strategy" - ; "-ao", Unit (pick_strategy AO), "Applicative Order strategy" - ; ( "-small" - , Unit (pick_step Small_step) - , "Small-step strategy kind (default is big-step)" ) - ; ( "-big" - , Unit (pick_step Big_step) - , "Small-step strategy kind (default is big-step)" ) - ; ( "-dparsetree" - , Unit (fun () -> opts.dump_parsetree <- true) - , "Dump parse tree, don't eval enything" ) - ; ( "-stop-after" - , String - (function - | "parsing" -> opts.stop_after <- SA_parsing - | _ -> failwith "Bad argument of -stop-after") - , "" ) - ] - (fun _ -> - Stdlib.Format.eprintf "Positioned arguments are not supported\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for Utyped Lambda Calculus" - in - run_single opts.dump_parsetree opts.stop_after (fun ast -> - let stra = - match opts.mode with - | Big_step, stra -> big_step_evaluator stra - | Small_step, AO -> ao_small_step_strat - | _ -> raise (Failure "Implement it yourself") - in - Lambda.apply_strat stra ast) -;; diff --git a/Lambda/bin/REPL.mli b/Lambda/bin/REPL.mli deleted file mode 100644 index c1135e06a..000000000 --- a/Lambda/bin/REPL.mli +++ /dev/null @@ -1,7 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] diff --git a/Lambda/bin/dune b/Lambda/bin/dune deleted file mode 100644 index a03fbc3b5..000000000 --- a/Lambda/bin/dune +++ /dev/null @@ -1,10 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (modules REPL) - (libraries lambda_lib) - (instrumentation - (backend bisect_ppx))) - -(cram - (deps ./REPL.exe %{bin:REPL})) diff --git a/Lambda/bin/repl.t b/Lambda/bin/repl.t deleted file mode 100644 index 35b4916cc..000000000 --- a/Lambda/bin/repl.t +++ /dev/null @@ -1,12 +0,0 @@ - - $ ./REPL.exe -help - Read-Eval-Print-Loop for Utyped Lambda Calculus - -cbv Call-by-value strategy - -cbn Call-by-name strategy - -no Normal Order strategy - -ao Applicative Order strategy - -small Small-step strategy kind (default is big-step) - -big Small-step strategy kind (default is big-step) - -dparsetree Dump parse tree, don't eval enything - -help Display this list of options - --help Display this list of options diff --git a/Lambda/dune b/Lambda/dune deleted file mode 100644 index 4189d77b9..000000000 --- a/Lambda/dune +++ /dev/null @@ -1,8 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - diff --git a/Lambda/dune-project b/Lambda/dune-project deleted file mode 100644 index 777931c47..000000000 --- a/Lambda/dune-project +++ /dev/null @@ -1,35 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "FIXME Vasya Pupkin ") - -(maintainers "FIXME Vasya Pupkin ") - -(bug_reports "https://github.com/Kakadu/fp2024") - -(homepage "https://github.com/Kakadu/fp2024") - -(package - (name Lambda) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "FIXME An interpreter for language") - (description - "FIXME. A longer description, for example, which are the most interesing features being supported, etc.") - (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files add the same dependecies here too - )) diff --git a/Lambda/lib/Pprintast.ml b/Lambda/lib/Pprintast.ml deleted file mode 100644 index c57422a5d..000000000 --- a/Lambda/lib/Pprintast.ml +++ /dev/null @@ -1,64 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(* Pretty printer goes here *) - -open Ast -open Utils - -let pp ?(compact = true) = - let open Format in - let mangle t fmt x = - if is_free_in x t || not compact then fprintf fmt "%s" x else fprintf fmt "_" - in - let rec pp fmt = function - | Var s -> Format.fprintf fmt "%s" s - | App (l, r) -> Format.fprintf fmt "(%a %a)" pp l pp r - | Abs (x, Abs (y, Var z)) when x = z && y <> z && compact -> - if compact then Format.fprintf fmt "⊤" - | Abs (x, Abs (y, Var z)) when y = z && x <> z && compact -> Format.fprintf fmt "⊥" - | Abs (f, Abs (x, Var z)) when x = z && x <> f && compact -> Format.fprintf fmt "0" - | Abs (f, Abs (x, App (Var g, Var z))) when x = z && x <> f && g = f && compact -> - Format.fprintf fmt "1" - | Abs (f, Abs (x, App (Var g, App (Var h, Var z)))) - when x = z && x <> f && g = f && h = g && compact -> Format.fprintf fmt "2" - | Abs (v1, Abs (v2, Abs (v3, Abs (v4, t)))) when compact -> - Format.fprintf - fmt - "(λ %a %a %a %a -> %a)" - (mangle t) - v1 - (mangle t) - v2 - (mangle t) - v3 - (mangle t) - v4 - pp - t - | Abs (v1, Abs (v2, Abs (v3, t))) when compact -> - Format.fprintf - fmt - "(λ %a %a %a -> %a)" - (mangle t) - v1 - (mangle t) - v2 - (mangle t) - v3 - pp - t - | Abs (v1, Abs (v2, t)) when compact -> - Format.fprintf fmt "(λ %a %a -> %a)" (mangle t) v1 (mangle t) v2 pp t - | Abs (x, t) -> Format.fprintf fmt "(λ %a . %a)" (mangle t) x pp t - in - pp -;; - -let pp_hum = pp ~compact:true -let pp = pp ~compact:false diff --git a/Lambda/lib/Pprintast.mli b/Lambda/lib/Pprintast.mli deleted file mode 100644 index 81f6c2ffb..000000000 --- a/Lambda/lib/Pprintast.mli +++ /dev/null @@ -1,13 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Verbose printing. Usable for paring *) -val pp : Format.formatter -> string Ast.t -> unit - -(** Print in fancy human-readable form *) -val pp_hum : Format.formatter -> string Ast.t -> unit diff --git a/Lambda/lib/Printast.ml b/Lambda/lib/Printast.ml deleted file mode 100644 index 56a1fd7d6..000000000 --- a/Lambda/lib/Printast.ml +++ /dev/null @@ -1,15 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -type 'name t = 'name Ast.t = - | Var of 'name - | Abs of 'name * 'name t - | App of 'name t * 'name t -[@@deriving show { with_path = false }] - -let pp_named = pp Format.pp_print_string diff --git a/Lambda/lib/Printast.mli b/Lambda/lib/Printast.mli deleted file mode 100644 index 2b73b7208..000000000 --- a/Lambda/lib/Printast.mli +++ /dev/null @@ -1,13 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Pretty-print representation of AST with names. *) -val pp_named : Format.formatter -> string Ast.t -> unit - -val pp : (Format.formatter -> 'name -> unit) -> Format.formatter -> 'name Ast.t -> unit -val show : (Format.formatter -> 'name -> unit) -> 'name Ast.t -> string diff --git a/Lambda/lib/ast.mli b/Lambda/lib/ast.mli deleted file mode 100644 index 2d0f48fc6..000000000 --- a/Lambda/lib/ast.mli +++ /dev/null @@ -1,19 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -type name = string - -(** The main type for our AST (дерева абстрактного синтаксиса) *) -type 'name t = - | Var of 'name (** Variable [x] *) - | Abs of 'name * 'name t (** Abstraction [λx.t] *) - | App of 'name t * 'name t - -(* Application [f g ] *) -(** In type definition above the 3rd constructor is intentionally without documentation - to test linter *) diff --git a/Lambda/lib/dune b/Lambda/lib/dune deleted file mode 100644 index e6f215765..000000000 --- a/Lambda/lib/dune +++ /dev/null @@ -1,20 +0,0 @@ -(library - (name lambda_lib) - (public_name Lambda.Lib) - (modules Ast Lambda Interpret Parser Printast Pprintast utils) - (modules_without_implementation ast) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) - -(library - (name tests) - (modules tests) - (libraries lambda_lib) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (instrumentation - (backend bisect_ppx)) - (inline_tests)) diff --git a/Lambda/lib/interpret.ml b/Lambda/lib/interpret.ml deleted file mode 100644 index 26eafed48..000000000 --- a/Lambda/lib/interpret.ml +++ /dev/null @@ -1,35 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Real monadic interpreter goes here *) - -open Utils - -type error = [ `UnknownVariable of string (** just for example *) ] - -module Interpret (M : MONAD_FAIL) : sig - val run : _ Ast.t -> (int, [> error ]) M.t -end = struct - let run _ = - (* TODO: implement interpreter here *) - if true then M.fail (`UnknownVariable "var") else failwith "not implemented" - ;; -end - -let parse_and_run str = - let module I = Interpret (Base.Result) in - let rez = Base.Result.(Parser.parse str >>= I.run) in - match rez with - | Result.Ok n -> Printf.printf "Success: %d\n" n - | Result.Error #Parser.error -> - Format.eprintf "Parsing error\n%!"; - exit 1 - | Result.Error #error -> - Format.eprintf "Interpreter error\n%!"; - exit 1 -;; diff --git a/Lambda/lib/interpret.mli b/Lambda/lib/interpret.mli deleted file mode 100644 index 8575e8abc..000000000 --- a/Lambda/lib/interpret.mli +++ /dev/null @@ -1,9 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -val parse_and_run : string -> unit diff --git a/Lambda/lib/lambda.ml b/Lambda/lib/lambda.ml deleted file mode 100644 index fa62c9bc1..000000000 --- a/Lambda/lib/lambda.ml +++ /dev/null @@ -1,118 +0,0 @@ -(** Copyright 2021-2023, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Utils - -(* Smart constructors *) -let var x = Var x -let abs x y = Abs (x, y) -let app x y = App (x, y) - -let replace_name x ~by = - let rec helper = function - | Var y when String.equal x y -> Var by - | Var t -> Var t - | App (l, r) -> App (helper l, helper r) - | Abs (y, t) when String.equal x y -> Abs (by, helper t) - | Abs (z, t) -> Abs (z, helper t) - in - helper -;; - -let rec next_name s old = - if List.mem ~equal:String.equal old s then next_name ("_" ^ s) old else s -;; - -(* The call [subst x ~by:v e] means `[x/v]e` or `e[v -> x]` *) -let subst x ~by:v = - let rec helper = function - | Var y when String.equal y x -> v - | Var y -> Var y - | App (l, r) -> app (helper l) (helper r) - | Abs (y, b) when String.equal y x -> abs y b - | Abs (y, t) when is_free_in y v -> - let frees = free_vars v @ free_vars t in - let w = next_name y frees in - helper (abs w (replace_name y ~by:w t)) - | Abs (y, b) -> abs y (helper b) - in - helper -;; - -type strat = - { on_var : strat -> name -> string Ast.t - ; on_abs : strat -> name -> string Ast.t -> string Ast.t - ; on_app : strat -> string Ast.t -> string Ast.t -> string Ast.t - } - -let apply_strat st = function - | Var name -> st.on_var st name - | Abs (x, b) -> st.on_abs st x b - | App (l, r) -> st.on_app st l r -;; - -let without_strat = - let on_var _ = var in - let on_abs _ = abs in - let on_app _ = app in - { on_var; on_abs; on_app } -;; - -let cbn_strat = - let on_app st f arg = - match apply_strat st f with - | Abs (x, e) -> apply_strat st (subst x ~by:arg e) - | f2 -> App (f2, arg) - in - { without_strat with on_app } -;; - -let under_abstraction st x b = abs x (apply_strat st b) - -(* Normal Order Reduction to Normal Form - Application function reduced as CBN first - + Reduce under abstractions *) -let nor_strat = - let on_app st f arg = - match apply_strat cbn_strat f with - | Abs (x, e) -> apply_strat st @@ subst x ~by:arg e - | f1 -> - let f2 = apply_strat st f1 in - let arg2 = apply_strat st arg in - App (f2, arg2) - in - { without_strat with on_app; on_abs = under_abstraction } -;; - -(* Call-by-Value Reduction to Weak Normal Form *) -let cbv_strat = - let on_app st f arg = - match apply_strat st f with - | Abs (x, e) -> - let arg2 = apply_strat st arg in - apply_strat st @@ subst x ~by:arg2 e - | f2 -> App (f2, apply_strat st arg) - in - { without_strat with on_app } -;; - -(* Applicative Order Reduction to Normal Form - As CBV but reduce under abstractions *) -let ao_strat = { cbv_strat with on_abs = under_abstraction } -let a = var "a" -let x = var "x" -let y = var "y" -let z = var "z" -let f = var "f" -let g = var "g" -let h = var "h" -let m = var "m" -let n = var "n" -let p = var "p" -let zero = abs "f" @@ abs "x" x -let one = abs "f" @@ abs "x" @@ app f x -let two = abs "f" @@ abs "x" @@ app f (app f x) -let three = abs "f" @@ abs "x" @@ app f (app f (app f x)) diff --git a/Lambda/lib/lambda.mli b/Lambda/lib/lambda.mli deleted file mode 100644 index cf56ce4f7..000000000 --- a/Lambda/lib/lambda.mli +++ /dev/null @@ -1,47 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(* - val var : 'a -> 'a Ast.t - val abs : 'a -> 'a Ast.t -> 'a Ast.t - val app : 'a Ast.t -> 'a Ast.t -> 'a Ast.t *) - -val subst : string -> by:string Ast.t -> string Ast.t -> string Ast.t - -type strat = - { on_var : strat -> Ast.name -> string Ast.t - ; on_abs : strat -> Ast.name -> string Ast.t -> string Ast.t - ; on_app : strat -> string Ast.t -> string Ast.t -> string Ast.t - } - -val apply_strat : strat -> string Ast.t -> string Ast.t -val without_strat : strat - -(** Predefined strategies *) - -val cbn_strat : strat -val nor_strat : strat -val cbv_strat : strat -val ao_strat : strat - -(** Example lambda expressions *) - -val a : string Ast.t -val x : string Ast.t -val y : string Ast.t -val z : string Ast.t -val f : string Ast.t -val g : string Ast.t -val h : string Ast.t -val m : string Ast.t -val n : string Ast.t -val p : string Ast.t -val zero : string Ast.t -val one : string Ast.t -val two : string Ast.t -val three : string Ast.t diff --git a/Lambda/lib/parser.ml b/Lambda/lib/parser.ml deleted file mode 100644 index 2b7f709be..000000000 --- a/Lambda/lib/parser.ml +++ /dev/null @@ -1,65 +0,0 @@ -(** Copyright 2021-2023, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(* TODO: implement parser here *) -open Angstrom - -let is_space = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -let spaces = skip_while is_space - -let varname = - satisfy (function - | 'a' .. 'z' -> true - | _ -> false) -;; - -let conde = function - | [] -> fail "empty conde" - | h :: tl -> List.fold_left ( <|> ) h tl -;; - -type dispatch = - { apps : dispatch -> string Ast.t Angstrom.t - ; single : dispatch -> string Ast.t Angstrom.t - } - -type error = [ `Parsing_error of string ] - -let pp_error ppf = function - | `Parsing_error s -> Format.fprintf ppf "%s" s -;; - -let parse_lam = - let single pack = - fix (fun _ -> - conde - [ char '(' *> pack.apps pack <* char ')' "Parentheses expected" - ; ((string "λ" <|> string "\\") *> spaces *> varname - <* spaces - <* (return () <* char '.' <|> string "->" *> return ()) - >>= fun var -> - pack.apps pack >>= fun b -> return (Ast.Abs (String.make 1 var, b))) - ; (varname <* spaces >>= fun c -> return (Ast.Var (String.make 1 c))) - ]) - in - let apps pack = - many1 (spaces *> pack.single pack <* spaces) - >>= function - | [] -> fail "bad syntax" - | x :: xs -> return @@ List.fold_left (fun l r -> Ast.App (l, r)) x xs - in - { single; apps } -;; - -let parse str = - match - Angstrom.parse_string (parse_lam.apps parse_lam) ~consume:Angstrom.Consume.All str - with - | Result.Ok x -> Result.Ok x - | Error er -> Result.Error (`Parsing_error er) -;; diff --git a/Lambda/lib/parser.mli b/Lambda/lib/parser.mli deleted file mode 100644 index 815d0317b..000000000 --- a/Lambda/lib/parser.mli +++ /dev/null @@ -1,22 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -type error = [ `Parsing_error of string ] - -val pp_error : Format.formatter -> [< `Parsing_error of string ] -> unit - -(** Main entry of parser *) -val parse : string -> (Ast.name Ast.t, [> error ]) result - -type dispatch = - { apps : dispatch -> Ast.name Ast.t Angstrom.t - ; single : dispatch -> Ast.name Ast.t Angstrom.t - } - -(* A collection of miniparsers *) -val parse_lam : dispatch diff --git a/Lambda/lib/tests.ml b/Lambda/lib/tests.ml deleted file mode 100644 index 7f7395a53..000000000 --- a/Lambda/lib/tests.ml +++ /dev/null @@ -1,56 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** ***** UNIT TESTS COULD GO HERE (JUST AN EXAMPLE) *) -let rec fact n = if n = 1 then 1 else n * fact (n - 1) - -let%test _ = fact 5 = 120 - -(* These is a simple unit test that tests a single function 'fact' - If you want to test something large, like interpretation of a piece - of a minilanguge, it is not longer a unit tests but an integration test. - Read about dune's cram tests and put the test into `demos/somefile.t`. -*) - -open Lambda_lib -open Parser - -let parse_optimistically str = Result.get_ok (parse str) -let pp = Printast.pp_named - -let%expect_test _ = - Format.printf "%a" pp (parse_optimistically "x y"); - [%expect {| (App ((Var x), (Var y))) |}] -;; - -let%expect_test _ = - Format.printf "%a" pp (parse_optimistically "(x y)"); - [%expect {| (App ((Var x), (Var y))) |}] -;; - -let%expect_test _ = - Format.printf "%a" pp (parse_optimistically "(\\x . x x)"); - [%expect {| (Abs (x, (App ((Var x), (Var x))))) |}] -;; - -let%expect_test _ = - Format.printf "%a" pp (parse_optimistically "(λf.λx. f (x x))"); - [%expect {| (Abs (f, (Abs (x, (App ((Var f), (App ((Var x), (Var x))))))))) |}] -;; - -let _ = Lambda_lib.Interpret.parse_and_run -let _ = Lambda_lib.Lambda.a -let _ = Lambda_lib.Lambda.one -let _ = Lambda_lib.Lambda.p -let _ = Lambda_lib.Lambda.three -let _ = Lambda_lib.Lambda.two -let _ = Lambda_lib.Lambda.without_strat -let _ = Lambda_lib.Lambda.zero -let _ = Lambda_lib.Parser.parse_lam -let _ = Lambda_lib.Printast.pp -let _ = Lambda_lib.Printast.show diff --git a/Lambda/lib/tests.mli b/Lambda/lib/tests.mli deleted file mode 100644 index 639d1975c..000000000 --- a/Lambda/lib/tests.mli +++ /dev/null @@ -1,9 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(* This file is intentionally empty *) diff --git a/Lambda/lib/utils.ml b/Lambda/lib/utils.ml deleted file mode 100644 index 4974b9db1..000000000 --- a/Lambda/lib/utils.ml +++ /dev/null @@ -1,34 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Base -open Ast - -(* TODO: use a set instead of list *) -let list_remove x = List.filter ~f:(fun a -> not (String.equal a x)) - -let free_vars = - let rec helper acc = function - | Var s -> s :: acc - | Abs (s, l) -> acc @ list_remove s (helper [] l) - | App (l, r) -> helper (helper acc r) l - in - helper [] -;; - -let is_free_in x term = List.mem (free_vars term) x ~equal:String.equal -let var x = Var x -let abs x l = Abs (x, l) -let app l r = App (l, r) - -(* TODO: rework this *) -module type MONAD_FAIL = sig - include Base.Monad.S2 - - val fail : 'e -> ('a, 'e) t -end diff --git a/Lambda/lib/utils.mli b/Lambda/lib/utils.mli deleted file mode 100644 index 70e625a5c..000000000 --- a/Lambda/lib/utils.mli +++ /dev/null @@ -1,22 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -val free_vars : string Ast.t -> string list -val is_free_in : string -> string Ast.t -> bool - -(** Smart constructors *) - -val var : 'a -> 'a Ast.t -val abs : 'a -> 'a Ast.t -> 'a Ast.t -val app : 'a Ast.t -> 'a Ast.t -> 'a Ast.t - -module type MONAD_FAIL = sig - include Base.Monad.S2 - - val fail : 'e -> ('a, 'e) t -end diff --git a/Lambda/tests/.gitignore b/Lambda/tests/.gitignore deleted file mode 100644 index 26685e795..000000000 --- a/Lambda/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -lam*.txt \ No newline at end of file diff --git a/Lambda/tests/dune b/Lambda/tests/dune deleted file mode 100644 index 317804108..000000000 --- a/Lambda/tests/dune +++ /dev/null @@ -1,31 +0,0 @@ -(executable - (name gen_tests) - (libraries lambda_lib) - (modules gen_tests) - (instrumentation - (backend bisect_ppx))) - -(rule - (deps ./gen_tests.exe) - (targets - lam_zero.txt - lam_one.txt - lam_1+1.txt - lam_2x1.txt - lam_3x2.txt - lam_fac3.txt) - (mode - (promote (until-clean))) - (action - (run %{deps}))) - -(cram - (applies_to interpret_tests) - (deps - lam_zero.txt - lam_one.txt - lam_1+1.txt - lam_2x1.txt - lam_3x2.txt - lam_fac3.txt - ../bin/REPL.exe)) diff --git a/Lambda/tests/gen_tests.ml b/Lambda/tests/gen_tests.ml deleted file mode 100644 index 6ae0f4292..000000000 --- a/Lambda/tests/gen_tests.ml +++ /dev/null @@ -1,61 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Lambda_lib -open Ast -open Lambda -open Utils - -let zero = abs "g" @@ abs "y" @@ Var "y" -let one = abs "f" @@ abs "x" @@ app f (Var "x") -let two = abs "f" @@ abs "x" @@ app f (app f x) -let three = abs "f" @@ abs "x" @@ app f (app f (app f x)) -let plus = abs "m" @@ abs "n" @@ abs "f" @@ abs "x" @@ app m @@ app f @@ app n @@ app f x -let mul = abs "x" @@ abs "y" @@ abs "z" @@ app x (app y z) -let true_ = abs "x" @@ abs "y" @@ Var "x" -let false_ = abs "x" @@ abs "y" @@ Var "y" -let isZero = abs "n" @@ app (app n (abs "x" false_)) true_ - -(* TODO: write the right if-then-else - by adding thunk around then and else branches to delay the evaluation *) -let pred = - let xxx = abs "g" @@ abs "h" @@ app h (app g f) in - abs "n" @@ abs "f" @@ abs "x" @@ app (app (app n xxx) (abs "u" x)) (abs "u" (Var "u")) -;; - -let pp = Pprintast.pp - -let out_term file lam = - Out_channel.with_open_text file (fun ch -> - Format.fprintf (Format.formatter_of_out_channel ch) "%a%!" pp lam; - flush ch) -;; - -let () = out_term "lam_zero.txt" zero -let () = out_term "lam_one.txt" one -let () = out_term "lam_1+1.txt" (app plus @@ app one one) -let () = out_term "lam_2x1.txt" (app (app mul two) one) -let () = out_term "lam_3x2.txt" (app (app mul three) two) - -(** Definition for normal order *) -module _ = struct - let ite cond th el = app (app (app isZero cond) th) el - - let fact = - abs "s" - @@ abs "n" - @@ ite (Var "n") one (app (app mul (app (var "s") (app pred (var "n")))) (var "n")) - ;; - - let ygrek = - let hack = abs "x" (app f (app x x)) in - abs "f" (app hack hack) - ;; - - let () = out_term "lam_fac3.txt" @@ app (app ygrek fact) three -end diff --git a/Lambda/tests/gen_tests.mli b/Lambda/tests/gen_tests.mli deleted file mode 100644 index b04319239..000000000 --- a/Lambda/tests/gen_tests.mli +++ /dev/null @@ -1,9 +0,0 @@ -(* Intentionally empty *) - -[@@@ocaml.text "/*"] - -(** Copyright 2021-2024, Kakadu and contributors *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] diff --git a/Lambda/tests/interpret_tests.t b/Lambda/tests/interpret_tests.t deleted file mode 100644 index 8a377a93e..000000000 --- a/Lambda/tests/interpret_tests.t +++ /dev/null @@ -1,74 +0,0 @@ -Copyright 2021-2024, Kakadu and contributors -SPDX-License-Identifier: CC0-1.0 - -Cram tests here. They run and compare program output to the expected output -https://dune.readthedocs.io/en/stable/tests.html#cram-tests -Use `dune promote` after you change things that should runned - -If you need to put sample program and use it both in your interpreter and preinstalled one, -you could put it into separate file. Thise will need stanza `(cram (deps demo_input.txt))` -in the dune file - - $ ../bin/REPL.exe -cbv -dparsetree < \f.x - Parsed result: (Abs (f, (Var x))) - Evaluated result: (λ _ . x) - $ ../bin/REPL.exe -dparsetree < garbage242 - Error: : end_of_input - - - - $ ../bin/REPL.exe -no -dparsetree < (\x.\y.x)(\u.u)((\x. x x)(\x.x x)) - Parsed result: (App ( - (App ((Abs (x, (Abs (y, (Var x))))), (Abs (u, (Var u))))), - (App ((Abs (x, (App ((Var x), (Var x))))), - (Abs (x, (App ((Var x), (Var x))))))) - )) - Evaluated result: (λ u . u) -Below we redirect contents of the file to the evaluator - $ ../bin/REPL.exe -dparsetree -stop-after parsing < lam_1+1.txt - Parsed result: (App ( - (Abs (m, - (Abs (n, - (Abs (f, - (Abs (x, - (App ((Var m), - (App ((Var f), - (App ((Var n), (App ((Var f), (Var x))))) - )) - )) - )) - )) - )) - )), - (App ((Abs (f, (Abs (x, (App ((Var f), (Var x))))))), - (Abs (f, (Abs (x, (App ((Var f), (Var x))))))))) - )) - - $ ../bin/REPL.exe -ao < lam_1+1.txt - Evaluated result: (λ n f x _x -> ((f (n (f x))) _x)) - $ ../bin/REPL.exe -ao < lam_2x1.txt - Evaluated result: 2 -Call by value doesn't reduce under abstraction - $ ../bin/REPL.exe -cbv < lam_2x1.txt - Evaluated result: (λ z . (2 (1 z))) - $ ../bin/REPL.exe -ao -small < lam_3x2.txt - -- ((λ y z -> ((λ f x -> (f (f (f x)))) (y z))) 2) - -- ((λ y z x -> ((y z) ((y z) ((y z) x)))) 2) - -- (λ z x -> ((2 z) ((2 z) ((2 z) x)))) - -- (λ z x -> ((λ x . (z (z x))) ((2 z) ((2 z) x)))) - -- (λ z x -> ((λ x . (z (z x))) ((λ x . (z (z x))) ((2 z) x)))) - -- (λ z x -> ((λ x . (z (z x))) ((λ x . (z (z x))) ((λ x . (z (z x))) x)))) - -- (λ z x -> ((λ x . (z (z x))) ((λ x . (z (z x))) (z (z x))))) - -- (λ z x -> ((λ x . (z (z x))) (z (z (z (z x)))))) - -- (λ z x -> (z (z (z (z (z (z x))))))) - Evaluated result: (λ z x -> (z (z (z (z (z (z x))))))) - $ ../bin/REPL.exe -ao < lam_zero.txt - Evaluated result: ⊥ -For 3! we use noral order reduction - $ cat lam_fac3.txt - (((λ f . ((λ x . (f (x x))) (λ x . (f (x x))))) (λ s . (λ n . ((((λ n . ((n (λ x . (λ x . (λ y . y)))) (λ x . (λ y . x)))) n) (λ f . (λ x . (f x)))) (((λ x . (λ y . (λ z . (x (y z))))) (s ((λ n . (λ f . (λ x . (((n (λ g . (λ h . (h (g f))))) (λ u . x)) (λ u . u))))) n))) n))))) (λ f . (λ x . (f (f (f x)))))) - $ ../bin/REPL.exe -no < lam_fac3.txt - Evaluated result: (λ z x -> (z (z (z (z (z (z x))))))) diff --git a/Makefile b/Makefile deleted file mode 100644 index 651b11f9d..000000000 --- a/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: deps -DEPS = ocamlformat.0.26.2 ocaml-lsp-server.1.18.0 dune.3.16.0 odig -deps: - opam install --yes $(DEPS) - -NEW_NAME=Lambda2 -copy_template: - @$(RM) -r $(NEW_NAME) - cp Lambda $(NEW_NAME) -r - @$(RM) $(NEW_NAME)/DONT_REMOVE_THIS_DIRECTORY.md - @sed 's/(name Lambda)/(name $(NEW_NAME))/g' $(NEW_NAME)/dune-project -i - @sed 's/public_name Lambda/public_name $(NEW_NAME)/g' $(NEW_NAME)/lib/dune -i - @mv $(NEW_NAME)/Lambda.opam $(NEW_NAME)/$(NEW_NAME).opam - @echo "\033[5m\033[1mПереименуйте Васю Пупкина в себя\033[22m\033[0m" - grep -n --color=auto -e FIXME -e 'FIXME Vasya Pupkin' $(NEW_NAME)/dune-project -r diff --git a/OCamlOOP/.envrc b/OCamlOOP/.envrc deleted file mode 100644 index 9aeb3bbc4..000000000 --- a/OCamlOOP/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) \ No newline at end of file diff --git a/OCamlOOP/.gitignore b/OCamlOOP/.gitignore deleted file mode 100644 index 7487aa72d..000000000 --- a/OCamlOOP/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs \ No newline at end of file diff --git a/OCamlOOP/.ocamlformat b/OCamlOOP/.ocamlformat deleted file mode 100644 index 7fd0ea01c..000000000 --- a/OCamlOOP/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 \ No newline at end of file diff --git a/OCamlOOP/.zanuda b/OCamlOOP/.zanuda deleted file mode 100644 index 39f42da0d..000000000 --- a/OCamlOOP/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml \ No newline at end of file diff --git a/OCamlOOP/COPYING b/OCamlOOP/COPYING deleted file mode 100644 index e72bfddab..000000000 --- a/OCamlOOP/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. \ No newline at end of file diff --git a/OCamlOOP/COPYING.CC0 b/OCamlOOP/COPYING.CC0 deleted file mode 100644 index 1625c1793..000000000 --- a/OCamlOOP/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. \ No newline at end of file diff --git a/OCamlOOP/COPYING.LESSER b/OCamlOOP/COPYING.LESSER deleted file mode 100644 index 153d416dc..000000000 --- a/OCamlOOP/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/OCamlOOP/Makefile b/OCamlOOP/Makefile deleted file mode 100644 index 2c5895c04..000000000 --- a/OCamlOOP/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" \ No newline at end of file diff --git a/OCamlOOP/OCamlOOP.opam b/OCamlOOP/OCamlOOP.opam deleted file mode 100644 index 44fa67609..000000000 --- a/OCamlOOP/OCamlOOP.opam +++ /dev/null @@ -1,40 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "OCaml interpreter with object-oriented programming support" -description: "OCaml interpreter with object-oriented programming support" -maintainer: [ - "Sultanov Muhammet " - "Kudrya Alexander " -] -authors: [ - "Sultanov Muhammet " - "Kudrya Alexander " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/VersusXX/OCamlOOP" -doc: "https://kakadu.github.io/fp2024/docs/OCamlOOP" -bug-reports: "https://github.com/VersusXX/OCamlOOP" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OCamlOOP/bin/dune b/OCamlOOP/bin/dune deleted file mode 100644 index f776c1837..000000000 --- a/OCamlOOP/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (public_name OCamlOOP) - (name main) - (libraries ocaml_oop_lib) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlOOP/bin/main.ml b/OCamlOOP/bin/main.ml deleted file mode 100644 index 72a347192..000000000 --- a/OCamlOOP/bin/main.ml +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_oop_lib.Ast - -let () = - let fact_ast : structure_item list = - [ Str_value - { d_rec = Rec - ; d_pat = Pat_var "factorial" - ; d_exp = - Exp_function - ( [ Pat_var "n" ] - , Exp_ifthenelse - ( Exp_apply (Exp_ident "<=", [ Exp_ident "n"; Exp_constant (Int 1) ]) - , Exp_constant (Int 1) - , Some - (Exp_apply - ( Exp_ident "*" - , [ Exp_ident "n" - ; Exp_apply - ( Exp_ident "factorial" - , [ Exp_apply - ( Exp_ident "-" - , [ Exp_ident "n"; Exp_constant (Int 1) ] ) - ] ) - ] )) ) ) - } - ] - in - print_endline (show_structure fact_ast) -;; diff --git a/OCamlOOP/dune b/OCamlOOP/dune deleted file mode 100644 index 98e54536a..000000000 --- a/OCamlOOP/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/OCamlOOP/dune-project b/OCamlOOP/dune-project deleted file mode 100644 index 7011fb038..000000000 --- a/OCamlOOP/dune-project +++ /dev/null @@ -1,31 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Sultanov Muhammet " "Kudrya Alexander ") - -(maintainers "Sultanov Muhammet " "Kudrya Alexander ") - -(bug_reports "https://github.com/VersusXX/OCamlOOP") - -(homepage "https://github.com/VersusXX/OCamlOOP") - -(package - (name OCamlOOP) - (synopsis "OCaml interpreter with object-oriented programming support") - (description "OCaml interpreter with object-oriented programming support") - (documentation "https://kakadu.github.io/fp2024/docs/OCamlOOP") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - )) \ No newline at end of file diff --git a/OCamlOOP/lib/ast.ml b/OCamlOOP/lib/ast.ml deleted file mode 100644 index 32adc1376..000000000 --- a/OCamlOOP/lib/ast.ml +++ /dev/null @@ -1,115 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** Identifier *) -type ident = string [@@deriving show { with_path = false }] - -type visibility = - | Public (** Represents a public entity *) - | Private (** Represents a private entity *) -[@@deriving show { with_path = false }] - -type recursion_flag = - | Rec (** Recursive binding *) - | Nonrec (** Non-recursive binding *) -[@@deriving show { with_path = false }] - -type binary_operator = - | Add (** [+]*) - | Subt (** [-]*) - | Mult (** [*]*) - | Div (** [/]*) - | Mod (** [%]*) - | And (** [&&]*) - | Or (** [||]*) - | Equal (** [=]*) - | NotEqual (** [!>]*) - | LessThan (** [<]*) - | LessEqual (** [<=]*) - | GreaterThan (** [>]*) - | GreaterEqual (** [>=]*) -[@@deriving show { with_path = false }] - -type unary_operator = - | Neg (** Unary [-]*) - | Not (** Unary [not]*) -[@@deriving show { with_path = false }] - -type constant = - | Int of int (** Integer constant such as [24] *) - | Float of float (** Float constant such as [3.14] *) - | Bool of bool (** Boolean constant such as [true] or [false] *) - | String of string (** String constant such as ["Hello, World!"] *) - | Char of char (** Char constant such as ['a'] *) - | Nil (** Represents empty list [[]] *) -[@@deriving show { with_path = false }] - -type pattern = - | Pat_any (** The pattern [_] *) - | Pat_var of ident (** A variable pattern such as [x] *) - | Pat_constant of constant (** Patterns such as [24], ['3.14'], ["true"], ... *) - | Pat_tuple of pattern list (** Patterns [(P1, ..., Pn)] *) - | Pat_cons of pattern * pattern (** The pattern such as [P1::P2] *) - | Pat_constructor of ident * pattern option - (** [Pat_construct(C, args)] represents: - - [C] when [args] is [None], - - [C P] when [args] is [Some P] *) -[@@deriving show { with_path = false }] - -type expression = - | Exp_ident of ident (** Identifier such as [x] *) - | Exp_constant of constant (** Constants such as [24], ['3.14'], ["true"], ... *) - | Exp_let of decl * expression - (** [Exp_let(flag, [(P1,E1) ; ... ; (Pn,En)], E)] represents: - - [let P1 = E1 and ... and Pn = EN in E] when [flag] is [Nonrecursive], - - [let rec P1 = E1 and ... and Pn = EN in E] when [flag] is [Recursive]. *) - | Exp_unary of unary_operator * expression (** Unary operators such as [-E], [not E] *) - | Exp_binary of expression * binary_operator * expression - (** Binary operators such as [E1 + E2], [E1 && E2] *) - | Exp_ifthenelse of expression * expression * expression option - (** [if E1 then E2 else E3] *) - | Exp_send of expression * ident (** [E # m]*) - | Exp_list of expression * expression - (** The expression such as [E1::E2] - This also represents lists [E1; ... En] via [E]*) - | Exp_tuple of expression list (** Tuples such as [(E1, ..., En)] *) - | Exp_function of pattern list * expression (** Function such as [fun P -> E] *) - | Exp_apply of expression * expression list - (** [Exp_apply(E0, [E1; ...; En])] represents [E0 E1 ... En] *) - | Exp_object of obj (** [object ... end] *) - | Exp_override of (ident * expression) list (** [{< x1 = E1; ...; xn = En >}] *) - | Exp_match of expression * (pattern * expression) list - (** [Exp_match(E, [C1; ...; Cn])] represents [match E with C1 | ... | Cn] *) - | Exp_construct of ident * expression option - (** [Exp_construct(C, exp)] represents: - - [C] when [exp] is [None], - - [C E] when [exp] is [Some E], - - [C (E1, ..., En)] when [exp] is [Some (Exp_tuple[E1;...;En])] *) -[@@deriving show { with_path = false }] - -and decl = - { d_rec : recursion_flag - ; d_pat : pattern - ; d_exp : expression - } - -and obj = - { self : pattern - ; fields : object_field list - } - -and object_field = - | Obj_val of ident * expression (** [val x = E] *) - | Obj_method of visibility * ident * expression (** [method x = E] *) - | Obj_inherit of expression (** [inherit E] *) - -type structure_item = - | Str_eval of expression (** [E] *) - | Str_value of decl - (** [Str_value(rec, [(P1, E1 ; ... ; (Pn, En))])] represents: - - [let P1 = E1 and ... and Pn = En] when [rec] is [Nonrecursive], - - [let rec P1 = E1 and ... and Pn = En ] when [rec] is [Recursive]. *) -[@@deriving show { with_path = false }] - -type structure = structure_item list [@@deriving show { with_path = false }] diff --git a/OCamlOOP/lib/dune b/OCamlOOP/lib/dune deleted file mode 100644 index 4e2d6dcaa..000000000 --- a/OCamlOOP/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name ocaml_oop_lib) - (public_name OCamlOOP.Lib) - (modules Ast Parser) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlOOP/lib/parser.ml b/OCamlOOP/lib/parser.ml deleted file mode 100644 index c4c8d62f5..000000000 --- a/OCamlOOP/lib/parser.ml +++ /dev/null @@ -1,343 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Base -open Ast - -let is_whitespace = Char.is_whitespace -let is_digit = Char.is_digit - -let is_uppercase = function - | 'A' .. 'Z' -> true - | _ -> false -;; - -let is_lowercase = function - | 'a' .. 'z' -> true - | _ -> false -;; - -let is_letter c = is_uppercase c || is_lowercase c -let is_ident c = is_letter c || Char.equal '_' c - -let is_keyword = function - | "rec" - | "end" - | "then" - | "fun" - | "function" - | "method" - | "match" - | "if" - | "else" - | "not" - | "with" - | "object" - | "let" - | "val" - | "true" - | "false" - | "in" -> true - | _ -> false -;; - -(*=====================Control characters=====================*) - -let ignore_spaces = take_while is_whitespace -let token1 p = ignore_spaces *> p -let token p = ignore_spaces *> string p -let left_paren = token "(" -let right_paren = token ")" -let parse_in_parens p = left_paren *> p <* right_paren -let parse_in_brackets p = token "[" *> p <* token "]" -let double_semicolon = token ";;" - -(*=====================Fold infix operators=====================*) - -let parse_left_assoc expr oper = - let rec continue acc = - lift2 (fun func arg -> func acc arg) oper expr >>= continue <|> return acc - in - expr >>= continue -;; - -let rec parse_right_assoc expr oper = - expr - >>= fun sub_expr -> - oper >>= (fun func -> parse_right_assoc expr oper >>| func sub_expr) <|> return sub_expr -;; - -(*=====================Constants=====================*) - -let const_integer = - token1 @@ take_while1 is_digit - >>= fun s -> - let num = Stdlib.int_of_string_opt s in - match num with - | Some n -> return @@ Int n - | None -> fail "Invalid integer" -;; - -let const_bool = - token1 @@ take_while1 is_letter - >>= function - | "true" -> return @@ Bool true - | "false" -> return @@ Bool false - | _ -> fail "Invalid boolean" -;; - -let const_float = - token1 @@ take_while1 is_digit - >>= fun s -> - let num = Stdlib.float_of_string_opt s in - match num with - | Some n -> return @@ Float n - | None -> fail "Invalid float" -;; - -let const_nil = token "[]" *> return Nil -let const = choice [ const_integer; const_float; const_bool; const_nil ] - -(*=====================Identifiers=====================*) - -let check_ident i = - match i with - | i when is_keyword i -> fail "keyword" - | "_" -> fail "unexpected wildcard" - | _ -> return i -;; - -let ident = - token1 peek_char - >>= (function - | Some x when Char.equal x '_' || is_lowercase x -> return x - | _ -> fail "Invalid identifier") - >>= fun _ -> take_while is_ident >>= check_ident -;; - -(*=====================Patterns=====================*) - -let pat_const = const >>| fun p -> Pat_constant p -let pat_cons = token "::" *> return (fun a b -> Pat_cons (a, b)) -let pat_any = token "_" *> ignore_spaces *> return Pat_any -let pat_val = ident >>| fun c -> Pat_var c -let tuple ident f = lift2 (fun h tl -> f @@ (h :: tl)) ident (many1 (token "," *> ident)) -let pat_tuple pat = parse_in_parens (tuple pat (fun ps -> Pat_tuple ps)) - -let pattern = - fix (fun pattern -> - let term = - choice [ parse_in_parens pattern; pat_const; pat_any; pat_val; pat_tuple pattern ] - in - let cons = parse_in_parens (parse_right_assoc term pat_cons) in - cons <|> term) -;; - -(*=====================Expressions=====================*) - -let exp_const = const >>| fun c -> Exp_constant c -let exp_val = ident >>| fun c -> Exp_ident c -let exp_cons = token "::" *> return (fun a b -> Exp_list (a, b)) - -let exp_list expr = - let rec creaet_list = function - | [] -> Exp_constant Nil - | h :: tl -> Exp_list (h, creaet_list tl) - in - let basic_list = parse_in_brackets @@ sep_by (token ";") expr >>| creaet_list in - let cons_list = parse_right_assoc (expr <|> basic_list) exp_cons in - basic_list <|> cons_list -;; - -let exp_tuple expr = tuple expr (fun es -> Exp_tuple es) -let exp_apply expr = parse_left_assoc expr (return (fun f a -> Exp_apply (f, [ a ]))) - -let exp_ifthenelse expr = - lift3 - (fun b t e -> Exp_ifthenelse (b, t, e)) - (token "if" *> expr) - (token "then" *> expr) - (option None (token "else" *> expr >>| Option.some)) -;; - -let exp_fun pexpr = - token "fun" *> many1 pattern - >>= fun args -> - token "->" *> pexpr - >>= fun e -> - match List.rev args with - | h :: tl -> - return - (List.fold_left - ~init:(Exp_function ([ h ], e)) - ~f:(fun acc x -> Exp_function ([ x ], acc)) - tl) - | _ -> fail "Invalid function" -;; - -(* let val_binding pat exp = { pat; exp } *) -let efun i e = Exp_function ([ i ], e) -let exp_pattern_matching pexpr = lift2 (fun k v -> k, v) (pattern <* token "->") pexpr - -let exp_match pexpr = - token "match" - *> lift2 - (fun v ptrns -> Exp_match (v, ptrns)) - (pexpr <* token "with") - (exp_pattern_matching pexpr - <|> token "|" *> exp_pattern_matching pexpr - >>= fun p -> many (token "|" *> exp_pattern_matching pexpr) >>| fun ps -> p :: ps - ) -;; - -let exp_decl pexpr = - let exp = - ignore_spaces *> many pattern - >>= fun args -> - token "=" *> pexpr - >>= fun e -> - match List.rev args with - | h :: tl -> return (List.fold_left ~init:(efun h e) ~f:(fun acc x -> efun x acc) tl) - | _ -> return e - in - token "let" - *> lift3 - (fun d_rec d_pat d_exp -> { d_rec; d_pat; d_exp }) - (token "rec" *> return Rec <|> return Nonrec) - (token1 pattern) - exp -;; - -let elet d e = Exp_let (d, e) -let exp_let pexpr = lift2 elet (exp_decl pexpr) (token "in" *> pexpr) - -let exp_sinvk pexpr = - let iter = token "#" *> ident in - let rec helper acc = - iter >>= fun sub -> helper (Exp_send (acc, sub)) <|> return (Exp_send (acc, sub)) - in - let acc = lift2 (fun s m -> Exp_send (s, m)) pexpr (token "#" *> ident) in - acc >>= helper <|> acc -;; - -let exp_override pexpr = - token "{<" - *> lift - (fun es -> Exp_override es) - (sep_by (token ";") (ident >>= fun id -> token "=" *> pexpr >>| fun e -> id, e)) - <* token ">}" -;; - -let exp_object pexpr = - let ov = - lift2 (fun a b -> Obj_val (a, b)) (token "val" *> ident) (token "=" *> pexpr) - in - let helper = - ignore_spaces *> many pattern - >>= fun args -> - token "=" *> pexpr - >>| fun e -> - match List.rev args with - | h :: tl -> - List.fold_left - ~init:(Exp_function ([ h ], e)) - ~f:(fun acc x -> Exp_function ([ x ], acc)) - tl - | _ -> e - in - let om = - lift3 - (fun a b c -> Obj_method (a, b, c)) - (token "method" *> token "private" *> return Private - <|> token "method" *> return Public) - ident - helper - in - let self_pat = token "self" *> return (Pat_var "self") in - token "object" - *> lift2 - (fun self fields -> Exp_object { self; fields }) - (option Pat_any (parse_in_parens (pat_any <|> self_pat))) - (many (ov <|> om) <* token "end") -;; - -(*=====================Binary/Unary operators=====================*) - -let bin_op chain1 e ops = chain1 e (ops >>| fun o l r -> Exp_binary (l, o, r)) -let left_bin_op = bin_op parse_left_assoc -let right_bin_op = bin_op parse_right_assoc -let op l = choice (List.map ~f:(fun (o, n) -> token o *> return n) l) -let mult_div = op [ "*", Mult; "/", Div ] -let add_sub = op [ "+", Add; "-", Subt ] - -let compare = - op - [ "<=", LessEqual - ; "<", LessThan - ; ">=", GreaterEqual - ; ">", GreaterThan - ; "=", Equal - ; "<>", NotEqual - ] -;; - -let and_op = op [ "&&", And ] -let or_op = op [ "||", Or ] -let neg = choice [ token "not" *> return Not; token "-" *> return Neg ] - -let expr = - fix (fun pexpr -> - let sube = choice [ parse_in_parens pexpr; exp_const; exp_val ] in - let send = exp_sinvk sube in - let term = exp_apply (send <|> sube) in - let term = - left_bin_op - (term <|> (neg >>= fun op -> term >>| fun exp -> Exp_unary (op, exp))) - mult_div - in - let term = left_bin_op term add_sub in - let term = exp_list term <|> term in - let term = left_bin_op term compare in - let term = right_bin_op term and_op in - let term = right_bin_op term or_op in - let term = exp_tuple term <|> term in - choice - [ exp_ifthenelse pexpr - ; exp_let pexpr - ; exp_match pexpr - ; exp_fun pexpr - ; exp_object pexpr - ; exp_override pexpr - ; term - ]) -;; - -let del = (double_semicolon <|> ignore_spaces) *> ignore_spaces - -let str_item = - expr - >>| (fun e -> Str_eval e) - <* double_semicolon - <|> (token1 (exp_decl expr) >>| fun v -> Str_value v) -;; - -let program = del *> many1 (str_item <* del) - -(* Define a standard error message for parsing issues *) -let syntax_error_msg = "Syntax error" - -(* Parser function that returns an error message wrapped in a Result *) -let parse s = - match parse_string ~consume:All program s with - | Ok v -> Ok v - | Error _ -> Error syntax_error_msg -;; - -(* Parser function that handles prefixes, also returning a standard error message *) -let parse_prefix s = - match parse_string ~consume:Prefix program s with - | Ok v -> Ok v - | Error _ -> Error syntax_error_msg -;; diff --git a/OCamlOOP/lib/parser.mli b/OCamlOOP/lib/parser.mli deleted file mode 100644 index 1401d3156..000000000 --- a/OCamlOOP/lib/parser.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> (Ast.structure_item list, string) result -val parse_prefix : string -> (Ast.structure_item list, string) result diff --git a/OCamlOOP/test/ast_check.t b/OCamlOOP/test/ast_check.t deleted file mode 100644 index f7fe083cb..000000000 --- a/OCamlOOP/test/ast_check.t +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2024-2025, VersusXX, AlexandrKudrya -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../bin/main.exe - [(Str_value - { d_rec = Rec; d_pat = (Pat_var "factorial"); - d_exp = - (Exp_function ([(Pat_var "n")], - (Exp_ifthenelse ( - (Exp_apply ((Exp_ident "<="), - [(Exp_ident "n"); (Exp_constant (Int 1))])), - (Exp_constant (Int 1)), - (Some (Exp_apply ((Exp_ident "*"), - [(Exp_ident "n"); - (Exp_apply ((Exp_ident "factorial"), - [(Exp_apply ((Exp_ident "-"), - [(Exp_ident "n"); (Exp_constant (Int 1))])) - ] - )) - ] - ))) - )) - )) - }) - ] diff --git a/OCamlOOP/test/dune b/OCamlOOP/test/dune deleted file mode 100644 index 032e6e61e..000000000 --- a/OCamlOOP/test/dune +++ /dev/null @@ -1,12 +0,0 @@ -(library - (name tests) - (libraries ocaml_oop_lib) - (preprocess - (pps ppx_expect)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to ast_check parser_tests) - (deps ../bin/main.exe)) diff --git a/OCamlOOP/test/parser_tests.ml b/OCamlOOP/test/parser_tests.ml deleted file mode 100644 index b2b4bbae3..000000000 --- a/OCamlOOP/test/parser_tests.ml +++ /dev/null @@ -1,163 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_oop_lib -open Parser - -let parse_test s = - match parse_prefix s with - | Ok v -> Format.printf "%s\n" Ast.(show_structure v) - | Error error -> Format.printf "%s\n" error -;; - -(* basic operators tests*) - -let%expect_test "basic_test" = - let () = parse_test "1 + 2 / 3;;" in - [%expect - {| - [(Str_eval - (Exp_binary ((Exp_constant (Int 1)), Add, - (Exp_binary ((Exp_constant (Int 2)), Div, (Exp_constant (Int 3))))))) - ] - |}] -;; - -(* if-then_else and match tests*) - -let%expect_test "test_ite" = - let () = parse_test {| - let x = if a > b then c else d in - |} in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "x"); - d_exp = - (Exp_ifthenelse ( - (Exp_binary ((Exp_ident "a"), GreaterThan, (Exp_ident "b"))), - (Exp_ident "c"), (Some (Exp_ident "d")))) - }) - ] - |}] -;; - -let%expect_test "test_it" = - let () = parse_test {| - let x = if a > b then c in - |} in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "x"); - d_exp = - (Exp_ifthenelse ( - (Exp_binary ((Exp_ident "a"), GreaterThan, (Exp_ident "b"))), - (Exp_ident "c"), None)) - }) - ] - |}] -;; - -let%expect_test "test_match" = - let () = - parse_test - {| - let n = - match a with - | 1 -> a - | 2 -> 2 - | _ -> 3 - ;; - |} - in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "n"); - d_exp = - (Exp_match ((Exp_ident "a"), - [((Pat_constant (Int 1)), (Exp_ident "a")); - ((Pat_constant (Int 2)), (Exp_constant (Int 2))); - (Pat_any, (Exp_constant (Int 3)))] - )) - }) - ] - |}] -;; - -(* let tests *) - -let%expect_test "test_with_let_function" = - let () = parse_test {|let f a = fun x -> x + a|} in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "f"); - d_exp = - (Exp_function ([(Pat_var "a")], - (Exp_function ([(Pat_var "x")], - (Exp_binary ((Exp_ident "x"), Add, (Exp_ident "a"))))) - )) - }) - ] - |}] -;; - -let%expect_test "test_with_let_types" = - let () = parse_test {| - let a = 15;; - let b = "Help";; - let c = [];; - |} in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "a"); d_exp = (Exp_constant (Int 15)) - }) - ] - |}] -;; - -(* big tests *) -let%expect_test "test_with_let_types" = - let () = - parse_test - {| - let fib a b n = - if n < 2 then n else fib b (b + a) (n - 1) - |} - in - [%expect - {| - [(Str_value - { d_rec = Nonrec; d_pat = (Pat_var "fib"); - d_exp = - (Exp_function ([(Pat_var "a")], - (Exp_function ([(Pat_var "b")], - (Exp_function ([(Pat_var "n")], - (Exp_ifthenelse ( - (Exp_binary ((Exp_ident "n"), LessThan, - (Exp_constant (Int 2)))), - (Exp_ident "n"), - (Some (Exp_apply ( - (Exp_apply ( - (Exp_apply ((Exp_ident "fib"), - [(Exp_ident "b")])), - [(Exp_binary ((Exp_ident "b"), Add, - (Exp_ident "a"))) - ] - )), - [(Exp_binary ((Exp_ident "n"), Subt, - (Exp_constant (Int 1)))) - ] - ))) - )) - )) - )) - )) - }) - ] - |}] -;; diff --git a/OCamlOOP/test/parser_tests.mli b/OCamlOOP/test/parser_tests.mli deleted file mode 100644 index 92a1b7fda..000000000 --- a/OCamlOOP/test/parser_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Sultanov Muhammet and Kudrya Alexander *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPolymorphicVariantsTypes/.envrc b/OCamlPolymorphicVariantsTypes/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/OCamlPolymorphicVariantsTypes/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/OCamlPolymorphicVariantsTypes/.gitignore b/OCamlPolymorphicVariantsTypes/.gitignore deleted file mode 100644 index aeaa40950..000000000 --- a/OCamlPolymorphicVariantsTypes/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build/ -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/OCamlPolymorphicVariantsTypes/.ocamlformat b/OCamlPolymorphicVariantsTypes/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/OCamlPolymorphicVariantsTypes/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/OCamlPolymorphicVariantsTypes/.zanuda b/OCamlPolymorphicVariantsTypes/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/OCamlPolymorphicVariantsTypes/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/OCamlPolymorphicVariantsTypes/COPYING b/OCamlPolymorphicVariantsTypes/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/OCamlPolymorphicVariantsTypes/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OCamlPolymorphicVariantsTypes/COPYING.CC0 b/OCamlPolymorphicVariantsTypes/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/OCamlPolymorphicVariantsTypes/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/OCamlPolymorphicVariantsTypes/COPYING.LESSER b/OCamlPolymorphicVariantsTypes/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/OCamlPolymorphicVariantsTypes/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/OCamlPolymorphicVariantsTypes/Makefile b/OCamlPolymorphicVariantsTypes/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/OCamlPolymorphicVariantsTypes/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/OCamlPolymorphicVariantsTypes/OCamlPolymorphicVariantsTypes.opam b/OCamlPolymorphicVariantsTypes/OCamlPolymorphicVariantsTypes.opam deleted file mode 100644 index 81a4f3411..000000000 --- a/OCamlPolymorphicVariantsTypes/OCamlPolymorphicVariantsTypes.opam +++ /dev/null @@ -1,37 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for miniML language" -description: - "An interpreter for miniML language similar to OCaml with polymorphic variants types" -maintainer: ["Ilia Suponev"] -authors: ["Ilia Suponev"] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/IliaSuponeff/OCaml-PolymorphicVariantsTypes/" -doc: "https://kakadu.github.io/fp2024/docs/OCamlPolymorphicVariantsTypes" -bug-reports: - "https://github.com/IliaSuponeff/OCaml-PolymorphicVariantsTypes/" -depends: [ - "dune" {>= "3.7"} - "stdio" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OCamlPolymorphicVariantsTypes/bin/REPL.ml b/OCamlPolymorphicVariantsTypes/bin/REPL.ml deleted file mode 100644 index b93ece9a3..000000000 --- a/OCamlPolymorphicVariantsTypes/bin/REPL.ml +++ /dev/null @@ -1,46 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Miniml.Ast -open Miniml.Parser -open Miniml.Parser_utility -open Miniml.Printer -open Stdio - -type options = - { mutable dumpast : bool - ; mutable file : string option - } -[@@deriving show { with_path = false }] - -let parse_args = - let opts = { dumpast = false; file = None } in - let open Arg in - parse - [ ( "-dparsetree" - , Unit (fun _ -> opts.dumpast <- true) - , "Dump AST of input code of moniML" ) - ; ( "-i" - , String (fun filename -> opts.file <- Some filename) - , "Input file of miniML's code to interpret it" ) - ] - (fun opt -> - Format.eprintf "Argument '%s' are not supported\n" opt; - exit ~-1) - "REPL of miniML"; - opts -;; - -let () = - let opts = parse_args in - let input = - match opts.file with - | Some filename -> In_channel.read_all filename |> String.trim - | None -> In_channel.input_all stdin |> String.trim - in - print_endline - (string_of_parse_result - (if opts.dumpast then show_program else fun _ -> "") - (parse program_parser input)) -;; diff --git a/OCamlPolymorphicVariantsTypes/bin/dune b/OCamlPolymorphicVariantsTypes/bin/dune deleted file mode 100644 index 23d46c379..000000000 --- a/OCamlPolymorphicVariantsTypes/bin/dune +++ /dev/null @@ -1,12 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (modules REPL) - (libraries miniml stdio) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) - -(cram - (deps ./main.exe %{bin:main})) diff --git a/OCamlPolymorphicVariantsTypes/dune b/OCamlPolymorphicVariantsTypes/dune deleted file mode 100644 index 98e54536a..000000000 --- a/OCamlPolymorphicVariantsTypes/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/OCamlPolymorphicVariantsTypes/dune-project b/OCamlPolymorphicVariantsTypes/dune-project deleted file mode 100644 index 08637d7f0..000000000 --- a/OCamlPolymorphicVariantsTypes/dune-project +++ /dev/null @@ -1,34 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Ilia Suponev") - -(maintainers "Ilia Suponev") - -(bug_reports - "https://github.com/IliaSuponeff/OCaml-PolymorphicVariantsTypes/") - -(homepage "https://github.com/IliaSuponeff/OCaml-PolymorphicVariantsTypes/") - -(package - (name OCamlPolymorphicVariantsTypes) - (synopsis "An interpreter for miniML language") - (description - "An interpreter for miniML language similar to OCaml with polymorphic variants types") - (documentation - "https://kakadu.github.io/fp2024/docs/OCamlPolymorphicVariantsTypes") - (version 0.1) - (depends - dune - stdio - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build))) diff --git a/OCamlPolymorphicVariantsTypes/lib/ast.ml b/OCamlPolymorphicVariantsTypes/lib/ast.ml deleted file mode 100644 index 3380f1e8a..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/ast.ml +++ /dev/null @@ -1,75 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** Identifier of variables and other definitions. **) -type identifier = string [@@deriving show { with_path = false }] - -(** Literals of miniML **) -type literal = - | IntLiteral of int (* 123 | 0 *) - | BoolLiteral of bool (* true | false *) - | UnitLiteral (* () value *) -[@@deriving show { with_path = false }] - -(** Operators for unary expressions **) -type unary_operator = - | Negate (* ~- *) - | Positive (* ~+ *) -[@@deriving show { with_path = false }] - -(** Definitions recurcive types *) -type recursive_type = - | Recursive (* let rec f = e *) - | Nonrecursive (* let f = e*) -[@@deriving show { with_path = false }] - -(** Operators for binary expressions **) -type binary_operator = - | Add (* + *) - | Subtract (* - *) - | Multiply (* * *) - | Division (* / *) - | And (* && *) - | Or (* || *) - | Gt (* > *) - | Lt (* < *) - | Gte (* >= *) - | Lte (* <= *) - | Equals (* = *) - | Unequals (* <> *) -[@@deriving show { with_path = false }] - -type pattern = - | PVar of identifier - | PTuple of pattern list (* (, ..., ) *) - | PUnit (* () *) -[@@deriving show { with_path = false }] - -type expression = - | Const of literal (* 123 | true *) - | Variable of identifier (* x | factorial *) - | Unary of unary_operator * expression (* ~-123 *) - | Binary of expression * binary_operator * expression (* 12 + 34 | true && (x > y) *) - | Tuple of expression list (* (1, 2, (let x = 6 in x)) *) - | If of expression * expression * expression option (* if x then false else true *) - | Lambda of pattern list * expression (* fun (x, (y,z)) -> x / (y + z) *) - | Apply of expression * expression list - (* factorial (n / 2) | (fun (x, (y,z)) -> x / (y + z)) (5, (2, 1)) *) - | Define of definition * expression (* let in *) - | ExpressionBlock of expression list (* (let g x = x / 2 in g y; y); *) -[@@deriving show { with_path = false }] - -and value_binding = pattern * expression [@@deriving show { with_path = false }] - -and definition = - recursive_type - * value_binding list (* [rec] P1 = E1 and ... and PN = EN *) -[@@deriving show { with_path = false }] - -type struct_item = - | DefineItem of definition (* let f x = x;; *) - | EvalItem of expression (* (fun x -> print_endline x) "Hello world";; *) -[@@deriving show { with_path = false }] - -type program = struct_item list [@@deriving show { with_path = false }] diff --git a/OCamlPolymorphicVariantsTypes/lib/dune b/OCamlPolymorphicVariantsTypes/lib/dune deleted file mode 100644 index 8550cf402..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/dune +++ /dev/null @@ -1,7 +0,0 @@ -(library - (name miniml) - (public_name OCamlPolymorphicVariantsTypes.Lib) - (preprocess - (pps ppx_deriving.show)) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlPolymorphicVariantsTypes/lib/parser.ml b/OCamlPolymorphicVariantsTypes/lib/parser.ml deleted file mode 100644 index 2ba8f1d2b..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/parser.ml +++ /dev/null @@ -1,379 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Parser_utility -open Utils - -(** Data record which contains [Miniml.Ast] - view of [binary_operator] - and it's view in string *) -type binary_operator_parse_data = - { oper_view : string - ; oper_ast : binary_operator - } - -(** Predicate to check string as keyword of Miniml *) -let is_keyword = function - | "true" | "false" -> true - | "if" | "then" | "else" -> true - | "fun" -> true - | "let" | "rec" | "and" | "in" -> true - | _ -> false -;; - -let ident_symbol = function - | 'a' .. 'z' | 'A' .. 'Z' | '_' | '\'' | '0' .. '9' -> true - | _ -> false -;; - -(** Parse [Miniml.identifier] value. *) -let ident = - let helper = many (dsatisfy ident_symbol Fun.id) in - skip_ws *> dsatisfy ident_symbol Fun.id - >>= fun s -> - if is_digit s || s = '\'' - then pfail - else - helper - >>| (fun l -> string_of_char_list (s :: l)) - >>= fun id -> if is_keyword id then pfail else preturn id -;; - -(** Parser of keyword *) -let keyword word = - let helper c = not (ident_symbol c) in - let check_end = asatisfy helper in - skip_ws *> ssequence word *> check_end *> preturn () -;; - -(** Parser of some elements sequence: - - [start]: first element of sequence - - [element_parser]: parser of one element in sequence - - [list_converter]: coverter of elements sequence to one new element - - [separator]: char sequence which splitted sequence elements *) -let element_sequence - : 'a 'b. 'a -> 'a parser -> ('a list -> 'b) -> string -> 'a parser -> 'b parser - = - fun start element_parser list_converter sep pnotfound -> - let next_element sep = - skip_ws - *> (if is_keyword sep then keyword sep else ssequence sep >>| fun _ -> ()) - *> (element_parser <|> pnotfound) - in - skip_ws - *> (many (next_element sep) >>| fun l -> list_converter (List.append [ start ] l)) -;; - -(** Parser of integer literals: [0 .. Int64.max_int]. - - [!] This parser returns also [ParseSuccess] or [ParseFail] *) -let integer = - let rec helper counter = - digit - >>= (fun v -> helper (v + (counter * 10))) - <|> (preturn counter >>| fun v -> IntLiteral v) - in - skip_ws *> digit >>= helper -;; - -(** Parser of boolean literals: [true], [false]. - - [!] This parser returns also [ParseSuccess] or [ParseFail] *) -let boolean = - skip_ws *> (keyword "true" >>| fun _ -> BoolLiteral true) - <|> (keyword "false" >>| fun _ -> BoolLiteral false) -;; - -(** Parser of patterns: [] | [] *) -let rec pattern_parser state = (skip_ws *> (pvariable <|> ptuple)) state - -(** Parser of variable pattern *) -and pvariable state = (skip_ws *> (ident >>| fun id -> PVar id)) state - -(** Parser of tuple pattern and unit pattern *) -and ptuple state = - let tuple_elements pfirst = - skip_ws - *> element_sequence - pfirst - pattern_parser - (fun l -> PTuple l) - "," - (perror "Not found expression after tuple separator: ','") - in - let brackets_subexpr = - skip_ws *> pattern_parser - >>= (fun pfirst -> tuple_elements pfirst <|> preturn pfirst) - <|> preturn PUnit - in - (skip_ws - *> (symbol '(' *> brackets_subexpr - <* (skip_ws *> symbol ')' <|> perror "Not found close bracket"))) - state -;; - -(** Parser of constants expression: [integer] and [boolean] - - [!] This parser returns also [ParseSuccess] or [ParseFail] *) -let const_expr = skip_ws *> (integer <|> boolean) >>| fun l -> Const l - -(** Parser of variable expression *) -let variable = skip_ws *> ident >>| fun s -> Variable s - -(** Parser of all expression which defines on [Miniml.Ast] module *) -let rec expr state = (skip_ws *> block_expr) state - -(** Parser of expression block *) -and block_expr state = - let helper ex = - element_sequence - ex - tuple_expr - (function - | ex :: [] -> ex - | _ as l -> ExpressionBlock l) - ";" - pfail - >>= fun block -> - assequence ";;" *> preturn block <|> ssequence ";" *> preturn block <|> preturn block - in - (skip_ws *> (tuple_expr >>= helper)) state - -(** Parser of tuple expression *) -and tuple_expr state = - let helper ex = - element_sequence - ex - boolean_expr - (function - | ex :: [] -> ex - | _ as l -> Tuple l) - "," - (perror "Not found expression after tuple separator: ','") - in - (skip_ws *> (boolean_expr >>= helper)) state - -(** Parser of applyable expressions *) -and applyable_expr state = (skip_ws *> bracket_expr <|> lambda_expr <|> variable) state - -(** Parser of basic expressions: - [] | [] | [] | [] | [] *) -and basic_expr inapply state = - (skip_ws *> unary_expr inapply - <|> if_expr - <|> define_expr - <|> (if inapply then applyable_expr else apply_expr) - <|> const_expr) - state - -(** Parser of unary expression *) -and unary_expr inapply state = - let helper = - symbol '+' *> basic_expr inapply - <|> (symbol '-' *> basic_expr inapply >>| fun e -> Unary (Negate, e)) - in - (skip_ws *> (helper <|> symbol '~' *> helper)) state - -(** Parser of brackets expression: - - unit: [()] - - else: [()] *) -and bracket_expr state = - (skip_ws *> symbol '(' *> (expr <|> preturn (Const UnitLiteral)) - <* (skip_ws *> symbol ')' <|> perror "Not found close bracket")) - state - -(** Abstract parser of binary operations - - [subparser]: parser of subexpression - - [operations]: list of one priorety level binary operations *) -and binary_expression subparser operations state = - let operation left oper = - skip_ws - *> ssequence oper.oper_view - *> (subparser - >>| (fun right -> Binary (left, oper.oper_ast, right)) - <|> perror - (Printf.sprintf - "Not found right operand of '%s' binary operator" - oper.oper_view)) - in - let rec next ex = - skip_ws *> (one_of (List.map (operation ex) operations) >>= next) <|> preturn ex - in - (skip_ws *> subparser >>= next) state - -(** Parser of binary expressions such as [ * ] and [ / ] *) -and multiply_expr state = - binary_expression - (basic_expr false) - [ { oper_view = "*"; oper_ast = Multiply }; { oper_view = "/"; oper_ast = Division } ] - state - -(** Parser of binary expressions such as [ + ] and [ - ] *) -and summary_expr state = - binary_expression - multiply_expr - [ { oper_view = "+"; oper_ast = Add }; { oper_view = "-"; oper_ast = Subtract } ] - state - -(** Parser of binary expressions such as - - [ = ] - - [ <> ] - - [ > ] - - [ < ] - - [ >= ] - - [ <= ] *) -and compare_expr state = - binary_expression - summary_expr - [ { oper_view = "="; oper_ast = Equals } - ; { oper_view = "<>"; oper_ast = Unequals } - ; { oper_view = ">="; oper_ast = Gte } - ; { oper_view = "<="; oper_ast = Lte } - ; { oper_view = ">"; oper_ast = Gt } - ; { oper_view = "<"; oper_ast = Lt } - ] - state - -(** Parser of binary expressions such as [ && ] and [ || ] *) -and boolean_expr state = - binary_expression - compare_expr - [ { oper_view = "&&"; oper_ast = And }; { oper_view = "||"; oper_ast = Or } ] - state - -and if_expr state = - let else_block ex then_ex = - skip_ws *> (expr >>| fun else_ex -> If (ex, then_ex, Some else_ex)) - <|> perror "Expected expression of 'else' branch for if expression" - in - let then_block ex = - skip_ws - *> (expr - >>= fun then_ex -> - skip_ws *> (keyword "else" *> else_block ex then_ex) - <|> preturn (If (ex, then_ex, None))) - <|> perror "Expected expression of 'then' branch for if expression" - in - (skip_ws - *> keyword "if" - *> (expr - >>= (fun ex -> - skip_ws - *> (keyword "then" *> then_block ex - <|> perror "Not found 'then' branch for if-expression")) - <|> perror "Not found if expression after keyword 'if'")) - state - -(** Parser of apply expressions such as [ ]*) -and apply_expr state = - let bin_op_checker = - skip_ws - *> one_of - (List.map - assequence - [ "+"; "-"; "/"; "*"; "&&"; "||"; "<="; ">="; "<>"; "<"; ">"; "=" ]) - in - let helper ex = - many (skip_ws *> basic_expr true) - >>= fun l -> preturn (if is_empty l then ex else Apply (ex, l)) - in - (skip_ws *> applyable_expr >>= fun ex -> bin_op_checker *> preturn ex <|> helper ex) - state - -(** Parser of lambdas definitions *) -and lambda_expr state = - (skip_ws - *> keyword "fun" - *> (many1 (skip_ws *> pattern_parser) - >>= (fun pl -> - skip_ws - *> (ssequence "->" *> (expr >>| fun ex -> Lambda (pl, ex)) - <|> perror "Not found expression of lambda") - <|> perror "Not found special sequence '->' of lambda definition") - <|> perror "Not found patterns for lambda definition")) - state - -(** Parser of value-bindings: [ = ]*) -and value_binding_parser state = - (skip_ws - *> (pattern_parser - >>= fun p -> - many (skip_ws *> pattern_parser) - >>= fun pl -> - skip_ws - *> (ssequence "=" - *> (skip_ws *> expr - >>| fun ex -> if is_empty pl then p, ex else p, Lambda (pl, ex)) - <|> perror "Not found expression of let-definition") - <|> perror "Not found special sequence '=' of let-definition binding expresssion") - <|> perror "Not found name-pattern of let-definition") - state - -and value_bindings_parser state = - (skip_ws *> value_binding_parser - >>= (fun vb -> - element_sequence - vb - value_binding_parser - Fun.id - "and" - (perror "Not found value binding")) - <|> perror "Not found value binging") - state - -(** Parser of let-definitions *) -and define_expr state = - let inexpr = - skip_ws - *> (keyword "in" - *> (expr <|> perror "Not found expression after keyword 'in' of let-xpression")) - <|> perror "Not found keyword for let-expression" - in - let recursive = - skip_ws *> keyword "rec" *> value_bindings_parser - >>= fun vbl -> inexpr >>| fun ex -> Define ((Recursive, vbl), ex) - in - let nonrecursive = - skip_ws *> value_bindings_parser - >>= fun vbl -> inexpr >>| fun ex -> Define ((Nonrecursive, vbl), ex) - in - (skip_ws *> keyword "let" *> (recursive <|> nonrecursive)) state -;; - -(** Parser of definition item *) -let define_item = - let inexpr = - skip_ws - *> keyword "in" - *> (expr <|> perror "Not found expression after keyword 'in' of let-xpression") - in - let recursive = - skip_ws *> keyword "rec" *> value_bindings_parser - >>= fun vbl -> - inexpr - >>| (fun ex -> EvalItem (Define ((Recursive, vbl), ex))) - <|> preturn (DefineItem (Recursive, vbl)) - in - let nonrecursive = - skip_ws *> value_bindings_parser - >>= fun vbl -> - inexpr - >>| (fun ex -> EvalItem (Define ((Nonrecursive, vbl), ex))) - <|> preturn (DefineItem (Nonrecursive, vbl)) - in - skip_ws *> keyword "let" *> (recursive <|> nonrecursive) -;; - -(** Parser of eval item *) -let eval_item = skip_ws *> expr >>| fun ex -> EvalItem ex - -(** Parser of all stricture item *) -let struct_item_parser = - skip_ws *> (define_item <|> eval_item) - >>= fun item -> skip_ws *> ssequence ";;" *> preturn item -;; - -(** Parser of program item *) -let program_parser = skip_ws *> many struct_item_parser diff --git a/OCamlPolymorphicVariantsTypes/lib/parser.mli b/OCamlPolymorphicVariantsTypes/lib/parser.mli deleted file mode 100644 index dad1c32b7..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/parser.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Parser_utility - -val program_parser : program parser diff --git a/OCamlPolymorphicVariantsTypes/lib/parser_utility.ml b/OCamlPolymorphicVariantsTypes/lib/parser_utility.ml deleted file mode 100644 index 50145ba1c..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/parser_utility.ml +++ /dev/null @@ -1,249 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Utils - -(** State of parser at one point in time. - It is characterized by the following parameters: - - [input]: [char list], it's the text that needs to be processed; - - [line]: [int], it's number of line in text where the parser is located; - - [inline]: [int], it's number of position in [line] where the parser is located. *) -type parser_state = - { input : char list - ; line : int - ; inline : int - } -[@@deriving show { with_path = false }] - -(** Result of parsing process - - [!] parse_result type parametrised by ['a] - which is type of value received upon successful completion of process - - It can be of three variants: - - [ParseSuccess]: successful completion - with not named parameters [{result: 'a; state: parser_state}]; - - [ParseError]: completion with a critical error - with not named parameters [{message: string; state: parser_state}]; - - [ParseFail]: completion without error and without parameters. *) -type 'a parse_result = - | ParseSuccess of 'a * parser_state - | ParseError of string * parser_state - | ParseFail -[@@deriving show { with_path = false }] - -(** Parser is function that receives certain [state] and returns the result of parsing *) -type 'a parser = parser_state -> 'a parse_result [@@deriving show { with_path = false }] - -(** Parser which always return [ParserFail] result *) -let pfail : _ parser = fun _ -> ParseFail - -(** Parser which always return [ParseError] result with [message] *) -let perror message : _ parser = fun state -> ParseError (message, state) - -(** Parser which always return [ParseSuccess] result with [value] *) -let preturn value : _ parser = fun state -> ParseSuccess (value, state) - -(** Parser combinator that allows to apply function to argument - - Use case: - [preturn (fun arg -> do_something(arg)) <*> some_parser] *) -let ( <*> ) : 'a 'b. ('a -> 'b) parser -> 'a parser -> 'b parser = - fun pfun parg state -> - match pfun state with - | ParseSuccess (f, st) -> - (match parg st with - | (ParseFail | ParseError _) as err -> err - | ParseSuccess (arg, st) -> preturn (f arg) st) - | (ParseFail | ParseError _) as err -> err -;; - -(** Parser combinator that allows to build parser from result of another parser *) -let ( >>= ) : 'a 'b. 'a parser -> ('a -> 'b parser) -> 'b parser = - fun p f state -> - match p state with - | (ParseFail | ParseError _) as err -> err - | ParseSuccess (res, st) -> f res st -;; - -(** Parser combinator that allows to ignore left result *) -let ( *> ) : 'a 'b. 'a parser -> 'b parser -> 'b parser = fun p1 p2 -> p1 >>= fun _ -> p2 - -(** Parser combinator that allows to ignore right result *) -let ( <* ) : 'a 'b. 'a parser -> 'b parser -> 'a parser = - fun p1 p2 -> p1 >>= fun res -> p2 >>= fun _ -> preturn res -;; - -(** Parser combinator that matches [*] in regular expressions (Kleene's star) *) -let rec many : 'a parser -> 'a list parser = - fun p state -> - match p state with - | ParseFail -> preturn [] state - | ParseError (msg, st) -> perror msg st - | ParseSuccess (res, st) -> (many p >>= fun tl -> preturn (res :: tl)) st -;; - -(** Parser combinator that matches [+] in regular expressions *) -let many1 p : _ list parser = p >>= fun x -> many p >>= fun xs -> preturn (x :: xs) - -(** Parser combinator that allows to get result as one of two parser *) -let ( <|> ) : 'a parser -> 'a parser -> 'a parser = - fun p1 p2 state -> - match p1 state with - | ParseFail -> p2 state - | (ParseError _ | ParseSuccess _) as final -> final -;; - -(** Parser combinator that allows to get result as one of two parser *) -let ( >>| ) : 'a 'b. 'a parser -> ('a -> 'b) -> 'b parser = - fun p f state -> - match p state with - | (ParseFail | ParseError _) as err -> err - | ParseSuccess (value, s) -> preturn (f value) s -;; - -(** Parser combinator that allows to get result as one of [N] parsers *) -let rec one_of : 'a parser list -> 'a parser = - fun plist state -> - match plist with - | p :: tl -> (p <|> one_of tl) state - | [] -> ParseFail -;; - -(** Char predicate is function for defining characters *) -type char_predicate = char -> bool [@@deriving show { with_path = false }] - -(** Char predicate to defining witespaces characters *) -let is_whitespace : char_predicate = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -(** Char predicate to defining digints characters *) -let is_digit : char_predicate = function - | '0' .. '9' -> true - | _ -> false -;; - -(** Char predicate to defining ASCII-letter characters *) -let is_ascci_letter : char_predicate = function - | 'a' .. 'z' | 'A' .. 'Z' -> true - | _ -> false -;; - -(** State chager is function that chage state on reading one symbols *) -type state_changer = char -> parser_state -> parser_state -[@@deriving show { with_path = false }] - -(** Default state changer *) -let default_schanger : state_changer = - fun sym state -> - match sym with - | '\n' -> { state with inline = 0; line = state.line + 1 } - | '\r' -> state - | _ -> { state with inline = state.inline + 1 } -;; - -(** Special parser function which read one character and processes it. - Processing sybfunctions as arguments: - - [condition]: [char_predicate], - it's predicate for defining characters to be processed; - - [converter]: [char -> 'a], it's function to processed character; - - [schanger]: [state_changer option], - it's option container to state chager function([state_changer]). - If [schanger] is [None] then will used [default_schanger] function; - - [state]: [parser_state], it's state of parser at beginning of reading character. - - [!] This parser returns also [ParseSuccess] or [ParseFail]*) -let rec satisfy - : char_predicate -> (char -> 'a) -> state_changer option -> parser_state - -> 'a parse_result - = - fun condition converter schanger state -> - match schanger with - | Some changer -> - (match state.input with - | sym :: tl when condition sym -> - preturn (converter sym) { (changer sym state) with input = tl } - | _ -> ParseFail) - | None -> satisfy condition converter (Some default_schanger) state -;; - -(** Default satisfy, it's satisfy function with default [state_changer]. - - [!] This parser returns also [ParseSuccess] or [ParseFail] *) -let dsatisfy : char_predicate -> (char -> 'a) -> parser_state -> 'a parse_result = - fun condition converter state -> satisfy condition converter None state -;; - -(** Satisfy to assert sympol *) -let asatisfy : (char -> bool) -> parser_state -> unit parse_result = - fun cond state -> - match state.input with - | sym :: _ when cond sym -> preturn () state - | _ -> pfail state -;; - -(** Check that [expected] character is found further in parsing text. - - [!] This chacker returns also [ParseSuccess] or [ParseFail] *) -let symbol expected = dsatisfy (( = ) expected) Fun.id - -(** Check that [expected] character sequence is found further in parsing text. - - [!] This chacker returns also [ParseSuccess] or [ParseFail] *) -let sequence expected = - let rec helper expected storage state = - match expected with - | sym :: tl -> - (match symbol sym state with - | ParseSuccess (value, new_state) -> - helper tl (List.append storage [ value ]) new_state - | _ -> ParseFail) - | _ -> preturn storage state - in - match expected with - | [] -> pfail - | _ -> helper expected [] -;; - -(** Check that [expected] string is found further in parsing text. - - [!] This checker returns also [ParseSuccess] or [ParseFail] *) -let ssequence expected = sequence (char_list_of_string expected) - -(** Special parser to skip whitespaces - - Returns: [unit parse_result] wich always [ParseSuccess] with updated state *) -let skip_ws state = - let rec helper st = - match dsatisfy is_whitespace is_whitespace st with - | ParseSuccess (is_ws, new_state) -> if is_ws then helper new_state else new_state - | _ -> st - in - preturn () (helper state) -;; - -(** Parser of digit character which convert it to integer in range from [0] to [9]. - - [!] This parser returns also [ParseSuccess] or [ParseFail] *) -let digit state = satisfy is_digit int_of_digit_char None state - -(** Parser for checking occurrence of char sequence in input data *) -let asequence expected = - sequence expected - >>= fun cl s -> - preturn () { s with input = List.append cl s.input; inline = s.inline - List.length cl } -;; - -(** Parser for checking occurrence of substring in input data *) -let assequence expected = asequence (char_list_of_string expected) - -(** Initialize started parser state *) -let init_parser_state (input_string : string) = - { input = char_list_of_string input_string; line = 1; inline = 0 } -;; - -(** Run parser [f] for input string *) -let parse f inputs = f (init_parser_state inputs) diff --git a/OCamlPolymorphicVariantsTypes/lib/parser_utility.mli b/OCamlPolymorphicVariantsTypes/lib/parser_utility.mli deleted file mode 100644 index dbc5244c2..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/parser_utility.mli +++ /dev/null @@ -1,60 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type parser_state = - { input : char list - ; line : int - ; inline : int - } -[@@deriving show { with_path = false }] - -type 'a parse_result = - | ParseSuccess of 'a * parser_state - | ParseError of string * parser_state - | ParseFail -[@@deriving show { with_path = false }] - -type 'a parser = parser_state -> 'a parse_result [@@deriving show { with_path = false }] - -val pfail : 'a parser -val perror : string -> 'a parser -val preturn : 'a -> 'a parser -val ( <*> ) : 'a 'b. ('a -> 'b) parser -> 'a parser -> 'b parser -val ( >>= ) : 'a 'b. 'a parser -> ('a -> 'b parser) -> 'b parser -val ( >>| ) : 'a 'b. 'a parser -> ('a -> 'b) -> 'b parser -val ( *> ) : 'a 'b. 'a parser -> 'b parser -> 'b parser -val ( <* ) : 'a 'b. 'a parser -> 'b parser -> 'a parser -val many : 'a parser -> 'a list parser -val many1 : 'a parser -> 'a list parser -val ( <|> ) : 'a parser -> 'a parser -> 'a parser -val one_of : 'a parser list -> 'a parser - -type char_predicate = char -> bool [@@deriving show { with_path = false }] - -val is_whitespace : char_predicate -val is_digit : char_predicate -val is_ascci_letter : char_predicate - -type state_changer = char -> parser_state -> parser_state -[@@deriving show { with_path = false }] - -val default_schanger : state_changer - -val satisfy - : char_predicate - -> (char -> 'a) - -> state_changer option - -> parser_state - -> 'a parse_result - -val dsatisfy : char_predicate -> (char -> 'a) -> parser_state -> 'a parse_result -val asatisfy : (char -> bool) -> parser_state -> unit parse_result -val symbol : char -> char parser -val sequence : char list -> char list parser -val ssequence : string -> char list parser -val skip_ws : unit parser -val digit : parser_state -> int parse_result -val asequence : char list -> unit parser -val assequence : string -> unit parser -val parse : 'a parser -> string -> 'a parse_result diff --git a/OCamlPolymorphicVariantsTypes/lib/printer.ml b/OCamlPolymorphicVariantsTypes/lib/printer.ml deleted file mode 100644 index eabe21aa9..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/printer.ml +++ /dev/null @@ -1,13 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Parser_utility - -(** Convert custom parse result to string view *) -let string_of_parse_result converter = function - | ParseFail -> "Parse process failed" - | ParseError (msg, state) -> - Printf.sprintf "ParseError(line=%d pos=%d): %s" state.line state.inline msg - | ParseSuccess (r, _) -> converter r -;; diff --git a/OCamlPolymorphicVariantsTypes/lib/printer.mli b/OCamlPolymorphicVariantsTypes/lib/printer.mli deleted file mode 100644 index 5fd594643..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/printer.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Parser_utility - -val string_of_parse_result : ('a -> string) -> 'a parse_result -> string diff --git a/OCamlPolymorphicVariantsTypes/lib/utils.ml b/OCamlPolymorphicVariantsTypes/lib/utils.ml deleted file mode 100644 index 725d9bdea..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/utils.ml +++ /dev/null @@ -1,17 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** Converter digit character value to integer value in range from [0] to [9] *) -let int_of_digit_char symbol = int_of_char symbol - int_of_char '0' - -(** Converter string value to list of characters *) -let char_list_of_string s = List.of_seq (String.to_seq s) - -(** Converter list of characters value to string *) -let string_of_char_list char_list = String.of_seq (List.to_seq char_list) - -let is_empty = function - | [] -> true - | _ -> false -;; diff --git a/OCamlPolymorphicVariantsTypes/lib/utils.mli b/OCamlPolymorphicVariantsTypes/lib/utils.mli deleted file mode 100644 index 4efd7809c..000000000 --- a/OCamlPolymorphicVariantsTypes/lib/utils.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val int_of_digit_char : char -> int -val char_list_of_string : string -> char list -val string_of_char_list : char list -> string -val is_empty : 'a list -> bool diff --git a/OCamlPolymorphicVariantsTypes/tests/dune b/OCamlPolymorphicVariantsTypes/tests/dune deleted file mode 100644 index 781187c59..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/dune +++ /dev/null @@ -1,12 +0,0 @@ -(library - (name tests) - (libraries miniml) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (instrumentation - (backend bisect_ppx)) - (inline_tests)) - -(cram - (applies_to interpret_tests) - (deps ../bin/REPL.exe ./factorial.test ./invalid-factorial.test)) diff --git a/OCamlPolymorphicVariantsTypes/tests/factorial.test b/OCamlPolymorphicVariantsTypes/tests/factorial.test deleted file mode 100644 index c36bc5706..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/factorial.test +++ /dev/null @@ -1,2 +0,0 @@ -let rec factorial n = if (n > 1) then n * factorial(n-1) else 1;; -factorial 5;; diff --git a/OCamlPolymorphicVariantsTypes/tests/interpret_tests.t b/OCamlPolymorphicVariantsTypes/tests/interpret_tests.t deleted file mode 100644 index 813588a40..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/interpret_tests.t +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2024-2027, Ilia Suponev -SPDX-License-Identifier: CC0-1.0 - - $ ../bin/REPL.exe -i=factorial.test - - $ ../bin/REPL.exe -dparsetree -i=factorial.test - [(DefineItem - (Recursive, - [((PVar "factorial"), - (Lambda ([(PVar "n")], - (If ((Binary ((Variable "n"), Gt, (Const (IntLiteral 1)))), - (Binary ((Variable "n"), Multiply, - (Apply ((Variable "factorial"), - [(Binary ((Variable "n"), Subtract, (Const (IntLiteral 1)) - )) - ] - )) - )), - (Some (Const (IntLiteral 1))))) - ))) - ])); - (EvalItem (Apply ((Variable "factorial"), [(Const (IntLiteral 5))])))] - - $ ../bin/REPL.exe -i=invalid-factorial.test - ParseError(line=1 pos=66): Not found expression after keyword 'in' of let-xpression diff --git a/OCamlPolymorphicVariantsTypes/tests/invalid-factorial.test b/OCamlPolymorphicVariantsTypes/tests/invalid-factorial.test deleted file mode 100644 index 792989a15..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/invalid-factorial.test +++ /dev/null @@ -1 +0,0 @@ -let rec factorial n = if (n > 1) then n * factorial(n-1) else 1 in ;; diff --git a/OCamlPolymorphicVariantsTypes/tests/parser_tests.ml b/OCamlPolymorphicVariantsTypes/tests/parser_tests.ml deleted file mode 100644 index 37c4dedfc..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/parser_tests.ml +++ /dev/null @@ -1,263 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Miniml.Ast -open Miniml.Parser -open Miniml.Parser_utility -open Miniml.Printer - -let test conv p input = print_string (string_of_parse_result conv (parse p input)) -let test_program = test show_program program_parser - -let%expect_test _ = - test_program {|if f x then g 10;;|}; - [%expect - {| - [(EvalItem - (If ((Apply ((Variable "f"), [(Variable "x")])), - (Apply ((Variable "g"), [(Const (IntLiteral 10))])), None))) - ] |}]; - test_program {|iff x then g 10;;|}; - [%expect {| [] |}]; - test_program {|if f x theng 10;;|}; - [%expect {| ParseError(line=1 pos=15): Not found 'then' branch for if-expression |}]; - test_program {|if f x then g 10 else ~-10;;|}; - [%expect - {| - [(EvalItem - (If ((Apply ((Variable "f"), [(Variable "x")])), - (Apply ((Variable "g"), [(Const (IntLiteral 10))])), - (Some (Unary (Negate, (Const (IntLiteral 10)))))))) - ] |}]; - test_program {|if f x then g 10 else~-10;;|}; - [%expect - {| - [(EvalItem - (If ((Apply ((Variable "f"), [(Variable "x")])), - (Apply ((Variable "g"), [(Const (IntLiteral 10))])), - (Some (Unary (Negate, (Const (IntLiteral 10)))))))) - ] |}]; - test_program {|if f x then g 10 else(~-10);;|}; - [%expect - {| - [(EvalItem - (If ((Apply ((Variable "f"), [(Variable "x")])), - (Apply ((Variable "g"), [(Const (IntLiteral 10))])), - (Some (Unary (Negate, (Const (IntLiteral 10)))))))) - ] |}]; - test_program {|1+(f x y) - (g x-y);;|}; - [%expect - {| - [(EvalItem - (Binary ( - (Binary ((Const (IntLiteral 1)), Add, - (Apply ((Variable "f"), [(Variable "x"); (Variable "y")])))), - Subtract, - (Apply ((Variable "g"), - [(Variable "x"); (Unary (Negate, (Variable "y")))])) - ))) - ] |}]; - test_program {|(1,);;|}; - [%expect - {| ParseError(line=1 pos=3): Not found expression after tuple separator: ',' |}]; - test_program {|(1;);;|}; - [%expect {| [(EvalItem (Const (IntLiteral 1)))] |}]; - test_program {|((1,2);(3,4));;|}; - [%expect - {| - [(EvalItem - (ExpressionBlock - [(Tuple [(Const (IntLiteral 1)); (Const (IntLiteral 2))]); - (Tuple [(Const (IntLiteral 3)); (Const (IntLiteral 4))])])) - ] |}]; - test_program {| ( 1 , ( 2 ; 3 ) , 4 ) ;;|}; - [%expect - {| - [(EvalItem - (Tuple - [(Const (IntLiteral 1)); - (ExpressionBlock [(Const (IntLiteral 2)); (Const (IntLiteral 3))]); - (Const (IntLiteral 4))])) - ] |}]; - test_program {| 1 , 2 ; 3 , 4 ;;|}; - [%expect - {| - [(EvalItem - (ExpressionBlock - [(Tuple [(Const (IntLiteral 1)); (Const (IntLiteral 2))]); - (Tuple [(Const (IntLiteral 3)); (Const (IntLiteral 4))])])) - ] |}]; - test_program {|(1,2);3,4;;|}; - [%expect - {| - [(EvalItem - (ExpressionBlock - [(Tuple [(Const (IntLiteral 1)); (Const (IntLiteral 2))]); - (Tuple [(Const (IntLiteral 3)); (Const (IntLiteral 4))])])) - ] |}]; - test_program {|(let f x = -x in f) 10;;|}; - [%expect - {| - [(EvalItem - (Apply ( - (Define ( - (Nonrecursive, - [((PVar "f"), - (Lambda ([(PVar "x")], (Unary (Negate, (Variable "x"))))))]), - (Variable "f"))), - [(Const (IntLiteral 10))]))) - ] |}]; - test_program {|(let f x = -x in f 10);;|}; - [%expect - {| - [(EvalItem - (Define ( - (Nonrecursive, - [((PVar "f"), - (Lambda ([(PVar "x")], (Unary (Negate, (Variable "x"))))))]), - (Apply ((Variable "f"), [(Const (IntLiteral 10))]))))) - ] |}]; - test_program - {| - let rec factorial n = if (n > 1) then n * factorial(n-1) else 1;; - factorial 5;; - |}; - [%expect - {| - [(DefineItem - (Recursive, - [((PVar "factorial"), - (Lambda ([(PVar "n")], - (If ((Binary ((Variable "n"), Gt, (Const (IntLiteral 1)))), - (Binary ((Variable "n"), Multiply, - (Apply ((Variable "factorial"), - [(Binary ((Variable "n"), Subtract, (Const (IntLiteral 1)) - )) - ] - )) - )), - (Some (Const (IntLiteral 1))))) - ))) - ])); - (EvalItem (Apply ((Variable "factorial"), [(Const (IntLiteral 5))])))] |}]; - test_program - {| - let rec f x = - if x > 0 then x + (g (x-1)) else 0 - and g x = - (f (x / 2)) - x - ;; - |}; - [%expect - {| - [(DefineItem - (Recursive, - [((PVar "f"), - (Lambda ([(PVar "x")], - (If ((Binary ((Variable "x"), Gt, (Const (IntLiteral 0)))), - (Binary ((Variable "x"), Add, - (Apply ((Variable "g"), - [(Binary ((Variable "x"), Subtract, (Const (IntLiteral 1)) - )) - ] - )) - )), - (Some (Const (IntLiteral 0))))) - ))); - ((PVar "g"), - (Lambda ([(PVar "x")], - (Binary ( - (Apply ((Variable "f"), - [(Binary ((Variable "x"), Division, (Const (IntLiteral 2)))) - ] - )), - Subtract, (Variable "x"))) - ))) - ])) - ] |}]; - test_program - {| - let t1 = (1,2,3, f x);; - let t2 = (print_endline (f -y); (not x) && g (x = y));; - (t1, t2);; - |}; - [%expect - {| - [(DefineItem - (Nonrecursive, - [((PVar "t1"), - (Tuple - [(Const (IntLiteral 1)); (Const (IntLiteral 2)); - (Const (IntLiteral 3)); - (Apply ((Variable "f"), [(Variable "x")]))])) - ])); - (DefineItem - (Nonrecursive, - [((PVar "t2"), - (ExpressionBlock - [(Apply ((Variable "print_endline"), - [(Binary ((Variable "f"), Subtract, (Variable "y")))])); - (Binary ((Apply ((Variable "not"), [(Variable "x")])), And, - (Apply ((Variable "g"), - [(Binary ((Variable "x"), Equals, (Variable "y")))])) - )) - ])) - ])); - (EvalItem (Tuple [(Variable "t1"); (Variable "t2")]))] |}]; - test_program - {| - let t1 = 1,2,3, f x;; - let t2 = print_endline (f -y); (not x) && g (x = y);; - t1, t2;; - |}; - [%expect - {| - [(DefineItem - (Nonrecursive, - [((PVar "t1"), - (Tuple - [(Const (IntLiteral 1)); (Const (IntLiteral 2)); - (Const (IntLiteral 3)); - (Apply ((Variable "f"), [(Variable "x")]))])) - ])); - (DefineItem - (Nonrecursive, - [((PVar "t2"), - (ExpressionBlock - [(Apply ((Variable "print_endline"), - [(Binary ((Variable "f"), Subtract, (Variable "y")))])); - (Binary ((Apply ((Variable "not"), [(Variable "x")])), And, - (Apply ((Variable "g"), - [(Binary ((Variable "x"), Equals, (Variable "y")))])) - )) - ])) - ])); - (EvalItem (Tuple [(Variable "t1"); (Variable "t2")]))] |}]; - test_program {| - let f = fun x -> fun y -> x / (y - 2);; - f ~-x ~-(f 10 30);; - |}; - [%expect - {| - [(DefineItem - (Nonrecursive, - [((PVar "f"), - (Lambda ([(PVar "x")], - (Lambda ([(PVar "y")], - (Binary ((Variable "x"), Division, - (Binary ((Variable "y"), Subtract, (Const (IntLiteral 2)))))) - )) - ))) - ])); - (EvalItem - (Apply ((Variable "f"), - [(Unary (Negate, (Variable "x"))); - (Unary (Negate, - (Apply ((Variable "f"), - [(Const (IntLiteral 10)); (Const (IntLiteral 30))])) - )) - ] - ))) - ] |}] -;; diff --git a/OCamlPolymorphicVariantsTypes/tests/parser_tests.mli b/OCamlPolymorphicVariantsTypes/tests/parser_tests.mli deleted file mode 100644 index 8c57c88e4..000000000 --- a/OCamlPolymorphicVariantsTypes/tests/parser_tests.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2027, Ilia Suponev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPrintf/.envrc b/OCamlPrintf/.envrc deleted file mode 100644 index 686a37170..000000000 --- a/OCamlPrintf/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) diff --git a/OCamlPrintf/.gitignore b/OCamlPrintf/.gitignore deleted file mode 100644 index 502e9e9de..000000000 --- a/OCamlPrintf/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs -.vscode/ -*.DS_Store diff --git a/OCamlPrintf/.ocamlformat b/OCamlPrintf/.ocamlformat deleted file mode 100644 index 6a7d1e559..000000000 --- a/OCamlPrintf/.ocamlformat +++ /dev/null @@ -1,3 +0,0 @@ -profile=janestreet -version=0.26.2 -max-indent=2 diff --git a/OCamlPrintf/.zanuda b/OCamlPrintf/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/OCamlPrintf/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/OCamlPrintf/COPYING b/OCamlPrintf/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/OCamlPrintf/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OCamlPrintf/COPYING.CC0 b/OCamlPrintf/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/OCamlPrintf/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/OCamlPrintf/COPYING.LESSER b/OCamlPrintf/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/OCamlPrintf/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/OCamlPrintf/Makefile b/OCamlPrintf/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/OCamlPrintf/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/OCamlPrintf/OCamlPrintf.opam b/OCamlPrintf/OCamlPrintf.opam deleted file mode 100644 index f2cc5159a..000000000 --- a/OCamlPrintf/OCamlPrintf.opam +++ /dev/null @@ -1,43 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "OCaml interpreter with support for printf" -description: "OCaml interpreter with support for printf" -maintainer: [ - "Maxim Rodionov " - "Vladimir Zaikin " -] -authors: [ - "Maxim Rodionov " - "Vladimir Zaikin " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/RodionovMaxim05/OCamlPrintf" -bug-reports: "https://github.com/RodionovMaxim05/OCamlPrintf" -depends: [ - "dune" {>= "3.7"} - "base" - "angstrom" - "qcheck-core" - "ppx_inline_test" {with-test} - "ppx_deriving" - "ppx_deriving_qcheck" - "ppx_expect" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OCamlPrintf/README.md b/OCamlPrintf/README.md deleted file mode 100644 index 1c7d056d6..000000000 --- a/OCamlPrintf/README.md +++ /dev/null @@ -1,67 +0,0 @@ - - -# OCamlPrintf - -`OCaml` interpreter with support for printf. - -#### MiniML - -- Standard data types: `bool`, `int`, `tuples`, `list` and `option`; -- Recursive functions; -- Comparisons of numbers and other arithmetic; -- Standard functions. - -#### Printf - -- Support for char, string types and operations with them; -- Support the formatted printing function. - -## Progress - -- [x] [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) - - [x] Factorial - - [x] MiniML -- [x] Parser - - [x] Factorial - - [x] MiniML -- [x] [REPL](https://en.wikipedia.org/wiki/Read–eval–print_loop) -- [x] Pretty Printer -- [x] [Quick Checker](https://en.wikipedia.org/wiki/QuickCheck) - - [x] Manual - - [x] Auto -- [x] Shrinker -- [x] Type Checker -- [x] Interpreter -- [ ] Support for char, string types and operations with them - - [x] Types - - [x] Comparison - - [x] Concatenation -- [ ] Support the formatted printing function - -## Build - -```shell -cd OCamlPrintf/ -dune build # Build the project. -``` - -## Run - -```shell -dune runtest # Run all tests. -dune exec -- repl/REPL.exe -dparsetree -fromfile tests/factorial.txt # Run parser tests and see AST. -dune exec -- tests/run_qchecker.exe -v # Run qchecker tests with verbose mode. -dune exec -- repl/REPL.exe -inference # Run inferencer in REPL. -dune exec repl/REPL.exe # Run interpreter. -``` - -## Authors - -- [@Friend-zva](https://github.com/Friend-zva) (Vladimir Zaikin) -- [@RodionovMaxim05](https://github.com/RodionovMaxim05) (Maxim Rodionov) - -## License - -Distributed under the GNU GENERAL PUBLIC LICENSE. See [lisence](COPYING) for more information. - -

(back to top)

diff --git a/OCamlPrintf/dune b/OCamlPrintf/dune deleted file mode 100644 index 98e54536a..000000000 --- a/OCamlPrintf/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/OCamlPrintf/dune-project b/OCamlPrintf/dune-project deleted file mode 100644 index 15cfa3871..000000000 --- a/OCamlPrintf/dune-project +++ /dev/null @@ -1,38 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors - "Maxim Rodionov " - "Vladimir Zaikin ") - -(maintainers - "Maxim Rodionov " - "Vladimir Zaikin ") - -(bug_reports "https://github.com/RodionovMaxim05/OCamlPrintf") - -(homepage "https://github.com/RodionovMaxim05/OCamlPrintf") - -(package - (name OCamlPrintf) - (synopsis "OCaml interpreter with support for printf") - (description "OCaml interpreter with support for printf") - ; (documentation "https://kakadu.github.io/fp2024/docs/OCamlPrintf") - (version 0.1) - (depends - dune - base - angstrom - qcheck-core - (ppx_inline_test :with-test) - ppx_deriving - ppx_deriving_qcheck - ppx_expect - bisect_ppx - (odoc :with-doc) - (ocamlformat :build))) diff --git a/OCamlPrintf/lib/ast.ml b/OCamlPrintf/lib/ast.ml deleted file mode 100644 index f3db03265..000000000 --- a/OCamlPrintf/lib/ast.ml +++ /dev/null @@ -1,279 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open QCheck.Gen - -let coef = 10 (* For the generator's speed. *) -let min_range = int_range 0 10 (* For the generator's speed. *) -let gen_string gen = string_size min_range ~gen -let gen_list gen = list_size min_range gen - -type 'a list_ = ('a list[@gen gen_list gen_a]) -[@@deriving show { with_path = false }, qcheck] - -let gen_char = - (* Exception quotation marks and backslash. *) - oneof [ return '!'; char_range '#' '&'; char_range '(' '['; char_range ']' '~' ] -;; - -let un_op_list = [ "~-", 1 ] - -let bin_op_list = - [ "*", 1 - ; "/", 1 - ; "+", 2 - ; "-", 2 - ; "^", 3 - ; ">=", 4 - ; "<=", 4 - ; "<>", 4 - ; "=", 4 - ; ">", 4 - ; "<", 4 - ; "&&", 5 - ; "||", 6 - ] -;; - -let is_operator opr = List.exists (fun (str, _) -> str = opr) bin_op_list -let is_negative_op opr = List.exists (fun (str, _) -> str = opr) un_op_list -let get_priority opr = List.assoc opr bin_op_list - -let is_keyword = function - | "and" - | "else" - | "false" - | "fun" - | "if" - | "in" - | "let" - | "function" - | "match" - | "rec" - | "then" - | "true" - | "with" - | "Some" - | "None" -> true - | _ -> false -;; - -let gen_ident = - let gen_id = - map2 - (fun fst_char rest_str -> - match Base.Char.to_string fst_char ^ rest_str with - | "_" -> "id" - | id -> id) - (oneof [ char_range 'a' 'z'; return '_' ]) - (gen_string - (oneof - [ char_range '0' '9' - ; char_range 'A' 'Z' - ; char_range 'a' 'z' - ; return '_' - ; return '\'' - ])) - in - gen_id >>= fun id -> if is_keyword id then gen_id else return id -;; - -type ident = (string[@gen gen_ident]) [@@deriving show { with_path = false }, qcheck] - -type rec_flag = - | Recursive - | Nonrecursive -[@@deriving show { with_path = false }, qcheck] - -type constant = - | Const_integer of (int[@gen nat]) - | Const_char of (char[@gen gen_char]) - | Const_string of (string[@gen gen_string gen_char]) -[@@deriving show { with_path = false }, qcheck] - -let gen_type_var = - let gen_type_var = - map3 - (fun fst_char snd_char rest_str -> - Printf.sprintf "%c%c%s" fst_char snd_char rest_str) - (oneof [ char_range 'a' 'z' ]) - (oneof [ char_range '0' '9'; char_range 'A' 'Z'; char_range 'a' 'z'; return '_' ]) - (gen_string - (oneof - [ char_range '0' '9' - ; char_range 'A' 'Z' - ; char_range 'a' 'z' - ; return '_' - ; return '\'' - ])) - in - gen_type_var - >>= fun type_var -> if is_keyword type_var then gen_type_var else return ("'" ^ type_var) -;; - -type core_type = - | Type_unit - | Type_char - | Type_int - | Type_string - | Type_bool - | Type_option of (core_type[@gen gen_core_type_sized (n / coef)]) - | Type_var of (ident[@gen gen_type_var]) - | Type_list of (core_type[@gen gen_core_type_sized (n / coef)]) - | Type_tuple of - (core_type[@gen gen_core_type_sized (n / coef)]) - * (core_type[@gen gen_core_type_sized (n / coef)]) - * (core_type[@gen gen_core_type_sized (n / coef)]) list_ - | Type_arrow of - (core_type[@gen gen_core_type_sized (n / coef)]) - * (core_type[@gen gen_core_type_sized (n / coef)]) -[@@deriving show { with_path = false }, qcheck] - -let gen_construct gen n tuple construct = - oneof - [ return ("()", None) - ; return ("true", None) - ; return ("false", None) - ; return ("None", None) - ; map (fun i -> "Some", Some i) (gen (n / coef)) - ; (let rec gen_list n = - if n = 0 - then return ("[]", None) - else ( - let element = gen 0 in - let tail = gen_list (n / coef) in - map2 (fun e t -> "::", Some (tuple (e, construct t, []))) element tail) - in - gen_list n) - ] -;; - -type pattern = - | Pat_any - | Pat_var of ident - | Pat_constant of constant - | Pat_tuple of - (pattern[@gen gen_pattern_sized (n / coef)]) - * (pattern[@gen gen_pattern_sized (n / coef)]) - * (pattern[@gen gen_pattern_sized (n / coef)]) list_ - | Pat_construct of - ((ident * pattern option) - [@gen - gen_construct - gen_pattern_sized - n - (fun (fst_pat, snd_pat, pat_list) -> Pat_tuple (fst_pat, snd_pat, pat_list)) - (fun (id, pat_opt) -> Pat_construct (id, pat_opt))]) - | Pat_constraint of (pattern[@gen gen_pattern_sized (n / coef)]) * core_type -[@@deriving show { with_path = false }, qcheck] - -type 'exp value_binding = - { pat : pattern - ; exp : 'exp - } -[@@deriving show { with_path = false }, qcheck] - -type 'exp case = - { left : pattern - ; right : 'exp - } -[@@deriving show { with_path = false }, qcheck] - -module Expression = struct - let gen_value_binding gen n fix_exp_fun = - oneof - [ map2 (fun var exp -> { pat = Pat_var var; exp }) gen_ident (gen (n / coef)) - ; map3 - (fun id type' exp -> { pat = Pat_constraint (Pat_var id, type'); exp }) - gen_ident - gen_core_type - (gen (n / coef)) - ; map2 (fun pat exp -> { pat; exp = fix_exp_fun exp }) gen_pattern (gen (n / coef)) - ] - ;; - - let gen_exp_apply gen n exp_ident exp_apply = - oneof - [ map2 (fun id arg -> exp_ident id, arg) gen_ident (gen (n / coef)) - ; map2 - (fun opr opn -> opr, opn) - (oneofl (List.map (fun (opr, _) -> exp_ident opr) un_op_list)) - (gen (n / coef)) - ; map3 - (fun opr opn1 opn2 -> opr, exp_apply (opn1, opn2)) - (oneofl (List.map (fun (opr, _) -> exp_ident opr) bin_op_list)) - (gen (n / coef)) - (gen (n / coef)) - ] - ;; - - type value_binding_exp = - (t value_binding - [@gen - gen_value_binding - gen_sized - n - (let rec fix_exp_fun = function - | Exp_fun (_, _, exp) -> fix_exp_fun exp - | Exp_function ({ left = _; right = exp }, _) -> fix_exp_fun exp - | Exp_constraint (exp, type') -> Exp_constraint (fix_exp_fun exp, type') - | exp -> exp - in - fix_exp_fun)]) - - and case_exp = - (t case - [@gen map2 (fun left right -> { left; right }) gen_pattern (gen_sized (n / coef))]) - - and t = - | Exp_ident of ident - | Exp_constant of constant - | Exp_let of - rec_flag - * value_binding_exp - * value_binding_exp list_ - * (t[@gen gen_sized (n / coef)]) - | Exp_fun of pattern * pattern list_ * (t[@gen gen_sized (n / coef)]) - | Exp_apply of - ((t * t) - [@gen - gen_exp_apply - gen_sized - n - (fun id -> Exp_ident id) - (fun (opn1, opn2) -> Exp_apply (opn1, opn2))]) - | Exp_function of case_exp * case_exp list_ - | Exp_match of (t[@gen gen_sized (n / coef)]) * case_exp * case_exp list_ - | Exp_ifthenelse of - (t[@gen gen_sized (n / coef)]) - * (t[@gen gen_sized (n / coef)]) - * (t[@gen gen_sized (n / coef)]) option - | Exp_tuple of - (t[@gen gen_sized (n / coef)]) - * (t[@gen gen_sized (n / coef)]) - * (t[@gen gen_sized (n / coef)]) list_ - | Exp_construct of - ((ident * t option) - [@gen - gen_construct - gen_sized - n - (fun (fst_exp, snd_exp, exp_list) -> Exp_tuple (fst_exp, snd_exp, exp_list)) - (fun (id, exp_opt) -> Exp_construct (id, exp_opt))]) - | Exp_sequence of (t[@gen gen_sized (n / coef)]) * (t[@gen gen_sized (n / coef)]) - | Exp_constraint of (t[@gen gen_sized (n / coef)]) * core_type - [@@deriving show { with_path = false }, qcheck] -end - -let show_value_binding = Expression.show_value_binding_exp -let show_case = Expression.show_case_exp -let show_expression = Expression.show - -type structure_item = - | Struct_eval of Expression.t - | Struct_value of - rec_flag * Expression.value_binding_exp * Expression.value_binding_exp list_ -[@@deriving show { with_path = false }, qcheck] - -type structure = structure_item list_ [@@deriving show { with_path = false }, qcheck] diff --git a/OCamlPrintf/lib/ast.mli b/OCamlPrintf/lib/ast.mli deleted file mode 100644 index 3e6285659..000000000 --- a/OCamlPrintf/lib/ast.mli +++ /dev/null @@ -1,149 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type 'a list_ = 'a list - -val show_list_ : (Format.formatter -> 'a -> unit) -> 'a list_ -> string - -(** Identifier *) -type ident = string - -val show_ident : ident -> string -val un_op_list : (ident * int) list -val bin_op_list : (ident * int) list -val get_priority : string -> int -val is_operator : string -> bool -val is_negative_op : string -> bool -val is_keyword : ident -> bool - -type rec_flag = - | Recursive (** Recursive value binding. *) - | Nonrecursive (** Nonrecursive value binding. *) - -val show_rec_flag : rec_flag -> string - -type constant = - | Const_integer of int (** A constant integer such as [1]. *) - | Const_char of char (** A constant character such as ['a']. *) - | Const_string of string (** A constant string such as ["const"]. *) - -val show_constant : constant -> string - -type core_type = - | Type_unit (** The type [unit]. *) - | Type_char (** The type [char]. *) - | Type_int (** The type [int]. *) - | Type_string (** The type [string]. *) - | Type_bool (** The type [bool]. *) - | Type_option of core_type (** [Type_option(T)] represents [T option]. *) - | Type_var of ident (** [Type_var(T)] represents [T](a variable type such as ['a]). *) - | Type_list of core_type (** [Type_list(T)] represents [T list]. *) - | Type_tuple of core_type * core_type * core_type list_ - (** [Type_tuple(T1, T2, [T3; ... ; Tn])] represents [T1 * ... * Tn]. *) - | Type_arrow of core_type * core_type (** [Type_arrow(T1, T2)] represents [T1 -> T2]. *) - -val show_core_type : core_type -> string - -type pattern = - | Pat_any (** [Pat_any] represents [_]. *) - | Pat_var of ident (** [Pat_var(I)] represents [I](a variable pattern such as [x]). *) - | Pat_constant of constant - (** [Pat_constant(C)] represents [C](a pattern such as [1], ['a'], ["const"]). *) - | Pat_tuple of pattern * pattern * pattern list_ - (** [Pat_tuple(P1, P2, [P3; ... ; Pn])] represents [(P1, ... , Pn)]. *) - | Pat_construct of (ident * pattern option) - (** [Pat_construct(I, pat)] represents - - [()] when [I] is ["()"] and [pat] is [None], - - [false] when [I] is ["false"] and [pat] is [None], - - [true] when [I] is ["true"] and [pat] is [None], - - [None] when [I] is ["None"] and [pat] is [None], - - [Some P] when [I] is ["Some"] and [pat] is [Some P], - - [[]] when [I] is ["[]"] and [pat] is [None], - - [[ P ]] when [I] is ["::"] and [pat] is - [Some (Pat_tuple(P, Pat_construct("[]", None), []))], - - [[ P1; P2; ... ]] when [I] is ["::"] and [pat] is - [Some (Pat_tuple(P1, Pat_construct("::", Some (Pat_tuple(P2, Pat_construct("::", ...), []))), []))]. *) - | Pat_constraint of pattern * core_type - (** [Pat_constraint(P, T)] represents [P : T]. *) - -val show_pattern : pattern -> string - -(** [{P; E}] represents [let P = E]. *) -type 'exp value_binding = - { pat : pattern - ; exp : 'exp - } - -(** [{P; E}] represents [P -> E]. *) -type 'exp case = - { left : pattern - ; right : 'exp - } - -module Expression : sig - type value_binding_exp = t value_binding - and case_exp = t case - - and t = - | Exp_ident of ident (** [Exp_ident(I)] represents [I](an identifier such as [x]). *) - | Exp_constant of constant - (** [Exp_constant(C)] represents [C](an expression such as [1], ['a'], ["const"]). *) - | Exp_let of rec_flag * value_binding_exp * value_binding_exp list_ * t - (** [Exp_let(flag, {P1; E1}, [{P2; E2}; ... ; {Pn; En}], E)] represents - - [let P1 = E1 and P2 = E2 and ... and Pn = En in E] when [flag] is [Nonrecursive], - - [let rec P1 = E1 and P2 = E2 and ... and Pn = En in E] when [flag] is [Recursive]. *) - | Exp_fun of pattern * pattern list_ * t - (** [Exp_fun(P1, [P2; ... ; Pn], E)] represents [fun P1 ... Pn -> E] *) - | Exp_apply of (t * t) - (** [Exp_apply(Exp_ident(I), E)] represents [I E] when [I] from [un_op_list], - [Exp_apply(Exp_ident(I), Exp_apply(E1, E2))] represents [E1 I E2] when [I] from [bin_op_list], - [Exp_apply(Exp_ident(I), E)] represents [I E], - [Exp_apply(Exp_ident(I), Exp_apply(E1, Exp_apply(E2, ...)))] represents [I E1 E2 ... ]. *) - | Exp_function of case_exp * case_exp list_ - (** [Exp_function({P1; E1}, [{P2; E2}; ... ; {Pn; En}])] represents - [function P1 -> E1 | P2 -> E2 | ... | Pn -> En]. *) - | Exp_match of t * case_exp * case_exp list_ - (** [Exp_match(E, {P1; E1}, [{P2; E2}; ... ; {Pn; En}])] represents - [match E with P1 -> E1 | P2 -> E2 | ... | Pn -> En]. *) - | Exp_ifthenelse of t * t * t option - (** [Exp_ifthenelse(E1, E2, opt)] represents - - [if E1 then E2] when [opt] is [None], - - [if E1 then E2 else E3] when [opt] is [Some E3]. *) - | Exp_tuple of t * t * t list_ - (** [Exp_tuple(E1, E2, [E3; ... ; En])] represents [(E1, ... , En)]. *) - | Exp_construct of (ident * t option) - (** [Exp_construct(I, exp)] represents - - [()] when [I] is ["()"] and [exp] is [None], - - [false] when [I] is ["false"] and [exp] is [None], - - [true] when [I] is ["true"] and [exp] is [None], - - [None] when [I] is ["None"] and [exp] is [None], - - [Some E] when [I] is ["Some"] and [exp] is [Some E], - - [[]] when [I] is ["[]"] and [exp] is [None], - - [[ E ]] when [I] is ["::"] and [exp] is - [Some (Exp_tuple(E, Exp_construct("[]", None), []))], - - [[ E1; E2; ... ]] when [I] is ["::"] and [exp] is - [Some (Exp_tuple(E1, Exp_construct("::", Some (Exp_tuple(E2, Exp_construct("::", ...), []))), []))]. *) - | Exp_sequence of t * t (** [Exp_sequence(E1, E2)] represents [E1; E2]. *) - | Exp_constraint of t * core_type (** [Exp_constraint(E, T)] represents [(E : T)]. *) -end - -val show_value_binding : Expression.value_binding_exp -> string -val show_case : Expression.case_exp -> string -val show_expression : Expression.t -> ident - -type structure_item = - | Struct_eval of Expression.t (** [Struct_eval(E)] represents [E]. *) - | Struct_value of - rec_flag * Expression.value_binding_exp * Expression.value_binding_exp list_ - (** [Struct_value(flag, {P1; E1}, [{P2; E2}; ... ; {Pn; En}], E)] represents - - [let P1 = E1 and P2 = E2 and ... and Pn = En in E] when [flag] is [Nonrecursive], - - [let rec P1 = E1 and P2 = E2 and ... and Pn = En in E] when [flag] is [Recursive]. *) - -val show_structure_item : structure_item -> string - -type structure = structure_item list_ - -val show_structure : structure -> string -val gen_structure : structure QCheck.Gen.t -val arb_structure : structure QCheck.arbitrary diff --git a/OCamlPrintf/lib/dune b/OCamlPrintf/lib/dune deleted file mode 100644 index ae8f0e32a..000000000 --- a/OCamlPrintf/lib/dune +++ /dev/null @@ -1,8 +0,0 @@ -(library - (name ocaml_printf_lib) - (public_name OCamlPrintf.Lib) - (libraries base angstrom qcheck-core qcheck-core.runner) - (preprocess - (pps ppx_deriving.show ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlPrintf/lib/inferencer.ml b/OCamlPrintf/lib/inferencer.ml deleted file mode 100644 index 3c43950ab..000000000 --- a/OCamlPrintf/lib/inferencer.ml +++ /dev/null @@ -1,821 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `No_variable_rec - | `No_arg_rec - | `Bound_several_times of string - | `Occurs_check of string * core_type - | `No_variable of string - | `Unification_failed of core_type * core_type - ] - -let pp_error ppf : error -> _ = function - | `No_variable_rec -> - Format.fprintf ppf "Only variables are allowed as left-hand side of `let rec'" - | `No_arg_rec -> - Format.fprintf - ppf - "This kind of expression is not allowed as right-hand side of `let rec'" - | `Bound_several_times id -> - Format.fprintf ppf "Variable '%s' is bound several times in the matching" id - | `Occurs_check (id, ty) -> - Format.fprintf - ppf - "Occurs check failed: the type variable %s occurs inside %a" - id - Pprinter.pp_core_type - ty - | `No_variable id -> Format.fprintf ppf "Undefined variable '%s'" id - | `Unification_failed (l, r) -> - Format.fprintf - ppf - "Unification failed on %a and %a" - Pprinter.pp_core_type - l - Pprinter.pp_core_type - r -;; - -module State = struct - open Base - - type 'a t = int -> int * ('a, error) Result.t - - let return x state = state, Result.return x - let fail e state = state, Result.fail e - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> f result state - | state, Result.Error e -> fail e state - ;; - - module Syntax = struct - let ( let* ) = ( >>= ) - end - - let ( >>| ) (monad : 'a t) (f : 'a -> 'b) : 'b t = - fun state -> - match monad state with - | state, Result.Ok result -> return (f result) state - | state, Result.Error e -> fail e state - ;; - - module RList = struct - let fold_left xs ~init ~f = - List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_right xs ~init ~f = - List.fold_right xs ~init ~f:(fun x acc -> - let open Syntax in - let* acc = acc in - f x acc) - ;; - end - - module RMap = struct - let fold map ~init ~f = - Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - let fresh state = state + 1, Result.Ok state - let run monad = snd (monad 0) -end - -module VarSet = struct - include Set.Make (String) - - let pp ppf set = - Format.fprintf ppf "[ "; - iter (Format.fprintf ppf "%s; ") set; - Format.fprintf ppf "]" - ;; -end - -type scheme = Scheme of VarSet.t * core_type - -let pp_scheme ppf = function - | Scheme (varset, ty) -> - Format.fprintf ppf "{ %a : %a }" VarSet.pp varset Pprinter.pp_core_type ty -;; - -module Type = struct - let rec occurs_in var = function - | Type_option ty | Type_list ty -> occurs_in var ty - | Type_var name -> name = var - | Type_tuple (fst_ty, snd_ty, ty_list) -> - List.exists (occurs_in var) (fst_ty :: snd_ty :: ty_list) - | Type_arrow (l, r) -> occurs_in var l || occurs_in var r - | _ -> false - ;; - - let free_vars = - let rec helper acc = function - | Type_option ty | Type_list ty -> helper acc ty - | Type_var name -> VarSet.add name acc - | Type_tuple (fst_ty, snd_ty, ty_list) -> - List.fold_left helper acc (fst_ty :: snd_ty :: ty_list) - | Type_arrow (l, r) -> helper (helper acc l) r - | _ -> acc - in - helper VarSet.empty - ;; -end - -module Subst = struct - open State - open State.Syntax - open Base - - let empty = Map.empty (module String) - let singleton1 = Map.singleton (module String) - - let singleton key value = - if Type.occurs_in key value - then fail (`Occurs_check (key, value)) - else return (Map.singleton (module String) key value) - ;; - - let remove = Map.remove - - let apply sub = - let rec helper = function - | Type_var name as ty -> - (match Map.find sub name with - | Some name -> name - | None -> ty) - | Type_option ty -> Type_option (helper ty) - | Type_list ty -> Type_list (helper ty) - | Type_tuple (fst_ty, snd_ty, ty_list) -> - Type_tuple (helper fst_ty, helper snd_ty, List.map ty_list ~f:helper) - | Type_arrow (l, r) -> Type_arrow (helper l, helper r) - | ty -> ty - in - helper - ;; - - let rec unify l r = - match l, r with - | Type_unit, Type_unit - | Type_int, Type_int - | Type_char, Type_char - | Type_string, Type_string - | Type_bool, Type_bool -> return empty - | Type_var l, Type_var r when String.equal l r -> return empty - | Type_var name, ty | ty, Type_var name -> singleton name ty - | Type_list ty1, Type_list ty2 | Type_option ty1, Type_option ty2 -> unify ty1 ty2 - | Type_tuple (fst1, snd1, list1), Type_tuple (fst2, snd2, list2) -> - (match - List.fold2 - (fst1 :: snd1 :: list1) - (fst2 :: snd2 :: list2) - ~init:(return empty) - ~f:(fun acc ty1 ty2 -> - let* sub_acc = acc in - let* unified_sub = unify (apply sub_acc ty1) (apply sub_acc ty2) in - compose sub_acc unified_sub) - with - | Ok res -> res - | _ -> fail (`Unification_failed (l, r))) - | Type_arrow (l1, r1), Type_arrow (l2, r2) -> - let* sub1 = unify l1 l2 in - let* sub2 = unify (apply sub1 r1) (apply sub1 r2) in - compose sub1 sub2 - | _ -> fail (`Unification_failed (l, r)) - - and extend key value sub = - match Map.find sub key with - | None -> - let value = apply sub value in - let* new_sub = singleton key value in - Map.fold sub ~init:(return new_sub) ~f:(fun ~key ~data acc -> - let* acc = acc in - let new_data = apply new_sub data in - return (Map.update acc key ~f:(fun _ -> new_data))) - | Some existing_value -> - let* new_sub = unify value existing_value in - compose sub new_sub - - and compose sub1 sub2 = RMap.fold sub2 ~init:(return sub1) ~f:extend - - let compose_all sub_list = RList.fold_left sub_list ~init:(return empty) ~f:compose - - let pp ppf sub = - Stdlib.Format.fprintf ppf "Subst:\n"; - Map.iteri sub ~f:(fun ~key:str ~data:ty -> - Stdlib.Format.fprintf ppf "%s <-> %a; " str Pprinter.pp_core_type ty); - Stdlib.Format.fprintf ppf "\n" - ;; -end - -module Scheme = struct - let free_vars (Scheme (bind_set, ty)) = VarSet.diff (Type.free_vars ty) bind_set - - let apply sub (Scheme (bind_set, ty)) = - let new_sub = VarSet.fold (fun key sub -> Subst.remove sub key) bind_set sub in - Scheme (bind_set, Subst.apply new_sub ty) - ;; -end - -module TypeEnv = struct - open Base - - type t = (ident, scheme, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let rec extend_with_pattern env_acc pat (Scheme (bind_set, ty) as scheme) = - match pat, ty with - | Pat_var id, _ -> extend env_acc id scheme - | Pat_tuple (fst_pat, snd_pat, pat_list), Type_tuple (fst_ty, snd_ty, ty_list) -> - let env = - List.fold2 - ~init:env_acc - ~f:(fun env pat ty -> extend_with_pattern env pat (Scheme (bind_set, ty))) - (fst_pat :: snd_pat :: pat_list) - (fst_ty :: snd_ty :: ty_list) - in - (match env with - | Ok env -> env - | _ -> env_acc) - | Pat_construct ("::", Some pat), Type_list ty -> - (match pat with - | Pat_tuple (head, tail, []) -> - let env_acc = extend_with_pattern env_acc head (Scheme (bind_set, ty)) in - extend_with_pattern env_acc tail scheme - | _ -> env_acc) - | Pat_construct ("Some", Some pat), Type_option ty -> - extend_with_pattern env_acc pat (Scheme (bind_set, ty)) - | _ -> env_acc - ;; - - let free_vars env = - Map.fold env ~init:VarSet.empty ~f:(fun ~key:_ ~data acc -> - VarSet.union acc (Scheme.free_vars data)) - ;; - - let apply sub env = Map.map env ~f:(Scheme.apply sub) - let find = Map.find - - let find_type_exn env key = - let (Scheme (_, ty)) = Map.find_exn env key in - ty - ;; - - let pp ppf env = - Stdlib.Format.fprintf ppf "TypeEnv:\n"; - Map.iteri env ~f:(fun ~key:str ~data:sch -> - Stdlib.Format.fprintf ppf "%s -> %a; " str pp_scheme sch); - Stdlib.Format.fprintf ppf "\n" - ;; -end - -module Infer = struct - open Ast.Expression - open State - open State.Syntax - - let unify = Subst.unify - let fresh_var = fresh >>| fun n -> Type_var ("'ty" ^ Int.to_string n) - - let instantiate (Scheme (bind_set, ty)) = - VarSet.fold - (fun name ty -> - let* ty = ty in - let* fresh = fresh_var in - let* sub = Subst.singleton name fresh in - return (Subst.apply sub ty)) - bind_set - (return ty) - ;; - - let generalize env ty ~remove_from_env id = - let env = - match remove_from_env, id with - | true, Some id -> Base.Map.remove env id - | _ -> env - in - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - let new_free, new_ty, _ = - VarSet.fold - (fun str (temp_free, temp_ty, n) -> - let degree = n / 26 in - let new_str = - (* 97 - is number 'a' in ASCII-table *) - Printf.sprintf - "'%c%s" - (Char.chr (97 + (n mod 26))) - (if degree = 0 then "" else Int.to_string degree) - in - let sub = Subst.singleton1 str (Type_var new_str) in - let new_free = VarSet.add new_str temp_free in - let new_ty = Subst.apply sub temp_ty in - new_free, new_ty, n + 1) - free - (VarSet.empty, ty, 0) - in - Scheme (new_free, new_ty) - ;; - - let lookup_env id env = - match TypeEnv.find env id with - | Some scheme -> - let* ans = instantiate scheme in - return (Subst.empty, ans) - | None -> fail (`No_variable id) - ;; - - let rec infer_pattern env = function - | Pat_any -> - let* fresh = fresh_var in - return (env, fresh) - | Pat_var id -> - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return (env, fresh) - | Pat_constant const -> - (match const with - | Const_integer _ -> return (env, Type_int) - | Const_string _ -> return (env, Type_string) - | Const_char _ -> return (env, Type_char)) - | Pat_tuple (fst_pat, snd_pat, pat_list) -> - let* env1, ty1 = infer_pattern env fst_pat in - let* env2, ty2 = infer_pattern env1 snd_pat in - let* env_rest, ty_list = - RList.fold_right - ~f:(fun pat acc -> - let* env_acc, ty_list = return acc in - let* env, ty = infer_pattern env_acc pat in - return (env, ty :: ty_list)) - ~init:(return (env2, [])) - pat_list - in - return (env_rest, Type_tuple (ty1, ty2, ty_list)) - | Pat_construct ("[]", None) -> - let* fresh = fresh_var in - return (env, Type_list fresh) - | Pat_construct ("::", Some (Pat_tuple (head, tail, []))) -> - let* fresh = fresh_var in - let* env, type_of_head = infer_pattern env head in - let* unified_sub = unify type_of_head fresh in - let env = TypeEnv.apply unified_sub env in - let rec infer_tail env sub_acc cur_pat = - let helper required_ty pat = - let* env, type_of_pat = infer_pattern env pat in - let* unified_sub = unify required_ty type_of_pat in - return (TypeEnv.apply unified_sub env, unified_sub) - in - match cur_pat with - | Pat_construct (_, None) -> return (env, sub_acc) - | Pat_construct (_, Some (Pat_tuple (next_head, next_tail, []))) -> - let* env, sub = helper fresh next_head in - let* env, final_sub = infer_tail env (sub :: sub_acc) next_tail in - return (env, final_sub) - | _ -> - let* env, sub = helper (Type_list fresh) cur_pat in - return (env, sub :: sub_acc) - in - let* env, sub_list = infer_tail env [ unified_sub ] tail in - let* final_sub = Subst.compose_all sub_list in - return (TypeEnv.apply final_sub env, Subst.apply final_sub (Type_list fresh)) - | Pat_construct (id, None) when id = "true" || id = "false" -> return (env, Type_bool) - | Pat_construct ("()", None) -> return (env, Type_unit) - | Pat_construct ("Some", Some pat) -> - let* env, ty = infer_pattern env pat in - return (env, Type_option ty) - | Pat_construct _ -> - let* fresh = fresh_var in - return (env, fresh) - | Pat_constraint (pat, c_ty) -> - let* env, ty = infer_pattern env pat in - let* unified_sub = unify ty c_ty in - return (TypeEnv.apply unified_sub env, Subst.apply unified_sub ty) - ;; - - let extend_env_with_bind_names env value_binding_list = - RList.fold_right - value_binding_list - ~init:(return (env, [])) - ~f:(fun let_bind acc -> - match let_bind with - | { pat = Pat_var id | Pat_constraint (Pat_var id, _); _ } -> - let* env, fresh_acc = return acc in - let* fresh = fresh_var in - let env = TypeEnv.extend env id (Scheme (VarSet.empty, fresh)) in - return (env, fresh :: fresh_acc) - | _ -> fail `No_variable_rec) - ;; - - let rec extract_names_from_pat func acc = function - | Pat_var id -> func acc id - | Pat_tuple (fst_pat, snd_pat, pat_list) -> - RList.fold_left - (fst_pat :: snd_pat :: pat_list) - ~init:(return acc) - ~f:(extract_names_from_pat func) - | Pat_construct ("::", Some exp) -> - (match exp with - | Pat_tuple (head, tail, []) -> - let* acc = extract_names_from_pat func acc head in - extract_names_from_pat func acc tail - | _ -> return acc) - | Pat_construct ("Some", Some pat) -> extract_names_from_pat func acc pat - | Pat_constraint (pat, _) -> extract_names_from_pat func acc pat - | _ -> return acc - ;; - - module StringSet = struct - include Set.Make (String) - - let add_id set value = - if mem value set then fail (`Bound_several_times value) else return (add value set) - ;; - end - - let check_names_from_let_binds = - RList.fold_left ~init:(return StringSet.empty) ~f:(fun set_acc { pat; _ } -> - extract_names_from_pat StringSet.add_id set_acc pat) - ;; - - let rec infer_expression env = function - | Exp_ident id -> lookup_env id env - | Exp_constant const -> - (match const with - | Const_integer _ -> return (Subst.empty, Type_int) - | Const_string _ -> return (Subst.empty, Type_string) - | Const_char _ -> return (Subst.empty, Type_char)) - | Exp_let (Nonrecursive, value_binding, value_binding_list, exp) -> - let* _ = check_names_from_let_binds (value_binding :: value_binding_list) in - let* env, sub1 = - infer_value_binding_list env Subst.empty (value_binding :: value_binding_list) - in - let* sub2, ty2 = infer_expression env exp in - let* composed_sub = Subst.compose sub2 sub1 in - return (composed_sub, ty2) - | Exp_let (Recursive, value_binding, value_binding_list, exp) -> - let* env, fresh_acc = - extend_env_with_bind_names env (value_binding :: value_binding_list) - in - let* env, sub1 = - infer_rec_value_binding_list - env - fresh_acc - Subst.empty - (value_binding :: value_binding_list) - in - let* sub2, ty2 = infer_expression env exp in - let* composed_sub = Subst.compose sub2 sub1 in - return (composed_sub, ty2) - | Exp_fun (pat, pat_list, exp) -> - let* env, ty1 = infer_pattern env pat in - let* sub, ty2 = - match pat_list with - | [] -> infer_expression env exp - | hd :: tl -> infer_expression env (Exp_fun (hd, tl, exp)) - in - return (sub, Type_arrow (Subst.apply sub ty1, ty2)) - | Exp_apply (Exp_ident opr, Exp_apply (exp1, exp2)) when is_operator opr -> - let* sub1, ty1 = infer_expression env exp1 in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) exp2 in - let* required_arg_ty, required_result_ty = - match opr with - | "*" | "/" | "+" | "-" -> return (Type_int, Type_int) - | "^" -> return (Type_string, Type_string) - | ">=" | "<=" | "<>" | "=" | ">" | "<" -> - let* fresh = fresh_var in - return (fresh, Type_bool) - | _ -> return (Type_bool, Type_bool) - in - let* unified_sub1 = Subst.unify (Subst.apply sub2 ty1) required_arg_ty in - let* unified_sub2 = Subst.unify (Subst.apply unified_sub1 ty2) required_arg_ty in - let* composed_sub = Subst.compose_all [ sub1; sub2; unified_sub1; unified_sub2 ] in - return (composed_sub, required_result_ty) - | Exp_apply (exp1, exp2) -> - (match exp1 with - | Exp_ident opr when is_negative_op opr -> - let* sub, ty = infer_expression env exp2 in - let* unified_sub = Subst.unify ty Type_int in - let* composed_sub = Subst.compose sub unified_sub in - return (composed_sub, Type_int) - | _ -> - let* sub1, ty1 = infer_expression env exp1 in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) exp2 in - let* fresh = fresh_var in - let* sub3 = unify (Subst.apply sub2 ty1) (Type_arrow (ty2, fresh)) in - let* composed_sub = Subst.compose_all [ sub3; sub2; sub1 ] in - let final_ty = Subst.apply composed_sub fresh in - return (composed_sub, final_ty)) - | Exp_function (case, case_list) -> - let* fresh_for_matching = fresh_var in - let* fresh_for_result = fresh_var in - infer_match_exp - env - ~with_exp:false - Subst.empty - fresh_for_matching - fresh_for_result - (case :: case_list) - | Exp_match (exp, case, case_list) -> - let* exp_sub, exp_ty = infer_expression env exp in - let env = TypeEnv.apply exp_sub env in - let* fresh_for_result = fresh_var in - infer_match_exp - env - ~with_exp:true - exp_sub - exp_ty - fresh_for_result - (case :: case_list) - | Exp_tuple (fst_exp, snd_exp, exp_list) -> - let* sub1, ty1 = infer_expression env fst_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) snd_exp in - let env = TypeEnv.apply sub2 env in - let* sub_rest, ty_list = - RList.fold_right - ~f:(fun exp acc -> - let* sub_acc, ty_list = return acc in - let* sub, ty = infer_expression (TypeEnv.apply sub_acc env) exp in - let* sub_acc = Subst.compose sub_acc sub in - return (sub_acc, ty :: ty_list)) - ~init:(return (Subst.empty, [])) - exp_list - in - let* sub_result = Subst.compose_all [ sub1; sub2; sub_rest ] in - let ty1 = Subst.apply sub_result ty1 in - let ty2 = Subst.apply sub_result ty2 in - let ty_list = List.map (fun ty -> Subst.apply sub_result ty) ty_list in - return (sub_result, Type_tuple (ty1, ty2, ty_list)) - | Exp_construct ("[]", None) -> - let* fresh = fresh_var in - return (Subst.empty, Type_list fresh) - | Exp_construct ("::", Some (Exp_tuple (head, tail, []))) -> - let* fresh = fresh_var in - let* sub, ty = infer_expression env head in - let* unified_sub = unify fresh ty in - let* sub = Subst.compose sub unified_sub in - let rec infer_tail sub_acc cur_exp = - let helper required_ty exp = - let* sub_of_exp, type_of_exp = infer_expression env exp in - let* unified_sub = unify required_ty type_of_exp in - let* sub = Subst.compose sub_of_exp unified_sub in - return sub - in - match cur_exp with - | Exp_construct (_, None) -> return sub_acc - | Exp_construct (_, Some (Exp_tuple (next_head, next_tail, []))) -> - let* sub = helper fresh next_head in - let* final_sub = infer_tail (sub :: sub_acc) next_tail in - return final_sub - | _ -> - let* sub = helper (Type_list fresh) cur_exp in - return (sub :: sub_acc) - in - let* sub_list = infer_tail [ sub ] tail in - let* final_sub = Subst.compose_all sub_list in - return (final_sub, Subst.apply final_sub (Type_list fresh)) - | Exp_construct (id, None) when id = "true" || id = "false" -> - return (Subst.empty, Type_bool) - | Exp_construct ("()", None) -> return (Subst.empty, Type_unit) - | Exp_construct ("Some", Some pat) -> - let* sub, ty = infer_expression env pat in - return (sub, Type_option ty) - | Exp_construct _ -> - let* fresh = fresh_var in - return (Subst.empty, fresh) - | Exp_ifthenelse (if_exp, then_exp, Some else_exp) -> - let* sub1, ty1 = infer_expression env if_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) then_exp in - let* sub3, ty3 = infer_expression (TypeEnv.apply sub2 env) else_exp in - let* sub4 = unify ty1 Type_bool in - let* sub5 = unify ty2 ty3 in - let* final_sub = Subst.compose_all [ sub5; sub4; sub3; sub2; sub1 ] in - return (final_sub, Subst.apply final_sub ty2) - | Exp_ifthenelse (if_exp, then_exp, None) -> - let* sub1, ty1 = infer_expression env if_exp in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) then_exp in - let* sub3 = unify ty1 Type_bool in - let* sub4 = unify ty2 Type_unit in - let* final_sub = Subst.compose_all [ sub4; sub3; sub2; sub1 ] in - return (final_sub, Subst.apply final_sub ty2) - | Exp_sequence (exp1, exp2) -> - let* sub1, ty1 = infer_expression env exp1 in - let* unified_sub = unify ty1 Type_unit in - let* sub2, ty2 = infer_expression (TypeEnv.apply sub1 env) exp2 in - let* final_sub = Subst.compose_all [ unified_sub; sub2; sub1 ] in - return (final_sub, ty2) - | Exp_constraint (exp, c_ty) -> - let* sub, ty = infer_expression env exp in - let* unified_sub = unify ty c_ty in - let* final_sub = Subst.compose unified_sub sub in - return (final_sub, Subst.apply unified_sub ty) - - and infer_match_exp env ~with_exp match_exp_sub match_exp_ty result_ty case_list = - let* cases_sub, case_ty = - RList.fold_left - case_list - ~init:(return (match_exp_sub, result_ty)) - ~f:(fun acc { left = pat; right = case_exp } -> - let* sub_acc, ty_acc = return acc in - let* env, pat_sub = - let* env, pat_ty = infer_pattern env pat in - let* unified_sub1 = unify match_exp_ty pat_ty in - let* pat_names = - extract_names_from_pat StringSet.add_id StringSet.empty pat - >>| StringSet.elements - in - if with_exp - then ( - let env = TypeEnv.apply unified_sub1 env in - let generalized_schemes = - Base.List.map pat_names ~f:(fun name -> - let ty = TypeEnv.find_type_exn env name in - let generalized_ty = - generalize env ty ~remove_from_env:true (Some name) - in - name, generalized_ty) - in - let env = - Base.List.fold generalized_schemes ~init:env ~f:(fun env (key, value) -> - TypeEnv.extend env key value) - in - return (env, unified_sub1)) - else return (env, unified_sub1) - in - let* composed_sub1 = Subst.compose sub_acc pat_sub in - let* case_exp_sub, case_exp_ty = - infer_expression (TypeEnv.apply composed_sub1 env) case_exp - in - let* unified_sub2 = unify ty_acc case_exp_ty in - let* composed_sub2 = - Subst.compose_all [ composed_sub1; case_exp_sub; unified_sub2 ] - in - return (composed_sub2, Subst.apply composed_sub2 ty_acc)) - in - let final_ty = - if with_exp - then case_ty - else Type_arrow (Subst.apply cases_sub match_exp_ty, case_ty) - in - return (cases_sub, final_ty) - - and infer_value_binding_list env sub let_binds = - let infer_vb new_sub env ty pat rest = - let* composed_sub = Subst.compose sub new_sub in - let env = TypeEnv.apply composed_sub env in - let generalized_ty = - generalize env (Subst.apply composed_sub ty) ~remove_from_env:false None - in - let* env, pat_ty = infer_pattern env pat in - let env = TypeEnv.extend_with_pattern env pat generalized_ty in - let* unified_sub = unify ty pat_ty in - let* final_sub = Subst.compose composed_sub unified_sub in - let env = TypeEnv.apply final_sub env in - infer_value_binding_list env final_sub rest - in - match let_binds with - | [] -> return (env, sub) - | { pat = Pat_constraint (pat, pat_ty); exp = Exp_fun (e_pat, e_pat_list, exp) } - :: rest -> - let* new_sub, ty = - infer_expression env (Exp_fun (e_pat, e_pat_list, Exp_constraint (exp, pat_ty))) - in - infer_vb new_sub env ty pat rest - | { pat = Pat_constraint (pat, pat_ty); exp = Exp_function _ as exp } :: rest -> - let* new_sub, ty = infer_expression env (Exp_constraint (exp, pat_ty)) in - infer_vb new_sub env ty pat rest - | { pat; exp } :: rest -> - let* new_sub, ty = infer_expression env exp in - infer_vb new_sub env ty pat rest - - and infer_rec_value_binding_list ?(debug = false) env fresh_acc sub let_binds = - let infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty = - let* new_sub = - match required_ty with - | Some c_ty -> - let* unified_sub = unify ty c_ty in - Subst.compose unified_sub new_sub - | None -> return new_sub - in - let* unified_sub = unify (Subst.apply new_sub fresh) ty in - let* composed_sub = Subst.compose_all [ new_sub; unified_sub; sub ] in - if debug then Subst.pp Format.std_formatter composed_sub; - let env = TypeEnv.apply composed_sub env in - let generalized_ty = - generalize env (Subst.apply composed_sub fresh) ~remove_from_env:true (Some id) - in - if debug then pp_scheme Format.std_formatter generalized_ty; - let env = TypeEnv.extend env id generalized_ty in - infer_rec_value_binding_list ~debug env fresh_acc composed_sub rest - in - match let_binds, fresh_acc with - | [], _ -> return (env, sub) - | ( { pat = Pat_var id; exp = (Exp_fun _ | Exp_function _) as exp } :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = infer_expression env exp in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | ( { pat = Pat_constraint (Pat_var id, pat_ty); exp = Exp_fun (pat, pat_list, exp) } - :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = - infer_expression env (Exp_fun (pat, pat_list, Exp_constraint (exp, pat_ty))) - in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | ( { pat = Pat_constraint (Pat_var id, pat_ty); exp = Exp_function _ as exp } :: rest - , fresh :: fresh_acc ) -> - let* new_sub, ty = infer_expression env (Exp_constraint (exp, pat_ty)) in - infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | { pat = Pat_var id; exp } :: rest, fresh :: fresh_acc -> - let* new_sub, ty = infer_expression env exp in - let update_fresh = Subst.apply new_sub fresh in - if ty = update_fresh - then fail `No_arg_rec - else infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:None - | { pat = Pat_constraint (Pat_var id, pat_ty); exp } :: rest, fresh :: fresh_acc -> - let* new_sub, ty = infer_expression env exp in - let update_fresh = Subst.apply new_sub fresh in - if ty = update_fresh - then fail `No_arg_rec - else infer_rec_vb new_sub fresh ty id fresh_acc rest ~required_ty:(Some pat_ty) - | _ -> fail `No_variable_rec - ;; - - let infer_structure_item ~debug (env, out_list) = - let get_names_from_let_binds env = - RList.fold_left ~init:(return []) ~f:(fun acc { pat; _ } -> - extract_names_from_pat - (fun acc id -> return (acc @ [ Some id, TypeEnv.find_type_exn env id ])) - acc - pat) - in - function - | Struct_eval exp -> - let* _, ty = infer_expression env exp in - return (env, out_list @ [ None, ty ]) - | Struct_value (Nonrecursive, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* _ = check_names_from_let_binds value_binding_list in - let* env, _ = infer_value_binding_list env Subst.empty value_binding_list in - let* id_list = get_names_from_let_binds env value_binding_list in - if debug then TypeEnv.pp Format.std_formatter env; - return (env, out_list @ id_list) - | Struct_value (Recursive, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env, fresh_acc = extend_env_with_bind_names env value_binding_list in - let* env, _ = - infer_rec_value_binding_list env fresh_acc Subst.empty value_binding_list - in - let* id_list = get_names_from_let_binds env value_binding_list in - if debug then TypeEnv.pp Format.std_formatter env; - return (env, out_list @ id_list) - ;; - - let infer_srtucture ~debug env ast = - let* env, out_list = - RList.fold_left ast ~init:(return (env, [])) ~f:(infer_structure_item ~debug) - in - let remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (Some id1, _), (Some id2, _) -> String.equal id1 id2 - | _ -> false - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> x :: xs - | _ :: xs -> xs - | [] -> [] - in - return (env, remove_duplicates out_list) - ;; -end - -let empty_env = TypeEnv.empty - -let env_with_print_funs = - let print_fun_list = - [ "print_int", Scheme (VarSet.empty, Type_arrow (Type_int, Type_unit)) - ; "print_endline", Scheme (VarSet.empty, Type_arrow (Type_string, Type_unit)) - ] - in - List.fold_left - (fun env (id, sch) -> TypeEnv.extend env id sch) - TypeEnv.empty - print_fun_list -;; - -let run_inferencer ?(debug = false) env ast = - State.run (Infer.infer_srtucture ~debug env ast) -;; diff --git a/OCamlPrintf/lib/inferencer.mli b/OCamlPrintf/lib/inferencer.mli deleted file mode 100644 index 8c8da30e7..000000000 --- a/OCamlPrintf/lib/inferencer.mli +++ /dev/null @@ -1,45 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - [ `No_variable_rec - (** Represents an error where a recursive variable is not allowed because that would lead to infinite recursion. - E.g. [let rec x = x + 1] *) - | `No_arg_rec - (** Represents an error where the left-hand side of the recursive binding is not a var. - E.g. [let rec [ a; b ] = ..] *) - | `Bound_several_times of string - (** Represents an error where a pattern bound the variable multiple times. - E.g. [let x, x = ..] *) - | `Occurs_check of string * Ast.core_type - (** Represents an occurs check failure. - This occurs when attempting to unify types, and one type is found to occur within another in a way that violates the rules of type systems. - E.g. [let rec f x = f] *) - | `No_variable of string - (** Represents an error indicating that a variable could not be found in the current scope. *) - | `Unification_failed of Ast.core_type * Ast.core_type - (** Represents that type unification has failed. - This occurs when two types cannot made equivalent during type inference. *) - ] - -val pp_error : Format.formatter -> error -> unit - -module VarSet : sig - type t = Set.Make(String).t -end - -type scheme = Scheme of VarSet.t * Ast.core_type - -module TypeEnv : sig - type t = (Ast.ident, scheme, Base.String.comparator_witness) Base.Map.t -end - -val empty_env : TypeEnv.t -val env_with_print_funs : TypeEnv.t - -val run_inferencer - : ?debug:bool - -> TypeEnv.t - -> Ast.structure - -> (TypeEnv.t * (Ast.ident option * Ast.core_type) list, error) result diff --git a/OCamlPrintf/lib/interpreter.ml b/OCamlPrintf/lib/interpreter.ml deleted file mode 100644 index a5785f803..000000000 --- a/OCamlPrintf/lib/interpreter.ml +++ /dev/null @@ -1,408 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `Type_error - | `Division_by_zero - | `Match_failure - | `No_variable of string - ] - -let pp_error ppf : error -> _ = function - | `Type_error -> Format.fprintf ppf "Type error" - | `Division_by_zero -> Format.fprintf ppf "Division by zero" - | `Match_failure -> Format.fprintf ppf "Matching failure" - | `No_variable id -> Format.fprintf ppf "Undefined variable '%s'" id -;; - -type value = - | Val_integer of int - | Val_char of char - | Val_string of string - | Val_fun of rec_flag * pattern * pattern list * Expression.t * env - | Val_function of Expression.t case list * env - | Val_tuple of value * value * value list - | Val_construct of ident * value option - | Val_builtin of string - -and env = (string, value, Base.String.comparator_witness) Base.Map.t - -let rec pp_value ppf = - let open Stdlib.Format in - function - | Val_integer int -> fprintf ppf "%i" int - | Val_char char -> fprintf ppf "'%c'" char - | Val_string str -> fprintf ppf "%S" str - | Val_tuple (fst_val, snd_val, val_list) -> - fprintf - ppf - "(%a)" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - (fst_val :: snd_val :: val_list) - | Val_fun _ -> fprintf ppf "" - | Val_function _ -> fprintf ppf "" - | Val_construct ("::", Some (Val_tuple (head, tail, []))) -> - fprintf ppf "@[[ %a" pp_value head; - let rec pp_tail = function - | Val_construct (_, None) -> fprintf ppf "@ ]@]" - | Val_construct (_, Some (Val_tuple (next_head, next_tail, []))) -> - fprintf ppf "@,; %a" pp_value next_head; - pp_tail next_tail - | Val_construct (_, Some _) -> () - | value -> fprintf ppf ";@ %a@ ]@]" pp_value value - in - pp_tail tail - | Val_construct (tag, None) -> fprintf ppf "%s" tag - | Val_construct ("Some", Some value) -> fprintf ppf "Some %a" pp_value value - | Val_construct _ -> () - | Val_builtin _ -> fprintf ppf "" -;; - -module Res = struct - open Base - - type 'a t = ('a, error) Result.t - - let fail = Result.fail - let return = Result.return - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - match monad with - | Ok result -> f result - | Error x -> fail x - ;; - - let ( let* ) = ( >>= ) -end - -module EvalEnv = struct - open Base - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let compose env1 env2 = - Map.fold env2 ~f:(fun ~key ~data env_acc -> extend env_acc key data) ~init:env1 - ;; - - let find_exn env key = - match Map.find env key with - | Some value -> Res.return value - | None -> Res.fail (`No_variable key) - ;; - - let find_exn1 env key = - let val' = Map.find_exn env key in - val' - ;; -end - -module Inter = struct - open Ast.Expression - open Res - open EvalEnv - - let eval_arith opr val1 val2 = return (Val_integer (opr val1 val2)) - let eval_concat opr val1 val2 = return (Val_string (opr val1 val2)) - - let eval_eq opr val1 val2 = - return (Val_construct (Bool.to_string (opr val1 val2), None)) - ;; - - let eval_bool opr val1 val2 = - return - (Val_construct - (Bool.to_string (opr (bool_of_string val1) (bool_of_string val2)), None)) - ;; - - let eval_bin_op = function - | "*", Val_integer val1, Val_integer val2 -> eval_arith ( * ) val1 val2 - | "/", Val_integer val1, Val_integer val2 when val2 <> 0 -> eval_arith ( / ) val1 val2 - | "/", _, Val_integer 0 -> fail `Division_by_zero - | "+", Val_integer val1, Val_integer val2 -> eval_arith ( + ) val1 val2 - | "-", Val_integer val1, Val_integer val2 -> eval_arith ( - ) val1 val2 - | "^", Val_string val1, Val_string val2 -> eval_concat ( ^ ) val1 val2 - | ">=", val1, val2 -> eval_eq ( >= ) val1 val2 - | "<=", val1, val2 -> eval_eq ( <= ) val1 val2 - | "<>", val1, val2 -> eval_eq ( <> ) val1 val2 - | "=", val1, val2 -> eval_eq ( = ) val1 val2 - | ">", val1, val2 -> eval_eq ( > ) val1 val2 - | "<", val1, val2 -> eval_eq ( < ) val1 val2 - | "&&", Val_construct (val1, None), Val_construct (val2, None) -> - eval_bool ( && ) val1 val2 - | "||", Val_construct (val1, None), Val_construct (val2, None) -> - eval_bool ( || ) val1 val2 - | _ -> fail `Type_error - ;; - - let rec match_pattern env = function - | Pat_any, _ -> Some env - | Pat_var name, value -> Some (extend env name value) - | Pat_constant (Const_integer pat), Val_integer value when pat = value -> Some env - | Pat_constant (Const_char pat), Val_char value when pat = value -> Some env - | Pat_constant (Const_string pat), Val_string value when pat = value -> Some env - | Pat_tuple (fst_pat, snd_pat, pat_list), Val_tuple (fst_val, snd_val, val_list) -> - let env = - Base.List.fold2 - ~f:(fun env pat value -> - match env with - | Some env -> match_pattern env (pat, value) - | None -> None) - ~init:(Some env) - (fst_pat :: snd_pat :: pat_list) - (fst_val :: snd_val :: val_list) - in - (match env with - | Ok env -> env - | _ -> None) - | ( Pat_construct ("::", Some (Pat_tuple (head_pat, tail_pat, []))) - , Val_construct ("::", Some (Val_tuple (head_val, tail_val, []))) ) -> - let env = match_pattern env (head_pat, head_val) in - (match env with - | Some env -> match_pattern env (tail_pat, tail_val) - | None -> None) - | Pat_construct (id_pat, None), Val_construct (id_val, None) when id_pat = id_val -> - Some env - | Pat_construct ("Some", Some pat), Val_construct ("Some", Some value) -> - match_pattern env (pat, value) - | Pat_constraint (pat, _), value -> match_pattern env (pat, value) - | _ -> None - ;; - - let rec extend_names_from_pat env = function - | (Pat_any | Pat_construct ("()", None)), _ -> return env - | Pat_var id, value -> return (extend env id value) - | Pat_tuple (fst_pat, snd_pat, pat_list), Val_tuple (fst_val, snd_val, val_list) -> - (match - Base.List.fold2 - (fst_pat :: snd_pat :: pat_list) - (fst_val :: snd_val :: val_list) - ~init:(return env) - ~f:(fun acc pat value -> - let* env = acc in - extend_names_from_pat env (pat, value)) - with - | Ok acc -> acc - | _ -> fail `Type_error) - | Pat_construct ("[]", None), Val_construct ("[]", None) -> return env - | ( Pat_construct ("::", Some (Pat_tuple (head_pat, tail_pat, []))) - , Val_construct ("::", Some (Val_tuple (head_val, tail_val, []))) ) -> - let* env = extend_names_from_pat env (head_pat, head_val) in - let* env = extend_names_from_pat env (tail_pat, tail_val) in - return env - | (Pat_construct ("Some", Some pat) | Pat_constraint (pat, _)), value -> - extend_names_from_pat env (pat, value) - | _ -> fail `Type_error - ;; - - let rec eval_expression env = function - | Exp_ident id -> find_exn env id - | Exp_constant const -> - (match const with - | Const_integer int -> return (Val_integer int) - | Const_char char -> return (Val_char char) - | Const_string str -> return (Val_string str)) - | Exp_let (Nonrecursive, value_binding, value_binding_list, exp) -> - let* env = eval_value_binding_list env (value_binding :: value_binding_list) in - eval_expression env exp - | Exp_let (Recursive, value_binding, value_binding_list, exp) -> - let* env = eval_rec_value_binding_list env (value_binding :: value_binding_list) in - eval_expression env exp - | Exp_fun (pat, pat_list, exp) -> - return (Val_fun (Nonrecursive, pat, pat_list, exp, env)) - | Exp_apply (Exp_ident opr, Exp_apply (exp1, exp2)) when is_operator opr -> - let* value1 = eval_expression env exp1 in - let* value2 = eval_expression env exp2 in - eval_bin_op (opr, value1, value2) - | Exp_apply (exp1, exp2) -> - (match exp1 with - | Exp_ident opr when is_negative_op opr -> - let* value = eval_expression env exp2 in - (match value with - | Val_integer value -> return (Val_integer (-value)) - | _ -> fail `Type_error) - | _ -> - let* fun_val = eval_expression env exp1 in - let* arg_val = eval_expression env exp2 in - (match fun_val with - | Val_fun (rec_flag, pat, pat_list, exp, fun_env) -> - let* new_env = - match rec_flag, match_pattern fun_env (pat, arg_val) with - | Recursive, Some extended_env -> return (compose env extended_env) - | Nonrecursive, Some extended_env -> return extended_env - | _, None -> fail `Match_failure - in - (match pat_list with - | [] -> eval_expression new_env exp - | first_pat :: rest_pat_list -> - return (Val_fun (Recursive, first_pat, rest_pat_list, exp, new_env))) - | Val_function (case_list, env) -> find_and_eval_case env arg_val case_list - | Val_builtin builtin -> - (match builtin, arg_val with - | "print_int", Val_integer integer -> - print_int integer; - return (Val_construct ("()", None)) - | "print_endline", Val_string str -> - print_endline str; - return (Val_construct ("()", None)) - | _ -> fail `Type_error) - | _ -> fail `Type_error)) - | Exp_function (case, case_list) -> return (Val_function (case :: case_list, env)) - | Exp_match (exp, case, case_list) -> - let* match_value = eval_expression env exp in - find_and_eval_case env match_value (case :: case_list) - | Exp_tuple (fst_exp, snd_exp, exp_list) -> - let* fst_val = eval_expression env fst_exp in - let* snd_val = eval_expression env snd_exp in - let* val_list = - Base.List.fold_right - ~f:(fun exp acc -> - let* acc = acc in - let* value = eval_expression env exp in - return (value :: acc)) - ~init:(return []) - exp_list - in - return (Val_tuple (fst_val, snd_val, val_list)) - | Exp_construct ("::", Some (Exp_tuple (head, tail, []))) -> - let* val1 = eval_expression env head in - let* val2 = eval_expression env tail in - return (Val_construct ("::", Some (Val_tuple (val1, val2, [])))) - | Exp_construct (id, None) -> return (Val_construct (id, None)) - | Exp_construct ("Some", Some pat) -> - let* value = eval_expression env pat in - return (Val_construct ("Some", Some value)) - | Exp_construct _ -> fail `Type_error - | Exp_ifthenelse (if_exp, then_exp, else_exp) -> - let* if_value = eval_expression env if_exp in - (match if_value with - | Val_construct ("true", None) -> eval_expression env then_exp - | Val_construct ("false", None) -> - Base.Option.value_map - else_exp - ~f:(eval_expression env) - ~default:(return (Val_construct ("()", None))) - | _ -> fail `Type_error) - | Exp_sequence (exp1, exp2) -> - let* _ = eval_expression env exp1 in - let* value = eval_expression env exp2 in - return value - | Exp_constraint (exp, _) -> eval_expression env exp - - and find_and_eval_case env value = function - | [] -> fail `Match_failure - | { left; right } :: tail -> - let env_temp = match_pattern env (left, value) in - (match env_temp with - | Some env -> eval_expression env right - | None -> find_and_eval_case env value tail) - - and eval_value_binding_list env value_binding_list = - Base.List.fold_left - ~f:(fun acc { pat; exp } -> - let* env = acc in - let* value = eval_expression env exp in - match pat with - | Pat_var name | Pat_constraint (Pat_var name, _) -> - let env = extend env name value in - return env - | _ -> - let* env = extend_names_from_pat env (pat, value) in - return env) - ~init:(return env) - value_binding_list - - and eval_rec_value_binding_list env value_binding_list = - Base.List.fold_left - ~f:(fun acc { pat; exp } -> - let* env = acc in - let* value = eval_expression env exp in - match pat with - | Pat_var name | Pat_constraint (Pat_var name, _) -> - let value = - match value with - | Val_fun (_, pat, pat_list, exp, env) -> - Val_fun (Recursive, pat, pat_list, exp, env) - | other -> other - in - let env = extend env name value in - return env - | _ -> fail `Type_error) - ~init:(return env) - value_binding_list - ;; - - let eval_structure_item env out_list = - let rec extract_names_from_pat env acc = function - | Pat_var id -> acc @ [ Some id, EvalEnv.find_exn1 env id ] - | Pat_tuple (fst_pat, snd_pat, pat_list) -> - Base.List.fold_left - (fst_pat :: snd_pat :: pat_list) - ~init:acc - ~f:(extract_names_from_pat env) - | Pat_construct ("::", Some exp) -> - (match exp with - | Pat_tuple (head, tail, []) -> - let acc = extract_names_from_pat env acc head in - extract_names_from_pat env acc tail - | _ -> acc) - | Pat_construct ("Some", Some pat) -> extract_names_from_pat env acc pat - | Pat_constraint (pat, _) -> extract_names_from_pat env acc pat - | _ -> acc - in - let get_names_from_let_binds env = - Base.List.fold_left ~init:[] ~f:(fun acc { pat; _ } -> - extract_names_from_pat env acc pat) - in - function - | Struct_eval exp -> - let* val' = eval_expression env exp in - return (env, out_list @ [ None, val' ]) - | Struct_value (Nonrecursive, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env = eval_value_binding_list env value_binding_list in - let eval_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ eval_list) - | Struct_value (Recursive, value_binding, value_binding_list) -> - let value_binding_list = value_binding :: value_binding_list in - let* env = eval_rec_value_binding_list env value_binding_list in - let eval_list = get_names_from_let_binds env value_binding_list in - return (env, out_list @ eval_list) - ;; - - let eval_structure env ast = - let* env, out_list = - Base.List.fold_left - ~f:(fun acc item -> - let* env, out_list = acc in - let* env, out_list = eval_structure_item env out_list item in - return (env, out_list)) - ~init:(return (env, [])) - ast - in - let remove_duplicates = - let fun_equal el1 el2 = - match el1, el2 with - | (Some id1, _), (Some id2, _) -> String.equal id1 id2 - | _ -> false - in - function - | x :: xs when not (Base.List.mem xs x ~equal:fun_equal) -> x :: xs - | _ :: xs -> xs - | [] -> [] - in - return (env, remove_duplicates out_list) - ;; -end - -let empty_env = EvalEnv.empty - -let env_with_print_funs = - let env = EvalEnv.extend empty_env "print_int" (Val_builtin "print_int") in - EvalEnv.extend env "print_endline" (Val_builtin "print_endline") -;; - -let run_interpreter = Inter.eval_structure diff --git a/OCamlPrintf/lib/interpreter.mli b/OCamlPrintf/lib/interpreter.mli deleted file mode 100644 index 2a45d3594..000000000 --- a/OCamlPrintf/lib/interpreter.mli +++ /dev/null @@ -1,37 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - [ `Type_error - (** Represents a type error that occurs when a type mismatch is detected in an expression. *) - | `Division_by_zero - (** Represents the error that occurs when attempting to perform a division by zero operation. *) - | `Match_failure - (** Represents a match error occurs when a pattern matching attempt fails. *) - | `No_variable of Ast.ident - (** Represents an error that occurs when attempting to use a variable that has not been declared or initialized. *) - ] - -val pp_error : Format.formatter -> error -> unit - -type value = - | Val_integer of int - | Val_char of char - | Val_string of string - | Val_fun of Ast.rec_flag * Ast.pattern * Ast.pattern list * Ast.Expression.t * env - | Val_function of Ast.Expression.t Ast.case list * env - | Val_tuple of value * value * value list - | Val_construct of Ast.ident * value option - | Val_builtin of Ast.ident - -and env = (Ast.ident, value, Base.String.comparator_witness) Base.Map.t - -val pp_value : Format.formatter -> value -> unit -val empty_env : env -val env_with_print_funs : env - -val run_interpreter - : env - -> Ast.structure - -> (env * (Ast.ident option * value) list, error) result diff --git a/OCamlPrintf/lib/parser.ml b/OCamlPrintf/lib/parser.ml deleted file mode 100644 index e8e2634c6..000000000 --- a/OCamlPrintf/lib/parser.ml +++ /dev/null @@ -1,603 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Ast -open Ast.Expression -open Angstrom - -(* ==================== Utils ==================== *) - -let skip_whitespaces = skip_while Char.is_whitespace - -let parse_comments = - skip_whitespaces *> string "(*" *> many_till any_char (string "*)") *> return () -;; - -let ws = many parse_comments *> skip_whitespaces -let token str = ws *> string str - -let skip_parens parse = - token "(" *> parse <* (token ")" <|> fail "There is no closing bracket.") -;; - -let is_separator = function - | ')' - | '(' - | '<' - | '>' - | '@' - | ',' - | ';' - | ':' - | '\\' - | '"' - | '/' - | '[' - | ']' - | '?' - | '=' - | '{' - | '}' - | ' ' - | '\r' - | '\t' - | '\n' - | '*' - | '-' -> true - | _ -> false -;; - -let keyword str = - token str - *> - let* is_space = - peek_char - >>| function - | Some c -> is_separator c - | None -> true - in - if is_space - then return str <* ws - else fail (Printf.sprintf "There is no separator after %S." str) -;; - -let safe_tl = function - | [] -> [] - | _ :: tail -> tail -;; - -let parse_chain_left_associative parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* elem = parse in - go (f acc elem)) - <|> return acc - in - let* elem = parse in - go elem -;; - -let parse_chain_right_associative parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* elem = parse in - let* next_elem = go elem in - return (f acc next_elem)) - <|> return acc - in - let* elem = parse in - go elem -;; - -(* ==================== Ident ==================== *) - -let parse_ident = - ws - *> - let* fst_char = - satisfy (function - | 'a' .. 'z' | '_' -> true - | _ -> false) - >>| String.of_char - in - let* rest_str = - take_while (function - | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' -> true - | _ -> false) - in - let id = fst_char ^ rest_str in - if is_keyword id then fail (Printf.sprintf "Impossible name: %S." id) else return id -;; - -(* ==================== Rec_flag ==================== *) - -let parse_rec_flag = ws *> option Nonrecursive (keyword "rec" *> return Recursive) - -(* ==================== Constant ==================== *) - -let parse_const_int = - take_while1 Char.is_digit >>| fun int_value -> Const_integer (Int.of_string int_value) -;; - -let parse_const_char = - string "\'" *> any_char <* string "\'" >>| fun char_value -> Const_char char_value -;; - -let parse_const_string = - string "\"" *> take_till (Char.equal '\"') - <* string "\"" - >>| fun str_value -> Const_string str_value -;; - -let parse_constant = - ws *> choice [ parse_const_int; parse_const_char; parse_const_string ] -;; - -(* =================== Core_type =================== *) - -let parse_type_var = - token "'" - *> - let* fst_char = - satisfy (function - | 'a' .. 'z' -> true - | _ -> false) - >>| String.of_char - in - let* is_valid_snd_char = - peek_char - >>| function - | Some snd_char -> - (match snd_char with - | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' -> true - | char' when is_separator char' -> true - | _ -> false) - | _ -> true - in - let* rest_str = - take_while (function - | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' -> true - | _ -> false) - in - let type_var = fst_char ^ rest_str in - if is_valid_snd_char && not (is_keyword type_var) - then return (Type_var ("'" ^ type_var)) - else fail (Printf.sprintf "Impossible type name: %S." type_var) -;; - -let parse_base_type = - choice - [ keyword "unit" *> return Type_unit - ; keyword "int" *> return Type_int - ; keyword "char" *> return Type_char - ; keyword "string" *> return Type_string - ; keyword "bool" *> return Type_bool - ; parse_type_var - ] -;; - -let parse_list_or_option_type parse_type = - let f acc_ty = function - | "list" -> Type_list acc_ty - | _ -> Type_option acc_ty - in - let chain_left_associative = - let rec go acc_ty = - (let* ty = keyword "list" <|> keyword "option" in - go (f acc_ty ty)) - <|> return acc_ty - in - let* fst_ty = parse_type in - go fst_ty - in - chain_left_associative -;; - -let parse_tuple_type parse_type = - let* fst_type = parse_type in - let* snd_type = token "*" *> parse_type in - let* type_list = many (token "*" *> parse_type) in - return (Type_tuple (fst_type, snd_type, type_list)) -;; - -let rec parse_arrow_type parse_type = - let* type1 = parse_type in - let* type2 = token "->" *> (parse_arrow_type parse_type <|> parse_type) in - return (Type_arrow (type1, type2)) -;; - -let parse_core_type = - ws - *> fix (fun parse_full_type -> - let parse_type = parse_base_type <|> skip_parens parse_full_type in - let parse_type = parse_list_or_option_type parse_type <|> parse_type in - let parse_type = parse_tuple_type parse_type <|> parse_type in - parse_arrow_type parse_type <|> parse_type) -;; - -(* ==================== Pattern & Expression ==================== *) - -let parse_construct_base_keyword = - choice [ keyword "true"; keyword "false"; keyword "None"; keyword "()" ] -;; - -let parse_construct_keyword_some parse = - let* tag = keyword "Some" in - let* opt = parse >>| Option.some in - return (tag, opt) -;; - -let parse_constraint parse = - let* elem = token "(" *> parse in - let* type' = token ":" *> parse_core_type <* token ")" in - return (elem, type') -;; - -let parse_tuple parse tuple = - let* fst = parse in - let* snd = token "," *> parse in - let* tail = many (token "," *> parse) in - return (tuple (fst, snd, tail)) -;; - -let parse_construct_list_1 parse construct func = - token "[" *> sep_by (token ";") parse - <* token "]" - >>| List.fold_right ~init:(construct ("[]", None)) ~f:func -;; - -let parse_construct_list_2 parse construct tuple = - parse_chain_right_associative - parse - (token "::" *> return (fun acc elem -> construct ("::", Some (tuple (acc, elem, []))))) -;; - -(* -------------------- Pattern -------------------- *) - -let parse_pat_any = keyword "_" *> return Pat_any -let parse_pat_var = parse_ident >>| fun var -> Pat_var var -let parse_pat_constant = parse_constant >>| fun const -> Pat_constant const - -let parse_pat_construct_base_keyword = - parse_construct_base_keyword >>| fun tag -> Pat_construct (tag, None) -;; - -let parse_base_pat = - choice - [ parse_pat_any; parse_pat_var; parse_pat_constant; parse_pat_construct_base_keyword ] -;; - -let parse_pat_construct_keyword_some parse_pat = - parse_construct_keyword_some (parse_base_pat <|> skip_parens parse_pat) - >>| fun (tag, pat_opt) -> Pat_construct (tag, pat_opt) -;; - -let parse_pat_constraint parse_pat = - parse_constraint parse_pat >>| fun (pat, type') -> Pat_constraint (pat, type') -;; - -let parse_pat_tuple parse_pat = - parse_tuple parse_pat (fun (fst_pat, snd_pat, pat_list) -> - Pat_tuple (fst_pat, snd_pat, pat_list)) -;; - -let parse_pat_construct_list_1 parse_pat = - parse_construct_list_1 - parse_pat - (fun (tag, pat_opt) -> Pat_construct (tag, pat_opt)) - (fun pat acc_pat -> Pat_construct ("::", Some (Pat_tuple (pat, acc_pat, [])))) -;; - -let parse_pat_construct_list_2 parse_pat = - parse_construct_list_2 - parse_pat - (fun (tag, pat_opt) -> Pat_construct (tag, pat_opt)) - (fun (fst_pat, snd_pat, pat_list) -> Pat_tuple (fst_pat, snd_pat, pat_list)) -;; - -let parse_pattern = - ws - *> fix (fun parse_full_pat -> - let parse_pat = - choice - [ parse_base_pat - ; parse_pat_construct_keyword_some parse_full_pat - ; parse_pat_constraint parse_full_pat - ; skip_parens parse_full_pat - ] - in - let parse_pat = parse_pat_construct_list_1 parse_pat <|> parse_pat in - let parse_pat = parse_pat_construct_list_2 parse_pat <|> parse_pat in - parse_pat_tuple parse_pat <|> parse_pat) -;; - -(* -------------------- Operator -------------------- *) - -let bin_op chain1 parse_exp parse_fun_op = - chain1 - parse_exp - (parse_fun_op >>| fun opr exp1 exp2 -> Exp_apply (opr, Exp_apply (exp1, exp2))) -;; - -let parse_left_bin_op = bin_op parse_chain_left_associative -let parse_right_bin_op = bin_op parse_chain_right_associative - -let parse_operator op_list = - choice (List.map ~f:(fun opr -> token opr *> return (Exp_ident opr)) op_list) -;; - -let mul_div = parse_operator [ "*"; "/" ] -let add_sub = parse_operator [ "+"; "-" ] -let concat = parse_operator [ "^" ] -let cmp = parse_operator [ ">="; "<="; "<>"; "="; ">"; "<" ] -let and_ = parse_operator [ "&&" ] -let or_ = parse_operator [ "||" ] - -(* -------------------- Value_binding -------------------- *) - -let parse_constraint_vb parse_exp opr = - let* type' = token ":" *> parse_core_type in - let* exp = token opr *> parse_exp in - return (Exp_constraint (exp, type')) -;; - -let parse_fun_binding parse_exp = - let* pat_var = parse_pat_var in - let* pat_list = many1 parse_pattern in - choice - [ (let* exp = parse_constraint_vb parse_exp "=" in - match exp with - | Exp_constraint (exp, type') -> - return - { pat = Pat_constraint (pat_var, type') - ; exp = Exp_fun (List.hd_exn pat_list, safe_tl pat_list, exp) - } - | _ -> - return - { pat = pat_var; exp = Exp_fun (List.hd_exn pat_list, safe_tl pat_list, exp) }) - ; (let* exp = token "=" *> parse_exp in - return - { pat = pat_var; exp = Exp_fun (List.hd_exn pat_list, safe_tl pat_list, exp) }) - ] -;; - -let parse_simple_binding parse_exp = - let* pat = parse_pattern in - choice - [ (let* exp = parse_constraint_vb parse_exp "=" in - match exp with - | Exp_constraint (exp, type') -> return { pat = Pat_constraint (pat, type'); exp } - | _ -> return { pat; exp }) - ; (let* exp = token "=" *> parse_exp in - return { pat; exp }) - ] -;; - -let parse_value_binding_list parse_exp = - sep_by1 - (keyword "and") - (ws *> (parse_fun_binding parse_exp <|> parse_simple_binding parse_exp)) -;; - -(* -------------------- Case -------------------- *) - -let parse_case parse_exp = - ws - *> option () (token "|" *> return ()) - *> - let* pat = parse_pattern in - let* exp = token "->" *> parse_exp in - return { left = pat; right = exp } -;; - -(* -------------------- Expression -------------------- *) - -let parse_exp_ident = parse_ident >>| fun id -> Exp_ident id -let parse_exp_constant = parse_constant >>| fun const -> Exp_constant const - -let parse_exp_construct_base_keyword = - parse_construct_base_keyword >>| fun tag -> Exp_construct (tag, None) -;; - -let parse_base_exp = - choice [ parse_exp_ident; parse_exp_constant; parse_exp_construct_base_keyword ] -;; - -let parse_exp_sequence parse_exp = - parse_chain_left_associative - parse_exp - (token ";" *> return (fun exp1 exp2 -> Exp_sequence (exp1, exp2))) -;; - -let parse_exp_construct_keyword_some parse_exp = - parse_construct_keyword_some (parse_base_exp <|> skip_parens parse_exp) - >>| fun (tag, exp_opt) -> Exp_construct (tag, exp_opt) -;; - -let parse_exp_constraint parse_exp = - parse_constraint parse_exp >>| fun (exp, type') -> Exp_constraint (exp, type') -;; - -let parse_exp_tuple parse_exp = - parse_tuple parse_exp (fun (fst_exp, snd_exp, exp_list) -> - Exp_tuple (fst_exp, snd_exp, exp_list)) -;; - -let parse_exp_construct_list_1 parse_exp = - let parse_exp_sequence = - skip_parens (parse_exp_sequence parse_exp) >>| fun exp -> true, exp - in - let parse_exp_list = parse_exp >>| fun exp -> false, exp in - parse_construct_list_1 - (parse_exp_sequence <|> parse_exp_list) - (fun (tag, exp_opt) -> Exp_construct (tag, exp_opt)) - (fun opt_exp acc_exp -> - let rec fix_exp_sequence opt_exp acc_exp = - match opt_exp with - | false, Exp_sequence (exp1, (Exp_sequence _ as exp2)) -> - fix_exp_sequence (false, exp1) (fix_exp_sequence (true, exp2) acc_exp) - | false, Exp_sequence (exp1, exp2) -> - fix_exp_sequence (false, exp1) (fix_exp_sequence (false, exp2) acc_exp) - | _, exp -> Exp_construct ("::", Some (Exp_tuple (exp, acc_exp, []))) - in - fix_exp_sequence opt_exp acc_exp) -;; - -let parse_exp_construct_list_2 parse_exp = - parse_construct_list_2 - parse_exp - (fun (tag, exp_opt) -> Exp_construct (tag, exp_opt)) - (fun (fst_exp, snd_exp, exp_list) -> Exp_tuple (fst_exp, snd_exp, exp_list)) -;; - -let parse_exp_let parse_exp = - keyword "let" - *> - let* rec_flag = parse_rec_flag in - let* value_binding_list = parse_value_binding_list parse_exp <* keyword "in" in - let* exp = parse_exp in - return - (Exp_let (rec_flag, List.hd_exn value_binding_list, safe_tl value_binding_list, exp)) -;; - -let parse_exp_fun parse_exp = - keyword "fun" - *> - let* pat = parse_pattern in - let* pat_list = many parse_pattern in - choice - [ (let* exp = parse_constraint_vb parse_exp "->" in - match exp with - | Exp_constraint (exp, type') -> - return (Exp_fun (Pat_constraint (pat, type'), pat_list, exp)) - | _ -> return (Exp_fun (pat, pat_list, exp))) - ; (let* exp = token "->" *> parse_exp in - return (Exp_fun (pat, pat_list, exp))) - ] -;; - -let parse_exp_function parse_exp = - keyword "function" - *> - let* case_list = sep_by1 (token "|") (parse_case parse_exp) in - return (Exp_function (List.hd_exn case_list, safe_tl case_list)) -;; - -let parse_exp_match parse_exp = - let* exp = keyword "match" *> parse_exp <* keyword "with" in - let* case_list = sep_by1 (token "|") (parse_case parse_exp) in - return (Exp_match (exp, List.hd_exn case_list, safe_tl case_list)) -;; - -let parse_exp_ifthenelse parse_exp = - let* if_exp = keyword "if" *> parse_exp in - let* then_exp = keyword "then" *> parse_exp in - let* else_exp = - option None (keyword "else" >>| Option.some) - >>= function - | None -> return None - | Some _ -> parse_exp >>| Option.some - in - return (Exp_ifthenelse (if_exp, then_exp, else_exp)) -;; - -let parse_top_exp parse_exp = - choice - [ parse_exp_let parse_exp - ; parse_exp_fun parse_exp - ; parse_exp_function parse_exp - ; parse_exp_match parse_exp - ; parse_exp_ifthenelse parse_exp - ] -;; - -let parse_exp_apply_fun parse_exp = - parse_chain_left_associative - parse_exp - (return (fun exp1 exp2 -> Exp_apply (exp1, exp2))) -;; - -let parse_exp_apply_un_op parse_exp = - let is_not_space = function - | '(' | '[' | '_' | '\'' | '\"' -> true - | c -> Char.is_alphanum c - in - let string_un_op str = - token str - *> - let* char_value = peek_char_fail in - if is_not_space char_value - then return str - else fail (Printf.sprintf "There is no space after unary minus.") - in - string_un_op "-" *> parse_exp - >>| (fun exp -> Exp_apply (Exp_ident "~-", exp)) - <|> parse_exp -;; - -let parse_exp_apply_bin_op parse_exp = - let parse_exp = parse_left_bin_op parse_exp mul_div in - let parse_exp = parse_left_bin_op parse_exp add_sub in - let parse_exp = parse_right_bin_op parse_exp concat in - let parse_exp = parse_left_bin_op parse_exp cmp in - let parse_exp = parse_right_bin_op parse_exp and_ in - parse_right_bin_op parse_exp or_ -;; - -let parse_exp_apply parse_exp = - let parse_exp = parse_exp_apply_fun parse_exp in - let parse_exp = parse_exp_apply_un_op parse_exp in - parse_exp_apply_bin_op parse_exp -;; - -let parse_expression = - ws - *> fix (fun parse_full_exp -> - let parse_exp = - choice - [ parse_base_exp - ; parse_exp_construct_keyword_some parse_full_exp - ; parse_exp_constraint parse_full_exp - ; parse_exp_construct_list_1 parse_full_exp - ; parse_top_exp parse_full_exp - ; skip_parens parse_full_exp - ] - in - let parse_exp = parse_exp_apply parse_exp <|> parse_exp in - let parse_exp = parse_exp_construct_list_2 parse_exp <|> parse_exp in - let parse_exp = parse_exp_tuple parse_exp <|> parse_exp in - let parse_exp = parse_exp_sequence parse_exp <|> parse_exp in - parse_top_exp parse_full_exp <|> parse_exp) -;; - -(* ==================== Structure ==================== *) - -let parse_struct_value = - keyword "let" - *> - let* rec_flag = parse_rec_flag in - let* value_binding_list = parse_value_binding_list parse_expression in - option - (Struct_value (rec_flag, List.hd_exn value_binding_list, safe_tl value_binding_list)) - (keyword "in" *> parse_expression - >>| fun exp -> - Struct_eval - (Exp_let (rec_flag, List.hd_exn value_binding_list, safe_tl value_binding_list, exp)) - ) -;; - -let parse_structure = - ws - *> - let parse_structure_item = - parse_struct_value <|> (parse_expression >>| fun exp -> Struct_eval exp) - in - let semicolons = many (token ";;") in - sep_by semicolons parse_structure_item <* semicolons <* ws -;; - -(* ==================== Execute ==================== *) - -let parse = parse_string ~consume:All parse_structure diff --git a/OCamlPrintf/lib/parser.mli b/OCamlPrintf/lib/parser.mli deleted file mode 100644 index cf5d449f7..000000000 --- a/OCamlPrintf/lib/parser.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> (Ast.structure, string) result diff --git a/OCamlPrintf/lib/pprinter.ml b/OCamlPrintf/lib/pprinter.ml deleted file mode 100644 index 8615b39ec..000000000 --- a/OCamlPrintf/lib/pprinter.ml +++ /dev/null @@ -1,308 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 **) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Ast.Expression -open Format - -let pp_rec_flag ppf = function - | Recursive -> fprintf ppf "let rec " - | Nonrecursive -> fprintf ppf "let " -;; - -let pp_comma ppf () = fprintf ppf "@,, " - -let pp_and indent ppf () = - pp_force_newline ppf (); - pp_open_hovbox ppf indent; - fprintf ppf "and " -;; - -let pp_ident ppf = fprintf ppf "%s" - -let pp_constant ppf = function - | Const_integer n -> fprintf ppf "%d" n - | Const_char c -> fprintf ppf "'%c'" c - | Const_string s -> fprintf ppf "%S" s -;; - -let rec pp_core_type_deep n ppf = function - | Type_unit -> fprintf ppf "unit" - | Type_int -> fprintf ppf "int" - | Type_char -> fprintf ppf "char" - | Type_string -> fprintf ppf "string" - | Type_bool -> fprintf ppf "bool" - | Type_option type' -> fprintf ppf "%a option" (pp_core_type_deep 2) type' - | Type_var type' -> pp_ident ppf type' - | Type_list type' -> fprintf ppf "%a list" (pp_core_type_deep 2) type' - | Type_tuple (fst_type, snd_type, type_list) -> - if n = 2 then fprintf ppf "("; - fprintf ppf "%a" (pp_core_type_deep 2) fst_type; - List.iter - (fun type' -> - fprintf ppf " * "; - fprintf ppf "%a" (pp_core_type_deep 2) type') - (snd_type :: type_list); - if n = 2 then fprintf ppf ")" - | Type_arrow (fst_type, snd_type) -> - if n <> 0 then fprintf ppf "("; - fprintf ppf "%a -> %a" (pp_core_type_deep 1) fst_type (pp_core_type_deep 0) snd_type; - if n <> 0 then fprintf ppf ")" -;; - -let pp_core_type = pp_core_type_deep 0 - -let rec pp_pattern_deep need_parens ppf = function - | Pat_any -> fprintf ppf "_" - | Pat_var var -> pp_ident ppf var - | Pat_constant const -> pp_constant ppf const - | Pat_tuple (fst_pat, snd_pat, pat_list) -> - pp_open_hvbox ppf 0; - if need_parens then fprintf ppf "( "; - fprintf - ppf - "%a@]" - (pp_print_list ~pp_sep:pp_comma (pp_pattern_deep true)) - (fst_pat :: snd_pat :: pat_list); - if need_parens then fprintf ppf " )" - | Pat_construct ("::", Some (Pat_tuple (head, tail, []))) -> - fprintf ppf "@[[ %a" (pp_pattern_deep true) head; - let rec pp_tail = function - | Pat_construct (_, None) -> fprintf ppf "@ ]@]" - | Pat_construct (_, Some (Pat_tuple (next_head, next_tail, []))) -> - fprintf ppf "@,; %a" (pp_pattern_deep true) next_head; - pp_tail next_tail - | Pat_construct (_, Some _) -> () - | pat -> fprintf ppf ";@ %a@ ]@]" (pp_pattern_deep true) pat - in - pp_tail tail - | Pat_construct (tag, None) -> fprintf ppf "%s" tag - | Pat_construct ("Some", Some pat) -> fprintf ppf "Some (%a)" (pp_pattern_deep true) pat - | Pat_construct _ -> () - | Pat_constraint (pat, core_type) -> - if need_parens then fprintf ppf "("; - fprintf ppf "@[%a@ :@ %a@]" (pp_pattern_deep true) pat pp_core_type core_type; - if need_parens then fprintf ppf ")" -;; - -let pp_pattern = pp_pattern_deep false - -let rec pp_expression_deep need_cut need_parens ppf = function - | Exp_ident id -> pp_ident ppf id - | Exp_constant const -> pp_constant ppf const - | Exp_let (rec_flag, fst_value_binding, value_binding_list, exp) -> - if need_parens then fprintf ppf "("; - pp_open_hvbox ppf 0; - (pp_value_binding_list 0) ppf (rec_flag, fst_value_binding :: value_binding_list); - fprintf ppf " in@ %a" (pp_expression_deep true true) exp; - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_fun (fst_pat, pat_list, exp) -> - if need_parens then fprintf ppf "("; - pp_open_box ppf 2; - fprintf - ppf - "fun@ %a@ " - (pp_print_list ~pp_sep:pp_print_space (pp_pattern_deep true)) - (fst_pat :: pat_list); - fprintf ppf "->@ %a" (pp_expression_deep false true) exp; - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_apply (exp1, exp2) -> - pp_open_box ppf 2; - (pp_exp_apply ~need_parens) ppf (exp1, exp2); - pp_close_box ppf () - | Exp_function (fst_case, case_list) -> - if need_cut then pp_force_newline ppf (); - if need_parens then fprintf ppf "("; - pp_open_vbox ppf 0; - fprintf ppf "function@ "; - fprintf ppf "%a" (pp_print_list pp_case) (fst_case :: case_list); - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_match (exp, fst_case, case_list) -> - if need_cut then pp_force_newline ppf (); - if need_parens then fprintf ppf "("; - pp_open_vbox ppf 0; - pp_open_hvbox ppf 0; - if need_parens then pp_open_vbox ppf 1 else pp_open_vbox ppf 2; - fprintf ppf "match %a@]@ with@]@ " (pp_expression_deep true false) exp; - fprintf ppf "%a" (pp_print_list pp_case) (fst_case :: case_list); - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_tuple (fst_exp, snd_exp, exp_list) -> - pp_open_hvbox ppf 0; - if need_parens then fprintf ppf "( "; - fprintf - ppf - "%a@]" - (pp_print_list ~pp_sep:pp_comma (pp_expression_deep false true)) - (fst_exp :: snd_exp :: exp_list); - if need_parens then fprintf ppf " )" - | Exp_construct ("::", Some (Exp_tuple (head, tail, []))) -> - fprintf ppf "@[[ %a" (pp_expression_deep false true) head; - let rec pp_tail = function - | Exp_construct (_, None) -> fprintf ppf "@ ]@]" - | Exp_construct (_, Some (Exp_tuple (next_head, next_tail, []))) -> - fprintf ppf "@,; %a" (pp_expression_deep false true) next_head; - pp_tail next_tail - | Exp_construct (_, Some _) -> () - | exp -> fprintf ppf ";@ %a@ ]@]" (pp_expression_deep false true) exp - in - pp_tail tail - | Exp_construct (tag, None) -> fprintf ppf "%s" tag - | Exp_construct ("Some", Some exp) -> - fprintf ppf "Some (%a)" (pp_expression_deep false true) exp - | Exp_construct _ -> () - | Exp_ifthenelse (exp1, exp2, None) -> - if need_parens then fprintf ppf "("; - pp_open_box ppf 0; - fprintf ppf "if %a@ " (pp_expression_deep false false) exp1; - fprintf ppf "@[then %a@]" (pp_expression_deep true true) exp2; - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_ifthenelse (exp1, exp2, Some exp3) -> - if need_parens then fprintf ppf "("; - pp_open_box ppf 0; - fprintf ppf "if %a@ " (pp_expression_deep false false) exp1; - fprintf ppf "@[then %a@]@ " (pp_expression_deep true true) exp2; - fprintf ppf "@[else %a@]" (pp_expression_deep true true) exp3; - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_sequence (exp1, exp2) -> - if need_parens then fprintf ppf "("; - pp_open_box ppf 0; - fprintf ppf "%a; " (pp_expression_deep need_cut true) exp1; - fprintf ppf "%a" (pp_expression_deep need_cut true) exp2; - if need_parens then fprintf ppf ")"; - pp_close_box ppf () - | Exp_constraint (exp, core_type) -> - fprintf - ppf - "@[(%a@ :@ %a)@]" - (pp_expression_deep false false) - exp - pp_core_type - core_type - -and pp_exp_apply ?(need_parens = false) ppf (exp1, exp2) = - let ( < ) opr1 opr2 = get_priority opr1 < get_priority opr2 - and ( <= ) opr1 opr2 = get_priority opr1 <= get_priority opr2 in - let pp condition opr exp = - if condition - then fprintf ppf "(%a)" (pp_exp_apply ~need_parens) (Exp_ident opr, exp) - else fprintf ppf "%a" (pp_exp_apply ~need_parens) (Exp_ident opr, exp) - in - match exp1 with - | Exp_ident exp_opr when is_operator exp_opr -> - (match exp2 with - | Exp_apply (Exp_apply (Exp_ident opr1, exp1), opn) when is_operator opr1 -> - (match get_priority exp_opr with - | 3 | 5 | 6 -> pp (exp_opr <= opr1) opr1 exp1 - | _ -> pp (exp_opr < opr1) opr1 exp1); - fprintf ppf " %s@ " exp_opr; - (match opn with - | Exp_apply (Exp_ident opr2, exp2) when is_operator opr2 -> - pp (opr1 <= opr2 && exp_opr < opr2) opr2 exp2 - | _ -> fprintf ppf "%a" (pp_expression_deep false true) opn) - | Exp_apply (opn, Exp_apply (Exp_ident opr2, exp2)) when is_operator opr2 -> - (match opn with - | Exp_apply (Exp_ident opr1, exp1) when is_operator opr1 -> - pp (opr2 <= opr1 && exp_opr < opr1) opr1 exp1 - | _ -> fprintf ppf "%a" (pp_expression_deep false true) opn); - fprintf ppf " %s@ " exp_opr; - (match get_priority exp_opr with - | 1 | 2 | 4 -> pp (exp_opr <= opr2) opr2 exp2 - | _ -> pp (exp_opr < opr2) opr2 exp2) - | Exp_apply (opn1, opn2) -> - fprintf - ppf - "%a %s@ %a" - (pp_expression_deep false true) - opn1 - exp_opr - (pp_expression_deep false true) - opn2 - | _ -> (pp_expression_deep false true) ppf exp2) - | Exp_ident exp_opr when is_negative_op exp_opr -> - (match exp2 with - | Exp_ident _ | Exp_constant _ -> - fprintf ppf "-%a" (pp_expression_deep false need_parens) exp2 - | Exp_apply _ -> fprintf ppf "-(%a)" (pp_expression_deep false need_parens) exp2 - | _ -> fprintf ppf "-%a" (pp_expression_deep false true) exp2) - | _ -> - fprintf ppf "%a " (pp_expression_deep false true) exp1; - (match exp2 with - | Exp_apply _ -> fprintf ppf "(%a)" (pp_expression_deep false true) exp2 - | _ -> fprintf ppf "%a" (pp_expression_deep false true) exp2) - -and pp_value_binding ppf = - pp_open_hvbox ppf 0; - function - | { pat = pat_var; exp = Exp_fun (pat, pat_list, exp) } -> - let pp_pattern_arg () = - fprintf - ppf - "%a" - (pp_print_list ~pp_sep:pp_print_space (pp_pattern_deep true)) - (pat :: pat_list) - in - (match pat_var with - | Pat_constraint (pat, type') -> - fprintf ppf "%a@ " pp_pattern pat; - pp_pattern_arg (); - fprintf ppf "@ : %a" pp_core_type type' - | _ -> - fprintf ppf "%a@ " pp_pattern pat_var; - pp_pattern_arg ()); - fprintf ppf "@ =@]@ "; - fprintf ppf "@[%a@]@]" (pp_expression_deep false false) exp - | { pat; exp = Exp_let _ as exp } -> - fprintf ppf "%a =@]@\n" pp_pattern pat; - fprintf ppf "@[%a@]@]" (pp_expression_deep false false) exp - | { pat; exp } -> - fprintf ppf "%a =@]@ " pp_pattern pat; - fprintf ppf "@[%a@]@]" (pp_expression_deep false false) exp - -and pp_case ppf = function - | { left; right } -> - fprintf - ppf - "@[| %a ->@ %a@]" - (pp_pattern_deep true) - left - (pp_expression_deep true true) - right - -and pp_value_binding_list indent ppf = function - | rec_flag, value_binding_list -> - pp_open_hovbox ppf indent; - pp_rec_flag ppf rec_flag; - fprintf - ppf - "%a" - (pp_print_list ~pp_sep:(pp_and indent) pp_value_binding) - value_binding_list -;; - -let pp_expression = pp_expression_deep false false - -let pp_structure_item ppf = function - | Struct_eval exp -> - fprintf ppf "@[%a@];;" pp_expression exp; - pp_print_flush ppf () - | Struct_value (rec_flag, fst_value_binding, value_binding_list) -> - (pp_value_binding_list 2) ppf (rec_flag, fst_value_binding :: value_binding_list); - pp_print_if_newline ppf (); - pp_print_cut ppf (); - fprintf ppf ";;"; - pp_print_flush ppf () -;; - -let pp_structure ppf ast = - if Base.List.is_empty ast - then fprintf ppf ";;" - else fprintf ppf "@[%a@]" (pp_print_list ~pp_sep:pp_force_newline pp_structure_item) ast; - pp_print_flush ppf () -;; diff --git a/OCamlPrintf/lib/pprinter.mli b/OCamlPrintf/lib/pprinter.mli deleted file mode 100644 index 64c0c7375..000000000 --- a/OCamlPrintf/lib/pprinter.mli +++ /dev/null @@ -1,14 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val pp_rec_flag : Format.formatter -> Ast.rec_flag -> unit -val pp_ident : Format.formatter -> string -> unit -val pp_constant : Format.formatter -> Ast.constant -> unit -val pp_core_type : Format.formatter -> Ast.core_type -> unit -val pp_pattern : Format.formatter -> Ast.pattern -> unit -val pp_expression : Format.formatter -> Ast.Expression.t -> unit -val pp_value_binding : Format.formatter -> Ast.Expression.value_binding_exp -> unit -val pp_case : Format.formatter -> Ast.Expression.case_exp -> unit -val pp_structure_item : Format.formatter -> Ast.structure_item -> unit -val pp_structure : Format.formatter -> Ast.structure -> unit diff --git a/OCamlPrintf/lib/qchecker.ml b/OCamlPrintf/lib/qchecker.ml deleted file mode 100644 index 5e6e4ba47..000000000 --- a/OCamlPrintf/lib/qchecker.ml +++ /dev/null @@ -1,47 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -let failure ast = - Format.asprintf - "*** PPrinter ***@.%a@.*** Ast ***@.%s@.*** Parser ***@.%s@." - Pprinter.pp_structure - ast - (Ast.show_structure ast) - (match Parser.parse (Format.asprintf "%a" Pprinter.pp_structure ast) with - | Ok ast_parsed -> Ast.show_structure ast_parsed - | Error error -> error) -;; - -let rule_gen ?(show_passed = false) ?(show_shrinker = false) ast = - match Parser.parse (Format.asprintf "%a" Pprinter.pp_structure ast) with - | Ok ast_parsed -> - if ast = ast_parsed - then ( - if show_passed - then Format.printf "@.*** PPrinter ***@.%a@." Pprinter.pp_structure ast; - true) - else ( - if show_shrinker - then ( - Format.printf "@.*** Shrinker ***@.%a@." Pprinter.pp_structure ast; - Format.printf "@.*** AST ***@.%s@." (Ast.show_structure ast)); - false) - | Error _ -> - if show_shrinker - then Format.printf "@.*** Shrinker ***@.%a@." Pprinter.pp_structure ast; - false -;; - -let run_gen ?(show_passed = false) ?(show_shrinker = false) ?(count = 10) = - let gen type_gen = - QCheck.make type_gen ~print:failure ~shrink:Shrinker.shrink_structure - in - QCheck_base_runner.run_tests_main - [ QCheck.Test.make - ~count - ~name:"the auto generator" - (gen Ast.gen_structure) - (fun ast -> rule_gen ~show_passed ~show_shrinker ast) - ] -;; diff --git a/OCamlPrintf/lib/qchecker.mli b/OCamlPrintf/lib/qchecker.mli deleted file mode 100644 index eb3fcdcc2..000000000 --- a/OCamlPrintf/lib/qchecker.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run_gen : ?show_passed:bool -> ?show_shrinker:bool -> ?count:int -> int diff --git a/OCamlPrintf/lib/shrinker.ml b/OCamlPrintf/lib/shrinker.ml deleted file mode 100644 index 80ed43fcd..000000000 --- a/OCamlPrintf/lib/shrinker.ml +++ /dev/null @@ -1,170 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Ast.Expression -open QCheck.Iter -open QCheck.Shrink - -let shrink_type_ident = function - | "'a" -> empty - | _ -> return "'a" -;; - -let shrink_ident = function - | "a" -> empty - | _ -> return "a" -;; - -let rec shrink_core_type = function - | Type_unit | Type_bool | Type_char | Type_int | Type_string -> empty - | Type_var id -> shrink_type_ident id >|= fun id' -> Type_var id' - | Type_list type' -> - return type' <+> (shrink_core_type type' >|= fun type'' -> Type_list type'') - | Type_option type' -> - return type' <+> (shrink_core_type type' >|= fun type'' -> Type_option type'') - | Type_tuple (fst_type, snd_type, type_list) -> - of_list [ fst_type; snd_type ] - <+> of_list type_list - <+> (shrink_core_type fst_type - >|= fun fst_type' -> Type_tuple (fst_type', snd_type, type_list)) - <+> (shrink_core_type snd_type - >|= fun snd_type' -> Type_tuple (fst_type, snd_type', type_list)) - <+> (list ~shrink:shrink_core_type type_list - >|= fun type_list' -> Type_tuple (fst_type, snd_type, type_list')) - | Type_arrow (fst_type, snd_type) -> - of_list [ fst_type; snd_type ] - <+> (shrink_core_type fst_type >|= fun fst_type' -> Type_arrow (fst_type', snd_type)) - <+> (shrink_core_type snd_type >|= fun snd_type' -> Type_arrow (fst_type, snd_type')) -;; - -let rec shrink_pattern = function - | Pat_any -> empty - | Pat_var var -> shrink_ident var >|= fun var' -> Pat_var var' - | Pat_constant const -> - (match const with - | Const_integer i -> int i >|= fun i' -> Pat_constant (Const_integer i') - | Const_char ch -> char ch >|= fun ch' -> Pat_constant (Const_char ch') - | Const_string str -> - shrink_ident str >|= fun str' -> Pat_constant (Const_string str')) - | Pat_tuple (fst_pat, snd_pat, pat_list) -> - of_list [ fst_pat; snd_pat ] - <+> of_list pat_list - <+> (shrink_pattern fst_pat >|= fun fst_pat' -> Pat_tuple (fst_pat', snd_pat, pat_list) - ) - <+> (shrink_pattern snd_pat >|= fun snd_pat' -> Pat_tuple (fst_pat, snd_pat', pat_list) - ) - <+> (list ~shrink:shrink_pattern pat_list - >|= fun pat_list' -> Pat_tuple (fst_pat, snd_pat, pat_list')) - | Pat_construct (_, None) -> empty - | Pat_construct (tag, Some pat) -> - return pat <+> (shrink_pattern pat >|= fun pat' -> Pat_construct (tag, Some pat')) - | Pat_constraint (pat, type') -> - return pat - <+> (shrink_pattern pat >|= fun pat' -> Pat_constraint (pat', type')) - <+> (shrink_core_type type' >|= fun type'' -> Pat_constraint (pat, type'')) -;; - -let rec shrink_expression = function - | Exp_ident id -> shrink_ident id >|= fun id' -> Exp_ident id' - | Exp_constant const -> - (match const with - | Const_integer i -> int i >|= fun i' -> Exp_constant (Const_integer i') - | Const_char ch -> char ch >|= fun ch' -> Exp_constant (Const_char ch') - | Const_string str -> - shrink_ident str >|= fun str' -> Exp_constant (Const_string str')) - | Exp_let (rec_flag, fst_value_binding, value_binding_list, exp) -> - return exp - <+> (shrink_expression exp - >|= fun exp' -> Exp_let (rec_flag, fst_value_binding, value_binding_list, exp')) - <+> (shrink_value_binding fst_value_binding - >|= fun fst_value_binding' -> - Exp_let (rec_flag, fst_value_binding', value_binding_list, exp)) - <+> (list ~shrink:shrink_value_binding value_binding_list - >|= fun value_binding_list' -> - Exp_let (rec_flag, fst_value_binding, value_binding_list', exp)) - <+> (shrink_expression exp - >|= fun exp' -> Exp_let (rec_flag, fst_value_binding, value_binding_list, exp')) - | Exp_fun (fst_pat, pat_list, exp) -> - return exp - <+> (shrink_pattern fst_pat >|= fun fst_pat' -> Exp_fun (fst_pat', pat_list, exp)) - <+> (list ~shrink:shrink_pattern pat_list - >|= fun pat_list' -> Exp_fun (fst_pat, pat_list', exp)) - <+> (shrink_expression exp >|= fun exp' -> Exp_fun (fst_pat, pat_list, exp')) - | Exp_apply (exp_fn, exp) -> - shrink_expression exp - >|= (fun exp_fn' -> Exp_apply (exp_fn', exp)) - <+> (shrink_expression exp >|= fun exp' -> Exp_apply (exp_fn, exp')) - | Exp_function (fst_case, case_list) -> - shrink_case fst_case - >|= (fun fst_case' -> Exp_function (fst_case', case_list)) - <+> (list ~shrink:shrink_case case_list - >|= fun case_list' -> Exp_function (fst_case, case_list')) - | Exp_match (exp, fst_case, case_list) -> - return exp - <+> (shrink_expression exp >|= fun exp' -> Exp_match (exp', fst_case, case_list)) - <+> (shrink_case fst_case >|= fun fst_case' -> Exp_match (exp, fst_case', case_list)) - <+> (list ~shrink:shrink_case case_list - >|= fun case_list' -> Exp_match (exp, fst_case, case_list')) - | Exp_tuple (fst_exp, snd_exp, exp_list) -> - of_list [ fst_exp; snd_exp ] - <+> of_list exp_list - <+> (shrink_expression fst_exp - >|= fun fst_exp' -> Exp_tuple (fst_exp', snd_exp, exp_list)) - <+> (shrink_expression snd_exp - >|= fun snd_exp' -> Exp_tuple (fst_exp, snd_exp', exp_list)) - <+> (list ~shrink:shrink_expression exp_list - >|= fun exp_list' -> Exp_tuple (fst_exp, snd_exp, exp_list')) - | Exp_construct (_, None) -> empty - | Exp_construct (tag, Some exp) -> - return exp <+> (shrink_expression exp >|= fun exp' -> Exp_construct (tag, Some exp')) - | Exp_ifthenelse (if_exp, then_exp, None) -> - of_list [ if_exp; then_exp ] - <+> (shrink_expression if_exp - >|= fun if_exp' -> Exp_ifthenelse (if_exp', then_exp, None)) - <+> (shrink_expression then_exp - >|= fun then_exp' -> Exp_ifthenelse (if_exp, then_exp', None)) - | Exp_ifthenelse (if_exp, then_exp, Some else_exp) -> - of_list [ if_exp; then_exp; else_exp ] - <+> (shrink_expression if_exp - >|= fun if_exp' -> Exp_ifthenelse (if_exp', then_exp, Some else_exp)) - <+> (shrink_expression then_exp - >|= fun then_exp' -> Exp_ifthenelse (if_exp, then_exp', Some else_exp)) - <+> (shrink_expression else_exp - >|= fun else_exp' -> Exp_ifthenelse (if_exp, then_exp, Some else_exp')) - | Exp_sequence (exp1, exp2) -> - of_list [ exp1; exp2 ] - <+> (shrink_expression exp1 >|= fun exp1' -> Exp_sequence (exp1', exp2)) - <+> (shrink_expression exp2 >|= fun exp2' -> Exp_sequence (exp1, exp2')) - | Exp_constraint (exp, type') -> - return exp - <+> (shrink_expression exp >|= fun exp' -> Exp_constraint (exp', type')) - <+> (shrink_core_type type' >|= fun type'' -> Exp_constraint (exp, type'')) - -and shrink_value_binding value_binding = - shrink_pattern value_binding.pat - >|= (fun pat' -> { value_binding with pat = pat' }) - <+> (shrink_expression value_binding.exp - >|= fun exp' -> { value_binding with exp = exp' }) - -and shrink_case case = - shrink_pattern case.left - >|= (fun left' -> { case with left = left' }) - <+> (shrink_expression case.right >|= fun right' -> { case with right = right' }) -;; - -let shrink_structure_item = function - | Struct_eval exp -> shrink_expression exp >|= fun exp' -> Struct_eval exp' - | Struct_value (rec_flag, fst_value_binding, value_binding_list) -> - return (Struct_value (rec_flag, fst_value_binding, [])) - <+> of_list (List.map (fun vb -> Struct_value (rec_flag, vb, [])) value_binding_list) - <+> (shrink_value_binding fst_value_binding - >|= fun fst_value_binding' -> - Struct_value (rec_flag, fst_value_binding', value_binding_list)) - <+> (list ~shrink:shrink_value_binding value_binding_list - >|= fun value_binding_list' -> - Struct_value (rec_flag, fst_value_binding, value_binding_list')) -;; - -let shrink_structure = list ~shrink:shrink_structure_item diff --git a/OCamlPrintf/lib/shrinker.mli b/OCamlPrintf/lib/shrinker.mli deleted file mode 100644 index 31541793e..000000000 --- a/OCamlPrintf/lib/shrinker.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val shrink_structure : Ast.structure QCheck.Shrink.t diff --git a/OCamlPrintf/repl/REPL.ml b/OCamlPrintf/repl/REPL.ml deleted file mode 100644 index 5d908c887..000000000 --- a/OCamlPrintf/repl/REPL.ml +++ /dev/null @@ -1,124 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_printf_lib -open Stdio - -type opts = - { mutable dump_parsetree : bool - ; mutable inference : bool - ; mutable input_file : string option - } - -let pp_global_error ppf = function - | #Inferencer.error as e -> Inferencer.pp_error ppf e - | #Interpreter.error as e -> Interpreter.pp_error ppf e -;; - -let run_single dump_parsetree inference input_source = - let run text env_infer env_inter = - let ast = Parser.parse text in - match ast with - | Error error -> - print_endline (Format.asprintf "Parsing error: %s" error); - env_infer, env_inter - | Ok ast -> - if dump_parsetree - then ( - print_endline (Ast.show_structure ast); - env_infer, env_inter) - else ( - match Inferencer.run_inferencer env_infer ast with - | Error e_infer -> - print_endline (Format.asprintf "Inferencer error: %a" pp_global_error e_infer); - env_infer, env_inter - | Ok (env_infer, out_infer_list) -> - if inference - then ( - List.iter - (function - | Some id, type' -> - print_endline - (Format.asprintf "val %s : %a" id Pprinter.pp_core_type type') - | None, type' -> - print_endline (Format.asprintf "- : %a" Pprinter.pp_core_type type')) - out_infer_list; - env_infer, env_inter) - else ( - print_endline "*** Printed ***"; - match Interpreter.run_interpreter env_inter ast with - | Ok (env_inter, out_inter_list) -> - print_endline "\n*** Output ***"; - List.iter2 - (fun (_, val') -> function - | Some id, type' -> - print_endline - (Format.asprintf - "val %s : %a = %a" - id - Pprinter.pp_core_type - type' - Interpreter.pp_value - val') - | None, type' -> - print_endline - (Format.asprintf - "- : %a = %a" - Pprinter.pp_core_type - type' - Interpreter.pp_value - val')) - out_inter_list - out_infer_list; - env_infer, env_inter - | Error e_inter -> - print_endline - (Format.asprintf "Interpreter error: %a" pp_global_error e_inter); - env_infer, env_inter)) - in - let env_infer, env_inter = - Inferencer.env_with_print_funs, Interpreter.env_with_print_funs - in - match input_source with - | Some file_name -> - let text = In_channel.read_all file_name |> String.trim in - let _, _ = run text env_infer env_inter in - () - | None -> - let rec input_lines lines env_infer env_inter = - match In_channel.input_line stdin with - | Some line -> - if line = ";;" || String.ends_with ~suffix:";;" line - then ( - let env_infer, env_inter = run (lines ^ line) env_infer env_inter in - input_lines "" env_infer env_inter) - else input_lines (lines ^ line) env_infer env_inter - | None -> () - in - let _ = input_lines "" env_infer env_inter in - () -;; - -let () = - let options = { dump_parsetree = false; inference = false; input_file = None } in - let () = - let open Arg in - parse - [ ( "-dparsetree" - , Unit (fun () -> options.dump_parsetree <- true) - , "Dump parse tree, don't evaluate anything" ) - ; ( "-inference" - , Unit (fun () -> options.inference <- true) - , "Inference, don't evaluate anything" ) - ; ( "-fromfile" - , String (fun filename -> options.input_file <- Some filename) - , "Read code from the file" ) - ] - (fun _ -> - Format.eprintf "Positional arguments are not supported\n"; - exit 1) - "Read-Eval-Print-Loop for custom language" - in - run_single options.dump_parsetree options.inference options.input_file -;; diff --git a/OCamlPrintf/repl/REPL.mli b/OCamlPrintf/repl/REPL.mli deleted file mode 100644 index 7d4ee4852..000000000 --- a/OCamlPrintf/repl/REPL.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPrintf/repl/dune b/OCamlPrintf/repl/dune deleted file mode 100644 index 265b276e1..000000000 --- a/OCamlPrintf/repl/dune +++ /dev/null @@ -1,5 +0,0 @@ -(executable - (name REPL) - (libraries ocaml_printf_lib stdio) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlPrintf/tests/REPL.t b/OCamlPrintf/tests/REPL.t deleted file mode 100644 index e14359358..000000000 --- a/OCamlPrintf/tests/REPL.t +++ /dev/null @@ -1,121 +0,0 @@ -Copyright 2024-2025, Friend-zva, RodionovMaxim05 -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../repl/REPL.exe -dparsetree -fromfile factorial.txt - [(Struct_value (Recursive, - { pat = (Pat_var "factorial"); - exp = - (Exp_fun ((Pat_var "n"), [], - (Exp_ifthenelse ( - (Exp_apply - ((Exp_ident "<="), - (Exp_apply - ((Exp_ident "n"), (Exp_constant (Const_integer 1)))))), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply - ((Exp_ident "*"), - (Exp_apply - ((Exp_ident "n"), - (Exp_apply - ((Exp_ident "factorial"), - (Exp_apply - ((Exp_ident "-"), - (Exp_apply - ((Exp_ident "n"), - (Exp_constant (Const_integer 1))))))))))))) - )) - )) - }, - [])) - ] - - $ ../repl/REPL.exe -dparsetree < let prime n = - > let rec check_zero x d = - > match d with - > | 1 -> true - > | _ -> x mod d <> 0 && check_zero x (d - 1) - > in - > match n with - > | 0 -> false - > | 1 -> false - > | _ -> check_zero n (n - 1) - > ;; - [(Struct_value (Nonrecursive, - { pat = (Pat_var "prime"); - exp = - (Exp_fun ((Pat_var "n"), [], - (Exp_let (Recursive, - { pat = (Pat_var "check_zero"); - exp = - (Exp_fun ((Pat_var "x"), [(Pat_var "d")], - (Exp_match ((Exp_ident "d"), - { left = (Pat_constant (Const_integer 1)); - right = (Exp_construct ("true", None)) }, - [{ left = Pat_any; - right = - (Exp_apply - ((Exp_ident "&&"), - (Exp_apply - ((Exp_apply - ((Exp_ident "<>"), - (Exp_apply - ((Exp_apply - ((Exp_apply - ((Exp_ident "x"), - (Exp_ident "mod"))), - (Exp_ident "d"))), - (Exp_constant (Const_integer 0)))))), - (Exp_apply - ((Exp_apply - ((Exp_ident "check_zero"), - (Exp_ident "x"))), - (Exp_apply - ((Exp_ident "-"), - (Exp_apply - ((Exp_ident "d"), - (Exp_constant (Const_integer 1)))))))))))) - } - ] - )) - )) - }, - [], - (Exp_match ((Exp_ident "n"), - { left = (Pat_constant (Const_integer 0)); - right = (Exp_construct ("false", None)) }, - [{ left = (Pat_constant (Const_integer 1)); - right = (Exp_construct ("false", None)) }; - { left = Pat_any; - right = - (Exp_apply - ((Exp_apply ((Exp_ident "check_zero"), (Exp_ident "n"))), - (Exp_apply - ((Exp_ident "-"), - (Exp_apply - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)))))))) - } - ] - )) - )) - )) - }, - [])) - ] - - $ ../repl/REPL.exe < let a = ;; - > let rec x = x + 1;; - > let f b = b;; - > f "const";; - Parsing error: : end_of_input - Inferencer error: This kind of expression is not allowed as right-hand side of `let rec' - *** Printed *** - - *** Output *** - val f : 'a -> 'a = - *** Printed *** - - *** Output *** - - : string = "const" diff --git a/OCamlPrintf/tests/dune b/OCamlPrintf/tests/dune deleted file mode 100644 index 60fbc805f..000000000 --- a/OCamlPrintf/tests/dune +++ /dev/null @@ -1,51 +0,0 @@ -(library - (name tests) - (libraries ocaml_printf_lib) - (modules Test_parser Test_pprinter Test_inferencer Test_interpreter) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to REPL infer eval) - (deps - ../repl/REPL.exe - factorial.txt - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml)) - -(executable - (name run_qchecker) - (modules run_qchecker) - (libraries ocaml_printf_lib) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to qchecker) - (deps run_qchecker.exe)) diff --git a/OCamlPrintf/tests/eval.t b/OCamlPrintf/tests/eval.t deleted file mode 100644 index 3886d5bf9..000000000 --- a/OCamlPrintf/tests/eval.t +++ /dev/null @@ -1,124 +0,0 @@ -Copyright 2024-2025, Friend-zva, RodionovMaxim05 -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../repl/REPL.exe -fromfile manytests/typed/001fac.ml - *** Printed *** - 24 - *** Output *** - val fac : int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/002fac.ml - *** Printed *** - 24 - *** Output *** - val fac_cps : int -> (int -> 'a) -> 'a = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/003fib.ml - *** Printed *** - 33 - *** Output *** - val fib_acc : int -> int -> int -> int = - val fib : int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/004manyargs.ml - *** Printed *** - 1111111111110100 - *** Output *** - val wrap : 'a -> 'a = - val test3 : int -> int -> int -> int = - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/005fix.ml - *** Printed *** - 720 - *** Output *** - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = - val fac : (int -> int) -> int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/006partial.ml - *** Printed *** - 1122 - *** Output *** - val foo : int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/006partial2.ml - *** Printed *** - 1237 - *** Output *** - val foo : int -> int -> int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/006partial3.ml - *** Printed *** - 489 - *** Output *** - val foo : int -> int -> int -> unit = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/007order.ml - *** Printed *** - 124-1103-55555510000 - *** Output *** - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int = - val main : unit = () - - $ ../repl/REPL.exe -fromfile manytests/typed/008ascription.ml - *** Printed *** - 8 - *** Output *** - val addi : ('a -> bool -> int) -> ('a -> bool) -> 'a -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/009let_poly.ml - *** Printed *** - - *** Output *** - val temp : int * bool = (1, true) - - $ ../repl/REPL.exe -fromfile manytests/typed/010sukharev.ml - *** Printed *** - - *** Output *** - val _1 : int -> int -> int * 'a -> bool = - val _2 : int = 1 - val _3 : (int * string) option = Some (1, "hi") - val _4 : int -> 'a = - val _5 : int = 42 - val _6 : 'a option -> 'a = - val int_of_option : int option -> int = - val _42 : int -> bool = - val id1 : 'a -> 'a = - val id2 : 'b -> 'b = - - $ ../repl/REPL.exe -fromfile manytests/typed/015tuples.ml - *** Printed *** - 1111 - *** Output *** - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = - val map : ('b -> 'a) -> 'b * 'b -> 'a * 'a = - val fixpoly : (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) * (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) -> ('a -> 'b) * ('a -> 'b) = - val feven : 'a * (int -> int) -> int -> int = - val fodd : (int -> int) * 'a -> int -> int = - val tie : (int -> int) * (int -> int) = (, ) - val meven : int -> int = - val modd : int -> int = - val main : int = 0 - - $ ../repl/REPL.exe -fromfile manytests/typed/016lists.ml - *** Printed *** - 1238 - *** Output *** - val length : 'a list -> int = - val length_tail : 'a list -> int = - val map : ('a -> 'b) -> 'a list -> 'b list = - val append : 'a list -> 'a list -> 'a list = - val concat : 'a list list -> 'a list = - val iter : ('a -> unit) -> 'a list -> unit = - val cartesian : 'b list -> 'a list -> ('b * 'a) list = - val main : int = 0 diff --git a/OCamlPrintf/tests/factorial.txt b/OCamlPrintf/tests/factorial.txt deleted file mode 100644 index fbaf8c6d3..000000000 --- a/OCamlPrintf/tests/factorial.txt +++ /dev/null @@ -1 +0,0 @@ -let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1);; diff --git a/OCamlPrintf/tests/infer.t b/OCamlPrintf/tests/infer.t deleted file mode 100644 index e14117260..000000000 --- a/OCamlPrintf/tests/infer.t +++ /dev/null @@ -1,118 +0,0 @@ -Copyright 2024-2025, Friend-zva, RodionovMaxim05 -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../repl/REPL.exe -inference -fromfile factorial.txt - val factorial : int -> int - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/001.ml - Inferencer error: Undefined variable 'fac' - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/002if.ml - Inferencer error: Unification failed on int and bool - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/003occurs.ml - Inferencer error: Occurs check failed: the type variable 'ty1 occurs inside 'ty1 -> 'ty3 - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/004let_poly.ml - Inferencer error: Unification failed on int and bool - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/005.ml - Inferencer error: Unification failed on string and int - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/015tuples.ml - Inferencer error: Only variables are allowed as left-hand side of `let rec' - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/016tuples_mismatch.ml - Inferencer error: Unification failed on int * int * int and 'ty0 * 'ty1 - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/097fun_vs_list.ml - Inferencer error: Unification failed on 'ty0 -> 'ty0 and 'ty1 list - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/097fun_vs_unit.ml - Inferencer error: Unification failed on 'ty0 -> 'ty0 and unit - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/098rec_int.ml - Inferencer error: This kind of expression is not allowed as right-hand side of `let rec' - - $ ../repl/REPL.exe -inference -fromfile manytests/do_not_type/099.ml - Inferencer error: Only variables are allowed as left-hand side of `let rec' - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/001fac.ml - val fac : int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/002fac.ml - val fac_cps : int -> (int -> 'a) -> 'a - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/003fib.ml - val fib_acc : int -> int -> int -> int - val fib : int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/004manyargs.ml - val wrap : 'a -> 'a - val test3 : int -> int -> int -> int - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/005fix.ml - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val fac : (int -> int) -> int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/006partial.ml - val foo : int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/006partial2.ml - val foo : int -> int -> int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/006partial3.ml - val foo : int -> int -> int -> unit - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/007order.ml - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main : unit - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/008ascription.ml - val addi : ('a -> bool -> int) -> ('a -> bool) -> 'a -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/009let_poly.ml - val temp : int * bool - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/010sukharev.ml - val _1 : int -> int -> int * 'a -> bool - val _2 : int - val _3 : (int * string) option - val _4 : int -> 'a - val _5 : int - val _6 : 'a option -> 'a - val int_of_option : int option -> int - val _42 : int -> bool - val id1 : 'a -> 'a - val id2 : 'b -> 'b - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/015tuples.ml - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val map : ('b -> 'a) -> 'b * 'b -> 'a * 'a - val fixpoly : (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) * (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) -> ('a -> 'b) * ('a -> 'b) - val feven : 'a * (int -> int) -> int -> int - val fodd : (int -> int) * 'a -> int -> int - val tie : (int -> int) * (int -> int) - val meven : int -> int - val modd : int -> int - val main : int - - $ ../repl/REPL.exe -inference -fromfile manytests/typed/016lists.ml - val length : 'a list -> int - val length_tail : 'a list -> int - val map : ('a -> 'b) -> 'a list -> 'b list - val append : 'a list -> 'a list -> 'a list - val concat : 'a list list -> 'a list - val iter : ('a -> unit) -> 'a list -> unit - val cartesian : 'b list -> 'a list -> ('b * 'a) list - val main : int diff --git a/OCamlPrintf/tests/manytests b/OCamlPrintf/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/OCamlPrintf/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/OCamlPrintf/tests/qchecker.t b/OCamlPrintf/tests/qchecker.t deleted file mode 100644 index b7cc77187..000000000 --- a/OCamlPrintf/tests/qchecker.t +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2024-2025, Friend-zva, RodionovMaxim05 -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ./run_qchecker.exe -s 20242025 - seed: 20242025 - ================================================================================ - success (ran 1 tests) diff --git a/OCamlPrintf/tests/run_qchecker.ml b/OCamlPrintf/tests/run_qchecker.ml deleted file mode 100644 index 15fd418c5..000000000 --- a/OCamlPrintf/tests/run_qchecker.ml +++ /dev/null @@ -1,10 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_printf_lib.Qchecker - -let () = - let _ : int = run_gen ~show_passed:false ~show_shrinker:false ~count:10 in - () -;; diff --git a/OCamlPrintf/tests/run_qchecker.mli b/OCamlPrintf/tests/run_qchecker.mli deleted file mode 100644 index 7d4ee4852..000000000 --- a/OCamlPrintf/tests/run_qchecker.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPrintf/tests/test_inferencer.ml b/OCamlPrintf/tests/test_inferencer.ml deleted file mode 100644 index 2daacb34f..000000000 --- a/OCamlPrintf/tests/test_inferencer.ml +++ /dev/null @@ -1,344 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_printf_lib.Parser -open Ocaml_printf_lib.Pprinter -open Ocaml_printf_lib.Inferencer - -let run str = - match parse str with - | Ok ast -> - (match run_inferencer empty_env ast with - | Ok (_, out_list) -> - List.iter - (function - | Some id, type' -> Format.printf "val %s : %a\n" id pp_core_type type' - | None, type' -> Format.printf "- : %a\n" pp_core_type type') - out_list - | Error e -> Format.printf "Inferencer error: %a\n" pp_error e) - | Error _ -> Format.printf "Parsing error\n" -;; - -let%expect_test "parsing error" = - run {| - let a = ;; - |}; - [%expect {| - Parsing error - |}] -;; - -let%expect_test "type check undefined variable" = - run {| - let a = b - |}; - [%expect {| - Inferencer error: Undefined variable 'b' - |}] -;; - -let%expect_test "type check negative expression" = - run {| - let f a q = -(if a then q else -q) - |}; - [%expect {| - val f : bool -> int -> int - |}] -;; - -let%expect_test "type check definition tuple" = - run {| - let (a, b) = (1, 2);; - |}; - [%expect {| - val a : int - val b : int - |}] -;; - -let%expect_test "type check definition variable" = - run {| - let a = 5 - |}; - [%expect {| - val a : int - |}] -;; - -let%expect_test "type check several definition variable" = - run {| - let f = 1 and r = "qwe";; let q = 2 - |}; - [%expect {| - val f : int - val r : string - val q : int - |}] -;; - -let%expect_test "type check several definition variable and executable them" = - run {| - let f a = a and a = 1;; - f "hello";; - a;; - |}; - [%expect {| - val f : 'a -> 'a - val a : int - - : string - - : int - |}] -;; - -let%expect_test "type check several recursive definition" = - run {| - let rec f1 a = a + 1 and f2 b = f1 b;; - |}; - [%expect {| - val f1 : int -> int - val f2 : int -> int - |}] -;; - -let%expect_test "type check definition function" = - run {| - let f a b c = if a then b else c - |}; - [%expect {| - val f : bool -> 'a -> 'a -> 'a - |}] -;; - -let%expect_test "type check definition construct" = - run {| - let (a :: b :: []) = [ 1; 2 ] - |}; - [%expect {| - val a : int - val b : int - |}] -;; - -let%expect_test "type check simple recursive let expression" = - run {| - let rec x : int = 1;; - |}; - [%expect {| - val x : int - |}] -;; - -let%expect_test "type check error in recursive let expression" = - run {| - let rec x = x + 1;; - |}; - [%expect - {| - Inferencer error: This kind of expression is not allowed as right-hand side of `let rec' - |}] -;; - -let%expect_test "type check recursive let expression" = - run - {| - let prime n = - let rec check_zero x d = - match d with - | 1 -> true - | _ -> x + d <> 0 && check_zero x (d - 1) - in - match n with - | 0 -> false - | 1 -> false - | _ -> check_zero n (n - 1) - ;; - |}; - [%expect {| - val prime : int -> bool - |}] -;; - -let%expect_test "type check of operators" = - run {| - let f x y z = if x + 1 = 0 && y = 1 || z >= 'w' then 2 else 26;; - |}; - [%expect {| - val f : int -> int -> char -> int - |}] -;; - -let%expect_test "type check pattern matching" = - run {| - let f a b = match a b with 1 -> 'q' | 2 -> 'w' | _ -> 'e' - |}; - [%expect {| - val f : ('a -> int) -> 'a -> char - |}] -;; - -let%expect_test "type check pattern bound the variable multiple times" = - run {| - let f = function - | x, x -> true - | _ -> false - |}; - [%expect - {| - Inferencer error: Variable 'x' is bound several times in the matching - |}] -;; - -let%expect_test "type check of expression list" = - run {| - let f a = [a; true] - |}; - [%expect {| - val f : bool -> bool list - |}] -;; - -let%expect_test "type check invalid expression list" = - run {| - let f a = [true; a; 2] - |}; - [%expect {| - Inferencer error: Unification failed on bool and int - |}] -;; - -let%expect_test "type check pattern and expression list construct" = - run - {| - let f p = - let list = 1 :: 2 :: p in - match list with - | 1 :: 2 :: [ 3; 4 ] -> true - | [ 1; 2 ] -> true - | _ -> false - |}; - [%expect {| - val f : int list -> bool - |}] -;; - -let%expect_test "type check pattern-matching" = - run - {| - let fmap f xs = - match xs with - | a :: [] -> [ f a ] - | a :: b :: [] -> [ f a; f b ] - | a :: b :: c :: [] -> [ f a; f b; f c ] - | _ -> [] - ;; - |}; - [%expect {| - val fmap : ('b -> 'a) -> 'b list -> 'a list - |}] -;; - -let%expect_test "type check of pattern list" = - run {| - let f a = match a with | [q; 1] -> q | [w; _] -> w - |}; - [%expect {| - val f : int list -> int - |}] -;; - -let%expect_test "type check Some and None" = - run - {| - let f a = - match a with - | Some (_) -> Some ('a') - | None -> None - ;; - |}; - [%expect {| - val f : 'a option -> char option - |}] -;; - -let%expect_test "type check definition function" = - run {| - let f = function - | Some (a) -> (a) - | None -> false - |}; - [%expect {| - val f : bool option -> bool - |}] -;; - -let%expect_test "type check expression constraint" = - run {| - let f a b = (b a : int) - |}; - [%expect {| - val f : 'a -> ('a -> int) -> int - |}] -;; - -let%expect_test "type check pattern constraint" = - run {| - let f (q : int -> 'a option) (x : int) = q x - |}; - [%expect {| - val f : (int -> 'a option) -> int -> 'a option - |}] -;; - -let%expect_test "type check pattern constraint with type var" = - run - {| - let f1 (q : 'a -> 'b) (x : 'a) = q x;; - let f2 (q : 'a -> 'b) (x : 'b) = q x;; - let f3 (q : 'a -> 'b) (x : 'c) = q x;; - |}; - [%expect - {| - val f1 : ('a -> 'b) -> 'a -> 'b - val f2 : ('a -> 'a) -> 'a -> 'a - val f3 : ('a -> 'b) -> 'a -> 'b - |}] -;; - -let%expect_test "type check recursive struct value" = - run - {| - let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1) - and strange_factorial k = if k <= 1 then 1 else k + strange_factorial (k - 1) - |}; - [%expect {| - val factorial : int -> int - val strange_factorial : int -> int - |}] -;; - -let%expect_test "type check polymorphism" = - run - {| - let rec f1 x = x;; - let foo1 = f1 1;; - let foo2 = f1 'a';; - let foo3 = f1 foo1;; - - let f2 x = x;; - let foo4 = f2 1;; - let foo5 = f2 'a';; - let foo6 = f2 foo5;; - |}; - [%expect - {| - val f1 : 'a -> 'a - val foo1 : int - val foo2 : char - val foo3 : int - val f2 : 'a -> 'a - val foo4 : int - val foo5 : char - val foo6 : char - |}] -;; diff --git a/OCamlPrintf/tests/test_inferencer.mli b/OCamlPrintf/tests/test_inferencer.mli deleted file mode 100644 index 7d4ee4852..000000000 --- a/OCamlPrintf/tests/test_inferencer.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPrintf/tests/test_interpreter.ml b/OCamlPrintf/tests/test_interpreter.ml deleted file mode 100644 index 5385fea7b..000000000 --- a/OCamlPrintf/tests/test_interpreter.ml +++ /dev/null @@ -1,126 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_printf_lib.Parser -open Ocaml_printf_lib.Interpreter - -let run str = - match parse str with - | Ok ast -> - (match run_interpreter empty_env ast with - | Ok (_, out_list) -> - List.iter - (function - | Some id, val' -> Format.printf "val %s = %a\n" id pp_value val' - | None, val' -> Format.printf "- = %a\n" pp_value val') - out_list - | Error e -> Format.printf "Interpreter error: %a\n" pp_error e) - | Error _ -> Format.printf "Parsing error\n" -;; - -let%expect_test "parsing error" = - run {| - let a = ;; - |}; - [%expect {| - Parsing error - |}] -;; - -let%expect_test "eval simple let binding" = - run {| - let a = -(4 + 4) - and b = true;; - |}; - [%expect {| - val a = -8 - val b = true - |}] -;; - -let%expect_test "eval tuple and list let bindings" = - run {| - let a, b = 1, (2, 3);; - let [ c; d ] = 3 :: 4 :: [] - |}; - [%expect {| - val a = 1 - val b = (2, 3) - val c = 3 - val d = 4 - |}] -;; - -let%expect_test "eval `let in'" = - run {| - let f = - let x = "abc" in - let y = "qwerty" in - x <> y - ;; - |}; - [%expect {| - val f = true - |}] -;; - -let%expect_test "eval 'Struct_eval'" = - run {| - 1;; - |}; - [%expect {| - - = 1 - |}] -;; - -let%expect_test "eval 'Exp_fun'" = - run {| - let foo x y = x * y - let q = foo 1 6 - let w = foo 2 (-5) - |}; - [%expect {| - val foo = - val q = 6 - val w = -10 - |}] -;; - -let%expect_test "eval recursive value binding 1" = - run {| - let rec x = 21 and y = x + 1;; - |}; - [%expect {| - val x = 21 - val y = 22 - |}] -;; - -let%expect_test "eval recursive value binding 2" = - run - {| - let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1);; - factorial 5 - |}; - [%expect {| - val factorial = - - = 120 - |}] -;; - -let%expect_test "eval pattern-matching" = - run - {| - let f = - match [ 1; 2; 3 ] with - | a :: [] -> a - | a :: b :: [] -> a + b - | a :: b :: c :: [] -> a + b + c - | _ -> 0 - ;; - |}; - [%expect {| - val f = 6 - |}] -;; diff --git a/OCamlPrintf/tests/test_interpreter.mli b/OCamlPrintf/tests/test_interpreter.mli deleted file mode 100644 index 7d4ee4852..000000000 --- a/OCamlPrintf/tests/test_interpreter.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlPrintf/tests/test_parser.ml b/OCamlPrintf/tests/test_parser.ml deleted file mode 100644 index a9468e027..000000000 --- a/OCamlPrintf/tests/test_parser.ml +++ /dev/null @@ -1,270 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_printf_lib.Parser -open Ocaml_printf_lib.Pprinter - -let run str = - match parse str with - | Ok ast -> Format.printf "%a \n" pp_structure ast - | Error error -> Format.printf "%s" error -;; - -let%expect_test "parsing error" = - run {| - let a = ;; - |}; - [%expect {| - : end_of_input - |}] -;; - -let%expect_test "parsing factorial with `match'" = - run - {| - let rec factorial n = - match n with - | 0 -> 1 - | 1 -> 1 - | _ -> n * factorial (n - 1) - ;; - |}; - [%expect - {| - let rec factorial n = - match n with - | 0 -> 1 - | 1 -> 1 - | _ -> n * factorial (n - 1) - ;; - |}] -;; - -let%expect_test "parsing expression with `fun'" = - run {| - let sum1 = fun x y -> (x + y) - let sum2 = fun x -> (fun y -> x + y) - |}; - [%expect {| - let sum1 x y = x + y;; - let sum2 x = fun y -> x + y;; - |}] -;; - -let%expect_test "parsing pattern and expression tuples" = - run {| - let a, b = 1, 2 - let a, b, c = -1, 2 + 3, f d - |}; - [%expect {| - let a, b = 1, 2;; - let a, b, c = -1, 2 + 3, f d;; - |}] -;; - -let%expect_test "parsing pattern and expression list" = - run - {| - let list [ a; b; c ] = [ a; b; c ];; - let foo1 = f [ a; b ];; - let foo2 = [ f a; f b ];; - let foo3 = f [ f a; f b ];; - let foo4 = f [ f a; [ f a; f b ] ];; - let foo5 = f [ [ f a; [ f a; f b ] ] ];; - [] + [];; - [ 1 + 2; -3; f a ] + [ f a; f b ];; - [ [ [] + []; -3; f a ] ] + [ [ f a; f b ] ] - |}; - [%expect - {| - let list [ a; b; c ] = [ a; b; c ];; - let foo1 = f [ a; b ];; - let foo2 = [ f a; f b ];; - let foo3 = f [ f a; f b ];; - let foo4 = f [ f a; [ f a; f b ] ];; - let foo5 = f [ [ f a; [ f a; f b ] ] ];; - [] + [];; - [ 1 + 2; -3; f a ] + [ f a; f b ];; - [ [ [] + []; -3; f a ] ] + [ [ f a; f b ] ];; - |}] -;; - -let%expect_test "parsing option and bool types" = - run - {| - let f = function - | Some (_) -> true - | None -> false - ;; - Some true;; - Some (Some true) - |}; - [%expect - {| - let f = function - | Some (_) -> true - | None -> false;; - Some (true);; - Some (Some (true));; - |}] -;; - -let%expect_test "parsing expression with `let'" = - run {| - 1 + let two = 2 in two * 3 - |}; - [%expect {| - 1 + (let two = 2 in two * 3);; - |}] -;; - -let%expect_test "parsing several structure items" = - run {| - let squared x = x * x;; - squared 5 - |}; - [%expect {| - let squared x = x * x;; - squared 5;; - |}] -;; - -let%expect_test "parsing expression sequence" = - run - {| - let a = (1, 2, ((); 3));; - [ (a; b) ];; - [ f a; [ () ]; ((); []) ];; - let a = [ ( (); 1); ( ( (); 2)); ( ((); (); 3) ); (((); 4); 5)] - |}; - [%expect - {| - let a = 1, 2, ((); 3);; - [ (a; b) ];; - [ f a; [ () ]; ((); []) ];; - let a = [ ((); 1); ((); 2); (((); ()); 3); (((); 4); 5) ];; - |}] -;; - -let%expect_test "parsing identifiers with explicitly assigned types 1" = - run {| - let f : int list = [ 1; 2; 3 ];; - |}; - [%expect {| - let f : int list = [ 1; 2; 3 ];; - |}] -;; - -let%expect_test "parsing identifiers with explicitly assigned types 2" = - run - {| - let f : int * char * string list = (1, 'a', ["first"; "second"; "third"]);; - |}; - [%expect - {| - let f : int * char * string list = 1, 'a', [ "first"; "second"; "third" ];; - |}] -;; - -let%expect_test "parsing identifiers with explicitly assigned types 3" = - run {| - let f (a : int) (b : int) : int = a + b;; - |}; - [%expect {| - let f (a : int) (b : int) : int = a + b;; - |}] -;; - -let%expect_test "parsing identifiers with explicitly assigned types 4" = - run {| - let (a : int -> (char -> int) -> int) = 1 + (x : char -> int);; - |}; - [%expect {| - let a : int -> (char -> int) -> int = 1 + (x : char -> int);; - |}] -;; - -let%expect_test "parsing chain right associative" = - run - {| - let f x y z = if x && (y || z && (y || x) || y) then true else false;; - let list (a :: b :: [ c ]) = a :: b :: [ c + 1 ] - |}; - [%expect - {| - let f x y z = if x && (y || z && (y || x) || y) then true else false;; - let list [ a; b; c ] = [ a; b; c + 1 ];; - |}] -;; - -let%expect_test "parsing chain left associative" = - run - {| - 8 / 800 - 555 * (35 + 35);; - let f x y z = if x = (y >= z && (y <= x) = y) then true else false;; - let f a b c = g a (b + c) b (a * b);; - let f a b c = a; b a; c [ a ];; - let f a : (int option list * unit option -> bool list option list) * string option option = a - |}; - [%expect - {| - 8 / 800 - 555 * (35 + 35);; - let f x y z = if x = (y >= z && y <= x = y) then true else false;; - let f a b c = g a (b + c) b (a * b);; - let f a b c = (a; b a); c [ a ];; - let f - a - : (int option list * unit option -> bool list option list) * string option option - = a - ;; - |}] -;; - -let%expect_test "parsing expression with priority" = - run - {| - 1 + 2 + 3;; - (1 + 2) - 3;; - (1 + 2) * 3;; - 3 * (1 + 2);; - (1 + 2) * (3 + 4);; - 1 * 2 * (3 + 4);; - (1 + 2) * 3 * 4;; - 1 / 2 - 3 * 4;; - g * f a (b + c) (d e) - |}; - [%expect - {| - 1 + 2 + 3;; - 1 + 2 - 3;; - (1 + 2) * 3;; - 3 * (1 + 2);; - (1 + 2) * (3 + 4);; - 1 * 2 * (3 + 4);; - (1 + 2) * 3 * 4;; - 1 / 2 - 3 * 4;; - g * f a (b + c) (d e);; - |}] -;; - -let%expect_test "parsing negative expressions" = - run - {| - -2 + 1;; - -(2 + -2);; - -(-1 + 1);; - let f a = -a;; - let f a = -(if a then -1 else 2);; - g * f (-a) (-b + c) (d (-e)) - |}; - [%expect - {| - -2 + 1;; - -(2 + -2);; - -(-1 + 1);; - let f a = -a;; - let f a = -(if a then -1 else 2);; - g * f (-a) (-b + c) (d (-e));; - |}] -;; diff --git a/OCamlPrintf/tests/test_parser.mli b/OCamlPrintf/tests/test_parser.mli deleted file mode 100644 index 3032386cd..000000000 --- a/OCamlPrintf/tests/test_parser.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run : string -> unit diff --git a/OCamlPrintf/tests/test_pprinter.ml b/OCamlPrintf/tests/test_pprinter.ml deleted file mode 100644 index 8999104db..000000000 --- a/OCamlPrintf/tests/test_pprinter.ml +++ /dev/null @@ -1,235 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Test_parser - -let%expect_test "parsing and pretty printing" = - run - {| -if true then 1 else 0;; - -let a b = if true then 1 else 0;; - -match - function - | _ -> true -with -| b -> true -;; - -if match b with - | b -> true -then ( - match b with - | b -> true) -else ( - match b with - | b -> true) -;; - -let a b = - match b with - | b -> - (match - function - | _ -> true - with - | b -> true) -;; - -let a b = - if match b with - | b -> true - then ( - match b with - | b -> true) - else ( - match b with - | b -> true) -;; - -let f a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a = 1;; - -match b with -| [ a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a; a ] -> true -| [ a; a; a; a; a ] -> false -| a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a -> true -| a, a, a, a, a, a -> false -| _ -> false -;; - |}; - [%expect - {| -if true then 1 else 0;; -let a b = if true then 1 else 0;; -match - function - | _ -> true with -| b -> true;; -if match b with - | b -> true -then - (match b with - | b -> true) -else - (match b with - | b -> true);; -let a b = match b with - | b -> - (match - function - | _ -> true with - | b -> true);; -let a b = - if match b with - | b -> true - then - (match b with - | b -> true) - else - (match b with - | b -> true) -;; -let f - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - a - = 1 -;; -match b with -| [ a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ; a - ] -> true -| [ a; a; a; a; a ] -> false -| ( a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a - , a ) -> true -| ( a, a, a, a, a, a ) -> false -| _ -> false;; - |}] -;; diff --git a/OCamlPrintf/tests/test_pprinter.mli b/OCamlPrintf/tests/test_pprinter.mli deleted file mode 100644 index 7d4ee4852..000000000 --- a/OCamlPrintf/tests/test_pprinter.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Friend-zva, RodionovMaxim05 *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/.envrc b/OCamlRV/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/OCamlRV/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/OCamlRV/.gitignore b/OCamlRV/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/OCamlRV/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/OCamlRV/.ocamlformat b/OCamlRV/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/OCamlRV/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/OCamlRV/.zanuda b/OCamlRV/.zanuda deleted file mode 100644 index dd0f2efa8..000000000 --- a/OCamlRV/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore bin/main.ml diff --git a/OCamlRV/COPYING b/OCamlRV/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/OCamlRV/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OCamlRV/COPYING.CC0 b/OCamlRV/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/OCamlRV/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/OCamlRV/COPYING.LESSER b/OCamlRV/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/OCamlRV/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/OCamlRV/Makefile b/OCamlRV/Makefile deleted file mode 100644 index 228423529..000000000 --- a/OCamlRV/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -.PHONY: all run fmt lint zanuda - -all: - dune build -j8 - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -zanuda: - dune build @check @runtest -j4 - zanuda -dir . diff --git a/OCamlRV/OCamlRV.opam b/OCamlRV/OCamlRV.opam deleted file mode 100644 index af2530375..000000000 --- a/OCamlRV/OCamlRV.opam +++ /dev/null @@ -1,43 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "OCaml with Recursive values" -description: - "An interpreter for mini version of OCaml with support of Recursive values" -maintainer: [ - "Viacheslav Sidorov " - "Danila Rudnev-Stepanyan " -] -authors: [ - "Viacheslav Sidorov " - "Danila Rudnev-Stepanyan " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/xamelllion/OCamlRV" -doc: "https://kakadu.github.io/fp2024/docs/OCamlRV" -bug-reports: "https://github.com/xamelllion/OCamlRV" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "ppx_deriving_qcheck" - "bisect_ppx" - "qcheck-core" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OCamlRV/README.md b/OCamlRV/README.md deleted file mode 100644 index 2c7c13cfb..000000000 --- a/OCamlRV/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# OCaml + Recursive values - -### How to build -``` -dune build . -``` - - -### How to run -``` -dune exec -- main bin/example.ml -interpret -dparsetree -``` diff --git a/OCamlRV/bin/dune b/OCamlRV/bin/dune deleted file mode 100644 index 44bdb83ad..000000000 --- a/OCamlRV/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name main) - (public_name main) - (libraries OCamlRV_lib stdio) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlRV/bin/example.ml b/OCamlRV/bin/example.ml deleted file mode 100644 index 679282375..000000000 --- a/OCamlRV/bin/example.ml +++ /dev/null @@ -1,13 +0,0 @@ -let rec list_iter l n = - if n = 0 - then () - else ( - match l with - | [] -> () - | [ x ] -> print_int x - | x :: xs -> - let () = print_int x in - list_iter xs (n - 1)) -;; - -list_iter [ 1; 2; 3; 4; 5 ] 5 diff --git a/OCamlRV/bin/main.ml b/OCamlRV/bin/main.ml deleted file mode 100644 index 47972f022..000000000 --- a/OCamlRV/bin/main.ml +++ /dev/null @@ -1,65 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Parser -open OCamlRV_lib.Interpreter -open OCamlRV_lib.Inferencer -open Stdio - -type opts = - { mutable dump_parsetree : bool - ; mutable interpret : bool - ; mutable inference : bool - ; mutable read_from_file : bool - ; mutable filename : string - ; mutable debug : bool - } - -let run_single options = - let text = - if options.read_from_file - then ( - try Stdlib.String.trim (Stdio.In_channel.read_all options.filename) with - | Sys_error e -> - Stdlib.Format.printf "%s\n" e; - Stdlib.exit 1) - else Stdlib.String.trim (In_channel.input_all stdin) - in - if options.dump_parsetree then Stdlib.Format.printf "%s\n\n" (parse_to_string text); - if options.inference then run_inferencer text; - if options.interpret then run_interpreter text ~debug:options.debug else () -;; - -let () = - if Array.length Sys.argv = 1 - then () - else ( - let opts = - { dump_parsetree = false - ; interpret = false - ; inference = false - ; read_from_file = false - ; filename = "" - ; debug = false - } - in - let () = - let open Stdlib.Arg in - parse - [ "-dparsetree", Unit (fun () -> opts.dump_parsetree <- true), "Dump parse tree." - ; "-interpret", Unit (fun () -> opts.interpret <- true), "Interpret code." - ; "-inference", Unit (fun () -> opts.inference <- true), "Inference code." - ; "-debug", Unit (fun () -> opts.debug <- true), "Debug mode." - ] - (fun filename -> - if opts.read_from_file - then ( - Stdlib.Format.printf "It can handle only one input file.\n"; - Stdlib.exit 1); - opts.read_from_file <- true; - opts.filename <- filename) - "Runner for OCamlRV" - in - run_single opts) -;; diff --git a/OCamlRV/dune b/OCamlRV/dune deleted file mode 100644 index b7cc7aa0f..000000000 --- a/OCamlRV/dune +++ /dev/null @@ -1,10 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - -(cram - (deps ./bin/main.exe)) diff --git a/OCamlRV/dune-project b/OCamlRV/dune-project deleted file mode 100644 index cf1b53d03..000000000 --- a/OCamlRV/dune-project +++ /dev/null @@ -1,33 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Viacheslav Sidorov " "Danila Rudnev-Stepanyan ") - -(maintainers "Viacheslav Sidorov " "Danila Rudnev-Stepanyan ") - -(bug_reports "https://github.com/xamelllion/OCamlRV") - -(homepage "https://github.com/xamelllion/OCamlRV") - -(package - (name OCamlRV) - (synopsis "OCaml with Recursive values") - (description "An interpreter for mini version of OCaml with support of Recursive values") - (documentation "https://kakadu.github.io/fp2024/docs/OCamlRV") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - ppx_deriving_qcheck - bisect_ppx - qcheck-core - (odoc :with-doc) - (ocamlformat :build) - )) diff --git a/OCamlRV/lib/ast.ml b/OCamlRV/lib/ast.ml deleted file mode 100644 index 1c6ce4031..000000000 --- a/OCamlRV/lib/ast.ml +++ /dev/null @@ -1,165 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type identifier = string [@@deriving show { with_path = false }] - -let gen_char = - let open QCheck.Gen in - map Char.chr (int_range (Char.code 'a') (Char.code 'z')) -;; - -let gen_identifier = - let open QCheck.Gen in - string_size (int_range 1 8) ~gen:gen_char -;; - -let gen_string = - let open QCheck.Gen in - string_size (int_range 0 32) ~gen:gen_char -;; - -let div = 15 - -type binary_operator = - | Add (** + *) - | Sub (** - *) - | Mul (** * *) - | Div (** / *) - | Lt (** < *) - | Gt (** > *) - | Eq (** = *) - | Neq (** <> *) - | Lte (** <= *) - | Gte (** >= *) - | And (** && *) - | Or (** || *) -[@@deriving show { with_path = false }, qcheck] - -type unary_operator = - | UnaryPlus (** + *) - | UnaryMinus (** - *) - | UnaryNeg (** not *) -[@@deriving show { with_path = false }, qcheck] - -type rec_flag = - | NonRec (** let a *) - | Rec (** let rec a *) -[@@deriving show { with_path = false }, qcheck] - -type constant = - | CInt of (int[@gen QCheck.Gen.int_range 0 1000]) - | CBool of bool - | CString of (string[@gen gen_string]) - | CUnit - | CNil -[@@deriving show { with_path = false }, qcheck] - -type fresh = int [@@deriving show { with_path = false }] - -type type_annot = - | AInt - | ABool - | AString - | AUnit - | AVar of (fresh[@gen QCheck.Gen.int_range 0 1000]) - | AFun of type_annot * type_annot - | AList of type_annot - | ATuple of type_annot list - | AOption of type_annot -[@@deriving show { with_path = false }, qcheck] - -type pattern = - | PAny (** _ *) - | PConstant of constant (** 123, true, "string" *) - | PVar of identifier (** x *) - | PCons of pattern * pattern (** p1::p2 *) - | PTuple of - pattern - * pattern - * (pattern list - [@gen QCheck.Gen.(list_size small_nat (gen_pattern_sized (n / div)))]) - (** p_1 ,..., p_n *) - | PList of - pattern - * (pattern list - [@gen QCheck.Gen.(list_size small_nat (gen_pattern_sized (n / div)))]) - | POption of pattern option - | PType of pattern * type_annot -[@@deriving show { with_path = false }, qcheck] - -type expression = - | ExprVariable of identifier (** x | y | z*) - | ExprConstant of constant (** 123 | true | "string" *) - | ExprBinOperation of binary_operator * expression * expression (** 1 + 1 | 2 * 2 *) - | ExprUnOperation of unary_operator * expression (** -x | not true *) - | ExprIf of expression * expression * expression option - (** if expr1 then expr2 else expr3 *) - | ExprMatch of - expression - * case - * (case list[@gen QCheck.Gen.(list_size small_nat (gen_case_sized (n / div)))]) - | ExprFunction of - case * (case list[@gen QCheck.Gen.(list_size small_nat (gen_case_sized (n / div)))]) - (** match e with p_1 -> e_1 |...| p_n -> e_n *) - | ExprLet of - rec_flag - * binding - * (binding list[@gen QCheck.Gen.(list_size (0 -- 4) (gen_binding_sized (n / div)))]) - * expression - (** [ExprLet(rec_flag, (p_1, e_1), [(p_2, e_2) ; ... ; (p_n, e_n)], e)] *) - | ExprApply of expression * expression (** fact n *) - | ExprTuple of - expression - * expression - * (expression list - [@gen QCheck.Gen.(list_size small_nat (gen_expression_sized (n / div)))]) - (** 1, 2, 3 *) - | ExprList of - expression - * (expression list - [@gen QCheck.Gen.(list_size small_nat (gen_expression_sized (n / div)))]) - | ExprCons of expression * expression (** t::tl *) - | ExprFun of (pattern[@gen gen_pattern_sized (n / div)]) * expression (** fun p -> e *) - | ExprOption of expression option - | ExprType of expression * type_annot -[@@deriving show { with_path = false }, qcheck] - -(** Used in `match` expression *) -and case = (pattern[@gen gen_pattern_sized (n / div)]) * expression -[@@deriving show { with_path = false }, qcheck] - -(** Used in `let` expression*) -and binding = (pattern[@gen gen_pattern_sized (n / div)]) * expression -[@@deriving show { with_path = false }, qcheck] - -let gen_expression = - QCheck.Gen.( - let* n = small_nat in - gen_expression_sized n) -;; - -let gen_case = - QCheck.Gen.( - let* n = small_nat in - gen_case_sized n) -;; - -let gen_binding = - QCheck.Gen.( - let* n = small_nat in - gen_binding_sized n) -;; - -type structure_item = - | SEval of expression - | SValue of - rec_flag - * binding - * (binding list[@gen QCheck.Gen.(list_size (0 -- 2) gen_binding)]) - (** [SValue(rec_flag, (p_1, e_1), [(p_2, e_2) ; ... ; (p_n, e_n)])] *) -[@@deriving show { with_path = false }, qcheck] - -type structure = - (structure_item list[@gen QCheck.Gen.(list_size (1 -- 2) gen_structure_item)]) -[@@deriving show { with_path = false }, qcheck] diff --git a/OCamlRV/lib/astPrinter.ml b/OCamlRV/lib/astPrinter.ml deleted file mode 100644 index abee33ab5..000000000 --- a/OCamlRV/lib/astPrinter.ml +++ /dev/null @@ -1,280 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Format - -let pp_binop ppf = function - | Add -> fprintf ppf "+" - | Sub -> fprintf ppf "-" - | Mul -> fprintf ppf "*" - | Div -> fprintf ppf "/" - | Lt -> fprintf ppf "<" - | Gt -> fprintf ppf ">" - | Eq -> fprintf ppf "=" - | Neq -> fprintf ppf "<>" - | Lte -> fprintf ppf "<=" - | Gte -> fprintf ppf ">=" - | And -> fprintf ppf "&&" - | Or -> fprintf ppf "||" -;; - -let pp_unop ppf = function - | UnaryPlus -> fprintf ppf "+" - | UnaryMinus -> fprintf ppf "-" - | UnaryNeg -> fprintf ppf "not " -;; - -let pp_annot = - let rec helper ppf = function - | AInt -> fprintf ppf "int" - | ABool -> fprintf ppf "bool" - | AString -> fprintf ppf "string" - | AUnit -> fprintf ppf "unit" - | AVar n -> fprintf ppf "'%d" n - | AFun (l, r) -> - (match l with - | AFun _ -> fprintf ppf "(%a) -> %a" helper l helper r - | _ -> fprintf ppf "%a -> %a" helper l helper r) - | AList t -> fprintf ppf "%a list" helper t - | ATuple l -> - let rec pp_tuple ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" helper x - | x :: xs -> - fprintf ppf "%a * " helper x; - pp_tuple ppf xs - in - fprintf ppf "%a" pp_tuple l - | AOption op -> fprintf ppf "%a option" helper op - in - helper -;; - -let pp_rec_flag ppf = function - | NonRec -> fprintf ppf "" - | Rec -> fprintf ppf " rec" -;; - -let pp_constant ppf = function - | CInt i -> fprintf ppf "%d" i - | CBool b -> fprintf ppf "%b" b - | CString s -> fprintf ppf "%S" s - | CUnit -> fprintf ppf "()" - | CNil -> fprintf ppf "[]" -;; - -let pp_pattern = - let rec helper ppf = function - | PAny -> fprintf ppf "_" - | PConstant l -> fprintf ppf "%a" pp_constant l - | PVar v -> fprintf ppf "%s" v - | PCons (p1, p2) -> - (match p1, p2 with - | POption _, POption _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | PCons _, PCons _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | POption _, _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | PCons _, _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | _, POption _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | _, PCons _ -> fprintf ppf "(%a)::(%a)" helper p1 helper p2 - | _ -> fprintf ppf "%a::%a" helper p1 helper p2) - | PTuple (p1, p2, rest) -> - let pp_tuple_helper ppf x = - match x with - | PCons _ | POption _ -> fprintf ppf "(%a)" helper x - | _ -> fprintf ppf "%a" helper x - in - let rec pp_tuple ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" pp_tuple_helper x - | x :: xs -> - fprintf ppf "%a, " pp_tuple_helper x; - pp_tuple ppf xs - in - fprintf ppf "(%a)" pp_tuple (p1 :: p2 :: rest) - | PList (p1, rest) -> - let pp_tuple_helper ppf x = - match x with - | PCons _ | POption _ -> fprintf ppf "(%a)" helper x - | _ -> fprintf ppf "%a" helper x - in - let rec pp_tuple ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" pp_tuple_helper x - | x :: xs -> - fprintf ppf "%a; " pp_tuple_helper x; - pp_tuple ppf xs - in - fprintf ppf "[%a]" pp_tuple (p1 :: rest) - | POption x -> - (match x with - | Some x -> fprintf ppf "Some (%a)" helper x - | None -> fprintf ppf "None") - | PType (pat, tp) -> fprintf ppf "(%a : %a)" helper pat pp_annot tp - in - helper -;; - -let rec pp_expr = - let rec helper ppf = function - | ExprVariable v -> fprintf ppf "%s" v - | ExprConstant l -> fprintf ppf "%a" pp_constant l - | ExprBinOperation (op, e1, e2) -> - (match e1, e2 with - | ExprVariable _, ExprVariable _ -> - fprintf ppf "%a %a %a" helper e1 pp_binop op helper e2 - | ExprConstant _, ExprConstant _ -> - fprintf ppf "%a %a %a" helper e1 pp_binop op helper e2 - | ExprVariable _, _ | ExprConstant _, _ -> - fprintf ppf "%a %a (%a)" helper e1 pp_binop op helper e2 - | _, ExprVariable _ | _, ExprConstant _ -> - fprintf ppf "(%a) %a %a" helper e1 pp_binop op helper e2 - | _ -> fprintf ppf "((%a) %a (%a))" helper e1 pp_binop op helper e2) - | ExprUnOperation (op, e) -> fprintf ppf "%a(%a)" pp_unop op helper e - | ExprIf (c, th, el) -> - let ppifexpr_helper ppf e = - match e with - | ExprVariable _ | ExprConstant _ -> fprintf ppf "%a" helper e - | _ -> fprintf ppf "(%a)" helper e - in - let ppifexpr = function - | None -> fprintf ppf "if %a then %a" ppifexpr_helper c ppifexpr_helper th - | Some x -> - fprintf - ppf - "if %a then %a else %a" - ppifexpr_helper - c - ppifexpr_helper - th - ppifexpr_helper - x - in - ppifexpr el - | ExprMatch (e, branch, branches) -> - fprintf ppf "match %a with\n" helper e; - let ppmatch ppf branches = - let pattern, branch_expr = branches in - match branch_expr with - | ExprVariable _ | ExprConstant _ -> - fprintf ppf "| %a -> %a" pp_pattern pattern helper branch_expr - | _ -> fprintf ppf "| %a -> (%a)" pp_pattern pattern helper branch_expr - in - let rec ppmatch_helper ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" ppmatch x - | x :: xs -> - fprintf ppf "%a\n" ppmatch x; - ppmatch_helper ppf xs - in - ppmatch_helper ppf (branch :: branches) - | ExprFunction (branch, branches) -> - fprintf ppf "function\n"; - let ppmatch ppf branches = - let pattern, branch_expr = branches in - match branch_expr with - | ExprVariable _ | ExprConstant _ -> - fprintf ppf "| %a -> %a" pp_pattern pattern helper branch_expr - | _ -> fprintf ppf "| %a -> (%a)" pp_pattern pattern helper branch_expr - in - let rec ppfunction_helper ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" ppmatch x - | x :: xs -> - fprintf ppf "%a\n" ppmatch x; - ppfunction_helper ppf xs - in - ppfunction_helper ppf (branch :: branches) - | ExprLet (rf, b, bl, e) -> - fprintf ppf "let%a %a in %a" pp_rec_flag rf pp_binding_list (b :: bl) helper e - | ExprApply (e1, e2) -> - (match e1, e2 with - | ExprVariable _, ExprVariable _ -> fprintf ppf "%a %a" helper e1 helper e2 - | _, ExprVariable _ -> fprintf ppf "(%a) %a" helper e1 helper e2 - | ExprVariable _, _ -> fprintf ppf "%a (%a)" helper e1 helper e2 - | _ -> fprintf ppf "(%a) (%a)" helper e1 helper e2) - | ExprTuple (p1, p2, rest) -> - let pp_tuple_helper ppf x = - match x with - | ExprBinOperation _ - | ExprUnOperation _ - | ExprIf _ - | ExprMatch _ - | ExprLet _ - | ExprApply _ - | ExprOption _ - | ExprFun _ -> fprintf ppf "(%a)" helper x - | _ -> fprintf ppf "%a" helper x - in - let rec pp_tuple ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" pp_tuple_helper x - | x :: xs -> - fprintf ppf "%a, " pp_tuple_helper x; - pp_tuple ppf xs - in - fprintf ppf "(%a)" pp_tuple (p1 :: p2 :: rest) - | ExprList (h, t) -> - let pp_list_helper ppf x = - match x with - | ExprBinOperation _ - | ExprUnOperation _ - | ExprIf _ - | ExprMatch _ - | ExprLet _ - | ExprApply _ - | ExprFun _ -> fprintf ppf "(%a)" helper x - | _ -> fprintf ppf "%a" helper x - in - let rec pp_list ppf = function - | [] -> () - | [ x ] -> fprintf ppf "%a" pp_list_helper x - | x :: xs -> - fprintf ppf "%a; " pp_list_helper x; - pp_list ppf xs - in - fprintf ppf "[%a]" pp_list (h :: t) - | ExprCons (e1, e2) -> - (match e1, e2 with - | ExprVariable _, ExprVariable _ -> fprintf ppf "%a::%a" helper e1 helper e2 - | ExprConstant _, ExprConstant _ -> fprintf ppf "%a::%a" helper e1 helper e2 - | ExprVariable _, _ -> fprintf ppf "%a::(%a)" helper e1 helper e2 - | ExprConstant _, _ -> fprintf ppf "%a::(%a)" helper e1 helper e2 - | _, ExprConstant _ -> fprintf ppf "(%a)::%a" helper e1 helper e2 - | _, ExprVariable _ -> fprintf ppf "(%a)::%a" helper e1 helper e2 - | _ -> fprintf ppf "(%a)::(%a)" helper e1 helper e2) - | ExprFun (p, e) -> fprintf ppf "fun %a -> %a" pp_pattern p helper e - | ExprOption x -> - (match x with - | Some x -> fprintf ppf "Some (%a)" helper x - | None -> fprintf ppf "None") - | ExprType (e, annot) -> fprintf ppf "(%a : %a)" helper e pp_annot annot - in - helper - -and pp_binding_list ppf = - let pp_binding ppf binding = - let p, e = binding in - match e with - | ExprFun (p1, e1) -> fprintf ppf "%a %a = %a" pp_pattern p pp_pattern p1 pp_expr e1 - | _ -> fprintf ppf "%a = %a" pp_pattern p pp_expr e - in - let rec helper = function - | [] -> () - | [ x ] -> fprintf ppf "%a" pp_binding x - | x :: xs -> - fprintf ppf "%a and " pp_binding x; - helper xs - in - helper -;; - -let pp_structure ppf = function - | SEval e -> fprintf ppf "%a" pp_expr e - | SValue (rf, b, bl) -> fprintf ppf "let%a %a" pp_rec_flag rf pp_binding_list (b :: bl) -;; - -let pp_structure_item_list ppf structure_list = - List.iter (fun item -> fprintf ppf "%a;;\n\n" pp_structure item) structure_list -;; diff --git a/OCamlRV/lib/astPrinter.mli b/OCamlRV/lib/astPrinter.mli deleted file mode 100644 index e76e7de82..000000000 --- a/OCamlRV/lib/astPrinter.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val pp_annot : Format.formatter -> Ast.type_annot -> unit -val pp_structure_item_list : Format.formatter -> Ast.structure_item list -> unit diff --git a/OCamlRV/lib/dune b/OCamlRV/lib/dune deleted file mode 100644 index 9e8bb4ab1..000000000 --- a/OCamlRV/lib/dune +++ /dev/null @@ -1,17 +0,0 @@ -(library - (name OCamlRV_lib) - (public_name OCamlRV.Lib) - (libraries angstrom qcheck-core qcheck-core.runner) - (modules ast parser astPrinter inferencer inferencerCore interpreter) - (preprocess - (pps ppx_expect ppx_deriving.show ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx))) - -(executable - (name quickcheck) - (public_name quickcheck) - (libraries OCamlRV_lib) - (modules quickcheck) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlRV/lib/inferencer.ml b/OCamlRV/lib/inferencer.ml deleted file mode 100644 index 0b13cf906..000000000 --- a/OCamlRV/lib/inferencer.ml +++ /dev/null @@ -1,408 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open AstPrinter -open InferencerCore -open InferencerCore.Result -open InferencerCore.Result.Syntax - -let fresh_var = fresh >>| fun n -> AVar n - -let instantiate : Scheme.t -> type_annot Result.t = - fun (S (xs, type_annot)) -> - VarSet.fold - (fun name typ -> - let* typ = typ in - let* f1 = fresh_var in - let* s = Subst.singleton name f1 in - return (Subst.apply s typ)) - xs - (return type_annot) -;; - -let generalize env ty = - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - Scheme.S (free, ty) -;; - -let generalize_rec env ty x = - let env = TypeEnv.remove env x in - generalize env ty -;; - -let rec infer_pattern env = function - | PAny -> - let* fresh = fresh_var in - return (env, fresh) - | PConstant c -> - (match c with - | CInt _ -> return (env, int_type) - | CBool _ -> return (env, bool_type) - | CString _ -> return (env, string_type) - | CUnit -> return (env, unit_type) - | CNil -> - let* fresh = fresh_var in - return (env, list_type fresh)) - | PVar x -> - let* fresh = fresh_var in - let env = TypeEnv.extend env x (Scheme.S (VarSet.empty, fresh)) in - return (env, fresh) - | PCons (p1, p2) -> - let* env1, t1 = infer_pattern env p1 in - let* env2, t2 = infer_pattern env1 p2 in - let* sub = Subst.unify (list_type t1) t2 in - let env = TypeEnv.apply sub env2 in - return (env, Subst.apply sub t2) - | PTuple (p1, p2, pl) -> - let* env, tl = - List.fold_left - ~f:(fun acc pat -> - let* env1, tl = acc in - let* env2, t = infer_pattern env1 pat in - return (env2, t :: tl)) - ~init:(return (env, [])) - (p1 :: p2 :: pl) - in - return (env, tuple_type (List.rev tl)) - | PList (p1, rest) -> - let* env1, t1 = infer_pattern env p1 in - let* env2, t_list = - List.fold_left - ~f:(fun acc pat -> - let* env_acc, _ = acc in - let* env_next, t_next = infer_pattern env_acc pat in - let* sub = Subst.unify t1 t_next in - let env_updated = TypeEnv.apply sub env_next in - return (env_updated, Subst.apply sub t1)) - ~init:(return (env1, list_type t1)) - rest - in - return (env2, t_list) - | POption (Some p) -> - let* env1, t1 = infer_pattern env p in - return (env1, AOption t1) - | POption None -> - let* fresh = fresh_var in - return (env, AOption fresh) - | PType (p, t) -> - let* env1, t1 = infer_pattern env p in - let* sub = Subst.unify t1 t in - let env = TypeEnv.apply sub env1 in - return (env, Subst.apply sub t1) -;; - -let rec infer_expression env = function - | ExprConstant c -> - (match c with - | CInt _ -> return (Subst.empty, int_type) - | CBool _ -> return (Subst.empty, bool_type) - | CString _ -> return (Subst.empty, string_type) - | CUnit -> return (Subst.empty, unit_type) - | CNil -> - let* fresh = fresh_var in - return (Subst.empty, list_type fresh)) - | ExprVariable x -> - (match TypeEnv.find x env with - | Some s -> - let* t = instantiate s in - return (Subst.empty, t) - | None -> fail (`Unbound x)) - | ExprBinOperation (op, e1, e2) -> - let* sub1, t1 = infer_expression env e1 in - let* sub2, t2 = infer_expression (TypeEnv.apply sub1 env) e2 in - let* e1t, e2t, et = - match op with - | Mul | Div | Add | Sub -> return (int_type, int_type, int_type) - | Eq | Neq | Lt | Lte | Gt | Gte -> - let* fresh = fresh_var in - return (fresh, fresh, bool_type) - | And | Or -> return (bool_type, bool_type, bool_type) - in - let* sub3 = Subst.unify (Subst.apply sub2 t1) e1t in - let* sub4 = Subst.unify (Subst.apply sub3 t2) e2t in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4 ] in - return (sub, Subst.apply sub et) - | ExprUnOperation (op, e) -> - let* sub1, t1 = infer_expression env e in - let* et = - match op with - | UnaryPlus | UnaryMinus -> return int_type - | UnaryNeg -> return bool_type - in - let* sub2 = Subst.unify (Subst.apply sub1 t1) et in - let* sub = Subst.compose_all [ sub1; sub2 ] in - return (sub, Subst.apply sub et) - | ExprIf (i, t, e) -> - let* sub1, t1 = infer_expression env i in - let* sub2, t2 = infer_expression (TypeEnv.apply sub1 env) t in - let* sub3, t3 = - match e with - | Some e -> - let* sub3, t3 = infer_expression (TypeEnv.apply sub2 env) e in - return (sub3, t3) - | None -> return (Subst.empty, unit_type) - in - let* sub4 = Subst.unify t1 bool_type in - let* sub5 = Subst.unify t2 t3 in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4; sub5 ] in - return (sub, Subst.apply sub t2) - | ExprMatch (e, c, cl) -> - let* sub1, t1 = infer_expression env e in - let env = TypeEnv.apply sub1 env in - let* fresh = fresh_var in - let* sub, t = - List.fold_left - ~f:(fun acc (pat, exp) -> - let* sub1, t = acc in - let* env1, pt = infer_pattern env pat in - let* sub2 = Subst.unify t1 pt in - let env2 = TypeEnv.apply sub2 env1 in - let* sub3, t' = infer_expression env2 exp in - let* sub4 = Subst.unify t' t in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4 ] in - return (sub, Subst.apply sub t)) - ~init:(return (sub1, fresh)) - (c :: cl) - in - return (sub, t) - | ExprFunction (c, cl) -> - let p, e = c in - let* env, t1 = infer_pattern env p in - let* s1, _ = infer_expression env e in - let env = TypeEnv.apply s1 env in - let* fresh = fresh_var in - let* sub, t = - List.fold_left - ~f:(fun acc (pat, exp) -> - let* sub1, t = acc in - let* env1, pt = infer_pattern env pat in - let* sub2 = Subst.unify t1 pt in - let env2 = TypeEnv.apply sub2 env1 in - let* sub3, t' = infer_expression env2 exp in - let* sub4 = Subst.unify t' t in - let* sub = Subst.compose_all [ sub1; sub2; sub3; sub4 ] in - return (sub, Subst.apply sub t)) - ~init:(return (s1, fresh)) - (c :: cl) - in - return (sub, Subst.apply sub (fun_type t1 t)) - | ExprLet (NonRec, b, bl, e) -> - let bindings = b :: bl in - let* env2 = infer_non_rec_binding_list env bindings in - let* s, t = infer_expression env2 e in - return (s, t) - | ExprLet (Rec, b, bl, e) -> - let bindings = b :: bl in - let* env2 = infer_rec_binding_list env bindings in - let* s, t = infer_expression env2 e in - return (s, t) - | ExprFun (p, e) -> - let* env, t = infer_pattern env p in - let* sub, t1 = infer_expression env e in - return (sub, Subst.apply sub (fun_type t t1)) - | ExprTuple (e1, e2, el) -> - let* sub, t = - List.fold_left - ~f:(fun acc e -> - let* sub, t = acc in - let* sub1, t1 = infer_expression env e in - let* sub2 = Subst.compose sub sub1 in - return (sub2, t1 :: t)) - ~init:(return (Subst.empty, [])) - (e1 :: e2 :: el) - in - return (sub, tuple_type (List.rev_map ~f:(Subst.apply sub) t)) - | ExprList (l, ls) -> - (match l :: ls with - | [] -> - let* fresh = fresh_var in - return (Subst.empty, list_type fresh) - | h :: tl -> - let* sr, tr = - List.fold_left tl ~init:(infer_expression env h) ~f:(fun acc e -> - let* sub, t = acc in - let* s1, t1 = infer_expression env e in - let* s2 = Subst.unify t t1 in - let* final_s = Subst.compose_all [ sub; s1; s2 ] in - let final_t = Subst.apply final_s t in - return (final_s, final_t)) - in - return (sr, AList tr)) - | ExprCons (e1, e2) -> - let* s1, t1 = infer_expression env e1 in - let* s2, t2 = infer_expression env e2 in - let* sub = Subst.unify (list_type t1) t2 in - let t = Subst.apply sub t2 in - let* sub = Subst.compose_all [ s1; s2; sub ] in - return (sub, t) - | ExprApply (e1, e2) -> - let* fresh = fresh_var in - let* s1, t1 = infer_expression env e1 in - let* s2, t2 = infer_expression (TypeEnv.apply s1 env) e2 in - let* s3 = Subst.unify (fun_type t2 fresh) (Subst.apply s2 t1) in - let* sub = Subst.compose_all [ s1; s2; s3 ] in - let t = Subst.apply sub fresh in - return (sub, t) - | ExprOption (Some eo) -> - let* s, t = infer_expression env eo in - return (s, AOption t) - | ExprOption None -> - let* t = fresh_var in - return (Subst.empty, AOption t) - | ExprType (e, t) -> - let* s1, t1 = infer_expression env e in - let* s2 = Subst.unify t t1 in - return (s2, Subst.apply s1 t1) - -and infer_non_rec_binding_list env (bl : binding list) = - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar x -> - let* s, t = infer_expression env e in - let env = TypeEnv.apply s env in - let sc = generalize env t in - let env = TypeEnv.extend env x sc in - return env - | PConstant CUnit -> - let* _, t1 = infer_pattern env p in - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t1 t2 in - let env = TypeEnv.apply sub env in - return env - | POption (Some (PVar x)) -> - let* _, t1 = infer_pattern env p in - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t1 t2 in - let env = TypeEnv.apply sub env in - (match t2 with - | AOption t -> - let sc = generalize env t in - let env = TypeEnv.extend env x sc in - return env - | _ -> return env) - | POption None -> - let* _, t1 = infer_pattern env p in - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t1 t2 in - let env = TypeEnv.apply sub env in - return env - | PAny -> - let* s1, _ = infer_expression env e in - let env = TypeEnv.apply s1 env in - return env - | PTuple _ -> - let* _, t1 = infer_pattern env p in - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t1 t2 in - let env = TypeEnv.apply sub env in - return env - | PList _ -> - let* _, t1 = infer_pattern env p in - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t1 t2 in - let env = TypeEnv.apply sub env in - return env - | PType (_, t) -> - let* _, t2 = infer_expression env e in - let* sub = Subst.unify t t2 in - let env = TypeEnv.apply sub env in - return env - | _ -> return env) - ~init:(return env) - bl - in - return env2 - -and infer_rec_binding_list env (bl : binding list) = - let* env0 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, _ = b in - match p with - | PVar x -> - let* fresh = fresh_var in - let sc = Scheme.S (VarSet.empty, fresh) in - let env = TypeEnv.extend env x sc in - return env - | _ -> fail `LeftHS) - ~init:(return env) - bl - in - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar x -> - let* fresh = fresh_var in - let sc = Scheme.S (VarSet.empty, fresh) in - let env = TypeEnv.extend env x sc in - let* s1, t1 = infer_expression env e in - (match t1 with - | AFun _ -> - let* s2 = Subst.unify t1 fresh in - let* s3 = Subst.compose s1 s2 in - let env = TypeEnv.apply s3 env in - let t2 = Subst.apply s3 t1 in - let sc = generalize_rec env t2 x in - let env = TypeEnv.extend env x sc in - return env - | _ -> fail `RightHS) - | _ -> fail `LeftHS) - ~init:(return env0) - bl - in - return env2 -;; - -let infer_structure_item env = function - | SValue (Rec, b, bl) -> - let bindings = b :: bl in - infer_rec_binding_list env bindings - | SValue (NonRec, b, bl) -> - let bindings = b :: bl in - infer_non_rec_binding_list env bindings - | SEval e -> - let* _, _ = infer_expression env e in - return env -;; - -let infer_structure (structure : structure) = - let env = - TypeEnv.extend TypeEnv.empty "print_int" (Scheme.S (VarSet.empty, AFun (AInt, AUnit))) - in - let env = - TypeEnv.extend env "print_endline" (Scheme.S (VarSet.empty, AFun (AString, AUnit))) - in - List.fold_left - ~f:(fun acc item -> - let* env = acc in - let* env = infer_structure_item env item in - return env) - ~init:(return env) - structure -;; - -let run_inferencer (s : string) = - let open Parser in - match parse s with - | Ok parsed -> - let res = run (infer_structure parsed) in - (match res with - | Ok env -> - Base.Map.iteri env ~f:(fun ~key ~data:(S (_, ty)) -> - if String.equal key "print_int" || String.equal key "print_endline" - then () - else Stdlib.Format.printf "val %s : %a\n" key pp_annot ty) - | Error e -> Stdlib.Format.printf "Infer error: %a\n" pp_error e) - | Error e -> Stdlib.Format.printf "Parsing error: %s\n" e -;; diff --git a/OCamlRV/lib/inferencer.mli b/OCamlRV/lib/inferencer.mli deleted file mode 100644 index 09519c6e4..000000000 --- a/OCamlRV/lib/inferencer.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run_inferencer : string -> unit diff --git a/OCamlRV/lib/inferencerCore.ml b/OCamlRV/lib/inferencerCore.ml deleted file mode 100644 index 571bf9507..000000000 --- a/OCamlRV/lib/inferencerCore.ml +++ /dev/null @@ -1,249 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open AstPrinter -open Base - -let fun_type l r = AFun (l, r) -let int_type = AInt -let bool_type = ABool -let string_type = AString -let unit_type = AUnit -let tuple_type t = ATuple t -let list_type t = AList t - -type error = - [ `Occurs_check - | `Unbound of identifier - | `Unification_failed of type_annot * type_annot - | `LeftHS - | `RightHS - ] - -let pp_error ppf : error -> _ = - let open Stdlib.Format in - function - | `Occurs_check -> fprintf ppf "Occurs check failed" - | `Unbound s -> fprintf ppf "Unbound variable '%s'" s - | `Unification_failed (l, r) -> - fprintf ppf "Unification failed on %a and %a" pp_annot l pp_annot r - | `LeftHS -> fprintf ppf "Only variables are allowed as left-hand side of `let rec'" - | `RightHS -> - fprintf ppf "This kind of expression is not allowed as right-hand side of `let rec'" -;; - -module VarSet = struct - include Stdlib.Set.Make (Int) -end - -module Result : sig - type 'a t - - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val return : 'a -> 'a t - val fail : error -> 'a t - - include Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - (** Creation of a fresh name from internal state *) - val fresh : int t - - (** Running a transformer: getting the inner result value *) - val run : 'a t -> ('a, error) Result.t - - module RMap : sig - val fold : ('a, 'b, 'c) Map.t -> init:'d t -> f:('a -> 'b -> 'd -> 'd t) -> 'd t - end -end = struct - (** A composition: State monad after Result monad *) - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let last, r = m st in - match r with - | Result.Error x -> last, Result.fail x - | Result.Ok a -> f a last - ;; - - let fail e st = st, Result.fail e - let return x last = last, Result.return x - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun m f st -> - match m st with - | st, Ok x -> st, Result.return (f x) - | st, Result.Error e -> st, Result.fail e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - let fresh : int t = fun last -> last + 1, Result.return last - let run m = snd (m 0) - - module RMap = struct - let fold m ~init ~f = - Map.fold m ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end -end - -module Type = struct - let rec occurs_in v = function - | AVar b -> b = v - | AFun (l, r) -> occurs_in v l || occurs_in v r - | ATuple tl -> List.exists tl ~f:(occurs_in v) - | AList t -> occurs_in v t - | AOption t -> occurs_in v t - | AInt | ABool | AString | AUnit -> false - ;; - - let free_vars = - let rec helper acc = function - | AVar b -> VarSet.add b acc - | AFun (l, r) -> helper (helper acc l) r - | ATuple tl -> List.fold_left tl ~init:acc ~f:helper - | AList t -> helper acc t - | AOption o -> helper acc o - | AInt | ABool | AString | AUnit -> acc - in - helper VarSet.empty - ;; -end - -module Subst : sig - type t - - val empty : t - val singleton : fresh -> type_annot -> t Result.t - val find : t -> fresh -> type_annot option - val remove : t -> fresh -> t - val apply : t -> type_annot -> type_annot - val unify : type_annot -> type_annot -> t Result.t - val compose : t -> t -> t Result.t - val compose_all : t list -> t Result.t -end = struct - open Result - open Result.Syntax - - type t = (fresh, type_annot, Int.comparator_witness) Map.t - - let empty = Map.empty (module Int) - let mapping k v = if Type.occurs_in k v then fail `Occurs_check else return (k, v) - - let singleton k v = - let* k, v = mapping k v in - return (Map.singleton (module Int) k v) - ;; - - let find = Map.find - let remove = Map.remove - - let apply s = - let rec helper = function - | AInt -> AInt - | ABool -> ABool - | AString -> AString - | AUnit -> AUnit - | AVar b as ty -> - (match find s b with - | None -> ty - | Some x -> x) - | AFun (l, r) -> fun_type (helper l) (helper r) - | AList t -> list_type (helper t) - | ATuple ts -> tuple_type (List.map ~f:helper ts) - | AOption o -> AOption (helper o) - in - helper - ;; - - let rec unify l r = - match l, r with - | AInt, AInt -> return empty - | ABool, ABool -> return empty - | AString, AString -> return empty - | AUnit, AUnit -> return empty - | AVar a, AVar b when Int.equal a b -> return empty - | AVar b, t | t, AVar b -> singleton b t - | AFun (l1, r1), AFun (l2, r2) -> - let* s1 = unify l1 l2 in - let* s2 = unify (apply s1 r1) (apply s1 r2) in - compose s1 s2 - | AList t1, AList t2 -> unify t1 t2 - | ATuple ts1, ATuple ts2 -> - (match - List.fold2 - ts1 - ts2 - ~f:(fun acc t1 t2 -> - let* acc = acc in - let* s = unify (apply acc t1) (apply acc t2) in - compose acc s) - ~init:(return empty) - with - | Unequal_lengths -> fail (`Unification_failed (l, r)) - | Ok s -> s) - | AOption t1, AOption t2 -> unify t1 t2 - | _ -> fail (`Unification_failed (l, r)) - - and extend k v s = - match find s k with - | None -> - let v = apply s v in - let* s2 = singleton k v in - RMap.fold s ~init:(return s2) ~f:(fun k v acc -> - let v = apply s2 v in - let* k, v = mapping k v in - return (Map.update acc k ~f:(fun _ -> v))) - | Some v2 -> - let* s2 = unify v v2 in - compose s s2 - - and compose s1 s2 = RMap.fold s2 ~init:(return s1) ~f:extend - - let compose_all = - List.fold_left ~init:(return empty) ~f:(fun acc s -> - let* acc = acc in - compose acc s) - ;; -end - -module Scheme = struct - type t = S of VarSet.t * type_annot - - let occurs_in v (S (xs, t)) = (not (VarSet.mem v xs)) && Type.occurs_in v t - let free_vars (S (xs, t)) = VarSet.diff (Type.free_vars t) xs - - let apply s (S (set, tp)) = - let s2 = VarSet.fold (fun k s -> Subst.remove s k) set s in - S (set, Subst.apply s2 tp) - ;; -end - -module TypeEnv = struct - type t = (identifier, Scheme.t, String.comparator_witness) Map.t - - let extend e k v = Map.update e k ~f:(fun _ -> v) - let remove = Map.remove - let empty = Map.empty (module String) - - let free_vars : t -> VarSet.t = - Map.fold ~init:VarSet.empty ~f:(fun ~key:_ ~data:s acc -> - VarSet.union acc (Scheme.free_vars s)) - ;; - - let apply s env = Map.map env ~f:(Scheme.apply s) - let find x env = Map.find env x -end diff --git a/OCamlRV/lib/inferencerCore.mli b/OCamlRV/lib/inferencerCore.mli deleted file mode 100644 index 1441ad201..000000000 --- a/OCamlRV/lib/inferencerCore.mli +++ /dev/null @@ -1,88 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val fun_type : Ast.type_annot -> Ast.type_annot -> Ast.type_annot -val int_type : Ast.type_annot -val bool_type : Ast.type_annot -val string_type : Ast.type_annot -val unit_type : Ast.type_annot -val tuple_type : Ast.type_annot list -> Ast.type_annot -val list_type : Ast.type_annot -> Ast.type_annot - -type error = - [ `Occurs_check - | `Unbound of string - | `Unification_failed of Ast.type_annot * Ast.type_annot - | `LeftHS - | `RightHS - ] - -val pp_error : Format.formatter -> error -> unit - -module VarSet : sig - type elt = int - type t = Set.Make(Base.Int).t - - val empty : t - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a - val diff : t -> t -> t -end - -module Result : sig - type 'a t - - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - val fresh : int t - val run : 'a t -> ('a, error) result - - module RMap : sig - val fold : ('a, 'b, 'c) Base.Map.t -> init:'d t -> f:('a -> 'b -> 'd -> 'd t) -> 'd t - end -end - -module Type : sig - val occurs_in : int -> Ast.type_annot -> bool - val free_vars : Ast.type_annot -> VarSet.t -end - -module Subst : sig - type t - - val empty : t - val singleton : int -> Ast.type_annot -> t Result.t - val find : t -> int -> Ast.type_annot option - val remove : t -> int -> t - val apply : t -> Ast.type_annot -> Ast.type_annot - val unify : Ast.type_annot -> Ast.type_annot -> t Result.t - val compose : t -> t -> t Result.t - val compose_all : t list -> t Result.t -end - -module Scheme : sig - type t = S of VarSet.t * Ast.type_annot - - val occurs_in : int -> t -> bool - val free_vars : t -> VarSet.t - val apply : Subst.t -> t -> t -end - -module TypeEnv : sig - type t = (string, Scheme.t, Base.String.comparator_witness) Base.Map.t - - val extend : ('a, 'b, 'c) Base.Map.t -> 'a -> 'b -> ('a, 'b, 'c) Base.Map.t - val remove : ('a, 'b, 'c) Base.Map.t -> 'a -> ('a, 'b, 'c) Base.Map.t - val empty : (string, 'a, Base.String.comparator_witness) Base.Map.t - val free_vars : t -> VarSet.t - val apply : Subst.t -> ('a, Scheme.t, 'b) Base.Map.t -> ('a, Scheme.t, 'b) Base.Map.t - val find : 'a -> ('a, 'b, 'c) Base.Map.t -> 'b option -end diff --git a/OCamlRV/lib/interpreter.ml b/OCamlRV/lib/interpreter.ml deleted file mode 100644 index e2ca275c5..000000000 --- a/OCamlRV/lib/interpreter.ml +++ /dev/null @@ -1,487 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Stdlib - -type builtin = - | BInt of (int -> unit) - | BString of (string -> unit) - -type environment = - (string, value, Base.Comparator.Make(Base.String).comparator_witness) Base.Map.t - -and value = - | VInt of int - | VBool of bool - | VString of string - | VUnit - | VList of value list - | VTuple of value list - | VNil - | VOption of value option - | VFun of pattern * rec_flag * expression * environment - | VMutualFun of pattern * rec_flag * expression * environment - | VFunction of case * case list * environment - | VBuiltin of builtin * string - -let rec pp_value ppf = - let open Stdlib.Format in - function - | VInt x -> fprintf ppf "%d" x - | VBool b -> fprintf ppf "%b" b - | VString s -> fprintf ppf "%s" s - | VUnit -> fprintf ppf "()" - | VList vl -> - fprintf - ppf - "[%a]" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf "; ") pp_value) - vl - | VTuple vl -> - fprintf - ppf - "(%a)" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - vl - | VNil -> fprintf ppf "[]" - | VFun _ -> fprintf ppf "" - | VBuiltin (_, name) -> fprintf ppf " %s" name - | VMutualFun _ -> fprintf ppf "" - | VFunction _ -> fprintf ppf "" - | VOption vo -> - (match vo with - | Some v -> fprintf ppf "Some %a" pp_value v - | None -> fprintf ppf "None") -;; - -type error = - | PatternMatchingFailed - | ApplyFailed of value * value - | WrongType of value - | UnboundVariable of string - | WrongBinaryOperation of binary_operator * value * value - | WrongUnaryOperation of unary_operator * value - -let pp_error ppf = - let open Stdlib.Format in - function - | PatternMatchingFailed -> fprintf ppf "PatternMatchingFailed" - | ApplyFailed (v1, v2) -> fprintf ppf "ApplyFailed: %a %a" pp_value v1 pp_value v2 - | WrongType v -> fprintf ppf "WrongType: %a" pp_value v - | UnboundVariable name -> fprintf ppf "UnboundVariable: %s" name - | WrongBinaryOperation (op, v1, v2) -> - fprintf - ppf - "WrongBinaryOperation: %a %a %a" - pp_value - v1 - pp_binary_operator - op - pp_value - v2 - | WrongUnaryOperation (op, v) -> - fprintf ppf "WrongUnaryOperation: %a %a" pp_unary_operator op pp_value v -;; - -let print_env env = - Format.printf "\nDEBUG environment:\n"; - Base.Map.iteri - ~f:(fun ~key ~data -> - Format.fprintf Format.std_formatter "%s = %a\n" key pp_value data) - env -;; - -module type MONAD_FAIL = sig - include Monad.S2 - - val fail : error -> ('a, error) t - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -module Env (M : MONAD_FAIL) = struct - open M - - let empty = - Base.Map.empty - (module struct - include String - include Base.Comparator.Make (Base.String) - end) - ;; - - let extend env k v = Base.Map.update env k ~f:(fun _ -> v) - - let find env name = - match Base.Map.find env name with - | Some x -> return x - | None -> fail (UnboundVariable name) - ;; -end - -module Eval (M : MONAD_FAIL) = struct - open M - open Env (M) - - let rec check_matching env = function - | PAny, _ -> Some env - | PConstant (CInt i1), VInt i2 when i1 = i2 -> Some env - | PConstant (CBool b1), VBool b2 when Bool.equal b1 b2 -> Some env - | PConstant (CString s1), VString s2 when String.equal s1 s2 -> Some env - | PConstant CNil, VList [] -> Some env - | PConstant CNil, VNil -> Some env - | PConstant CUnit, VUnit -> Some env - | PVar x, v -> Some (extend env x v) - | PTuple (p1, p2, rest), VTuple vl -> - let pl = p1 :: p2 :: rest in - let env = - Base.List.fold2 - pl - vl - ~f:(fun env p v -> - match env with - | Some e -> check_matching e (p, v) - | None -> None) - ~init:(Some env) - in - (match env with - | Ok env -> env - | _ -> None) - | PList (p1, rest), VList vl -> - let pl = p1 :: rest in - let env = - Base.List.fold2 - pl - vl - ~f:(fun env p v -> - match env with - | Some e -> check_matching e (p, v) - | None -> None) - ~init:(Some env) - in - (match env with - | Ok env -> env - | _ -> None) - | PCons (p1, p2), VList (v :: vl) -> - let env = check_matching env (p2, VList vl) in - (match env with - | Some env -> check_matching env (p1, v) - | None -> None) - | POption None, VOption None -> Some env - | POption (Some p), VOption (Some v) -> - let env = check_matching env (p, v) in - (match env with - | Some env -> Some env - | None -> None) - | _ -> None - ;; - - let eval_binop (op, v1, v2) = - match op, v1, v2 with - | Add, VInt x, VInt y -> return (VInt (x + y)) - | Sub, VInt x, VInt y -> return (VInt (x - y)) - | Mul, VInt x, VInt y -> return (VInt (x * y)) - | Div, VInt x, VInt y -> return (VInt (x / y)) - | Lt, VInt x, VInt y -> return (VBool (x < y)) - | Gt, VInt x, VInt y -> return (VBool (x > y)) - | Eq, VInt x, VInt y -> return (VBool (x = y)) - | Neq, VInt x, VInt y -> return (VBool (x <> y)) - | Lte, VInt x, VInt y -> return (VBool (x <= y)) - | Gte, VInt x, VInt y -> return (VBool (x >= y)) - | And, VBool x, VBool y -> return (VBool (x && y)) - | Or, VBool x, VBool y -> return (VBool (x || y)) - | _ -> fail (WrongBinaryOperation (op, v1, v2)) - ;; - - let eval_unop (op, v) = - match op, v with - | UnaryPlus, VInt x -> return (VInt (Stdlib.( ~+ ) x)) - | UnaryMinus, VInt x -> return (VInt (-x)) - | UnaryNeg, VBool x -> return (VBool (not x)) - | _ -> fail (WrongUnaryOperation (op, v)) - ;; - - let eval_tuple_binding env pl vl = - return - (match vl with - | VTuple tl -> - let a = - Base.List.fold2 - pl - tl - ~f:(fun env p v -> - match p with - | PVar s -> extend env s v - | POption (Some (PVar s)) -> - (match v with - | VOption (Some vo) -> extend env s vo - | _ -> env) - | _ -> env) - ~init:env - in - (match a with - | Ok r -> r - | Unequal_lengths -> env) - | _ -> env) - ;; - - let rec eval_expr (env : environment) = function - | ExprConstant c -> - (match c with - | CInt i -> return (VInt i) - | CBool b -> return (VBool b) - | CString s -> return (VString s) - | CUnit -> return VUnit - | CNil -> return VNil) - | ExprVariable x -> - let* v = find env x in - let v = - match v with - | VFun (p, Rec, e, env) -> VFun (p, Rec, e, extend env x v) - | _ -> v - in - return v - | ExprBinOperation (op, e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - eval_binop (op, v1, v2) - | ExprUnOperation (op, e) -> - let* v = eval_expr env e in - eval_unop (op, v) - | ExprIf (cond, t, Some f) -> - let* cv = eval_expr env cond in - (match cv with - | VBool true -> eval_expr env t - | VBool false -> eval_expr env f - | _ -> fail (WrongType cv)) - | ExprIf (cond, t, None) -> - let* cv = eval_expr env cond in - (match cv with - | VBool true -> eval_expr env t - | VBool false -> return VUnit - | _ -> fail (WrongType cv)) - | ExprLet (NonRec, b, bl, e) -> - let bindings = b :: bl in - let* env2 = eval_non_rec_binding_list env bindings in - eval_expr env2 e - | ExprLet (Rec, (PVar x, e1), [], e) -> - let* v = eval_expr env e1 in - let env1 = extend env x v in - let v = - match v with - | VFun (p, _, e, _) -> VFun (p, Rec, e, env1) - | _ -> v - in - let env2 = extend env x v in - eval_expr env2 e - | ExprLet (Rec, b, bl, e) -> - let bindings = b :: bl in - let* env2 = eval_rec_binding_list env bindings in - eval_expr env2 e - | ExprFun (p, e) -> return (VFun (p, NonRec, e, env)) - | ExprMatch (e, c, cl) -> - let* v = eval_expr env e in - let rec match_helper env v = function - | (p, e) :: tl -> - let env' = check_matching env (p, v) in - (match env' with - | Some env -> eval_expr env e - | None -> match_helper env v tl) - | [] -> fail PatternMatchingFailed - in - match_helper env v (c :: cl) - | ExprFunction (c, cl) -> return (VFunction (c, cl, env)) - | ExprApply (e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - (match v1 with - | VFun (p, _, e, env) -> - let* env' = - match check_matching env (p, v2) with - | Some env -> return env - | None -> fail (ApplyFailed (v1, v2)) - in - eval_expr env' e - | VFunction (c, cl, env) -> - let cases = c :: cl in - let rec try_match = function - | [] -> fail PatternMatchingFailed - | (pattern, body) :: rest -> - (match check_matching env (pattern, v2) with - | Some new_env -> eval_expr new_env body - | None -> try_match rest) - in - try_match cases - | VMutualFun (p, _, e, _) -> - let* env' = - match check_matching env (p, v2) with - | Some env -> return env - | None -> fail (ApplyFailed (v1, v2)) - in - eval_expr env' e - | VBuiltin (b, _) -> - let status = - match b, v2 with - | BInt b, VInt i -> - b i; - Ok VUnit - | BString b, VString s -> - b s; - Ok VUnit - | _, _ -> Error VUnit - in - (match status with - | Ok _ -> return VUnit - | Error _ -> fail (WrongType v1)) - | _ -> fail (ApplyFailed (v1, v2))) - | ExprTuple (e1, e2, el) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - let* vl = - Base.List.fold_left - ~f:(fun acc e -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - ~init:(return []) - el - in - return (VTuple (v1 :: v2 :: List.rev vl)) - | ExprList (hd, tl) -> - let* vhd = eval_expr env hd in - let* vtl = - Base.List.fold_left - ~f:(fun acc e -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - ~init:(return []) - tl - in - return (VList (vhd :: List.rev vtl)) - | ExprCons (h, tl) -> - let* hv = eval_expr env h in - let* tlv = eval_expr env tl in - (match tlv with - | VList vl -> return (VList (hv :: vl)) - | VNil -> return (VList [ hv ]) - | t -> fail (WrongType t)) - | ExprOption opt_expr -> - (match opt_expr with - | None -> return (VOption None) - | Some e -> - let* v = eval_expr env e in - return (VOption (Some v))) - | ExprType (e, _) -> eval_expr env e - - and eval_non_rec_binding_list env bl = - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar name -> - let* v = eval_expr env e in - return (extend env name v) - | PType (PVar name, _) -> - let* v = eval_expr env e in - return (extend env name v) - | PAny -> - let _ = eval_expr env e in - return env - | PConstant CUnit -> - let _ = eval_expr env e in - return env - | PTuple (p1, p2, pl) -> - let* vl = eval_expr env e in - let pl = p1 :: p2 :: pl in - eval_tuple_binding env pl vl - | POption (Some (PVar var)) -> - let* v = eval_expr env e in - (match v with - | VOption (Some vo) -> return (extend env var vo) - | _ -> fail (WrongType v)) - | _ -> return env) - ~init:(return env) - bl - in - return env2 - - and eval_rec_binding_list env bl = - let* env2 = - Base.List.fold_left - ~f:(fun env b -> - let* env = env in - let p, e = b in - match p with - | PVar name -> - (match e with - | ExprFun (p1, e1) -> - return (extend env name (VMutualFun (p1, Rec, e1, env))) - | _ -> return env) - | _ -> return env) - ~init:(return env) - bl - in - return env2 - ;; - - let eval_structure_item (env : environment) structure_item = - let env = extend env "print_int" (VBuiltin (BInt print_int, "print_int")) in - let env = - extend env "print_endline" (VBuiltin (BString print_endline, "print_endline")) - in - match structure_item with - | SEval e -> - let _ = eval_expr env e in - return env - | SValue (NonRec, b, bl) -> - let bindings = b :: bl in - eval_non_rec_binding_list env bindings - | SValue (Rec, b, bl) -> - let bindings = b :: bl in - eval_rec_binding_list env bindings - ;; - - let eval_structure (s : structure) = - Base.List.fold_left - ~f:(fun env item -> - let* env = env in - let* env = eval_structure_item env item in - return env) - ~init:(return empty) - s - ;; -end - -module Interpret = Eval (struct - include Base.Result - - let ( let* ) m f = bind m ~f - end) - -let test_interpreter text = - let open Stdlib.Format in - match Parser.parse text with - | Ok parsed -> - (match Interpret.eval_structure parsed with - | Ok _ -> () - | Error e -> fprintf std_formatter "Interpretation error: %a\n" pp_error e) - | Error e -> printf "Parsing error: %s\n" e -;; - -let run_interpreter text ~debug = - let open Stdlib.Format in - match Parser.parse text with - | Ok parsed -> - (match Interpret.eval_structure parsed with - | Ok env -> - (match debug with - | true -> print_env env - | _ -> ()) - | Error e -> fprintf std_formatter "%a\n" pp_error e) - | Error e -> printf "Parsing error: %s\n" e -;; diff --git a/OCamlRV/lib/interpreter.mli b/OCamlRV/lib/interpreter.mli deleted file mode 100644 index e5f109352..000000000 --- a/OCamlRV/lib/interpreter.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run_interpreter : string -> debug:bool -> unit -val test_interpreter : string -> unit diff --git a/OCamlRV/lib/parser.ml b/OCamlRV/lib/parser.ml deleted file mode 100644 index eb0a2e629..000000000 --- a/OCamlRV/lib/parser.ml +++ /dev/null @@ -1,358 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast -open Base - -(*--------------------------- Common part ---------------------------*) - -let is_id c = Char.is_alphanum c || Char.equal c '_' || Char.equal c '\'' - -let is_keyword = function - | "let" - | "rec" - | "in" - | "fun" - | "match" - | "with" - | "if" - | "then" - | "else" - | "and" - | "not" - | "true" - | "false" -> true - | _ -> false -;; - -let skip_comment = - take_while Char.is_whitespace - *> string "(*" - *> many_till any_char (string "*)") - *> return () -;; - -let ws = many skip_comment *> take_while Char.is_whitespace -let token s = ws *> string s - -let chainl1 e op = - let rec go acc = lift2 (fun f x -> f acc x) op e >>= go <|> return acc in - e >>= go -;; - -(*--------------------------- Constants ---------------------------*) - -let integer = - let* digits = ws *> take_while1 Char.is_digit in - return (Int.of_string digits) -;; - -let pinteger = integer >>| fun i -> CInt i - -let pbool = - let t = token "true" *> return (CBool true) in - let f = token "false" *> return (CBool false) in - choice [ t; f ] -;; - -let escaped_char = - char '\\' - *> choice [ char 'n' *> return '\n'; char '\\' *> return '\\'; char '"' *> return '"' ] -;; - -let regular_char = - satisfy (function - | '"' -> false - | '\\' -> false - | _ -> true) -;; - -let pstring = - token "\"" *> many (escaped_char <|> regular_char) - <* char '"' - >>| fun s -> CString (String.of_char_list s) -;; - -let punit = token "()" *> return CUnit -let pnil = token "[]" *> return CNil -let pconstant = choice [ pinteger; pbool; pstring; punit; pnil ] - -(*--------------------------- Types ---------------------------*) - -let rec annot_list t = - let* base = t in - let* _ = token "list" in - annot_list (return (AList base)) <|> return (AList base) -;; - -let annot_option t = - let* base = t in - let* _ = token "option" in - return (AOption base) -;; - -let annot_alone = - choice - [ token "int" *> return AInt - ; token "string" *> return AString - ; token "bool" *> return ABool - ; token "unit" *> return AUnit - ] -;; - -let parse_type_annotation = - let alone = annot_alone in - let list_type = annot_list alone <|> alone in - let opt_type = annot_option list_type <|> list_type in - opt_type -;; - -let pattern_with_type ppat = - let* pat = ws *> token "(" *> ppat in - let* constr = ws *> token ":" *> ws *> parse_type_annotation <* ws <* token ")" in - return (PType (pat, constr)) -;; - -(*--------------------------- Patterns ---------------------------*) - -let ppany = token "_" *> return PAny -let ppconstant = pconstant >>| fun a -> PConstant a - -let variable = - let* fst = ws *> peek_char_fail in - match fst with - | 'a' .. 'z' | '_' -> - let* rest = take_while is_id in - (match rest with - | "_" -> fail "Wildcard can't be used as indetifier" - | s when is_keyword s -> fail "Keyword can't be used as identifier" - | name -> return name) - | _ -> fail "Invalid literal" -;; - -let ppvariable = variable >>| fun v -> PVar v -let pparens p = token "(" *> p <* token ")" -let brackets p = token "[" *> p <* token "]" - -let pptuple ppattern = - let* el1 = ws *> ppattern in - let* el2 = token "," *> ws *> ppattern in - let* rest = many (token "," *> ppattern) in - return (PTuple (el1, el2, rest)) -;; - -let pp_option_none = ws *> token "None" *> return (POption None) -let pp_option_some pe = ws *> token "Some" *> pe >>| fun x -> POption (Some x) -let pp_option pe = choice [ pp_option_none; pp_option_some pe ] - -let ppcons pe = - let* e1 = pe in - let* rest = many (token "::" *> pe) in - let rec helper = function - | [] -> e1 - | [ x ] -> x - | x :: xs -> PCons (x, helper xs) - in - return (helper (e1 :: rest)) -;; - -let pplist pe = - brackets @@ sep_by1 (token ";") pe - >>| function - | [] -> PConstant CNil - | [ x ] -> PList (x, []) - | x :: xs -> PList (x, xs) -;; - -let pattern = - fix (fun pat -> - let term = - choice - [ ppvariable - ; ppany - ; ppconstant - ; pparens pat - ; pp_option pat - ; pattern_with_type pat - ; pplist pat - ] - in - let cons = ppcons term in - let tuple = pptuple term <|> cons in - tuple) -;; - -(*--------------------------- Expressions ---------------------------*) - -let ebinop op e1 e2 = ExprBinOperation (op, e1, e2) -let eapply e1 e2 = ExprApply (e1, e2) -let elet f b bl e = ExprLet (f, b, bl, e) -let efun p e = ExprFun (p, e) -let eif e1 e2 e3 = ExprIf (e1, e2, e3) -let grd = token "|" -let punary_neg = token "-" *> return UnaryMinus -let punary_not = token "not" *> return UnaryNeg -let punary_add = token "+" *> return UnaryPlus -let punary_op = choice [ punary_neg; punary_not; punary_add ] -let peunop pe = lift2 (fun op e -> ExprUnOperation (op, e)) punary_op pe -let pevar = variable >>| fun v -> ExprVariable v -let peconstant = pconstant >>| fun l -> ExprConstant l - -let ematch e = function - | [] -> ExprOption None (* unreachable *) - | [ x ] -> ExprMatch (e, x, []) - | x :: xs -> ExprMatch (e, x, xs) -;; - -let pematch pe = - let pexpr = token "match" *> pe <* token "with" <* option "" grd in - let pcase = lift2 (fun p e -> p, e) (pattern <* token "->") pe in - lift2 ematch pexpr (sep_by1 grd pcase) -;; - -let efunction = function - | [] -> ExprOption None (* unreachable *) - | [ x ] -> ExprFunction (x, []) - | x :: xs -> ExprFunction (x, xs) -;; - -let pefunction pe = - let* _ = token "function" <* option "" grd in - let pcase = lift2 (fun p e -> p, e) (pattern <* token "->") pe in - lift efunction (sep_by1 grd pcase) -;; - -let petuple pe = - let* el1 = ws *> pe in - let* el2 = token "," *> ws *> pe in - let* rest = many (token "," *> pe) in - return (ExprTuple (el1, el2, rest)) -;; - -let pelist pe = - brackets @@ sep_by1 (token ";") pe - >>| function - | [] -> ExprConstant CNil - | [ x ] -> ExprList (x, []) - | x :: xs -> ExprList (x, xs) -;; - -let pecons pe = - let* e1 = pe in - let* rest = many (token "::" *> pe) in - let rec helper = function - | [] -> e1 - | [ x ] -> x - | x :: xs -> ExprCons (x, helper xs) - in - return (helper (e1 :: rest)) -;; - -let padd = token "+" *> return (ebinop Add) -let psub = token "-" *> return (ebinop Sub) -let pmul = token "*" *> return (ebinop Mul) -let pdiv = token "/" *> return (ebinop Div) - -let pcmp = - choice - [ token "=" *> return (ebinop Eq) - ; token "<>" *> return (ebinop Neq) - ; token "<=" *> return (ebinop Lte) - ; token ">=" *> return (ebinop Gte) - ; token "<" *> return (ebinop Lt) - ; token ">" *> return (ebinop Gt) - ; token "&&" *> return (ebinop And) - ; token "||" *> return (ebinop Or) - ] -;; - -let get_rec_keyword = - let* r = ws *> take_while1 is_id in - if String.compare r "rec" = 0 then return true else fail "There in no 'rec' keyword." -;; - -let parse_rec_flag = - let* is_rec = get_rec_keyword <|> return false in - if is_rec then return Rec else return NonRec -;; - -let annot_expr pe = - lift2 (fun expr annot -> ExprType (expr, annot)) (pe <* token ":") parse_type_annotation -;; - -let efunf ps e = List.fold_right ps ~f:efun ~init:e - -let pbinding pe = - both pattern (lift2 efunf (many pattern <* token "=") (annot_expr pe <|> pe)) -;; - -let pelet pe = - lift4 - elet - (token "let" *> parse_rec_flag) - (pbinding pe) - (many (token "and" *> pbinding pe)) - (token "in" *> pe) -;; - -let pefun pe = - lift2 efun (token "fun" *> pattern) (lift2 efunf (many pattern <* token "->") pe) -;; - -let peif pe = - fix (fun peif -> - lift3 - eif - (token "if" *> (peif <|> pe)) - (token "then" *> (peif <|> pe)) - (option None (token "else" *> (peif <|> pe) >>| Option.some))) -;; - -let p_option_none = ws *> token "None" *> return (ExprOption None) -let p_option_some pe = ws *> token "Some" *> pe >>| fun x -> ExprOption (Some x) -let p_option pe = choice [ p_option_none; p_option_some pe ] - -let expr = - fix (fun expr -> - let term = choice [ pevar; peconstant; pelist expr; pparens expr ] in - let apply = chainl1 term (return eapply) in - let apply_with_annot = annot_expr apply <|> apply in - let cons = pecons apply_with_annot in - let ife = peif expr <|> cons in - let opt = p_option ife <|> ife in - let unops = opt <|> peunop opt in - let ops1 = chainl1 unops (pmul <|> pdiv) in - let ops2 = chainl1 ops1 (padd <|> psub) in - let cmp = chainl1 ops2 pcmp in - let tuple = petuple cmp <|> cmp in - choice [ pefunction expr; tuple; pelet expr; pematch expr; pefun expr ]) -;; - -(*--------------------------- Structure ---------------------------*) - -let pstructure = - let pseval = expr >>| fun e -> SEval e in - let psvalue = - lift3 - (fun f b bl -> SValue (f, b, bl)) - (token "let" *> parse_rec_flag) - (pbinding expr) - (many (token "and" *> pbinding expr)) - in - choice [ pseval; psvalue ] -;; - -let structure = - let psemicolon = token ";;" in - many (pstructure <* psemicolon <* ws <|> (pstructure <* ws)) -;; - -let parse s = parse_string ~consume:All structure s - -let parse_to_string input = - match parse input with - | Ok structure -> show_structure structure - | Error err -> err -;; diff --git a/OCamlRV/lib/parser.mli b/OCamlRV/lib/parser.mli deleted file mode 100644 index 9ad87aaba..000000000 --- a/OCamlRV/lib/parser.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val parse : string -> (structure, string) result -val parse_to_string : string -> string diff --git a/OCamlRV/lib/quickcheck.ml b/OCamlRV/lib/quickcheck.ml deleted file mode 100644 index b5df6b7e8..000000000 --- a/OCamlRV/lib/quickcheck.ml +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Ast -open OCamlRV_lib.Parser -open OCamlRV_lib.AstPrinter - -let arbitrary_structure = - QCheck.make gen_structure ~print:(Format.asprintf "%a" pp_structure_item_list) -;; - -let run n = - QCheck_base_runner.run_tests - [ QCheck.Test.make ~count:n arbitrary_structure (fun s -> - (* Stdlib.Format.printf "%s\n" (show_structure s); *) - Result.ok s = parse (Format.asprintf "%a" pp_structure_item_list s)) - ] -;; - -let run_tests n = - let _ = run n in - () -;; - -let () = - Arg.parse - [ "-seed", Arg.Int QCheck_base_runner.set_seed, " Set seed" - ; "-gen", Arg.Int run_tests, " Number of runs" - ] - (fun _ -> assert false) - "help" -;; diff --git a/OCamlRV/lib/quickcheck.mli b/OCamlRV/lib/quickcheck.mli deleted file mode 100644 index 35a49d294..000000000 --- a/OCamlRV/lib/quickcheck.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/manytests.t/.ocamlformat b/OCamlRV/manytests.t/.ocamlformat deleted file mode 100644 index e3346c163..000000000 --- a/OCamlRV/manytests.t/.ocamlformat +++ /dev/null @@ -1 +0,0 @@ -disable=true diff --git a/OCamlRV/manytests.t/do_not_type b/OCamlRV/manytests.t/do_not_type deleted file mode 120000 index 72ad29826..000000000 --- a/OCamlRV/manytests.t/do_not_type +++ /dev/null @@ -1 +0,0 @@ -../../manytests/do_not_type/ \ No newline at end of file diff --git a/OCamlRV/manytests.t/run.t b/OCamlRV/manytests.t/run.t deleted file mode 100644 index d8f87973e..000000000 --- a/OCamlRV/manytests.t/run.t +++ /dev/null @@ -1,81 +0,0 @@ -Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan -SPDX-License-Identifier: LGPL-3.0-or-later - -Test 'typed': - - $ ../bin/main.exe typed/001fac.ml -interpret - 24 - - $ ../bin/main.exe typed/002fac.ml -interpret - 24 - - $ ../bin/main.exe typed/003fib.ml -interpret - 33 - - $ ../bin/main.exe typed/004manyargs.ml -interpret - 1111111111110100 - - $ ../bin/main.exe typed/005fix.ml -interpret - 720 - - $ ../bin/main.exe typed/006partial.ml -interpret - 1122 - - $ ../bin/main.exe typed/006partial2.ml -interpret - 1237 - - $ ../bin/main.exe typed/006partial3.ml -interpret - 489 - -Неопределённый порядок аргументов?.. - $ ../bin/main.exe typed/007order.ml -interpret - 124-1103-55555510000 - - $ ../bin/main.exe typed/008ascription.ml -interpret - 8 - - $ ../bin/main.exe typed/009let_poly.ml -interpret - - - $ ../bin/main.exe typed/010sukharev.ml -interpret - - $ ../bin/main.exe typed/015tuples.ml -interpret - 1111 - - $ ../bin/main.exe typed/016lists.ml -interpret - 1238 - -Test do_not_type: - - $ ../bin/main.exe do_not_type/001.ml -inference - Infer error: Unbound variable 'fac' - - $ ../bin/main.exe do_not_type/002if.ml -inference - Infer error: Unification failed on int and bool - - $ ../bin/main.exe do_not_type/003occurs.ml -inference - Infer error: Occurs check failed - - $ ../bin/main.exe do_not_type/004let_poly.ml -inference - Infer error: Unification failed on bool and int - - $ ../bin/main.exe do_not_type/005.ml -inference - Infer error: Unification failed on int and string - - $ ../bin/main.exe do_not_type/015tuples.ml -inference - Infer error: Only variables are allowed as left-hand side of `let rec' - - $ ../bin/main.exe do_not_type/016tuples_mismatch.ml -inference - Infer error: Unification failed on '0 * '1 and int * int * int - - $ ../bin/main.exe do_not_type/097fun_vs_list.ml -inference - Infer error: Unification failed on '0 list and '1 -> '1 - - $ ../bin/main.exe do_not_type/097fun_vs_unit.ml -inference - Infer error: Unification failed on unit and '0 -> '0 - - $ ../bin/main.exe do_not_type/098rec_int.ml -inference - Infer error: This kind of expression is not allowed as right-hand side of `let rec' - - $ ../bin/main.exe do_not_type/099.ml -inference - Infer error: Only variables are allowed as left-hand side of `let rec' diff --git a/OCamlRV/manytests.t/typed b/OCamlRV/manytests.t/typed deleted file mode 120000 index 791e8f986..000000000 --- a/OCamlRV/manytests.t/typed +++ /dev/null @@ -1 +0,0 @@ -../../manytests/typed/ \ No newline at end of file diff --git a/OCamlRV/tests/astPrinter.ml b/OCamlRV/tests/astPrinter.ml deleted file mode 100644 index 3292307a1..000000000 --- a/OCamlRV/tests/astPrinter.ml +++ /dev/null @@ -1,333 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Ast -open OCamlRV_lib.AstPrinter - -let%expect_test "apply test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval (ExprApply (ExprVariable "f", ExprVariable "x")) ]; - [%expect {| f x;; |}] -;; - -let%expect_test "cons test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval (ExprCons (ExprVariable "f", ExprVariable "x")) ]; - [%expect {| f::x;; |}] -;; - -let%expect_test "let expression test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue (NonRec, (PVar "x", ExprConstant (CInt 5)), []) ]; - [%expect {| let x = 5;; |}] -;; - -let%expect_test "factorial test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( Rec - , ( PVar "fact" - , ExprFun - ( PVar "n" - , ExprIf - ( ExprBinOperation (Lte, ExprVariable "n", ExprConstant (CInt 1)) - , ExprConstant (CInt 1) - , Some - (ExprBinOperation - ( Mul - , ExprVariable "n" - , ExprApply - ( ExprVariable "fact" - , ExprBinOperation - (Sub, ExprVariable "n", ExprConstant (CInt 1)) ) )) ) ) - ) - , [] ) - ]; - [%expect {| let rec fact n = if (n <= (1)) then 1 else (n * (fact (n - (1))));; |}] -;; - -let%expect_test "complex let test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "a" - , ExprLet - ( NonRec - , (PVar "b", ExprConstant (CInt 1)) - , [] - , ExprLet - ( NonRec - , (PVar "c", ExprConstant (CInt 1)) - , [] - , ExprBinOperation (Add, ExprVariable "b", ExprVariable "c") ) ) ) - , [] ) - ]; - [%expect {| let a = let b = 1 in let c = 1 in b + c;; |}] -;; - -let%expect_test "tuple test" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "a" - , ExprTuple - ( ExprConstant (CInt 1) - , ExprConstant (CString "2") - , [ ExprConstant (CInt 3) ] ) ) - , [] ) - ]; - [%expect {| let a = (1, "2", 3);; |}] -;; - -let%expect_test _ = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprCons - ( ExprConstant (CInt 1) - , ExprCons - (ExprConstant (CInt 2), ExprCons (ExprConstant (CInt 3), ExprConstant CNil)) - )) - ]; - [%expect {| 1::(2::(3::[]));; |}] -;; - -let%expect_test "bin op with parentheses" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprBinOperation - ( Add - , ExprConstant (CInt 1) - , ExprBinOperation (Mul, ExprConstant (CInt 2), ExprConstant (CInt 2)) )) - ]; - [%expect {| 1 + (2 * 2);; |}] -;; - -let%expect_test "bin op with parentheses" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprBinOperation - ( Mul - , ExprBinOperation (Add, ExprConstant (CInt 1), ExprConstant (CInt 2)) - , ExprConstant (CInt 2) )) - ]; - [%expect {| (1 + 2) * 2;; |}] -;; - -let%expect_test "let expressions" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , (PVar "a", ExprConstant (CInt 1)) - , [ PVar "b", ExprConstant (CInt 2); PVar "c", ExprConstant (CInt 3) ] ) - ]; - [%expect {| let a = 1 and b = 2 and c = 3;; |}] -;; - -let%expect_test "complex let epressions" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "a" - , ExprLet - ( NonRec - , (PVar "x", ExprConstant (CInt 1)) - , [ PVar "y", ExprConstant (CInt 2) ] - , ExprBinOperation (Add, ExprVariable "x", ExprVariable "y") ) ) - , [] ) - ]; - [%expect {| let a = let x = 1 and y = 2 in x + y;; |}] -;; - -let%expect_test "let none expression" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue (NonRec, (PVar "a", ExprOption None), []) ]; - [%expect {| let a = None;; |}] -;; - -let%expect_test "let some expression" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue (NonRec, (PVar "a", ExprOption (Some (ExprConstant (CInt 1)))), []) ]; - [%expect {| let a = Some (1);; |}] -;; - -let%expect_test "bin op with if then else" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprBinOperation - ( Add - , ExprConstant (CInt 1) - , ExprIf (ExprVariable "a", ExprVariable "b", Some (ExprVariable "c")) )) - ]; - [%expect {| 1 + (if a then b else c);; |}] -;; - -let%expect_test "bin op with if then else" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprBinOperation - ( Add - , ExprConstant (CInt 1) - , ExprIf (ExprVariable "a", ExprVariable "b", Some (ExprVariable "c")) )) - ]; - [%expect {| 1 + (if a then b else c);; |}] -;; - -let%expect_test "pretty print match with multiple branches" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval - (ExprMatch - ( ExprVariable "x" - , (PConstant (CInt 0), ExprConstant (CString "zero")) - , [ PConstant (CInt 1), ExprConstant (CString "one") - ; PAny, ExprConstant (CString "other") - ] )) - ]; - [%expect {| -match x with -| 0 -> "zero" -| 1 -> "one" -| _ -> "other";; -|}] -;; - -let%expect_test "let expr with match match with multiple branches" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "numder" - , ExprMatch - ( ExprVariable "arabic" - , (PConstant (CInt 1), ExprConstant (CString "one")) - , [ PConstant (CInt 2), ExprConstant (CString "two") - ; PConstant (CInt 3), ExprConstant (CString "three") - ] ) ) - , [] ) - ]; - [%expect - {| -let numder = match arabic with -| 1 -> "one" -| 2 -> "two" -| 3 -> "three";; -|}] -;; - -let%expect_test "let expr with match match with multiple branches" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "a" - , ExprFunction - ( (POption None, ExprConstant CUnit) - , [ POption (Some (PVar "e")), ExprConstant CUnit ] ) ) - , [] ) - ]; - [%expect {| -let a = function -| None -> () -| Some (e) -> ();; -|}] -;; - -let%expect_test "" = - Format.printf - "%a\n" - pp_structure_item_list - [ SEval (ExprUnOperation (UnaryNeg, ExprVariable "a")) ]; - [%expect {| not (a);; |}] -;; - -let%expect_test "" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue (NonRec, (PType (PVar "a", AInt), ExprConstant (CInt 5)), []) ]; - [%expect {| let (a : int) = 5;; |}] -;; - -let%expect_test "" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "f" - , ExprFun - ( PType (PVar "x", AInt) - , ExprFun - ( PType (PVar "y", AInt) - , ExprBinOperation (Add, ExprVariable "x", ExprVariable "y") ) ) ) - , [] ) - ]; - [%expect {| let f (x : int) = fun (y : int) -> x + y;; |}] -;; - -let%expect_test "" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue (NonRec, (PType (PVar "a", AList AInt), ExprConstant CNil), []) ]; - [%expect {| let (a : int list) = [];; |}] -;; - -let%expect_test "" = - Format.printf - "%a\n" - pp_structure_item_list - [ SValue - ( NonRec - , ( PVar "addi" - , ExprFun - ( PVar "f" - , ExprFun - ( PVar "g" - , ExprFun - ( PVar "x" - , ExprType - ( ExprApply - ( ExprApply (ExprVariable "f", ExprVariable "x") - , ExprType - (ExprApply (ExprVariable "g", ExprVariable "x"), ABool) - ) - , AInt ) ) ) ) ) - , [] ) - ]; - [%expect {| let addi f = fun g -> fun x -> ((f x) ((g x : bool)) : int);; |}] -;; diff --git a/OCamlRV/tests/astPrinter.mli b/OCamlRV/tests/astPrinter.mli deleted file mode 100644 index 35a49d294..000000000 --- a/OCamlRV/tests/astPrinter.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/tests/dune b/OCamlRV/tests/dune deleted file mode 100644 index 45b89e044..000000000 --- a/OCamlRV/tests/dune +++ /dev/null @@ -1,14 +0,0 @@ -(library - (name tests) - (public_name OCamlRV.Tests) - (libraries OCamlRV_lib) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (inline_tests) - (modules parser astPrinter inferencer interpreter) - (instrumentation - (backend bisect_ppx))) - -(cram - (applies_to quickcheck) - (deps ../lib/quickcheck.exe)) diff --git a/OCamlRV/tests/inferencer.ml b/OCamlRV/tests/inferencer.ml deleted file mode 100644 index 8104bb094..000000000 --- a/OCamlRV/tests/inferencer.ml +++ /dev/null @@ -1,255 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Inferencer - -let test_infer = run_inferencer - -(*---------------- Simple Expressions -----------------*) - -let%expect_test _ = - test_infer {| - let rec fact n = if n <= 1 then 1 else n * fact (n - 1) - |}; - [%expect {| val fact : int -> int |}] -;; - -let%expect_test _ = - test_infer - {| - let rec fib_loop m n i = if i = 0 then m else fib_loop n (n + m) (i - 1) - |}; - [%expect {| val fib_loop : int -> int -> int -> int |}] -;; - -let%expect_test _ = - test_infer - {| - let rec fibo n = if n <= 1 then n else fibo (n - 1) + fibo (n - 2) - |}; - [%expect {| val fibo : int -> int |}] -;; - -let%expect_test _ = - test_infer {|let a b = if b then 1 else 2|}; - [%expect {| val a : bool -> int |}] -;; - -let%expect_test _ = - test_infer {|let a = if true then ()|}; - [%expect {| val a : unit |}] -;; - -let%expect_test _ = - test_infer {|let a = if true then 1|}; - [%expect {| Infer error: Unification failed on int and unit |}] -;; - -let%expect_test _ = - test_infer - {| - let res cond = match cond with | "firstMatch" -> 1 | "SecondMatch" -> 2| _ -> 3 - |}; - [%expect {| val res : string -> int |}] -;; - -(*------------------ List Tests --------------------*) -let%expect_test _ = - test_infer {| let list = []|}; - [%expect {| val list : '0 list |}] -;; - -let%expect_test _ = - test_infer {| - let someCons = 1::2::3::[] - |}; - [%expect {| val someCons : int list |}] -;; - -let%expect_test _ = - test_infer - {| - let rec sum_list lst = match lst with | [] -> 0 | x::xs -> x + sum_list xs - |}; - [%expect {| val sum_list : int list -> int |}] -;; - -let%expect_test _ = - test_infer - {|let rec double_list lst = match lst with - | [] -> [] - | x::xs -> (2 * x)::double_list xs|}; - [%expect {| val double_list : int list -> int list|}] -;; - -(*-------------------Primitives---------------------*) - -let%expect_test _ = - test_infer {| - let f = false|}; - [%expect {| val f : bool |}] -;; - -let%expect_test _ = - test_infer {| - let t = true|}; - [%expect {| val t : bool |}] -;; - -let%expect_test _ = - test_infer {| - let stroka = "this is string"|}; - [%expect {| val stroka : string |}] -;; - -let%expect_test _ = - test_infer {| - let l = 1::2::[]|}; - [%expect {| val l : int list |}] -;; - -let%expect_test _ = - test_infer {| - let l = "1"::"2"::[]|}; - [%expect {| val l : string list |}] -;; - -let%expect_test _ = - test_infer {| - let a = ()|}; - [%expect {| val a : unit |}] -;; - -let%expect_test _ = - test_infer {| - let a = (1, true, "3")|}; - [%expect {| val a : int * bool * string |}] -;; - -let%expect_test _ = - test_infer {| - let a = [1; 2; 3]|}; - [%expect {| val a : int list |}] -;; - -let%expect_test _ = - test_infer {| - let a = ["1"; 2; 3]|}; - [%expect {| Infer error: Unification failed on string and int |}] -;; - -let%expect_test _ = - test_infer {| - let idk (fs : int) (sn : int) = fs + sn * fs|}; - [%expect {| val idk : int -> int -> int |}] -;; - -(* Тесты ниже нужны скорее убедиться чтобы мы всякие ошибки детектили, тк считаю что в тайпчекере важнее находить not well typed случаи *) - -let%expect_test _ = - test_infer {| - let a = "hello" + 5|}; - [%expect {| Infer error: Unification failed on string and int |}] -;; - -let%expect_test _ = - test_infer {| - let a = b + 5|}; - [%expect {| Infer error: Unbound variable 'b' |}] -;; - -let%expect_test _ = - test_infer {| - let b = 1::2 in let a = 5 in b + a |}; - [%expect {| Infer error: Unification failed on int list and int |}] -;; - -let%expect_test _ = - test_infer {| - let a = "hello" + 5|}; - [%expect {| Infer error: Unification failed on string and int |}] -;; - -let%expect_test _ = - test_infer {| - let a = true + 5|}; - [%expect {| Infer error: Unification failed on bool and int |}] -;; - -let%expect_test _ = - test_infer - {| - let res cond = match cond with | 1 -> "firstMatch" | 2 -> "SecondMatch" | "ERRORCASE" -> 3 - |}; - [%expect {| Infer error: Unification failed on int and string |}] -;; - -let%expect_test _ = - test_infer {|let a b = if b then 1 else "two"|}; - [%expect {| Infer error: Unification failed on int and string |}] -;; - -let%expect_test _ = - test_infer {| - let c (a : int) (b : string list) = a + b|}; - [%expect {| Infer error: Unification failed on string list and int |}] -;; - -let%expect_test _ = - test_infer {| - let c (a : int) (b : int list) = a + b|}; - [%expect {| Infer error: Unification failed on int list and int |}] -;; - -let%expect_test _ = - test_infer {| let (a : int) = true |}; - [%expect {| Infer error: Unification failed on int and bool |}] -;; - -let%expect_test _ = - test_infer {| let a = 1 and b = 2 |}; - [%expect {| - val a : int - val b : int - |}] -;; - -let%expect_test _ = - test_infer {| let () = 123 |}; - [%expect {| Infer error: Unification failed on unit and int |}] -;; - -let%expect_test _ = - test_infer {| let Some x = 123 |}; - [%expect {| Infer error: Unification failed on '0 option and int |}] -;; - -let%expect_test _ = - test_infer {| let rec Some x = 123 |}; - [%expect {| Infer error: Only variables are allowed as left-hand side of `let rec' |}] -;; - -let%expect_test _ = - test_infer {| let (a, b, c) = (1, 2) |}; - [%expect {| Infer error: Unification failed on '0 * '1 * '2 and int * int |}] -;; - -let%expect_test _ = - test_infer {| - let f = function - | 1 -> () - | _ -> () - |}; - [%expect {| val f : int -> unit |}] -;; - -let%expect_test _ = - test_infer {| - let f = function - | 1 -> () - | "2" -> () - | _ -> () - |}; - [%expect {| Infer error: Unification failed on int and string |}] -;; diff --git a/OCamlRV/tests/inferencer.mli b/OCamlRV/tests/inferencer.mli deleted file mode 100644 index 35a49d294..000000000 --- a/OCamlRV/tests/inferencer.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/tests/interpreter.ml b/OCamlRV/tests/interpreter.ml deleted file mode 100644 index 8e8a6d0a0..000000000 --- a/OCamlRV/tests/interpreter.ml +++ /dev/null @@ -1,206 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Interpreter - -(* Some arithmetic *) - -let%expect_test _ = - test_interpreter {| - let a = ((2 + 2 - 2) * 7) / 2;; - print_int a;; - |}; - [%expect {| 7 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let x = 1;; - let y = x * 2;; - let z = 3;; - print_int (x + y + z);; - |}; - [%expect {| 6 |}] -;; - -(* Match, Function, Option, Tuple *) - -let%expect_test _ = - test_interpreter - {| - let a = Some 123;; - match a with - | Some x -> print_int x - | None -> print_endline "None" - ;; - |}; - [%expect {| 123 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let a = function - | Some x -> print_int x - | None -> print_endline "None" - ;; - a (None);; - |}; - [%expect {| None |}] -;; - -let%expect_test _ = - test_interpreter - {| - let a = (1, 2);; - match a with - | (0, 0) -> print_endline "Error" - | (1, 2) -> print_endline "Ok" - ;; - |}; - [%expect {| Ok |}] -;; - -let%expect_test _ = - test_interpreter - {| - let a = [1; 2];; - match a with - | [0; 0] -> print_endline "Error" - | [1; 2] -> print_endline "Ok" - ;; - |}; - [%expect {| Ok |}] -;; - -let%expect_test _ = - test_interpreter {| - let () = print_int 1;; - |}; - [%expect {| 1 |}] -;; - -let%expect_test _ = - test_interpreter {| - let _ = print_int 1;; - |}; - [%expect {| 1 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let (a, b, _) = (1, 2, 3);; - print_int a;; - print_int b;; - |}; - [%expect {| 12 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let () = - let (a, b, c) = (1, 2, 3) in - print_int (a + b + c);; - |}; - [%expect {| 6 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let a = 1 and b = 2 and c = 3;; - print_int a;; - print_int b;; - print_int c;; - |}; - [%expect {| 123 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let x = - let a = 1 - and b = 2 - and c = 3 in - a + b + c - ;; - print_int x;; - |}; - [%expect {| 6 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let Some x = Some 1;; - let a, Some y = 1, Some 2;; - print_int x;; - print_int y;; - |}; - [%expect {| 12 |}] -;; - -(* Mutual recursion *) - -let%expect_test _ = - test_interpreter - {| - let rec even n = - match n with - | 0 -> 1 - | x -> odd (x-1) - and odd n = - match n with - | 0 -> 0 - | x -> even (x-1);; - print_int (odd 10);; - print_int (even 10);; - |}; - [%expect {| 01 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let () = - let rec even n = - match n with - | 0 -> 1 - | x -> odd (x-1) - and odd n = - match n with - | 0 -> 0 - | x -> even (x-1) in - print_int (even 7) - |}; - [%expect {| 0 |}] -;; - -(* Some functions *) - -let%expect_test _ = - test_interpreter - {| - let rec f n = if n <= 1 then 1 else n * f (n - 1);; - print_int (f 5);; - |}; - [%expect {| 120 |}] -;; - -let%expect_test _ = - test_interpreter - {| - let rec sum_list lst = - match lst with - | [] -> 0 - | head :: tail -> head + sum_list tail - ;; - print_int (sum_list [1; 2; 3; 4; 5]);; - |}; - [%expect {| 15 |}] -;; diff --git a/OCamlRV/tests/interpreter.mli b/OCamlRV/tests/interpreter.mli deleted file mode 100644 index 35a49d294..000000000 --- a/OCamlRV/tests/interpreter.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/tests/parser.ml b/OCamlRV/tests/parser.ml deleted file mode 100644 index 6dd3c0b4a..000000000 --- a/OCamlRV/tests/parser.ml +++ /dev/null @@ -1,439 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlRV_lib.Ast -open OCamlRV_lib.Parser - -let parse_to_unit input = - match parse input with - | Ok structure -> Stdlib.Format.printf "%s\n" (show_structure structure) - | Error err -> Stdlib.Format.printf "%s\n" err -;; - -(* ------------------- binary operations -------------------*) - -let%expect_test _ = - parse_to_unit "1 + 1"; - [%expect - {| - [(SEval - (ExprBinOperation (Add, (ExprConstant (CInt 1)), (ExprConstant (CInt 1)) - ))) - ] |}] -;; - -(* ------------------- simple let expressions -------------------*) - -let%expect_test _ = - parse_to_unit "let x = 5"; - [%expect {| [(SValue (NonRec, ((PVar "x"), (ExprConstant (CInt 5))), []))] |}] -;; - -let%expect_test _ = - parse_to_unit "let feets = 5280"; - [%expect {| [(SValue (NonRec, ((PVar "feets"), (ExprConstant (CInt 5280))), []))] |}] -;; - -let%expect_test _ = - parse_to_unit {| let lie = "i love Ocaml" |}; - [%expect - {| -[(SValue (NonRec, ((PVar "lie"), (ExprConstant (CString "i love Ocaml"))), - [])) - ]|}] -;; - -let%expect_test _ = - parse_to_unit "let list = []"; - [%expect {| [(SValue (NonRec, ((PVar "list"), (ExprConstant CNil)), []))] |}] -;; - -let%expect_test _ = - parse_to_unit {| let t = (1, "2", 3) |}; - [%expect - {| - [(SValue (NonRec, - ((PVar "t"), - (ExprTuple ((ExprConstant (CInt 1)), (ExprConstant (CString "2")), - [(ExprConstant (CInt 3))]))), - [])) - ] |}] -;; - -let%expect_test _ = - parse_to_unit "a::b"; - [%expect {| - [(SEval (ExprCons ((ExprVariable "a"), (ExprVariable "b"))))] |}] -;; - -(*------------------- if expressions -------------------*) - -let%expect_test _ = - parse_to_unit "if 5 > 3 then true else false"; - [%expect - {| - [(SEval - (ExprIf ( - (ExprBinOperation (Gt, (ExprConstant (CInt 5)), - (ExprConstant (CInt 3)))), - (ExprConstant (CBool true)), (Some (ExprConstant (CBool false)))))) - ] |}] -;; - -let%expect_test _ = - parse_to_unit "if x then 1 + 2 else 3"; - [%expect - {| - [(SEval - (ExprIf ((ExprVariable "x"), - (ExprBinOperation (Add, (ExprConstant (CInt 1)), - (ExprConstant (CInt 2)))), - (Some (ExprConstant (CInt 3)))))) - ] |}] -;; - -let%expect_test _ = - parse_to_unit "if x > y then x * y else square x"; - [%expect - {| - [(SEval - (ExprIf ((ExprBinOperation (Gt, (ExprVariable "x"), (ExprVariable "y"))), - (ExprBinOperation (Mul, (ExprVariable "x"), (ExprVariable "y"))), - (Some (ExprApply ((ExprVariable "square"), (ExprVariable "x"))))))) - ] |}] -;; - -let%expect_test _ = - parse_to_unit "let (a, b) = (1, 2)"; - [%expect - {| - [(SValue (NonRec, - ((PTuple ((PVar "a"), (PVar "b"), [])), - (ExprTuple ((ExprConstant (CInt 1)), (ExprConstant (CInt 2)), []))), - [])) - ] |}] -;; - -let%expect_test _ = - parse_to_unit {| - match a with - | None -> () - | Some e -> () - - |}; - [%expect - {| - [(SEval - (ExprMatch ((ExprVariable "a"), ((POption None), (ExprConstant CUnit)), - [((POption (Some (PVar "e"))), (ExprConstant CUnit))]))) - ] |}] -;; - -let%expect_test _ = - parse_to_unit {| - let a = function - | None -> () - | Some e -> () - |}; - [%expect - {| - [(SValue (NonRec, - ((PVar "a"), - (ExprFunction (((POption None), (ExprConstant CUnit)), - [((POption (Some (PVar "e"))), (ExprConstant CUnit))]))), - [])) - ] |}] -;; - -(*------------------- Factorial and Fibonacci -------------------*) - -let%expect_test "fibo test" = - parse_to_unit "let rec fibo n = if n <= 1 then n else fibo (n - 1) + fibo (n - 2)"; - [%expect - {| - [(SValue (Rec, - ((PVar "fibo"), - (ExprFun ((PVar "n"), - (ExprIf ( - (ExprBinOperation (Lte, (ExprVariable "n"), - (ExprConstant (CInt 1)))), - (ExprVariable "n"), - (Some (ExprBinOperation (Add, - (ExprApply ((ExprVariable "fibo"), - (ExprBinOperation (Sub, (ExprVariable "n"), - (ExprConstant (CInt 1)))) - )), - (ExprApply ((ExprVariable "fibo"), - (ExprBinOperation (Sub, (ExprVariable "n"), - (ExprConstant (CInt 2)))) - )) - ))) - )) - ))), - [])) - ] |}] -;; - -let%expect_test "fib test" = - parse_to_unit "let rec fib_loop m n i = if i = 0 then m else fib_loop n (n + m) (i - 1)"; - [%expect - {| - [(SValue (Rec, - ((PVar "fib_loop"), - (ExprFun ((PVar "m"), - (ExprFun ((PVar "n"), - (ExprFun ((PVar "i"), - (ExprIf ( - (ExprBinOperation (Eq, (ExprVariable "i"), - (ExprConstant (CInt 0)))), - (ExprVariable "m"), - (Some (ExprApply ( - (ExprApply ( - (ExprApply ((ExprVariable "fib_loop"), - (ExprVariable "n"))), - (ExprBinOperation (Add, (ExprVariable "n"), - (ExprVariable "m"))) - )), - (ExprBinOperation (Sub, (ExprVariable "i"), - (ExprConstant (CInt 1)))) - ))) - )) - )) - )) - ))), - [])) - ] |}] -;; - -let%expect_test "factorial test" = - parse_to_unit "let rec fact n = if n <= 1 then 1 else n * fact (n - 1)"; - [%expect - {| -[(SValue (Rec, - ((PVar "fact"), - (ExprFun ((PVar "n"), - (ExprIf ( - (ExprBinOperation (Lte, (ExprVariable "n"), - (ExprConstant (CInt 1)))), - (ExprConstant (CInt 1)), - (Some (ExprBinOperation (Mul, (ExprVariable "n"), - (ExprApply ((ExprVariable "fact"), - (ExprBinOperation (Sub, (ExprVariable "n"), - (ExprConstant (CInt 1)))) - )) - ))) - )) - ))), - [])) - ] -|}] -;; - -(*------------------- match expression -------------------*) - -let%expect_test "match" = - parse_to_unit {|match x with -| 0 -> "zero" -| 1 -> "one" -| _ -> "other" - -|}; - [%expect - {| -[(SEval - (ExprMatch ((ExprVariable "x"), - ((PConstant (CInt 0)), (ExprConstant (CString "zero"))), - [((PConstant (CInt 1)), (ExprConstant (CString "one"))); - (PAny, (ExprConstant (CString "other")))] - ))) - ] -|}] -;; - -let%expect_test "value equals match" = - parse_to_unit - {|let numder = match arabic with -| 1 -> "one" -| 2 -> "two" -| 3 -> "three"|}; - [%expect - {| - [(SValue (NonRec, - ((PVar "numder"), - (ExprMatch ((ExprVariable "arabic"), - ((PConstant (CInt 1)), (ExprConstant (CString "one"))), - [((PConstant (CInt 2)), (ExprConstant (CString "two"))); - ((PConstant (CInt 3)), (ExprConstant (CString "three")))] - ))), - [])) - ] |}] -;; - -let%expect_test "bin operations with if then else" = - parse_to_unit {| 1 + if a then b else c |}; - [%expect - {| - [(SEval - (ExprBinOperation (Add, (ExprConstant (CInt 1)), - (ExprIf ((ExprVariable "a"), (ExprVariable "b"), - (Some (ExprVariable "c")))) - ))) - ] - |}] -;; - -let%expect_test "cons test" = - parse_to_unit "1::2::3::[]"; - [%expect - {| - [(SEval - (ExprCons ((ExprConstant (CInt 1)), - (ExprCons ((ExprConstant (CInt 2)), - (ExprCons ((ExprConstant (CInt 3)), (ExprConstant CNil))))) - ))) - ] - |}] -;; - -let%expect_test "sum list test" = - parse_to_unit - {| let rec sum_list lst = match lst with | [] -> 0 | x::xs -> x + sum_list xs |}; - [%expect - {| - [(SValue (Rec, - ((PVar "sum_list"), - (ExprFun ((PVar "lst"), - (ExprMatch ((ExprVariable "lst"), - ((PConstant CNil), (ExprConstant (CInt 0))), - [((PCons ((PVar "x"), (PVar "xs"))), - (ExprBinOperation (Add, (ExprVariable "x"), - (ExprApply ((ExprVariable "sum_list"), (ExprVariable "xs"))) - ))) - ] - )) - ))), - [])) - ] |}] -;; - -let%expect_test "double list test" = - parse_to_unit - "let rec double_list lst = match lst with | [] -> [] | x::xs -> (2 * x)::double_list \ - xs"; - [%expect - {| - [(SValue (Rec, - ((PVar "double_list"), - (ExprFun ((PVar "lst"), - (ExprMatch ((ExprVariable "lst"), - ((PConstant CNil), (ExprConstant CNil)), - [((PCons ((PVar "x"), (PVar "xs"))), - (ExprCons ( - (ExprBinOperation (Mul, (ExprConstant (CInt 2)), - (ExprVariable "x"))), - (ExprApply ((ExprVariable "double_list"), (ExprVariable "xs") - )) - ))) - ] - )) - ))), - [])) - ] |}] -;; - -let%expect_test "unary tests" = - parse_to_unit "let b = not (x > 5)"; - [%expect - {| - [(SValue (NonRec, - ((PVar "b"), - (ExprUnOperation (UnaryNeg, - (ExprBinOperation (Gt, (ExprVariable "x"), (ExprConstant (CInt 5)))) - ))), - [])) - ] |}] -;; - -(*------------------- type annotation -------------------*) - -let%expect_test "" = - parse_to_unit "let (a : int) = 5"; - [%expect - {| - [(SValue (NonRec, ((PType ((PVar "a"), AInt)), (ExprConstant (CInt 5))), [])) - ] |}] -;; - -let%expect_test "" = - parse_to_unit {| let (a : string) = "hello" |}; - [%expect - {| - [(SValue (NonRec, - ((PType ((PVar "a"), AString)), (ExprConstant (CString "hello"))), - [])) - ] |}] -;; - -let%expect_test "" = - parse_to_unit "let (a : bool) = true"; - [%expect - {| - [(SValue (NonRec, ((PType ((PVar "a"), ABool)), (ExprConstant (CBool true))), - [])) - ] |}] -;; - -let%expect_test "" = - parse_to_unit "let (a : unit) = ()"; - [%expect - {| - [(SValue (NonRec, ((PType ((PVar "a"), AUnit)), (ExprConstant CUnit)), []))] |}] -;; - -let%expect_test "" = - parse_to_unit "let (a : int list) = []"; - [%expect - {| - [(SValue (NonRec, ((PType ((PVar "a"), (AList AInt))), (ExprConstant CNil)), - [])) - ] |}] -;; - -let%expect_test "" = - parse_to_unit "let f (x : int) (y : int) = x + y"; - [%expect - {| - [(SValue (NonRec, - ((PVar "f"), - (ExprFun ((PType ((PVar "x"), AInt)), - (ExprFun ((PType ((PVar "y"), AInt)), - (ExprBinOperation (Add, (ExprVariable "x"), (ExprVariable "y"))))) - ))), - [])) - ] |}] -;; - -let%expect_test "" = - parse_to_unit "let addi = fun f g x -> (f x (g x: bool) : int)"; - [%expect - {| - [(SValue (NonRec, - ((PVar "addi"), - (ExprFun ((PVar "f"), - (ExprFun ((PVar "g"), - (ExprFun ((PVar "x"), - (ExprType ( - (ExprApply ( - (ExprApply ((ExprVariable "f"), (ExprVariable "x"))), - (ExprType ( - (ExprApply ((ExprVariable "g"), (ExprVariable "x"))), - ABool)) - )), - AInt)) - )) - )) - ))), - [])) - ] |}] -;; diff --git a/OCamlRV/tests/parser.mli b/OCamlRV/tests/parser.mli deleted file mode 100644 index 35a49d294..000000000 --- a/OCamlRV/tests/parser.mli +++ /dev/null @@ -1,3 +0,0 @@ -(** Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) diff --git a/OCamlRV/tests/quickcheck.t b/OCamlRV/tests/quickcheck.t deleted file mode 100644 index 4880d7c4a..000000000 --- a/OCamlRV/tests/quickcheck.t +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2024-2025, Viacheslav Sidorov and Danila Rudnev-Stepanyan -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../lib/quickcheck.exe -seed 342723456 -gen 1 - random seed: 342723456 - ================================================================================ - success (ran 1 tests) diff --git a/OCamlWeakTypeVariables/.envrc b/OCamlWeakTypeVariables/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/OCamlWeakTypeVariables/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/OCamlWeakTypeVariables/.gitignore b/OCamlWeakTypeVariables/.gitignore deleted file mode 100644 index e7fa6315a..000000000 --- a/OCamlWeakTypeVariables/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs -myocaml.code-workspace -.vscode \ No newline at end of file diff --git a/OCamlWeakTypeVariables/.ocamlformat b/OCamlWeakTypeVariables/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/OCamlWeakTypeVariables/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/OCamlWeakTypeVariables/.zanuda b/OCamlWeakTypeVariables/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/OCamlWeakTypeVariables/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/OCamlWeakTypeVariables/COPYING b/OCamlWeakTypeVariables/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/OCamlWeakTypeVariables/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OCamlWeakTypeVariables/COPYING.CC0 b/OCamlWeakTypeVariables/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/OCamlWeakTypeVariables/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/OCamlWeakTypeVariables/COPYING.LESSER b/OCamlWeakTypeVariables/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/OCamlWeakTypeVariables/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/OCamlWeakTypeVariables/Makefile b/OCamlWeakTypeVariables/Makefile deleted file mode 100644 index af16a33cb..000000000 --- a/OCamlWeakTypeVariables/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./bin/REPL.exe && rlwrap _build/default/bin/REPL.exe - -infer: - dune build ./bin/REPL.exe && rlwrap _build/default/bin/REPL.exe -dinferprogram - -infers: - dune build ./bin/REPL.exe && rlwrap _build/default/bin/REPL.exe -dinference - -parsetree: - dune build ./bin/REPL.exe && rlwrap _build/default/bin/REPL.exe -dparsetree - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/language dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/OCamlWeakTypeVariables/OCamlWeakTypeVariables.opam b/OCamlWeakTypeVariables/OCamlWeakTypeVariables.opam deleted file mode 100644 index f70b4515c..000000000 --- a/OCamlWeakTypeVariables/OCamlWeakTypeVariables.opam +++ /dev/null @@ -1,42 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for Ocaml" -description: - "Our implementation of interpreter for Ocaml with support of weak type variables!!!!!!!" -maintainer: [ - "Damir Yunusov " - "Ilhom Kombaev " -] -authors: [ - "Damir Yunusov " - "Ilhom Kombaev " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/homka122/OCamlWeakTypeVariables" -doc: "https://kakadu.github.io/fp2024/docs/OCamlWeakTypeVariables" -bug-reports: "https://github.com/homka122/OCamlWeakTypeVariables" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OCamlWeakTypeVariables/bin/REPL.ml b/OCamlWeakTypeVariables/bin/REPL.ml deleted file mode 100644 index 146fbb533..000000000 --- a/OCamlWeakTypeVariables/bin/REPL.ml +++ /dev/null @@ -1,124 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Lib - -type opts = - { mutable dump_parsetree : bool - ; mutable dump_inference : bool - ; mutable dump_parseprogram : bool - ; mutable dump_inferprogram : bool - } - -module REPL_monad = struct - type 'a t = ('a, string) Base.Result.t - - let fail = Base.Result.fail - let return = Base.Result.return - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - match monad with - | Ok result -> f result - | Error x when Base.String.( <> ) x "" -> - Format.printf "Error: %s\n" x; - fail "" - | _ -> fail "" - ;; - - let ( let* ) = ( >>= ) -end - -let run_single opts = - let open REPL_monad in - let text = In_channel.(input_all stdin) |> String.trim in - if not - (opts.dump_inferprogram - || opts.dump_inference - || opts.dump_parsetree - || opts.dump_parseprogram) - then ( - let _ = - let* program = Parser.parse_program text in - let* _ = Infer.run_program_inferencer_exn program in - let* value = Interpreter.run_interpret_exn program in - (* Format.printf "Value: %a\n" Interpreter.pp_value value; *) - return value - in - ()); - if opts.dump_inferprogram - then ( - let ast = Parser.parse_program text in - match ast with - | Error e -> Format.printf "Error: %s\n" e - | Result.Ok program -> - (match Infer.run_program_inferencer program with - | Ok (env, names) -> Format.printf "%a\n" (Infer.TypeEnv.pp_names names) env - | Error e -> Format.printf "Error: %a\n" Infer_print.pp_error_my e)); - if opts.dump_parseprogram - then ( - let ast = Parser.parse_program text in - match ast with - | Error e -> Format.printf "Error: %s\n" e - | Result.Ok program -> Format.printf "Parsed program: %a\n" Ast.pp_program program); - if opts.dump_parsetree - then ( - let ast = Parser.parse text in - match ast with - | Error e -> Format.printf "Error: %s\n%!" e - | Result.Ok ast -> - Format.printf "Parsed result: @[%a@]\n%!" Lib.Ast.pp_structure_item ast); - if opts.dump_inference - then ( - let ast = Parser.parse text in - match ast with - | Error e -> Format.printf "Error: %s\n%!" e - | Result.Ok ast -> - (match ast with - | Pstr_eval expr -> - (match Infer.run_expr_inferencer expr with - | Ok t -> - (* Format.printf "> %s;;\n\n" text; *) - Format.printf "- : %a\n" Infer_print.pp_typ_my t - | Error e -> Format.printf "%a\n" Infer_print.pp_error_my e) - | _ -> - (match Infer.run_structure_inferencer ast with - | Ok (env, names) -> Format.printf "%a\n" (Infer.TypeEnv.pp_names names) env - | Error e -> Format.printf "Error: %a\n" Infer_print.pp_error_my e))) -;; - -let () = - let opts = - { dump_parsetree = false - ; dump_inference = false - ; dump_parseprogram = false - ; dump_inferprogram = false - } - in - let () = - let open Stdlib.Arg in - parse - [ ( "-dparsetree" - , Unit (fun () -> opts.dump_parsetree <- true) - , "Dump parse tree, don't eval anything" ) - ; ( "-dinference" - , Unit (fun () -> opts.dump_inference <- true) - , "Infer structure, don't eval anything" ) - ; ( "-dparseprogram" - , Unit (fun () -> opts.dump_parseprogram <- true) - , "Dump parse program, don't eval anything" ) - ; ( "-dinferprogram" - , Unit (fun () -> opts.dump_inferprogram <- true) - , "Infer program, don't eval anything" ) - ] - (fun _ -> - Stdlib.Format.eprintf "Anonymous arguments are not supported\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for my cool homka&damir's parser" - in - run_single opts -;; diff --git a/OCamlWeakTypeVariables/bin/dune b/OCamlWeakTypeVariables/bin/dune deleted file mode 100644 index 1ff280138..000000000 --- a/OCamlWeakTypeVariables/bin/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (libraries lib)) - -(cram - (deps ./REPL.exe %{bin:REPL})) diff --git a/OCamlWeakTypeVariables/bin/repl.t b/OCamlWeakTypeVariables/bin/repl.t deleted file mode 100644 index 033f8dfcb..000000000 --- a/OCamlWeakTypeVariables/bin/repl.t +++ /dev/null @@ -1,11 +0,0 @@ -Copyright 2024-2025, Damir Yunusov, Ilhom Kombaev -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ./REPL.exe -help - Read-Eval-Print-Loop for my cool homka&damir's parser - -dparsetree Dump parse tree, don't eval anything - -dinference Infer structure, don't eval anything - -dparseprogram Dump parse program, don't eval anything - -dinferprogram Infer program, don't eval anything - -help Display this list of options - --help Display this list of options diff --git a/OCamlWeakTypeVariables/dune b/OCamlWeakTypeVariables/dune deleted file mode 100644 index 98e54536a..000000000 --- a/OCamlWeakTypeVariables/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/OCamlWeakTypeVariables/dune-project b/OCamlWeakTypeVariables/dune-project deleted file mode 100644 index 086741997..000000000 --- a/OCamlWeakTypeVariables/dune-project +++ /dev/null @@ -1,37 +0,0 @@ -(lang dune 3.7) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors - "Damir Yunusov " - "Ilhom Kombaev ") - -(maintainers - "Damir Yunusov " - "Ilhom Kombaev ") - -(bug_reports "https://github.com/homka122/OCamlWeakTypeVariables") - -(homepage "https://github.com/homka122/OCamlWeakTypeVariables") - -(generate_opam_files true) - -(package - (name OCamlWeakTypeVariables) - (synopsis "An interpreter for Ocaml") - (description - "Our implementation of interpreter for Ocaml with support of weak type variables!!!!!!!") - (documentation - "https://kakadu.github.io/fp2024/docs/OCamlWeakTypeVariables") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build))) diff --git a/OCamlWeakTypeVariables/lib/ast.ml b/OCamlWeakTypeVariables/lib/ast.ml deleted file mode 100644 index 22525cafb..000000000 --- a/OCamlWeakTypeVariables/lib/ast.ml +++ /dev/null @@ -1,72 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** constants *) -type constant = - | Pconst_int of int (** constant of int. Ex: 5 *) - | Pconst_string of string (** constant of string. Ex: "homka" *) - | Pconst_boolean of bool (** constant of boolean. Ex: true *) -[@@deriving show { with_path = false }] - -(** identificator *) -type id = string [@@deriving show { with_path = false }] - -type pattern = - | Ppat_any (** The pattern _. *) - | Ppat_var of string (** A variable pattern such as x *) - | Ppat_constant of constant (** Patterns such as 1, 'a', "true", 1.0 *) - | Ppat_tuple of pattern list (** Patterns (P1, ..., Pn). Invariant: n >= 2 *) - | Ppat_construct of id * pattern option -[@@deriving show { with_path = false }] - -(** recursive flag *) -type rec_flag = - | Recursive - | NonRecursive -[@@deriving show { with_path = false }] - -type expression = - | Pexp_ident of id (** Identifiers. Ex: "homka" *) - | Pexp_constant of constant (** Expressions constant. Ex: 5, "Homka", true *) - | Pexp_let of rec_flag * value_binding list * expression - (** Pexp_let(flag, [(P1,E1) ; ... ; (Pn,En)], E) represents: - let P1 = E1 and ... and Pn = EN in E when flag is Nonrecursive - let rec P1 = E1 and ... and Pn = EN in E when flag is Recursive *) - | Pexp_fun of pattern * expression (** fun P -> E *) - | Pexp_apply of expression * expression list (** Function: Ex: print a (5 + 5) b true *) - | Pexp_tuple of expression list (** Expressions (E1, ..., En). Invariant: n >= 2 *) - | Pexp_ifthenelse of expression * expression * expression option - (** if E1 then E2 else E3. Ex: If homka then hype else no_hype *) - | Pexp_constraint of expression * Types.typ (** (E : T) *) - | Pexp_construct of id * expression option - | Pexp_match of expression * case list (** match E0 with P1 -> E1 | ... | Pn -> En *) - | Pexp_function of case list (** function P1 -> E1 | ... | Pn -> En *) -[@@deriving show { with_path = false }] - -(* let pat : type_constraint = exp *) -and value_binding = - { pvb_pat : pattern - ; pvb_expr : expression - } -[@@deriving show { with_path = false }] - -and case = - { pc_lhs : pattern - ; pc_rhs : expression - } -[@@deriving show { with_path = false }] - -type structure_item = - | Pstr_eval of expression - | Pstr_value of rec_flag * value_binding list - (** Pstr_value(rec, [(P1, E1 ; ... ; (Pn, En))]) represents: - et P1 = E1 and ... and Pn = EN when rec is Nonrecursive, - let rec P1 = E1 and ... and Pn = EN when rec is Recursive.*) -[@@deriving show { with_path = false }] - -type program = structure_item list [@@deriving show { with_path = false }] diff --git a/OCamlWeakTypeVariables/lib/config.ml b/OCamlWeakTypeVariables/lib/config.ml deleted file mode 100644 index 5dbffd898..000000000 --- a/OCamlWeakTypeVariables/lib/config.ml +++ /dev/null @@ -1,13 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -let debug = false -let vars_min = true -let vars_char = true -let show_scheme_vars = false -let use_cuneiform = true diff --git a/OCamlWeakTypeVariables/lib/config.mli b/OCamlWeakTypeVariables/lib/config.mli deleted file mode 100644 index 816fcdecd..000000000 --- a/OCamlWeakTypeVariables/lib/config.mli +++ /dev/null @@ -1,41 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Enable debug output to stdout. - If true, prints debug messages to stdout. *) -val debug : bool - -(** Minimize type variables. - If true, type variables will minimize as much as possible. - Example: '4 -> '2 -> ('5 option) -> '4 - becomes: '1 -> '2 -> '3 option -> '1 *) -val vars_min : bool - -(** Representing type variables with letters instead of numbers. - If true, type variables use alphabetical characters (e.g., 'a 'b). - Example: '4 -> '2 -> >('5 option) -> '4 - becomes: 'd -> 'b -> ('e option) -> 'd *) -val vars_char : bool - -(** Display quantified type variables explicitly. - If true, binding variables are printed before the type. - For example 'a -> 'b -> int - will be 'b . 'a -> 'b -> int *) -val show_scheme_vars : bool - -(** Cuneiform is a logo-syllabic writing system that was used to write several languages of the Ancient Near East. - The script was in active use from the early Bronze Age until the beginning of the Common Era. - Cuneiform scripts are marked by and named for the characteristic wedge-shaped impressions (Latin: cuneus) which form their signs. - Cuneiform is the earliest known writing system and was originally developed to write - the Sumerian language of southern Mesopotamia. - - For example '4 -> '2 -> ('5 option) -> '4 - becomes: '𒀀 -> '𒀐 -> '𒀲 option -> '𒀀 - - Inspired by Kirill Smirnov *) -val use_cuneiform : bool diff --git a/OCamlWeakTypeVariables/lib/dune b/OCamlWeakTypeVariables/lib/dune deleted file mode 100644 index df5b6eb20..000000000 --- a/OCamlWeakTypeVariables/lib/dune +++ /dev/null @@ -1,16 +0,0 @@ -(library - (name lib) - (libraries angstrom config) - (modules ast parser types infer infer_print interpreter) - (inline_tests) - (preprocess - (pps ppx_deriving.show ppx_inline_test ppx_expect)) - (instrumentation - (backend bisect_ppx))) - -(library - (name config) - (libraries angstrom) - (modules config) - (instrumentation - (backend bisect_ppx))) diff --git a/OCamlWeakTypeVariables/lib/infer.ml b/OCamlWeakTypeVariables/lib/infer.ml deleted file mode 100644 index 0696a6339..000000000 --- a/OCamlWeakTypeVariables/lib/infer.ml +++ /dev/null @@ -1,799 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Ast -open Types -open Config - -module R : sig - type 'a t - - val return : 'a -> 'a t - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - val ( <$> ) : ('a -> 'b) -> 'a t -> 'b t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - - (* Map functions by Homka122 😼😼😼 *) - val map : 'a list -> f:('a -> 'b t) -> 'b list t - val fmap : 'a list -> f:('a -> 'b) -> 'b list t - val map2 : 'a list -> 'b list -> f:('a -> 'b -> 'c t) -> 'c list t - val fmap2 : 'a list -> 'b list -> f:('a -> 'b -> 'c) -> 'c list t - end - - module RMap : sig - val fold_left - : ('a, 'b, 'c) Base.Map.t - -> init:'d t - -> f:('a -> 'b -> 'd -> 'd t) - -> 'd t - end - - val fresh : int t - val run : 'a t -> int -> ('a, error) Result.t -end = struct - type 'a t = int -> int * ('a, error) Result.t (* State and Result monad composition *) - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f s -> - match m s with - | s, Result.Error e -> s, Error e - | s, Result.Ok v -> f v s - ;; - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun m f s -> - match m s with - | s, Result.Error e -> s, Error e - | s, Result.Ok v -> s, Base.Result.return @@ f v - ;; - - let ( <$> ) : ('a -> 'b) -> 'a t -> 'b t = fun f m -> m >>| f - let return v last = last, Base.Result.return v - let fail e state = state, Base.Result.fail e - let bind x ~f = x >>= f - let fresh last = last + 1, Result.Ok last - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - module RMap = struct - let fold_left mp ~init ~f = - let open Syntax in - Base.Map.fold mp ~init ~f:(fun ~key ~data acc -> - let* acc = acc in - f key data acc) - ;; - end - - module RList = struct - let fold_left lt ~init ~f = - let open Syntax in - Base.List.fold_left lt ~init ~f:(fun acc item -> - let* acc = acc in - f acc item) - ;; - - (* Map functions by Homka122 😼😼😼 (I'm proud of these) *) - let map xs ~f = - let open Syntax in - let rec helper acc = function - | x :: t -> - let* res = f x in - helper (res :: acc) t - | [] -> return (List.rev acc) - in - helper [] xs - ;; - - let fmap xs ~f = map xs ~f:(fun x -> return (f x)) - - let map2 xs ys ~f = - let open Syntax in - let rec helper acc = function - | [], [] -> return (List.rev acc) - | [], _ :: _ | _ :: _, [] -> fail (SomeError "two lists must be have equal size") - | hx :: tx, hy :: ty -> - let* res = f hx hy in - helper (res :: acc) (tx, ty) - in - helper [] (xs, ys) - ;; - - let fmap2 xs ys ~f = map2 xs ys ~f:(fun x y -> return (f x y)) - end - - let run m init = snd (m init) -end - -module Type = struct - type t = typ - - let rec occurs_in v = function - | TVar b -> b = v - | TArrow (left, right) -> occurs_in v left || occurs_in v right - | TList typ -> occurs_in v typ - | TOption typ -> occurs_in v typ - | TTuple (a, b, typ_list) -> - List.fold_left (fun acc item -> acc || occurs_in v item) false (a :: b :: typ_list) - | TBase _ -> false - ;; - - let type_vars = - let rec helper acc = function - | TVar n -> TVarSet.add n acc - | TArrow (left, right) -> helper (helper acc left) right - | TList typ -> helper acc typ - | TOption typ -> helper acc typ - | TTuple (a, b, typ_list) -> List.fold_left helper acc (a :: b :: typ_list) - | TBase _ -> acc - in - helper TVarSet.empty - ;; -end - -module Subst : sig - type t - - val empty : t - val singleton : int -> typ -> t R.t - val remove : t -> int -> t - val apply : t -> typ -> typ - val unify : typ -> typ -> t R.t - val compose : t -> t -> t R.t - val compose_all : t list -> t R.t - val pp : Format.formatter -> t -> unit -end = struct - open R - open R.Syntax - - type t = (type_var, typ, Base.Int.comparator_witness) Base.Map.t - - let empty = Base.Map.empty (module Base.Int) - - let mapping k v = - (* if debug then Format.printf "Mapping %d to %s\n" k @@ show_typ v; *) - if Type.occurs_in k v then fail (OccursCheckFailed (k, v)) else return (k, v) - ;; - - let singleton k v = - let* k, v = mapping k v in - return (Base.Map.singleton (module Base.Int) k v) - ;; - - let find (sub : t) k = Base.Map.find sub k - let remove (sub : t) k : t = Base.Map.remove sub k - - let apply sub t = - let rec helper t = - match t with - | TVar n -> - (match find sub n with - | None -> TVar n - | Some (TVar v) when v = n -> TVar n - | Some v -> helper v) - | TArrow (left, right) -> TArrow (helper left, helper right) - | TList typ -> TList (helper typ) - | TOption typ -> TOption (helper typ) - | TTuple (a, b, t_list) -> - TTuple (helper a, helper b, Base.List.map t_list ~f:helper) - | TBase t -> TBase t - in - helper t - ;; - - let rec unify l r = - (* if debug then Format.printf "Unify: %s AND %s\n" (show_typ l) (show_typ r); *) - match l, r with - | TBase l, TBase r when l = r -> return empty - | TVar a, TVar b when a = b -> return empty - | TVar a, t | t, TVar a -> singleton a t - | TArrow (left1, right1), TArrow (left2, right2) -> - let* sub1 = unify left1 left2 in - let* sub2 = unify (apply sub1 right1) (apply sub1 right2) in - compose sub1 sub2 - | TList typ1, TList typ2 -> unify typ1 typ2 - | TOption typ1, TOption typ2 -> unify typ1 typ2 - | TTuple (a, b, t_list1), TTuple (c, d, t_list2) -> - (match - Base.List.fold2 - (a :: b :: t_list1) - (c :: d :: t_list2) - ~init:(return empty) - ~f:(fun acc it1 it2 -> - let* sub1 = acc in - let* sub2 = unify (apply sub1 it1) (apply sub1 it2) in - compose sub1 sub2) - with - | Ok r -> r - | _ -> fail (UnificationFailed (l, r))) - | _ -> fail (UnificationFailed (l, r)) - - and compose sub1 sub2 = - (* RMap.fold_left sub2 ~init:(return sub1) ~f:extend *) - let sub2 = Base.Map.map sub2 ~f:(fun s -> apply sub1 s) in - let* sub = - Base.Map.fold sub1 ~init:(return sub2) ~f:(fun ~key ~data sub -> - let* sub = sub in - match Base.Map.find sub key with - | None -> return @@ Base.Map.add_exn sub ~key ~data - | Some v -> - let* s = unify v data in - compose s sub) - in - return sub - ;; - - let compose_all sub_list = - RList.fold_left (List.rev sub_list) ~init:(return empty) ~f:compose - ;; - - let pp fmt sub = - if Base.Map.is_empty sub - then Format.fprintf fmt "empty" - else ( - Format.fprintf fmt "{"; - Base.Map.iteri sub ~f:(fun ~key ~data -> - Format.fprintf - fmt - "%a : %a; " - Infer_print.pp_typ_my - (TVar key) - Infer_print.pp_typ_my - data); - Format.fprintf fmt "}") - ;; -end - -let print_sub ?(name = "Sub") sub = Format.printf "%s: %a\n" name Subst.pp sub - -module Scheme = struct - let free_vars (Scheme (bind_vars, ty)) = TVarSet.diff (Type.type_vars ty) bind_vars - - let apply sub (Scheme (bind_vars, ty)) = - let sub2 = TVarSet.fold (fun sub key -> Subst.remove key sub) bind_vars sub in - Scheme (bind_vars, Subst.apply sub2 ty) - ;; -end - -module TypeEnv : sig - type t - - val empty : t - val free_vars : t -> TVarSet.t - val extend : t -> string -> scheme -> t - val find : t -> string -> scheme option - val find_exn : t -> string -> scheme - val remove : t -> string -> t - val apply : Subst.t -> t -> t - val operators : (id list * typ) list - val pp : Format.formatter -> t -> unit - val pp_names : id list -> Format.formatter -> t -> unit - val print : ?name:string -> t -> unit -end = struct - type t = (string, scheme, Base.String.comparator_witness) Base.Map.t - - let empty : t = Base.Map.empty (module Base.String) - - let free_vars (env : t) = - Base.Map.fold - ~init:TVarSet.empty - ~f:(fun ~key:_ ~data acc -> TVarSet.union acc (Scheme.free_vars data)) - env - ;; - - let apply sub env = Base.Map.map env ~f:(Scheme.apply sub) - let extend env key schema = Base.Map.update env key ~f:(fun _ -> schema) - let find = Base.Map.find - let find_exn = Base.Map.find_exn - let remove = Base.Map.remove - - let operators = - [ [ "+"; "-"; "*"; "/" ], TBase BInt @-> TBase BInt @-> TBase BInt - ; [ "print_int" ], TBase BInt @-> TBase BUnit - ; [ "<="; "<"; ">"; ">="; "="; "<>" ], TVar 0 @-> TVar 0 @-> TBase BBool - ; [ "Some" ], TVar 0 @-> TOption (TVar 0) - ; [ "None" ], TOption (TVar 0) - ; [ "()" ], TBase BUnit - ; [ "[]" ], TList (TVar 0) - ; [ "::" ], TTuple (TVar 0, TList (TVar 0), []) @-> TList (TVar 0) - ] - ;; - - let pp_key_value fmt key (Scheme (s, t)) = - if not Config.show_scheme_vars - then Format.fprintf fmt "val %s : %a\n" key Infer_print.pp_typ_my t - else ( - Format.fprintf fmt "val %s: " key; - TVarSet.iter (fun t -> Format.fprintf fmt "%a " Infer_print.pp_typ_my (TVar t)) s; - Format.fprintf fmt ". %a\n" Infer_print.pp_typ_my t) - ;; - - let pp fmt env = Base.Map.iteri env ~f:(fun ~key ~data -> pp_key_value fmt key data) - - (* Print types of specific variables *) - let pp_names names fmt env = - List.iter - (fun key -> - let value = find_exn env key in - pp_key_value fmt key value) - names - ;; - - let print ?(name = "Env") env = Format.printf "%s: %a" name pp env -end - -let ( >- ) = TypeEnv.apply -let ( |- ) = Subst.apply - -module DebugLog = struct - let log (f : unit -> unit) = - if debug - then ( - f (); - print_newline ()) - ;; - - module Aux = struct - let non_rec_vb env sub = - (fun () -> - TypeEnv.print env; - Format.printf "sub: %a\n" Subst.pp sub) - |> log - ;; - - let rec_vb env' subs ts sub env'' = - (fun () -> - Format.printf "Env: \n%a\n" TypeEnv.pp env'; - List.iter (fun sub -> Format.printf "Sub: %a\n" Subst.pp sub) subs; - List.iter (fun t -> Format.printf "Type: %a\n" Infer_print.pp_typ_my t) ts; - Format.printf "Sub: %a\n" Subst.pp sub; - Format.printf "Env: %a\n" TypeEnv.pp env'') - |> log - ;; - end - - module Expr = struct - let apply env e0 = - (fun () -> - Format.printf "Env: %a\n" TypeEnv.pp env; - Format.printf "e0: %a\n" pp_expression e0) - |> log - ;; - - let apply_helper_1 e = - (fun () -> - Format.printf "APPLY\n"; - Format.printf "e1: %a\n" pp_expression e) - |> log - ;; - - let apply_helper_2 t0 sub0 t1 sub1 sub2 sub3 = - (fun () -> - Infer_print.( - Format.printf "t0: %a sub0: %a\n" pp_typ_my t0 Subst.pp sub0; - Format.printf "t1: %a sub1: %a\n" pp_typ_my t1 Subst.pp sub1; - Format.printf "sub2: %a\n" Subst.pp sub2; - Format.printf "sub3: %a\n" Subst.pp sub3; - print_newline ())) - |> log - ;; - - let non_rec_let let_expr t sub1 sub = - (fun () -> - Format.printf "Non rec let %a\n" pp_expression let_expr; - Format.printf "t: %a\n" Infer_print.pp_typ_my t; - Format.printf "sub1: %a\n" Subst.pp sub1; - Format.printf "sub: %a\n" Subst.pp sub) - |> log - ;; - - let match_expr env_pat ty_expr t_pat sub_expr sub_un_exprs sub = - (fun () -> - TypeEnv.print env_pat; - Infer_print.print_typ ~name:"ty_expr" ty_expr; - Infer_print.print_typ ~name:"t_pat" t_pat; - print_sub ~name:"sub_expr" sub_expr; - print_sub ~name:"sub_un_expr" sub_un_exprs; - print_sub ~name:"sub" sub) - |> log - ;; - end -end - -open R -open R.Syntax - -let fresh_var = fresh >>| fun name -> TVar name - -let instantiate : scheme -> typ R.t = - fun (Scheme (bind_var, ty)) -> - TVarSet.fold - (fun var_name acc -> - let* acc = acc in - let* fv = fresh_var in - let* sub = Subst.singleton var_name fv in - return (sub |- acc)) - bind_var - (return ty) -;; - -let generalize : TypeEnv.t -> Type.t -> scheme = - fun env ty -> - let free = TVarSet.diff (Type.type_vars ty) (TypeEnv.free_vars env) in - Scheme (free, ty) -;; - -let lookup_env env name = - match TypeEnv.find env name with - | Some scheme -> - let* ty = instantiate scheme in - return (ty, Subst.empty) - | None -> fail (Unbound name) -;; - -let infer_const c = - let ty = - match c with - | Pconst_int _ -> TBase BInt - | Pconst_boolean _ -> TBase BBool - | Pconst_string _ -> TBase BString - in - return (ty, Subst.empty) -;; - -let rec infer_pattern env ?ty = - let names = [] in - function - | Ppat_var v -> - let* fv = fresh_var in - let schema = - match ty with - | Some t -> generalize env t - | None -> Scheme (TVarSet.empty, fv) - in - let env = TypeEnv.extend env v schema in - return (fv, env, v :: names) - | Ppat_constant c -> - let* ty, _ = infer_const c in - return (ty, env, []) - | Ppat_tuple [] | Ppat_tuple [ _ ] -> - fail (SomeError "Pattern tuple must contain greather or equal two elements") - | Ppat_tuple (first :: second :: pats) -> - let* fv1, env1, names1 = infer_pattern env first in - let* fv2, env2, names2 = infer_pattern env1 second in - let infer_pats_acc acc pat = - let fvs, env, names = acc in - let* fv, env, new_names = infer_pattern env pat in - return (fv :: fvs, env, names @ new_names) - in - let* fvs, env, names = - RList.fold_left ~init:(return ([], env2, [])) ~f:infer_pats_acc pats - in - (* not effective list concat but this is for mother of readability *) - return (TTuple (fv1, fv2, List.rev fvs), env, names1 @ names2 @ names) - | Ppat_construct (name, None) -> - let* ty, _ = lookup_env env name in - return (ty, env, []) - | Ppat_construct (name, Some pat) -> - let* ty, _ = lookup_env env name in - (match ty with - | TArrow (f, s) -> - let* ty_pat, env, names = infer_pattern env pat in - let* sub_un = Subst.unify f ty_pat in - return (sub_un |- s, sub_un >- env, names) - | _ -> fail (SomeError "Constructor don't accept arguments")) - | Ppat_any -> - let* fv = fresh_var in - return (fv, env, names) -;; - -let infer_non_rec_value_bindings infer_expr env vbs = - (* Example: let homka = fun x y -> let z = x y in z + 2 *) - let* env, sub, names = - RList.fold_left - ~f:(fun (env, sub, names) vb -> - (* Env: {x: 'a, y: 'b} *) - (* vb: {pat: z, expr: x y} *) - (* So t0 will be 'c and sub0 will be '{a: 'b -> 'c} *) - let* t0, sub0 = infer_expr env vb.pvb_expr in - let* sub = Subst.compose sub0 sub in - let env = TypeEnv.apply sub env in - (* With type (x y): 'c we append new variable z with type 'c *) - let* env, sub, new_names = - match vb.pvb_pat with - | Ppat_var v -> (TypeEnv.extend env v (generalize env t0), sub, [ v ]) |> return - | _ -> - let* t, env, new_names = infer_pattern env vb.pvb_pat in - let* sub_un = Subst.unify t t0 in - let* sub = Subst.compose_all [ sub_un; sub ] in - return (TypeEnv.apply sub env, sub, new_names) - in - let repeated_name = List.find_opt (fun name -> List.mem name names) new_names in - match repeated_name with - | Some name -> fail (PatternNameTwice name) - | None -> return (env, sub, List.append (List.rev new_names) names)) - ~init:(return (env, Subst.empty, [])) - vbs - in - DebugLog.Aux.non_rec_vb env sub; - return (env, sub, names) -;; - -let rec get_expr_names = function - | Pexp_ident i -> [ i ] - | Pexp_constant _ -> [] - | Pexp_apply (e0, es) -> - List.fold_left (fun acc e -> get_expr_names e @ acc) [] (e0 :: es) - | Pexp_constraint (e, _) -> get_expr_names e - | Pexp_construct (e, None) -> [ e ] - | Pexp_construct (e, Some c) -> e :: get_expr_names c - | Pexp_fun (_, e) -> get_expr_names e - | Pexp_function cs -> - List.fold_left (fun acc case -> get_expr_names case.pc_rhs @ acc) [] cs - | Pexp_ifthenelse (e0, e1, None) -> get_expr_names e0 @ get_expr_names e1 - | Pexp_ifthenelse (e0, e1, Some e2) -> - get_expr_names e0 @ get_expr_names e1 @ get_expr_names e2 - | Pexp_let (_, _, e) -> get_expr_names e - | Pexp_match (e, cs) -> get_expr_names e @ get_expr_names (Pexp_function cs) - | Pexp_tuple es -> List.fold_left (fun acc e -> get_expr_names e @ acc) [] es -;; - -let infer_rec_value_bindings infer_expr env vbs = - let exprs, patterns = List.split @@ List.map (fun x -> x.pvb_expr, x.pvb_pat) vbs in - (* New type variables to all names in patterns *) - let* env', fvs, names = - RList.fold_left - patterns - ~init:(return (env, [], [])) - ~f:(fun (env, fvs, names) pat -> - let* fv, env, new_names = infer_pattern env pat in - let repeated_name = List.find_opt (fun name -> List.mem name new_names) names in - match repeated_name with - | Some name -> fail (PatternNameTwice name) - | None -> return (env, fv :: fvs, List.append (List.rev new_names) names)) - in - (* We get types of e0, e1, ... en and additional type info about type of variables outside of ei expression for all i *) - let* ts, subs = List.split <$> RList.map exprs ~f:(fun expr -> infer_expr env' expr) in - (* Combine all information about variables *) - let* sub = Subst.compose_all subs in - (* Apply all gotten types to out new names *) - let* env'' = - RList.fold_left - (List.combine (List.combine ts fvs) patterns) - ~init:(return env) - ~f:(fun env ((ty, fv), pat) -> - match pat with - | Ppat_var v -> - let* sub_un = Subst.unify ty (sub |- fv) in - let env = - TypeEnv.extend (TypeEnv.apply sub env) v (generalize env (sub_un |- ty)) - in - return env - | _ -> - SomeError "Only variables are allowed as left-hand side of `let rec`" |> fail) - in - DebugLog.Aux.rec_vb env' subs ts sub env''; - let validate_expr expr = - (* List.iter (Format.printf "%s ") (get_expr_names expr); *) - (* List.iter (Format.printf "%s ") names; *) - let has_no_free_occurence = - List.for_all (fun name -> not (List.mem name names)) (get_expr_names expr) - in - let is_variable_fun_function = - match expr with - | Pexp_ident _ | Pexp_fun _ | Pexp_function _ -> true - | _ -> false - in - has_no_free_occurence || is_variable_fun_function - in - let result_expr_check = List.for_all validate_expr exprs in - if not result_expr_check - then - fail - (SomeError "This kind of expression is not allowed as right-hand side of 'let rec'") - else return (env'', sub, names) -;; - -(* https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Algorithm_W *) -let infer_expr = - let rec helper : TypeEnv.t -> expression -> (typ * Subst.t) t = - fun env expr -> - (* if debug then Format.printf "Infer expression: \n\t%s\n" (show_expression expr); *) - match expr with - | Pexp_constant c -> infer_const c - | Pexp_ident id -> lookup_env env id - | Pexp_fun (pattern, expr) -> - let* t, env', _ = infer_pattern env pattern in - let* t', sub = helper env' expr in - return (sub |- t @-> t', sub) - (* Constraint type inference by Homka122 😼😼😼 *) - | Pexp_constraint (expr, ty) -> - let* t, sub = helper env expr in - let* sub0 = Subst.unify t ty in - let* sub = Subst.compose sub0 sub in - return (t, sub) - (* Recursive apply type inference by Homka122 😼😼😼 *) - | Pexp_apply (e0, es) -> - DebugLog.Expr.apply env e0; - let rec helper_apply init = function - | [] -> return init - | e1 :: tl -> - DebugLog.Expr.apply_helper_1 e1; - let* t' = fresh_var in - let t0, sub0 = init in - let* t1, sub1 = helper (sub0 >- env) e1 in - let* sub2 = Subst.unify (sub1 |- t0) (t1 @-> t') in - let* sub3 = Subst.compose_all [ sub0; sub1; sub2 ] in - DebugLog.Expr.apply_helper_2 t0 sub0 t1 sub1 sub2 sub3; - helper_apply (sub2 |- t', sub3) tl - in - let* init = helper env e0 in - helper_apply init es - (* Recursive ifthenelse type inference with option else by Homka122 😼😼😼 *) - | Pexp_ifthenelse (e0, e1, None) -> - let* t0, sub0 = helper env e0 in - let* t1, sub1 = helper env e1 in - let* sub_bool = Subst.unify t0 (TBase BBool) in - let* sub = Subst.compose_all [ sub_bool; sub1; sub0 ] in - return (sub |- t1, sub) - | Pexp_ifthenelse (e0, e1, Some e2) -> - let* t0, sub0 = helper env e0 in - let* t1, sub1 = helper env e1 in - let* t2, sub2 = helper env e2 in - let* sub_bool = Subst.unify t0 (TBase BBool) in - let* sub_eq = Subst.unify t1 t2 in - let* sub = Subst.compose_all [ sub_bool; sub_eq; sub2; sub1; sub0 ] in - return (sub |- t2, sub) - (* let x0 = e0 and x1 = e1 and ... xn = en in e_f *) - (* each xN = eN generate type tN of xN, type kN of eN, substitution S0 and envN with xN: tN *) - (* So I think i can just generate substitution with unify tN and kN *) - (* i want to die after three hours of attempting implemented this 😿😿😿 *) - (* Recursive multiple let definitions type inference by Homka122 😼😼😼 (it took 4 hours) *) - | Pexp_let (NonRecursive, vb, e1) as let_expr -> - let* env, sub0, _ = infer_non_rec_value_bindings helper env vb in - let* t, sub1 = helper (sub0 >- env) e1 in - let* sub = Subst.compose sub1 sub0 in - DebugLog.Expr.non_rec_let let_expr t sub1 sub; - return (t, sub) - (* https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Typing_rule *) - | Pexp_let (Recursive, vbs, e1) -> - let* env, sub0, _ = infer_rec_value_bindings helper env vbs in - let* t, sub1 = helper env e1 in - let* sub = Subst.compose sub0 sub1 in - return (t, sub) - | Pexp_tuple [] | Pexp_tuple [ _ ] -> - fail (SomeError "Tuple expression must contain two or more expressions") - | Pexp_tuple (e0 :: e1 :: exps) -> - let* t0, sub0 = helper env e0 in - let* t1, sub1 = helper env e1 in - let* ts, subs = List.split <$> RList.map exps ~f:(fun e -> helper env e) in - let* sub = Subst.compose_all (sub0 :: sub1 :: subs) in - return (TTuple (t0, t1, ts), sub) - | Pexp_construct (name, expr) -> - let list = - match expr with - | None -> [] - | Some x -> [ x ] - in - let* ty, sub = helper env (Pexp_apply (Pexp_ident name, list)) in - return (ty, sub) - | Pexp_match (e, cases) -> - let* t0, sub0 = helper env e in - let env = sub0 >- env in - let* fv = fresh_var in - RList.fold_left - cases - ~init:(return (fv, sub0)) - ~f:(fun (ty, sub) case -> - let* t_pat, env_pat, names = infer_pattern env case.pc_lhs in - let* sub_un_pat = Subst.unify t_pat t0 in - let* sub1 = Subst.compose sub_un_pat sub in - let env_pat = - List.fold_left - (fun env name -> - let (Scheme (_, t)) = TypeEnv.find_exn env name in - let env = TypeEnv.remove env name in - TypeEnv.extend env name (generalize env t)) - (sub_un_pat >- env_pat) - names - in - let* ty_expr, sub_expr = helper (sub1 >- env_pat) case.pc_rhs in - let* sub_un_exprs = Subst.unify ty_expr ty in - let* sub = Subst.compose_all [ sub_un_exprs; sub_expr; sub1 ] in - DebugLog.Expr.match_expr env_pat ty_expr t_pat sub_expr sub_un_exprs sub; - return (sub |- ty, sub)) - | Pexp_function cases -> - let* fv_match = fresh_var in - let* fv_result = fresh_var in - let* ty, sub = - RList.fold_left - cases - ~init:(return (fv_result, Subst.empty)) - ~f:(fun (ty, sub) case -> - let* t_pat, env_pat, _ = infer_pattern env case.pc_lhs in - let* sub_un_pat = Subst.unify t_pat fv_match in - let* sub1 = Subst.compose sub_un_pat sub in - let* ty_expr, sub_expr = helper (sub1 >- env_pat) case.pc_rhs in - let* sub_un_exprs = Subst.unify ty ty_expr in - let* sub = Subst.compose_all [ sub_un_exprs; sub_expr; sub1 ] in - return (sub |- ty, sub)) - in - return (sub |- (sub |- fv_match) @-> ty, sub) - in - helper -;; - -let infer_structure = - let helper env = function - | Pstr_eval expr -> - let* _, _ = infer_expr env expr in - return (env, []) - | Pstr_value (NonRecursive, vbs) -> - let* env, _, names = infer_non_rec_value_bindings infer_expr env vbs in - return (env, List.rev names) - | Pstr_value (Recursive, vbs) -> - let* env, _, names = infer_rec_value_bindings infer_expr env vbs in - return (env, names) - in - helper -;; - -let infer_program env program = - RList.fold_left - program - ~init:(return (env, [])) - ~f:(fun (env, names) structure -> - let* new_env, new_names = infer_structure env structure in - return (new_env, names @ new_names)) -;; - -let defaultEnv = - List.fold_left - (fun env (names, typ) -> - List.fold_left - (fun env_in name -> TypeEnv.extend env_in name (generalize env_in typ)) - env - names) - TypeEnv.empty - TypeEnv.operators -;; - -let run_expr_inferencer expr = - Result.map fst (run (infer_expr defaultEnv expr) (List.length TypeEnv.operators)) -;; - -let run_structure_inferencer ?(env = defaultEnv) structure = - run (infer_structure env structure) (List.length TypeEnv.operators) -;; - -let run_structure_inferencer_exn ?(env = defaultEnv) structure = - match run (infer_structure env structure) (List.length TypeEnv.operators) with - | Error e -> Error (Format.asprintf "%a" Infer_print.pp_error_my e) - | Ok x -> Ok x -;; - -let run_program_inferencer ?(env = defaultEnv) program = - run (infer_program env program) (List.length TypeEnv.operators) -;; - -let run_program_inferencer_exn ?(env = defaultEnv) program = - match run (infer_program env program) (List.length TypeEnv.operators) with - | Error e -> Error (Format.asprintf "%a" Infer_print.pp_error_my e) - | Ok x -> Ok x -;; diff --git a/OCamlWeakTypeVariables/lib/infer.mli b/OCamlWeakTypeVariables/lib/infer.mli deleted file mode 100644 index 6387a3493..000000000 --- a/OCamlWeakTypeVariables/lib/infer.mli +++ /dev/null @@ -1,84 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Composition of state and error monads *) -module R : sig - type 'a t - - val return : 'a -> 'a t - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val fail : Types.error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - val ( <$> ) : ('a -> 'b) -> 'a t -> 'b t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - - (* Map functions by Homka122 😼😼😼 *) - val map : 'a list -> f:('a -> 'b t) -> 'b list t - val fmap : 'a list -> f:('a -> 'b) -> 'b list t - val map2 : 'a list -> 'b list -> f:('a -> 'b -> 'c t) -> 'c list t - val fmap2 : 'a list -> 'b list -> f:('a -> 'b -> 'c) -> 'c list t - end - - module RMap : sig - val fold_left - : ('a, 'b, 'c) Base.Map.t - -> init:'d t - -> f:('a -> 'b -> 'd -> 'd t) - -> 'd t - end - - val fresh : int t - val run : 'a t -> int -> ('a, Types.error) Result.t -end - -(** Type Environment representing variables and their schemes *) -module TypeEnv : sig - type t - - val operators : (string list * Types.typ) list - val pp : Format.formatter -> t -> unit - val pp_names : string list -> Format.formatter -> t -> unit - val print : ?name:string -> t -> unit -end - -(** Type Environment with built-in variables (functions, constructors, etc...) *) -val defaultEnv : TypeEnv.t - -(** Run inferencer to expression *) -val run_expr_inferencer : Ast.expression -> (Types.typ, Types.error) result - -(** Run inferencer to structure *) -val run_structure_inferencer - : ?env:TypeEnv.t - -> Ast.structure_item - -> (TypeEnv.t * string list, Types.error) result - -val run_structure_inferencer_exn - : ?env:TypeEnv.t - -> Ast.structure_item - -> (TypeEnv.t * string list, string) result - -(** Run inferencer to program *) -val run_program_inferencer - : ?env:TypeEnv.t - -> Ast.structure_item list - -> (TypeEnv.t * string list, Types.error) result - -(** Run inferencer to program, but error is formatted *) -val run_program_inferencer_exn - : ?env:TypeEnv.t - -> Ast.structure_item list - -> (TypeEnv.t * string list, string) result diff --git a/OCamlWeakTypeVariables/lib/infer_print.ml b/OCamlWeakTypeVariables/lib/infer_print.ml deleted file mode 100644 index cd3e692db..000000000 --- a/OCamlWeakTypeVariables/lib/infer_print.ml +++ /dev/null @@ -1,133 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Types - -let pp_base_type_my fmt = function - | BInt -> Format.fprintf fmt "int" - | BBool -> Format.fprintf fmt "bool" - | BUnit -> Format.fprintf fmt "unit" - | BString -> Format.fprintf fmt "string" -;; - -let minimize_variable t = - let map = - let rec helper (min, map) = function - | TVar v when Base.Map.mem map v -> min, map - | TVar v -> min + 1, Base.Map.add_exn map ~key:v ~data:min - | TArrow (l, r) -> - let min, map = helper (min, map) l in - let min, map = helper (min, map) r in - min, map - | TTuple (f, s, xs) -> List.fold_left helper (min, map) (f :: s :: xs) - | TList l -> helper (min, map) l - | TOption o -> helper (min, map) o - | TBase _ -> min, map - in - helper (0, Base.Map.empty (module Base.Int)) t |> snd - in - let rec helper = function - | TVar v -> TVar (Base.Map.find_exn map v) - | TArrow (l, r) -> TArrow (helper l, helper r) - | TTuple (f, s, xs) -> TTuple (helper f, helper s, List.map helper xs) - | TList l -> TList (helper l) - | TOption o -> TOption (helper o) - | TBase b -> TBase b - in - helper t -;; - -let get_number_digits base num = - let rec helper acc num = - if num < base then num :: acc else helper (Int.rem num base :: acc) ((num / base) - 1) - in - let digits = helper [] num in - digits -;; - -let pp_typ_my fmt t = - let t = if Config.vars_min then minimize_variable t else t in - let rec helper fmt = function - | TBase b -> pp_base_type_my fmt b - | TVar v when Config.vars_char && Config.use_cuneiform -> - let alphabet = [ "𒀀"; "𒀐"; "𒀲"; "𒂷"; "𒌧" ] in - let digits = get_number_digits (List.length alphabet) v in - let runes = List.map (fun d -> List.nth alphabet d) digits in - let word = String.concat "" runes in - Format.fprintf fmt "'%s" word - | TVar v when Config.vars_char -> - (* Just represent the number in the base-26 numeral system *) - let digits = get_number_digits 26 v in - let chars = List.map (fun d -> Char.chr (d + 97)) digits in - let word = String.init (List.length chars) (fun i -> List.nth chars i) in - Format.fprintf fmt "'%s" word - | TVar v -> Format.fprintf fmt "'%s" (string_of_int v) - | TArrow ((TArrow (_, _) as l), r) -> - Format.fprintf fmt "(%a) -> %a" helper l helper r - | TArrow (l, r) -> Format.fprintf fmt "%a -> %a" helper l helper r - | TTuple (f, s, xs) -> - Format.fprintf - fmt - "%a" - (Format.pp_print_list - ~pp_sep:(fun _ _ -> Format.printf " * ") - (fun fmt ty -> - match ty with - | TBase _ | TVar _ -> Format.fprintf fmt "%a" helper ty - | _ -> Format.fprintf fmt "(%a)" helper ty)) - (f :: s :: xs) - | TList l -> - (match l with - | TBase _ | TVar _ -> Format.fprintf fmt "%a list" helper l - | _ -> Format.fprintf fmt "(%a) list" helper l) - | TOption o -> - (match o with - | TBase _ | TVar _ -> Format.fprintf fmt "%a option" helper o - | _ -> Format.fprintf fmt "(%a) option" helper o) - in - helper fmt t -;; - -let pp_error_my fmt e = - match e with - | UnificationFailed (f, s) -> - Format.fprintf fmt "Can't unify (%a) and (%a)" pp_typ_my f pp_typ_my s - | Unbound id -> Format.fprintf fmt "Unbound value %s" id - | PatternNameTwice id -> Format.fprintf fmt "Variable %s is bound several time" id - | _ as e -> Format.printf "%a" pp_error e -;; - -let print_typ ?(name = "typ") t = Format.printf "%s: %a\n" name pp_typ_my t - -let%expect_test "just type" = - Format.printf "%a" pp_typ_my (TVar 4); - [%expect {| '𒀀 |}] -;; - -let%expect_test "just arrow type" = - Format.printf "%a" pp_typ_my (TArrow (TVar 4, TArrow (TVar 3, TVar 4))); - [%expect {| '𒀀 -> '𒀐 -> '𒀀 |}] -;; - -let%expect_test "super arrow type" = - Format.printf "%a" pp_typ_my (TArrow (TVar 2, TTuple (TVar 1, TVar 2, [ TVar 5 ]))); - [%expect {| '𒀀 -> '𒀐 * '𒀀 * '𒀲 |}] -;; - -let%expect_test "ultra hard arrow type" = - Format.printf - "%a" - pp_typ_my - (TArrow (TVar 2, TTuple (TVar 1, TVar 2, [ TVar 5; TList (TVar 2) ]))); - [%expect {| '𒀀 -> '𒀐 * '𒀀 * '𒀲 * ('𒀀 list) |}] -;; - -let%expect_test "option ." = - Format.printf "%a" pp_typ_my (TOption (TVar 2)); - [%expect {| '𒀀 option |}] -;; diff --git a/OCamlWeakTypeVariables/lib/infer_print.mli b/OCamlWeakTypeVariables/lib/infer_print.mli deleted file mode 100644 index caab162bf..000000000 --- a/OCamlWeakTypeVariables/lib/infer_print.mli +++ /dev/null @@ -1,19 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -(** Pretty printer for base type *) -val pp_base_type_my : Format.formatter -> Types.base_type -> unit - -(** Pretty printer for type *) -val pp_typ_my : Format.formatter -> Types.typ -> unit - -(** Pretty printf for inference errors *) -val pp_error_my : Format.formatter -> Types.error -> unit - -(** Print type *) -val print_typ : ?name:string -> Types.typ -> unit diff --git a/OCamlWeakTypeVariables/lib/interpreter.ml b/OCamlWeakTypeVariables/lib/interpreter.ml deleted file mode 100644 index 155c99379..000000000 --- a/OCamlWeakTypeVariables/lib/interpreter.ml +++ /dev/null @@ -1,407 +0,0 @@ -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - | Type_error - | Pattern_error of pattern - | Eval_expr_error of expression - | No_variable of string - | Match_error - -module Res : sig - type 'a t - - val fail : error -> 'a t - val return : 'a -> 'a t - val run : 'a t -> ('a, error) result - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t - val ( <|> ) : 'a t -> 'a t -> 'a t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t -end = struct - open Base - - type 'a t = ('a, error) Result.t - - let fail = Result.fail - let return = Result.return - let run m = m - - let ( >>= ) (monad : 'a t) (f : 'a -> 'b t) : 'b t = - match monad with - | Ok result -> f result - | Error x -> fail x - ;; - - let ( >>| ) (monad : 'a t) (f : 'a -> 'b) : 'b t = - match monad with - | Ok result -> return (f result) - | Error x -> fail x - ;; - - let ( <|> ) (first : 'a t) (second : 'a t) : 'a t = - match first with - | Ok result -> return result - | Error _ -> - (match second with - | Ok result -> return result - | Error e -> fail e) - ;; - - let ( let* ) = ( >>= ) - let ( let+ ) = ( >>| ) -end - -module rec Value : sig - type value = - | Val_integer of int - | Val_string of string - | Val_boolean of bool - | Val_fun of pattern * expression * EvalEnv.t - | Val_rec_fun of id * value - | Val_function of case list * EvalEnv.t - | Val_tuple of value list - | Val_construct of id * value option - | Val_builtin of string - - val pp : Format.formatter -> value -> unit -end = struct - type value = - | Val_integer of int - | Val_string of string - | Val_boolean of bool - | Val_fun of pattern * expression * EvalEnv.t - | Val_rec_fun of id * value - | Val_function of case list * EvalEnv.t - | Val_tuple of value list - | Val_construct of id * value option - | Val_builtin of string - - let rec pp ppf = - let open Stdlib.Format in - function - | Val_integer int -> fprintf ppf "%i" int - | Val_boolean bool -> fprintf ppf "'%b'" bool - | Val_string str -> fprintf ppf "%S" str - | Val_tuple vls -> - fprintf ppf "(%a)" (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp) vls - | Val_fun _ | Val_rec_fun _ | Val_builtin _ -> fprintf ppf "" - | Val_function _ -> fprintf ppf "" - | Val_construct (tag, None) -> fprintf ppf "%s" tag - | Val_construct ("Some", Some value) -> fprintf ppf "Some %a" pp value - | Val_construct (tag, Some v) -> fprintf ppf "[%s] %a" tag pp v - ;; -end - -and EvalEnv : sig - type t - - val empty : t - val extend : t -> string -> Value.value -> t - val compose : t -> t -> t - val find_exn : t -> string -> Value.value Res.t - val find_exn1 : t -> string -> Value.value -end = struct - open Base - - type t = (id, Value.value, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - let extend env key value = Map.update env key ~f:(fun _ -> value) - - let compose env1 env2 = - Map.fold env2 ~f:(fun ~key ~data env_acc -> extend env_acc key data) ~init:env1 - ;; - - let find_exn env key = - match Map.find env key with - | Some value -> Res.return value - | None -> Res.fail (No_variable key) - ;; - - let find_exn1 env key = - let val' = Map.find_exn env key in - val' - ;; -end - -let pp_error ppf : error -> _ = function - | Type_error -> Format.fprintf ppf "Type error" - | Pattern_error pat -> - Format.fprintf ppf "Error while interpret pattern (%a)" pp_pattern pat - | Eval_expr_error expr -> - Format.printf "Error while interpret expression (%a)" pp_expression expr - | No_variable s -> Format.fprintf ppf "No variable with name %s" s - | Match_error -> Format.fprintf ppf "Match failure" -;; - -let%expect_test "pp value" = - Format.printf - "Value: %a" - Value.pp - (Val_tuple - [ Val_string "Homka" - ; Val_integer 122 - ; Val_boolean true - ; Val_fun (Ppat_var "x", Pexp_ident "homka", EvalEnv.empty) - ; Val_rec_fun ("damir", Val_fun (Ppat_var "x", Pexp_ident "homka", EvalEnv.empty)) - ; Val_construct ("Some", Some (Val_integer 52)) - ; Val_construct ("[]", None) - ; Val_builtin "print_int" - ]); - [%expect {| Value: ("Homka", 122, 'true', , , Some 52, [], ) |}] -;; - -let%expect_test "pp error" = - Format.printf - "Errors:\n %a\n %a\n %a\n %a\n %a\n" - pp_error - Type_error - pp_error - (Pattern_error Ppat_any) - pp_error - (Eval_expr_error (Pexp_ident "damir")) - pp_error - (No_variable "homka") - pp_error - Match_error; - [%expect - {| - Errors: - Type error - Error while interpret pattern (Ppat_any) - Error while interpret expression (( - Pexp_ident "damir")) - No variable with name homka - Match failure |}] -;; - -module Inter = struct - open Value - open Res - open EvalEnv - - let rec match_pattern env = function - | Ppat_any, _ -> return env - | Ppat_var name, value -> return (extend env name value) - | Ppat_constant _, _ -> return env - | Ppat_tuple pts, Val_tuple values -> - List.fold_left2 - (fun env pat value -> - let* env = env in - match_pattern env (pat, value)) - (return env) - pts - values - | Ppat_construct (pat_name, None), Val_construct (val_name, None) - when pat_name = val_name -> return env - | Ppat_construct (pat_name, Some constr), Val_construct (val_name, Some value) -> - if pat_name <> val_name then fail Type_error else match_pattern env (constr, value) - | o, _ -> fail (Pattern_error o) - ;; - - let eval_const = function - | Pconst_int c -> return (Val_integer c) - | Pconst_string c -> return (Val_string c) - | Pconst_boolean c -> return (Val_boolean c) - ;; - - let eval_non_rec_vbs eval_expr env vbs = - let+ homka_env = - Base.List.fold_left vbs ~init:(return env) ~f:(fun env vb -> - let* env = env in - let* homka_expr = eval_expr env vb.pvb_expr in - match_pattern env (vb.pvb_pat, homka_expr)) - in - homka_env - ;; - - let eval_rec_vbs eval_expr env vbs = - let eval_vb env vb = - let* env = env in - let* homka_expr = eval_expr env vb.pvb_expr in - let* homka_expr = - match vb.pvb_pat with - | Ppat_var name -> - (match homka_expr with - | Val_fun _ as v -> return (Val_rec_fun (name, v)) - | v -> return v) - | _ -> fail Type_error - in - match_pattern env (vb.pvb_pat, homka_expr) - in - let* homka_env = Base.List.fold_left vbs ~init:(return env) ~f:eval_vb in - let* homka_env = Base.List.fold_left vbs ~init:(return homka_env) ~f:eval_vb in - return homka_env - ;; - - let eval_cases eval_expr env cases init_value = - let rec helper = function - | [] -> fail Match_error - | case :: tl -> - (let* env = match_pattern env (case.pc_lhs, init_value) in - let* res = eval_expr env case.pc_rhs in - return res) - <|> helper tl - in - helper cases - ;; - - let binary_operators_int_arith = [ "+", ( + ); "-", ( - ); "*", ( * ); "/", ( / ) ] - - let binary_operators_compare = - [ "<=", ( <= ); "<", ( < ); ">", ( > ); ">=", ( >= ); "=", ( = ); "<>", ( <> ) ] - ;; - - let is_binary_op_int name = - List.exists (fun (list_op, _) -> name = list_op) binary_operators_int_arith - ;; - - let is_binary_op_compare name = - List.exists (fun (list_op, _) -> name = list_op) binary_operators_compare - ;; - - let eval_binary_op_int eval_expr env op_name e1 e2 = - let _, op = - List.find (fun (list_op, _) -> list_op = op_name) binary_operators_int_arith - in - let* first = eval_expr env e1 in - let* second = eval_expr env e2 in - match first, second with - | Val_integer f, Val_integer s -> return (Val_integer (op f s)) - | _ -> fail Type_error - ;; - - let eval_binary_op_compare eval_expr env op_name e1 e2 = - let get_op () = - snd (List.find (fun (list_op, _) -> list_op = op_name) binary_operators_compare) - in - let* first = eval_expr env e1 in - let* second = eval_expr env e2 in - match first, second with - | Val_integer f, Val_integer s -> return (Val_boolean ((get_op ()) f s)) - | Val_boolean f, Val_boolean s -> return (Val_boolean ((get_op ()) f s)) - | Val_string f, Val_string s -> return (Val_boolean ((get_op ()) f s)) - | _ -> fail Type_error - ;; - - let rec eval_expr env = function - | Pexp_ident id -> find_exn env id - | Pexp_constant const -> eval_const const - | Pexp_apply (Pexp_ident op_name, [ e1; e2 ]) when is_binary_op_int op_name -> - eval_binary_op_int eval_expr env op_name e1 e2 - | Pexp_apply (Pexp_ident op_name, [ e1; e2 ]) when is_binary_op_compare op_name -> - eval_binary_op_compare eval_expr env op_name e1 e2 - | Pexp_apply (e0, es) -> - let rec helper value0 es = - match es with - | e1 :: es -> - let* value1 = eval_expr env e1 in - let* result = - match value0 with - | Val_fun (fun_pat, fun_expr, fun_env) -> - let* fun_env = match_pattern fun_env (fun_pat, value1) in - let* res = eval_expr fun_env fun_expr in - return res - | Val_rec_fun (id, Val_fun (fun_pat, fun_expr, fun_env)) -> - let fun_env = extend fun_env id value0 in - let* fun_env = match_pattern fun_env (fun_pat, value1) in - let* res = eval_expr fun_env fun_expr in - return res - | Val_function (cases, fun_env) -> eval_cases eval_expr fun_env cases value1 - | Val_builtin "print_int" -> - (match value1 with - | Val_integer i -> - (* There is must no be newline, but without that manytests work poorly *) - Format.printf "%d\n" i; - return (Val_construct ("()", None)) - | _ -> fail Type_error) - | _ -> fail Type_error - in - helper result es - | [] -> return value0 - in - let* value0 = eval_expr env e0 in - helper value0 es - | Pexp_let (NonRecursive, vbs, expr) -> - let* homka_env = eval_non_rec_vbs eval_expr env vbs in - eval_expr homka_env expr - | Pexp_let (Recursive, vbs, expr) -> - let* homka_env = eval_rec_vbs eval_expr env vbs in - eval_expr homka_env expr - | Pexp_ifthenelse (e0, e1, None) -> - let* value_e0 = eval_expr env e0 in - (match value_e0 with - | Val_boolean true -> - let* value_e1 = eval_expr env e1 in - (* Without else branch return type must be unit *) - (match value_e1 with - | Val_construct ("()", None) as v -> return v - | _ -> fail Type_error) - | Val_boolean false -> return (Val_construct ("()", None)) - | _ -> fail Type_error) - | Pexp_ifthenelse (e0, e1, Some e2) -> - let* value_e0 = eval_expr env e0 in - (match value_e0 with - | Val_boolean true -> eval_expr env e1 - | Val_boolean false -> eval_expr env e2 - | _ -> fail Type_error) - | Pexp_fun (pat, expr) -> Val_fun (pat, expr, env) |> return - | Pexp_tuple exprs -> - let rec helper (acc : value list) = function - | e0 :: es -> - let* value = eval_expr env e0 in - helper (value :: acc) es - | [] -> return acc - in - let+ values = helper [] exprs in - Val_tuple (List.rev values) - | Pexp_construct (name, None) -> return (Val_construct (name, None)) - | Pexp_construct (name, Some expr) -> - let+ value = eval_expr env expr in - Val_construct (name, Some value) - | Pexp_constraint (expr, _) -> eval_expr env expr - | Pexp_match (expr, cases) -> - let* value_match = eval_expr env expr in - eval_cases eval_expr env cases value_match - | Pexp_function cases -> return (Val_function (cases, env)) - ;; - - let eval_structure env = function - | Pstr_eval expr -> - let* _ = eval_expr env expr in - return env - | Pstr_value (NonRecursive, vbs) -> eval_non_rec_vbs eval_expr env vbs - | Pstr_value (Recursive, vbs) -> eval_rec_vbs eval_expr env vbs - ;; - - let eval_program env program = - let rec helper env = function - | hd :: tl -> - let* env = eval_structure env hd in - helper env tl - | [] -> return env - in - let* res = helper env program in - return res - ;; -end - -let initial_env = - let empty = EvalEnv.empty in - EvalEnv.extend empty "print_int" (Val_builtin "print_int") -;; - -let interpret = Inter.eval_program -let run_interpret = interpret initial_env - -let run_interpret_exn str = - let res = interpret initial_env str |> Res.run in - match res with - | Ok v -> Ok v - | Error e -> Error (Format.asprintf "%a" pp_error e) -;; diff --git a/OCamlWeakTypeVariables/lib/interpreter.mli b/OCamlWeakTypeVariables/lib/interpreter.mli deleted file mode 100644 index 1f3228ec4..000000000 --- a/OCamlWeakTypeVariables/lib/interpreter.mli +++ /dev/null @@ -1,52 +0,0 @@ -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - | Type_error - | Pattern_error of Ast.pattern - | Eval_expr_error of Ast.expression - | No_variable of string - | Match_error - -module Res : sig - type 'a t - - val fail : error -> 'a t - val return : 'a -> 'a t - val run : 'a t -> ('a, error) result - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t - val ( <|> ) : 'a t -> 'a t -> 'a t - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t -end - -module rec Value : sig - type value = - | Val_integer of int - | Val_string of string - | Val_boolean of bool - | Val_fun of Ast.pattern * Ast.expression * EvalEnv.t - | Val_rec_fun of string * value - | Val_function of Ast.case list * EvalEnv.t - | Val_tuple of value list - | Val_construct of string * value option - | Val_builtin of string - - val pp : Format.formatter -> value -> unit -end - -and EvalEnv : sig - type t - - val empty : t - val extend : t -> string -> Value.value -> t - val compose : t -> t -> t - val find_exn : t -> string -> Value.value Res.t - val find_exn1 : t -> string -> Value.value -end - -val pp_error : Format.formatter -> error -> unit -val run_interpret : Ast.structure_item list -> EvalEnv.t Res.t -val run_interpret_exn : Ast.structure_item list -> (EvalEnv.t, string) result diff --git a/OCamlWeakTypeVariables/lib/parser.ml b/OCamlWeakTypeVariables/lib/parser.ml deleted file mode 100644 index f70ecc00d..000000000 --- a/OCamlWeakTypeVariables/lib/parser.ml +++ /dev/null @@ -1,392 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Ast -open Angstrom - -let is_whitespace = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -let is_keyword = function - | "let" - | "rec" - | "and" - | "if" - | "then" - | "else" - | "true" - | "false" - | "match" - | "with" - | "in" - | "fun" - | "type" -> true - | _ -> false -;; - -let ws = take_while is_whitespace -let wss t = ws *> t <* ws -let token s = ws *> string s <* ws -let word s = ws *> string s <* take_while1 is_whitespace -let parens t = token "(" *> t <* token ")" - -let p_const_int = - let is_digit = function - | '0' .. '9' -> true - | _ -> false - in - let* sign = choice [ token "-"; token "+"; token "" ] in - let* first_digit = satisfy is_digit in - let+ digits = - take_while (function - | '0' .. '9' | '_' -> true - | _ -> false) - in - Pconst_int (int_of_string (sign ^ Char.escaped first_digit ^ digits)) -;; - -let p_const_string = - let+ s = - token "\"" - *> take_while (function - | '"' -> false - | _ -> true) - <* token "\"" - in - Pconst_string s -;; - -let p_const_bool = - let+ bool_str = choice [ token "true"; token "false" ] in - Pconst_boolean (bool_of_string bool_str) -;; - -let p_const = - choice - ~failure_msg:"Error while parsing literal" - [ p_const_int; p_const_string; p_const_bool ] -;; - -let pexpr_const = p_const >>| fun x -> Pexp_constant x - -let capitalized_ident = - let* first = - ws - *> satisfy (function - | 'A' .. 'Z' -> true - | _ -> false) - in - let* rest = - take_while (function - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '\'' -> true - | _ -> false) - <* ws - in - let word = Char.escaped first ^ rest in - return word -;; - -let lowercase_ident = - let* first = - ws - *> satisfy (function - | 'a' .. 'z' | '_' -> true - | _ -> false) - in - let* rest = - take_while (function - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '\'' -> true - | _ -> false) - <* ws - in - let word = Char.escaped first ^ rest in - if is_keyword word then fail "Keyword identificators are not allowed." else return word -;; - -(* TODO: readable error message *) -let p_id : id t = - let* var = lowercase_ident in - if var = "_" then fail {| Wildcard "_" not expected |} else return var -;; - -let pexp_ident = p_id >>| fun i -> Pexp_ident i - -let chain_left parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* first = parse in - go (f acc first)) - <|> return acc - in - parse >>= go -;; - -let chain_right parse parse_fun = - let rec go acc = - (let* f = parse_fun in - let* first = parse in - let* second = go first in - return (f acc second)) - <|> return acc - in - parse >>= go -;; - -let pexp_ident_constr id = Pexp_ident id -let pexp_apply_constr expr exprs = Pexp_apply (expr, exprs) - -let p_binop p expr = - chain_left - expr - (let+ ident = p >>| pexp_ident_constr in - fun x y -> pexp_apply_constr ident [ x; y ]) -;; - -let p_cons expr = - (* let+ list = sep_by (token "::") expr in - List.fold_right - (fun acc e -> Pexp_construct ("::", Some (Pexp_tuple [ e; acc ]))) - list - (Pexp_construct ("[]", None)) - ;; *) - chain_right - expr - (token "::" *> return (fun x y -> Pexp_construct ("::", Some (Pexp_tuple [ x; y ])))) -;; - -let p_tuple expr = - let* first = expr <* token "," in - let+ es = sep_by (token ",") expr in - Pexp_tuple (first :: es) -;; - -let p_pattern = - let pat_const = p_const >>| fun c -> Ppat_constant c in - let pat_var = - lowercase_ident >>| fun var -> if var = "_" then Ppat_any else Ppat_var var - in - fix (fun pattern : pattern t -> - let pat_const = choice [ parens pattern; pat_const; pat_var ] in - let pat_construct = - (let* name = capitalized_ident in - let+ body = option None (pattern >>| fun p -> Some p) in - Ppat_construct (name, body)) - <|> pat_const - in - let pat_list = - (let* list = token "[" *> sep_by (token ";") pat_construct <* token "]" in - return - (List.fold_right - (fun x y -> Ppat_construct ("::", Some (Ppat_tuple [ x; y ]))) - list - (Ppat_construct ("[]", None)))) - <|> pat_construct - in - let pat_cons = - chain_right - pat_list - (token "::" - >>= fun c -> return @@ fun x y -> Ppat_construct (c, Some (Ppat_tuple [ x; y ])) - ) - <|> pat_list - in - let pat_tuple = - lift2 (fun l ls -> Ppat_tuple (l :: ls)) pat_cons (many1 (token "," *> pat_cons)) - <|> pat_cons - in - let pat_unit = word "()" >>| (fun _ -> Ppat_construct ("()", None)) <|> pat_tuple in - pat_unit) -;; - -let p_fun expr = - let* _ = token "fun" in - let* ps = many1 p_pattern in - let* _ = token "->" in - let+ e = expr in - List.fold_right (fun f p -> Pexp_fun (f, p)) ps e -;; - -let p_branch (expr : expression t) = - let* first = token "if" *> expr in - let* second = token "then" *> expr in - let* else_token = option None (token "else" >>| fun _ -> Some 1) in - match else_token with - | None -> return (Pexp_ifthenelse (first, second, None)) - | Some _ -> - let+ third = expr >>| fun e -> Some e in - Pexp_ifthenelse (first, second, third) -;; - -let p_apply expr = - let* first = wss expr in - let* single = wss (peek_string 1) in - match single with - | "+" | "-" -> fail "" - | _ -> - let+ second = many1 (wss expr) in - Pexp_apply (first, second) -;; - -let p_rec_flag = word "rec" >>| (fun _ -> Recursive) <|> return NonRecursive - -let p_value_binding expr = - let* pattern = p_pattern in - let* xs = many p_pattern in - let+ expr = token "=" *> expr in - { pvb_pat = pattern - ; pvb_expr = - (match xs with - | [] -> expr - | _ -> List.fold_right (fun f p -> Pexp_fun (f, p)) xs expr) - } -;; - -let p_let_in expr = - let* rec_flag = token "let" *> p_rec_flag in - let* vb = p_value_binding expr in - let* value_bindings = many (token "and" *> p_value_binding expr) in - let+ expr = token "in" *> expr in - Pexp_let (rec_flag, vb :: value_bindings, expr) -;; - -let token_or xs : string t = - let token_functions = List.map token xs in - match token_functions with - | h :: t -> List.fold_right ( <|> ) t h - | _ -> fail "token_or require two or more tokens" -;; - -module TypeParser : sig - val p_typ : Types.typ t -end = struct - open Types - - let p_typ_base = - choice - [ (token "int" >>| fun _ -> TBase BInt) - ; (token "string" >>| fun _ -> TBase BString) - ; (token "unit" >>| fun _ -> TBase BUnit) - ; (token "bool" >>| fun _ -> TBase BBool) - ] - ;; - - let p_typ_tuple typ = - let* f = typ in - let* s = token "*" *> typ in - let+ rest = many (token "*" *> typ) in - TTuple (f, s, rest) - ;; - - let p_typ_list typ = typ <* token "list" >>| fun t -> TList t - let p_typ_option typ = typ <* token "option" >>| fun t -> TOption t - - let rec p_typ_arrow typ = - let* f = typ in - let+ s = token "->" *> (p_typ_arrow typ <|> typ) in - TArrow (f, s) - ;; - - let p_typ = - fix (fun typ_all -> - let typ = p_typ_base <|> parens typ_all in - let typ = p_typ_list typ <|> p_typ_option typ <|> typ in - let typ = p_typ_tuple typ <|> typ in - let typ = p_typ_arrow typ <|> typ in - typ) - ;; -end - -let pexpr_constraint expr = - let* expr = token "(" *> expr in - let+ ty = token ":" *> TypeParser.p_typ <* token ")" in - Pexp_constraint (expr, ty) -;; - -let p_construct_unit = token "()" *> return (Pexp_construct ("()", None)) - -let p_construct expr = - (let* name = capitalized_ident in - let+ body = option None (expr >>| fun x -> Some x) in - Pexp_construct (name, body)) - <|> p_construct_unit -;; - -let p_pattern_matching expr = - let case = - let* p = p_pattern in - let* e = token "->" *> expr in - return { pc_lhs = p; pc_rhs = e } - in - let* first = (token "|" <|> ws) *> case in - (* Format.printf "%a\n" pp_case first; *) - let+ cases = many (token "|" *> case) in - first :: cases -;; - -let p_match expr = - let* e = word "match" *> expr in - let+ cases = word "with" *> p_pattern_matching expr in - Pexp_match (e, cases) -;; - -let p_function expr = - let+ cases = word "function" *> p_pattern_matching expr in - Pexp_function cases -;; - -let p_list expr = - let* list = token "[" *> sep_by (token ";") expr <* token "]" in - return - (List.fold_right - (fun x y -> Pexp_construct ("::", Some (Pexp_tuple [ x; y ]))) - list - (Pexp_construct ("[]", None))) -;; - -let p_expr = - fix (fun expr -> - let expr_const = - choice - [ parens expr; pexpr_const; pexpr_constraint expr; pexp_ident; p_branch expr ] - in - let expr_construct = p_construct expr <|> expr_const in - let expr_fun = p_fun expr <|> expr_construct in - let expr_list = p_list expr <|> expr_fun in - let expr_apply = p_apply expr_list <|> expr_list in - let expr_mul_div = p_binop (token "*" <|> token "/") expr_apply <|> expr_apply in - let expr_add_sub = p_binop (token "+" <|> token "-") expr_mul_div <|> expr_mul_div in - let expr_comparison = - p_binop (token_or [ "<"; "<="; ">"; ">="; "="; "<>" ]) expr_add_sub <|> expr_add_sub - in - let expr_cons = p_cons expr_comparison <|> expr_comparison in - let expr_let_in = p_let_in expr <|> expr_cons in - let expr_function = p_function expr <|> expr_let_in in - let expr_match = p_match expr <|> expr_function in - let expr_tuple = p_tuple expr_match <|> expr_match in - expr_tuple) -;; - -let p_str_value expr = - let* rec_flag = token "let" *> p_rec_flag in - let* vb = p_value_binding expr in - let+ value_bindings = many (token "and" *> p_value_binding expr) in - Pstr_value (rec_flag, vb :: value_bindings) -;; - -let p_structure = - let str_value = p_str_value p_expr in - let str_eval = p_expr >>| (fun ex -> Pstr_eval ex) <|> str_value in - str_eval -;; - -let parse_expr str = parse_string ~consume:All p_expr str -let parse_structure str = parse_string ~consume:All p_structure str -let parse = parse_structure -let parse_program str = parse_string ~consume:All (many p_structure <* end_of_input) str diff --git a/OCamlWeakTypeVariables/lib/parser.mli b/OCamlWeakTypeVariables/lib/parser.mli deleted file mode 100644 index 7e94aba9e..000000000 --- a/OCamlWeakTypeVariables/lib/parser.mli +++ /dev/null @@ -1,13 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -open Ast - -val parse_expr : string -> (expression, string) result -val parse : string -> (structure_item, string) result -val parse_program : string -> (program, string) result diff --git a/OCamlWeakTypeVariables/lib/types.ml b/OCamlWeakTypeVariables/lib/types.ml deleted file mode 100644 index 29254dc28..000000000 --- a/OCamlWeakTypeVariables/lib/types.ml +++ /dev/null @@ -1,41 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -type type_var = int [@@deriving show { with_path = false }] - -type base_type = - | BInt - | BBool - | BUnit - | BString -[@@deriving show { with_path = false }] - -type typ = - | TBase of base_type - | TVar of type_var - | TArrow of typ * typ - | TTuple of typ * typ * typ list - | TList of typ - | TOption of typ -[@@deriving show { with_path = false }] - -let ( @-> ) a b = TArrow (a, b) - -module TVarSet = Stdlib.Set.Make (Int) -module VarSet = Stdlib.Set.Make (String) - -type error = - | OccursCheckFailed of type_var * typ - | UnificationFailed of typ * typ - | Unbound of string - | PatternNameTwice of string - | UnknownType of string - | SomeError of string -[@@deriving show { with_path = false }] - -type scheme = Scheme of TVarSet.t * typ diff --git a/OCamlWeakTypeVariables/lib/types.mli b/OCamlWeakTypeVariables/lib/types.mli deleted file mode 100644 index 7c026ff57..000000000 --- a/OCamlWeakTypeVariables/lib/types.mli +++ /dev/null @@ -1,60 +0,0 @@ -[@@@ocaml.text "/*"] - -(** Copyright 2024-2025, Damir Yunusov and Ilhom Kombaev *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -[@@@ocaml.text "/*"] - -type type_var = int - -(** `base_type` representing base type. *) -type base_type = - | BInt (** Int base type *) - | BBool (** Bool base type *) - | BUnit (** Unit base type *) - | BString (** String base type *) - -(** `typ` representing type of expression or pattern *) -type typ = - | TBase of base_type - | TVar of type_var - | TArrow of typ * typ - | TTuple of typ * typ * typ list - | TList of typ - | TOption of typ - -(** Infix operator for creation `TArrow` type *) -val ( @-> ) : typ -> typ -> typ - -(** Set for keeping variable types *) -module TVarSet : sig - include module type of Set.Make (Int) -end - -(** Set for keeping variable names in environment *) -module VarSet : sig - include module type of Set.Make (String) -end - -(** Errors due inference of expression or pattern *) -type error = - | OccursCheckFailed of type_var * typ - (** Type variable contains in type. It's error because infinity types appear *) - | UnificationFailed of typ * typ (** Unification process end with error. *) - | Unbound of string (** Some variable x don't containing in environment *) - | PatternNameTwice of string (** Some variable x appears twice in one pattern *) - | UnknownType of string (** Unknown type given in expression constraint *) - | SomeError of string (** Error with custom message *) - -val pp_type_var : Format.formatter -> type_var -> unit -val show_type_var : type_var -> string -val pp_base_type : Format.formatter -> base_type -> unit -val show_base_type : base_type -> string -val pp_typ : Format.formatter -> typ -> unit -val show_typ : typ -> string -val pp_error : Format.formatter -> error -> unit -val show_error : error -> string - -(** Scheme it's type with set of free variables in that type *) -type scheme = Scheme of TVarSet.t * typ diff --git a/OCamlWeakTypeVariables/myocaml.code-workspace b/OCamlWeakTypeVariables/myocaml.code-workspace deleted file mode 100644 index 0451a4d17..000000000 --- a/OCamlWeakTypeVariables/myocaml.code-workspace +++ /dev/null @@ -1,18 +0,0 @@ -{ - "folders": [ - { - "path": "./" - }, - { - "path": "../Lambda", - "name": "Lambda" - }, - { - "path": "../", - "name": "fp2024" - } - ], - "settings": { - "editor.formatOnSave": true - } -} diff --git a/OCamlWeakTypeVariables/tests/dune b/OCamlWeakTypeVariables/tests/dune deleted file mode 100644 index 07a30bab1..000000000 --- a/OCamlWeakTypeVariables/tests/dune +++ /dev/null @@ -1,30 +0,0 @@ -(cram - (applies_to *) - (deps - ../bin/REPL.exe - manytests/typed/001fac.ml - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/006partial.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/005.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/016tuples_mismatch.ml - manytests/do_not_type/097fun_vs_list.ml - manytests/do_not_type/097fun_vs_unit.ml - manytests/do_not_type/098rec_int.ml - manytests/do_not_type/099.ml)) diff --git a/OCamlWeakTypeVariables/tests/manytests b/OCamlWeakTypeVariables/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/OCamlWeakTypeVariables/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/OCamlWeakTypeVariables/tests/test_infer.t b/OCamlWeakTypeVariables/tests/test_infer.t deleted file mode 100644 index 469a30863..000000000 --- a/OCamlWeakTypeVariables/tests/test_infer.t +++ /dev/null @@ -1,63 +0,0 @@ - $ ../bin/REPL.exe -dinference < let fac self n = if n<=1 then 1 else n * self (n-1) - val fac : (int -> int) -> int -> int - - - $ ../bin/REPL.exe -dinference < let f x y z homka damir chtooo = x y (homka + damir) chtooo - val f : ('𒀀 -> int -> '𒀐 -> '𒀲) -> '𒀀 -> '𒂷 -> int -> int -> '𒀐 -> '𒀲 - - - $ ../bin/REPL.exe -dinference < let fac self n = if true then 1 else n * self (n - 1) - val fac : (int -> int) -> int -> int - - - $ ../bin/REPL.exe -dinference < let rec homka n = damir 4 - > and damir n = homka 5 - val damir : int -> '𒀀 - val homka : int -> '𒀀 - - - $ ../bin/REPL.exe -dinference < let rec homka n = damir 4 - > and damir n = homka 5 in homka - - : int -> '𒀀 - - $ ../bin/REPL.exe -dinference < let rec x = y + 3 and y = true - Error: (SomeError - "This kind of expression is not allowed as right-hand side of 'let rec'") - - $ ../bin/REPL.exe -dinference < let homka = fun x y -> let z = x y in z + 2 - val homka : ('𒀀 -> int) -> '𒀀 -> int - - - $ ../bin/REPL.exe -dinference < let foo b = if b then fun foo -> foo + 2 else fun foo -> foo * 10 - > and homka = 122 - > and fac self n = if true then 1 else n * self (n - 1) - val foo : bool -> int -> int - val homka : int - val fac : (int -> int) -> int -> int - - - $ ../bin/REPL.exe -dinference < let homka x = let y = x + 2 and z = x in z - val homka : int -> int - - $ ../bin/REPL.exe -dinference < let id x = x in - > let homka = Some id in - > match homka with - > | Some f -> f 42, f "42" - - : int * string - - $ ../bin/REPL.exe -dinference < fun id -> - > let homka = Some id in - > match homka with - > | Some f -> f 42, f "42" - Can't unify (int) and (string) diff --git a/OCamlWeakTypeVariables/tests/test_infer_errors.t b/OCamlWeakTypeVariables/tests/test_infer_errors.t deleted file mode 100644 index 7e12df8de..000000000 --- a/OCamlWeakTypeVariables/tests/test_infer_errors.t +++ /dev/null @@ -1,3 +0,0 @@ - $ ../bin/REPL.exe -dinference < let x = 2 and x = 3 - Error: Variable x is bound several time diff --git a/OCamlWeakTypeVariables/tests/test_manytests_do_not_typed.t b/OCamlWeakTypeVariables/tests/test_manytests_do_not_typed.t deleted file mode 100644 index 827775b1f..000000000 --- a/OCamlWeakTypeVariables/tests/test_manytests_do_not_typed.t +++ /dev/null @@ -1,33 +0,0 @@ - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/001.ml - Error: Unbound value fac - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/002if.ml - Error: Can't unify (int) and (bool) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/003occurs.ml - Error: (OccursCheckFailed (9, (TArrow ((TVar 9), (TVar 12))))) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/004let_poly.ml - Error: Can't unify (int) and (bool) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/005.ml - Error: Can't unify (string) and (int) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/015tuples.ml - Error: (SomeError "Only variables are allowed as left-hand side of `let rec`") - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/016tuples_mismatch.ml - Error: Can't unify ('𒀀 * '𒀐) and (int * int * int) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/097fun_vs_list.ml - Error: Can't unify ('𒀀 list) and ('𒀀 -> '𒀀) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/097fun_vs_unit.ml - Error: Can't unify (unit) and ('𒀀 -> '𒀀) - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/098rec_int.ml - Error: (SomeError - "This kind of expression is not allowed as right-hand side of 'let rec'") - - $ ../bin/REPL.exe -dinferprogram < manytests/do_not_type/099.ml - Error: (SomeError "Only variables are allowed as left-hand side of `let rec`") diff --git a/OCamlWeakTypeVariables/tests/test_manytests_typed.t b/OCamlWeakTypeVariables/tests/test_manytests_typed.t deleted file mode 100644 index 06fd8d220..000000000 --- a/OCamlWeakTypeVariables/tests/test_manytests_typed.t +++ /dev/null @@ -1,101 +0,0 @@ - $ ../bin/REPL.exe -dinferprogram < manytests/typed/001fac.ml - val fac : int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/002fac.ml - val fac_cps : int -> (int -> '𒀀) -> '𒀀 - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/003fib.ml - val fib_acc : int -> int -> int -> int - val fib : int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/004manyargs.ml - val wrap : '𒀀 -> '𒀀 - val test3 : int -> int -> int -> int - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/005fix.ml - val fix : (('𒀀 -> '𒀐) -> '𒀀 -> '𒀐) -> '𒀀 -> '𒀐 - val fac : (int -> int) -> int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/006partial2.ml - val foo : int -> int -> int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/006partial3.ml - val foo : int -> int -> int -> unit - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/006partial.ml - val foo : int -> int - val foo : int -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/007order.ml - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main : unit - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/008ascription.ml - val addi : ('𒀀 -> bool -> int) -> ('𒀀 -> bool) -> '𒀀 -> int - val main : int - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/009let_poly.ml - val temp : int * bool - - $ cat manytests/typed/010sukharev.ml | ../bin/REPL.exe -dinferprogram - val _1 : int -> int -> int * '𒀀 -> bool - val _2 : int - val _3 : (int * string) option - val _4 : int -> '𒀀 - val _5 : int - val _6 : '𒀀 option -> '𒀀 - val int_of_option : int option -> int - val _42 : int -> bool - val id1 : '𒀀 -> '𒀀 - val id2 : '𒀀 -> '𒀀 - - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/015tuples.ml - val fix : (('𒀀 -> '𒀐) -> '𒀀 -> '𒀐) -> '𒀀 -> '𒀐 - val map : ('𒀀 -> '𒀐) -> '𒀀 * '𒀀 -> '𒀐 * '𒀐 - val fixpoly : (('𒀀 -> '𒀐) * ('𒀀 -> '𒀐) -> '𒀀 -> '𒀐) * (('𒀀 -> '𒀐) * ('𒀀 -> '𒀐) -> '𒀀 -> '𒀐) -> ('𒀀 -> '𒀐) * ('𒀀 -> '𒀐) - val feven : '𒀀 * (int -> int) -> int -> int - val fodd : (int -> int) * '𒀀 -> int -> int - val tie : (int -> int) * (int -> int) - val modd : int -> int - val meven : int -> int - val main : int - - $ ../bin/REPL.exe -dinferprogram < manytests/typed/016lists.ml - val length : '𒀀 list -> int - val length_tail : '𒀀 list -> int - val map : ('𒀀 -> '𒀐) -> '𒀀 list -> '𒀐 list - val append : '𒀀 list -> '𒀀 list -> '𒀀 list - val concat : ('𒀀 list) list -> '𒀀 list - val iter : ('𒀀 -> unit) -> '𒀀 list -> unit - val cartesian : '𒀀 list -> '𒀐 list -> ('𒀀 * '𒀐) list - val main : int - - $ ../bin/REPL.exe -dinference < let f m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m17 m18 - > m19 m20 m21 m22 m23 m24 m25 m26 m27 m28 m29 m30 m31 m32 m33 m34 m35 m36 - > m37 m38 m39 m40 m41 m42 m43 m44 m45 m46 m47 m48 m49 m50 m51 m52 m53 m54 - > m55 m56 m57 m58 m59 m60 m61 m62 m63 m64 m65 m66 m67 m68 m69 m70 m71 m72 - > m73 m74 m75 m76 m77 m78 m79 m80 m81 m82 m83 m84 m85 m86 m87 m88 m89 m90 - > m91 m92 m93 m94 m95 m96 m97 m98 m99 m100 = 1 - val f : '𒀀 -> '𒀐 -> '𒀲 -> '𒂷 -> '𒌧 -> '𒀀𒀀 -> '𒀀𒀐 -> '𒀀𒀲 -> '𒀀𒂷 -> '𒀀𒌧 -> '𒀐𒀀 -> '𒀐𒀐 -> '𒀐𒀲 -> '𒀐𒂷 -> '𒀐𒌧 -> '𒀲𒀀 -> '𒀲𒀐 -> '𒀲𒀲 -> '𒀲𒂷 -> '𒀲𒌧 -> '𒂷𒀀 -> '𒂷𒀐 -> '𒂷𒀲 -> '𒂷𒂷 -> '𒂷𒌧 -> '𒌧𒀀 -> '𒌧𒀐 -> '𒌧𒀲 -> '𒌧𒂷 -> '𒌧𒌧 -> '𒀀𒀀𒀀 -> '𒀀𒀀𒀐 -> '𒀀𒀀𒀲 -> '𒀀𒀀𒂷 -> '𒀀𒀀𒌧 -> '𒀀𒀐𒀀 -> '𒀀𒀐𒀐 -> '𒀀𒀐𒀲 -> '𒀀𒀐𒂷 -> '𒀀𒀐𒌧 -> '𒀀𒀲𒀀 -> '𒀀𒀲𒀐 -> '𒀀𒀲𒀲 -> '𒀀𒀲𒂷 -> '𒀀𒀲𒌧 -> '𒀀𒂷𒀀 -> '𒀀𒂷𒀐 -> '𒀀𒂷𒀲 -> '𒀀𒂷𒂷 -> '𒀀𒂷𒌧 -> '𒀀𒌧𒀀 -> '𒀀𒌧𒀐 -> '𒀀𒌧𒀲 -> '𒀀𒌧𒂷 -> '𒀀𒌧𒌧 -> '𒀐𒀀𒀀 -> '𒀐𒀀𒀐 -> '𒀐𒀀𒀲 -> '𒀐𒀀𒂷 -> '𒀐𒀀𒌧 -> '𒀐𒀐𒀀 -> '𒀐𒀐𒀐 -> '𒀐𒀐𒀲 -> '𒀐𒀐𒂷 -> '𒀐𒀐𒌧 -> '𒀐𒀲𒀀 -> '𒀐𒀲𒀐 -> '𒀐𒀲𒀲 -> '𒀐𒀲𒂷 -> '𒀐𒀲𒌧 -> '𒀐𒂷𒀀 -> '𒀐𒂷𒀐 -> '𒀐𒂷𒀲 -> '𒀐𒂷𒂷 -> '𒀐𒂷𒌧 -> '𒀐𒌧𒀀 -> '𒀐𒌧𒀐 -> '𒀐𒌧𒀲 -> '𒀐𒌧𒂷 -> '𒀐𒌧𒌧 -> '𒀲𒀀𒀀 -> '𒀲𒀀𒀐 -> '𒀲𒀀𒀲 -> '𒀲𒀀𒂷 -> '𒀲𒀀𒌧 -> '𒀲𒀐𒀀 -> '𒀲𒀐𒀐 -> '𒀲𒀐𒀲 -> '𒀲𒀐𒂷 -> '𒀲𒀐𒌧 -> '𒀲𒀲𒀀 -> '𒀲𒀲𒀐 -> '𒀲𒀲𒀲 -> '𒀲𒀲𒂷 -> '𒀲𒀲𒌧 -> '𒀲𒂷𒀀 -> '𒀲𒂷𒀐 -> '𒀲𒂷𒀲 -> '𒀲𒂷𒂷 -> '𒀲𒂷𒌧 -> int - diff --git a/OCamlWeakTypeVariables/tests/test_manytests_typed_eval.t b/OCamlWeakTypeVariables/tests/test_manytests_typed_eval.t deleted file mode 100644 index e15495aa9..000000000 --- a/OCamlWeakTypeVariables/tests/test_manytests_typed_eval.t +++ /dev/null @@ -1,65 +0,0 @@ - $ ../bin/REPL.exe < (fun x -> x) (fun x -> x) (fun x -> x) 5 - - $ ../bin/REPL.exe < manytests/typed/001fac.ml - 24 - - $ ../bin/REPL.exe < manytests/typed/002fac.ml - 24 - - $ ../bin/REPL.exe < manytests/typed/003fib.ml - 3 - 3 - - $ ../bin/REPL.exe < manytests/typed/004manyargs.ml - 1111111111 - 1 - 10 - 100 - - $ ../bin/REPL.exe < manytests/typed/005fix.ml - 720 - - $ ../bin/REPL.exe < manytests/typed/006partial.ml - 1122 - - $ ../bin/REPL.exe < manytests/typed/006partial2.ml - 1 - 2 - 3 - 7 - - $ ../bin/REPL.exe < manytests/typed/006partial3.ml - 4 - 8 - 9 - -Argument eval order is undefined in OCaml, so in my language that also undefined 😼 - $ ../bin/REPL.exe < manytests/typed/007order.ml - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - - $ ../bin/REPL.exe < manytests/typed/008ascription.ml - 8 - - $ ../bin/REPL.exe < manytests/typed/009let_poly.ml - - $ cat manytests/typed/010sukharev.ml | ../bin/REPL.exe - - $ ../bin/REPL.exe < manytests/typed/015tuples.ml - 1 - 1 - 1 - 1 - - - $ ../bin/REPL.exe < manytests/typed/016lists.ml - 1 - 2 - 3 - 8 diff --git a/OCamlWeakTypeVariables/tests/test_parser.t b/OCamlWeakTypeVariables/tests/test_parser.t deleted file mode 100644 index 1e29f2c05..000000000 --- a/OCamlWeakTypeVariables/tests/test_parser.t +++ /dev/null @@ -1,329 +0,0 @@ -Copyright 2024-2025, Damir Yunusov, Ilhom Kombaev -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../bin/REPL.exe -dparsetree < 2 * 2 - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_constant (Pconst_int 2))] - ))) - - $ ../bin/REPL.exe -dparsetree < 2 * ((2 * (124 * homka))) * (((2 * 1))) - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 124)); - (Pexp_ident "homka")] - )) - ] - )) - ] - )); - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_constant (Pconst_int 1))] - )) - ] - ))) - - $ ../bin/REPL.exe -dparsetree < 2 * ((2 / (124 / homka))) * (1) * (2 / 2) * (((2 * 1))) - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_apply ((Pexp_ident "*"), - [(Pexp_apply ((Pexp_ident "*"), - [(Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_apply ((Pexp_ident "/"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_apply ((Pexp_ident "/"), - [(Pexp_constant (Pconst_int 124)); - (Pexp_ident "homka")] - )) - ] - )) - ] - )); - (Pexp_constant (Pconst_int 1))] - )); - (Pexp_apply ((Pexp_ident "/"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_constant (Pconst_int 2))] - )) - ] - )); - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_constant (Pconst_int 1))] - )) - ] - ))) - - $ ../bin/REPL.exe -dparsetree < fun x -> 5 - Parsed result: (Pstr_eval - (Pexp_fun ((Ppat_var "x"), (Pexp_constant (Pconst_int 5))))) - - $ ../bin/REPL.exe -dparsetree < fun x -> fun y -> fun z -> 5 - Parsed result: (Pstr_eval - (Pexp_fun ((Ppat_var "x"), - (Pexp_fun ((Ppat_var "y"), - (Pexp_fun ((Ppat_var "z"), - (Pexp_constant (Pconst_int 5)))) - )) - ))) - - $ ../bin/REPL.exe -dparsetree < fun x y z -> 5 - Parsed result: (Pstr_eval - (Pexp_fun ((Ppat_var "x"), - (Pexp_fun ((Ppat_var "y"), - (Pexp_fun ((Ppat_var "z"), - (Pexp_constant (Pconst_int 5)))) - )) - ))) - - $ ../bin/REPL.exe -dparsetree < if x then y else z - Parsed result: (Pstr_eval - (Pexp_ifthenelse ((Pexp_ident "x"), (Pexp_ident "y"), - (Some (Pexp_ident "z"))))) - - $ ../bin/REPL.exe -dparsetree < if x then if y then z - Parsed result: (Pstr_eval - (Pexp_ifthenelse ((Pexp_ident "x"), - (Pexp_ifthenelse ((Pexp_ident "y"), (Pexp_ident "z"), - None)), - None))) - - $ ../bin/REPL.exe -dparsetree < 2 * if true then 2 else 1 - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "*"), - [(Pexp_constant (Pconst_int 2)); - (Pexp_ifthenelse ( - (Pexp_constant (Pconst_boolean true)), - (Pexp_constant (Pconst_int 2)), - (Some (Pexp_constant (Pconst_int 1))))) - ] - ))) - - $ ../bin/REPL.exe -dparsetree < fun x y -> if x then y - Parsed result: (Pstr_eval - (Pexp_fun ((Ppat_var "x"), - (Pexp_fun ((Ppat_var "y"), - (Pexp_ifthenelse ((Pexp_ident "x"), (Pexp_ident "y"), - None)) - )) - ))) - - $ ../bin/REPL.exe -dparsetree < fun x -> fun y -> if x then y else x - Parsed result: (Pstr_eval - (Pexp_fun ((Ppat_var "x"), - (Pexp_fun ((Ppat_var "y"), - (Pexp_ifthenelse ((Pexp_ident "x"), (Pexp_ident "y"), - (Some (Pexp_ident "x")))) - )) - ))) - - $ ../bin/REPL.exe -dparsetree < f y z - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "f"), - [(Pexp_ident "y"); (Pexp_ident "z")]))) - - $ ../bin/REPL.exe -dparsetree < let homka = 5 in homka - Parsed result: (Pstr_eval - (Pexp_let (NonRecursive, - [{ pvb_pat = (Ppat_var "homka"); - pvb_expr = (Pexp_constant (Pconst_int 5)) } - ], - (Pexp_ident "homka")))) - - $ ../bin/REPL.exe -dparsetree < let homka = fun x -> x + 2 in homka - Parsed result: (Pstr_eval - (Pexp_let (NonRecursive, - [{ pvb_pat = (Ppat_var "homka"); - pvb_expr = - (Pexp_fun ((Ppat_var "x"), - (Pexp_apply ((Pexp_ident "+"), - [(Pexp_ident "x"); - (Pexp_constant (Pconst_int 2))] - )) - )) - } - ], - (Pexp_ident "homka")))) - - $ ../bin/REPL.exe -dparsetree < let reca = 5 - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_var "reca"); - pvb_expr = (Pexp_constant (Pconst_int 5)) } - ] - )) - - $ ../bin/REPL.exe -dparsetree < (5+5, fun homka x -> 5, "looool") - Parsed result: (Pstr_eval - (Pexp_tuple - [(Pexp_apply ((Pexp_ident "+"), - [(Pexp_constant (Pconst_int 5)); - (Pexp_constant (Pconst_int 5))] - )); - (Pexp_fun ((Ppat_var "homka"), - (Pexp_fun ((Ppat_var "x"), - (Pexp_tuple - [(Pexp_constant (Pconst_int 5)); - (Pexp_constant (Pconst_string "looool"))]) - )) - )) - ])) - - $ ../bin/REPL.exe -dparsetree < (let x = 5 in 4, x) - Parsed result: (Pstr_eval - (Pexp_let (NonRecursive, - [{ pvb_pat = (Ppat_var "x"); - pvb_expr = (Pexp_constant (Pconst_int 5)) } - ], - (Pexp_tuple - [(Pexp_constant (Pconst_int 4)); (Pexp_ident "x")]) - ))) - - $ ../bin/REPL.exe -dparsetree < let x = (1, 2, 3) - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_var "x"); - pvb_expr = - (Pexp_tuple - [(Pexp_constant (Pconst_int 1)); - (Pexp_constant (Pconst_int 2)); - (Pexp_constant (Pconst_int 3))]) - } - ] - )) - - $ ../bin/REPL.exe -dparsetree < -5 - Parsed result: (Pstr_eval (Pexp_constant (Pconst_int -5))) - - $ ../bin/REPL.exe -dparsetree < 5-5 - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "-"), - [(Pexp_constant (Pconst_int 5)); - (Pexp_constant (Pconst_int 5))] - ))) - - $ ../bin/REPL.exe -dparsetree < 5-(-5) - Parsed result: (Pstr_eval - (Pexp_apply ((Pexp_ident "-"), - [(Pexp_constant (Pconst_int 5)); - (Pexp_constant (Pconst_int -5))] - ))) - - $ ../bin/REPL.exe -dparsetree < let Some x = Some 5 - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = - (Ppat_construct ("Some", (Some (Ppat_var "x")))); - pvb_expr = - (Pexp_construct ("Some", - (Some (Pexp_constant (Pconst_int 5))))) - } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let Homka, homka = Some 5 - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = - (Ppat_tuple - [(Ppat_construct ("Homka", None)); (Ppat_var "homka") - ]); - pvb_expr = - (Pexp_construct ("Some", - (Some (Pexp_constant (Pconst_int 5))))) - } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let homka, Homka = Some 5 - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = - (Ppat_tuple - [(Ppat_var "homka"); (Ppat_construct ("Homka", None)) - ]); - pvb_expr = - (Pexp_construct ("Some", - (Some (Pexp_constant (Pconst_int 5))))) - } - ] - )) - - $ ../bin/REPL.exe -dparsetree < match homka with homka -> homka - Parsed result: (Pstr_eval - (Pexp_match ((Pexp_ident "homka"), - [{ pc_lhs = (Ppat_var "homka"); - pc_rhs = (Pexp_ident "homka") } - ] - ))) - - $ ../bin/REPL.exe -dparsetree < let homka = match 5 + 5 with 2 -> "lol" | 122 -> "Homka" | 42 -> "suvorovrain" - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_var "homka"); - pvb_expr = - (Pexp_match ( - (Pexp_apply ((Pexp_ident "+"), - [(Pexp_constant (Pconst_int 5)); - (Pexp_constant (Pconst_int 5))] - )), - [{ pc_lhs = (Ppat_constant (Pconst_int 2)); - pc_rhs = (Pexp_constant (Pconst_string "lol")) }; - { pc_lhs = (Ppat_constant (Pconst_int 122)); - pc_rhs = (Pexp_constant (Pconst_string "Homka")) - }; - { pc_lhs = (Ppat_constant (Pconst_int 42)); - pc_rhs = - (Pexp_constant (Pconst_string "suvorovrain")) } - ] - )) - } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let homka = function 1 -> "damir" | 2 -> "homka" | 3 -> "kirilos" - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_var "homka"); - pvb_expr = - (Pexp_function - [{ pc_lhs = (Ppat_constant (Pconst_int 1)); - pc_rhs = (Pexp_constant (Pconst_string "damir")) }; - { pc_lhs = (Ppat_constant (Pconst_int 2)); - pc_rhs = (Pexp_constant (Pconst_string "homka")) - }; - { pc_lhs = (Ppat_constant (Pconst_int 3)); - pc_rhs = - (Pexp_constant (Pconst_string "kirilos")) } - ]) - } - ] - )) diff --git a/OCamlWeakTypeVariables/tests/test_parser_const.t b/OCamlWeakTypeVariables/tests/test_parser_const.t deleted file mode 100644 index 16fb5332f..000000000 --- a/OCamlWeakTypeVariables/tests/test_parser_const.t +++ /dev/null @@ -1,30 +0,0 @@ -Copyright 2024-2025, Damir Yunusov, Ilhom Kombaev -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../bin/REPL.exe -dparsetree < 1 - Parsed result: (Pstr_eval (Pexp_constant (Pconst_int 1))) - - $ ../bin/REPL.exe -dparsetree < 1_000 - Parsed result: (Pstr_eval (Pexp_constant (Pconst_int 1000))) - - $ ../bin/REPL.exe -dparsetree < 1___1 - Parsed result: (Pstr_eval (Pexp_constant (Pconst_int 11))) - - $ ../bin/REPL.exe -dparsetree < 1_000_000 - Parsed result: (Pstr_eval (Pexp_constant (Pconst_int 1000000))) - - $ ../bin/REPL.exe -dparsetree < _ - Error: : not enough input - - $ ../bin/REPL.exe -dparsetree < "Homka" - Parsed result: (Pstr_eval (Pexp_constant (Pconst_string "Homka"))) - - $ ../bin/REPL.exe -dparsetree < true - Parsed result: (Pstr_eval (Pexp_constant (Pconst_boolean true))) diff --git a/OCamlWeakTypeVariables/tests/test_parser_factorial.t b/OCamlWeakTypeVariables/tests/test_parser_factorial.t deleted file mode 100644 index 10485f63c..000000000 --- a/OCamlWeakTypeVariables/tests/test_parser_factorial.t +++ /dev/null @@ -1,32 +0,0 @@ -Copyright 2024-2025, Damir Yunusov, Ilhom Kombaev -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../bin/REPL.exe -dparsetree < let rec factorial n = if n = 0 then 1 else n * factorial (n - 1) - Parsed result: (Pstr_value (Recursive, - [{ pvb_pat = (Ppat_var "factorial"); - pvb_expr = - (Pexp_fun ((Ppat_var "n"), - (Pexp_ifthenelse ( - (Pexp_apply ((Pexp_ident "="), - [(Pexp_ident "n"); - (Pexp_constant (Pconst_int 0))] - )), - (Pexp_constant (Pconst_int 1)), - (Some (Pexp_apply ((Pexp_ident "*"), - [(Pexp_ident "n"); - (Pexp_apply ((Pexp_ident "factorial"), - [(Pexp_apply ((Pexp_ident "-"), - [(Pexp_ident "n"); - (Pexp_constant (Pconst_int 1)) - ] - )) - ] - )) - ] - ))) - )) - )) - } - ] - )) diff --git a/OCamlWeakTypeVariables/tests/test_parser_pattern.t b/OCamlWeakTypeVariables/tests/test_parser_pattern.t deleted file mode 100644 index 890d601c8..000000000 --- a/OCamlWeakTypeVariables/tests/test_parser_pattern.t +++ /dev/null @@ -1,56 +0,0 @@ -Copyright 2024-2025, Damir Yunusov, Ilhom Kombaev -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../bin/REPL.exe -dparsetree < let _ = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = Ppat_any; pvb_expr = (Pexp_ident "homka") }])) - - $ ../bin/REPL.exe -dparsetree < let homka = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_var "homka"); - pvb_expr = (Pexp_ident "homka") } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let 122 = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_constant (Pconst_int 122)); - pvb_expr = (Pexp_ident "homka") } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let "homka" = "homka" - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_constant (Pconst_string "homka")); - pvb_expr = (Pexp_constant (Pconst_string "homka")) } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let _, _ = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_tuple [Ppat_any; Ppat_any]); - pvb_expr = (Pexp_ident "homka") } - ] - )) - - - $ ../bin/REPL.exe -dparsetree < let x, y = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_tuple [(Ppat_var "x"); (Ppat_var "y")]); - pvb_expr = (Pexp_ident "homka") } - ] - )) - - $ ../bin/REPL.exe -dparsetree < let (_, _, _) = homka - Parsed result: (Pstr_value (NonRecursive, - [{ pvb_pat = (Ppat_tuple [Ppat_any; Ppat_any; Ppat_any]); - pvb_expr = (Pexp_ident "homka") } - ] - )) diff --git a/Ocaml/.envrc b/Ocaml/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/Ocaml/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/Ocaml/.gitignore b/Ocaml/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/Ocaml/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/Ocaml/.ocamlformat b/Ocaml/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/Ocaml/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/Ocaml/.zanuda b/Ocaml/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/Ocaml/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/Ocaml/COPYING b/Ocaml/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/Ocaml/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/Ocaml/COPYING.CC0 b/Ocaml/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/Ocaml/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/Ocaml/COPYING.LESSER b/Ocaml/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/Ocaml/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/Ocaml/Makefile b/Ocaml/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/Ocaml/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/Ocaml/Ocaml.opam b/Ocaml/Ocaml.opam deleted file mode 100644 index 38575d14a..000000000 --- a/Ocaml/Ocaml.opam +++ /dev/null @@ -1,35 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for Ocaml" -description: "An interpreter for Ocaml" -maintainer: ["Daniil Kadochnikov"] -authors: ["Daniil Kadochnikov"] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/Kakadu/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/Lambda" -bug-reports: "https://github.com/Kakadu/fp2024" -depends: [ - "dune" {>= "3.7"} - "angstrom" - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/Ocaml/bin/demo.ml b/Ocaml/bin/demo.ml deleted file mode 100755 index 85609fcf8..000000000 --- a/Ocaml/bin/demo.ml +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocaml_lib -open Launcher - -let () = run (Stdio.In_channel.input_all stdin) diff --git a/Ocaml/bin/dune b/Ocaml/bin/dune deleted file mode 100644 index e4e3036dd..000000000 --- a/Ocaml/bin/dune +++ /dev/null @@ -1,8 +0,0 @@ -(executable - (name demo) - (modules demo) - (public_name demoInterpret) - (libraries ocaml_lib stdio)) - -(cram - (deps ./demo.exe)) diff --git a/Ocaml/dune b/Ocaml/dune deleted file mode 100644 index 0ef8774ec..000000000 --- a/Ocaml/dune +++ /dev/null @@ -1,16 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - -; (executable -; (name REPL) -; (public_name REPL) -; (modules REPL) -; (libraries lambda_lib stdio)) - -; (cram -; (deps ./REPL.exe %{bin:REPL})) diff --git a/Ocaml/dune-project b/Ocaml/dune-project deleted file mode 100644 index f928f94a8..000000000 --- a/Ocaml/dune-project +++ /dev/null @@ -1,34 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Daniil Kadochnikov") - -(maintainers "Daniil Kadochnikov") - -(bug_reports "https://github.com/Kakadu/fp2024") - -(homepage "https://github.com/Kakadu/fp2024") - -(package - (name Ocaml) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for Ocaml") - (description "An interpreter for Ocaml") - (documentation "https://kakadu.github.io/fp2024/docs/Lambda") - (version 0.1) - (depends - dune - angstrom - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - ; base - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/Ocaml/lib/Pprint.ml b/Ocaml/lib/Pprint.ml deleted file mode 100644 index 447b8f45d..000000000 --- a/Ocaml/lib/Pprint.ml +++ /dev/null @@ -1,109 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Format -open Typedtree -open Ast -open Interpreter.Interpret - -let rec pp_typ ppf = function - | Ty_var n -> fprintf ppf "'_%d" n - | TyInt -> pp_print_string ppf "int" - | TyBool -> pp_print_string ppf "bool" - | TyString -> pp_print_string ppf "string" - | TyTuple ty -> - fprintf ppf "("; - Format.pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf " * ") pp_typ ppf ty; - fprintf ppf ")" - | TyList ty -> fprintf ppf "%a list" pp_typ ty - | TyOption ty -> fprintf ppf "%a option" pp_typ ty - | Arrow (l, r) -> fprintf ppf "(%a -> %a)" pp_typ l pp_typ r -;; - -let rec pp_typ_expr ppf = function - | Some TInt -> pp_print_string ppf "int" - | Some TBool -> pp_print_string ppf "bool" - | Some TString -> pp_print_string ppf "string" - | Some (TTuple ty) -> - fprintf ppf "("; - Format.pp_print_list - ~pp_sep:(fun ppf () -> fprintf ppf " * ") - pp_typ_expr - ppf - (List.rev (trasform_to_some ty)); - fprintf ppf ")" - | Some (TList ty) -> fprintf ppf "(%a list)" pp_typ_expr (Some ty) - | Some (TOption ty) -> fprintf ppf "(%a option)" pp_typ_expr (Some ty) - | Some (TFun (l, r)) -> - fprintf ppf "(%a -> %a)" pp_typ_expr (Some l) pp_typ_expr (Some r) - | None -> pp_print_string ppf "No type" - -and trasform_to_some ty = List.fold_left (fun acc t -> Some t :: acc) [] ty - -let pp_scheme ppf = function - | S (xs, t) -> fprintf ppf "forall %a . %a" VarSet.pp xs pp_typ t -;; - -let pp_expr = - let rec helper ppf = function - | EInt n -> fprintf ppf "%d" n - | EBool n -> fprintf ppf "%b" n - | EString n -> fprintf ppf "%S" n - | ETuple expr -> - fprintf ppf "("; - Format.pp_print_list - ~pp_sep:(fun ppf () -> fprintf ppf ", ") - helper - ppf - (List.rev expr); - fprintf ppf ")" - | EList expr -> - fprintf ppf "["; - Format.pp_print_list - ~pp_sep:(fun ppf () -> fprintf ppf "; ") - helper - ppf - (List.rev expr); - fprintf ppf "]" - | ESome expr -> - fprintf ppf "Some "; - helper ppf expr - | ENone -> fprintf ppf "None" - | EFun (_, _) -> fprintf ppf "" - | _ -> fprintf ppf "PPrint: unexpected error while printing expr" - in - helper -;; - -let pp_dec ppf ((name, expr), t) = - fprintf ppf "val %s : " name; - pp_typ ppf t; - fprintf ppf " = "; - pp_expr ppf expr -;; - -let print_type ppf = function - | t :: [] -> pp_typ ppf t - | _ -> fprintf ppf "PPrint: unexpected error while uncovering value for printing" -;; - -let pp_val ppf t = function - | VConst x -> - fprintf ppf "- : "; - print_type ppf t; - fprintf ppf " = "; - pp_expr ppf x - | VClosure (_, _, x) | VRecClosure (_, _, _, x) -> - fprintf ppf "- : "; - print_type ppf t; - fprintf ppf " = "; - pp_expr ppf x - | VDeclaration x -> - let com_l = List.combine x t in - Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.pp_print_newline ppf ()) - pp_dec - ppf - com_l -;; diff --git a/Ocaml/lib/Pprint.mli b/Ocaml/lib/Pprint.mli deleted file mode 100644 index 1b962aaca..000000000 --- a/Ocaml/lib/Pprint.mli +++ /dev/null @@ -1,12 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val pp_typ : Format.formatter -> Typedtree.ty -> unit -val pp_typ_expr : Format.formatter -> Ast.type_expr option -> unit -val trasform_to_some : Ast.type_expr list -> Ast.type_expr option list -val pp_scheme : Format.formatter -> Typedtree.scheme -> unit -val pp_expr : Format.formatter -> Ast.expr -> unit -val pp_dec : Format.formatter -> (string * Ast.expr) * Typedtree.ty -> unit -val print_type : Format.formatter -> Typedtree.ty list -> unit -val pp_val : Format.formatter -> Typedtree.ty list -> Interpreter.Interpret.value -> unit diff --git a/Ocaml/lib/ast.ml b/Ocaml/lib/ast.ml deleted file mode 100644 index 2656bec7d..000000000 --- a/Ocaml/lib/ast.ml +++ /dev/null @@ -1,51 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type type_expr = - | TInt - | TBool - | TString - | TTuple of type_expr list - | TList of type_expr - | TOption of type_expr - | TFun of type_expr * type_expr -[@@deriving show { with_path = false }] - -type pattern = PVar of string * type_expr option [@@deriving show { with_path = false }] - -type binary_operator = - | Add (* + *) - | Sub (* - *) - | Mul (* * *) - | Div (* / *) - | And (* && *) - | Or (* || *) - | Eq (* = *) - | Neq (* <> *) - | Lt (* < *) - | Gt (* > *) - | Le (* <= *) - | Ge (* >= *) -[@@deriving show { with_path = false }] - -type rec_flag = - | Recursive - | NonRecursive -[@@deriving show { with_path = false }] - -type expr = - | EInt of int - | EBool of bool - | EVar of string * type_expr option - | EString of string - | EBinOp of binary_operator * expr * expr - | EApp of expr * expr - | EFun of pattern * expr - | ELet of rec_flag * (pattern * expr) list * expr option - | EIf of expr * expr * expr - | ETuple of expr list - | EList of expr list - | ESome of expr - | ENone -[@@deriving show { with_path = false }] diff --git a/Ocaml/lib/dune b/Ocaml/lib/dune deleted file mode 100644 index 81637e064..000000000 --- a/Ocaml/lib/dune +++ /dev/null @@ -1,10 +0,0 @@ -(library - (name ocaml_lib) - (public_name Ocaml.Lib) - (modules Inferencer Typedtree Pprint Ast Parser Interpreter Launcher) - (libraries base angstrom) - (preprocess - (pps ppx_deriving.show ppx_expect)) - (inline_tests) - (instrumentation - (backend bisect_ppx))) diff --git a/Ocaml/lib/inferencer.ml b/Ocaml/lib/inferencer.ml deleted file mode 100644 index 7326e9c36..000000000 --- a/Ocaml/lib/inferencer.ml +++ /dev/null @@ -1,923 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Typedtree -open Ast - -let use_logging = false - -let log fmt = - if use_logging - then Format.kasprintf (fun s -> Format.printf "%s\n%!" s) fmt - else Format.ifprintf Format.std_formatter fmt -;; - -type error = - [ `Occurs_check - | `No_variable of string - | `Unification_failed of ty * ty - | `Unapplicable_type of type_expr option * ty - | `Unexpected_error - ] - -let pp_error ppf : error -> _ = function - | `Occurs_check -> Format.fprintf ppf "Type Checker Error: occurs check failed" - | `No_variable s -> Format.fprintf ppf "Type Checker Error: undefined variable '%s'" s - | `Unification_failed (l, r) -> - Format.fprintf - ppf - "Type Checker Error: unification failed on %a and %a" - Pprint.pp_typ - l - Pprint.pp_typ - r - | `Unapplicable_type (par, inf) -> - Format.fprintf - ppf - "Type Checker Error: expression has type %a but expected %a" - Pprint.pp_typ - inf - Pprint.pp_typ_expr - par - | `Unexpected_error -> Format.fprintf ppf "Type Checker Error: unexpected Error" -;; - -module R : sig - type 'a t - - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - end - - (** Creation of a fresh name from internal state *) - val fresh : int t - - (** Running a transformer: getting the inner result value *) - val run : 'a t -> ('a, error) Result.t -end = struct - (* A compositon: State monad after Result monad *) - type 'a t = int -> int * ('a, error) Result.t - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let last, r = m st in - match r with - | Result.Error x -> last, Error x - | Ok a -> f a last - ;; - - let fail e st = st, Base.Result.fail e - let return x last = last, Base.Result.return x - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Ok x -> st, Ok (f x) - | st, Result.Error e -> st, Result.Error e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - end - - let fresh : int t = fun last -> last + 1, Result.Ok last - let run m = snd (m 0) -end - -type fresh = int - -module Type = struct - type t = ty - - let rec occurs_in v = function - | Ty_var b -> b = v - | Arrow (l, r) -> occurs_in v l || occurs_in v r - | TyList t -> occurs_in v t - | TyOption t -> occurs_in v t - | TyTuple tl -> List.exists (occurs_in v) tl - | TyInt | TyBool | TyString -> false - ;; - - let free_vars = - let rec helper acc = function - | Ty_var b -> VarSet.add b acc - | Arrow (l, r) -> helper (helper acc l) r - | TyList t -> helper acc t - | TyOption t -> helper acc t - | TyTuple tl -> List.fold_left helper acc tl - | TyInt | TyBool | TyString -> acc - in - helper VarSet.empty - ;; -end - -module Subst : sig - type t - - val pp : Stdlib.Format.formatter -> t -> unit - val empty : t - val singleton : fresh -> ty -> t R.t - - (** Getting value from substitution. May raise [Not_found] *) - val find_exn : fresh -> t -> ty - - val find : fresh -> t -> ty option - val apply : t -> ty -> ty - val unify : ty -> ty -> t R.t - val unify_with_tyexpr : type_expr option -> ty -> t R.t - - (** Compositon of substitutions *) - val compose : t -> t -> t R.t - - val compose_all : t list -> t R.t - val remove : t -> fresh -> t -end = struct - open R - open R.Syntax - open Base - open Ast - - (* an association list. In real world replace it by a finite map *) - type t = (fresh * ty) list - - let pp ppf subst = - let open Stdlib.Format in - fprintf - ppf - "[ %a ]" - (pp_print_list - ~pp_sep:(fun ppf () -> fprintf ppf ", ") - (fun ppf (k, v) -> fprintf ppf "%d -> %a" k Pprint.pp_typ v)) - subst - ;; - - let empty = [] - let mapping k v = if Type.occurs_in k v then fail `Occurs_check else return (k, v) - - let singleton k v = - let* mapping = mapping k v in - return [ mapping ] - ;; - - let find_exn k xs = List.Assoc.find_exn xs k ~equal:Int.equal - let find k xs = List.Assoc.find xs k ~equal:Int.equal - let remove xs k = List.Assoc.remove xs k ~equal:Int.equal - - let apply s = - let rec helper = function - | Ty_var b as ty -> - (match find_exn b s with - | exception Not_found_s _ -> ty - | x -> x) - | Arrow (l, r) -> Arrow (helper l, helper r) - | TyList t -> TyList (helper t) - | TyOption t -> TyOption (helper t) - | TyTuple tl -> TyTuple (Stdlib.List.map helper tl) - | other -> other - in - helper - ;; - - let rec unify l r = - match l, r with - | TyInt, TyInt | TyBool, TyBool | TyString, TyString -> return empty - | Ty_var a, Ty_var b when Int.equal a b -> return empty - | Ty_var b, t | t, Ty_var b -> singleton b t - | Arrow (l1, r1), Arrow (l2, r2) -> - let* subs1 = unify l1 l2 in - let* subs2 = unify (apply subs1 r1) (apply subs1 r2) in - compose subs1 subs2 - | TyTuple tl1, TyTuple tl2 -> - if List.length tl1 <> List.length tl2 - then fail (`Unification_failed (l, r)) - else ( - let unify_pairs acc (t1, t2) = - let* s = acc in - let* s' = unify (apply s t1) (apply s t2) in - compose s s' - in - try - Stdlib.List.fold_left unify_pairs (return empty) (Stdlib.List.combine tl1 tl2) - with - | Invalid_argument _ -> fail (`Unification_failed (l, r))) - | TyList t1, TyList t2 -> unify t1 t2 - | TyOption t1, TyOption t2 -> unify t1 t2 - | l, r -> fail (`Unification_failed (l, r)) - - and extend s (k, v) = - match List.Assoc.find s ~equal:Int.equal k with - | None -> - let v = apply s v in - let* s2 = singleton k v in - RList.fold_left s ~init:(return s2) ~f:(fun acc (k, v) -> - let v = apply s2 v in - let* mapping = mapping k v in - return (mapping :: acc)) - | Some v2 -> - let* s2 = unify v v2 in - compose s s2 - - and compose s1 s2 = RList.fold_left s2 ~init:(return s1) ~f:extend - - let rec type_transform = function - | TInt -> TyInt - | TBool -> TyBool - | TString -> TyString - | TTuple l -> - TyTuple - (List.rev (Stdlib.List.fold_left (fun acc t -> type_transform t :: acc) [] l)) - | TList t -> TyList (type_transform t) - | TOption t -> TyOption (type_transform t) - | TFun (l, r) -> Arrow (type_transform l, type_transform r) - ;; - - let rec unify_with_tyexpr (l : type_expr option) (r : ty) = - match l, r with - | Some TInt, TyInt | Some TBool, TyBool | Some TString, TyString -> return empty - | None, _ -> return empty - | Some t, Ty_var b -> return [ b, type_transform t ] - | Some (TFun (l1, r1)), Arrow (l2, r2) -> - let* subs1 = unify_with_tyexpr (Some l1) l2 in - let* subs2 = unify_with_tyexpr (Some r1) (apply subs1 r2) in - compose subs1 subs2 - | Some (TTuple tl1), TyTuple tl2 -> - if List.length tl1 <> List.length tl2 - then fail (`Unapplicable_type (l, r)) - else ( - let unify_pairs acc (t1, t2) = - let* s = acc in - let* s' = unify_with_tyexpr (Some t1) (apply s t2) in - compose s s' - in - try - Stdlib.List.fold_left unify_pairs (return empty) (Stdlib.List.combine tl1 tl2) - with - | Invalid_argument _ -> fail (`Unapplicable_type (l, r))) - | Some (TList t1), TyList t2 -> unify_with_tyexpr (Some t1) t2 - | Some (TOption t1), TyOption t2 -> unify_with_tyexpr (Some t1) t2 - | l, r -> fail (`Unapplicable_type (l, r)) - ;; - - let compose_all ss = RList.fold_left ss ~init:(return empty) ~f:compose -end - -module VarSet = struct - include VarSet - - let fold_left_m f acc set = - fold - (fun x acc -> - let open R.Syntax in - let* acc = acc in - f acc x) - acc - set - ;; -end - -module Scheme = struct - type t = scheme - - let occurs_in v = function - | S (xs, t) -> (not (VarSet.mem v xs)) && Type.occurs_in v t - ;; - - let free_vars = function - | S (bs, t) -> VarSet.diff (Type.free_vars t) bs - ;; - - let apply sub (S (names, ty)) = - let s2 = VarSet.fold (fun k s -> Subst.remove s k) names sub in - S (names, Subst.apply s2 ty) - ;; - - let pp = Pprint.pp_scheme -end - -module TypeEnv = struct - open Base - - type t = (string * scheme) list - - let extend e h = h :: e - let empty = [] - - let free_vars : t -> VarSet.t = - List.fold_left ~init:VarSet.empty ~f:(fun acc (_, s) -> - VarSet.union acc (Scheme.free_vars s)) - ;; - - let apply s env = List.Assoc.map env ~f:(Scheme.apply s) - - let pp ppf xs = - Stdlib.Format.fprintf ppf "{| "; - List.iter xs ~f:(fun (n, s) -> - Stdlib.Format.fprintf ppf "%s -> %a; " n Pprint.pp_scheme s); - Stdlib.Format.fprintf ppf "|}%!" - ;; - - let find_exn name xs = List.Assoc.find_exn ~equal:String.equal xs name -end - -open R -open R.Syntax -open Ast - -let unify = Subst.unify -let unify_with_tyexpr = Subst.unify_with_tyexpr -let fresh_var = fresh >>| fun n -> Ty_var n - -let instantiate : scheme -> ty R.t = - fun (S (bs, t)) -> - VarSet.fold_left_m - (fun typ name -> - let* f1 = fresh_var in - let* s = Subst.singleton name f1 in - return (Subst.apply s typ)) - bs - (return t) -;; - -let generalize : TypeEnv.t -> Type.t -> Scheme.t = - fun env ty -> - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - S (free, ty) -;; - -let lookup_env e xs = - match Base.List.Assoc.find_exn xs ~equal:String.equal e with - | (exception Stdlib.Not_found) | (exception Base.Not_found_s _) -> fail (`No_variable e) - | scheme -> - let* ans = instantiate scheme in - return (Subst.empty, ans) -;; - -let pp_env subst ppf env = - let env : TypeEnv.t = - List.map (fun (k, S (args, v)) -> k, S (args, Subst.apply subst v)) env - in - TypeEnv.pp ppf env -;; - -let uncover_item = function - | t :: [] -> return t - | _ -> fail `Unexpected_error -;; - -let infer = - let rec (helper : TypeEnv.t -> Ast.expr -> (Subst.t * ty list) R.t) = - fun env -> function - | EInt _ -> return (Subst.empty, [ TyInt ]) - | EBool _ -> return (Subst.empty, [ TyBool ]) - | EString _ -> return (Subst.empty, [ TyString ]) - | EVar (name, ex_type) -> - let* s, t = lookup_env name env in - let* s' = - match run (unify_with_tyexpr ex_type t) with - | Result.Error _ -> fail (`Unapplicable_type (ex_type, t)) - | Ok subst -> return subst - in - let* s = Subst.compose s s' in - return (s, [ t ]) - | EBinOp (op, e1, e2) -> - let* s1, t1 = helper env e1 in - let* t1 = uncover_item t1 in - let env' = TypeEnv.apply s1 env in - let* s2, t2 = helper env' e2 in - let* t2 = uncover_item t2 in - let* s3, result_type = - match op with - | Add | Sub | Mul | Div -> - let* s1 = unify t1 TyInt in - let* s2 = unify t2 TyInt in - let* final_subst = Subst.compose_all [ s1; s2 ] in - return (final_subst, TyInt) - | And | Or -> - let* s1 = unify t1 TyBool in - let* s2 = unify t2 TyBool in - let* final_subst = Subst.compose_all [ s1; s2 ] in - return (final_subst, TyBool) - | Eq | Neq | Lt | Gt | Le | Ge -> - let* s = unify t1 t2 in - return (s, TyBool) - in - let* final_subst = Subst.compose_all [ s3; s2; s1 ] in - return (final_subst, [ Subst.apply final_subst result_type ]) - | EFun (PVar (x, _), e1) -> - let* tv = fresh_var in - let env2 = TypeEnv.extend env (x, S (VarSet.empty, tv)) in - let* s, ty = helper env2 e1 in - let* ty = uncover_item ty in - let trez = Arrow (Subst.apply s tv, ty) in - return (s, [ trez ]) - | EApp (e1, e2) -> - let* s1, t1 = helper env e1 in - let* t1 = uncover_item t1 in - let* s2, t2 = helper (TypeEnv.apply s1 env) e2 in - let* t2 = uncover_item t2 in - let* tv = fresh_var in - let* s3 = unify (Subst.apply s2 t1) (Arrow (t2, tv)) in - let trez = Subst.apply s3 tv in - let* final_subst = Subst.compose_all [ s3; s2; s1 ] in - return (final_subst, [ trez ]) - | ETuple exprs -> - let infer_list = - List.fold_left - (fun acc t -> - let* sub, typ = acc in - let* s, t = helper env t in - let* t = uncover_item t in - return (s :: sub, t :: typ)) - (return ([], [])) - exprs - in - let* s, t = infer_list in - let* final_subst = Subst.compose_all s in - return (final_subst, [ TyTuple (List.rev t) ]) - | EList exprs -> - let* fresh_tv = fresh_var in - let rec infer_list acc = function - | [] -> return (acc, TyList fresh_tv) - | hd :: tl -> - let* sub, ty = helper env hd in - let* ty = uncover_item ty in - let* sub2 = Subst.unify ty fresh_tv in - let* sub = Subst.compose sub sub2 in - infer_list (sub :: acc) tl - in - let* sub, ty = infer_list [] exprs in - let* sub = Subst.compose_all sub in - let ty = Subst.apply sub ty in - return (sub, [ ty ]) - | ESome e -> - let* s, t = helper env e in - let* t = uncover_item t in - return (s, [ TyOption t ]) - | ENone -> - let* tv = fresh_var in - return (Subst.empty, [ TyOption tv ]) - | ELet (Recursive, bindings, body) -> - let extend_env env (PVar (x, _)) = - let* fresh_tv = fresh_var in - return (TypeEnv.extend env (x, S (VarSet.empty, fresh_tv)), fresh_tv) - in - let* initial_env, fresh_types = - List.fold_left - (fun acc (p, _) -> - let* env, fresh_tvs = acc in - let* env', fresh_tv = extend_env env p in - return (env', fresh_tv :: fresh_tvs)) - (return (env, [])) - bindings - in - let infer_bindings env bindings fresh_types = - List.fold_left2 - (fun acc (pattern, expr) fresh_type -> - let* env', s_acc = acc in - let* s, t = helper env' expr in - let* t = uncover_item t in - let* s = Subst.compose s_acc s in - match pattern with - | PVar (name, pat_type) -> - let* s' = - match run (unify_with_tyexpr pat_type t) with - | Result.Error _ -> fail (`Unapplicable_type (pat_type, t)) - | Ok subst -> return subst - in - let* s = Subst.compose s s' in - let* s' = unify (Subst.apply s fresh_type) t in - let* s = Subst.compose s' s in - let env = TypeEnv.apply s env' in - let generalized_type = generalize env (Subst.apply s fresh_type) in - let env = TypeEnv.(extend (apply s env) (name, generalized_type)) in - return (env, s)) - (return (env, Subst.empty)) - bindings - (List.rev fresh_types) - in - let* extended_env, final_subst = infer_bindings initial_env bindings fresh_types in - let* s, t = - match body with - | Some expr_body -> - let* s_body, t_body = helper extended_env expr_body in - let* t_body = uncover_item t_body in - let* final_subst' = Subst.compose s_body final_subst in - return (final_subst', [ t_body ]) - | None -> - let find_type env bindings = - List.fold_left - (fun acc (pattern, _) -> - let* acc' = acc in - match pattern with - | PVar (name, _) -> - let* _, t = lookup_env name env in - return (t :: acc')) - (return []) - bindings - in - let* types = find_type extended_env bindings in - return (final_subst, List.rev types) - in - return (s, t) - | ELet (NonRecursive, bindings, body) -> - let infer_bindings env bindings = - List.fold_left - (fun acc (pattern, expr) -> - let* env', acc' = acc in - let* s, t = helper env' expr in - let* t = uncover_item t in - let env' = TypeEnv.apply s env' in - match pattern with - | PVar (name, pat_type) -> - let* s' = - match run (unify_with_tyexpr pat_type t) with - | Result.Error _ -> fail (`Unapplicable_type (pat_type, t)) - | Ok subst -> return subst - in - let* s'' = Subst.compose s s' in - let env'' = TypeEnv.apply s'' env' in - let generalized_type = generalize env'' t in - let* composed_s = Subst.compose s'' acc' in - return (TypeEnv.extend env'' (name, generalized_type), composed_s)) - (return (env, Subst.empty)) - bindings - in - let* extended_env, substs = infer_bindings env bindings in - let* s, t = - match body with - | Some expr_body -> - let* s_body, t_body = helper extended_env expr_body in - let* t_body = uncover_item t_body in - let* final_subst' = Subst.compose s_body substs in - return (final_subst', [ t_body ]) - | None -> - let find_type env bindings = - List.fold_left - (fun acc (pattern, _) -> - let* acc' = acc in - match pattern with - | PVar (name, _) -> - let* _, t = lookup_env name env in - return (t :: acc')) - (return []) - bindings - in - let* types = find_type extended_env bindings in - return (substs, List.rev types) - in - return (s, t) - | EIf (c, th, el) -> - let* s1, t1 = helper env c in - let* t1 = uncover_item t1 in - let* s2, t2 = helper env th in - let* t2 = uncover_item t2 in - let* s3, t3 = helper env el in - let* t3 = uncover_item t3 in - let* s4 = unify t1 TyBool in - let* s5 = unify t2 t3 in - let* final_subst = Subst.compose_all [ s5; s4; s3; s2; s1 ] in - return (final_subst, [ Subst.apply s5 t2 ]) - in - helper -;; - -let w e = Result.map snd (run (infer TypeEnv.empty e)) -let show_ty_list l = List.fold_left (fun acc t -> acc ^ show_ty t) "" l - -let test_infer subst = - match w subst with - | Result.Error er -> pp_error Format.std_formatter er - | Ok subst -> print_endline (show_ty_list subst) -;; - -let%expect_test "infer: int" = - test_infer (EInt 5); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: bool" = - test_infer (EBool true); - [%expect {| TyBool |}] -;; - -let%expect_test "infer: bool" = - test_infer (EString "Hi!"); - [%expect {| TyString |}] -;; - -(* Test EVar *) -let test_var str env = - match Result.map snd (run (lookup_env str env)) with - | Result.Error er -> pp_error Format.std_formatter er - | Ok subst -> print_endline (show_ty subst) -;; - -let%expect_test "infer: lookup_env: var" = - let env = TypeEnv.extend TypeEnv.empty ("x", S (VarSet.empty, TyBool)) in - test_var "x" env; - [%expect {| TyBool |}] -;; - -let%expect_test "infer: lookup_env: var" = - test_var "x" TypeEnv.empty; - [%expect {| Type Checker Error: undefined variable 'x' |}] -;; - -(* Test EBinOp *) -let%expect_test "infer: binOp int int" = - test_infer (EBinOp (Add, EInt 1, EInt 2)); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp bool bool" = - test_infer (EBinOp (And, EBool true, EBool false)); - [%expect {| TyBool |}] -;; - -let%expect_test "infer: binOp a a bool" = - test_infer (EBinOp (Eq, EBool true, EBool false)); - [%expect {| TyBool |}] -;; - -let%expect_test "infer: binOp a a int" = - test_infer (EBinOp (Eq, EInt 5, EInt 4)); - [%expect {| TyBool |}] -;; - -let%expect_test "infer: binOp dif types fail" = - test_infer (EBinOp (Eq, EBool true, EInt 4)); - [%expect {| Type Checker Error: unification failed on bool and int |}] -;; - -let%expect_test "infer: binOp wrong types fail" = - test_infer (EBinOp (Add, EBool true, EBool false)); - [%expect {| Type Checker Error: unification failed on bool and int |}] -;; - -let%expect_test "infer: binOp wrong types fail" = - test_infer (EBinOp (And, EInt 4, EInt 7)); - [%expect {| Type Checker Error: unification failed on int and bool |}] -;; - -(* Test EFun *) -let%expect_test "infer: fun basic" = - test_infer (EFun (PVar ("x", None), EBinOp (Add, EVar ("x", None), EInt 1))); - [%expect {| (Arrow (TyInt, TyInt)) |}] -;; - -let%expect_test "infer: fun multiple" = - test_infer - (EFun - ( PVar ("x", None) - , EFun (PVar ("y", None), EBinOp (Add, EVar ("x", None), EVar ("y", None))) )); - [%expect {| (Arrow (TyInt, (Arrow (TyInt, TyInt)))) |}] -;; - -(* Test ELet NonRec *) -let%expect_test "infer: binOp let basic" = - test_infer (ELet (NonRecursive, [ PVar ("x", None), EInt 5 ], Some (EVar ("x", None)))); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp multi let" = - test_infer - (ELet - ( NonRecursive - , [ PVar ("x", None), EBinOp (Add, EInt 5, EInt 1) - ; PVar ("y", None), EBinOp (Add, EInt 6, EInt 2) - ] - , Some (EBinOp (Add, EVar ("x", None), EVar ("y", None))) )); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp included let" = - test_infer - (ELet - ( NonRecursive - , [ PVar ("x", None), EInt 5 ] - , Some - (ELet - ( NonRecursive - , [ PVar ("y", None), EBinOp (Add, EVar ("x", None), EInt 5) ] - , Some (EVar ("y", None)) )) )); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp let basic" = - test_infer (ELet (Recursive, [ PVar ("x", None), EInt 5 ], Some (EVar ("x", None)))); - [%expect {| TyInt |}] -;; - -(* Test ELet Rec *) -let%expect_test "infer: binOp let basic" = - test_infer (ELet (Recursive, [ PVar ("x", None), EInt 5 ], Some (EVar ("x", None)))); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp included let" = - test_infer - (ELet - ( Recursive - , [ PVar ("x", None), EInt 5 ] - , Some - (ELet - ( NonRecursive - , [ PVar ("y", None), EBinOp (Add, EVar ("x", None), EInt 5) ] - , Some (EVar ("y", None)) )) )); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: binOp let basic" = - test_infer (ELet (Recursive, [ PVar ("x", None), EInt 5 ], Some (EVar ("x", None)))); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: let recursive" = - test_infer - (ELet - ( Recursive - , [ ( PVar ("fact", None) - , EFun - ( PVar ("n", None) - , EBinOp (Add, EVar ("n", None), EApp (EVar ("fact", None), EInt 4)) ) ) - ] - , Some (EApp (EVar ("fact", None), EInt 5)) )); - [%expect {| TyInt |}] -;; - -(* Test ETuple *) -let%expect_test "infer: tuple with int and bool" = - test_infer (ETuple [ EInt 42; EBool true ]); - [%expect {| (TyTuple [TyInt; TyBool]) |}] -;; - -let%expect_test "infer: tuple with two ints" = - test_infer (ETuple [ EInt 1; EInt 2 ]); - [%expect {| (TyTuple [TyInt; TyInt]) |}] -;; - -let%expect_test "infer: nested tuple" = - test_infer (ETuple [ EInt 1; ETuple [ EBool true; EString "Hello" ] ]); - [%expect {| (TyTuple [TyInt; (TyTuple [TyBool; TyString])]) |}] -;; - -(* Test EList *) -let%expect_test "infer: list of ints" = - test_infer (EList [ EInt 1; EInt 2; EInt 3 ]); - [%expect {| (TyList TyInt) |}] -;; - -let%expect_test "infer: empty list" = - test_infer (EList []); - [%expect {| (TyList (Ty_var 0)) |}] -;; - -let%expect_test "infer: list with mixed types" = - test_infer (EList [ EInt 1; EBool true; EString "Test" ]); - [%expect {| Type Checker Error: unification failed on bool and string |}] -;; - -let%expect_test "infer: nested list" = - test_infer (EList [ EList [ EInt 1; EInt 2 ]; EList [ EInt 3; EInt 4 ] ]); - [%expect {| (TyList (TyList TyInt)) |}] -;; - -(* Test ESome ENone *) -let%expect_test "infer: Some with bool" = - test_infer (ESome (EBool true)); - [%expect {| (TyOption TyBool) |}] -;; - -let%expect_test "infer: Some with None" = - test_infer (ESome ENone); - [%expect {| (TyOption (TyOption (Ty_var 0))) |}] -;; - -let%expect_test "infer: None" = - test_infer ENone; - [%expect {| (TyOption (Ty_var 0)) |}] -;; - -(* Parsed type testing *) -let%expect_test "infer: non-recursive let with TInt" = - test_infer - (ELet (NonRecursive, [ PVar ("x", Some TInt), EInt 42 ], Some (EVar ("x", None)))); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: non-recursive let type mismatch TInt vs TBool" = - test_infer - (ELet (NonRecursive, [ PVar ("x", Some TBool), EInt 42 ], Some (EVar ("x", None)))); - [%expect {| Type Checker Error: expression has type int but expected bool |}] -;; - -let%expect_test "infer: non-recursive let with tuple type (TInt * TBool)" = - test_infer - (ELet - ( NonRecursive - , [ PVar ("y", Some (TTuple [ TInt; TBool ])), ETuple [ EInt 1; EBool true ] ] - , Some (EVar ("y", None)) )); - [%expect {| (TyTuple [TyInt; TyBool]) |}] -;; - -let%expect_test "infer: non-recursive let with incorrect tuple type (TInt * TString)" = - test_infer - (ELet - ( NonRecursive - , [ PVar ("y", Some (TTuple [ TInt; TString ])), ETuple [ EInt 1; EBool true ] ] - , Some (EVar ("y", None)) )); - [%expect - {| Type Checker Error: expression has type (int * bool) but expected (int * string) |}] -;; - -let%expect_test "infer: recursive let with TFun TInt -> TInt" = - test_infer - (ELet - ( Recursive - , [ ( PVar ("f", Some (TFun (TInt, TInt))) - , EFun (PVar ("x", Some TInt), EBinOp (Add, EVar ("x", None), EInt 1)) ) - ] - , Some (EVar ("f", None)) )); - [%expect {| (Arrow (TyInt, TyInt)) |}] -;; - -let%expect_test "infer: recursive let with incorrect TFun TString -> TInt" = - test_infer - (ELet - ( Recursive - , [ ( PVar ("f", Some (TFun (TString, TInt))) - , EFun (PVar ("x", Some TInt), EBinOp (Add, EVar ("x", None), EInt 1)) ) - ] - , Some (EVar ("f", None)) )); - [%expect - {| Type Checker Error: expression has type (int -> int) but expected (string -> int) |}] -;; - -let%expect_test "infer: recursive let with TFun TOption TInt -> TInt" = - test_infer - (ELet - ( Recursive - , [ ( PVar ("f", Some (TFun (TOption TInt, TInt))) - , EFun - (PVar ("x", Some (TOption TInt)), EApp (EVar ("f", None), ESome (EInt 5))) - ) - ] - , Some (EVar ("f", None)) )); - [%expect {| (Arrow ((TyOption TyInt), TyInt)) |}] -;; - -(* Test EIf *) - -let%expect_test "infer: if-then-else with TInt branches" = - test_infer (EIf (EBool true, EInt 1, EInt 0)); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: if-then-else with mismatched branch types" = - test_infer (EIf (EBool true, EInt 1, EBool false)); - [%expect {| Type Checker Error: unification failed on int and bool |}] -;; - -let%expect_test "infer: if-then-else with variable condition" = - test_infer - (ELet - ( NonRecursive - , [ PVar ("x", Some TInt), EInt 10 ] - , Some (EIf (EBinOp (Gt, EVar ("x", None), EInt 5), EInt 1, EInt 0)) )); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: nested if-then-else" = - test_infer (EIf (EBool true, EIf (EBool false, EInt 1, EInt 2), EInt 3)); - [%expect {| TyInt |}] -;; - -let%expect_test "infer: if-then-else with function branches" = - test_infer - (EIf - ( EBool true - , EFun (PVar ("x", Some TInt), EBinOp (Add, EVar ("x", None), EInt 1)) - , EFun (PVar ("y", Some TInt), EBinOp (Sub, EVar ("y", None), EInt 1)) )); - [%expect {| (Arrow (TyInt, TyInt)) |}] -;; diff --git a/Ocaml/lib/inferencer.mli b/Ocaml/lib/inferencer.mli deleted file mode 100644 index 47c6fc7b5..000000000 --- a/Ocaml/lib/inferencer.mli +++ /dev/null @@ -1,156 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val use_logging : bool -val log : ('a, Format.formatter, unit, unit) format4 -> 'a - -type error = - [ `No_variable of string - | `Occurs_check - | `Unapplicable_type of Ast.type_expr option * Typedtree.ty - | `Unexpected_error - | `Unification_failed of Typedtree.ty * Typedtree.ty - ] - -val pp_error : Format.formatter -> error -> unit - -module R : sig - type 'a t - - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val return : 'a -> 'a t - val fail : error -> 'a t - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - end - - val fresh : int t - val run : 'a t -> ('a, error) result -end - -type fresh = int - -module Type : sig - type t = Typedtree.ty - - val occurs_in : fresh -> Typedtree.ty -> bool - val free_vars : Typedtree.ty -> Typedtree.binder_set -end - -module Subst : sig - type t - - val pp : Format.formatter -> t -> unit - val empty : t - val singleton : fresh -> Typedtree.ty -> t R.t - val find_exn : fresh -> t -> Typedtree.ty - val find : fresh -> t -> Typedtree.ty option - val apply : t -> Typedtree.ty -> Typedtree.ty - val unify : Typedtree.ty -> Typedtree.ty -> t R.t - val unify_with_tyexpr : Ast.type_expr option -> Typedtree.ty -> t R.t - val compose : t -> t -> t R.t - val compose_all : t list -> t R.t - val remove : t -> fresh -> t -end - -module VarSet : sig - type elt = fresh - type t = Typedtree.binder_set - - val empty : t - val is_empty : t -> bool - val mem : elt -> t -> bool - val add : elt -> t -> t - val singleton : elt -> t - val remove : elt -> t -> t - val union : t -> t -> t - val inter : t -> t -> t - val disjoint : t -> t -> bool - val diff : t -> t -> t - val compare : t -> t -> fresh - val equal : t -> t -> bool - val subset : t -> t -> bool - val iter : (elt -> unit) -> t -> unit - val map : (elt -> elt) -> t -> t - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a - val for_all : (elt -> bool) -> t -> bool - val exists : (elt -> bool) -> t -> bool - val filter : (elt -> bool) -> t -> t - val filter_map : (elt -> elt option) -> t -> t - val partition : (elt -> bool) -> t -> t * t - val cardinal : t -> fresh - val elements : t -> elt list - val min_elt : t -> elt - val min_elt_opt : t -> elt option - val max_elt : t -> elt - val max_elt_opt : t -> elt option - val choose : t -> elt - val choose_opt : t -> elt option - val split : elt -> t -> t * bool * t - val find : elt -> t -> elt - val find_opt : elt -> t -> elt option - val find_first : (elt -> bool) -> t -> elt - val find_first_opt : (elt -> bool) -> t -> elt option - val find_last : (elt -> bool) -> t -> elt - val find_last_opt : (elt -> bool) -> t -> elt option - val of_list : elt list -> t - val to_seq_from : elt -> t -> elt Seq.t - val to_seq : t -> elt Seq.t - val to_rev_seq : t -> elt Seq.t - val add_seq : elt Seq.t -> t -> t - val of_seq : elt Seq.t -> t - val pp : Format.formatter -> t -> unit - val fold_left_m : ('a -> elt -> 'a R.t) -> t -> 'a R.t -> 'a R.t -end - -module Scheme : sig - type t = Typedtree.scheme - - val occurs_in : fresh -> Typedtree.scheme -> bool - val free_vars : Typedtree.scheme -> VarSet.t - val apply : Subst.t -> Typedtree.scheme -> Typedtree.scheme - val pp : Format.formatter -> Typedtree.scheme -> unit -end - -module TypeEnv : sig - type t = (string * Typedtree.scheme) list - - val extend : 'a list -> 'a -> 'a list - val empty : 'a list - val free_vars : t -> VarSet.t - - val apply - : Subst.t - -> ('a, Typedtree.scheme) Base.List.Assoc.t - -> ('a, Typedtree.scheme) Base.List.Assoc.t - - val pp : Format.formatter -> (string * Typedtree.scheme) list -> unit - val find_exn : string -> (string, 'a) Base.List.Assoc.t -> 'a -end - -val unify : Typedtree.ty -> Typedtree.ty -> Subst.t R.t -val unify_with_tyexpr : Ast.type_expr option -> Typedtree.ty -> Subst.t R.t -val fresh_var : Typedtree.ty R.t -val instantiate : Typedtree.scheme -> Typedtree.ty R.t -val generalize : TypeEnv.t -> Type.t -> Scheme.t - -val lookup_env - : string - -> (string, Typedtree.scheme) Base.List.Assoc.t - -> (Subst.t * Typedtree.ty) R.t - -val pp_env : Subst.t -> Format.formatter -> (string * Typedtree.scheme) list -> unit -val uncover_item : 'a list -> 'a R.t -val infer : TypeEnv.t -> Ast.expr -> (Subst.t * Typedtree.ty list) R.t -val w : Ast.expr -> (Typedtree.ty list, error) result -val show_ty_list : Typedtree.ty list -> string -val test_infer : Ast.expr -> unit -val test_var : string -> (string, Typedtree.scheme) Base.List.Assoc.t -> unit diff --git a/Ocaml/lib/interpreter.ml b/Ocaml/lib/interpreter.ml deleted file mode 100644 index 802f05fe0..000000000 --- a/Ocaml/lib/interpreter.ml +++ /dev/null @@ -1,573 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - [ `Unfound_var of string - | `Unexpected_error - | `Division_by_zero - ] - -let pp_error ppf : error -> _ = function - | `Unfound_var name -> - Format.fprintf - ppf - "Interpreter Error: couldn't find \"%a\"" - Format.pp_print_string - name - | `Unexpected_error -> Format.fprintf ppf "Interpreter Error: unexpected error" - | `Division_by_zero -> Format.fprintf ppf "Interpreter Error: division by zero" -;; - -module R : sig - type 'a t = ('a, error) Result.t - - val bind : 'a t -> f:('a -> 'b t) -> 'b t - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end -end = struct - type 'a t = ('a, error) Result.t - - let ( >>= ) e1 e2 = - match e1 with - | Result.Error x -> Result.Error x - | Ok a -> e2 a - ;; - - let return x = Result.Ok x - let fail e = Result.Error e - let bind x ~f = x >>= f - - let ( >>| ) e f = - match e with - | Result.Error x -> Result.Error x - | Ok a -> Result.Ok (f a) - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end -end - -module Interpret = struct - open R - open R.Syntax - - module Env : sig - include Map.S with type key = string - - val pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit - val find : 'a t -> key -> 'a R.t - end = struct - include Map.Make (String) - - let find map name = - match find_opt name map with - | Some v -> return v - | None -> fail (`Unfound_var name) - ;; - - let pp pp_v ppf m = - Format.(iter (fun k -> fprintf ppf "@[%a=%a@] " pp_print_string k pp_v) m) - ;; - end - - type value = - | VConst of expr - | VClosure of string option * value Env.t * expr - | VRecClosure of string option * value Env.t * string list * expr - | VDeclaration of (string * expr) list - [@@deriving show { with_path = false }] - - let eval = - let rec helper env = function - | EInt n -> return (VConst (EInt n)) - | EBool b -> return (VConst (EBool b)) - | EString s -> return (VConst (EString s)) - | EBinOp (op, e1, e2) -> - let* e1 = helper env e1 in - let* e2 = helper env e2 in - (match e1, e2 with - | VConst e1', VConst e2' -> eval_binop (op, e1', e2') - | _ -> fail `Unexpected_error) - | EVar (name, _) -> Env.find env name - | EFun (pattern, body) -> return (VClosure (None, env, EFun (pattern, body))) - | ELet (NonRecursive, bindings, body) -> - let* env_with_bindings = - List.fold_left - (fun acc (PVar (x, _), e) -> - let* acc' = acc in - let* v = helper acc' e in - return (Env.add x v acc')) - (return env) - bindings - in - (match body with - | Some e -> helper env_with_bindings e - | None -> - let* list_let = - List.fold_left - (fun acc (PVar (name, _), _) -> - let* acc' = acc in - let* v = Env.find env_with_bindings name in - match v with - | VConst e -> return ((name, e) :: acc') - | VClosure (_, _, b) -> return ((name, b) :: acc') - | _ -> fail `Unexpected_error) - (return []) - bindings - in - return (VDeclaration (List.rev list_let))) - | ELet (Recursive, bindings, body) -> - let func_list = List.map (fun (PVar (name, _), _) -> name) bindings in - let* placeholder_env = - List.fold_left - (fun acc (PVar (name, _), e) -> - let* acc' = acc in - let* v = - match e with - | EFun (_, _) as ex -> return (VRecClosure (None, env, func_list, ex)) - | _ -> helper acc' e - in - return (Env.add name v acc')) - (return env) - bindings - in - (match body with - | Some expr -> helper placeholder_env expr - | None -> - let* list_let = - List.fold_left - (fun acc (PVar (name, _), _) -> - let* acc' = acc in - let* v = Env.find placeholder_env name in - match v with - | VConst e -> return ((name, e) :: acc') - | VRecClosure (_, _, _, b) -> return ((name, b) :: acc') - | _ -> fail `Unexpected_error) - (return []) - bindings - in - return (VDeclaration (List.rev list_let))) - | EApp (fn, arg) -> - let* arg_val = helper env arg in - helper env fn - >>= (function - | VClosure (_, closure_env, EFun (PVar (par, _), body)) -> - let updated_env = Env.add par arg_val closure_env in - helper updated_env body - | VRecClosure (_, closure_env, recs_list, EFun (PVar (par, _), body)) -> - let updated_env = Env.add par arg_val closure_env in - let* final_env = - List.fold_left - (fun acc s -> - let* acc' = acc in - let* v = Env.find env s in - return (Env.add s v acc')) - (return updated_env) - recs_list - in - helper final_env body - | _ -> fail `Unexpected_error) - | EIf (cond, then_expr, else_expr) -> - let* cond_val = helper env cond in - (match cond_val with - | VConst (EBool true) -> helper env then_expr - | VConst (EBool false) -> helper env else_expr - | _ -> fail `Unexpected_error) - | ETuple ex -> - let* ex_list = - List.fold_left - (fun acc e -> - let* acc' = acc in - let* v = helper env e in - match v with - | VConst x -> return (x :: acc') - | VClosure (_, _, ex) -> return (ex :: acc') - | VRecClosure (_, _, _, ex) -> return (ex :: acc') - | _ -> fail `Unexpected_error) - (return []) - ex - in - return (VConst (ETuple ex_list)) - | EList ex -> - let* ex_list = - List.fold_left - (fun acc e -> - let* acc' = acc in - let* v = helper env e in - match v with - | VConst x -> return (x :: acc') - | VClosure (_, _, ex) -> return (ex :: acc') - | VRecClosure (_, _, _, ex) -> return (ex :: acc') - | _ -> fail `Unexpected_error) - (return []) - ex - in - return (VConst (EList ex_list)) - | ESome ex -> - let* v = helper env ex in - let* ex = - match v with - | VConst x -> return x - | VClosure (_, _, ex) -> return ex - | VRecClosure (_, _, _, ex) -> return ex - | _ -> fail `Unexpected_error - in - return (VConst (ESome ex)) - | ENone -> return (VConst ENone) - and eval_binop = function - | Add, EInt i1, EInt i2 -> return (VConst (EInt (i1 + i2))) - | Sub, EInt i1, EInt i2 -> return (VConst (EInt (i1 - i2))) - | Mul, EInt i1, EInt i2 -> return (VConst (EInt (i1 * i2))) - | Div, EInt i1, EInt i2 -> - (match i2 with - | 0 -> fail `Division_by_zero - | _ -> return (VConst (EInt (i1 / i2)))) - | And, EBool i1, EBool i2 -> return (VConst (EBool (i1 && i2))) - | Or, EBool i1, EBool i2 -> return (VConst (EBool (i1 || i2))) - | Eq, EInt i1, EInt i2 -> return (VConst (EBool (i1 = i2))) - | Eq, EBool i1, EBool i2 -> return (VConst (EBool (i1 = i2))) - | Neq, EInt i1, EInt i2 -> return (VConst (EBool (i1 <> i2))) - | Neq, EBool i1, EBool i2 -> return (VConst (EBool (i1 <> i2))) - | Lt, EInt i1, EInt i2 -> return (VConst (EBool (i1 < i2))) - | Lt, EBool i1, EBool i2 -> return (VConst (EBool (i1 < i2))) - | Gt, EInt i1, EInt i2 -> return (VConst (EBool (i1 > i2))) - | Gt, EBool i1, EBool i2 -> return (VConst (EBool (i1 > i2))) - | Le, EInt i1, EInt i2 -> return (VConst (EBool (i1 <= i2))) - | Le, EBool i1, EBool i2 -> return (VConst (EBool (i1 <= i2))) - | Ge, EInt i1, EInt i2 -> return (VConst (EBool (i1 >= i2))) - | Ge, EBool i1, EBool i2 -> return (VConst (EBool (i1 >= i2))) - | _ -> fail `Unexpected_error - in - helper - ;; -end - -open Interpret - -let interpret ex = eval Env.empty ex - -let test_inter e = - match eval Env.empty e with - | Ok v -> print_endline (show_value v) - | Error e -> pp_error Format.std_formatter e -;; - -let test_inter_wenv env e = - match eval env e with - | Ok v -> print_endline (show_value v) - | Error e -> pp_error Format.std_formatter e -;; - -let%expect_test "infer: int" = - test_inter (EInt 5); - [%expect {| (VConst (EInt 5)) |}] -;; - -let%expect_test "infer: int" = - test_inter (EBool true); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "infer: int" = - test_inter (EString "hello"); - [%expect {| (VConst (EString "hello")) |}] -;; - -(* Binon tests *) -let%expect_test "eval: addition" = - test_inter (EBinOp (Add, EInt 3, EInt 4)); - [%expect {| (VConst (EInt 7)) |}] -;; - -let%expect_test "eval: subtraction" = - test_inter (EBinOp (Sub, EInt 10, EInt 4)); - [%expect {| (VConst (EInt 6)) |}] -;; - -let%expect_test "eval: multiplication" = - test_inter (EBinOp (Mul, EInt 2, EInt 5)); - [%expect {| (VConst (EInt 10)) |}] -;; - -let%expect_test "eval: division" = - test_inter (EBinOp (Div, EInt 10, EInt 2)); - [%expect {| (VConst (EInt 5)) |}] -;; - -let%expect_test "eval: division by zero" = - test_inter (EBinOp (Div, EInt 10, EInt 0)); - [%expect {| Interpreter Error: division by zero |}] -;; - -let%expect_test "eval: logical and" = - test_inter (EBinOp (And, EBool true, EBool false)); - [%expect {| (VConst (EBool false)) |}] -;; - -let%expect_test "eval: logical or" = - test_inter (EBinOp (Or, EBool true, EBool false)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: equality (integers)" = - test_inter (EBinOp (Eq, EInt 3, EInt 3)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: inequality (booleans)" = - test_inter (EBinOp (Neq, EBool true, EBool false)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: less than" = - test_inter (EBinOp (Lt, EInt 2, EInt 5)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: greater than" = - test_inter (EBinOp (Gt, EInt 5, EInt 3)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: less than or equal" = - test_inter (EBinOp (Le, EInt 4, EInt 4)); - [%expect {| (VConst (EBool true)) |}] -;; - -let%expect_test "eval: greater than or equal" = - test_inter (EBinOp (Ge, EInt 6, EInt 6)); - [%expect {| (VConst (EBool true)) |}] -;; - -(* Evar test *) -let%expect_test "EVar: unfound variable" = - test_inter_wenv Env.empty (EVar ("x", None)); - [%expect {| Interpreter Error: couldn't find "x" |}] -;; - -let%expect_test "EVar: found variable" = - let env = Env.add "x" (VConst (EInt 42)) Env.empty in - test_inter_wenv env (EVar ("x", None)); - [%expect {| (VConst (EInt 42)) |}] -;; - -(* EFun test *) -let%expect_test "eval: fun" = - test_inter (EFun (PVar ("x", None), EInt 42)); - [%expect {| (VClosure (None, , (EFun ((PVar ("x", None)), (EInt 42))))) |}] -;; - -(* EApp test *) -let%expect_test "EApp: function application" = - let env = - Env.add - "f" - (VClosure - ( Some "f" - , Env.empty - , EFun (PVar ("x", Some TInt), EBinOp (Add, EVar ("x", None), EInt 1)) )) - Env.empty - in - test_inter_wenv env (EApp (EVar ("f", None), EInt 5)); - [%expect {| (VConst (EInt 6)) |}] -;; - -(* EIf test *) -let%expect_test "interpret if-then-else: true condition" = - let expr = EIf (EBool true, EInt 1, EInt 0) in - test_inter expr; - [%expect {| (VConst (EInt 1)) |}] -;; - -let%expect_test "interpret if-then-else: false condition" = - let expr = EIf (EBool false, EInt 1, EInt 0) in - test_inter expr; - [%expect {| (VConst (EInt 0)) |}] -;; - -let%expect_test "interpret if-then-else: non-boolean condition error" = - let expr = EIf (EInt 5, EInt 1, EInt 0) in - test_inter expr; - [%expect {| Interpreter Error: unexpected error |}] -;; - -(* non rec let test *) -let%expect_test "ELet NonRecursive: multiple definitions without body" = - test_inter_wenv - Env.empty - (ELet - ( NonRecursive - , [ PVar ("f", Some TInt), EInt 0 - ; ( PVar ("g", Some TInt) - , EFun (PVar ("x", None), EBinOp (Add, EVar ("x", None), EInt 1)) ) - ] - , None )); - [%expect - {| - (VDeclaration - [("f", (EInt 0)); - ("g", - (EFun ((PVar ("x", None)), (EBinOp (Add, (EVar ("x", None)), (EInt 1))) - ))) - ]) |}] -;; - -let%expect_test "ELet NonRecursive: multiple definitions without body" = - test_inter_wenv - Env.empty - (ELet - ( NonRecursive - , [ PVar ("f", Some TInt), EInt 0; PVar ("g", Some TInt), EInt 0 ] - , Some (EVar ("f", None)) )); - [%expect {| (VConst (EInt 0)) |}] -;; - -(* rec let test *) -let%expect_test "recursive let: factorial" = - let expr = - ELet - ( Recursive - , [ ( PVar ("fact", None) - , EFun - ( PVar ("n", None) - , EIf - ( EBinOp (Eq, EVar ("n", None), EInt 0) - , EInt 1 - , EBinOp - ( Mul - , EVar ("n", None) - , EApp (EVar ("fact", None), EBinOp (Sub, EVar ("n", None), EInt 1)) - ) ) ) ) - ] - , Some (EApp (EVar ("fact", None), EInt 5)) ) - in - test_inter expr; - [%expect {| (VConst (EInt 120)) |}] -;; - -let%expect_test "recursive let: fibonacci" = - let expr = - ELet - ( Recursive - , [ ( PVar ("fib", None) - , EFun - ( PVar ("n", None) - , EIf - ( EBinOp (Lt, EVar ("n", None), EInt 2) - , EVar ("n", None) - , EBinOp - ( Add - , EApp (EVar ("fib", None), EBinOp (Sub, EVar ("n", None), EInt 1)) - , EApp (EVar ("fib", None), EBinOp (Sub, EVar ("n", None), EInt 2)) - ) ) ) ) - ] - , Some (EApp (EVar ("fib", None), EInt 7)) ) - in - test_inter expr; - [%expect {| (VConst (EInt 13)) |}] -;; - -let%expect_test "recursive let: multiple recursive functions" = - let expr = - ELet - ( Recursive - , [ ( PVar ("even", None) - , EFun - ( PVar ("n", None) - , EIf - ( EBinOp (Eq, EVar ("n", None), EInt 0) - , EInt 1 - , EApp (EVar ("odd", None), EBinOp (Sub, EVar ("n", None), EInt 1)) ) ) - ) - ; ( PVar ("odd", None) - , EFun - ( PVar ("n", None) - , EIf - ( EBinOp (Eq, EVar ("n", None), EInt 0) - , EInt 0 - , EApp (EVar ("even", None), EBinOp (Sub, EVar ("n", None), EInt 1)) ) - ) ) - ] - , Some (EApp (EVar ("even", None), EInt 4)) ) - in - test_inter expr; - [%expect {| (VConst (EInt 1)) |}] -;; - -let%expect_test "recursive let: multiple recursive functions" = - let expr = - ELet - ( Recursive - , [ ( PVar ("even", Some (TFun (TInt, TInt))) - , EFun - ( PVar ("n", Some TInt) - , EIf - ( EBinOp (Eq, EVar ("n", None), EInt 0) - , EInt 1 - , EApp (EVar ("odd", None), EBinOp (Sub, EVar ("n", None), EInt 1)) ) ) - ) - ; ( PVar ("odd", Some (TFun (TInt, TInt))) - , EFun - ( PVar ("n", Some TInt) - , EIf - ( EBinOp (Eq, EVar ("n", None), EInt 0) - , EInt 0 - , EApp (EVar ("even", None), EBinOp (Sub, EVar ("n", None), EInt 1)) ) - ) ) - ] - , None ) - in - test_inter expr; - [%expect - {| - (VDeclaration - [("even", - (EFun ((PVar ("n", (Some TInt))), - (EIf ((EBinOp (Eq, (EVar ("n", None)), (EInt 0))), (EInt 1), - (EApp ((EVar ("odd", None)), - (EBinOp (Sub, (EVar ("n", None)), (EInt 1))))) - )) - ))); - ("odd", - (EFun ((PVar ("n", (Some TInt))), - (EIf ((EBinOp (Eq, (EVar ("n", None)), (EInt 0))), (EInt 0), - (EApp ((EVar ("even", None)), - (EBinOp (Sub, (EVar ("n", None)), (EInt 1))))) - )) - ))) - ]) |}] -;; - -let%expect_test "interpreter: tuple" = - let expr = ETuple [ EInt 1; EInt 2; EInt 3 ] in - test_inter expr; - [%expect {| (VConst (ETuple [(EInt 3); (EInt 2); (EInt 1)])) |}] -;; - -let%expect_test "interpreter: list" = - let expr = EList [ EInt 1; EInt 2; EInt 3 ] in - test_inter expr; - [%expect {| (VConst (EList [(EInt 3); (EInt 2); (EInt 1)])) |}] -;; - -let%expect_test "interpretation of Some expression" = - let expr = ESome (EInt 42) in - test_inter expr; - [%expect {| (VConst (ESome (EInt 42))) |}] -;; - -let%expect_test "interpretation of None expression" = - let expr = ENone in - test_inter expr; - [%expect {| (VConst ENone) |}] -;; diff --git a/Ocaml/lib/interpreter.mli b/Ocaml/lib/interpreter.mli deleted file mode 100644 index a2f763d96..000000000 --- a/Ocaml/lib/interpreter.mli +++ /dev/null @@ -1,32 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - [ `Division_by_zero - | `Unexpected_error - | `Unfound_var of string - ] - -val pp_error : Format.formatter -> error -> unit - -module R : sig - type 'a t = ('a, error) result - - val bind : 'a t -> f:('a -> 'b t) -> 'b t -end - -module Interpret : sig - module Env : sig - type key = string - type +!'a t - end - - type value = - | VConst of Ast.expr - | VClosure of string option * value Env.t * Ast.expr - | VRecClosure of string option * value Env.t * string list * Ast.expr - | VDeclaration of (string * Ast.expr) list -end - -val interpret : Ast.expr -> Interpret.value R.t diff --git a/Ocaml/lib/launcher.ml b/Ocaml/lib/launcher.ml deleted file mode 100644 index 1ec1da617..000000000 --- a/Ocaml/lib/launcher.ml +++ /dev/null @@ -1,208 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Parser -open Inferencer -open Interpreter - -let run input = - match parse input with - | Ok ast -> - (match w ast with - | Ok t -> - (match interpret ast with - | Ok v -> Pprint.pp_val Format.std_formatter t v - | Error e -> Interpreter.pp_error Format.std_formatter e) - | Error err -> Inferencer.pp_error Format.std_formatter err) - | Error e -> Parser.pp_error Format.std_formatter e -;; - -let%expect_test "basic arithmetic" = - run "1 + 2 * 3"; - [%expect {| - : int = 7 |}] -;; - -let%expect_test "arithmetic with parentheses" = - run "(1 + 2) * 3"; - [%expect {| - : int = 9 |}] -;; - -let%expect_test "basic logic" = - run "true && false || true"; - [%expect {| - : bool = true |}] -;; - -let%expect_test "if-then-else true branch" = - run "if 1 < 2 then 42 else 0"; - [%expect {| - : int = 42 |}] -;; - -let%expect_test "if-then-else false branch" = - run "if 2 < 1 then 42 else 0"; - [%expect {| - : int = 0 |}] -;; - -let%expect_test "simple function application" = - run "let f = fun x -> x + 1 in f 5"; - [%expect {| - : int = 6 |}] -;; - -let%expect_test "recursive function - factorial" = - run "let rec fact = fun n -> if n = 0 then 1 else n * fact (n - 1) in fact 5"; - [%expect {| - : int = 120 |}] -;; - -let%expect_test "tuple" = - run "(1, true, \"hello\")"; - [%expect {| - : (int * bool * string) = (1, true, "hello") |}] -;; - -let%expect_test "list of integers" = - run "[1; 2; 3]"; - [%expect {| - : int list = [1; 2; 3] |}] -;; - -let%expect_test "some and none" = - run "Some 42"; - [%expect {| - : int option = Some 42 |}] -;; - -let%expect_test "none option" = - run "None"; - [%expect {| - : '_0 option = None |}] -;; - -let%expect_test "closure captures external variable" = - run "let x = 10 in let f = fun y -> x + y in f 5"; - [%expect {| - : int = 15 |}] -;; - -let%expect_test "closure captures and modifies external variable" = - run "let x = 3 in let f = fun y -> let x = 5 in x + y in f 2"; - [%expect {| - : int = 7 |}] -;; - -let%expect_test "closure with recursive function" = - run - "let rec counter = fun n -> if n = 0 then 0 else 1 + counter (n - 1) in let f = fun \ - x -> counter x in f 3"; - [%expect {| - : int = 3 |}] -;; - -let%expect_test "nested closures" = - run "let add = fun x -> fun y -> x + y in let add_five = add 5 in add_five 10"; - [%expect {| - : int = 15 |}] -;; - -let%expect_test "closure with nested functions and shadowing" = - run - "let x = 1 in let f = fun y -> let g = fun z -> x + y + z in g 5 in let x = 10 in f 3"; - [%expect {| - : int = 9 |}] -;; - -let%expect_test "closure with argument passing" = - run - "let make_adder = fun x -> fun y -> x + y in let add_ten = make_adder 10 in add_ten \ - 20"; - [%expect {| - : int = 30 |}] -;; - -let%expect_test "closure remembers state at creation" = - run "let x = 2 in let f = fun y -> x + y in let x = 10 in f 3"; - [%expect {| - : int = 5 |}] -;; - -let%expect_test "partial application returns closure" = - run "let add = fun x -> fun y -> x + y in add 5"; - [%expect {| - : (int -> int) = |}] -;; - -let%expect_test "partial application within nested functions" = - run - "let multiply = fun x -> fun y -> x * y in let double = multiply 2 in let triple = \ - multiply 3 in (double 10, triple 10)"; - [%expect {| - : (int * int) = (20, 30) |}] -;; - -let%expect_test "partial application type inference" = - run "let make_adder = fun x -> fun y -> x + y in let add_ten = make_adder 10 in add_ten"; - [%expect {| - : (int -> int) = |}] -;; - -let%expect_test "partial application followed by application" = - run - "let subtract = fun x -> fun y -> x - y in let minus_five = subtract 5 in minus_five \ - 3"; - [%expect {| - : int = 2 |}] -;; - -let%expect_test "returning closure as function result" = - run - "let create_multiplier = fun x -> fun y -> x * y in let multiplier_of_two = \ - create_multiplier 2 in multiplier_of_two"; - [%expect {| - : (int -> int) = |}] -;; - -let%expect_test "simple non-recursive value declaration" = - run "let x = 42"; - [%expect {| val x : int = 42 |}] -;; - -let%expect_test "recursive function declaration" = - run "let rec f = fun x -> if x = 0 then 1 else x * f (x - 1) "; - [%expect {| val f : (int -> int) = |}] -;; - -let%expect_test "simple non-recursive function declaration" = - run "let f = fun x -> x + 1"; - [%expect {| val f : (int -> int) = |}] -;; - -let%expect_test "simple non-recursive value and function declarations" = - run "let x = 10 and f = fun y -> x + y"; - [%expect {| - val x : int = 10 - val f : (int -> int) = |}] -;; - -let%expect_test "multiple recursive function declarations" = - run - "let rec f = fun x -> if x = 0 then 1 else x * f (x - 1) in let rec g = fun x -> if \ - x = 0 then 2 else x + g (x - 1)"; - [%expect {| val g : (int -> int) = |}] -;; - -let%expect_test "recursive function declaration without body" = - run "let rec f = fun x -> if x = 0 then 1 else x * f (x - 1)"; - [%expect {| val f : (int -> int) = |}] -;; - -let%expect_test "multiple non-recursive value declarations" = - run "let x = 10 and y = 20 and z = x + y"; - [%expect {| - val x : int = 10 - val y : int = 20 - val z : int = 30 |}] -;; - -let%expect_test "multiple non-recursive function declarations" = - run "let f = fun x -> x + 1 and g = fun y -> y * 2"; - [%expect {| - val f : (int -> int) = - val g : (int -> int) = |}] -;; - -let%expect_test "multiple non-recursive function declarations" = - run "let f = fun x -> x + 1"; - [%expect {| - val f : (int -> int) = |}] -;; - -let%expect_test "fixed point combinator test" = - run - "let rec y f x = f (y f) x in let factorial fac n = if n = 1 then 1 else n * fac (n \ - - 1) in y factorial 5"; - [%expect {| - - : int = 120 |}] -;; diff --git a/Ocaml/lib/launcher.mli b/Ocaml/lib/launcher.mli deleted file mode 100644 index 000c6863f..000000000 --- a/Ocaml/lib/launcher.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run : string -> unit diff --git a/Ocaml/lib/parser.ml b/Ocaml/lib/parser.ml deleted file mode 100644 index 5abb2ac7e..000000000 --- a/Ocaml/lib/parser.ml +++ /dev/null @@ -1,772 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast -open Result - -type error = - [ `Parsing_Error of string - | `Some_Error - ] - -let pp_error ppf : error -> _ = function - | `Parsing_Error msg -> Format.fprintf ppf "Parser Error: %s" msg - | `Some_Error -> Format.fprintf ppf "Parser Error:" -;; - -(* Tools for parsers*) -let spaces = skip_many (char ' ' <|> char '\t' <|> char '\n') -let parens parse_expr = char '(' *> spaces *> parse_expr <* spaces <* char ')' -let with_spaces parse_expr = spaces *> parse_expr <* spaces - -(* functions for chains of operations *) -let chainl1 p op = - let rec go acc = lift2 (fun f x -> f acc x) op p >>= go <|> return acc in - p >>= go -;; - -let chainl1_pat p op = - let rec go acc = lift (fun f -> f acc) op >>= go <|> return acc in - p >>= go -;; - -let chainr1 p op = - let rec go acc = - op - >>= (fun f -> p >>= fun x -> go x >>= fun result -> return (f acc result)) - <|> return acc - in - p >>= go -;; - -(* type_expr parsing *) -let parse_type_int = string "int" >>| fun _ -> TInt -let parse_type_bool = string "bool" >>| fun _ -> TBool -let parse_type_string = string "string" >>| fun _ -> TString - -let parse_keyword_list_opt = - choice - [ (string "list" >>| fun _ t -> TList t); (string "option" >>| fun _ t -> TOption t) ] -;; - -let parse_type_expr = - fix (fun parse_type_expr -> - let term = - choice - [ parse_type_int; parse_type_bool; parse_type_string; parens parse_type_expr ] - in - let parse_type_list_opt = chainl1_pat term (spaces *> parse_keyword_list_opt) in - let parse_type_tuple = - lift2 - (fun head tail -> TTuple (head :: tail)) - parse_type_list_opt - (many1 (with_spaces (string "*") *> parse_type_list_opt)) - <|> parse_type_list_opt - in - let parse_type_fun = - chainr1 parse_type_tuple (with_spaces (string "->") >>| fun _ a b -> TFun (a, b)) - in - parse_type_fun) -;; - -(* name of variable parsing *) -let is_first_letter = function - | 'a' .. 'z' | 'A' .. 'Z' | '_' -> true - | _ -> false -;; - -let is_letter_or_digit_or_underscore = function - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' -> true - | _ -> false -;; - -let keywords = - [ "in" - ; "let" - ; "rec" - ; "fun" - ; "true" - ; "false" - ; "and" - ; "Some" - ; "None" - ; "if" - ; "then" - ; "else" - ] -;; - -let is_keyword s = List.mem s keywords - -let variable = - satisfy is_first_letter - >>= fun first_char -> - take_while is_letter_or_digit_or_underscore - >>= fun rest -> - let ident = String.make 1 first_char ^ rest in - if is_keyword ident - then fail "Error: Syntax error: variable should not use a keyword name" - else return ident -;; - -(* Variable or typed variable parsing *) -let parse_typed_var = - parens - (variable - >>= fun n -> with_spaces (char ':') *> parse_type_expr >>| fun t -> n, Some t) - <|> (variable >>| fun n -> n, None) -;; - -(* pattern parsing *) -let parse_pattern = parse_typed_var >>| fun (n, t) -> PVar (n, t) - -(* rec_flag parsing *) -let parse_rec_flag = option NonRecursive (string "rec" >>| fun _ -> Recursive) - -(* IntLiteral parsing *) -let integer_literal_parser = - take_while1 (function - | '0' .. '9' -> true - | _ -> false) - >>| fun s -> EInt (int_of_string s) -;; - -(* BoolLiteral parsing*) -let boolean_literal_parser = - string "true" >>| (fun _ -> EBool true) <|> (string "false" >>| fun _ -> EBool false) -;; - -(* Var parsing*) -let var_literal_parser = parse_typed_var >>| fun (n, t) -> EVar (n, t) - -(* StringLiteral parsing*) -let string_literal_parser = - char '"' *> take_while (fun c -> c <> '"') <* char '"' >>| fun s -> EString s -;; - -(* BinaryOp parsing *) -let mul_div_literal = - choice - [ (char '*' >>| fun _ lhs rhs -> EBinOp (Mul, lhs, rhs)) - ; (char '/' >>| fun _ lhs rhs -> EBinOp (Div, lhs, rhs)) - ] -;; - -let plus_sub_literal = - choice - [ (char '+' >>| fun _ lhs rhs -> EBinOp (Add, lhs, rhs)) - ; (char '-' >>| fun _ lhs rhs -> EBinOp (Sub, lhs, rhs)) - ] -;; - -let compare_literal = - choice - [ (string "<=" >>| fun _ lhs rhs -> EBinOp (Le, lhs, rhs)) - ; (string ">=" >>| fun _ lhs rhs -> EBinOp (Ge, lhs, rhs)) - ; (string "<>" >>| fun _ lhs rhs -> EBinOp (Neq, lhs, rhs)) - ; (char '=' >>| fun _ lhs rhs -> EBinOp (Eq, lhs, rhs)) - ; (char '<' >>| fun _ lhs rhs -> EBinOp (Lt, lhs, rhs)) - ; (char '>' >>| fun _ lhs rhs -> EBinOp (Gt, lhs, rhs)) - ] -;; - -let and_literal = string "&&" >>| fun _ lhs rhs -> EBinOp (And, lhs, rhs) -let or_literal = string "||" >>| fun _ lhs rhs -> EBinOp (Or, lhs, rhs) - -(* Fun parsing *) -let parse_fun parse_expr = - string "fun" - *> - let inner_func = - fix (fun inner_func -> - spaces *> parse_pattern - >>= fun pat -> - with_spaces (string "->") *> parse_expr - <|> inner_func - >>| fun expr -> EFun (pat, expr)) - in - inner_func -;; - -(* Part of let parsing for expressions and declarations *) -let parse_let_part parse_expr = - let parse_body = - return (fun name expr -> name, expr) - <*> spaces *> parse_pattern - <*> with_spaces (string "=") *> parse_expr - <|> (return (fun name pats expr -> - name, List.fold_right (fun p acc -> EFun (p, acc)) pats expr) - <*> (spaces *> variable >>| fun n -> PVar (n, None)) - <*> many1 (spaces *> parse_pattern) - <*> with_spaces (string "=") *> parse_expr) - in - return (fun isrec body_list -> isrec, body_list) - <*> (string "let" *> spaces *> parse_rec_flag <* spaces) - <*> lift2 - (fun f tl -> f :: tl) - parse_body - (many (with_spaces (string "and") *> parse_body)) -;; - -(* Parse Let *) -let parse_let parse_expr = - parse_let_part parse_expr - >>= fun (rf, b) -> - option None (with_spaces (string "in") *> parse_expr >>| fun ex -> Some ex) - >>| fun ex_opt -> ELet (rf, b, ex_opt) -;; - -(* List parsing *) -let parse_list parse_expr = - char '[' *> spaces *> sep_by (with_spaces (char ';')) parse_expr - <* spaces - <* char ']' - >>| fun exprs -> EList exprs -;; - -(* Some, None parsing *) -let parse_some parse_expr = - string "Some" *> spaces *> parse_expr - >>| (fun ex -> ESome ex) - <|> (string "None" >>| fun _ -> ENone) -;; - -(* App parsing *) -let parse_app parse_expr = chainl1 parse_expr (spaces >>| fun _ lhs rhs -> EApp (lhs, rhs)) - -(* Tuple parsing *) -let parse_tuple parse_expr = - parse_expr - >>= fun first -> - many1 (with_spaces (char ',') *> parse_expr) - >>= fun rest -> return (ETuple (first :: rest)) -;; - -(* IfThenElse parsing *) -let parse_if parse_expr = - with_spaces (string "if") *> parse_expr - >>= fun e1 -> - with_spaces (string "then") *> parse_expr - >>= fun e2 -> with_spaces (string "else") *> parse_expr >>| fun e3 -> EIf (e1, e2, e3) -;; - -(* expr parsing *) -let parse_expr = - fix (fun parse_expr -> - let term = - choice - [ integer_literal_parser - ; boolean_literal_parser - ; string_literal_parser - ; var_literal_parser - ; parens parse_expr - ] - in - let parse_app_or_some = parse_some term <|> parse_app term in - let mul_div = chainl1 parse_app_or_some (with_spaces mul_div_literal) in - let add_sub = chainl1 mul_div (with_spaces plus_sub_literal) in - let comparison = chainl1 add_sub (with_spaces compare_literal) in - let logical_and = chainl1 comparison (with_spaces and_literal) in - let logical_or = chainl1 logical_and (with_spaces or_literal) in - let parse_let_fun = - parse_let parse_expr - <|> parse_fun parse_expr - <|> parse_list parse_expr - <|> parse_if parse_expr - <|> logical_or - in - parse_tuple parse_let_fun <|> parse_let_fun) -;; - -(* Функция для парсинга строки *) -let parse s = - match parse_string ~consume:All (spaces *> parse_expr <* spaces <* end_of_input) s with - | Ok ast -> Ok ast - | Error msg -> Error (`Parsing_Error msg) -;; - -(* type_expr tests *) -let parse_test s = - match parse s with - | Ok ast -> print_endline (show_expr ast) - | Error msg -> pp_error Format.std_formatter msg -;; - -let%expect_test "parsing type: int" = - parse_test "(x: int)"; - [%expect {| (EVar ("x", (Some TInt))) |}] -;; - -let%expect_test "parsing type: bool" = - parse_test "(x: bool)"; - [%expect {| (EVar ("x", (Some TBool))) |}] -;; - -let%expect_test "parsing type: string" = - parse_test "(x: string)"; - [%expect {| (EVar ("x", (Some TString))) |}] -;; - -let%expect_test "parsing type: tuple" = - parse_test "(x: int * bool)"; - [%expect {| (EVar ("x", (Some (TTuple [TInt; TBool])))) |}] -;; - -let%expect_test "parsing type: nested tuple" = - parse_test "(x: int * (bool * string))"; - [%expect {| (EVar ("x", (Some (TTuple [TInt; (TTuple [TBool; TString])])))) |}] -;; - -let%expect_test "parsing type: list" = - parse_test "(x: int list)"; - [%expect {| (EVar ("x", (Some (TList TInt)))) |}] -;; - -let%expect_test "parsing type: list of tuples" = - parse_test "(x: (int * bool) list)"; - [%expect {| (EVar ("x", (Some (TList (TTuple [TInt; TBool]))))) |}] -;; - -let%expect_test "parsing type: option" = - parse_test "(x: int option)"; - [%expect {| (EVar ("x", (Some (TOption TInt)))) |}] -;; - -let%expect_test "parsing type: option of lists" = - parse_test "(x: int list option)"; - [%expect {| (EVar ("x", (Some (TOption (TList TInt))))) |}] -;; - -let%expect_test "parsing type: function" = - parse_test "(x: int -> bool)"; - [%expect {| (EVar ("x", (Some (TFun (TInt, TBool))))) |}] -;; - -let%expect_test "parsing type: function with multiple arguments" = - parse_test "(x: int -> bool -> string)"; - [%expect {| (EVar ("x", (Some (TFun (TInt, (TFun (TBool, TString))))))) |}] -;; - -let%expect_test "parsing type: function with tuple argument" = - parse_test "(x: (int * bool) -> string)"; - [%expect {| (EVar ("x", (Some (TFun ((TTuple [TInt; TBool]), TString))))) |}] -;; - -let%expect_test "parsing type: function returning a function" = - parse_test "(x: int -> (bool -> string))"; - [%expect {| (EVar ("x", (Some (TFun (TInt, (TFun (TBool, TString))))))) |}] -;; - -let%expect_test "parsing type: complex type" = - parse_test "(x: (int -> bool) list option -> (string * int) -> string option list)"; - [%expect - {| - (EVar ("x", - (Some (TFun ((TOption (TList (TFun (TInt, TBool)))), - (TFun ((TTuple [TString; TInt]), (TList (TOption TString))))))) - )) |}] -;; - -(* expr tests *) -(* int test *) -let%expect_test "parsing expr: integer" = - parse_test "123"; - [%expect {| (EInt 123) |}] -;; - -(* bool test *) -let%expect_test "parsing expr: boolean true" = - parse_test "true"; - [%expect {| (EBool true) |}] -;; - -let%expect_test "parsing expr: boolean false" = - parse_test "false"; - [%expect {| (EBool false) |}] -;; - -(* var test *) -let%expect_test "parsing expr: identifier 1" = - parse_test "my_variable"; - [%expect {| (EVar ("my_variable", None)) |}] -;; - -let%expect_test "parsing expr: identifier 2" = - parse_test "_123"; - [%expect {| (EVar ("_123", None)) |}] -;; - -let%expect_test "parsing expr: identifier 3" = - parse_test "Papa__123"; - [%expect {| (EVar ("Papa__123", None)) |}] -;; - -let%expect_test "parsing expr: identifier 4" = - parse_test "(smth : int)"; - [%expect {| (EVar ("smth", (Some TInt))) |}] -;; - -(* string test *) -let%expect_test "parsing expr: string" = - parse_test "\"hello, world!\""; - [%expect {| (EString "hello, world!") |}] -;; - -let%expect_test "parsing expr: empty string" = - parse_test "\"\""; - [%expect {| (EString "") |}] -;; - -(* binOp test *) -let%expect_test "parsing expr: simple addition" = - parse_test "1 + 2"; - [%expect {| (EBinOp (Add, (EInt 1), (EInt 2))) |}] -;; - -let%expect_test "parsing expr: simple subtraction" = - parse_test "5 - 3"; - [%expect {| (EBinOp (Sub, (EInt 5), (EInt 3))) |}] -;; - -let%expect_test "parsing expr: simple multiplication" = - parse_test "4 * 2"; - [%expect {| (EBinOp (Mul, (EInt 4), (EInt 2))) |}] -;; - -let%expect_test "parsing expr: simple division" = - parse_test "8 / 4"; - [%expect {| (EBinOp (Div, (EInt 8), (EInt 4))) |}] -;; - -let%expect_test "parsing expr: addition and multiplication" = - parse_test "1 + 2 * 3"; - [%expect {| - (EBinOp (Add, (EInt 1), (EBinOp (Mul, (EInt 2), (EInt 3))))) |}] -;; - -let%expect_test "parsing expr: subtraction and division" = - parse_test "10 - 8 / 2"; - [%expect {| - (EBinOp (Sub, (EInt 10), (EBinOp (Div, (EInt 8), (EInt 2))))) |}] -;; - -let%expect_test "parsing expr: parentheses with multiplication" = - parse_test "(1 + 2) * 3"; - [%expect {| - (EBinOp (Mul, (EBinOp (Add, (EInt 1), (EInt 2))), (EInt 3))) |}] -;; - -let%expect_test "parsing expr: nested parentheses" = - parse_test "((1 + 2) * (3 - 4)) / 5"; - [%expect - {| - (EBinOp (Div, - (EBinOp (Mul, (EBinOp (Add, (EInt 1), (EInt 2))), - (EBinOp (Sub, (EInt 3), (EInt 4))))), - (EInt 5))) |}] -;; - -let%expect_test "parsing expr: equality" = - parse_test "1 + 2 = 3"; - [%expect {| - (EBinOp (Eq, (EBinOp (Add, (EInt 1), (EInt 2))), (EInt 3))) |}] -;; - -let%expect_test "parsing expr: inequality" = - parse_test "4 <> 5"; - [%expect {| (EBinOp (Neq, (EInt 4), (EInt 5))) |}] -;; - -let%expect_test "parsing expr: less than" = - parse_test "2 < 3"; - [%expect {| (EBinOp (Lt, (EInt 2), (EInt 3))) |}] -;; - -let%expect_test "parsing expr: greater than or equal" = - parse_test "5 >= 4"; - [%expect {| (EBinOp (Ge, (EInt 5), (EInt 4))) |}] -;; - -let%expect_test "parsing expr: mixed arithmetic and comparison" = - parse_test "1 + 2 * 3 > 5"; - [%expect - {| - (EBinOp (Gt, (EBinOp (Add, (EInt 1), (EBinOp (Mul, (EInt 2), (EInt 3))))), - (EInt 5))) |}] -;; - -let%expect_test "parsing expr: arithmetic and logical and" = - parse_test "1 < 2 && 3 > 2"; - [%expect - {| - (EBinOp (And, (EBinOp (Lt, (EInt 1), (EInt 2))), - (EBinOp (Gt, (EInt 3), (EInt 2))))) |}] -;; - -let%expect_test "parsing expr: logical or and and" = - parse_test "true || false && true"; - [%expect - {| - (EBinOp (Or, (EBool true), (EBinOp (And, (EBool false), (EBool true))))) |}] -;; - -let%expect_test "parsing expr: logical and with comparison" = - parse_test "1 + 2 * 3 <= 7 && 4 > 2"; - [%expect - {| - (EBinOp (And, - (EBinOp (Le, (EBinOp (Add, (EInt 1), (EBinOp (Mul, (EInt 2), (EInt 3))))), - (EInt 7))), - (EBinOp (Gt, (EInt 4), (EInt 2))))) |}] -;; - -let%expect_test "parsing expr: logical or with comparison" = - parse_test "true || 1 + 2 * 3 < 7"; - [%expect - {| - (EBinOp (Or, (EBool true), - (EBinOp (Lt, (EBinOp (Add, (EInt 1), (EBinOp (Mul, (EInt 2), (EInt 3))))), - (EInt 7))) - )) |}] -;; - -(* Fun test *) -let%expect_test "parsing expr: function" = - parse_test "fun x -> x + 1"; - [%expect - {| - (EFun ((PVar ("x", None)), (EBinOp (Add, (EVar ("x", None)), (EInt 1))))) |}] -;; - -let%expect_test "parsing expr: function with multiple arguments" = - parse_test "fun x y z -> x + y * z"; - [%expect - {| - (EFun ((PVar ("x", None)), - (EFun ((PVar ("y", None)), - (EFun ((PVar ("z", None)), - (EBinOp (Add, (EVar ("x", None)), - (EBinOp (Mul, (EVar ("y", None)), (EVar ("z", None)))))) - )) - )) - )) |}] -;; - -let%expect_test "parsing expr: function in parentheses" = - parse_test "(fun x -> x + 1)"; - [%expect - {| - (EFun ((PVar ("x", None)), (EBinOp (Add, (EVar ("x", None)), (EInt 1))))) |}] -;; - -let%expect_test "parsing expr: function returning another function" = - parse_test "fun x -> fun y -> x + y"; - [%expect - {| - (EFun ((PVar ("x", None)), - (EFun ((PVar ("y", None)), - (EBinOp (Add, (EVar ("x", None)), (EVar ("y", None)))))) - )) |}] -;; - -(* App test *) -let%expect_test "parsing expr: application" = - parse_test "x y"; - [%expect {| (EApp ((EVar ("x", None)), (EVar ("y", None)))) |}] -;; - -let%expect_test "parsing expr: application with parentheses" = - parse_test "(x) (y)"; - [%expect {| (EApp ((EVar ("x", None)), (EVar ("y", None)))) |}] -;; - -let%expect_test "parsing expr: nested application left associative" = - parse_test "x y z"; - [%expect - {| (EApp ((EApp ((EVar ("x", None)), (EVar ("y", None)))), (EVar ("z", None)))) |}] -;; - -let%expect_test "parsing expr: nested application with parentheses" = - parse_test "x (y z)"; - [%expect - {| (EApp ((EVar ("x", None)), (EApp ((EVar ("y", None)), (EVar ("z", None)))))) |}] -;; - -(* Let test *) -let%expect_test "parsing expr: let variable" = - parse_test "let x = 5 in x"; - [%expect - {| - (ELet (NonRecursive, [((PVar ("x", None)), (EInt 5))], - (Some (EVar ("x", None))))) |}] -;; - -let%expect_test "parsing expr: let variable" = - parse_test "let x = 5"; - [%expect {| (ELet (NonRecursive, [((PVar ("x", None)), (EInt 5))], None)) |}] -;; - -let%expect_test "parsing expr: let typed variable" = - parse_test "let (x : int) = x + 1 in x"; - [%expect - {| - (ELet (NonRecursive, - [((PVar ("x", (Some TInt))), (EBinOp (Add, (EVar ("x", None)), (EInt 1)))) - ], - (Some (EVar ("x", None))))) |}] -;; - -let%expect_test "parsing expr: let function with multiple patterns" = - parse_test "let f x y = 5 in f x y"; - [%expect - {| - (ELet (NonRecursive, - [((PVar ("f", None)), - (EFun ((PVar ("x", None)), (EFun ((PVar ("y", None)), (EInt 5))))))], - (Some (EApp ((EApp ((EVar ("f", None)), (EVar ("x", None)))), - (EVar ("y", None))))) - )) |}] -;; - -let%expect_test "parsing expr: let function with multiple typed patterns" = - parse_test "let f x (y : int) = x + y in f"; - [%expect - {| - (ELet (NonRecursive, - [((PVar ("f", None)), - (EFun ((PVar ("x", None)), - (EFun ((PVar ("y", (Some TInt))), - (EBinOp (Add, (EVar ("x", None)), (EVar ("y", None)))))) - ))) - ], - (Some (EVar ("f", None))))) |}] -;; - -let%expect_test "parsing expr: let rec with multiple patterns" = - parse_test "let rec f (x: string) y = x + y in f"; - [%expect - {| - (ELet (Recursive, - [((PVar ("f", None)), - (EFun ((PVar ("x", (Some TString))), - (EFun ((PVar ("y", None)), - (EBinOp (Add, (EVar ("x", None)), (EVar ("y", None)))))) - ))) - ], - (Some (EVar ("f", None))))) |}] -;; - -let%expect_test "parsing expr: mutual recursion with two functions" = - parse_test "let rec even x = x + 1 and odd x = x + 2 in even 4"; - [%expect - {| - (ELet (Recursive, - [((PVar ("even", None)), - (EFun ((PVar ("x", None)), (EBinOp (Add, (EVar ("x", None)), (EInt 1))) - ))); - ((PVar ("odd", None)), - (EFun ((PVar ("x", None)), (EBinOp (Add, (EVar ("x", None)), (EInt 2))) - ))) - ], - (Some (EApp ((EVar ("even", None)), (EInt 4)))))) |}] -;; - -let%expect_test "parsing expr: mutual recursion with three functions" = - parse_test "let rec f x = g x and g x = h x and h x = x in f 5"; - [%expect - {| - (ELet (Recursive, - [((PVar ("f", None)), - (EFun ((PVar ("x", None)), - (EApp ((EVar ("g", None)), (EVar ("x", None))))))); - ((PVar ("g", None)), - (EFun ((PVar ("x", None)), - (EApp ((EVar ("h", None)), (EVar ("x", None))))))); - ((PVar ("h", None)), (EFun ((PVar ("x", None)), (EVar ("x", None)))))], - (Some (EApp ((EVar ("f", None)), (EInt 5)))))) |}] -;; - -(* Tuple test *) -let%expect_test "parsing expr: tuple" = - parse_test "(1, 2, 3)"; - [%expect {| (ETuple [(EInt 1); (EInt 2); (EInt 3)]) |}] -;; - -let%expect_test "parsing expr: nested tuple" = - parse_test "((1, 2), (3, 4))"; - [%expect - {| - (ETuple [(ETuple [(EInt 1); (EInt 2)]); (ETuple [(EInt 3); (EInt 4)])]) |}] -;; - -let%expect_test "parsing expr: tuple with different types" = - parse_test "(1, true, \"hello\")"; - [%expect {| (ETuple [(EInt 1); (EBool true); (EString "hello")]) |}] -;; - -(* List test *) -let%expect_test "parsing expr: empty list" = - parse_test "[]"; - [%expect {| (EList []) |}] -;; - -let%expect_test "parsing expr: list" = - parse_test "[1; 2; 3]"; - [%expect {| (EList [(EInt 1); (EInt 2); (EInt 3)]) |}] -;; - -let%expect_test "parsing expr: nested list" = - parse_test "[[1; 2]; [3; 4]]"; - [%expect {| - (EList [(EList [(EInt 1); (EInt 2)]); (EList [(EInt 3); (EInt 4)])]) |}] -;; - -let%expect_test "parsing expr: list with different types" = - parse_test "[1; true; \"hello\"]"; - [%expect {| (EList [(EInt 1); (EBool true); (EString "hello")]) |}] -;; - -(* Some test *) -let%expect_test "parsing expr: Some with integer literal" = - parse_test "Some 10"; - [%expect {| (ESome (EInt 10)) |}] -;; - -let%expect_test "parsing expr: Some with variable" = - parse_test "Some x"; - [%expect {| (ESome (EVar ("x", None))) |}] -;; - -(* None test *) -let%expect_test "parsing expr: None" = - parse_test "None"; - [%expect {| ENone |}] -;; - -(* Eif test *) -let%expect_test "parsing expr: if-then-else true case" = - parse_test "if true then 1 else 0"; - [%expect {| (EIf ((EBool true), (EInt 1), (EInt 0))) |}] -;; - -let%expect_test "parsing expr: if-then-else false case" = - parse_test "if false then 42 else 99"; - [%expect {| (EIf ((EBool false), (EInt 42), (EInt 99))) |}] -;; - -let%expect_test "parsing expr: nested if-then-else" = - parse_test "if true then (if false then 1 else 2) else 3"; - [%expect - {| (EIf ((EBool true), (EIf ((EBool false), (EInt 1), (EInt 2))), (EInt 3))) |}] -;; - -let%expect_test "parsing expr: if-then-else with expressions" = - parse_test "if x > 0 then x + 1 else x - 1"; - [%expect - {| - (EIf ((EBinOp (Gt, (EVar ("x", None)), (EInt 0))), - (EBinOp (Add, (EVar ("x", None)), (EInt 1))), - (EBinOp (Sub, (EVar ("x", None)), (EInt 1))))) |}] -;; diff --git a/Ocaml/lib/parser.mli b/Ocaml/lib/parser.mli deleted file mode 100644 index afa3ae2b4..000000000 --- a/Ocaml/lib/parser.mli +++ /dev/null @@ -1,11 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type error = - [ `Parsing_Error of string - | `Some_Error - ] - -val pp_error : Format.formatter -> error -> unit -val parse : string -> (Ast.expr, error) result diff --git a/Ocaml/lib/typedtree.ml b/Ocaml/lib/typedtree.ml deleted file mode 100644 index dca769092..000000000 --- a/Ocaml/lib/typedtree.ml +++ /dev/null @@ -1,30 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type binder = int [@@deriving show { with_path = false }] - -module VarSet = struct - include Stdlib.Set.Make (Int) - - let pp ppf s = - Format.fprintf ppf "[ "; - iter (Format.fprintf ppf "%d; ") s; - Format.fprintf ppf "]" - ;; -end - -type binder_set = VarSet.t [@@deriving show { with_path = false }] - -type ty = - | TyInt - | TyBool - | TyString - | TyTuple of ty list - | TyList of ty - | TyOption of ty - | Ty_var of binder - | Arrow of ty * ty -[@@deriving show { with_path = false }] - -type scheme = S of binder_set * ty [@@deriving show { with_path = false }] diff --git a/Ocaml/lib/typedtree.mli b/Ocaml/lib/typedtree.mli deleted file mode 100644 index 5a4c9c260..000000000 --- a/Ocaml/lib/typedtree.mli +++ /dev/null @@ -1,80 +0,0 @@ -(** Copyright 2021-2023, Daniil Kadochnikov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type binder = int - -val pp_binder : Format.formatter -> binder -> unit -val show_binder : binder -> string - -module VarSet : sig - type elt = binder - type t = Set.Make(Int).t - - val empty : t - val is_empty : t -> bool - val mem : elt -> t -> bool - val add : elt -> t -> t - val singleton : elt -> t - val remove : elt -> t -> t - val union : t -> t -> t - val inter : t -> t -> t - val disjoint : t -> t -> bool - val diff : t -> t -> t - val compare : t -> t -> binder - val equal : t -> t -> bool - val subset : t -> t -> bool - val iter : (elt -> unit) -> t -> unit - val map : (elt -> elt) -> t -> t - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a - val for_all : (elt -> bool) -> t -> bool - val exists : (elt -> bool) -> t -> bool - val filter : (elt -> bool) -> t -> t - val filter_map : (elt -> elt option) -> t -> t - val partition : (elt -> bool) -> t -> t * t - val cardinal : t -> binder - val elements : t -> elt list - val min_elt : t -> elt - val min_elt_opt : t -> elt option - val max_elt : t -> elt - val max_elt_opt : t -> elt option - val choose : t -> elt - val choose_opt : t -> elt option - val split : elt -> t -> t * bool * t - val find : elt -> t -> elt - val find_opt : elt -> t -> elt option - val find_first : (elt -> bool) -> t -> elt - val find_first_opt : (elt -> bool) -> t -> elt option - val find_last : (elt -> bool) -> t -> elt - val find_last_opt : (elt -> bool) -> t -> elt option - val of_list : elt list -> t - val to_seq_from : elt -> t -> elt Seq.t - val to_seq : t -> elt Seq.t - val to_rev_seq : t -> elt Seq.t - val add_seq : elt Seq.t -> t -> t - val of_seq : elt Seq.t -> t - val pp : Format.formatter -> t -> unit -end - -type binder_set = VarSet.t - -val pp_binder_set : Format.formatter -> binder_set -> unit -val show_binder_set : binder_set -> string - -type ty = - | TyInt - | TyBool - | TyString - | TyTuple of ty list - | TyList of ty - | TyOption of ty - | Ty_var of binder - | Arrow of ty * ty - -val pp_ty : Format.formatter -> ty -> unit -val show_ty : ty -> string - -type scheme = S of binder_set * ty - -val pp_scheme : Format.formatter -> scheme -> unit -val show_scheme : scheme -> string diff --git a/OcamlADT/.envrc b/OcamlADT/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/OcamlADT/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/OcamlADT/.gitignore b/OcamlADT/.gitignore deleted file mode 100644 index 41f7e6a9d..000000000 --- a/OcamlADT/.gitignore +++ /dev/null @@ -1,98 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### macOS Patch ### -# iCloud generated files -*.icloud - -### OCaml ### -*.annot -*.cmo -*.cma -*.cmi -*.a -*.o -*.cmx -*.cmxs -*.cmxa - -# ocamlbuild working directory -_build/ - -# ocamlbuild targets -*.byte -*.native - -# oasis generated files -setup.data -setup.log - -# Merlin configuring file for Vim and Emacs -.merlin - -# Dune generated files -*.install - -# Local OPAM switch -_opam/ - -### VisualStudioCode ### -.vscode/* -.vscode -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -!.vscode/*.code-snippets - -# Local History for Visual Studio Code -.history/ - -# Built Visual Studio Code Extensions -*.vsix - -### VisualStudioCode Patch ### -# Ignore all local history of files -.history -.ionide \ No newline at end of file diff --git a/OcamlADT/.ocamlformat b/OcamlADT/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/OcamlADT/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/OcamlADT/.zanuda b/OcamlADT/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/OcamlADT/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/OcamlADT/COPYING b/OcamlADT/COPYING deleted file mode 100644 index 53d1f3d01..000000000 --- a/OcamlADT/COPYING +++ /dev/null @@ -1,675 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - diff --git a/OcamlADT/COPYING.CCO b/OcamlADT/COPYING.CCO deleted file mode 100644 index 6ca207ef0..000000000 --- a/OcamlADT/COPYING.CCO +++ /dev/null @@ -1,122 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. - diff --git a/OcamlADT/COPYING.LESSER b/OcamlADT/COPYING.LESSER deleted file mode 100644 index 5357f6918..000000000 --- a/OcamlADT/COPYING.LESSER +++ /dev/null @@ -1,166 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - diff --git a/OcamlADT/Makefile b/OcamlADT/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/OcamlADT/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/OcamlADT/OcamlADT.opam b/OcamlADT/OcamlADT.opam deleted file mode 100644 index a6f9b9640..000000000 --- a/OcamlADT/OcamlADT.opam +++ /dev/null @@ -1,44 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for Ocaml language with ADT" -description: "An interpreter for Ocaml language with ADT." -maintainer: [ - "Rodion Suvorov " - "Mikhail Gavrilenko " -] -authors: [ - "Rodion Suvorov " - "Mikhail Gavrilenko " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/qrutyy/OcamlADT" -bug-reports: "https://github.com/qrutyy/OcamlADT" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "ppx_deriving_qcheck" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "base" - "stdio" - "angstrom" - "qcheck-core" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OcamlADT/bin/dune b/OcamlADT/bin/dune deleted file mode 100644 index 7db2ff062..000000000 --- a/OcamlADT/bin/dune +++ /dev/null @@ -1,10 +0,0 @@ -(executable - (name interpret) - (public_name interpret) - (modules interpret) - (libraries ocamladt_lib ocamladt_tests) - (instrumentation - (backend bisect_ppx))) - -(cram - (deps ./interpret.exe %{bin:interpret})) diff --git a/OcamlADT/bin/interpret.ml b/OcamlADT/bin/interpret.ml deleted file mode 100644 index 317b7409b..000000000 --- a/OcamlADT/bin/interpret.ml +++ /dev/null @@ -1,130 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Ast -open Ocamladt_lib.Parser -open Ocamladt_lib.Interpreter -open Ocamladt_lib.Interpreter.PPrinter -open Ocamladt_lib.Infer -open Ocamladt_lib.InferTypes -open Format - -(* ------------------------------- *) -(* Command-line Options *) -(* ------------------------------- *) - -type options = - { mutable show_ast : bool - ; mutable file_string : string option - } - -let usage_msg = - "\n\ - Ocaml+ADT interpreter\n\n\ - Usage (file mode): dune exec ./bin/interpret.exe \n\ - Usage (repl mode): dune exec ./bin/interpret.exe \n\n\ - Options:\n\ - --ast Dump abstract syntax tree of a program\n\ - REPL commands:\n\ - help Display usage message\n\ - quit Quit the REPL mode\n" -;; - -(* ------------------------------- *) -(* REPL and File Modes *) -(* ------------------------------- *) - -(* A helper that parses a fixed word (like "help" or "quit") with surrounding whitespace. *) - -let rec read_repl_input inp_chan = - match In_channel.input_line inp_chan with - | None -> None - | Some input -> - (match input with - | "help" -> - print_endline usage_msg; - flush stdout; - read_repl_input inp_chan - | "quit" -> None - | _ -> - (match parse input with - | Error _ -> - print_endline "Syntax error"; - read_repl_input inp_chan - | Ok ast -> if ast = [] then read_repl_input inp_chan else Some ast)) -;; - -(* Read an entire input and process it *) -let process_input options ast = - print_endline "Running... "; - flush stdout; - if options.show_ast - then ( - print_endline "\nAST dump:"; - print_endline (show_program ast); - print_newline ()); - let tcr = run_infer_program ast env_with_things in - match tcr with - | Error err -> Format.printf "Type error: %a\n" pp_inf_err err - | Ok (env, _) -> - (match run_interpreter ast with - | Error e -> pp_error Format.std_formatter e - | Ok olist -> - List.iter - (fun (tag, v) -> - match tag with - | Some id -> - (match Base.Map.find env id with - | Some (Forall (args, typ)) -> - let m, _, _ = minimize (binder_to_list args) in - let type_str = Format.asprintf "%a" (pprint_type ~poly_names_map:m) typ in - Format.printf "val %s : %s = %a\n" id type_str PPrinter.pp_value v - | None -> Format.printf "val %s = %a\n" id PPrinter.pp_value v) - | None -> if v <> VString "" then Format.printf "_ = %a\n" PPrinter.pp_value v) - olist); - flush stdout; - Format.pp_print_flush Format.std_formatter () -;; - -let run_repl options = - let inp_chan = stdin in - let rec helper () = - match read_repl_input inp_chan with - | None -> () (* Exit the loop if no input is provided (i.e., "quit" command) *) - | Some ast -> - process_input options ast; - helper () - in - helper () -;; - -let run_file options string = - match parse string with - | Error _ -> print_endline "Syntax Error" - | Ok ast -> process_input options ast -;; - -(* ------------------------------- *) -(* Main Entry *) -(* ------------------------------- *) - -let () = - let options = { show_ast = false; file_string = None } in - let arg_list = [ "--ast", Arg.Unit (fun () -> options.show_ast <- true), "Dump AST" ] in - let read_file path = - if Sys.file_exists path - then ( - let ch = open_in_bin path in - let s = really_input_string ch (in_channel_length ch) in - close_in ch; - options.file_string <- Some s) - else ( - Printf.eprintf "File %s not found\n" path; - exit 255) - in - Arg.parse arg_list read_file usage_msg; - match options.file_string with - | Some s -> run_file options s - | None -> run_repl options -;; diff --git a/OcamlADT/bin/program.miniml b/OcamlADT/bin/program.miniml deleted file mode 100644 index 0b5d367d1..000000000 --- a/OcamlADT/bin/program.miniml +++ /dev/null @@ -1,7 +0,0 @@ -let foo b = if b then (fun foo -> foo+2) else (fun foo -> foo*10) - -let foo x = foo true (foo false (foo true (foo false x))) -let main = - let () = print_int (foo 11) in - 0 - diff --git a/OcamlADT/dune b/OcamlADT/dune deleted file mode 100644 index 98e54536a..000000000 --- a/OcamlADT/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/OcamlADT/dune-project b/OcamlADT/dune-project deleted file mode 100644 index d28429989..000000000 --- a/OcamlADT/dune-project +++ /dev/null @@ -1,40 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors - "Rodion Suvorov " - "Mikhail Gavrilenko ") - -(maintainers - "Rodion Suvorov " - "Mikhail Gavrilenko ") - -(bug_reports "https://github.com/qrutyy/OcamlADT") - -(homepage "https://github.com/qrutyy/OcamlADT") - -(package - (name OcamlADT) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for Ocaml language with ADT") - (description "An interpreter for Ocaml language with ADT.") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - ppx_deriving_qcheck - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - base - stdio - angstrom - qcheck-core - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/OcamlADT/lib/ast.ml b/OcamlADT/lib/ast.ml deleted file mode 100644 index c0aa4802f..000000000 --- a/OcamlADT/lib/ast.ml +++ /dev/null @@ -1,243 +0,0 @@ -(** Copyright 2024, Rodion Suvorov, Mikhail Gavrilenko*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open QCheck -open Base -open Gen -open Stdlib - -type ident = string [@@deriving eq, show { with_path = false }] - -let gen_charc = map Char.chr (int_range (Char.code 'a') (Char.code 'z')) - -let is_not_keyword = function - | "let" - | "if" - | "then" - | "else" - | "in" - | "fun" - | "true" - | "false" - | "rec" - | "and" - | "function" - | "match" - | "with" - | "type" - | "of" -> false - | _ -> true -;; - -let rec gen_filtered_ident base_gen = - let open QCheck.Gen in - base_gen - >>= fun ident -> - if is_not_keyword ident then return ident else gen_filtered_ident base_gen -;; - -let gen_ident = - let base_gen = - map2 - (fun start_sym rest_sym -> Base.Char.to_string start_sym ^ rest_sym) - (oneof [ char_range 'A' 'Z'; char_range 'a' 'z'; return '_' ]) - (small_string - ~gen: - (oneof - [ char_range 'A' 'Z'; char_range 'a' 'z'; char_range '0' '9'; return '_' ])) - in - gen_filtered_ident base_gen -;; - -let gen_ident_uc = - let base_gen = - map2 - (fun start_sym rest_sym -> Base.Char.to_string start_sym ^ rest_sym) - (char_range 'A' 'Z') - (small_string - ~gen: - (oneof - [ char_range 'A' 'Z'; char_range 'a' 'z'; char_range '0' '9'; return '_' ])) - in - gen_filtered_ident base_gen -;; - -let gen_ident_lc include_us = - let start_sym = - if include_us then oneof [ char_range 'a' 'z'; return '_' ] else char_range 'a' 'z' - in - let base_gen = - map2 - (fun start_sym rest_sym -> Base.Char.to_string start_sym ^ rest_sym) - start_sym - (small_string - ~gen: - (oneof - [ char_range 'A' 'Z'; char_range 'a' 'z'; char_range '0' '9'; return '_' ])) - in - gen_filtered_ident base_gen -;; - -module List1 = struct - type 'a t = 'a * ('a list[@gen list_size (int_bound 5) gen_a]) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module List2 = struct - type 'a t = 'a * 'a * ('a list[@gen list_size (int_bound 5) gen_a]) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module Constant = struct - type t = - | Const_integer of (int[@gen small_nat]) (** integer as [52] *) - | Const_char of (char[@gen gen_charc]) (** char as ['w'] *) - | Const_string of (string[@gen small_string ~gen:gen_charc]) - (** string as ["Kakadu"] *) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module TypeExpr = struct - type t = - | Type_arrow of t * t (** [Type_arrow(T1, T2)] represents: - [T1 -> T2] *) - | Type_var of (ident[@gen gen_ident]) - | Type_tuple of t List2.t (** [Type_tuple([T1, T2, ... Tn])] *) - | Type_construct of ident * t list - (** [Type_construct(lident, l)] represents: - - [tconstr] when [l=[]], - - [T tconstr] when [l=[T]], - - [(T1, ..., Tn) tconstr] when [l=[T1 ; ... ; Tn]]. *) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module Pattern = struct - type t = - | Pat_constraint of t * (TypeExpr.t[@gen TypeExpr.gen_sized (n / 2)]) - (** Pattern [(P : T)] *) - | Pat_any (** The pattern [_]. *) - | Pat_var of (ident[@gen gen_ident_lc false]) (** A variable pattern such as [x] *) - | Pat_constant of Constant.t (** Patterns such as [52], ['w'], ["uwu"] *) - | Pat_tuple of t List2.t (** Patterns [(P1, ..., Pn)]. *) - | Pat_construct of (ident[@gen gen_ident_uc]) * t option - (** [Pat_construct(C, args)] represents: - - [C] when [args] is [None], - - [C P] when [args] is [Some (P)] - - [C (P1, ..., Pn)] when [args] is - [Some (Pat_tuple [P1; ...; Pn])] *) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module Expression = struct - type rec_flag = - | Nonrecursive - | Recursive - [@@deriving eq, show { with_path = false }, qcheck] - - type 'expr value_binding = - { pat : Pattern.t - ; expr : 'expr - } - [@@deriving eq, show { with_path = false }] - - let gen_value_binding gen_expr n = - map2 (fun pat expr -> { pat; expr }) (Pattern.gen_sized (n / 2)) (gen_expr (n / 2)) - ;; - - type 'expr case = - { first : Pattern.t - ; second : 'expr - } - [@@deriving eq, show { with_path = false }] - - let gen_case gen_expr n = - map2 - (fun first second -> { first; second }) - (Pattern.gen_sized (n / 2)) - (gen_expr (n / 2)) - ;; - - type t = - | Exp_ident of (ident[@gen gen_ident_lc true]) (** Identifiers such as [x] *) - | Exp_constant of Constant.t (** Expressions constant such as [1], ['a'], ["true"]**) - | Exp_tuple of t List2.t (** Expressions [(E1, E2, ..., En)] *) - | Exp_function of (t case[@gen gen_case gen_sized (n / 2)]) List1.t - (** [Exp_function (P1, [P2; ...; Pn])] represents - [function P1 | ... | Pn] *) - | Exp_fun of (Pattern.t[@gen Pattern.gen_sized (n / 2)]) List1.t * t - (**[Exp_fun (P1, [P2; ...; Pn], E)] represents: - [fun P1 ... Pn -> E] *) - | Exp_apply of t * t (** [Pexp_apply(E0, E1)] - represents [E0 E1]*) - | Exp_match of t * (t case[@gen gen_case gen_sized (n / 2)]) List1.t - (** [match E0 with P1 -> E1 || Pn -> En] *) - | Exp_constraint of t * (TypeExpr.t[@gen TypeExpr.gen_sized (n / 2)]) (** [(E : T)] *) - | Exp_if of t * t * t option (** [if E1 then E2 else E3] *) - | Exp_let of - rec_flag * (t value_binding[@gen gen_value_binding gen_sized (n / 2)]) List1.t * t - (** [Exp_let(flag, [(P1,E1) ; ... ; (Pn,En)], E)] represents: - - [let P1 = E1 and ... and Pn = EN in E] - when [flag] is [Nonrecursive], - - [let rec P1 = E1 and ... and Pn = EN in E] - when [flag] is [Recursive]. *) - | Exp_construct of (ident[@gen gen_ident_uc]) * t option - (** [Exp_construct(C, exp)] represents: - - [C] when [exp] is [None], - - [C E] when [exp] is [Some E], - - [C (E1, ..., En)] when [exp] is [Some (Exp_tuple[E1;...;En])] *) - [@@deriving eq, show { with_path = false }, qcheck] -end - -module Structure = struct - type structure_item = - | Str_eval of Expression.t - | Str_value of Expression.rec_flag * Expression.t Expression.value_binding List1.t - (** [Str_value(rec, [(P1, E1 ; ... ; (Pn, En))])] represents: - - [let P1 = E1 and ... and Pn = EN] - when [rec] is [Nonrecursive], - - [let rec P1 = E1 and ... and Pn = EN ] - when [rec] is [Recursiv e ee]. *) - | Str_adt of ident list * ident * (ident * TypeExpr.t option) List1.t - (** [Str_type(C0, [(C1, [(T11; T12; ... ; T1n_1)]); (C2, [(T21;T22; ... ; T2n_2)]); ... ; - (Cm, [(Tm1;Tm2; ... ; Tmn_n)]) ])] represents: - - [type C0 = - | C1 of T11 * ... * T1n_1 - | ... - | Cm of Tm1 * ... * Tmn_n - ] - - n_i: [n_i >= 0] - Invariant: [m > 0] *) - [@@deriving eq, show { with_path = false }] - - let gen_structure_item n = - frequency - [ 0, map (fun expr -> Str_eval expr) (Expression.gen_sized (n / 2)) - ; ( 0 - , let* rec_flag = - oneof [ return Expression.Nonrecursive; return Expression.Recursive ] - in - let* bind1 = Expression.gen_value_binding Expression.gen_sized (n / 2) in - let* bindl = - small_list (Expression.gen_value_binding Expression.gen_sized (n / 2)) - in - return (Str_value (rec_flag, (bind1, bindl))) ) - ; ( 1 - , let* tparam = small_list (gen_ident_lc true) in - let* idt = gen_ident_lc true in - let* cons1 = Gen.pair gen_ident_uc (Gen.option (TypeExpr.gen_sized (n / 20))) in - let* consl = - small_list (Gen.pair gen_ident_uc (Gen.option (TypeExpr.gen_sized (n / 20)))) - in - return (Str_adt (tparam, idt, (cons1, consl))) ) - ] - ;; -end - -type program = Structure.structure_item list [@@deriving eq, show { with_path = false }] - -module Program = struct - let gen_program n = list_size (int_bound 6) (Structure.gen_structure_item (n / 2)) -end diff --git a/OcamlADT/lib/ast.mli b/OcamlADT/lib/ast.mli deleted file mode 100644 index f66baaf63..000000000 --- a/OcamlADT/lib/ast.mli +++ /dev/null @@ -1,194 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type ident = string - -val equal_ident : ident -> ident -> bool -val pp_ident : Format.formatter -> ident -> unit -val show_ident : ident -> string -val gen_charc : char QCheck.Gen.t -val is_not_keyword : string -> bool -val gen_filtered_ident : string QCheck.Gen.t -> string QCheck.Gen.t -val gen_ident : string QCheck.Gen.t -val gen_ident_uc : string QCheck.Gen.t -val gen_ident_lc : bool -> string QCheck.Gen.t - -module List1 : sig - type 'a t = 'a * 'a list - - val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool - val pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit - val show : (Format.formatter -> 'a -> unit) -> 'a t -> ident - val gen : 'a QCheck.Gen.t -> ('a * 'a list) QCheck.Gen.t - val arb : 'a QCheck.Gen.t -> ('a * 'a list) QCheck.arbitrary -end - -module List2 : sig - type 'a t = 'a * 'a * 'a list - - val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool - val pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit - val show : (Format.formatter -> 'a -> unit) -> 'a t -> ident - val gen : 'a QCheck.Gen.t -> ('a * 'a * 'a list) QCheck.Gen.t - val arb : 'a QCheck.Gen.t -> ('a * 'a * 'a list) QCheck.arbitrary -end - -module Constant : sig - type t = - | Const_integer of int (** Integer constant. *) - | Const_char of char (** Character constant. *) - | Const_string of ident (** String constant. *) - - val equal : t -> t -> bool - val pp : Format.formatter -> t -> unit - val show : t -> ident - val gen : t QCheck.Gen.t - val arb : t QCheck.arbitrary -end - -module TypeExpr : sig - type t = - | Type_arrow of t * t (** Represents a function type: [T1 -> T2]. *) - | Type_var of ident (** Represents a type variable: ['a]. *) - | Type_tuple of t List2.t (** Represents a tuple type: [(T1, T2, ..., Tn)]. *) - | Type_construct of ident * t list - (** Represents a type constructor with arguments: [C T1 ... Tn]. *) - - val equal : t -> t -> bool - val pp : Format.formatter -> t -> unit - val show : t -> ident - val gen_sized : int -> t QCheck.Gen.t - val gen : t QCheck.Gen.t - val arb_sized : int -> t QCheck.arbitrary - val arb : t QCheck.arbitrary -end - -module Pattern : sig - type t = - | Pat_constraint of t * TypeExpr.t (** A pattern with a type constraint: [(P : T)]. *) - | Pat_any (** The wildcard pattern [_]. *) - | Pat_var of ident (** A variable pattern, such as [x]. *) - | Pat_constant of Constant.t - (** A constant pattern, such as [1], ["text"], or ['t']. *) - | Pat_tuple of t List2.t (** A tuple pattern, such as [(P1, P2, ..., Pn)]. *) - | Pat_construct of ident * t option - (** A constructor pattern, such as [C] or [C P]. *) - - val equal : t -> t -> bool - val pp : Format.formatter -> t -> unit - val show : t -> ident - val gen_sized : int -> t QCheck.Gen.t - val gen : t QCheck.Gen.t - val arb_sized : int -> t QCheck.arbitrary - val arb : t QCheck.arbitrary -end - -module Expression : sig - type rec_flag = - | Nonrecursive (** zanuda is zanuda *) - | Recursive (** zanuda is zanuda *) - - val equal_rec_flag : rec_flag -> rec_flag -> bool - val pp_rec_flag : Format.formatter -> rec_flag -> unit - val show_rec_flag : rec_flag -> ident - val gen_rec_flag : rec_flag QCheck.Gen.t - val arb_rec_flag : rec_flag QCheck.arbitrary - - type 'expr value_binding = - { pat : Pattern.t - ; expr : 'expr - } - - val equal_value_binding - : ('expr -> 'expr -> bool) - -> 'expr value_binding - -> 'expr value_binding - -> bool - - val pp_value_binding - : (Format.formatter -> 'expr -> unit) - -> Format.formatter - -> 'expr value_binding - -> unit - - val show_value_binding - : (Format.formatter -> 'expr -> unit) - -> 'expr value_binding - -> ident - - val gen_value_binding : (int -> 'a QCheck.Gen.t) -> int -> 'a value_binding QCheck.Gen.t - - type 'expr case = - { first : Pattern.t - ; second : 'expr - } - - val equal_case : ('expr -> 'expr -> bool) -> 'expr case -> 'expr case -> bool - - val pp_case - : (Format.formatter -> 'expr -> unit) - -> Format.formatter - -> 'expr case - -> unit - - val show_case : (Format.formatter -> 'expr -> unit) -> 'expr case -> ident - val gen_case : (int -> 'a QCheck.Gen.t) -> int -> 'a case QCheck.Gen.t - - type t = - | Exp_ident of ident (** Identifiers such as [x] and [M.x]. *) - | Exp_constant of Constant.t - (** Expressions with constants such as [1], ['a'], ["true"]. *) - | Exp_tuple of t List2.t (** A tuple expression, such as [(E1, E2, ..., En)]. *) - | Exp_function of t case List1.t - (** A function with pattern matching, such as [function P1 -> E1 | ... | Pn -> En]. *) - | Exp_fun of Pattern.t List1.t * t - (** A function expression, such as [fun P1 ... Pn -> E]. *) - | Exp_apply of t * t (** Function application, such as [E0 E1]. *) - | Exp_match of t * t case List1.t - (** A match expression, such as [match E0 with P1 -> E1 | ... | Pn -> En]. *) - | Exp_constraint of t * TypeExpr.t (** A type constraint, such as [(E : T)]. *) - | Exp_if of t * t * t option - (** An if-then-else expression, such as [if E1 then E2 else E3]. *) - | Exp_let of rec_flag * t value_binding List1.t * t - (** A let-binding, such as [let P1 = E1 and ... and Pn = En in E]. *) - | Exp_construct of ident * t option - (** A constructor expression, such as [C] or [C E]. *) - - val equal : t -> t -> bool - val pp : Format.formatter -> t -> unit - val show : t -> ident - val gen_sized : int -> t QCheck.Gen.t - val gen : t QCheck.Gen.t - val arb_sized : int -> t QCheck.arbitrary - val arb : t QCheck.arbitrary -end - -module Structure : sig - type structure_item = - | Str_eval of Expression.t (** An evaluated expression, such as [E]. *) - | Str_value of Expression.rec_flag * Expression.t Expression.value_binding List1.t - (** A let-binding, such as: - - [let P1 = E1 and ... and Pn = En] - when [rec] is [rec_flag.Nonrecursive]. - - [let rec P1 = E1 and ... and Pn = En] - when [rec] is [rec_flag.Recursive]. *) - | Str_adt of ident list * ident * (ident * TypeExpr.t option) List1.t - (** A type declaration for an algebraic data type (ADT), - such as [type t1 = ... | ... | tn = ...]. *) - - val equal_structure_item : structure_item -> structure_item -> bool - val pp_structure_item : Format.formatter -> structure_item -> unit - val show_structure_item : structure_item -> ident - val gen_structure_item : int -> structure_item QCheck.Gen.t -end - -type program = Structure.structure_item list - -val equal_program : program -> program -> bool -val pp_program : Format.formatter -> program -> unit -val show_program : program -> string - -module Program : sig - val gen_program : int -> Structure.structure_item list QCheck.Gen.t -end diff --git a/OcamlADT/lib/dune b/OcamlADT/lib/dune deleted file mode 100644 index 65f66fcf7..000000000 --- a/OcamlADT/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name ocamladt_lib) - (public_name OcamlADT.Lib) - (modules Ast Parser Pprinter InferTypes Infer Interpreter) - (libraries angstrom base stdio) - (preprocess - (pps ppx_deriving.show ppx_deriving.eq ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx))) diff --git a/OcamlADT/lib/infer.ml b/OcamlADT/lib/infer.ml deleted file mode 100644 index c8bf6dfb1..000000000 --- a/OcamlADT/lib/infer.ml +++ /dev/null @@ -1,858 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast.TypeExpr -open InferTypes - -module MInfer = struct - open Base - - type 'a t = int -> int * ('a, InferTypes.error) Result.t - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f st -> - let last, r = m st in - match r with - | Result.Error x -> last, Error x - | Ok a -> f a last - ;; - - let fail e st = st, Result.fail e - let return x last = last, Result.return x - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Ok x -> st, Ok (f x) - | st, Result.Error e -> st, Result.Error e - ;; - - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_left2 xs xl ~init ~f = - Base.List.fold2 - ~f:(fun acc x l -> - let open Syntax in - let* acc = acc in - f acc x l) - ~init - xs - xl - ;; - - let fold_right xs ~init ~f = - Base.List.fold_right xs ~init ~f:(fun x acc -> - let open Syntax in - let* acc = acc in - f x acc) - ;; - end - - let fresh : int t = fun last -> last + 1, Result.Ok last - let run m = snd (m 0) -end - -module Type = struct - type t = Ast.TypeExpr.t - - let rec occurs_check tvar = function - | Type_var binder -> binder = tvar - | Type_arrow (l, r) -> occurs_check tvar l || occurs_check tvar r - | Type_tuple (t1, t2, t) -> - List.fold_left (fun acc h -> acc || occurs_check tvar h) false (t1 :: t2 :: t) - | Type_construct (_, ty) -> - List.fold_left (fun acc h -> acc || occurs_check tvar h) false ty - ;; - - let free_vars = - let rec helper acc = function - | Type_var binder -> VarSet.add binder acc - | Type_arrow (l, r) -> helper (helper acc l) r - | Type_tuple (t1, t2, t) -> - List.fold_left (fun acc h -> helper acc h) acc (t1 :: t2 :: t) - | Type_construct (_, ty) -> List.fold_left (fun acc h -> helper acc h) acc ty - in - helper VarSet.empty - ;; -end - -module Substitution = struct - open MInfer - open MInfer.Syntax - open Base - - type t = (string, Type.t, Base.String.comparator_witness) Base.Map.t - - let empty = Map.empty (module Base.String) - - let singleton k v = - match k, v with - | a, Type_var b when String.equal a b -> return (Base.Map.empty (module Base.String)) - | _ -> - if Type.occurs_check k v - then fail (Occurs_check (k, v)) - else return (Base.Map.singleton (module Base.String) k v) - ;; - - let remove = Map.remove - - let apply sub = - let rec helper = function - | Type_var b as typ -> - (match Map.find sub b with - | Some b -> b - | None -> typ) - | Type_arrow (l, r) -> Type_arrow (helper l, helper r) - | Type_tuple (t1, t2, t) -> Type_tuple (helper t1, helper t2, List.map t ~f:helper) - | Type_construct (id, ty) -> Type_construct (id, List.map ty ~f:helper) - in - helper - ;; - - let fold mp init f = - Map.fold mp ~init ~f:(fun ~key:k ~data:vm acc -> - let* acc = acc in - f k vm acc) - ;; - - let rec unify l r = - match l, r with - | Type_var a, Type_var b when String.equal a b -> return empty - | Type_var b, t | t, Type_var b -> singleton b t - | Type_arrow (l1, r1), Type_arrow (l2, r2) -> - let* subs1 = unify l1 l2 in - let* subs2 = unify (apply subs1 r1) (apply subs1 r2) in - compose subs1 subs2 - | Type_tuple (l11, l12, l1), Type_tuple (l21, l22, l2) -> - (match - Base.List.fold2 - (l11 :: l12 :: l1) - (l21 :: l22 :: l2) - ~init:(return empty) - ~f:(fun acc t1 t2 -> - let* sub1 = acc in - let* sub2 = unify (apply sub1 t1) (apply sub1 t2) in - compose sub1 sub2) - with - | Ok sub -> sub - | _ -> fail (Unification_failed (l, r))) - | Type_construct (id1, ty1), Type_construct (id2, ty2) when String.equal id1 id2 -> - let* subs = - match - Base.List.fold2 ty1 ty2 ~init:(return empty) ~f:(fun acc t1 t2 -> - let* sub1 = acc in - let* sub2 = unify (apply sub1 t1) (apply sub1 t2) in - compose sub1 sub2) - with - | Ok sub -> sub - | _ -> fail (Unification_failed (l, r)) - in - return subs - | _ -> fail (Unification_failed (l, r)) - - and extend k v s = - match Map.find s k with - | None -> - let v = apply s v in - let* s2 = singleton k v in - fold s (return s2) (fun k v acc -> - let* acc = return acc in - let v = apply s2 v in - return (Map.update acc k ~f:(fun _ -> v))) - | Some v2 -> - let* s2 = unify v v2 in - compose s s2 - - and compose s1 s2 = fold s2 (return s1) extend - and compose_all ss = RList.fold_left ss ~init:(return empty) ~f:compose -end - -module Scheme = struct - type t = scheme - - let free_vars = function - | Forall (bs, t) -> VarSet.diff (Type.free_vars t) bs - ;; - - let apply subst (Forall (binder_set, typ)) = - let s2 = VarSet.fold (fun k s -> Substitution.remove s k) binder_set subst in - Forall (binder_set, Substitution.apply s2 typ) - ;; - - let pp_scheme fmt = function - | Forall (st, typ) -> - if VarSet.is_empty st - then - Format.fprintf - fmt - "%a" - (pprint_type ~poly_names_map:(Base.Map.empty (module Base.String))) - typ - else - Format.fprintf - fmt - "%a. %a" - VarSet.pp - st - (pprint_type ~poly_names_map:(Base.Map.empty (module Base.String))) - typ - ;; -end - -module TypeEnv = struct - open Base - - type t = (string, scheme, String.comparator_witness) Map.t - - let extend env name scheme = Map.set env ~key:name ~data:scheme - let empty = Map.empty (module String) - let fold f init mp = Map.fold mp ~init ~f:(fun ~key:k ~data:v acc -> f k v acc) - - let free_vars : t -> VarSet.t = - fold (fun _ s acc -> VarSet.union acc (Scheme.free_vars s)) VarSet.empty - ;; - - let apply s env = Map.map env ~f:(Scheme.apply s) - let find name xs = Map.find xs name - let find_exn name xs = Map.find_exn xs name - let remove sub k = Base.Map.remove sub k - - let pp_env fmt environment = - Map.iteri environment ~f:(fun ~key ~data -> - Stdlib.Format.fprintf fmt "%S: %a\n" key Scheme.pp_scheme data) - ;; -end - -open MInfer -open MInfer.Syntax - -let fresh_var = fresh >>| fun n -> Type_var (Int.to_string n) - -let instantiate : scheme -> Ast.TypeExpr.t MInfer.t = - fun (Forall (bs, t)) -> - VarSet.fold - (fun name typ -> - let* typ = typ in - let* f1 = fresh_var in - let* s = Substitution.singleton name f1 in - return (Substitution.apply s typ)) - bs - (return t) -;; - -let generalize : TypeEnv.t -> Type.t -> Scheme.t = - fun env ty -> - let free = VarSet.diff (Type.free_vars ty) (TypeEnv.free_vars env) in - Forall (free, ty) -;; - -open Ast.Constant -open Ast.Expression -open Ast.Pattern - -let rec infer_pat ~debug pat env = - match pat with - | Pat_any -> - let* fresh = fresh_var in - return (env, fresh) - | Pat_var ident -> - let* fresh = fresh_var in - let new_env = TypeEnv.extend env ident (Forall (VarSet.empty, fresh)) in - return (new_env, fresh) - | Pat_constant const -> - (match const with - | Const_char _ -> return (env, Type_construct ("char", [])) - | Const_integer _ -> return (env, Type_construct ("int", [])) - | Const_string _ -> return (env, Type_construct ("string", []))) - | Pat_tuple (pat1, pat2, rest) -> - let* env1, typ1 = infer_pat ~debug pat1 env in - let* env2, typ2 = infer_pat ~debug pat2 env1 in - let* env3, typ3 = - RList.fold_right - ~f:(fun pat acc -> - let* env_acc, typ_list = return acc in - let* env, typ = infer_pat ~debug pat env_acc in - return (env, typ :: typ_list)) - ~init:(return (env2, [])) - rest - in - return (env3, Type_tuple (typ1, typ2, typ3)) - | Pat_construct (name, pat) -> - (match TypeEnv.find name env with - | None -> fail (Unbound_variable name) - | Some (Forall (x, Type_arrow (arg, adt))) -> - let* typ = instantiate (Forall (x, Type_arrow (arg, adt))) in - (match pat with - | Some const_pat -> - let* patenv, typepat = infer_pat ~debug const_pat env in - let* uni_sub = Substitution.unify arg typepat in - let new_env = TypeEnv.apply uni_sub patenv in - return (new_env, Substitution.apply uni_sub adt) - | None -> return (env, typ)) - | Some el -> - let* typ = instantiate el in - return (env, typ)) - | Pat_constraint (pat, typ) -> - let* pat_env, pat_typ = infer_pat ~debug pat env in - let* uni_sub = Substitution.unify pat_typ typ in - let new_env = TypeEnv.apply uni_sub pat_env in - return (new_env, Substitution.apply uni_sub pat_typ) -;; - -let rec extend_helper env pat (Forall (binder_set, typ) as scheme) = - match pat, typ with - | Pat_var name, _ -> TypeEnv.extend env name scheme - | Pat_tuple (p1, p2, prest), Type_tuple (t1, t2, trest) -> - let new_env = - Base.List.fold2 - ~init:env - ~f:(fun env pat typ -> extend_helper env pat (Forall (binder_set, typ))) - (p1 :: p2 :: prest) - (t1 :: t2 :: trest) - in - (match new_env with - | Ok new_env -> new_env - | _ -> env) - | _ -> env -;; - -let add_names_rec env vb_list = - RList.fold_right - ~f:(fun vb acc -> - match vb with - | { pat = Pat_var name; _ } | { pat = Pat_constraint (Pat_var name, _); _ } -> - let* env_acc, fresh_acc = return acc in - let* fresh = fresh_var in - let env_acc = TypeEnv.extend env_acc name (Forall (VarSet.empty, fresh)) in - return (env_acc, fresh :: fresh_acc) - | _ -> fail Wrong_rec) - vb_list - ~init:(return (env, [])) -;; - -let infer_rest_vb ~debug env_acc sub_acc sub typ pat = - let* comp_sub = Substitution.compose sub_acc sub in - let new_env = TypeEnv.apply comp_sub env_acc in - let new_scheme = generalize new_env (Substitution.apply comp_sub typ) in - let* pat_env, pat_typ = infer_pat ~debug pat new_env in - let new_env = extend_helper pat_env pat new_scheme in - let* uni_sub = Substitution.unify typ pat_typ in - let* res_sub = Substitution.compose comp_sub uni_sub in - let res_env = TypeEnv.apply res_sub new_env in - return (res_env, res_sub) -;; - -let infer_rec_rest_vb sub_acc env_acc fresh typ name new_sub = - let* uni_sub = Substitution.unify (Substitution.apply new_sub fresh) typ in - let* comp_sub = Substitution.compose_all [ new_sub; uni_sub; sub_acc ] in - let env_acc = TypeEnv.apply comp_sub env_acc in - let env_rm = TypeEnv.remove env_acc name in - let new_scheme = generalize env_rm (Substitution.apply comp_sub fresh) in - let env_acc = TypeEnv.extend env_acc name new_scheme in - return (env_acc, comp_sub) -;; - -let rec get_pat_names acc pat = - match pat with - | Pat_var id -> id :: acc - | Pat_tuple (pat1, pat2, rest) -> - Base.List.fold_left ~f:get_pat_names ~init:acc (pat1 :: pat2 :: rest) - | Pat_construct ("Some", Some pat) -> get_pat_names acc pat - | Pat_constraint (pat, _) -> get_pat_names acc pat - | _ -> acc -;; - -let rec infer_exp ~debug exp env = - match exp with - | Exp_ident varname -> - (match TypeEnv.find varname env with - | None -> fail (Unbound_variable varname) - | Some x -> - let* typ = instantiate x in - return (Substitution.empty, typ)) - | Exp_constant const -> - (match const with - | Const_char _ -> return (Substitution.empty, Type_construct ("char", [])) - | Const_integer _ -> return (Substitution.empty, Type_construct ("int", [])) - | Const_string _ -> return (Substitution.empty, Type_construct ("string", []))) - | Exp_apply (Exp_ident op, Exp_tuple (exp1, exp2, [])) -> - (match op with - | "*" | "/" | "+" | "-" | "<" | ">" | "=" | "<>" | "<=" | ">=" | "&&" | "||" -> - let* sub1, typ1 = infer_exp ~debug exp1 env in - let* sub2, typ2 = infer_exp ~debug exp2 (TypeEnv.apply sub1 env) in - let* arg_typ, res_typ = - match TypeEnv.find op env with - | Some (Forall (_, Type_arrow (Type_arrow (arg, _), res))) -> return (arg, res) - | _ -> fail @@ Unsupported_operator op - in - let* unif_sub1 = Substitution.unify (Substitution.apply sub2 typ1) arg_typ in - let* unif_sub2 = Substitution.unify (Substitution.apply unif_sub1 typ2) arg_typ in - let* comp_sub = Substitution.compose_all [ sub1; sub2; unif_sub1; unif_sub2 ] in - return (comp_sub, res_typ) - | _ -> - let* sub1, typ1 = infer_exp ~debug (Exp_ident op) env in - let* sub2, typ2 = - infer_exp ~debug (Exp_tuple (exp1, exp2, [])) (TypeEnv.apply sub1 env) - in - let* fresh = fresh_var in - let* unif_sub = - Substitution.unify (Substitution.apply sub2 typ1) (Type_arrow (typ2, fresh)) - in - let* comp_sub = Substitution.compose_all [ unif_sub; sub2; sub1 ] in - let res_typ = Substitution.apply comp_sub fresh in - return (comp_sub, res_typ)) - | Exp_apply (exp1, exp2) -> - (match exp1 with - | Exp_ident op when op = "+" || op = "-" -> - let* sub1, typ1 = infer_exp ~debug exp2 env in - let* unif_sub = Substitution.unify typ1 (Type_construct ("int", [])) in - let* comp_sub = Substitution.compose sub1 unif_sub in - return (comp_sub, Type_construct ("int", [])) - | _ -> - let* sub1, typ1 = infer_exp ~debug exp1 env in - let* sub2, typ2 = infer_exp ~debug exp2 (TypeEnv.apply sub1 env) in - let* fresh = fresh_var in - let* unif_sub = - Substitution.unify (Substitution.apply sub2 typ1) (Type_arrow (typ2, fresh)) - in - let* comp_sub = Substitution.compose_all [ unif_sub; sub2; sub1 ] in - let res_typ = Substitution.apply comp_sub fresh in - return (comp_sub, res_typ)) - | Exp_fun ((pattern, patterns), expr) -> - let* new_env, typ1 = infer_pat ~debug pattern env in - let* sub1, typ2 = - match patterns with - | hd :: tl -> infer_exp ~debug (Exp_fun ((hd, tl), expr)) new_env - | [] -> infer_exp ~debug expr new_env - in - return (sub1, Type_arrow (Substitution.apply sub1 typ1, typ2)) - | Exp_construct (name, Some expr) -> - let* ty, sub = infer_exp ~debug (Exp_apply (Exp_ident name, expr)) env in - return (ty, sub) - | Exp_construct (name, None) -> - let* ty, sub = infer_exp ~debug (Exp_ident name) env in - return (ty, sub) - | Exp_tuple (exp1, exp2, rest) -> - let* sub1, typ1 = infer_exp ~debug exp1 env in - let new_env = TypeEnv.apply sub1 env in - let* sub2, typ2 = infer_exp ~debug exp2 new_env in - let new_env = TypeEnv.apply sub2 new_env in - let* sub3, typ3 = - RList.fold_right - ~f:(fun exp acc -> - let* sub_acc, typ_list = return acc in - let new_env = TypeEnv.apply sub_acc new_env in - let* sub, typ = infer_exp ~debug exp new_env in - let* sub_acc = Substitution.compose sub_acc sub in - return (sub_acc, typ :: typ_list)) - ~init:(return (Substitution.empty, [])) - rest - in - let* fin_sub = Substitution.compose_all [ sub1; sub2; sub3 ] in - let typ1 = Substitution.apply fin_sub typ1 in - let typ2 = Substitution.apply fin_sub typ2 in - let typ3 = List.map (fun typ -> Substitution.apply fin_sub typ) typ3 in - return (fin_sub, Type_tuple (typ1, typ2, typ3)) - | Exp_if (ifexp, thenexp, Some elseexp) -> - let* sub1, typ1 = infer_exp ~debug ifexp env in - let* uni_sub1 = Substitution.unify typ1 (Type_construct ("bool", [])) in - let* sub2, typ2 = infer_exp ~debug thenexp env in - let* sub3, typ3 = infer_exp ~debug elseexp env in - let* uni_sub2 = Substitution.unify typ2 typ3 in - let* comp_sub = Substitution.compose_all [ sub1; uni_sub1; sub2; sub3; uni_sub2 ] in - return (comp_sub, typ3) - | Exp_if (ifexp, thenexp, None) -> - let* sub1, typ1 = infer_exp ~debug ifexp env in - let* uni_sub1 = Substitution.unify typ1 (Type_construct ("bool", [])) in - let* sub2, typ2 = infer_exp ~debug thenexp env in - let* comp_sub = Substitution.compose_all [ sub1; uni_sub1; sub2 ] in - return (comp_sub, typ2) - | Exp_match (expr, (case, rest)) -> - let* subexpr, typexpr = infer_exp ~debug expr env in - let new_env = TypeEnv.apply subexpr env in - let* fresh = fresh_var in - let* res_sub, res_typ = - RList.fold_left - (case :: rest) - ~init:(return (subexpr, fresh)) - ~f:(fun acc case -> - let* sub, typ = return acc in - let pat_names = get_pat_names [] case.first in - let* pat_env, pat_typ = infer_pat ~debug case.first new_env in - let* uni_sub = Substitution.unify pat_typ typexpr in - let* comp_sub = Substitution.compose sub uni_sub in - let pat_env = - Base.List.fold_left - ~f:(fun env name -> - let (Forall (_, typ)) = TypeEnv.find_exn name env in - let env = TypeEnv.remove env name in - TypeEnv.extend env name (generalize env typ)) - ~init:(TypeEnv.apply uni_sub pat_env) - pat_names - in - let* subexpr, typexpr = - infer_exp ~debug case.second (TypeEnv.apply comp_sub pat_env) - in - let* uni_sub2 = Substitution.unify typexpr typ in - let* res_sub = Substitution.compose_all [ uni_sub2; subexpr; comp_sub ] in - return (res_sub, Substitution.apply res_sub typ)) - in - return (res_sub, res_typ) - | Exp_function (case, rest) -> - let* fresh1 = fresh_var in - let* fresh2 = fresh_var in - let* res_sub, res_typ = - RList.fold_left - (case :: rest) - ~init:(return (Substitution.empty, fresh2)) - ~f:(fun acc case -> - let* sub, typ = return acc in - let* pat_env, pat_typ = infer_pat ~debug case.first env in - let* uni_sub1 = Substitution.unify pat_typ fresh1 in - let* sub1 = Substitution.compose uni_sub1 sub in - let new_env = TypeEnv.apply sub1 pat_env in - let* subexpr, typexpr = infer_exp ~debug case.second new_env in - let* uni_sub2 = Substitution.unify typ typexpr in - let* comp_sub = Substitution.compose_all [ uni_sub2; subexpr; sub1 ] in - return (comp_sub, Substitution.apply comp_sub typ)) - in - return (res_sub, Type_arrow (Substitution.apply res_sub fresh1, res_typ)) - | Exp_let (Nonrecursive, (value_binding, rest), exp) -> - let* new_env, sub, _ = - infer_value_binding_list ~debug (value_binding :: rest) env Substitution.empty - in - let* subb, typp = infer_exp ~debug exp new_env in - let* comp_sub = Substitution.compose sub subb in - return (comp_sub, typp) - | Exp_let (Recursive, (value_binding, rest), exp) -> - let* new_env, fresh_vars = add_names_rec env (value_binding :: rest) in - let* new_env, sub, _ = - infer_rec_value_binding_list - ~debug - (value_binding :: rest) - new_env - Substitution.empty - fresh_vars - in - let* subb, typp = infer_exp ~debug exp new_env in - let* comp_sub = Substitution.compose subb sub in - return (comp_sub, typp) - | Exp_constraint (expr, typ) -> - let* sub, typ1 = infer_exp ~debug expr env in - let* uni_sub = Substitution.unify typ1 typ in - let* comp_sub = Substitution.compose sub uni_sub in - return (comp_sub, typ1) - -and infer_value_binding_list ~debug vb_list env sub = - let* res_env, res_sub, names = - RList.fold_left - vb_list - ~init:(return (env, sub, [])) - ~f:(fun acc vb -> - let* env_acc, sub_acc, names = return acc in - match vb with - | { pat = Pat_constraint (pat, pat_typ); expr = Exp_fun ((fpat, fpatrest), exp) } - -> - let* sub, typ = - infer_exp - ~debug - (Exp_fun ((fpat, fpatrest), Exp_constraint (exp, pat_typ))) - env_acc - in - let* res_env, res_sub = infer_rest_vb ~debug env_acc sub_acc sub typ pat in - let name = get_pat_names names pat in - return (res_env, res_sub, names @ name) - | { pat = Pat_constraint (pat, pat_typ); expr = Exp_function _ as exp } -> - let* sub, typ = infer_exp ~debug (Exp_constraint (exp, pat_typ)) env_acc in - let* res_env, res_sub = infer_rest_vb ~debug env_acc sub_acc sub typ pat in - let name = get_pat_names names pat in - return (res_env, res_sub, names @ name) - | { pat; expr } -> - let* sub, typ = infer_exp ~debug expr env_acc in - let* res_env, res_sub = infer_rest_vb ~debug env_acc sub_acc sub typ pat in - let name = get_pat_names names pat in - return (res_env, res_sub, names @ name)) - in - return (res_env, res_sub, names) - -and infer_rec_value_binding_list ~debug vb_list env sub fresh_vars = - let* res_env, res_sub, names = - match - RList.fold_left2 - vb_list - fresh_vars - ~init:(return (env, sub, [])) - ~f:(fun acc vb fv -> - let* env_acc, sub_acc, names = return acc in - match vb, fv with - | ( ( { pat = Pat_var name; expr = Exp_fun _ as exp } - | { pat = Pat_var name; expr = Exp_function _ as exp } ) - , fresh ) -> - let* subexpr, typexpr = infer_exp ~debug exp env_acc in - let* res_env, res_sub = - infer_rec_rest_vb sub_acc env_acc fresh typexpr name subexpr - in - return (res_env, res_sub, names @ [ name ]) - | ( { pat = Pat_constraint (Pat_var name, pat_typ) - ; expr = Exp_fun ((pat, pat_list), expr) - } - , fresh ) -> - let* subexpr, typexpr = - infer_exp - ~debug - (Exp_fun ((pat, pat_list), Exp_constraint (expr, pat_typ))) - env - in - let* res_env, res_sub = - infer_rec_rest_vb sub_acc env_acc fresh typexpr name subexpr - in - return (res_env, res_sub, names @ [ name ]) - | { pat = Pat_var name; expr }, fresh -> - let* subexpr, typexpr = infer_exp ~debug expr env_acc in - (match typexpr with - | Type_arrow (_, _) -> - let new_fresh = Substitution.apply sub_acc fresh in - if typexpr = new_fresh - then fail Wrong_rec - else - let* res_env, res_sub = - infer_rec_rest_vb sub_acc env_acc fresh typexpr name subexpr - in - return (res_env, res_sub, names @ [ name ]) - | _ -> fail Wrong_rec) - | _ -> fail Wrong_rec) - with - | Ok result -> result - | Unequal_lengths -> fail Incorrect_list_lengths - in - return (res_env, res_sub, names) -;; - -open Ast.Structure - -let rec check_poly_types ~debug typ_list marity = function - | Type_var var when Base.List.mem typ_list var ~equal:String.equal -> return () - | Type_var name -> fail (Unbound_variable name) - | Type_construct (name, args) -> - let* arity = - Base.Map.find marity name - |> Base.Option.value_map ~f:return ~default:(fail (Undeclared_type name)) - in - if arity = Base.List.length args - then check_many ~debug typ_list marity args - else fail Arity_mismatch - | Type_arrow (l, r) -> - let* () = check_poly_types ~debug typ_list marity l in - check_poly_types ~debug typ_list marity r - | Type_tuple (t1, t2, rest) -> - let* () = check_poly_types ~debug typ_list marity t1 in - let* () = check_poly_types ~debug typ_list marity t2 in - check_many ~debug typ_list marity rest - -and check_many ~debug typ_list marity args = - let rec iter = function - | [] -> return () - | arg :: rest -> - let* () = check_poly_types ~debug typ_list marity arg in - iter rest - in - iter args -;; - -let ( ! ) fresh = Type_var fresh - -let infer_structure_item ~debug env item marity names = - match item with - | Str_eval exp -> - let* _, typ = infer_exp ~debug exp env in - let new_env = TypeEnv.extend env "-" (Forall (VarSet.empty, typ)) in - return (new_env, marity, names @ [ "-" ]) - | Str_value (Nonrecursive, (value_binding, rest)) -> - let* env, _, names = - infer_value_binding_list ~debug (value_binding :: rest) env Substitution.empty - in - return (env, marity, names) - | Str_value (Recursive, (value_binding, rest)) -> - let* new_env, fresh_vars = add_names_rec env (value_binding :: rest) in - let* new_env, _, names = - infer_rec_value_binding_list - ~debug - (value_binding :: rest) - new_env - Substitution.empty - fresh_vars - in - return (new_env, marity, names) - | Str_adt (poly, name, (variant, rest)) -> - let adt_type = Type_construct (name, Base.List.map poly ~f:( ! )) in - let type_arity = List.length poly in - let arity_map = Base.Map.set marity ~key:name ~data:type_arity in - let* constrs = - RList.fold_left - (variant :: rest) - ~init:(return env) - ~f:(fun acc (constr_name, constr_types) -> - let* env_acc = return acc in - let* fresh = fresh in - let* new_env = - match constr_types with - | None -> - return - (TypeEnv.extend - env_acc - constr_name - (Forall (VarSet.singleton (Int.to_string fresh), adt_type))) - | Some typ -> - let* () = check_poly_types ~debug poly arity_map typ in - return - (TypeEnv.extend - env_acc - constr_name - (Forall (VarSet.of_list poly, Type_arrow (typ, adt_type)))) - in - return new_env) - in - return (constrs, arity_map, names) -;; - -let infer_program ~debug program env = - let marity = Base.Map.empty (module Base.String) in - let marity = Base.Map.add_exn marity ~key:"int" ~data:0 in - let marity = Base.Map.add_exn marity ~key:"char" ~data:0 in - let marity = Base.Map.add_exn marity ~key:"string" ~data:0 in - let marity = Base.Map.add_exn marity ~key:"bool" ~data:0 in - let marity = Base.Map.add_exn marity ~key:"unit" ~data:0 in - let* env, _, names = - RList.fold_left - program - ~init:(return (env, marity, [])) - ~f:(fun acc item -> - let* env_acc, arr_acc, names = return acc in - let* env, arr, name = infer_structure_item ~debug env_acc item arr_acc names in - return (env, arr, names @ name)) - in - return (env, names) -;; - -let env_with_things = - let things_list = - [ ( "+" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("int", []), Type_construct ("int", [])) - , Type_construct ("int", []) ) ) ) - ; ( "-" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("int", []), Type_construct ("int", [])) - , Type_construct ("int", []) ) ) ) - ; ( "*" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("int", []), Type_construct ("int", [])) - , Type_construct ("int", []) ) ) ) - ; ( "/" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("int", []), Type_construct ("int", [])) - , Type_construct ("int", []) ) ) ) - ; ( "<" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( ">" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( "<>" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( "<=" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( ">=" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( "=" - , Forall - ( VarSet.singleton "a" - , Type_arrow - (Type_arrow (Type_var "a", Type_var "a"), Type_construct ("bool", [])) ) ) - ; ( "||" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("bool", []), Type_construct ("bool", [])) - , Type_construct ("bool", []) ) ) ) - ; ( "&&" - , Forall - ( VarSet.empty - , Type_arrow - ( Type_arrow (Type_construct ("bool", []), Type_construct ("bool", [])) - , Type_construct ("bool", []) ) ) ) - ; ( "print_int" - , Forall - ( VarSet.empty - , Type_arrow (Type_construct ("int", []), Type_construct ("unit", [])) ) ) - ; ( "print_endline" - , Forall - ( VarSet.empty - , Type_arrow (Type_construct ("string", []), Type_construct ("unit", [])) ) ) - ; ( "print_char" - , Forall - ( VarSet.empty - , Type_arrow (Type_construct ("char", []), Type_construct ("unit", [])) ) ) - ; ( "print_bool" - , Forall - ( VarSet.empty - , Type_arrow (Type_construct ("bool", []), Type_construct ("unit", [])) ) ) - ; ( "Some" - , Forall - ( VarSet.singleton "a" - , Type_arrow (Type_var "a", Type_construct ("option", [ Type_var "a" ])) ) ) - ; "None", Forall (VarSet.singleton "a", Type_construct ("option", [ Type_var "a" ])) - ; ( "::" - , Forall - ( VarSet.singleton "a" - , Type_arrow - ( Type_tuple (Type_var "a", Type_construct ("list", [ Type_var "a" ]), []) - , Type_construct ("list", [ Type_var "a" ]) ) ) ) - ; "[]", Forall (VarSet.singleton "a", Type_construct ("list", [ Type_var "a" ])) - ; "()", Forall (VarSet.empty, Type_construct ("unit", [])) - ; "true", Forall (VarSet.empty, Type_construct ("bool", [])) - ; "false", Forall (VarSet.empty, Type_construct ("bool", [])) - ] - in - List.fold_left - (fun env (id, sch) -> TypeEnv.extend env id sch) - TypeEnv.empty - things_list -;; - -let run_infer_program ?(debug = false) (program : Ast.program) env = - run (infer_program ~debug program env) -;; diff --git a/OcamlADT/lib/infer.mli b/OcamlADT/lib/infer.mli deleted file mode 100644 index d706807ac..000000000 --- a/OcamlADT/lib/infer.mli +++ /dev/null @@ -1,30 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open InferTypes - -module Type : sig - type t = Ast.TypeExpr.t - - val occurs_check : string -> t -> bool - val free_vars : t -> VarSet.t -end - -module Substitution : sig - type t = (string, Type.t, Base.String.comparator_witness) Base.Map.t -end - -module TypeEnv : sig - type t = (string, scheme, Base.String.comparator_witness) Base.Map.t - - val pp_env : Format.formatter -> t -> unit -end - -val env_with_things : TypeEnv.t - -val run_infer_program - : ?debug:bool - -> Ast.program - -> TypeEnv.t - -> (TypeEnv.t * string list, InferTypes.error) Result.t diff --git a/OcamlADT/lib/inferTypes.ml b/OcamlADT/lib/inferTypes.ml deleted file mode 100644 index 007c97804..000000000 --- a/OcamlADT/lib/inferTypes.ml +++ /dev/null @@ -1,188 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Format -open Ast.TypeExpr -open Stdlib - -type binder = int [@@deriving show { with_path = false }] - -module VarSet = struct - include Set.Make (String) - - let pp ppf s = - Format.fprintf ppf "[ "; - iter (Format.fprintf ppf "%s; ") s; - Format.fprintf ppf "]" - ;; -end - -type binder_set = VarSet.t [@@deriving show { with_path = false }] -type scheme = Forall of binder_set * t [@@deriving show { with_path = false }] - -open Base - -(* get polymorphic type names from VarSet *) -let binder_to_list args = - let args = VarSet.elements args in - List.sort (List.map args ~f:Int.of_string) ~compare:Int.compare -;; - -(** turn ['2, '5, '1231, ...] (value is not important, only order) list of - names of polymorphic types into ['a, 'b, 'c ... ] - when english alphabet is out, turn values into ['aa, 'bb, ...] and etc.*) -let minimize dargs = - let counter = 0 in - let coef = 0 in - let m = Map.empty (module Base.String) in - List.fold_left dargs ~init:(m, coef, counter) ~f:(fun (m, coef, counter) el -> - let str = - let rec build coef counter str = - if coef = 0 - then str ^ Char.escaped (Stdlib.Char.chr (counter + 97)) - else build (coef - 1) counter (str ^ Char.escaped (Stdlib.Char.chr (counter + 97))) - in - build coef counter "" - in - let counter = counter + 1 in - let coef = coef + (counter / 26) in - let counter = counter % 26 in - let el = Stdlib.string_of_int el in - Base.Map.set m ~key:el ~data:str, coef, counter) -;; - -let rec pprint_type_tuple ?(poly_names_map = Map.empty (module String)) fmt = function - | [] -> () - | [ h ] -> - (match h with - | Type_arrow (_, _) -> fprintf fmt "(%a)" (pprint_type ~poly_names_map) h - | _ -> fprintf fmt "%a" (pprint_type ~poly_names_map) h) - | h :: tl -> - (match h with - | Type_arrow (_, _) -> - fprintf - fmt - "(%a) * %a" - (pprint_type ~poly_names_map) - h - (pprint_type_tuple ~poly_names_map) - tl - | _ -> - fprintf - fmt - "%a * %a" - (pprint_type ~poly_names_map) - h - (pprint_type_tuple ~poly_names_map) - tl) - -and pprint_type ?(poly_names_map = Map.empty (module String)) fmt = function - | Type_var num -> - (match Map.find poly_names_map num with - | Some k -> fprintf fmt "'%s" k - | None -> fprintf fmt "'%s" num) - | Type_arrow (ty1, ty2) -> - (match ty1, ty2 with - | Type_arrow (_, _), _ -> - fprintf - fmt - "(%a) -> %a" - (pprint_type ~poly_names_map) - ty1 - (pprint_type ~poly_names_map) - ty2 - | _ -> - fprintf - fmt - "%a -> %a" - (pprint_type ~poly_names_map) - ty1 - (pprint_type ~poly_names_map) - ty2) - | Type_tuple (t1, t2, ty_lst) -> - fprintf fmt "%a" (pprint_type_tuple ~poly_names_map) (t1 :: t2 :: ty_lst) - | Type_construct (name, []) -> fprintf fmt "%s" name - | Type_construct (name, ty_list) -> - fprintf fmt "%a %s" (pprint_type_list_with_parens ~poly_names_map) ty_list name - -and pprint_type_list_with_parens ?(poly_names_map = Map.empty (module String)) fmt ty_list - = - let rec print_types fmt = function - | [] -> () - | [ ty ] -> (pprint_type_with_parens_if_tuple ~poly_names_map) fmt ty - | ty :: rest -> - fprintf - fmt - "%a %a" - (pprint_type_with_parens_if_tuple ~poly_names_map) - ty - print_types - rest - in - print_types fmt ty_list - -and pprint_type_with_parens_if_tuple ?(poly_names_map = Map.empty (module String)) fmt ty = - match ty with - | Type_tuple _ -> fprintf fmt "(%a)" (pprint_type ~poly_names_map) ty - | _ -> (pprint_type ~poly_names_map) fmt ty -;; - -(*errors*) -type error = - | Occurs_check of string * Ast.TypeExpr.t - (** same polymotphic type occured while substitution apply ['a : 'a -> 'b]*) - | Unification_failed of Ast.TypeExpr.t * Ast.TypeExpr.t - | Unbound_variable of string - | Arity_mismatch - (** mismatch of types arity - [type 'a foo = Foo - type bar = Bar of foo] *) - | Undeclared_type of string - | Wrong_rec (** invalid right value in recursive let declaration *) - | Unsupported_operator of string (** for binary operators*) - | Incorrect_list_lengths - -let collect_type_vars typ = - let rec aux acc = function - | Type_var num -> num :: acc - | Type_arrow (t1, t2) -> aux (aux acc t1) t2 - | Type_tuple (t1, t2, tl) -> List.fold_left ~f:aux ~init:(aux (aux acc t1) t2) tl - | Type_construct (_, ty_list) -> List.fold_left ~f:aux ~init:acc ty_list - in - aux [] typ -;; - -let collect_vars_from_error = function - | Occurs_check (str, typ) -> str :: collect_type_vars typ - | Unification_failed (t1, t2) -> collect_type_vars t1 @ collect_type_vars t2 - | _ -> [] -;; - -let pp_inf_err fmt err = - let type_vars = collect_vars_from_error err in - let var_map, _, _ = minimize (List.map type_vars ~f:Stdlib.int_of_string) in - match err with - | Occurs_check (str, t) -> - fprintf - fmt - "Occurs_check: %a and %a\n" - (pprint_type ~poly_names_map:var_map) - (Type_var str) - (pprint_type ~poly_names_map:var_map) - t - | Unification_failed (typ1, typ2) -> - fprintf - fmt - "Unification_failed: %a # %a" - (pprint_type ~poly_names_map:var_map) - typ1 - (pprint_type ~poly_names_map:var_map) - typ2 - | Unbound_variable str -> fprintf fmt "Unbound_variable: %S" str - | Arity_mismatch -> fprintf fmt "Arity_mismatch" - | Undeclared_type str -> fprintf fmt "Undeclared_type: %S" str - | Wrong_rec -> fprintf fmt "Wrong right value in rec" - | Unsupported_operator op -> fprintf fmt "Operator %s is not supported" op - | Incorrect_list_lengths -> fprintf fmt "Lists have unequal lengths" -;; diff --git a/OcamlADT/lib/inferTypes.mli b/OcamlADT/lib/inferTypes.mli deleted file mode 100644 index 3076c30e9..000000000 --- a/OcamlADT/lib/inferTypes.mli +++ /dev/null @@ -1,42 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Format -open Ast.TypeExpr -open Stdlib - -type binder = int [@@deriving show] - -module VarSet : sig - include Set.S with type elt = string - - val pp : formatter -> t -> unit -end - -type binder_set = VarSet.t [@@deriving show] -type scheme = Forall of binder_set * t [@@deriving show] - -val binder_to_list : binder_set -> int list - -val minimize - : int list - -> (string, string, Base.String.comparator_witness) Base.Map.t * int * int - -val pprint_type - : ?poly_names_map:(string, string, Base.String.comparator_witness) Base.Map.t - -> formatter - -> t - -> unit - -type error = - | Occurs_check of string * t - | Unification_failed of t * t - | Unbound_variable of string - | Arity_mismatch - | Undeclared_type of string - | Wrong_rec - | Unsupported_operator of string - | Incorrect_list_lengths - -val pp_inf_err : formatter -> error -> unit diff --git a/OcamlADT/lib/interpreter.ml b/OcamlADT/lib/interpreter.ml deleted file mode 100644 index 27d4a3e18..000000000 --- a/OcamlADT/lib/interpreter.ml +++ /dev/null @@ -1,729 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type error = - | DivisionByZero - | TypeMismatch (* just a stub for interp unit tests + some below *) - | UnboundVariable of string - | PatternMismatch - | RecursionError - | EmptyProgram - | ParserError - | NotAnADT of string - | NotAnADTVariant of string - | UndefinedConstructor of string - | UndefinedArgs - -type value = - | VInt of int - | VString of string - | VChar of char - | VBool of bool - | VTuple of value List2.t - | VFun of Pattern.t List1.t * Expression.t * environment * Expression.rec_flag - | VFunction of Expression.t Expression.case List1.t * environment - | VConstruct of ident * value option - | VAdt of (value * ident list * ident * (ident * TypeExpr.t option) List1.t) - (* ident list is being left for type printing *) - | VUnit - | VType of TypeExpr.t * ident option (* ident - adt type name *) - | VBuiltin_binop of (value -> value -> (value, error) Result.t) - | VBuiltin_print of (value -> (value, error) Result.t) - -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -let compare_values v1 v2 = - match v1, v2 with - | VInt i1, VInt i2 -> i1 = i2 - | VString s1, VString s2 -> Base.String.equal s1 s2 - | VChar c1, VChar c2 -> Base.Char.equal c1 c2 - | _ -> false -;; - -let list1_to_list2 = function - | el1, el2 :: ell -> Some (el1, el2, ell) - | _ -> None -;; - -let make_list1 = function - | [] -> None - | x :: xs -> Some (x, xs) -;; - -let to_bool = function - | VBool b -> b - | VInt n -> n <> 0 - | _ -> raise (Invalid_argument "TypeMismatch") -;; - -module type Error_monad = sig - (* 'a - successfull value, 'e - error type *) - type ('a, 'e) t - - (* Wraps in Result type *) - val return : 'a -> ('a, 'e) t - - (* Monad interface description *) - val fail : 'e -> ('a, 'e) t - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -module Env (M : Error_monad) = struct - (*Environment functor that is used to store the initialized data in some scope. - It is treated like an abstract mapping (a lil different from one in TypeInf)*) - - open M - - let builtin_bools = - Base.Map.of_alist_exn - (module Base.String) - [ "true", VBool true; "false", VBool false ] - ;; - - let builtin_functions = - Base.Map.of_alist_exn - (module Base.String) - [ ( "print_endline" - , VBuiltin_print - (function - | VString s -> - print_endline s; - Ok VUnit - | _ -> Error TypeMismatch) ) - ; ( "print_int" - , VBuiltin_print - (function - | VInt i -> - print_endline (string_of_int i); - Ok VUnit - | _ -> Error TypeMismatch) ) - ; ( "print_char" - , VBuiltin_print - (function - | VChar c -> - print_endline (String.make 1 c); - Ok VUnit - | _ -> Error TypeMismatch) ) - ; ( "print_bool" - , VBuiltin_print - (function - | VBool b -> - print_endline (string_of_bool b); - Ok VUnit - | _ -> Error TypeMismatch) ) - ] - ;; - - let create_binop f = - VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VInt (f a b)) - | _ -> Error TypeMismatch) - ;; - - let builtin_binops = - Base.Map.of_alist_exn - (module Base.String) - [ "+", create_binop ( + ) - ; "-", create_binop ( - ) - ; "*", create_binop ( * ) - ; ( "/" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt _, VInt 0 -> Error DivisionByZero - | VInt a, VInt b -> Ok (VInt (a / b)) - | _ -> Error TypeMismatch) ) - ; ( "=" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a = b)) - | VBool a, VBool b -> Ok (VBool (a = b)) - | VString a, VString b -> Ok (VBool (a = b)) - | VChar a, VChar b -> Ok (VBool (a = b)) - | _ -> Error TypeMismatch) ) - ; ( ">" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a > b)) - | VString a, VString b -> Ok (VBool (a > b)) - | VChar a, VChar b -> Ok (VBool (a > b)) - | _ -> Error TypeMismatch) ) - ; ( "<" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a < b)) - | VString a, VString b -> Ok (VBool (a < b)) - | VChar a, VChar b -> Ok (VBool (a < b)) - | _ -> Error TypeMismatch) ) - ; ( ">=" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a >= b)) - | VString a, VString b -> Ok (VBool (a >= b)) - | VChar a, VChar b -> Ok (VBool (a >= b)) - | _ -> Error TypeMismatch) ) - ; ( "<=" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a <= b)) - | VString a, VString b -> Ok (VBool (a <= b)) - | VChar a, VChar b -> Ok (VBool (a <= b)) - | _ -> Error TypeMismatch) ) - ; ( "<>" - , VBuiltin_binop - (fun v1 v2 -> - match v1, v2 with - | VInt a, VInt b -> Ok (VBool (a <> b)) - | VString a, VString b -> Ok (VBool (a <> b)) - | VChar a, VChar b -> Ok (VBool (a <> b)) - | _ -> Error TypeMismatch) ) - ; ( "&&" - , VBuiltin_binop - (fun v1 v2 -> - try Ok (VBool (to_bool v1 && to_bool v2)) with - | Invalid_argument _ -> Error TypeMismatch) ) - ; ( "||" - , VBuiltin_binop - (fun v1 v2 -> - try Ok (VBool (to_bool v1 || to_bool v2)) with - | Invalid_argument _ -> Error TypeMismatch) ) - ] - ;; - - let init = - let all_bindings = - List.concat - [ Base.Map.to_alist builtin_binops - ; Base.Map.to_alist builtin_functions - ; Base.Map.to_alist builtin_bools - ] - in - Base.Map.of_alist_reduce (module Base.String) all_bindings ~f:(fun v _ -> v) - ;; - - (* If duplicates exist, prefer the first occurrence *) - let lookup env name = - match Base.Map.find env name with - | Some s -> return s - | None -> fail (UnboundVariable name) - ;; - - let extend env name value = Base.Map.set env ~key:name ~data:value - - let combine env1 env2 = - Base.Map.fold env2 ~f:(fun ~key ~data env_acc -> extend env_acc key data) ~init:env1 - ;; -end - -(*Interpretator functor, that uses M monad as a base for evaluation *) -module Interpreter (M : Error_monad) = struct - open M - module E = Env (M) - - let lift_result = function - | Ok v -> return v - | Error e -> fail e - ;; - - (* mapM applies a monadic function f to each element of a list and combines results in a list *) - let mapM f env lst = - let rec aux acc = function - | [] -> return (List.rev acc) - | x :: xs -> - let* res = f env x in - aux (res :: acc) xs - in - aux [] lst - ;; - - let mapM2 f env lst lst2 = - let rec aux acc env = function - | [], [] -> return (Some env) - | x :: xs, y :: ys -> - let* env_opt = f x y env in - (match env_opt with - | Some new_env -> aux acc new_env (xs, ys) - | None -> return None) - | _ -> fail PatternMismatch (* In case lists have different lengths *) - in - aux [] env (lst, lst2) - ;; - - let eval_const = function - | Constant.Const_integer i -> return (VInt i) - | Constant.Const_char c -> return (VChar c) - | Constant.Const_string s -> return (VString s) - ;; - - (* let rec eval_type_expr env = function - | TypeExpr.Type_var ident -> - let* as_value = E.lookup env ident in - (match as_value with - | VType (type_value, _) -> return type_value - | _ -> fail TypeMismatch) - | TypeExpr.Type_arrow (t1, t2) -> - let* t1_resolved = eval_type_expr env t1 in - let* t2_resolved = eval_type_expr env t2 in - return (TypeExpr.Type_arrow (t1_resolved, t2_resolved)) - | TypeExpr.Type_tuple types -> - let t1, t2, tl = types in - let* rt1 = eval_type_expr env t1 in - let* rt2 = eval_type_expr env t2 in - let* rtl = mapM eval_type_expr env tl in - return (TypeExpr.Type_tuple (rt1, rt2, rtl)) - | TypeExpr.Type_construct (type_name, args) -> - let* as_val = E.lookup env type_name in - (match as_val with - | VType (TypeExpr.Type_construct (_, tparams), _) -> - if List.length args <> List.length tparams - then fail UndefinedArgs - else - let* resolved_args = mapM eval_type_expr env args in - return (TypeExpr.Type_construct (type_name, resolved_args)) - | VType (TypeExpr.Type_var s, _) -> return (TypeExpr.Type_var s) - | VAdt (_, tparams, _, _) -> - if List.length args <> List.length tparams - then fail UndefinedArgs - else - let* resolved_args = mapM eval_type_expr env args in - return (TypeExpr.Type_construct (type_name, resolved_args)) - | _ -> fail (UndefinedConstructor type_name)) - ;; *) - - let rec eval_pattern pattern value env = - match pattern, value with - | Pattern.Pat_any, _ -> return (Some env) - | Pattern.Pat_var var, v -> return (Some (E.extend env var v)) - | Pattern.Pat_constant c, v -> - let* const_val = eval_const c in - if compare_values const_val v then return (Some env) else return None - | Pattern.Pat_tuple (p1, p2, ps), VTuple (v1, v2, vs) -> - let* env1_opt = eval_pattern p1 v1 env in - let* env1 = - match env1_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* env2_opt = eval_pattern p2 v2 env1 in - let* env2 = - match env2_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* final_env_opt = mapM2 eval_pattern env2 ps vs in - return final_env_opt - | Pattern.Pat_construct ("Some", Some p), VConstruct ("Some", Some v) -> - eval_pattern p v env - | Pattern.Pat_construct ("None", None), VConstruct ("None", None) -> return (Some env) - | Pattern.Pat_construct ("()", None), _ -> return (Some env) - | ( Pattern.Pat_construct ("::", Some (Pattern.Pat_tuple (p_hd, p_tl, []))) - , VConstruct ("::", Some (VTuple (v_hd, v_tl, []))) ) -> - let* env1_opt = eval_pattern p_hd v_hd env in - let* env1 = - match env1_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - eval_pattern p_tl v_tl env1 - | Pattern.Pat_construct (cname, Some pat), VAdt (args, _, tname, _) -> - if String.equal cname tname - then ( - match args with - | VTuple (v1, v2, vs) -> - (match pat with - | Pattern.Pat_tuple (p1, p2, ps) -> - let* env1_opt = eval_pattern p1 v1 env in - let* env1 = - match env1_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* env2_opt = eval_pattern p2 v2 env1 in - let* env2 = - match env2_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* final_env_opt = mapM2 eval_pattern env2 ps vs in - return final_env_opt - | _ -> fail PatternMismatch) - | VConstruct ("[]", None) -> - (match pat with - | Pattern.Pat_construct ("[]", None) -> return (Some env) - | _ -> fail PatternMismatch) - | VConstruct ("::", Some (VTuple (head, tail, []))) -> - (match pat with - | Pattern.Pat_construct ("::", Some (Pattern.Pat_tuple (ph, pt, []))) -> - let* env1_opt = eval_pattern ph head env in - let* env1 = - match env1_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - eval_pattern pt tail env1 - | _ -> fail PatternMismatch) - | _ -> eval_pattern pat args env) - else return None - | Pattern.Pat_construct (ctor, None), VString s -> - if String.equal ctor s then return (Some env) else fail PatternMismatch - | Pattern.Pat_construct (ctor, None), VAdt (_, _, tname, _) -> - if String.equal ctor tname then return (Some env) else return None - | Pattern.Pat_construct (cname, Some p), v -> - (match v with - | VAdt (args, _, tname, _) -> - if String.equal cname tname - then ( - match args with - | VTuple (v1, v2, vs) -> - (match p with - | Pattern.Pat_tuple (p1, p2, ps) -> - let* env1_opt = eval_pattern p1 v1 env in - let* env1 = - match env1_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* env2_opt = eval_pattern p2 v2 env1 in - let* env2 = - match env2_opt with - | Some env -> return env - | None -> fail PatternMismatch - in - let* final_env_opt = mapM2 eval_pattern env2 ps vs in - return final_env_opt - | _ -> fail PatternMismatch) - | _ -> eval_pattern p args env) - else return None - | VConstruct (_, None) | VInt _ -> eval_pattern p v env - | VUnit -> return (Some env) - | VConstruct (name, Some value) -> - if String.equal cname name then eval_pattern p value env else return None - | _ -> fail PatternMismatch) - | Pattern.Pat_construct (cname, None), v -> - (match v with - | VConstruct (name, Some _) -> - if String.equal cname name then return (Some env) else return None - | VUnit -> return (Some env) - | VConstruct (_, None) | VInt _ -> return (Some env) - | _ -> fail PatternMismatch) - | Pattern.Pat_constraint (pat, _), v -> eval_pattern pat v env - | _ -> fail PatternMismatch - ;; - - let rec eval_expr (env : environment) = function - | Expression.Exp_ident name -> E.lookup env name - | Expression.Exp_constant ex -> eval_const ex - | Expression.Exp_tuple (e1, e2, el) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - let* vl = mapM eval_expr env el in - return (VTuple (v1, v2, vl)) - | Expression.Exp_function (c1, cl) -> return (VFunction ((c1, cl), env)) - | Expression.Exp_fun (patterns, body) -> - return (VFun (patterns, body, env, Nonrecursive)) - | Expression.Exp_apply (func, args) -> - let* func_val = eval_expr env func in - (match func_val with - | VBuiltin_binop binop -> - (match args with - | Expression.Exp_tuple (arg1, arg2, []) -> - let* arg1_val = eval_expr env arg1 in - let* arg2_val = eval_expr env arg2 in - let* binop_res = lift_result (binop arg1_val arg2_val) in - return binop_res - | exp -> - (* Negative operator with 1 operand case *) - let* arg_val = eval_expr env exp in - let* binop_res = lift_result (binop (VInt 0) arg_val) in - return binop_res) - | VBuiltin_print print_fn -> - (match args with - | Expression.Exp_constant c -> - let* arg_val = eval_const c in - let* _ = lift_result (print_fn arg_val) in - return (VString "") - | Expression.Exp_ident id -> - let* arg_val = E.lookup env id in - let* _ = lift_result (print_fn arg_val) in - return (VString "") - | Expression.Exp_apply (func, args) -> - let* arg_val = eval_expr env (Expression.Exp_apply (func, args)) in - let* _ = lift_result (print_fn arg_val) in - return (VString "") - | _ -> fail PatternMismatch) - | VFun (patterns, body, fun_env, rec_flag) -> - let p1, pl = patterns in - let* arg_val = eval_expr env args in - let* extended_env_opt = eval_pattern p1 arg_val fun_env in - let* new_env = - match rec_flag, extended_env_opt with - | Recursive, Some extended_env -> return (E.combine env extended_env) - | Nonrecursive, Some extended_env -> return extended_env - | _, None -> fail PatternMismatch - in - (match pl with - | [] -> eval_expr new_env body - | pf :: p_rest -> return (VFun ((pf, p_rest), body, new_env, Recursive))) - | VFunction ((c1, cl), env) -> - let* arg_val = eval_expr env args in - eval_cases env arg_val (c1 :: cl) - | _ -> fail TypeMismatch) - | Expression.Exp_match (expr, cases) -> - let c1, cl = cases in - let* v = eval_expr env expr in - eval_cases env v (c1 :: cl) - | Expression.Exp_if (cond, then_expr, else_expr_opt) -> - let* cond_val = eval_expr env cond in - (match cond_val with - | VBool false -> - (match else_expr_opt with - | Some else_expr -> eval_expr env else_expr - | None -> fail PatternMismatch) - | VBool true -> eval_expr env then_expr - | VConstruct ("true", None) -> eval_expr env then_expr - | VConstruct ("false", None) -> - (match else_expr_opt with - | Some else_expr -> eval_expr env else_expr - | None -> fail PatternMismatch) - | _ -> fail PatternMismatch) - | Expression.Exp_let (Nonrecursive, (b1, bl), body) -> - (* Non-recursive bindings: evaluate and extend one by one *) - let* env = eval_value_binding_list env (b1 :: bl) in - eval_expr env body - | Expression.Exp_let (Recursive, (b1, bl), body) -> - (* Handle recursive bindings directly *) - let* env = eval_rec_value_binding_list env (b1 :: bl) in - eval_expr env body - | Expression.Exp_construct ("Some", Some e) -> - let* v = eval_expr env e in - return (VConstruct ("Some", Some v)) - | Expression.Exp_construct ("None", None) -> return (VConstruct ("None", None)) - | Expression.Exp_construct ("()", None) -> return VUnit - | Expression.Exp_construct (ctor_name, args) -> - (match args with - | Some provided_args -> - let* evaluated_args = eval_expr env provided_args in - return (VConstruct (ctor_name, Some evaluated_args)) - | None -> return (VConstruct (ctor_name, None))) - | Expression.Exp_constraint (expr, _type_expr) -> eval_expr env expr - - and eval_cases env value = function - | [] -> fail PatternMismatch - | { Expression.first = pattern; second = body } :: rest -> - let* env' = eval_pattern pattern value env in - (match env' with - | Some extended_env -> eval_expr extended_env body - | None -> eval_cases env value rest) - - and eval_rec_value_binding_list env value_binding_list = - Base.List.fold_left - ~init:(return env) - ~f:(fun acc_env { Expression.pat; expr } -> - let* env = acc_env in - let* value = eval_expr env expr in - match pat with - | Pattern.Pat_var name | Pattern.Pat_constraint (Pattern.Pat_var name, _) -> - let value = - match value with - | VFun (patterns, body, closure_env, Nonrecursive) -> - VFun (patterns, body, closure_env, Recursive) - | other -> other - in - let env = E.extend env name value in - return env - | _ -> fail PatternMismatch) - value_binding_list - - and eval_value_binding_list env value_binding_list = - Base.List.fold_left - ~init:(return env) - ~f:(fun acc_env { Expression.pat; expr } -> - let* env = acc_env in - let* value = eval_expr env expr in - match pat with - | Pattern.Pat_var name | Pattern.Pat_constraint (Pattern.Pat_var name, _) -> - let env = E.extend env name value in - return env - | _ -> - let* env = eval_pattern pat value env in - (match env with - | Some extended_env -> return extended_env - | None -> fail PatternMismatch)) - value_binding_list - ;; - - let eval_str_item (env : environment) olist = - let rec extract_names_from_pat env acc = function - | Pattern.Pat_var id -> - let* value = E.lookup env id in - return (acc @ [ Some id, value ]) - | Pattern.Pat_tuple (fst_pat, snd_pat, pat_list) -> - Base.List.fold_left - (fst_pat :: snd_pat :: pat_list) - ~init:(return acc) - ~f:(fun acc_monadic pat -> - let* acc = acc_monadic in - extract_names_from_pat env acc pat) - | Pattern.Pat_construct ("::", Some exp) -> - (match exp with - | Pattern.Pat_tuple (head, tail, []) -> - let* acc = extract_names_from_pat env acc head in - extract_names_from_pat env acc tail - | _ -> return acc) - | Pattern.Pat_construct ("Some", Some pat) -> extract_names_from_pat env acc pat - | Pattern.Pat_constraint (pat, _) -> extract_names_from_pat env acc pat - | _ -> return acc - in - (* Extract names from value bindings *) - let get_names_from_vb env bindings = - Base.List.fold_left - ~init:(return []) - ~f:(fun acc_monadic { Expression.pat; _ } -> - let* acc = acc_monadic in - extract_names_from_pat env acc pat) - (* Extract names from patterns in bindings *) - bindings - in - function - | Structure.Str_eval str -> - let* vl = eval_expr env str in - return (env, olist @ [ None, vl ]) - (* No tag for the evaluated expression *) - | Structure.Str_value (Nonrecursive, bindings) -> - let bindings_list = fst bindings :: snd bindings in - let* env = eval_value_binding_list env bindings_list in - let* vl = get_names_from_vb env bindings_list in - return (env, olist @ vl) - | Structure.Str_value (Recursive, bindings) -> - let bindings_list = fst bindings :: snd bindings in - let* env = eval_rec_value_binding_list env bindings_list in - let* vl = get_names_from_vb env bindings_list in - return (env, olist @ vl) - | Structure.Str_adt (targs, type_name, constructors) -> - (* Add the ADT type itself to the environment *) - let new_env = - E.extend env type_name (VAdt (VUnit, targs, type_name, constructors)) - in - return (new_env, olist) - ;; - - let remove_duplicates out_list = - let fun_equal el1 el2 = - match el1, el2 with - | (Some id1, _), (Some id2, _) -> String.equal id1 id2 - | _ -> false - in - Base.List.fold_right out_list ~init:[] ~f:(fun x acc -> - if Base.List.exists acc ~f:(fun y -> fun_equal x y) then acc else x :: acc) - ;; - - let interpret_program (prog : program) = - let rec eval_prog env olist = function - | [] -> return olist - | [ item ] -> - let* _, vl = eval_str_item env olist item in - return (olist @ vl) - | item :: rest -> - let* new_env, new_olist = eval_str_item env olist item in - eval_prog new_env new_olist rest - in - match prog with - | [] -> fail EmptyProgram - | _ -> - let* final_olist = eval_prog E.init [] prog in - let deduplicated_olist = remove_duplicates final_olist in - return deduplicated_olist - ;; -end - -module RESULT_MONAD_ERROR = struct - (* Basic Result monad extension. - Result is used for more advanced error handling *) - include Result - - type ('a, 'e) t = ('a, 'e) result - - let return x = Ok x - let fail e = Error e - - let ( >>= ) m f = - match m with - | Ok x -> f x - | Error e -> Error e - ;; - - let ( let* ) = ( >>= ) -end - -(* Interpreter functor extension *) -module InterpreterWResult = Interpreter (RESULT_MONAD_ERROR) - -let run_interpreter = InterpreterWResult.interpret_program - -module PPrinter = struct - open Stdlib.Format - - let rec pp_value fmt = function - | VInt i -> fprintf fmt "%i" i - | VChar c -> fprintf fmt "'%c'" c - | VString s -> fprintf fmt "%S" s - | VBool b -> fprintf fmt "%b" b - | VTuple (fst_val, snd_val, val_list) -> - fprintf - fmt - "(%a)" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - (fst_val :: snd_val :: val_list) - | VFun _ -> fprintf fmt "" - | VFunction _ -> fprintf fmt "" - | VBuiltin_print _ -> fprintf fmt "" - (* Recursively format list elements *) - | VConstruct ("::", Some (VTuple (head, tail, []))) -> - let rec extract_list acc = function - | VConstruct ("::", Some (VTuple (hd, tl, []))) -> extract_list (hd :: acc) tl - | VConstruct ("[]", None) -> List.rev acc - | v -> List.rev (v :: acc) - in - let elements = extract_list [ head ] tail in - fprintf - fmt - "[%a]" - (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt "; ") pp_value) - elements - | VAdt (_, _, name, _) -> fprintf fmt ": %s" name - | VConstruct ("[]", _) -> fprintf fmt "[]" - | VConstruct (ct, Some v) -> - fprintf fmt "%s " ct; - pp_value fmt v - | VConstruct (ct, None) -> fprintf fmt "%s" ct - | VUnit -> fprintf fmt "unit" - | _ -> fprintf fmt "Intepreter error: Value error" - ;; - - let pp_error fmt = function - | PatternMismatch -> fprintf fmt "Interpreter error: Pattern mismatch" - | DivisionByZero -> fprintf fmt "Interpreter error: Division by zero" - | UnboundVariable s -> fprintf fmt "Interpreter error: Unbound value %s" s - | TypeMismatch -> fprintf fmt "Interpreter error: Type mismatch" - | RecursionError -> fprintf fmt "Interpreter error: Recursion error" - | EmptyProgram -> fprintf fmt "Empty program" - | ParserError -> fprintf fmt "Parser Error" - | NotAnADT s -> fprintf fmt "Interpreter error: %s is not an ADT" s - | NotAnADTVariant s -> fprintf fmt "Interpreter error: %s is not an ADT's variant" s - | UndefinedConstructor s -> - fprintf fmt "Interpreter error: Undefined constructor %s" s - | UndefinedArgs -> fprintf fmt "InterpreterError: Undefined arguments" - ;; - - let print_error = printf "%a" pp_error -end diff --git a/OcamlADT/lib/interpreter.mli b/OcamlADT/lib/interpreter.mli deleted file mode 100644 index 0fc95a380..000000000 --- a/OcamlADT/lib/interpreter.mli +++ /dev/null @@ -1,81 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -(** Interpreter error type *) -type error = - | DivisionByZero - | TypeMismatch - | UnboundVariable of string - | PatternMismatch - | RecursionError - | EmptyProgram - | ParserError - | NotAnADT of string - | NotAnADTVariant of string - | UndefinedConstructor of string - | UndefinedArgs - -(** Runtime value type *) -type value = - | VInt of int - | VString of string - | VChar of char - | VBool of bool - | VTuple of value List2.t - | VFun of Pattern.t List1.t * Expression.t * environment * Expression.rec_flag - | VFunction of Expression.t Expression.case List1.t * environment - | VConstruct of ident * value option - | VAdt of (value * ident list * ident * (ident * TypeExpr.t option) List1.t) - | VUnit - | VType of TypeExpr.t * ident option - | VBuiltin_binop of (value -> value -> (value, error) Result.t) - | VBuiltin_print of (value -> (value, error) Result.t) - -(** Environment: a map from variable names to values *) -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -(** Utility functions *) -val compare_values : value -> value -> bool - -val list1_to_list2 : 'a List1.t -> ('a * 'a * 'a list) option - -(** Create a List1.t from a standard list, if the list is nonempty. *) -val make_list1 : 'a list -> ('a * 'a list) option - -(** Convert a value to a boolean; raises [Invalid_argument "TypeMismatch"] if the value is not convertible. *) -val to_bool : value -> bool - -(** Module type for an error monad. *) -module type Error_monad = sig - type ('a, 'e) t - - val return : 'a -> ('a, 'e) t - val fail : 'e -> ('a, 'e) t - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -(** [Interpreter(M)] is the interpreter functor using monad [M]. *) -module Interpreter (M : Error_monad) : sig - val interpret_program : program -> ((ident option * value) list, error) M.t -end - -(** [RESULT_MONAD_ERROR] is an implementation of [Error_monad] using ocaml's [Result]. *) -module RESULT_MONAD_ERROR : Error_monad - -(** [InterpreterWResult] is the interpreter instantiated with [RESULT_MONAD_ERROR]. *) -module InterpreterWResult : sig - include module type of Interpreter (RESULT_MONAD_ERROR) -end - -(** [run_interpreter] runs the interpreter on a [program]. *) -val run_interpreter : program -> ((ident option * value) list, error) result - -(** Pretty printer functions for interpreter values and errors. *) -module PPrinter : sig - val pp_value : Stdlib.Format.formatter -> value -> unit - val pp_error : Stdlib.Format.formatter -> error -> unit - val print_error : error -> unit -end diff --git a/OcamlADT/lib/parser.ml b/OcamlADT/lib/parser.ml deleted file mode 100644 index 5589593a2..000000000 --- a/OcamlADT/lib/parser.ml +++ /dev/null @@ -1,625 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Angstrom -open Base -open Char - -(* - | _ _ _ __ __ _ _ ____ __ __ - |U /"\ uU |"|u| | \ \/"/ ___ |"| ___ U /"\ uU | _'\ u \ \ / / - | \/ _ \/ \| |\| | /\ /\ |_"_| U | | u |_"_| \/ _ \/ \| |_) |/ \ V / - | / ___ \ | |_| |U / \ u | | \| |/__ | | / ___ \ | _ < U_|"|_u - |/_/ \_\ <<\___/ /_/\_\ U/| |\u |_____| U/| |\u /_/ \_\ |_| \_\ |_| - | \\ >>(__) )( ,-,>> \\_.-,_|___|_,-.// \\.-,_|___|_,-.\\ >> // \\_.-,//|(_ - |(__) (__) (__) \_) (__)\_)-' '-(_/(_")("_)\_)-' '-(_/(__) (__)(__) (__)\_) (__) -*) - -let is_whitespace = function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false -;; - -let pass_ws = skip_while is_whitespace - -(** Parser that matches string literals an 's' skipping all whitespaces before *) -let pass_ws1 = skip is_whitespace *> pass_ws - -let token s = pass_ws *> string s -let pparenth stmt = token "(" *> stmt <* token ")" - -let ptowhitespace = function - | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' -> true - | _ -> false -;; - -let pident_cap = - let first_char_str = - satisfy (function - | 'A' .. 'Z' -> true - | _ -> false) - in - lift2 (fun fc rs -> String.make 1 fc ^ rs) first_char_str (take_while ptowhitespace) - >>= fun ident -> - if Ast.is_not_keyword ident - then return ident - else fail "Found a keyword instead of an identifier" -;; - -let pident_lc = - let first_char_str = - satisfy (function - | 'a' .. 'z' | '_' -> true - | _ -> false) - in - lift2 (fun fc rs -> String.make 1 fc ^ rs) first_char_str (take_while ptowhitespace) - >>= fun ident -> - if Ast.is_not_keyword ident - then return ident - else fail "Found a keyword instead of an identifier" -;; - -(* - | ____ U ___ u _ _ ____ _____ _ _ _ _____ - |U /"___| \/"_ \/ | \ |"| / __"| u |_ " _| U /"\ u | \ |"| |_ " _| - |\| | u | | | |<| \| |><\___ \/ | | \/ _ \/ <| \| |> | | - | | |/__.-,_| |_| |U| |\ |u u___) | /| |\ / ___ \ U| |\ |u /| |\ - | \____|\_)-\___/ |_| \_| |____/>> u |_|U /_/ \_\ |_| \_| u |_|U - | _// \\ \\ || \\,-.)( (__)_// \\_ \\ >> || \\,-._// \\_ - |(__)(__) (__) (_") (_/(__) (__) (__)(__) (__)(_") (_/(__) (__) - - |U _____ u __ __ ____ ____ U _____ u ____ ____ U ___ u _ _ - |\| ___'|/ \ \/"/ U| _"\ uU | _"\ u \| ___"|// __"| u/ __"| u ___ \/"_ \/ | \ |"| - | | _|" /\ /\ \| |_) |/ \| |_) |/ | _|" <\___ \/<\___ \/ |_"_| | | | |<| \| |> - | | |___ U / \ u | __/ | _ < | |___ u___) | u___) | | | .-,_| |_| |U| |\ |u - | |_____| /_/\_\ |_| |_| \_\ |_____| |____/>>|____/>> U/| |\u\_)-\___/ |_| \_| - | << >>,-,>> \\_ ||>>_ // \\_ << >> )( (__))( (__).-,_|___|_,-. \\ || \\,-. - |(__) (__)\_) (__)(__)__) (__) (__)(__) (__)(__) (__) \_)-' '-(_/ (__) (_") (_/ -*) -let pconstint = - let* number = Int.of_string <$> take_while1 is_digit in - return (Constant.Const_integer number) -;; - -let pconstchar = - let* c = token "'" *> any_char <* token "'" in - return (Constant.Const_char c) -;; - -let pconststring = - token "\"" - *> lift - (fun str -> Constant.Const_string str) - (take_while (function - | '"' -> false - | _ -> true)) - <* token "\"" -;; - -let pconst = pconstchar <|> pconstint <|> pconststring - -let lchain p op = - let rec loop acc = - (let* f = op in - let* y = p in - loop (f acc y)) - <|> return acc - in - let* x = p in - loop x -;; - -let rchain p op = - let rec loop acc = - (let* f = op in - let* y = p in - let new_acc = f acc y in - loop new_acc) - <|> return acc - in - let* x = p in - loop x -;; - -(* - | _____ __ __ ____ U _____ u - | |_ " _| \ \ / /U| _"\ u\| ___'|/ - | | | \ V / \| |_) |/ | _|" - | /| |\ U_|"|_u | __/ | |___ - | u |_|U |_| |_| |_____| - | _// \\_.-,//|(_ ||>>_ << >> - |(__) (__)\_) (__)(__)__) (__) (__) - - |U _____ u __ __ ____ ____ U _____ u ____ ____ U ___ u _ _ - |\| ___'|/ \ \/"/ U| _"\ uU | _"\ u \| ___"|// __"| u/ __"| u ___ \/"_ \/ | \ |"| - | | _|" /\ /\ \| |_) |/ \| |_) |/ | _|" <\___ \/<\___ \/ |_"_| | | | |<| \| |> - | | |___ U / \ u | __/ | _ < | |___ u___) | u___) | | | .-,_| |_| |U| |\ |u - | |_____| /_/\_\ |_| |_| \_\ |_____| |____/>>|____/>> U/| |\u\_)-\___/ |_| \_| - | << >>,-,>> \\_ ||>>_ // \\_ << >> )( (__))( (__).-,_|___|_,-. \\ || \\,-. - |(__) (__)\_) (__)(__)__) (__) (__)(__) (__)(__) (__) \_)-' '-(_/ (__) (_") (_/ -*) - -let ptypearrow = pass_ws *> token "->" >>| fun _ lhs rhs -> TypeExpr.Type_arrow (lhs, rhs) - -let pmultiargsapp pty = - let* args = pparenth @@ sep_by1 (pass_ws *> char ',') pty in - let* id = pass_ws *> pident_lc in - return (TypeExpr.Type_construct (id, args)) -;; - -let ptypevar = - let* id = token "'" *> (pident_lc <|> pident_cap) in - return (TypeExpr.Type_var id) -;; - -let ptypetuple ptype = - let* el1 = ptype in - let* el2 = token "*" *> ptype in - let* rest = many (token "*" *> ptype) in - return (TypeExpr.Type_tuple (el1, el2, rest)) -;; - -let ptypeconstr = - pass_ws - *> fix (fun ptconstr -> - let* tparams = - pass_ws - *> option - [] - (pparenth (sep_by (token ",") ptypevar) - <|> (let* typevar = ptypevar in - return [ typevar ]) - <|> (let* ctuple = pparenth (ptypetuple ptconstr) in - return [ ctuple ]) - <|> - let* ttuple = pparenth (ptypetuple ptypevar) in - return [ ttuple ]) - in - let* tname = - option - None - (let* name = pass_ws *> (pident_lc <|> pident_cap) in - return (Some name)) - in - match tname, tparams with - | Some "", [] | None, [] | None, [ TypeExpr.Type_var _ ] -> - fail "Type constructor cannot have a single type parameter without a name" - | Some name, _ -> return (TypeExpr.Type_construct (name, tparams)) - | None, _ -> - (match tparams with - | x :: _ -> return x - | _ -> fail "Not enough elementts")) -;; - -let ptypeconstr_app = - let* base = ptypeconstr in - let* extra_args = sep_by (token " ") ptypeconstr in - match extra_args with - | [] -> return base - | _ -> - (match base with - | TypeExpr.Type_construct (name, args) -> - return (TypeExpr.Type_construct (name, args @ extra_args)) - | _ -> fail "Expected a type constructor, but found an incompatible expression") -;; - -let ptype = - pass_ws - *> fix (fun ptype -> - let ptvar = - pass_ws - *> choice - [ (pident_lc >>| fun id -> TypeExpr.Type_construct (id, [])) - ; ptypevar - ; pmultiargsapp ptype - ; pparenth ptype - ; ptypeconstr - ] - in - let pttuple = ptypetuple ptvar <|> ptvar in - let ptarr = rchain pttuple ptypearrow <|> pttuple in - let* arg = ptarr in - let rec pcons acc = - option - acc - (pass_ws1 *> pident_lc >>= fun id -> pcons (TypeExpr.Type_construct (id, [ acc ]))) - in - pcons arg) -;; - -let ptype_adt = pass_ws *> ptypeconstr_app <|> ptypevar - -(* - | ____ _ _____ _____ U _____ u ____ _ _ - |U| _"\ uU /"\ u |_ " _| |_ " _| \| ___"|/U | _"\ u | \ |'| - |\| |_) |/ \/ _ \/ | | | | | _|" \| |_) |/<| \| |> - | | __/ / ___ \ /| |\ /| |\ | |___ | _ < U| |\ |u - | |_| /_/ \_\ u |_|U u |_|U |_____| |_| \_\ |_| \_| - | ||>>_ \\ >> _// \\_ _// \\_ << >> // \\_ || \\,-. - |(__)__) (__) (__)(__) (__)(__) (__)(__) (__) (__) (__)(_") (_/ -*) - -let ppatlist ppat = - let* list = token "[" *> sep_by (token ";") ppat <* token "]" in - return - (Stdlib.List.fold_right - (fun x y -> - Ast.Pattern.Pat_construct ("::", Some (Ast.Pattern.Pat_tuple (x, y, [])))) - list - (Ast.Pattern.Pat_construct ("[]", None))) -;; - -let ppatcons ppat = - let rec consparser () = - let* pat = ppat in - token "::" - >>= (fun c -> - consparser () - >>= fun rest -> - return - (Ast.Pattern.Pat_construct (c, Some (Ast.Pattern.Pat_tuple (pat, rest, []))))) - <|> return pat - in - consparser () -;; - -let pspecials = choice [ token "()"; token "true"; token "false"; token "None" ] - -let ppatconst = - let* const = pconst in - return (Pattern.Pat_constant const) -;; - -let ptuplepat ppattern = - let* el1 = ppattern in - let* el2 = token "," *> ppattern in - let* rest = many (token "," *> ppattern) in - return (Pattern.Pat_tuple (el1, el2, rest)) -;; - -let ppatvar = - let* id = pident_lc in - match id with - | "_" -> return Pattern.Pat_any - | _ -> return (Pattern.Pat_var id) -;; - -let ppatconstruct (ppattern : Pattern.t Angstrom.t) = - let* name = pident_cap in - let* arg = option None (ppattern >>| Option.some) in - return (Pattern.Pat_construct (name, arg)) -;; - -let ppatconstraint ppattern = - let* pat = token "(" *> ppattern in - let* pattype = token ":" *> pass_ws *> ptype <* token ")" in - return (Pattern.Pat_constraint (pat, pattype)) -;; - -let ppattern = - fix (fun ppattern -> - let poprnd = - fix (fun poprnd -> - pass_ws - *> choice - [ (pspecials >>| fun name -> Pattern.Pat_construct (name, None)) - ; ppatvar - ; ppatconst - ; ppatconstruct poprnd - ; pparenth ppattern - ; ppatconstraint ppattern - ]) - in - let plist = ppatlist poprnd <|> poprnd in - let pcons = ppatcons plist <|> plist in - ptuplepat pcons <|> pcons) -;; - -(* - |U _____ u __ __ ____ ____ U _____ u ____ ____ U ___ u _ _ - |\| ___'|/ \ \/"/ U| _"\ uU | _"\ u \| ___"|// __"| u/ __"| u ___ \/"_ \/ | \ |"| - | | _|" /\ /\ \| |_) |/ \| |_) |/ | _|" <\___ \/<\___ \/ |_"_| | | | |<| \| |> - | | |___ U / \ u | __/ | _ < | |___ u___) | u___) | | | .-,_| |_| |U| |\ |u - | |_____| /_/\_\ |_| |_| \_\ |_____| |____/>>|____/>> U/| |\u\_)-\___/ |_| \_| - | << >>,-,>> \\_ ||>>_ // \\_ << >> )( (__))( (__).-,_|___|_,-. \\ || \\,-. - |(__) (__)\_) (__)(__)__) (__) (__)(__) (__)(__) (__) \_)-' '-(_/ (__) (_") (_/ -*) - -let pexpcons expr = - let rec consparser () = - let* exp = expr in - token "::" - >>= (fun _ -> - consparser () - >>= fun rest -> - return - (Ast.Expression.Exp_construct - ("::", Some (Ast.Expression.Exp_tuple (exp, rest, []))))) - <|> return exp - in - consparser () -;; - -let pexplist expr = - let* list = token "[" *> sep_by (token ";") expr <* token "]" in - return - (Base.List.fold_right - list - ~f:(fun x y -> - Ast.Expression.Exp_construct ("::", Some (Ast.Expression.Exp_tuple (x, y, [])))) - ~init:(Ast.Expression.Exp_construct ("[]", None))) -;; - -let pexprconst = - let* const = pconst in - return (Expression.Exp_constant const) -;; - -let pidentexpr = - pident_lc - >>= fun ident -> - if is_not_keyword ident - then return (Expression.Exp_ident ident) - else fail "Found a keyword instead of an identifier" -;; - -let pcase pexpr = - pass_ws - *> option () (token "|" *> return ()) - *> - let* first = pass_ws *> ppattern in - let* second = token "->" *> pass_ws *> pexpr in - return { Expression.first; second } -;; - -let pfunction pexpr = - token "function" - *> - let* first_case = pcase pexpr in - let* case_list = sep_by (token "|") (pcase pexpr) in - return (Ast.Expression.Exp_function (first_case, case_list)) -;; - -let pmatch pexpr = - let* exp = token "match" *> pexpr <* token "with" in - let* casefs = pcase pexpr in - let* case_list = sep_by (token "|") (pcase pexpr) in - return (Ast.Expression.Exp_match (exp, (casefs, case_list))) -;; - -let pletbinding pexpr = - let psimple = - let* pat = ppattern in - let* expr = token "=" *> pexpr in - return { Expression.pat; expr } - in - let pfun = - let* pat = pass_ws *> ppatvar in - let* parameterfs = ppattern in - let* parametertl = many ppattern in - let* exprw = token "=" *> pexpr in - let expr = Expression.Exp_fun ((parameterfs, parametertl), exprw) in - return { Expression.pat; expr } - in - choice [ psimple; pfun ] -;; - -let plethelper pexpr = - let precflag = - token "rec" *> pass_ws1 *> return Expression.Recursive - <|> return Expression.Nonrecursive - in - let* recflag = token "let" *> precflag in - let* bindingfs = pletbinding pexpr in - let* bindingtl = many (token "and" *> pletbinding pexpr) in - return (recflag, bindingfs, bindingtl) -;; - -let pletexpr pexpr = - let* recflag, bindingfs, bindingtl = plethelper pexpr in - let* expr = token "in" *> pass_ws *> pexpr in - return (Expression.Exp_let (recflag, (bindingfs, bindingtl), expr)) -;; - -let ptupleexpr pexpr = - let* el1 = pexpr in - let* el2 = token "," *> pexpr in - let* rest = many (token "," *> pexpr) in - return (Expression.Exp_tuple (el1, el2, rest)) -;; - -let pifexpr pexpr = - let* condition = token "if" *> pass_ws1 *> pexpr in - let* thenexpr = token "then" *> pass_ws1 *> pexpr in - let* elseexpr = - option None (pass_ws1 *> token "else" >>| Option.some) - >>= function - | None -> return None - | Some _ -> pexpr >>| Option.some - in - return (Expression.Exp_if (condition, thenexpr, elseexpr)) -;; - -let pfunexpr pexpr = - lift3 - (fun first_pattern rest_patterns body_expr -> - Expression.Exp_fun ((first_pattern, rest_patterns), body_expr)) - (token "fun" *> ppattern) - (many ppattern) - (token "->" *> pexpr) -;; - -let rec parseprefop pexpr pop = - (let* f = pop in - let* expr = parseprefop pexpr pop in - return @@ f expr) - <|> pexpr -;; - -let parsebinop binoptoken = - token binoptoken - *> return (fun e1 e2 -> - Expression.Exp_apply (Exp_ident binoptoken, Exp_tuple (e1, e2, []))) -;; - -let padd = parsebinop "+" -let psub = parsebinop "-" -let pdiv = parsebinop "/" -let pmul = parsebinop "*" - -let pcompops = - choice - [ parsebinop ">=" - ; parsebinop "<=" - ; parsebinop "<>" - ; parsebinop "<" - ; parsebinop ">" - ; parsebinop "=" - ] -;; - -let plogops = choice [ parsebinop "&&"; parsebinop "||" ] - -let pexprconstraint pexpr = - let* expr = token "(" *> pexpr in - let* exprtype = token ":" *> ptype <* token ")" in - return (Expression.Exp_constraint (expr, exprtype)) -;; - -let papplyexpr = - pass_ws - >>| fun _ lhs rhs -> - match lhs with - | Expression.Exp_construct (id, None) -> Expression.Exp_construct (id, Some rhs) - | _ -> Exp_apply (lhs, rhs) -;; - -let pexpr = - fix (fun pexpr -> - let poprnd = - pass_ws - *> choice - [ (pspecials >>| fun name -> Expression.Exp_construct (name, None)) - ; pparenth pexpr - ; pidentexpr - ; pexprconstraint pexpr - ; (pident_cap >>| fun id -> Expression.Exp_construct (id, None)) - ; pexprconst - ; pfunction pexpr - ; pfunexpr pexpr - ; pexplist pexpr - ; pletexpr pexpr - ; pifexpr pexpr - ; pmatch pexpr - ] - in - let pconstructor_apply = - let* constr = - pparenth (pident_cap >>| fun id -> Expression.Exp_construct (id, None)) - in - let* arg = poprnd in - return (Expression.Exp_apply (constr, arg)) - in - let papply = lchain (pconstructor_apply <|> poprnd) papplyexpr in - let prefop = - parseprefop - papply - (choice [ token "+"; token "-" ] - >>| fun id expr -> Expression.Exp_apply (Exp_ident id, expr)) - <|> papply - in - let pmuldiv = lchain prefop (pmul <|> pdiv) in - let paddsub = lchain pmuldiv (padd <|> psub) in - let pcompare = lchain paddsub pcompops in - let pexpcons = pexpcons pcompare <|> pcompare in - let plogop = rchain pexpcons plogops in - let ptuple = ptupleexpr plogop <|> plogop in - choice - [ pfunction pexpr; pfunexpr pexpr; pletexpr pexpr; pifexpr pexpr; pmatch pexpr ] - <|> ptuple) -;; - -(* - | ____ _____ ____ _ _ ____ _____ _ _ ____ U _____ u - | / __"| u |_ " _|U | _"\ uU |"|u| |U /"___| |_ " _|U |"|u| |U | _"\ u \| ___'|/ - |<\___ \/ | | \| |_) |/ \| |\| |\| | u | | \| |\| | \| |_) |/ | _|" - | u___) | /| |\ | _ < | |_| | | |/__ /| |\ | |_| | | _ < | |___ - | |____/>> u |_|U |_| \_\ <<\___/ \____| u |_|U <<\___/ |_| \_\ |_____| - | )( (__)_// \\_ // \\_(__) )( _// \\ _// \\_(__) )( // \\_ << >> - | (__) (__) (__)(__) (__) (__) (__)(__)(__) (__) (__) (__) (__)(__) (__) - - | _____ U _____ u __ __ ____ - | ___ |_ " _| \| ___"|/U|' \/ '|u / __"| u - | |_"_| | | | _|" \| |\/| |/<\___ \/ - | | | /| |\ | |___ | | | | u___) | - | U/| |\u u |_|U |_____| |_| |_| |____/>> - |.-,_|___|_,-._// \\_ << >> <<,-,,-. )( (__) - | \_)-' '-(_/(__) (__)(__) (__) (./ \.) (__) -*) - -let pseval = lift (fun expr -> Structure.Str_eval expr) pexpr - -let pstrlet = - let* recflag, bindingfs, bindingtl = plethelper pexpr in - return (Structure.Str_value (recflag, (bindingfs, bindingtl))) -;; - -let pstradt = - let* _ = token "type" in - let* type_param = - option - [] - (pparenth (sep_by (token ",") (token "'" *> pident_lc)) - <|> many (token "'" *> pident_lc)) - in - let* type_name = pass_ws *> pident_lc in - let var = - let* name = option None (pass_ws *> pident_cap >>= fun n -> return (Some n)) in - match name with - | Some x -> - (* Constructor case: Can have "of" *) - let* ctype = - option - None - (token "of" - *> let* types = sep_by (token "*") ptype_adt in - match types with - | x :: y :: xs -> return (Some (TypeExpr.Type_tuple (x, y, xs))) - | [ x ] -> return (Some x) - | [] -> fail "Expected type after 'of'") - in - return (x, ctype) - | None -> - (* Lowercase type alias case: Must have a type expression *) - let* ctype = - let* types = sep_by (token "*") ptype_adt in - match types with - | x :: y :: xs -> return (Some (TypeExpr.Type_tuple (x, y, xs))) (* Tuple case *) - | [ x ] -> return (Some x) (* Single type *) - | [] -> fail "Expected type definition" - in - return ("", ctype) - in - let* _ = token "=" in - let* fvar = - option - None - (option None (token "|" *> return None) *> (var >>= fun v -> return (Some v))) - in - let* varl = many (token "|" *> var) in - match fvar with - | Some fvar -> return (Structure.Str_adt (type_param, type_name, (fvar, varl))) - | None -> fail "Expected at least one variant" -;; - -let pstr_item = pseval <|> pstrlet <|> pstradt - -let pstructure = - let psemicolon = many (token ";;") in - sep_by psemicolon pstr_item <* psemicolon <* pass_ws -;; - -let parse str = parse_string ~consume:All pstructure str -let parse_str str = parse str |> Result.ok_or_failwith diff --git a/OcamlADT/lib/parser.mli b/OcamlADT/lib/parser.mli deleted file mode 100644 index 2e3297908..000000000 --- a/OcamlADT/lib/parser.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val parse : string -> (Structure.structure_item list, string) result -val parse_str : string -> Structure.structure_item list diff --git a/OcamlADT/lib/pprinter.ml b/OcamlADT/lib/pprinter.ml deleted file mode 100644 index 7a78e0a49..000000000 --- a/OcamlADT/lib/pprinter.ml +++ /dev/null @@ -1,290 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Angstrom -open Ast -open Stdlib.Format - -let get_op_pr id = - let open Expression in - match id with - | Exp_ident "&&" -> 3 - | Exp_ident "||" -> 2 - | Exp_ident ">" - | Exp_ident "<" - | Exp_ident ">=" - | Exp_ident "<=" - | Exp_ident "<>" - | Exp_ident "=" -> 4 - | Exp_ident "+" | Exp_ident "-" -> 5 - | Exp_ident "*" | Exp_ident "/" -> 6 - | Exp_if (_, _, _) -> 1 - | Exp_let (_, _, _) - | Exp_match (_, _) - | Exp_function _ - | Exp_fun (_, _) - | Exp_constant _ | Exp_ident _ -> 0 - | Exp_apply (_, _) | Exp_construct _ -> 7 - | _ -> 0 -;; - -let pprint_constant fmt = - let open Constant in - function - | Const_integer n -> fprintf fmt "%d" n - | Const_char c -> fprintf fmt "'%c'" c - | Const_string s -> fprintf fmt "%S" s -;; - -let rec pprint_type fmt = - let open TypeExpr in - function - | Type_arrow (tye1, tye2) -> fprintf fmt "(%a -> %a)" pprint_type tye1 pprint_type tye2 - | Type_var id -> fprintf fmt "'%s" id - | Type_tuple (tye1, tye2, tyel) -> - fprintf - fmt - "(%s)" - (String.concat - ~sep:" * " - (List.map (tye1 :: tye2 :: tyel) ~f:(fun t -> asprintf "%a" pprint_type t))) - | Type_construct (id, tyel) -> - let tyel_str = - String.concat - ~sep:", " - (List.map tyel ~f:(fun t -> - match t with - | Type_var tye -> asprintf "'%s" tye - | Type_tuple (t1, t2, rest) -> - let tuple_types = t1 :: t2 :: rest in - let tuple_str = String.concat ~sep:" * " (List.map tuple_types ~f:show) in - "(" ^ tuple_str ^ ")" - | _ -> show t)) - in - let tyel_strf = - match List.length tyel with - | 0 -> "" - | 1 -> tyel_str ^ " " - | _ -> "(" ^ tyel_str ^ ") " - in - fprintf fmt "%s%s" tyel_strf id -;; - -let rec pprint_pattern fmt = - let open Pattern in - function - | Pat_constraint (p, tye) -> fprintf fmt "(%a : %a)" pprint_pattern p pprint_type tye - | Pat_any -> fprintf fmt "_" - | Pat_var id -> fprintf fmt "%s" id - | Pat_constant c -> pprint_constant fmt c - | Pat_tuple (p1, p2, pl) -> - fprintf - fmt - "(%s)" - (String.concat - ~sep:", " - (List.map (p1 :: p2 :: pl) ~f:(fun p -> asprintf "%a" pprint_pattern p))) - | Pat_construct (id, None) -> fprintf fmt "(%s)" id - | Pat_construct (id, Some p) -> - (match p with - | Pat_tuple _ -> fprintf fmt "(%s (%a))" id pprint_pattern p - | _ -> fprintf fmt "%s %a" id pprint_pattern p) -;; - -let pprint_rec fmt = - let open Expression in - function - | Nonrecursive -> fprintf fmt "" - | Recursive -> fprintf fmt "rec " -;; - -let rec pprint_expression fmt n = - let open Expression in - function - | Exp_ident id -> fprintf fmt "%s" id - | Exp_constant ct -> pprint_constant fmt ct - | Exp_tuple (ex1, ex2, exl) -> - fprintf - fmt - "(%s)" - (String.concat - ~sep:", " - (List.map (ex1 :: ex2 :: exl) ~f:(fun ex -> - let op_pr_t = get_op_pr ex in - asprintf "%a" (fun fmt -> pprint_expression fmt (op_pr_t + 1)) ex))) - | Exp_function (cs1, csl) when n > 0 -> - fprintf fmt "(%a)" pprint_function_with_cases (cs1, csl, n + 1) - | Exp_function (cs1, csl) -> - fprintf fmt "%a" pprint_function_with_cases (cs1, csl, n + 1) - | Exp_fun ((pt1, ptl), exp) -> - let if_string = - asprintf - "fun%s -> %a" - (String.concat - ~sep:"" - (List.map (pt1 :: ptl) ~f:(fun p -> asprintf " %a" pprint_pattern p))) - (fun fmt -> pprint_expression fmt n) - exp - in - if n > 0 then fprintf fmt "(%s)" if_string else fprintf fmt "%s" if_string - | Exp_apply (ex1, ex2) -> - let op_pr = get_op_pr ex1 in - let format_apply = - match ex2 with - | Expression.Exp_tuple (first, second, _) - when List.mem [ 2; 3; 4; 5; 6 ] op_pr ~equal:Int.equal -> - let left_pr, right_pr = - if List.mem [ 2; 3 ] op_pr ~equal:Int.equal - then op_pr + 1, op_pr - else op_pr, op_pr + 1 - in - asprintf - "%a %a %a" - (fun fmt -> pprint_expression fmt left_pr) - first - (fun fmt -> pprint_expression fmt op_pr) - ex1 - (fun fmt -> pprint_expression fmt right_pr) - second - | _ -> - asprintf - "%a %a" - (fun fmt -> pprint_expression fmt (op_pr + 1)) - ex1 - (fun fmt -> pprint_expression fmt (op_pr + 1)) - ex2 - in - if n > op_pr then fprintf fmt "(%s)" format_apply else fprintf fmt "%s" format_apply - | Exp_match (ex, (cs, csl)) -> - let op_pr1 = get_op_pr ex in - let match_string = - asprintf - "match %a with\n | %s" - (fun fmt -> pprint_expression fmt (op_pr1 + 1)) - ex - (String.concat - ~sep:"\n | " - (List.map (cs :: csl) ~f:(fun cs -> - asprintf "%a" (fun fmt -> pprint_case fmt n) cs))) - in - if n > 0 then fprintf fmt "(%s)" match_string else fprintf fmt "%s" match_string - | Exp_constraint (ex, tye) -> - fprintf fmt "(%a : %a)" (fun fmt -> pprint_expression fmt (n + 1)) ex pprint_type tye - | Exp_if (ex1, ex2, None) -> - let if_string = - asprintf - "if %a\n then %a" - (fun fmt -> pprint_expression fmt (n + 1)) - ex1 - (fun fmt -> pprint_expression fmt (n + 1)) - ex2 - in - if n > 0 then fprintf fmt "(%s)" if_string else fprintf fmt "%s" if_string - | Exp_if (ex1, ex2, Some ex3) -> - let if_string = - asprintf - "if %a\n then %a\n else %a" - (fun fmt -> pprint_expression fmt (n + 1)) - ex1 - (fun fmt -> pprint_expression fmt (n + 1)) - ex2 - (fun fmt -> pprint_expression fmt (n + 1)) - ex3 - in - if n > 0 then fprintf fmt "(%s)" if_string else fprintf fmt "%s" if_string - | Exp_let (rec_fl, (vbind1, vbindl), ex) -> - let let_string = - asprintf - "let %a%s in %a" - pprint_rec - rec_fl - (String.concat - ~sep:" and " - (List.map (vbind1 :: vbindl) ~f:(fun vb -> - asprintf "%a" (fun fmt -> pprint_value_binding fmt n) vb))) - (fun fmt -> pprint_expression fmt (n + 1)) - ex - in - if n > 0 then fprintf fmt "(%s)" let_string else fprintf fmt "%s" let_string - | Exp_construct (id, None) -> fprintf fmt "(%s)" id - | Exp_construct (id, Some exp) -> - fprintf fmt "(%s (%a))" id (fun fmt -> pprint_expression fmt (n + 1)) exp - -and pprint_value_binding fmt n vb = - let open Expression in - fprintf - fmt - "%a = %a" - pprint_pattern - vb.pat - (fun fmt -> pprint_expression fmt (n + 1)) - vb.expr - -and pprint_case fmt n case = - let open Expression in - fprintf - fmt - "%a -> %a" - pprint_pattern - case.first - (fun fmt -> pprint_expression fmt (n + 1)) - case.second - -and pprint_function_with_cases fmt (cs, csl, n) = - fprintf - fmt - "function %s" - (String.concat - (List.map (cs :: csl) ~f:(fun c -> - asprintf "\n | %a" (fun fmt -> pprint_case fmt n) c))) -;; - -let pprint_structure_item fmt n = - let open Structure in - function - | Str_eval exp -> fprintf fmt "%a ;;\n" (fun fmt -> pprint_expression fmt n) exp - | Str_value (rec_flag, (vbind1, vbindl)) -> - let bindings_str = - match vbind1 :: vbindl with - | [] -> "" - | _ -> - String.concat - ~sep:" and\n " - (List.map (vbind1 :: vbindl) ~f:(fun vb -> - asprintf "%a" (fun fmt -> pprint_value_binding fmt n) vb)) - in - fprintf fmt "let %a%s;;\n\n" pprint_rec rec_flag bindings_str - | Str_adt (tparam, id, (constr1, constrl)) -> - let tparam_ident_str = - match List.length tparam with - | 0 -> "" - | 1 -> asprintf "'%s " (List.hd_exn tparam) - | _ -> - "('" - ^ String.concat ~sep:", '" (List.map tparam ~f:(fun param -> asprintf "%s" param)) - ^ ") " - in - let var_t_str = - match constr1 :: constrl with - | [] -> "" - | _ -> - " | " - ^ String.concat - ~sep:"\n | " - (List.map (constr1 :: constrl) ~f:(fun (id, typ) -> - match typ with - | Some t -> asprintf "%s of %a" id pprint_type t - | None -> asprintf "%s" id)) - in - fprintf fmt "type %s%s =\n%s\n;;\n\n" tparam_ident_str id var_t_str -;; - -let pprint_program fmt = List.iter ~f:(pprint_structure_item fmt 0) - -let pp printer parser str = - match parse_string ~consume:Angstrom.Consume.All parser str with - | Ok res -> printer std_formatter res - | Error _ -> Stdio.print_endline "Syntax error" -;; diff --git a/OcamlADT/lib/pprinter.mli b/OcamlADT/lib/pprinter.mli deleted file mode 100644 index 3fa001649..000000000 --- a/OcamlADT/lib/pprinter.mli +++ /dev/null @@ -1,22 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val pprint_constant : Format.formatter -> Constant.t -> unit -val pprint_type : Format.formatter -> TypeExpr.t -> unit -val pprint_pattern : Format.formatter -> Pattern.t -> unit -val pprint_rec : Format.formatter -> Expression.rec_flag -> unit -val pprint_expression : Format.formatter -> int -> Expression.t -> unit - -val pprint_value_binding - : Format.formatter - -> int - -> Expression.t Expression.value_binding - -> unit - -val pprint_case : Format.formatter -> int -> Expression.t Expression.case -> unit -val pprint_structure_item : Format.formatter -> int -> Structure.structure_item -> unit -val pprint_program : Format.formatter -> Structure.structure_item list -> unit -val pp : (Format.formatter -> 'a -> unit) -> 'a Angstrom.t -> string -> unit diff --git a/OcamlADT/lib/qshrinker/dune b/OcamlADT/lib/qshrinker/dune deleted file mode 100644 index 91d3a0539..000000000 --- a/OcamlADT/lib/qshrinker/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name qshrinker) - (modules Shrinker) - (libraries stdio ocamladt_lib) - (preprocess - (pps ppx_expect ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx)) - (inline_tests)) diff --git a/OcamlADT/lib/qshrinker/shrinker.ml b/OcamlADT/lib/qshrinker/shrinker.ml deleted file mode 100644 index 88f019392..000000000 --- a/OcamlADT/lib/qshrinker/shrinker.ml +++ /dev/null @@ -1,165 +0,0 @@ -(** Copyright 2024, Rodion Suvorov, Mikhail Gavrilenko*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open QCheck.Iter -open QCheck.Shrink -open Ocamladt_lib.Ast - -module ShrinkQCheck = struct - let filter predicate iter = - iter >>= fun x -> if predicate x then QCheck.Iter.return x else QCheck.Iter.empty - ;; - - let shrink_list1 ~shrink_head ~shrink_tail (head, tail) = - match tail with - | [] -> shrink_head head >|= fun head' -> head', tail - | _ -> - let open QCheck.Iter in - shrink_head head - >|= (fun head' -> head', tail) - <+> (QCheck.Shrink.list ~shrink:shrink_tail tail >|= fun tail' -> head, tail') - |> filter (fun (_, t) -> - match t with - | [] -> false - | _ -> true) - ;; - - let shrink_list2 ~shrink_first ~shrink_second ~shrink_tail (first, second, tail) = - match tail with - | [] -> - let open QCheck.Iter in - shrink_first first - >|= (fun first' -> first', second, tail) - <+> (shrink_second second >|= fun second' -> first, second', tail) - | _ -> - let open QCheck.Iter in - shrink_first first - >|= (fun first' -> first', second, tail) - <+> (shrink_second second >|= fun second' -> first, second', tail) - <+> (QCheck.Shrink.list ~shrink:shrink_tail tail - >|= fun tail' -> first, second, tail') - |> filter (fun (_, _, t) -> - match t with - | [] -> false - | _ -> true) - ;; - - let rec shrink_pattern = function - | Pattern.Pat_any -> QCheck.Iter.return Pattern.Pat_any - | Pattern.Pat_var id -> string ~shrink:char id >|= fun id' -> Pattern.Pat_var id' - | Pattern.Pat_constant const -> - (match const with - | Constant.Const_integer i -> - int i >|= fun i' -> Pattern.Pat_constant (Constant.Const_integer i') - | Constant.Const_char ch -> - char ch >|= fun ch' -> Pattern.Pat_constant (Constant.Const_char ch') - | Constant.Const_string str -> - string ~shrink:char str - >|= fun str' -> Pattern.Pat_constant (Constant.Const_string str')) - | Pattern.Pat_tuple pats -> - shrink_list2 - ~shrink_first:shrink_pattern - ~shrink_second:shrink_pattern - ~shrink_tail:shrink_pattern - pats - >|= fun pats' -> Pattern.Pat_tuple pats' - | Pattern.Pat_construct (x, None) -> - QCheck.Iter.return (Pattern.Pat_construct (x, None)) - | Pattern.Pat_construct (id, Some pat) -> - shrink_pattern pat >|= fun pat' -> Pattern.Pat_construct (id, Some pat') - | Pattern.Pat_constraint (pat, core_type) -> - shrink_pattern pat >|= fun pat' -> Pattern.Pat_constraint (pat', core_type) - - and shrink_expression = function - | Expression.Exp_ident id -> - string ~shrink:char id >|= fun id' -> Expression.Exp_ident id' - | Expression.Exp_constant const -> - (match const with - | Constant.Const_integer i -> - int i >|= fun i' -> Expression.Exp_constant (Constant.Const_integer i') - | Constant.Const_char ch -> - char ch >|= fun ch' -> Expression.Exp_constant (Constant.Const_char ch') - | Constant.Const_string str -> - string ~shrink:char str - >|= fun str' -> Expression.Exp_constant (Constant.Const_string str')) - | Expression.Exp_tuple pats -> - shrink_list2 - ~shrink_first:shrink_expression - ~shrink_second:shrink_expression - ~shrink_tail:shrink_expression - pats - >|= fun pats' -> Expression.Exp_tuple pats' - | Expression.Exp_function cases -> - shrink_list1 ~shrink_head:shrink_case ~shrink_tail:shrink_case cases - >|= fun cases' -> Expression.Exp_function cases' - | Expression.Exp_fun (patterns, exp) -> - shrink_list1 ~shrink_head:shrink_pattern ~shrink_tail:shrink_pattern patterns - >|= (fun patterns' -> Expression.Exp_fun (patterns', exp)) - <+> shrink_expression exp - >|= fun exp' -> Expression.Exp_fun (patterns, exp') - | Expression.Exp_apply (exp1, exp2) -> - shrink_expression exp1 - >|= (fun exp1' -> Expression.Exp_apply (exp1', exp2)) - <+> shrink_expression exp2 - >|= fun exp2' -> Expression.Exp_apply (exp1, exp2') - | Expression.Exp_match (exp, cases) -> - shrink_expression exp - >>= fun exp' -> - shrink_list1 ~shrink_head:shrink_case ~shrink_tail:shrink_case cases - >>= fun cases' -> return (Expression.Exp_match (exp', cases')) - | Expression.Exp_let (rec_flag, bindings, exp) -> - shrink_list1 - ~shrink_head:shrink_value_binding - ~shrink_tail:shrink_value_binding - bindings - >|= (fun bindings' -> Expression.Exp_let (rec_flag, bindings', exp)) - <+> shrink_expression exp - >|= fun exp' -> Expression.Exp_let (rec_flag, bindings, exp') - | Expression.Exp_construct (_, None) -> empty - | Expression.Exp_construct (id, Some exp) -> - shrink_expression exp >|= fun exp' -> Expression.Exp_construct (id, Some exp') - | Expression.Exp_constraint (exp, core_type) -> - shrink_expression exp >|= fun exp' -> Expression.Exp_constraint (exp', core_type) - | Expression.Exp_if (cond, then_exp, None) -> - shrink_expression cond - >|= (fun cond' -> Expression.Exp_if (cond', then_exp, None)) - <+> shrink_expression then_exp - >|= fun then_exp' -> Expression.Exp_if (cond, then_exp', None) - | Expression.Exp_if (cond, then_exp, Some else_exp) -> - shrink_expression cond - >|= (fun cond' -> Expression.Exp_if (cond', then_exp, Some else_exp)) - <+> shrink_expression then_exp - >|= (fun then_exp' -> Expression.Exp_if (cond, then_exp', Some else_exp)) - <+> shrink_expression else_exp - >|= fun else_exp' -> Expression.Exp_if (cond, then_exp, Some else_exp') - - and shrink_value_binding value_binding = - let open Expression in - shrink_pattern value_binding.Expression.pat - >>= fun pat' -> - shrink_expression value_binding.Expression.expr - >>= fun expr' -> return { pat = pat'; expr = expr' } - - and shrink_case case = - let open Expression in - shrink_pattern case.Expression.first - >>= fun first' -> - shrink_expression case.Expression.second - >>= fun second' -> return { first = first'; second = second' } - ;; - - let shrink_structure_item = function - | Structure.Str_eval expr -> - shrink_expression expr >|= fun expr' -> Structure.Str_eval expr' - | Structure.Str_value (rec_flag, bindings) -> - shrink_list1 - ~shrink_head:shrink_value_binding - ~shrink_tail:shrink_value_binding - bindings - >|= fun (head', tail') -> Structure.Str_value (rec_flag, (head', tail')) - | Structure.Str_adt (r, b, a) -> return (Structure.Str_adt (r, b, a)) - ;; - - let shrink_structure = list ~shrink:shrink_structure_item -end diff --git a/OcamlADT/lib/qshrinker/shrinker.mli b/OcamlADT/lib/qshrinker/shrinker.mli deleted file mode 100644 index 925cbc8f2..000000000 --- a/OcamlADT/lib/qshrinker/shrinker.mli +++ /dev/null @@ -1,30 +0,0 @@ -(** Copyright 2024, Rodion Suvorov, Mikhail Gavrilenko*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Ast -open QCheck.Iter - -module ShrinkQCheck : sig - val filter : ('a -> bool) -> 'a t -> 'a t - - val shrink_list1 - : shrink_head:('a -> 'a t) - -> shrink_tail:'b QCheck.Shrink.t - -> 'a * 'b list - -> ('a * 'b list) t - - val shrink_list2 - : shrink_first:('a -> 'a t) - -> shrink_second:('b -> 'b t) - -> shrink_tail:'c QCheck.Shrink.t - -> 'a * 'b * 'c list - -> ('a * 'b * 'c list) t - - val shrink_pattern : Pattern.t QCheck.Shrink.t - val shrink_expression : Expression.t QCheck.Shrink.t - val shrink_value_binding : Expression.t Expression.value_binding QCheck.Shrink.t - val shrink_case : Expression.t Expression.case QCheck.Shrink.t - val shrink_structure_item : Structure.structure_item -> Structure.structure_item t - val shrink_structure : Structure.structure_item list QCheck.Shrink.t -end diff --git a/OcamlADT/lib/tests/dune b/OcamlADT/lib/tests/dune deleted file mode 100644 index f2869e456..000000000 --- a/OcamlADT/lib/tests/dune +++ /dev/null @@ -1,12 +0,0 @@ -(library - (name qcheckrun) - (libraries stdio ocamladt_lib qcheck-core qcheck-core.runner qshrinker) - (preprocess - (pps ppx_expect ppx_deriving.show)) - (instrumentation - (backend bisect_ppx)) - (inline_tests)) - -(cram - (applies_to interpret_tests) - (deps ../repl/REPL.exe)) diff --git a/OcamlADT/lib/tests/qcheckrun.ml b/OcamlADT/lib/tests/qcheckrun.ml deleted file mode 100644 index a9ee45fbf..000000000 --- a/OcamlADT/lib/tests/qcheckrun.ml +++ /dev/null @@ -1,52 +0,0 @@ -(** Copyright 2024, Rodion Suvorov, Mikhail Gavrilenko*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Ocamladt_lib.Parser -open Ocamladt_lib.Ast -open Ocamladt_lib.Pprinter -open Stdlib.Format - -let arbitrary = - QCheck.make - ~print:(fun p -> asprintf "%a" pp_program p) - (* ~shrink:Shrinker.ShrinkQCheck.shrink_structure *) - (Program.gen_program 20) -;; - -let test_round_trip2 = - QCheck.Test.make - ~name:"round-trip parsing and pretty printing" - ~count:10 - arbitrary - (fun program -> - let program_ast = show_program program in - if String.equal program_ast "[]" - then ( - printf ""; - true) - else ( - let printed_program = asprintf "%a" pprint_program program in - match parse printed_program with - | Ok parsed_program -> - let result = equal_program parsed_program program in - if result - then () - else - printf - "Mismatch! Original: %s\nPprinted: %s\nParsed: %s\n" - (show_program program) - printed_program - (show_program parsed_program); - result - | Error err -> - printf "Generated program:\n%s\n\n" printed_program; - printf "Parsing failed with error: %s\n" err; - false)) -;; - -let () = - let _ : int = QCheck_base_runner.run_tests [ test_round_trip2 ] in - () -;; diff --git a/OcamlADT/lib/tests/qcheckrun.mli b/OcamlADT/lib/tests/qcheckrun.mli deleted file mode 100644 index 41d88af4f..000000000 --- a/OcamlADT/lib/tests/qcheckrun.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Ast - -val arbitrary : program QCheck.arbitrary -val test_round_trip2 : QCheck2.Test.t diff --git a/OcamlADT/repl/REPL.ml b/OcamlADT/repl/REPL.ml deleted file mode 100644 index 1682ea2cb..000000000 --- a/OcamlADT/repl/REPL.ml +++ /dev/null @@ -1,45 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Stdio -open Ocamladt_lib.Ast -open Ocamladt_lib.Parser - -type config = - { mutable dump_parsetree : bool - ; mutable source_file : string option - } - -let read_source = function - | Some filename -> In_channel.with_file filename ~f:In_channel.input_all - | None -> In_channel.input_all stdin -;; - -let process_input cfg = - let code = read_source cfg.source_file in - match parse code with - | Ok ast -> - if cfg.dump_parsetree - then printf "AST: %s\n" (show_program ast) - else printf "Code executed: %s\n" code - | Error err -> eprintf "Error during parsing: %s\n" err -;; - -let () = - let config = { dump_parsetree = false; source_file = None } in - let () = - let open Arg in - parse - [ "-dparsetree", Unit (fun () -> config.dump_parsetree <- true), "Parse tree dump" - ; ( "-srcfile" - , String (fun filename -> config.source_file <- Some filename) - , "Read code from source file" ) - ] - (fun _ -> - Format.eprintf "Zero arguments are not supported\n"; - exit 1) - "REPL for Ocaml+ADT" - in - process_input config -;; diff --git a/OcamlADT/repl/dune b/OcamlADT/repl/dune deleted file mode 100644 index f9effbc62..000000000 --- a/OcamlADT/repl/dune +++ /dev/null @@ -1,7 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (modules REPL) - (libraries stdio OcamlADT.Lib) - (instrumentation - (backend bisect_ppx))) diff --git a/OcamlADT/repl/factexample.txt b/OcamlADT/repl/factexample.txt deleted file mode 100644 index 38c22fb14..000000000 --- a/OcamlADT/repl/factexample.txt +++ /dev/null @@ -1 +0,0 @@ -j ;; \ No newline at end of file diff --git a/OcamlADT/tests/dune b/OcamlADT/tests/dune deleted file mode 100644 index 24ac1bfd0..000000000 --- a/OcamlADT/tests/dune +++ /dev/null @@ -1,39 +0,0 @@ -(library - (name ocamladt_tests) - (public_name OcamlADT.Tests) - (libraries - stdio - ocamladt_lib - qcheck-core - qcheck-core.runner - ppx_deriving_qcheck) - (preprocess - (pps ppx_expect ppx_deriving_qcheck)) - (instrumentation - (backend bisect_ppx)) - (inline_tests)) - -(cram - (applies_to repl) - (deps - ../bin/interpret.exe - manytests/typed/001fac.ml - manytests/typed/002fac.ml - manytests/typed/003fib.ml - manytests/typed/004manyargs.ml - manytests/typed/005fix.ml - manytests/typed/006partial.ml - manytests/typed/006partial2.ml - manytests/typed/006partial3.ml - manytests/typed/007order.ml - manytests/typed/008ascription.ml - manytests/typed/009let_poly.ml - manytests/typed/010sukharev.ml - manytests/typed/015tuples.ml - manytests/typed/016lists.ml - manytests/do_not_type/001.ml - manytests/do_not_type/002if.ml - manytests/do_not_type/003occurs.ml - manytests/do_not_type/004let_poly.ml - manytests/do_not_type/015tuples.ml - manytests/do_not_type/099.ml)) diff --git a/OcamlADT/tests/infer.ml b/OcamlADT/tests/infer.ml deleted file mode 100644 index 16d556bf5..000000000 --- a/OcamlADT/tests/infer.ml +++ /dev/null @@ -1,956 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Parser -open Format -open Ocamladt_lib.Infer -open Ocamladt_lib.InferTypes -open Base - -let filter names = - let rev_names = List.rev names in - List.fold_left rev_names ~init:[] ~f:(fun acc name -> - match List.find acc ~f:(fun a -> String.equal a name) with - | None -> acc @ [ name ] - | Some _ -> acc) -;; - -let pprint_result env (names : string list) = - let trash = [] in - List.iter - (List.rev @@ filter names) - ~f:(fun key -> - match Map.find env key with - | None -> printf "" - | Some typ -> - (match List.find trash ~f:(fun a -> String.equal a key) with - | Some _ -> printf "" - | None -> - (match typ with - | Forall (args, typ) -> - let m, _, _ = minimize (binder_to_list args) in - (match key with - | x when Stdlib.Char.code x.[0] >= 65 && Stdlib.Char.code x.[0] <= 90 -> - printf "" - | "-" -> printf "%s : %a\n" key (pprint_type ~poly_names_map:m) typ - | _ -> printf "val %s : %a\n" key (pprint_type ~poly_names_map:m) typ)))) -;; - -let parse_and_infer_result program = - match parse_str program with - | str -> - (match run_infer_program str env_with_things with - | Ok (env, names) -> pprint_result env names - (* | Ok env -> printf "%a\n" TypeEnv.pp_env env *) - | Error err -> printf "%a" pp_inf_err err) -;; - -(* - | ____ U ___ u _ _ U ___ u _____ _____ __ __ ____ U _____ u - | | _"\ \/"_ \/ | \ |"| \/"_ \/|_ " _| |_ " _| \ \ / /U| _"\ u\| ___"|/ - |/| | | | | | | | <| \| |> | | | | | | | | \ V / \| |_) |/ | _|' - |U| |_| |\.-,_| |_| | U| |\ |u.-,_| |_| | /| |\ /| |\ U_|"|_u | __/ | |___ - | |____/ u \_)-\___/ |_| \_| \_)-\___/ u |_|U u |_|U |_| |_| |_____| - | |||_ \\ || \\,-. \\ _// \\_ _// \\_.-,//|(_ ||>>_ << >> - | (__)_) (__) (_") (_/ (__) (__) (__) (__) (__)\_) (__)(__)__) (__) (__) -*) - -(*PASSED*) -let%expect_test "001" = - parse_and_infer_result {| -let recfac n = if n<=1 then 1 else n * fac (n-1);;|}; - [%expect {| Unbound_variable: "fac" |}] -;; - -(*PASSED*) -let%expect_test "002" = - parse_and_infer_result {| -let main = if true then 1 else false;;|}; - [%expect {| Unification_failed: int # bool |}] -;; - -(*PASSED*) -let%expect_test "003 " = - parse_and_infer_result - {| -let fix f = (fun x -> f (fun f -> x x f)) (fun x -> f (fun f -> x x f));;|}; - [%expect {| Occurs_check: 'c and 'c -> 'b |}] -;; - -(*PASSED*) -let%expect_test "004 " = - parse_and_infer_result {| -let _1 = - (fun f -> (f 1, f true)) (fun x -> x);;|}; - [%expect {| Unification_failed: int # bool |}] -;; - -(*PASSED*) -let%expect_test "005 " = - parse_and_infer_result - {| -let _2 = function - | Some f -> let _ = f "42" in f 42 - | None -> 1;;|}; - [%expect {| Unification_failed: string # int |}] -;; - -(*PASSED*) -let%expect_test "015" = - parse_and_infer_result {|let rec (a,b) = (a,b);;|}; - [%expect {| Wrong right value in rec |}] -;; - -(*PASSED*) -let%expect_test "016" = - parse_and_infer_result {|let a, _ = 1, 2, 3;;|}; - [%expect {| Unification_failed: int * int * int # 'b * 'a |}] -;; - -(*PASSED*) -let%expect_test "091.1" = - parse_and_infer_result {|let [a] = (fun x -> x);;|}; - [%expect {| Unification_failed: 'b -> 'b # 'c list |}] -;; - -(*PASSED*) -let%expect_test "097.2" = - parse_and_infer_result {|let () = (fun x -> x);;|}; - [%expect {| Unification_failed: 'b -> 'b # unit |}] -;; - -(*PASSED*) -let%expect_test "098" = - parse_and_infer_result {|let rec x = x + 1;;|}; - [%expect {| Wrong right value in rec |}] -;; - -(*PASSED*) -let%expect_test "098" = - parse_and_infer_result {|let rec x::[] = [1];;|}; - [%expect {| Wrong right value in rec |}] -;; - -(* - | _____ __ __ ____ U _____ u ____ - | |_ " _| \ \ / /U| _"\ u\| ___"|/| _"\ - | | | \ V / \| |_) |/ | _|" /| | | | - | /| |\ U_|"|_u | __/ | |___ U| |_| |\ - | u |_|U |_| |_| |_____| |____/ u - | _// \\_.-,//|(_ ||>>_ << >> |||_ - |(__) (__)\_) (__)(__)__) (__) (__)(__)_) -*) - -(*PASSED*) -let%expect_test "001fact without builtin" = - parse_and_infer_result {| -let rec fac n = if n<=1 then 1 else n * fac (n-1);;|}; - [%expect {| - val fac : int -> int |}] -;; - -(*passed*) -let%expect_test "001fact with builtin" = - parse_and_infer_result - {| -let rec fac n = if n<=1 then 1 else n * fac (n-1);; - let main = - let () = print_int (fac 4) in - 0;;|}; - [%expect {| - val fac : int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "002fact without builtin" = - parse_and_infer_result - {| -let rec fac_cps n k = - if n=1 then k 1 else - fac_cps (n-1) (fun p -> k (p*n));;|}; - [%expect {| - val fac_cps : int -> (int -> 'a) -> 'a |}] -;; - -(*passed*) -let%expect_test "002fact builtin" = - parse_and_infer_result - {| -let rec fac_cps n k = - if n=1 then k 1 else - fac_cps (n-1) (fun p -> k (p*n));; let main = - let () = print_int (fac_cps 4 (fun print_int -> print_int)) in - 0;;|}; - [%expect {| - val fac_cps : int -> (int -> 'a) -> 'a - val main : int |}] -;; - -(*PASSED*) -let%expect_test "003fib without builtin" = - parse_and_infer_result - {| -let rec fib_acc a b n = - if n=1 then b - else - let n1 = n-1 in - let ab = a+b in - fib_acc b ab n1;; - let rec fib n = - if n<2 - then n - else fib (n - 1) + fib (n - 2);;|}; - [%expect {| - val fib_acc : int -> int -> int -> int - val fib : int -> int |}] -;; - -(*passed*) -let%expect_test "003fib builtin" = - parse_and_infer_result - {| -let rec fib_acc a b n = - if n=1 then b - else - let n1 = n-1 in - let ab = a+b in - fib_acc b ab n1;; - let rec fib n = - if n<2 - then n - else fib (n - 1) + fib (n - 2);; - let main = - let () = print_int (fib_acc 0 1 4) in - let () = print_int (fib 4) in - 0;;|}; - [%expect - {| - val fib_acc : int -> int -> int -> int - val fib : int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "004" = - parse_and_infer_result - {| -let wrap f = if 1 = 1 then f else f;; - -let test3 a b c = - let a = print_int a in - let b = print_int b in - let c = print_int c in - 0;; - -let test10 a b c d e f g h i j = a + b + c + d + e + f + g + h + i + j;; - -let main = - let rez = - (wrap test10 1 10 100 1000 10000 100000 1000000 10000000 100000000 - 1000000000) - in - let () = print_int rez in - let temp2 = wrap test3 1 10 100 in - 0;;|}; - [%expect - {| - val wrap : 'a -> 'a - val test3 : int -> int -> int -> int - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "005" = - parse_and_infer_result - {| -let rec fix f x = f (fix f) x;; - -let fac self n = if n<=1 then 1 else n * self (n-1);;|}; - [%expect - {| - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val fac : (int -> int) -> int -> int |}] -;; - -(*PASSED*) -let%expect_test "005" = - parse_and_infer_result - {| -let rec fix f x = f (fix f) x;; - -let fac self n = if n<=1 then 1 else n * self (n-1);; - -let main = - let () = print_int (fix fac 6) in - 0;;|}; - [%expect - {| - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val fac : (int -> int) -> int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "006" = - parse_and_infer_result - {|let foo b = if b then (fun foo -> foo+2) else (fun foo -> foo*10);; - let foo x = foo true (foo false (foo true (foo false x)));; - let main = - let () = print_int (foo 11) in - 0;;|}; - [%expect {| - val foo : int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "006.2" = - parse_and_infer_result - {|let foo a b c = - let () = print_int a in - let () = print_int b in - let () = print_int c in - a + b * c;; - -let main = - let foo = foo 1 in - let foo = foo 2 in - let foo = foo 3 in - let () = print_int foo in - 0;;|}; - [%expect {| - val foo : int -> int -> int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "006.3" = - parse_and_infer_result - {|let foo a = - let () = print_int a in fun b -> - let () = print_int b in fun c -> - print_int c;; - -let main = - let () = foo 4 8 9 in - 0;;|}; - [%expect {| - val foo : int -> int -> int -> unit - val main : int |}] -;; - -(*PASSED*) -let%expect_test "007" = - parse_and_infer_result - {|let _start () () a () b _c () d __ = - let () = print_int (a+b) in - let () = print_int __ in - a*b / _c + d;; - -let main = - print_int (_start (print_int 1) (print_int 2) 3 (print_int 4) 100 1000 (print_int (-1)) 10000 (-555555));;|}; - [%expect - {| - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int - val main : unit |}] -;; - -(*PASSED*) -let%expect_test "008" = - parse_and_infer_result - {| -let addi = fun f g x -> (f x (g x: bool) : int);; -let main = - let () = print_int (addi (fun x b -> if b then x+1 else x*2) (fun _start -> _start/2 = 0) 4) in - 0;;|}; - [%expect - {| - val addi : ('a -> bool -> int) -> ('a -> bool) -> 'a -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "009" = - parse_and_infer_result {| -let temp = - let f = fun x -> x in - (f 1, f true);;|}; - [%expect {| - val temp : int * bool |}] -;; - -(*PASSED*) -let%expect_test "010" = - parse_and_infer_result - {| - - let _1 = fun x y (a, _) -> (x + y - a) = 1 - -let _2 = - let x, Some f = 1, Some ( "p1onerka was here" ) - in x - -let _3 = Some (1, "hi") - -let _4 = let rec f x = f 5 in f - -let _5 = - let id x = x in - match Some id with - | Some f -> let _ = f "42" in f 42 - | None -> 0 - -let _6 = fun arg -> match arg with Some x -> let y = x in y - -let int_of_option = function Some x -> x | None -> 0 - -let _42 = function 42 -> true | _ -> false - -let id1, id2 = let id x = x in (id, id) - |}; - [%expect - {| - val _1 : int -> int -> int * 'a -> bool - val _2 : int - val _3 : (int * string) option - val _4 : int -> 'a - val _5 : int - val _6 : 'a option -> 'a - val int_of_option : int option -> int - val _42 : int -> bool - val id2 : 'b -> 'b - val id1 : 'a -> 'a |}] -;; - -(*PASSED*) -let%expect_test "015" = - parse_and_infer_result - {| -let rec fix f x = f (fix f) x -let map f p = let (a,b) = p in (f a, f b) -let fixpoly l = - fix (fun self l -> map (fun li x -> li (self l) x) l) l -let feven p n = - let (e, o) = p in - if n = 0 then 1 else o (n - 1) -let fodd p n = - let (e, o) = p in - if n = 0 then 0 else e (n - 1) - let tie = fixpoly (feven, fodd) - let rec meven n = if n = 0 then 1 else modd (n - 1) -and modd n = if n = 0 then 1 else meven (n - 1) -let main = - let () = print_int (modd 1) in - let () = print_int (meven 2) in - let (even,odd) = tie in - let () = print_int (odd 3) in - let () = print_int (even 4) in - 0 -|}; - [%expect - {| - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b - val map : ('a -> 'b) -> 'a * 'a -> 'b * 'b - val fixpoly : (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) * (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) -> ('a -> 'b) * ('a -> 'b) - val feven : 'a * (int -> int) -> int -> int - val fodd : (int -> int) * 'a -> int -> int - val tie : (int -> int) * (int -> int) - val meven : int -> int - val modd : int -> int - val main : int |}] -;; - -(*PASSED*) -let%expect_test "016" = - parse_and_infer_result - {| -let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl - -let length_tail = - let rec helper acc xs = - match xs with - | [] -> acc - | h::tl -> helper (acc + 1) tl - in - helper 0 - -let rec map f xs = - match xs with - | [] -> [] - | a::[] -> [f a] - | a::b::[] -> [f a; f b] - | a::b::c::[] -> [f a; f b; f c] - | a::b::c::d::tl -> f a :: f b :: f c :: f d :: map f tl - -let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys) - -let concat = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper - -let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter f tl - -let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - -let main = - let () = iter print_int [1;2;3] in - let () = print_int (length (cartesian [1;2] [1;2;3;4])) in - 0 - -|}; - [%expect - {| - val length : 'a list -> int - val length_tail : 'a list -> int - val map : ('a -> 'b) -> 'a list -> 'b list - val append : 'a list -> 'a list -> 'a list - val concat : 'a list list -> 'a list - val iter : ('a -> unit) -> 'a list -> unit - val cartesian : 'a list -> 'b list -> ('a * 'b) list - val main : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5+5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5+5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5/5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5-5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5*5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5>=5;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5<=5;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5>5;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|5<5;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|true || false;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|false && false;;|}; - [%expect {| - : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {|let id x = x in -let homka = Some id in -match homka with -| Some f -> f 42, f "42";;|}; - [%expect {| - : int * string |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|function 5 -> 'c';;|}; - [%expect {| - : int -> char |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|function 5 -> 'c' | 22 -> 'k';;|}; - [%expect {| - : int -> char |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|function 5 -> 'c' | 22 -> 23;;|}; - [%expect {| Unification_failed: char # int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|function 5 -> 'c' | 'c' -> 23;;|}; - [%expect {| Unification_failed: int # char |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {|let id x = x in -let homkaOBOLTUS = id in -match homkaOBOLTUS with -| f -> f 42, f "42";;|}; - [%expect {| - : int * string |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|if 5=5 then 1 else 5;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|if 5=5 then "aboba";;|}; - [%expect {| - : string |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|if 5 then "aboba";;|}; - [%expect {| Unification_failed: int # bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|if true then "andreichik" else 7;;|}; - [%expect {| Unification_failed: string # int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|(5,6,7);;|}; - [%expect {| - : int * int * int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|(5,7);;|}; - [%expect {| - : int * int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|('c',7,false,"andreichik");;|}; - [%expect {| - : char * int * bool * string |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {|function -5 -> 'c' -| 67 -> 'b' -| 68 -> 'h' -| 69 -> 's' -| 89 -> 'a';;|}; - [%expect {| - : int -> char |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {|match 9 with -|5 -> 5 -|6 -> 5 -|7 -> 7 -|7 -> 1 -|7 -> 1 -|7 -> 1 -| _ -> 3 -;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|fun x -> fun y -> y+x;;|}; - [%expect {| - : int -> int -> int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|fun x -> fun y -> fun z -> fun w -> y + x * z / w;;|}; - [%expect {| - : int -> int -> int -> int -> int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let x = 1 -let y = 2 -let z = 3|}; - [%expect {| - val x : int - val y : int - val z : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let y = 5|}; - [%expect {| - val y : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let _ = (2,5) and y = ("a","b")|}; - [%expect {| - val y : string * string |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let x = (2,5) and y = ("a","b")|}; - [%expect {| - val y : string * string - val x : int * int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let (x,y) = (2,5) and z = ("a","b") - let f = x|}; - [%expect - {| - val z : string * string - val y : int - val x : int - val f : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let (x,y) = (2,'c');;|}; - [%expect {| - val y : char - val x : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let x = 5=5;;|}; - [%expect {| - val x : bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let rec g () = g ();;|}; - [%expect {| - val g : unit -> 'a |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let x = 6 and y = 6 in x + y;;|}; - [%expect {| - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let rec f x = f x;;|}; - [%expect {| - val f : 'a -> 'b |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {|let f = fun x -> x;;|}; - [%expect {| - val f : 'a -> 'a |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| -let x = 5;; -let 5 = x;;|}; - [%expect {| - val x : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| -let x = (6: char);;|}; - [%expect {| Unification_failed: int # char |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| -let x = ()|}; - [%expect {| - val x : unit |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {| -let square x = x * x;; -let id = fun x -> x in (id square) (id 123);;|}; - [%expect {| - val square : int -> int - - : int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result - {| -let rec meven n = if n = 0 then 1 else modd (n - 1) - and modd n = if n = 0 then 1 else meven (n - 1) -;;|}; - [%expect {| - val meven : int -> int - val modd : int -> int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| let f (x: int) = x + x;;|}; - [%expect {| - val f : int -> int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| let f (x: int)(y: int) = x + y;;|}; - [%expect {| - val f : int -> int -> int |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| let f (x: int) = x || x;;|}; - [%expect {| Unification_failed: int # bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| let f (x: int) = function 5 -> true | 6 -> false;;|}; - [%expect {| - val f : int -> int -> bool |}] -;; - -let%expect_test "zero" = - parse_and_infer_result {| let (f: int -> bool) = function 5 -> true | 6 -> false;;|}; - [%expect {| - val f : int -> bool |}] -;; - -let%expect_test "Simplest ADT" = - parse_and_infer_result {| - type shape = Circle - let x = Circle -|}; - [%expect {| - val x : shape |}] -;; - -let%expect_test "ADT of" = - parse_and_infer_result - {| - type shape = Circle of int ;; - type 'a koka = Circle of int ;; - let x = Circle 5 -|}; - [%expect {| - val x : 'a koka |}] -;; - -let%expect_test "ADT of few" = - parse_and_infer_result - {| - type shape = - Circle of int -| Rectangle of char -| Triangle of int*int -;; -let x = 10;; -let Circle (5,5) = Circle x;; -|}; - [%expect {| Unification_failed: int # int * int |}] -;; - -let%expect_test "ADT with poly" = - parse_and_infer_result - {| - type 'a shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let x = 10 -let y = Circle x -let (z: int shape) = Rectangle (2,5) -let q = Square 34985734895 -|}; - [%expect - {| - val x : int - val y : 'a shape - val z : int shape - val q : 'a shape |}] -;; - -let%expect_test "ADT with poly constraint" = - parse_and_infer_result - {| - type 'a shape = Circle of int - | Rectangle of char * int - | Square of int * 'a * 'a -;; -let (x: shape) = Circle 5;; -|}; - [%expect {| Unification_failed: 'a shape # shape |}] -;; - -let%expect_test "ADT with constraint" = - parse_and_infer_result - {| - type 'a shape = Circle of int - | Rectangle of char * int - | Square of int * 'a * 'a -;; -let (x: (int,int) shape) = Circle 5;; -|}; - [%expect {| Unification_failed: 'a shape # int int shape |}] -;; - -let%expect_test "ADT with constraint exp" = - parse_and_infer_result - {| - type 'a shape = Circle of int - | Rectangle of char * int - | Square of int * 'a * 'a -;; -let y = Circle 5;; -let (x: char shape) = y;; -|}; - [%expect {| - val y : 'a shape - val x : char shape |}] -;; - -let%expect_test "ADT arity" = - parse_and_infer_result {| -type 'a foo = Foo -type bar = Bar of foo - -|}; - [%expect {| - Arity_mismatch |}] -;; - -let%expect_test "ADT arity" = - parse_and_infer_result - {| -type 'a foo = Foo -type 'a bar = Bar of 'a foo -let x = Bar Foo -|}; - [%expect {| - val x : 'a bar |}] -;; - -let%expect_test "alot" = - parse_and_infer_result - {| -let f q w e r t y u i o p a s d g h j k l z x c v b n m qq ww ee rr tt yy uu ii oo pp aa ss dd ff gg hh jj kk ll zz xx cc vv = 5;;|}; - [%expect - {| - val f : 'a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> 'h -> 'i -> 'j -> 'k -> 'l -> 'm -> 'n -> 'o -> 'p -> 'q -> 'r -> 's -> 't -> 'u -> 'v -> 'w -> 'x -> 'y -> 'z -> 'aa -> 'bb -> 'cc -> 'dd -> 'ee -> 'ff -> 'gg -> 'hh -> 'ii -> 'jj -> 'kk -> 'll -> 'mm -> 'nn -> 'oo -> 'pp -> 'qq -> 'rr -> 'ss -> 'tt -> 'uu -> 'vv -> int |}] -;; diff --git a/OcamlADT/tests/infer.mli b/OcamlADT/tests/infer.mli deleted file mode 100644 index 05791decd..000000000 --- a/OcamlADT/tests/infer.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Infer - -val pprint_result : TypeEnv.t -> string list -> unit diff --git a/OcamlADT/tests/interpreter.ml b/OcamlADT/tests/interpreter.ml deleted file mode 100644 index 2e42fca26..000000000 --- a/OcamlADT/tests/interpreter.ml +++ /dev/null @@ -1,1384 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Interpreter -open Ocamladt_lib.Interpreter.PPrinter -open Ocamladt_lib.Parser - -let pp_interpret ast = - match run_interpreter ast with - | Ok olist -> - List.iter - (fun (tag, val') -> - match tag with - | Some id -> Format.printf "val %s = %a\n" id pp_value val' - | None -> if val' <> VString "" then Format.printf "_ = %a\n" pp_value val') - olist - | Error e -> print_error e -;; - -let pp_parse str = - let ast = parse str in - match ast with - | Ok ast -> pp_interpret ast - | Error _ -> print_error ParserError -;; - -let%expect_test "empty program (fail: EmptyProgram)" = - pp_parse {||}; - [%expect {| Empty program |}] -;; - -let%expect_test "negative int constant" = - pp_parse {|-1;;|}; - [%expect {| - _ = -1 |}] -;; - -let%expect_test "zero" = - pp_parse {|0;;|}; - [%expect {| _ = 0 |}] -;; - -let%expect_test "x" = - pp_parse {|x;;|}; - [%expect {| Interpreter error: Unbound value x |}] -;; - -let%expect_test "substraction" = - pp_parse {|5-11;;|}; - [%expect {| - _ = -6 |}] -;; - -let%expect_test "strange move" = - pp_parse {|5=5;;|}; - [%expect {| - _ = true |}] -;; - -let%expect_test "assignment (fail: UnboundValue - x)" = - pp_parse {|x = 51;;|}; - [%expect {| - Interpreter error: Unbound value x |}] -;; - -let%expect_test "operators with different priorities" = - pp_parse {|5-5*1;;|}; - [%expect {| _ = 0 |}] -;; - -let%expect_test "just let (int)" = - pp_parse {|let x = 51;;|}; - [%expect {| val x = 51 |}] -;; - -let%expect_test "just let (string)" = - pp_parse {|let x = "51";;|}; - [%expect {| val x = "51" |}] -;; - -let%expect_test "just let (char)" = - pp_parse {|let x = '5';;|}; - [%expect {| val x = '5' |}] -;; - -let%expect_test "int print_endline (fail: TypeMismatch)" = - pp_parse {|let x = 51 in -print_endline x;;|}; - [%expect {| - Interpreter error: Type mismatch |}] -;; - -let%expect_test "string print_endline" = - pp_parse {|let x = "51" in -print_endline x;;|}; - [%expect {| - 51 |}] -;; - -let%expect_test "print_endline" = - pp_parse {|print_endline "51";;|}; - [%expect {| - 51 |}] -;; - -let%expect_test "print_endline as an arg" = - pp_parse {|let f = print_endline in -f "Hello";;|}; - [%expect {| - Hello |}] -;; - -let%expect_test "print_endline as an arg (fail: TypeMismatch)" = - pp_parse {|let f = print_endline in -f 5;;|}; - [%expect {| - Interpreter error: Type mismatch |}] -;; - -let%expect_test "print_int as an arg" = - pp_parse {|let f = print_int in -f 51;;|}; - [%expect {| - 51 |}] -;; - -let%expect_test "print_int let assignment" = - pp_parse {|let reca = 51 in -print_int reca;;|}; - [%expect {| - 51 |}] -;; - -let%expect_test "print_char as an arg" = - pp_parse {|let f = print_char in -f '5';;|}; - [%expect {| - 5 |}] -;; - -let%expect_test "print_char let assignment" = - pp_parse {|let reca = '5' in -print_char reca;;|}; - [%expect {| - 5 |}] -;; - -let%expect_test "let assignment none (fail: PatternMismatch)" = - pp_parse {|let Some Some Some Some Some None = 1 in -print_int None;;|}; - [%expect {| - Interpreter error: Pattern mismatch |}] -;; - -let%expect_test "multiple let assignments" = - pp_parse {| let x = 3 in let y = 4 in print_int (x + y) ;; |}; - [%expect {| - 7 |}] -;; - -let%expect_test "multiple let bool assignments" = - pp_parse {| let x = 5 = 5 in let y = 4 = 5 in print_bool (x && y) ;; |}; - [%expect {| - false |}] -;; - -let%expect_test "fun assignment with bool operators" = - pp_parse {| let id = fun x y -> x && y in print_bool (id true false) ;; |}; - [%expect {| Interpreter error: Type mismatch |}] -;; - -let%expect_test "fun assignment with bool operators (tuple arg)" = - pp_parse {| let id = fun (x, y) -> x && y in print_bool (id (true,false)) ;; |}; - [%expect {| Interpreter error: Type mismatch |}] -;; - -let%expect_test "too damn simple fun assignment (TC should fail?)" = - pp_parse {| let id = fun x -> y in print_int (id 7) ;; |}; - [%expect {| Interpreter error: Unbound value y |}] -;; - -(*4 am vibes, im sorry*) -let%expect_test "not too damn simple fun assignment" = - pp_parse {| let id = fun x -> x * x in print_int (id 7) ;; |}; - [%expect {| - 49 |}] -;; - -let%expect_test "match case (_ case)" = - pp_parse - {| -let classify n = - match n with - | 0 -> "zero" - | 1 -> "one" - | _ -> "other" -in -print_endline (classify 2);; |}; - [%expect {| - other |}] -;; - -let%expect_test "match case (specific pattern case)" = - pp_parse - {| -let classify n = - match n with - | "0" -> 51 - | "1" -> 811 - | _ -> 0 -in -print_int (classify "1");; |}; - [%expect {| - 811 |}] -;; - -let%expect_test "if then case" = - pp_parse - {| let x = 10 in -if x > 5 then print_endline "> 5" -else print_endline "<= 5";; - |}; - [%expect {| - > 5 |}] -;; - -let%expect_test "if then case (else)" = - pp_parse - {| let check_number n = - if n = 0 then - print_endline "Zero" - else if n = 1 then - print_endline "One" - else - print_endline "Other" -in -check_number 5 -;; |}; - [%expect {| - Other |}] -;; - -let%expect_test "if then case (then)" = - pp_parse - {| let check_number n = - if n = 0 then - print_endline "Zero" - else if n = 1 then - print_endline "One" - else - print_endline "Other" -in -check_number 0 -;; |}; - [%expect {| - Zero |}] -;; - -let%expect_test "if then case (else if)" = - pp_parse - {| let check_number n = - if n = 0 then - print_endline "Zero" - else if n = 1 then - print_int 555555555555 - else - print_endline "Other" -in -check_number 1 -;; |}; - [%expect {| - 555555555555 |}] -;; - -let%expect_test "if then case (else if) v2" = - pp_parse - {| let check_number n = - if n >= 0 then - print_endline "Zero" - else if n = 1 then - print_int 555555555555 - n - else - print_endline "Other" -in -check_number 1 -;; |}; - [%expect {| - Zero |}] -;; - -let%expect_test "nested assignments" = - pp_parse - {| - let x = - let y = - let z = - let w = 1 - in w - in z - in y -;; |}; - [%expect {| - val x = 1 |}] -;; - -let%expect_test "factorial" = - pp_parse - {| -let rec fact n = if n = 0 then 1 else n * fact(n-1) in -print_int (fact 5) -;; |}; - [%expect {| - 120 |}] -;; - -(*i just wanna km*) -(*upd: dont mind. fixed :\ .*) -let%expect_test "recursive function (nested apply - multiple args)" = - pp_parse - {| let rec pow x y = if y = 0 then 1 else x * pow x (y - 1) in print_int (pow 5 6);;|}; - [%expect {| - 15625 |}] -;; - -let%expect_test "factorial (multiple structure items)" = - pp_parse - {| -let rec fact n = if n = 0 then 1 else n * fact(n-1);; -let x = fact 6 in print_int x ;; |}; - [%expect {| - 720 - val fact = |}] -;; - -let%expect_test "not y.dev" = - pp_parse - {| let arith x y = (x * y, x / y, x + y, x - y);; - let prod x y = - let fst (a, _, _, _) = a in - fst (arith x y) - ;; - let p = prod 3 1;; - |}; - [%expect {| - val arith = - val prod = - val p = 3 |}] -;; - -let%expect_test "wrong input (fail: ParserError)" = - pp_parse {|let = ;;|}; - [%expect {| Parser Error |}] -;; - -let%expect_test "eval simple let binding" = - pp_parse {| let a = -(4 + 4) and b = true;; |}; - [%expect {| - val a = -8 - val b = true - |}] -;; - -let%expect_test "multiple nested let's" = - pp_parse {| - let f = - let x = "fowl" in - let y = "51" in - x <> y - ;; - |}; - [%expect {| val f = true |}] -;; - -let%expect_test "tuple assignment" = - pp_parse {| let test1 = (1, "hello", 314);; |}; - [%expect {| - val test1 = (1, "hello", 314) - |}] -;; - -let%expect_test "tuple (no assignment)" = - pp_parse {| (1, "hello", 314);; |}; - [%expect {| - _ = (1, "hello", 314) - |}] -;; - -let%expect_test "tuple assignment v2" = - pp_parse {| let swap (x, y) = (y, x);; -let test = swap (1, "ocaml");; |}; - [%expect {| - val swap = - val test = ("ocaml", 1) - |}] -;; - -let%expect_test "()" = - pp_parse - {| - let a = - let b = - let rec f = (let x = 3 in x) + 1 - in f - in ();; - let s = "string";; - |}; - [%expect {| - val a = unit - val s = "string" |}] -;; - -let%expect_test "multiple funs (+ nested)" = - pp_parse - {| let fix f = (fun x -> f (fun f -> x x f)) (fun x -> f (fun f -> x x f)) ;; - |}; - [%expect {| - val fix = - |}] -;; - -let%expect_test "option type match" = - pp_parse {| -let _2 = function - | Some f -> let _ = f "42" in f 42 - | None -> 1 -;; - |}; - [%expect {| - val _2 = - |}] -;; - -let%expect_test "tuples mismatch (fail: PatternMismatch)" = - pp_parse {| -let a, _ = 1, 2, 3 ;; - |}; - [%expect {| - Interpreter error: Pattern mismatch - |}] -;; - -let%expect_test "just fun assignment" = - pp_parse {| -let a = (fun x -> x) ;; - |}; - [%expect {| - val a = - |}] -;; - -let%expect_test "list (shouldn't work, see tests below)" = - pp_parse {| -let [a] = [42] ;; - |}; - [%expect {| - val a = 42 |}] -;; - -(* -------- ADT --------*) - -let%expect_test "adt" = - pp_parse - {| -type shape = Point of int - | Circle of int * int - | Rect of int * int * int -;; -|}; - [%expect {||}] -;; - -(*we dont support regular types like float*) -let%expect_test "adt (infer should fail)" = - pp_parse - {| -type point = float * float;; -type shape = Point of point - | Circle of point * float - | Rect of point * point -;;|}; - [%expect {| |}] -;; - -let%expect_test "simple adt with pattern matching + printing" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int - | Square of int -;; -let area s = - match s with - | Circle c -> 3 - | Square c -> 0 - | _ -> 10 -;; -let x = Circle 5 in -let y = area x in -print_int y -;; - |}; - [%expect {| - 3 - val area = |}] -;; - -let%expect_test "simple adt with pattern matching function (else case) + printing" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int - | Square of int -;; -let area s = - match s with - | Square c -> 0 - | Circle c -> 3 - | _ -> 10 -;; -let x = Rectangle 5 in -let y = area x in -print_int y -;; - |}; - [%expect {| - 10 - val area = |}] -;; - -let%expect_test "simple adt with pattern matching + printing v2" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let area s = - match s with - | Circle c -> 3 - | Square c -> 0 - | _ -> 10 -;; -let x = Rectangle (5, 10) in -let y = area x in -print_int y -;; - |}; - [%expect {| - 10 - val area = |}] -;; - -let%expect_test "simple adt with pattern matching + printing v3" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let area s = - match s with - | Circle c -> 3 - | Square c -> 0 - | Rectangle (c1, c2) -> c1 * c2 -;; -let x = Rectangle (5, 10) in -let y = area x in -print_int y -;; - |}; - [%expect {| - 50 - val area = |}] -;; - -let%expect_test "simple adt NORM (infer should fail)" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int * int - | Square of int -;; - -let x = Chto 5 -;; - |}; - [%expect {| val x = Chto 5 |}] -;; - -let%expect_test "simple adt with pattern matching (fail: PatternMismatch)" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let area s = - match s with - | Circle c -> 3 - | Chto c -> 0 -;; -let x = Square 5 in -let y = area x in -print_int y -;; - |}; - [%expect {| Interpreter error: Pattern mismatch |}] -;; - -let%expect_test "simple adt (fail: UnboundValue area)" = - pp_parse - {| -type shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let x = Cir 5 in -print_int area x;; - |}; - [%expect {| Interpreter error: Unbound value area |}] -;; - -(* good, needs a initialization check + infer print(see next tests)*) -let%expect_test "poly adt tree" = - pp_parse {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - |}; - [%expect {| |}] -;; - -let%expect_test "poly adt tree (dumb insert)" = - pp_parse - {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - -let rec insert x = function - | Leaf -> Node (x, Leaf, Leaf) - | _ -> Node (x, Leaf, Leaf) -;; - -let tree1 = - insert 6 Leaf -;; - -let rec tree_size t = - match t with - | Leaf -> 0 - | Node (a, left, right) -> 1 + tree_size left + tree_size right -;; - -let () = print_int (tree_size tree1) - - |}; - [%expect - {| - 1 - val insert = - val tree1 = Node (6, Leaf, Leaf) - val tree_size = |}] -;; - -let%expect_test "empty poly adt tree (dumb insert)" = - pp_parse - {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - -let rec insert x = function - | Leaf -> Node (x, Leaf, Leaf) - | _ -> Node (x, Leaf, Leaf) -;; - -let tree2 = Leaf;; - -let rec tree_size t = - match t with - | Leaf -> 0 - | Node (_, left, right) -> 1 + tree_size left + tree_size right -;; - -let () = print_int (tree_size tree2) - - |}; - [%expect - {| - 0 - val insert = - val tree2 = Leaf - val tree_size = |}] -;; - -let%expect_test "poly adt tree v2" = - pp_parse - {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - -let rec insert x = function - | Leaf -> Node (x, Leaf, Leaf) - | Node (value, left, right) -> - if x < value then - Node (value, insert x left, right) - else - Node (value, left, insert x right) -;; - -let tree = - insert 5 (insert 8 (insert 3 (insert 6 Leaf)));; - -let rec tree_size t = - match t with - | Leaf -> 0 - | Node (a, left, right) -> 1 + tree_size left + tree_size right -;; - -let () = print_int (tree_size tree) - - |}; - [%expect - {| - 4 - val insert = - val tree = Node (6, Node (3, Leaf, Node (5, Leaf, Leaf)), Node (8, Leaf, Leaf)) - val tree_size = |}] -;; - -let%expect_test "poly adt tree v2 (constructs)" = - pp_parse - {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - -let tree = - Node (6, - Node (3, Leaf, Node (5, Leaf, Leaf)), - Node (8, Leaf, Leaf) - );; - -let rec tree_size t = - match t with - | Leaf -> 0 - | Node (_, left, right) -> 1 + tree_size left + tree_size right -;; - -let () = print_int (tree_size tree) - - |}; - [%expect - {| - 4 - val tree = Node (6, Node (3, Leaf, Node (5, Leaf, Leaf)), Node (8, Leaf, Leaf)) - val tree_size = |}] -;; - -(*good*) -let%expect_test "simple print" = - pp_parse {| -let () = print_int 5;; - |}; - [%expect {| 5 |}] -;; - -let%expect_test "empty program (no ;;) (fail: emptyprogram)" = - pp_parse {||}; - [%expect {| Empty program |}] -;; - -let%expect_test "function" = - pp_parse - {| - let f = function - | 5 -> 5 - | _ -> 0 - in - f 5, f 42 - |}; - [%expect {| _ = (5, 0) |}] -;; - -let%expect_test "pattern matching function with print_int" = - pp_parse {| let f = function 0 -> 42 | _ -> 99 in -print_int (f 0)|}; - [%expect {| 42 |}] -;; - -let%expect_test "nested function as apply with print_int" = - pp_parse {| print_int ((function x -> function y -> x + y) 3 4);; |}; - [%expect {| 7 |}] -;; - -let%expect_test "tuple pattern function with print_string (fail: TypeMismatch)" = - pp_parse {| print_endline ((function (x, y) -> x + y) ("Hello", " World")) |}; - [%expect {| Interpreter error: Type mismatch |}] -;; - -let%expect_test "function inside let binding with print_int" = - pp_parse {| let f = function x -> x * 2 in print_int (f 10) |}; - [%expect {| 20 |}] -;; - -let%expect_test "some" = - pp_parse - {| - let f = function - | Some x -> x - | None -> 0 - in - f None, f (Some 42) - |}; - [%expect {| _ = (None, 42) |}] -;; - -(*aka manytests*) - -let%expect_test "001fac" = - pp_parse - {| -let rec fac n = if n<=1 then 1 else n * fac (n-1) - -let main = - let () = print_int (fac 4) in - 0 -|}; - [%expect {| - 24 - val fac = - val main = 0 |}] -;; - -let%expect_test "002fac" = - pp_parse - {| -let rec fac_cps n k = - if n=1 then k 1 else - fac_cps (n-1) (fun p -> k (p*n)) - -let main = - let () = print_int (fac_cps 4 (fun print_int -> print_int)) in - 0 -|}; - [%expect {| - 24 - val fac_cps = - val main = 0 |}] -;; - -let%expect_test "003fac" = - pp_parse - {| -let rec fib_acc a b n = - if n=1 then b - else - let n1 = n-1 in - let ab = a+b in - fib_acc b ab n1 - -let rec fib n = - if n<2 - then n - else fib (n - 1) + fib (n - 2) - -let main = - let () = print_int (fib_acc 0 1 4) in - let () = print_int (fib 4) in - 0 -|}; - [%expect {| - 3 - 3 - val fib_acc = - val fib = - val main = 0 |}] -;; - -let%expect_test "004manyargs" = - pp_parse - {| - -let wrap f = if 1 = 1 then f else f - -let test3 a b c = - let a = print_int a in - let b = print_int b in - let c = print_int c in - 0 - -let test10 a b c d e f g h i j = a + b + c + d + e + f + g + h + i + j - -let main = - let rez = - (wrap test10 1 10 100 1000 10000 100000 1000000 10000000 100000000 - 1000000000) - in - let () = print_int rez in - let temp2 = wrap test3 1 10 100 in - 0 -|}; - [%expect - {| - 1111111111 - 1 - 10 - 100 - val wrap = - val test3 = - val test10 = - val main = 0 |}] -;; - -let%expect_test "005fix" = - pp_parse - {| -let rec fix f x = f (fix f) x - -let fac self n = if n<=1 then 1 else n * self (n-1) - -let main = - let () = print_int (fix fac 6) in - 0 -|}; - [%expect {| - 720 - val fix = - val fac = - val main = 0 |}] -;; - -let%expect_test "006partial" = - pp_parse - {| -let foo a b c = - let () = print_int a in - let () = print_int b in - let () = print_int c in - a + b * c - -let main = - let foo = foo 1 in - let foo = foo 2 in - let foo = foo 3 in - let () = print_int foo in - 0 -|}; - [%expect {| - 1 - 2 - 3 - 7 - val foo = - val main = 0 |}] -;; - -let%expect_test "006partial2" = - pp_parse - {| -let foo b = if b then (fun foo -> foo+2) else (fun foo -> foo*10) - -let foo x = foo true (foo false (foo true (foo false x))) -let main = - let () = print_int (foo 11) in - 0 -|}; - [%expect {| - 1122 - val foo = - val main = 0 |}] -;; - -let%expect_test "006partial3" = - pp_parse - {| - -let foo a = - let () = print_int a in fun b -> - let () = print_int b in fun c -> - print_int c - -let main = - let () = foo 4 8 9 in - 0 -|}; - [%expect {| - 4 - 8 - 9 - val foo = - val main = 0 |}] -;; - -let%expect_test "007order" = - pp_parse - {| -let _start () () a () b _c () d __ = - let () = print_int (a+b) in - let () = print_int __ in - a*b / _c + d - - -let main = - print_int (_start (print_int 1) (print_int 2) 3 (print_int 4) 100 1000 (print_int (-1)) 10000 (-555555)) -|}; - [%expect - {| - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - val _start = - val main = "" |}] -;; - -let%expect_test "008ascription" = - pp_parse - {| -let addi = fun f g x -> (f x (g x: bool) : int) - -let main = - let () = print_int (addi (fun x b -> if b then x+1 else x*2) (fun _start -> _start/2 = 0) 4) in - 0 -|}; - [%expect {| - 8 - val addi = - val main = 0 |}] -;; - -let%expect_test "009let_poly" = - pp_parse {| -let temp = - let f = fun x -> x in - (f 1, f true) -|}; - [%expect {| val temp = (1, true) |}] -;; - -let%expect_test "010sukharev" = - pp_parse - {| - let _1 = fun x y (a, _) -> (x + y - a) = 1 - -let _2 = - let x, Some f = 1, Some ( "p1onerka was here" ) - in x - -let _3 = Some (1, "hi") - -let _4 = let rec f x = f 5 in f - -let _5 = - let id x = x in - match Some id with - | Some f -> let _ = f "42" in f 42 - | None -> 0 - -let int_of_option = function Some x -> x | None -> 0 -|}; - [%expect - {| - val _1 = - val _2 = 1 - val _3 = Some (1, "hi") - val _4 = - val _5 = 42 - val int_of_option = |}] -;; - -let%expect_test "011sukharev" = - pp_parse {| -let id1, id2 = let id x = x in (id, id) - -|}; - [%expect {| - val id1 = - val id2 = - |}] -;; - -let%expect_test "012sukharev" = - pp_parse {| -let _6 = fun arg -> match arg with Some x -> let y = x in y - -|}; - [%expect {| val _6 = |}] -;; - -let%expect_test "013sukharev" = - pp_parse {| - -let _42 = function 42 -> true | _ -> false -|}; - [%expect {| val _42 = |}] -;; - -let%expect_test "015tuples" = - pp_parse - {| - -let rec fix f x = f (fix f) x -let map f p = let (a,b) = p in (f a, f b) -let fixpoly l = - fix (fun self l -> map (fun li x -> li (self l) x) l) l -let feven p n = - let (e, o) = p in - if n = 0 then 1 else o (n - 1) -let fodd p n = - let (e, o) = p in - if n = 0 then 0 else e (n - 1) -let tie = fixpoly (feven, fodd) - -let rec meven n = if n = 0 then 1 else modd (n - 1) -and modd n = if n = 0 then 1 else meven (n - 1) -let main = - let () = print_int (modd 1) in - let () = print_int (meven 2) in - let (even,odd) = tie in - 0 -|}; - [%expect - {| - 1 - 1 - val fix = - val map = - val fixpoly = - val feven = - val fodd = - val tie = (, ) - val meven = - val modd = - val main = 0 |}] -;; - -(*bad**) -let%expect_test "016lists" = - pp_parse - {| -let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl - -let length_tail = - let rec helper acc xs = - match xs with - | [] -> acc - | h::tl -> helper (acc + 1) tl - in - helper 0 - -let rec map f xs = - match xs with - | [] -> [] - | a::[] -> [f a] - | a::b::[] -> [f a; f b] - | a::b::c::[] -> [f a; f b; f c] - | a::b::c::d::tl -> f a :: f b :: f c :: f d :: map f tl - -let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys) - -let concat = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper - -let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter f tl - -let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - -let main = - let () = iter print_int [1;2;3] in - let () = print_int (length (cartesian [1;2] [1;2;3;4])) in - 0 -|}; - [%expect - {| - 1 - 2 - 3 - 8 - val length = - val length_tail = - val map = - val append = - val concat = - val iter = - val cartesian = - val main = 0 |}] -;; - -let%expect_test "debug_length" = - pp_parse - {| - let rec map f xs = match xs with | [] -> [] | h::t -> (f h)::map f t in - let rec append xs ys = match xs with [] -> ys | h::t -> h::append t ys in - let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - in - let rec length xs = - match xs with - | [] -> 0 - | h::t -> 1 + length t - in - let result = cartesian [1;2] [1;2;3;4] in - let () = result in - length result|}; - [%expect {| - _ = 8 |}] -;; - -let%expect_test "empty_list" = - pp_parse {|match [] with | [] -> 1 | _ -> 0|}; - [%expect {| - _ = 1 |}] -;; - -let%expect_test "cons_head" = - pp_parse {| match [1;2;3] with | h::t -> h |}; - [%expect {| - _ = 1 |}] -;; - -let%expect_test "cons_tail" = - pp_parse "match [1;2;3] with | h::t -> t"; - [%expect {| - _ = [2; 3] |}] -;; - -let%expect_test "tuple_cons" = - pp_parse {| match [1;2;3] with | h::t -> (h, t) |}; - [%expect {| - _ = (1, [2; 3]) |}] -;; - -let%expect_test "length_function" = - pp_parse - {|let rec length xs = match xs with | [] -> 0 | h::t -> 1 + length t in length [1;2;3]|}; - [%expect {| - _ = 3 |}] -;; - -let%expect_test "length_tail_function" = - pp_parse - {| let rec helper acc xs = match xs with | [] -> acc | h::t -> helper (acc+1) t in - helper 0 [1;2;3] |}; - [%expect {| - _ = 3 |}] -;; - -let%expect_test "map_function" = - pp_parse - {| let rec map f xs = match xs with | [] -> [] | h::t -> (f h)::map f t in map (fun x - -> x+1) [1;2;3] |}; - [%expect {| - _ = [2; 3; 4] |}] -;; - -let%expect_test "append_function" = - pp_parse - {|let rec append xs ys = match xs with | [] -> ys | h::t -> h::append t ys in append - [1;2] [3;4] |}; - [%expect {| - _ = [1; 2; 3; 4] |}] -;; - -let%expect_test "concat_function" = - pp_parse - {|let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys) -in - let rec concat xs = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper xs - in - concat [[1;2]; [3; 4]]|}; - [%expect {| - _ = [1; 2; 3; 4] |}] -;; - -let%expect_test "iter_function" = - pp_parse - {| let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter - print_int [1;2;3]|}; - [%expect {| -val iter = -|}] -;; - -let%expect_test "list_basic" = - pp_parse {|let lst = 1 :: 2 :: 3 :: [] in lst|}; - [%expect {| - _ = [1; 2; 3] |}] -;; - -let%expect_test "list_match" = - pp_parse {|match 1 :: 2 :: 3 :: [] with | [] -> 0 | h :: _ -> h|}; - [%expect {| - _ = 1 |}] -;; - -let%expect_test "list_append" = - pp_parse - {|let append xs ys = match xs with | [] -> ys | h :: t -> h :: append t ys in append - [1; 2] [3; 4]|}; - [%expect {| - _ = [1; 2; 3; 4] |}] -;; - -let%expect_test "debug_cartesian" = - pp_parse - {|let rec map f xs = match xs with | [] -> [] | h::t -> (f h)::map f t in - let rec append xs ys = match xs with | [] -> ys | h::t -> h::append t ys in - let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - in - cartesian [1;2] [1;2;3;4]|}; - [%expect {| - _ = [(1, 1); (1, 2); (1, 3); (1, 4); (2, 1); (2, 2); (2, 3); (2, 4)] |}] -;; - -let%expect_test "fix_factorial" = - pp_parse - {| -let rec fix f x = f (fix f) x in -let factorial f n = - if n = 0 then 1 else n * f (n - 1) -in -let factorial_fn = fix factorial in -factorial_fn 5 -|}; - [%expect {| _ = 120 |}] -;; - -let%expect_test "map_increment" = - pp_parse - {| -let map f p = let (a,b) = p in (f a, f b) in -let pair = (1, 2) in -map (fun x -> x + 1) pair -|}; - [%expect {| _ = (2, 3) |}] -;; - -let%expect_test "meven_modd" = - pp_parse - {| -let rec meven n = if n = 0 then 1 else modd (n - 1) -and modd n = if n = 0 then 1 else meven (n - 1) -in -(meven 2, modd 1) -|}; - [%expect {| _ = (1, 1) |}] -;; - -let%expect_test "rec calls" = - pp_parse {| -let rec f () = y in -let y = 42 in -f () -;; -|}; - [%expect {| _ = 42 |}] -;; diff --git a/OcamlADT/tests/interpreter.mli b/OcamlADT/tests/interpreter.mli deleted file mode 100644 index 901785c8d..000000000 --- a/OcamlADT/tests/interpreter.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val pp_interpret : Ocamladt_lib.Ast.program -> unit diff --git a/OcamlADT/tests/manytests b/OcamlADT/tests/manytests deleted file mode 120000 index 274b77057..000000000 --- a/OcamlADT/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests/ \ No newline at end of file diff --git a/OcamlADT/tests/parser.ml b/OcamlADT/tests/parser.ml deleted file mode 100644 index 48975ae42..000000000 --- a/OcamlADT/tests/parser.ml +++ /dev/null @@ -1,4453 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Parser -open Ocamladt_lib.Ast - -(* open Angstrom *) -let test_program str = print_endline (show_program (parse_str str)) - -let%expect_test "negative int constant" = - test_program {|-1;;|}; - [%expect - {| [(Str_eval (Exp_apply ((Exp_ident "-"), (Exp_constant (Const_integer 1)))))] |}] -;; - -(*good*) -let%expect_test "positive int constant" = - test_program {|+1;;|}; - [%expect - {| [(Str_eval (Exp_apply ((Exp_ident "+"), (Exp_constant (Const_integer 1)))))] |}] -;; - -(*good*) -let%expect_test " nt constant" = - test_program {|1;;|}; - [%expect {| [(Str_eval (Exp_constant (Const_integer 1)))] |}] -;; - -(*good*) -let%expect_test "whitespace befor int constant" = - test_program {| 1;;|}; - [%expect {| [(Str_eval (Exp_constant (Const_integer 1)))] |}] -;; - -(*good*) -let%expect_test "negative zero" = - test_program {|-0;;|}; - [%expect - {| [(Str_eval (Exp_apply ((Exp_ident "-"), (Exp_constant (Const_integer 0)))))] |}] -;; - -(*good*) -let%expect_test "positive zero" = - test_program {|+0;;|}; - [%expect - {| [(Str_eval (Exp_apply ((Exp_ident "+"), (Exp_constant (Const_integer 0)))))] |}] -;; - -(*good*) -let%expect_test "char" = - test_program {|''';;|}; - [%expect {| [(Str_eval (Exp_constant (Const_char '\'')))] |}] -;; - -(*good*) -let%expect_test "zero" = - test_program {|0;;|}; - [%expect {| [(Str_eval (Exp_constant (Const_integer 0)))] |}] -;; - -(*good*) -let%expect_test "substraction" = - test_program {|5-11;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 11)), [])) - ))) - ] |}] -;; - -(*good*) -let%expect_test "strange move" = - test_program {|5=5;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - ))) - ] |}] -;; - -(*good*) -let%expect_test "(assignment)" = - test_program {|x = 52;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "="), - (Exp_tuple ((Exp_ident "x"), (Exp_constant (Const_integer 52)), []))))) - ] |}] -;; - -(*good*) -let%expect_test "multiplication" = - test_program {|5*5;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - ))) - ] |}] -;; - -(*good*) -let%expect_test "operators with different priorities" = - test_program {|5-5*1;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), [])) - )), - [])) - ))) - ] |}] -;; - -(*good*) -let%expect_test "operators with different priorities" = - test_program {|5*5-1;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - )), - (Exp_constant (Const_integer 1)), [])) - ))) - ] |}] -;; - -(*good*) - -let%expect_test "parenthesis with operators with different priorities" = - test_program {|5*(5-1);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), [])) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis3" = - test_program {|(5);;|}; - [%expect {| [(Str_eval (Exp_constant (Const_integer 5)))] |}] -;; - -let%expect_test "parenthesis1" = - test_program {|(5*(5-1));;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), [])) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis2" = - test_program {|105 * 64 / 27 - 2 * (5*(5-1)) + 47 / 64 - (56 * (57 *4) - 5);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "/"), - (Exp_tuple - ((Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 105)), - (Exp_constant (Const_integer 64)), - [])) - )), - (Exp_constant (Const_integer 27)), [])) - )), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), - [])) - )), - [])) - )), - [])) - )), - [])) - )), - (Exp_apply ((Exp_ident "/"), - (Exp_tuple - ((Exp_constant (Const_integer 47)), - (Exp_constant (Const_integer 64)), [])) - )), - [])) - )), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 56)), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 57)), - (Exp_constant (Const_integer 4)), [])) - )), - [])) - )), - (Exp_constant (Const_integer 5)), [])) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis3" = - test_program {|1 + (2 + 3);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_constant (Const_integer 3)), [])) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "logical ops + parenthesis" = - test_program - {| - ((3 * (9 - 12 / 4) < 7 && 1) || 1 && 5 < 6) || 20 - 100 / (4 + 16) && 10 < 12 ;; -|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "&&"), - (Exp_tuple - ((Exp_apply ((Exp_ident "||"), - (Exp_tuple - ((Exp_apply ((Exp_ident "&&"), - (Exp_tuple - ((Exp_apply ((Exp_ident "||"), - (Exp_tuple - ((Exp_apply ((Exp_ident "&&"), - (Exp_tuple - ((Exp_apply ((Exp_ident "<"), - (Exp_tuple - ((Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant - (Const_integer 3)), - (Exp_apply ( - (Exp_ident "-"), - (Exp_tuple - ((Exp_constant - (Const_integer - 9)), - (Exp_apply ( - (Exp_ident "/"), - (Exp_tuple - ((Exp_constant - (Const_integer - 12)), - (Exp_constant - (Const_integer - 4)), - [])) - )), - [])) - )), - [])) - )), - (Exp_constant (Const_integer 7)), - [])) - )), - (Exp_constant (Const_integer 1)), - [])) - )), - (Exp_constant (Const_integer 1)), [])) - )), - (Exp_apply ((Exp_ident "<"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 6)), [])) - )), - [])) - )), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 20)), - (Exp_apply ((Exp_ident "/"), - (Exp_tuple - ((Exp_constant (Const_integer 100)), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 4)), - (Exp_constant (Const_integer 16)), - [])) - )), - [])) - )), - [])) - )), - [])) - )), - (Exp_apply ((Exp_ident "<"), - (Exp_tuple - ((Exp_constant (Const_integer 10)), - (Exp_constant (Const_integer 12)), [])) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis4" = - test_program {|((5-1)*5);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), [])) - )), - (Exp_constant (Const_integer 5)), [])) - ))) - ] |}] -;; - -let%expect_test "whitespace befor int constant" = - test_program - {| let x = 10 in -if x > 5 then print_endline "> 5" -else print_endline "<= 5";; - 5+5;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 10)) }, []), - (Exp_if ( - (Exp_apply ((Exp_ident ">"), - (Exp_tuple - ((Exp_ident "x"), (Exp_constant (Const_integer 5)), [])) - )), - (Exp_apply ((Exp_ident "print_endline"), - (Exp_constant (Const_string "> 5")))), - (Some (Exp_apply ((Exp_ident "print_endline"), - (Exp_constant (Const_string "<= 5"))))) - )) - ))); - (Str_eval - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis5" = - test_program {|(5*5-1);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - )), - (Exp_constant (Const_integer 1)), [])) - ))) - ] |}] -;; - -let%expect_test "parenthesis5" = - test_program {|(1-5*5);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - )), - [])) - ))) - ] |}] -;; - -(* +(+(1, 2), 3) *) - -let%expect_test "parenthesis2" = - test_program {|( 5-1 );;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 1)), [])) - ))) - ] |}] -;; - -(* good fr *) -let%expect_test "tuple" = - test_program {|(5,1,2,5);;|}; - [%expect - {| - [(Str_eval - (Exp_tuple - ((Exp_constant (Const_integer 5)), (Exp_constant (Const_integer 1)), - [(Exp_constant (Const_integer 2)); (Exp_constant (Const_integer 5))]))) - ] |}] -;; - -(* good fr *) -let%expect_test "int + a" = - test_program {|5+'a';;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), (Exp_constant (Const_char 'a')), - [])) - ))) - ] |}] -;; - -let%expect_test "let assignment" = - test_program {|let x = 5 in 6;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 5)) }, []), - (Exp_constant (Const_integer 6))))) - ] |}] -;; - -let%expect_test "let assignment" = - test_program {|let reca = 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "reca"); expr = (Exp_constant (Const_integer 1)) }, []) - )) - ] |}] -;; - -let%expect_test "let assignment" = - test_program {|let Some None = Some 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_construct ("Some", (Some (Pat_construct ("None", None))))); - expr = - (Exp_construct ("Some", (Some (Exp_constant (Const_integer 1))))) }, - []) - )) - ] |}] -;; - -let%expect_test "let assignment none" = - test_program {|let Some Some Some Some Some None = 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("None", - None))) - ))) - ))) - ))) - ))) - )); - expr = (Exp_constant (Const_integer 1)) }, - []) - )) - ] |}] -;; - -let%expect_test "let assignment none" = - test_program {|let Some Some Some Some Some None = 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("Some", - (Some (Pat_construct ("None", - None))) - ))) - ))) - ))) - ))) - )); - expr = (Exp_constant (Const_integer 1)) }, - []) - )) - ] |}] -;; - -let%expect_test "let assignment with recursion" = - test_program {|let rec x = 5 in 6;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Recursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 5)) }, []), - (Exp_constant (Const_integer 6))))) - ] |}] -;; - -let%expect_test "let assignment with recursion" = - test_program {|let rec x = 5 in 7;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Recursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 5)) }, []), - (Exp_constant (Const_integer 7))))) - ] |}] -;; - -let%expect_test "apply without space" = - test_program {|f(x);;|}; - [%expect {| [(Str_eval (Exp_apply ((Exp_ident "f"), (Exp_ident "x"))))] |}] -;; - -let%expect_test "apply num to ident" = - test_program {|f (x-1);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "f"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple ((Exp_ident "x"), (Exp_constant (Const_integer 1)), [])) - )) - ))) - ] |}] -;; - -let%expect_test "simple fun" = - test_program {|fun x -> y;;|}; - [%expect {| [(Str_eval (Exp_fun (((Pat_var "x"), []), (Exp_ident "y"))))] |}] -;; - -let%expect_test "multi pattern fun" = - test_program {|fun x -> y;;|}; - [%expect {| [(Str_eval (Exp_fun (((Pat_var "x"), []), (Exp_ident "y"))))] |}] -;; - -let%expect_test "multi pattern fun" = - test_program {|5>5;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident ">"), - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 5)), [])) - ))) - ] |}] -;; - -let%expect_test "multi fun" = - test_program {|fun p -> fun x -> z;;|}; - [%expect - {| - [(Str_eval - (Exp_fun (((Pat_var "p"), []), - (Exp_fun (((Pat_var "x"), []), (Exp_ident "z")))))) - ] |}] -;; - -let%expect_test "apply and subtraction" = - test_program {|f (x-1);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "f"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple ((Exp_ident "x"), (Exp_constant (Const_integer 1)), [])) - )) - ))) - ] |}] -;; - -let%expect_test "exprlet and" = - test_program {|let x = 5 and y = 10;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 5)) }, - [{ pat = (Pat_var "y"); expr = (Exp_constant (Const_integer 10)) }]) - )) - ] |}] -;; - -let%expect_test "exprlet and" = - test_program {|let rec x x x x x x x = y and x = 20 in 5;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Recursive, - ({ pat = (Pat_var "x"); - expr = - (Exp_fun ( - ((Pat_var "x"), - [(Pat_var "x"); (Pat_var "x"); (Pat_var "x"); (Pat_var "x"); - (Pat_var "x")]), - (Exp_ident "y"))) - }, - [{ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 20)) }]), - (Exp_constant (Const_integer 5))))) - ] |}] -;; - -let%expect_test "let and tuple" = - test_program {|let (a,b) = (b,a);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "a"), (Pat_var "b"), [])); - expr = (Exp_tuple ((Exp_ident "b"), (Exp_ident "a"), [])) }, - []) - )) - ] |}] -;; - -let%expect_test "let and" = - test_program {|let rec x x x x x x x = y and x = 20;;|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "x"); - expr = - (Exp_fun ( - ((Pat_var "x"), - [(Pat_var "x"); (Pat_var "x"); (Pat_var "x"); (Pat_var "x"); - (Pat_var "x")]), - (Exp_ident "y"))) - }, - [{ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 20)) }]) - )) - ] |}] -;; - -let%expect_test "multiplication and apply" = - test_program {|x * f x;;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_ident "x"), (Exp_apply ((Exp_ident "f"), (Exp_ident "x"))), - [])) - ))) - ] |}] -;; - -let%expect_test "let and apply" = - test_program {|let f x = x;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "f"); - expr = (Exp_fun (((Pat_var "x"), []), (Exp_ident "x"))) }, - []) - )) - ] |}] -;; - -let%expect_test "pattern constraint" = - test_program {|let (x : int * int) = (x: int);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), [])) - )); - expr = - (Exp_constraint ((Exp_ident "x"), (Type_construct ("int", [])))) }, - []) - )) - ] |}] -;; - -let%expect_test "pattern constraint" = - test_program {|let (x : int*int) = (x: int*int);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), [])) - )); - expr = - (Exp_constraint ((Exp_ident "x"), - (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), [])) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "pattern constraint" = - test_program {|let (x : int->int) = (x: int->int);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_arrow ((Type_construct ("int", [])), - (Type_construct ("int", [])))) - )); - expr = - (Exp_constraint ((Exp_ident "x"), - (Type_arrow ((Type_construct ("int", [])), - (Type_construct ("int", [])))) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "let and apply" = - test_program {|let f x = g a b c;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "f"); - expr = - (Exp_fun (((Pat_var "x"), []), - (Exp_apply ( - (Exp_apply ((Exp_apply ((Exp_ident "g"), (Exp_ident "a"))), - (Exp_ident "b"))), - (Exp_ident "c"))) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "let and apply v2" = - test_program {|let fact x = fact(x-1);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "fact"); - expr = - (Exp_fun (((Pat_var "x"), []), - (Exp_apply ((Exp_ident "fact"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "x"), (Exp_constant (Const_integer 1)), [])) - )) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "if then" = - test_program {|if 5 then 6;;|}; - [%expect - {| - [(Str_eval - (Exp_if ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 6)), None))) - ] |}] -;; - -let%expect_test "if statement. condition from fact" = - test_program {|if n = 0 then 1 else 7;;|}; - [%expect - {| - [(Str_eval - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_constant (Const_integer 7)))))) - ] |}] -;; - -let%expect_test "let and if" = - test_program {|let x = if n = 0 then 6 else 7 in 6;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); - expr = - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 6)), - (Some (Exp_constant (Const_integer 7))))) - }, - []), - (Exp_constant (Const_integer 6))))) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let rec fact n = if n = 0 then 1 else n * fact(n-1);;|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "fact"); - expr = - (Exp_fun (((Pat_var "n"), []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_apply ((Exp_ident "fact"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), - [])) - )) - )), - [])) - ))) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let (x: int->char->string -> x *x* x) = 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_arrow ( - (Type_arrow ( - (Type_arrow ((Type_construct ("int", [])), - (Type_construct ("char", [])))), - (Type_construct ("string", [])))), - (Type_tuple - ((Type_construct ("x", [])), (Type_construct ("x", [])), - [(Type_construct ("x", []))])) - )) - )); - expr = (Exp_constant (Const_integer 1)) }, - []) - )) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let rec a = 1;;|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "a"); expr = (Exp_constant (Const_integer 1)) }, []))) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let rec a = 1;;|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "a"); expr = (Exp_constant (Const_integer 1)) }, []))) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let reca = 1 in 5;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "reca"); expr = (Exp_constant (Const_integer 1)) }, - []), - (Exp_constant (Const_integer 5))))) - ] |}] -;; - -let%expect_test "factorial" = - test_program {|let reca = 1;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "reca"); expr = (Exp_constant (Const_integer 1)) }, []) - )) - ] |}] -;; - -let%expect_test "_" = - test_program {|let recgP6Tz_9 = zdghovr and _ = n_4p;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "recgP6Tz_9"); expr = (Exp_ident "zdghovr") }, - [{ pat = Pat_any; expr = (Exp_ident "n_4p") }]) - )) - ] |}] -;; - -(*good*) -let%expect_test "_" = - test_program {|(f : (int -> int -> int));;|}; - [%expect - {| - [(Str_eval - (Exp_constraint ((Exp_ident "f"), - (Type_arrow ( - (Type_arrow ((Type_construct ("int", [])), - (Type_construct ("int", [])))), - (Type_construct ("int", [])))) - ))) - ] |}] -;; - -let%expect_test "_" = - test_program {|let (f:(x)) = 5;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_constraint ((Pat_var "f"), (Type_construct ("x", [])))); - expr = (Exp_constant (Const_integer 5)) }, - []) - )) - ] |}] -;; - -let%expect_test "_" = - test_program {| function -| "" -> 'a' -| "" -> "izvkvwcet" ;;|}; - [%expect - {| - [(Str_eval - (Exp_function - ({ first = (Pat_constant (Const_string "")); - second = (Exp_constant (Const_char 'a')) }, - [{ first = (Pat_constant (Const_string "")); - second = (Exp_constant (Const_string "izvkvwcet")) } - ]))) - ] |}] -;; - -(*good*) -let%expect_test "_" = - test_program - {|('v' : (sqEcf8boz* s58r6D_P_bX___yy_93GPH__04_r___d9Zc_1U2__c8XmN1n_F_WBqxl68h_8_TCGqp3B_5w_Y_53a6_d_6_H9845__c5__09s* sh__7ud_43* s_KKm_z3r5__jHMLw_qd1760R_G__nI6_J040__AB_6s0__D__d__e32Te6H_4__Ec_V_E__f_* o0_a_W_* f__LcPREH13__mY_CezffoI5_8_u_zU__ZncOnf_v4_L8_44Y72_3_A5_B758TViP_u_vyFU9_1* qD0* g4wp33A_W* e1V_gi_6y* x_Sv_PZ)) ;; |}; - [%expect - {| - [(Str_eval - (Exp_constraint ((Exp_constant (Const_char 'v')), - (Type_tuple - ((Type_construct ("sqEcf8boz", [])), - (Type_construct ( - "s58r6D_P_bX___yy_93GPH__04_r___d9Zc_1U2__c8XmN1n_F_WBqxl68h_8_TCGqp3B_5w_Y_53a6_d_6_H9845__c5__09s", - [])), - [(Type_construct ("sh__7ud_43", [])); - (Type_construct ( - "s_KKm_z3r5__jHMLw_qd1760R_G__nI6_J040__AB_6s0__D__d__e32Te6H_4__Ec_V_E__f_", - [])); - (Type_construct ("o0_a_W_", [])); - (Type_construct ( - "f__LcPREH13__mY_CezffoI5_8_u_zU__ZncOnf_v4_L8_44Y72_3_A5_B758TViP_u_vyFU9_1", - [])); - (Type_construct ("qD0", [])); - (Type_construct ("g4wp33A_W", [])); - (Type_construct ("e1V_gi_6y", [])); - (Type_construct ("x_Sv_PZ", []))])) - ))) - ] |}] -;; - -let%expect_test "not keyword" = - test_program {|(Kakadu_52) (fun x -> x);;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_construct ("Kakadu_52", None)), - (Exp_fun (((Pat_var "x"), []), (Exp_ident "x")))))) - ] |}] -;; - -let%expect_test "adt v0" = - test_program {|type shape = Circle;;|}; - [%expect {| [(Str_adt ([], "shape", (("Circle", None), [])))] |}] -;; - -let%expect_test "adt v1" = - test_program {|type shape = Circle | Square of int;;|}; - [%expect - {| - [(Str_adt ([], "shape", - (("Circle", None), [("Square", (Some (Type_construct ("int", []))))]))) - ] |}] -;; - -let%expect_test "adt v2" = - test_program {|type shape = Circle | Square;;|}; - [%expect {| [(Str_adt ([], "shape", (("Circle", None), [("Square", None)])))] |}] -;; - -let%expect_test "adt v3" = - test_program {|type shape = Circle | Square of int * int;;|}; - [%expect - {| - [(Str_adt ([], "shape", - (("Circle", None), - [("Square", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt with poly" = - test_program {|type 'a shape = Circle | Square of 'a * 'a ;;|}; - [%expect - {| - [(Str_adt (["a"], "shape", - (("Circle", None), - [("Square", (Some (Type_tuple ((Type_var "a"), (Type_var "a"), []))))]) - )) - ] |}] -;; - -let%expect_test "bad adt with poly (wrong types)" = - test_program {|type 'a shape = Circle | Square of 'b;;|}; - [%expect - {| - [(Str_adt (["a"], "shape", - (("Circle", None), [("Square", (Some (Type_var "b")))]))) - ] |}] -;; - -let%expect_test "adt with poly (not poly in variant)" = - test_program {|type 'a shape = Circle | Square of int;;|}; - [%expect - {| - [(Str_adt (["a"], "shape", - (("Circle", None), [("Square", (Some (Type_construct ("int", []))))]))) - ] |}] -;; - -let%expect_test "adt with poly v.easy" = - test_program {|type 'a shape = Circle;;|}; - [%expect {| [(Str_adt (["a"], "shape", (("Circle", None), [])))] |}] -;; - -let%expect_test "adt with multiple poly v1" = - test_program {|type ('a, 'b) shape = Circle | Square of 'a;;|}; - [%expect - {| - [(Str_adt (["a"; "b"], "shape", - (("Circle", None), [("Square", (Some (Type_var "a")))]))) - ] |}] -;; - -let%expect_test "adt with multiple poly v2" = - test_program {|type ('a, 'b) shape = Circle | Square of ('a,'b) shape;;|}; - [%expect - {| - [(Str_adt (["a"; "b"], "shape", - (("Circle", None), - [("Square", - (Some (Type_construct ("shape", [(Type_var "a"); (Type_var "b")]))))]) - )) - ] |}] -;; - -let%expect_test "just let (char)" = - test_program {|let x = '5';;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_char '5')) }, []))) - ] |}] -;; - -let%expect_test "string print_endline" = - test_program {|let x = "51" in -print_endline x;;|}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_string "51")) }, - []), - (Exp_apply ((Exp_ident "print_endline"), (Exp_ident "x")))))) - ] |}] -;; - -let%expect_test "string print_endline" = - test_program {|x = "51";;|}; - [%expect - {| - [(Str_eval - (Exp_apply ((Exp_ident "="), - (Exp_tuple ((Exp_ident "x"), (Exp_constant (Const_string "51")), [])) - ))) - ] |}] -;; - -let%expect_test "match case" = - test_program - {|let classify n = - match n with - | 0 -> "zero" - | 1 -> "one" - | _ -> "other" -;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "classify"); - expr = - (Exp_fun (((Pat_var "n"), []), - (Exp_match ((Exp_ident "n"), - ({ first = (Pat_constant (Const_integer 0)); - second = (Exp_constant (Const_string "zero")) }, - [{ first = (Pat_constant (Const_integer 1)); - second = (Exp_constant (Const_string "one")) }; - { first = Pat_any; - second = (Exp_constant (Const_string "other")) } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "adt with tuple in variant" = - test_program {|type shape = Circle | Square of int * int ;;|}; - [%expect - {| - [(Str_adt ([], "shape", - (("Circle", None), - [("Square", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt with recursive poly variant" = - test_program {|type ('a, 'b) shape = Circle | Square of 'a shape;;|}; - [%expect - {| - [(Str_adt (["a"; "b"], "shape", - (("Circle", None), - [("Square", (Some (Type_construct ("shape", [(Type_var "a")]))))]) - )) - ] |}] -;; - -let%expect_test "adt list" = - test_program {| -type 'a my_list = Nil | Cons of 'a * 'a my_list;; -|}; - [%expect - {| - [(Str_adt (["a"], "my_list", - (("Nil", None), - [("Cons", - (Some (Type_tuple - ((Type_var "a"), - (Type_construct ("my_list", [(Type_var "a")])), [])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt nested type_construct in args" = - test_program - {| -type 'a nested_list = Nil -| Cons of 'a * 'a nested_list -| List of 'a nested_list;; - -|}; - [%expect - {| - [(Str_adt (["a"], "nested_list", - (("Nil", None), - [("Cons", - (Some (Type_tuple - ((Type_var "a"), - (Type_construct ("nested_list", [(Type_var "a")])), - [])))); - ("List", (Some (Type_construct ("nested_list", [(Type_var "a")]))))]) - )) - ] |}] -;; - -let%expect_test "adt nested type_construct in args" = - test_program - {| -type 'a nested_list = Nil -| Cons of 'a * 'a nested_list -| List of 'a nested_list nested_list;; -|}; - [%expect - {| - [(Str_adt (["a"], "nested_list", - (("Nil", None), - [("Cons", - (Some (Type_tuple - ((Type_var "a"), - (Type_construct ("nested_list", [(Type_var "a")])), - [])))); - ("List", - (Some (Type_construct ("nested_list", - [(Type_var "a"); (Type_construct ("nested_list", []))])))) - ]) - )) - ] |}] -;; - -let%expect_test "poly adt (tree)" = - test_program {| -type 'a tree = Leaf - | Node of 'a * 'a tree * 'a tree -;; - |}; - [%expect - {| - [(Str_adt (["a"], "tree", - (("Leaf", None), - [("Node", - (Some (Type_tuple - ((Type_var "a"), (Type_construct ("tree", [(Type_var "a")])), - [(Type_construct ("tree", [(Type_var "a")]))])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt list with pair" = - test_program - {| type ('a, 'b) pair_list = Nil - | Cons of ('a * 'b) * ('a, 'b) pair_list;; -|}; - [%expect - {| - [(Str_adt (["a"; "b"], "pair_list", - (("Nil", None), - [("Cons", - (Some (Type_tuple - ((Type_tuple ((Type_var "a"), (Type_var "b"), [])), - (Type_construct ("pair_list", - [(Type_var "a"); (Type_var "b")])), - [])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt list with 2 el in node" = - test_program - {| type ('a, 'b) pair_list = Nil - | Cons of 'a * 'b * ('a, 'b) pair_list;; -|}; - [%expect - {| - [(Str_adt (["a"; "b"], "pair_list", - (("Nil", None), - [("Cons", - (Some (Type_tuple - ((Type_var "a"), (Type_var "b"), - [(Type_construct ("pair_list", - [(Type_var "a"); (Type_var "b")])) - ])))) - ]) - )) - ] |}] -;; - -let%expect_test "adt" = - test_program - {| -type shape = Point of int - | Circle of int * int - | Rect of int * int * int -;; -|}; - [%expect - {| - [(Str_adt ([], "shape", - (("Point", (Some (Type_construct ("int", [])))), - [("Circle", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))); - ("Rect", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [(Type_construct ("int", []))])))) - ]) - )) - ] |}] -;; - -let%expect_test "simple adt with pattern matching function (else case) + printing" = - test_program - {| -type shape = Circle of int - | Rectangle of (int*int) * int - | Square of int -;; -let area s = - match s with - | Square c -> 0 - | Circle c -> 3 - | Rectangle c -> 10 -;; -let x = Square 5 in -let y = area x in -print_int y -;; - - |}; - [%expect - {| - [(Str_adt ([], "shape", - (("Circle", (Some (Type_construct ("int", [])))), - [("Rectangle", - (Some (Type_tuple - ((Type_tuple - ((Type_construct ("int", [])), - (Type_construct ("int", [])), [])), - (Type_construct ("int", [])), [])))); - ("Square", (Some (Type_construct ("int", []))))]) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "area"); - expr = - (Exp_fun (((Pat_var "s"), []), - (Exp_match ((Exp_ident "s"), - ({ first = (Pat_construct ("Square", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 0)) }, - [{ first = (Pat_construct ("Circle", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 3)) }; - { first = - (Pat_construct ("Rectangle", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 10)) } - ]) - )) - )) - }, - []) - )); - (Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); - expr = - (Exp_construct ("Square", (Some (Exp_constant (Const_integer 5))) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "y"); - expr = (Exp_apply ((Exp_ident "area"), (Exp_ident "x"))) }, - []), - (Exp_apply ((Exp_ident "print_int"), (Exp_ident "y"))))) - ))) - ] |}] -;; - -let%expect_test "rec fun (pow)" = - test_program - {| -let rec pow x y = if y = 0 then 1 else x * pow x (y - 1) in print_int (pow 5 6) -;; |}; - [%expect - {| - [(Str_eval - (Exp_let (Recursive, - ({ pat = (Pat_var "pow"); - expr = - (Exp_fun (((Pat_var "x"), [(Pat_var "y")]), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "y"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_ident "x"), - (Exp_apply ( - (Exp_apply ((Exp_ident "pow"), - (Exp_ident "x"))), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "y"), - (Exp_constant (Const_integer 1)), - [])) - )) - )), - [])) - ))) - )) - )) - }, - []), - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ( - (Exp_apply ((Exp_ident "pow"), (Exp_constant (Const_integer 5)) - )), - (Exp_constant (Const_integer 6)))) - )) - ))) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let x = 5 and (z,v,c) = (5,6,7);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_constant (Const_integer 5)) }, - [{ pat = (Pat_tuple ((Pat_var "z"), (Pat_var "v"), [(Pat_var "c")])); - expr = - (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 6)), - [(Exp_constant (Const_integer 7))])) - } - ]) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|fun x -> x+x;;|}; - [%expect - {| - [(Str_eval - (Exp_fun (((Pat_var "x"), []), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple ((Exp_ident "x"), (Exp_ident "x"), [])))) - ))) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let main = - let () = print_int (fib 4) in - 0;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "fib"), - (Exp_constant (Const_integer 4)))) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let (x:char) = 20;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_constraint ((Pat_var "x"), (Type_construct ("char", [])))); - expr = (Exp_constant (Const_integer 20)) }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let (x:(char*char)) = 20;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_tuple - ((Type_construct ("char", [])), (Type_construct ("char", [])), - [])) - )); - expr = (Exp_constant (Const_integer 20)) }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let (x: int option) = 20;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_construct ("option", [(Type_construct ("int", []))])))); - expr = (Exp_constant (Const_integer 20)) }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {||}; - [%expect {| [] |}] -;; - -let%expect_test "keyword" = - test_program {|let () = print_int 5;;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), (Exp_constant (Const_integer 5)) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|let addi = fun f g x -> (f x (g x: bool) : int);;|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "addi"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "g"); (Pat_var "x")]), - (Exp_constraint ( - (Exp_apply ((Exp_apply ((Exp_ident "f"), (Exp_ident "x"))), - (Exp_constraint ( - (Exp_apply ((Exp_ident "g"), (Exp_ident "x"))), - (Type_construct ("bool", [])))) - )), - (Type_construct ("int", [])))) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "simple adt with pattern matching function + printing v3" = - test_program - {| -type 'a shape = Circle of int - | Rectangle of int * int - | Square of int -;; -let area s = - match s with - | Circle c -> 3 - | Square c -> 0 - | Rectangle (c1, c2) -> c1 * c2 -;; -let x = Rectangle (5, 10) in -let y = area x in -print_int y -;; - |}; - [%expect - {| - [(Str_adt (["a"], "shape", - (("Circle", (Some (Type_construct ("int", [])))), - [("Rectangle", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))); - ("Square", (Some (Type_construct ("int", []))))]) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "area"); - expr = - (Exp_fun (((Pat_var "s"), []), - (Exp_match ((Exp_ident "s"), - ({ first = (Pat_construct ("Circle", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 3)) }, - [{ first = (Pat_construct ("Square", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 0)) }; - { first = - (Pat_construct ("Rectangle", - (Some (Pat_tuple ((Pat_var "c1"), (Pat_var "c2"), []))) - )); - second = - (Exp_apply ((Exp_ident "*"), - (Exp_tuple ((Exp_ident "c1"), (Exp_ident "c2"), [])))) - } - ]) - )) - )) - }, - []) - )); - (Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); - expr = - (Exp_construct ("Rectangle", - (Some (Exp_tuple - ((Exp_constant (Const_integer 5)), - (Exp_constant (Const_integer 10)), []))) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "y"); - expr = (Exp_apply ((Exp_ident "area"), (Exp_ident "x"))) }, - []), - (Exp_apply ((Exp_ident "print_int"), (Exp_ident "y"))))) - ))) - ] |}] -;; - -let%expect_test "simple adt with pattern matching function + printing v3" = - test_program - {| -type ('a,'b) shape = Circle of int - | Rectangle of int * int - | Square of 'a * 'b -;; - |}; - [%expect - {| - [(Str_adt (["a"; "b"], "shape", - (("Circle", (Some (Type_construct ("int", [])))), - [("Rectangle", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))); - ("Square", (Some (Type_tuple ((Type_var "a"), (Type_var "b"), []))))]) - )) - ] |}] -;; - -let%expect_test "function assignment with bool operators" = - test_program {| let id = fun (x, y) -> x && y in print_bool (id true false) ;; |}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "id"); - expr = - (Exp_fun (((Pat_tuple ((Pat_var "x"), (Pat_var "y"), [])), []), - (Exp_apply ((Exp_ident "&&"), - (Exp_tuple ((Exp_ident "x"), (Exp_ident "y"), [])))) - )) - }, - []), - (Exp_apply ((Exp_ident "print_bool"), - (Exp_apply ( - (Exp_apply ((Exp_ident "id"), (Exp_construct ("true", None)))), - (Exp_construct ("false", None)))) - )) - ))) - ] |}] -;; - -let%expect_test "function" = - test_program - {| - let f = function - | Some x -> x - | None -> 0 - in - f None, f (Some 42) - |}; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "f"); - expr = - (Exp_function - ({ first = (Pat_construct ("Some", (Some (Pat_var "x")))); - second = (Exp_ident "x") }, - [{ first = (Pat_construct ("None", None)); - second = (Exp_constant (Const_integer 0)) } - ])) - }, - []), - (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_construct ("None", None)))), - (Exp_apply ((Exp_ident "f"), - (Exp_construct ("Some", - (Some (Exp_constant (Const_integer 42))))) - )), - [])) - ))) - ] |}] -;; - -let%expect_test "keyword" = - test_program {| -let _6 = fun arg -> match arg with Some x -> let y = x in y;; - |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "_6"); - expr = - (Exp_fun (((Pat_var "arg"), []), - (Exp_match ((Exp_ident "arg"), - ({ first = (Pat_construct ("Some", (Some (Pat_var "x")))); - second = - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "y"); expr = (Exp_ident "x") }, []), - (Exp_ident "y"))) - }, - []) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "lists v1" = - test_program {| -let x = [];; - |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "x"); expr = (Exp_construct ("[]", None)) }, []))) - ] |}] -;; - -let%expect_test "keyword" = - test_program - {|let rec fix f x = f (fix f) x;; -let map f p = let (a,b) = p in (f a, f b);; -let fixpoly l = - fix (fun self l -> map (fun li x -> li (self l) x) l) l;; -let feven p n = - let (e, o) = p in - if n = 0 then 1 else o (n - 1);; -let fodd p n = - let (e, o) = p in - if n = 0 then 0 else e (n - 1);; - let tie = fixpoly (feven, fodd);; |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "fix"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "x")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "f"), - (Exp_apply ((Exp_ident "fix"), (Exp_ident "f"))))), - (Exp_ident "x"))) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "map"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "p")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "a"), (Pat_var "b"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_apply ((Exp_ident "f"), (Exp_ident "b"))), [])) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "fixpoly"); - expr = - (Exp_fun (((Pat_var "l"), []), - (Exp_apply ( - (Exp_apply ((Exp_ident "fix"), - (Exp_fun (((Pat_var "self"), [(Pat_var "l")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "map"), - (Exp_fun (((Pat_var "li"), [(Pat_var "x")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "li"), - (Exp_apply ((Exp_ident "self"), - (Exp_ident "l"))) - )), - (Exp_ident "x"))) - )) - )), - (Exp_ident "l"))) - )) - )), - (Exp_ident "l"))) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "feven"); - expr = - (Exp_fun (((Pat_var "p"), [(Pat_var "n")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "e"), (Pat_var "o"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "o"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "fodd"); - expr = - (Exp_fun (((Pat_var "p"), [(Pat_var "n")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "e"), (Pat_var "o"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 0)), - (Some (Exp_apply ((Exp_ident "e"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "tie"); - expr = - (Exp_apply ((Exp_ident "fixpoly"), - (Exp_tuple ((Exp_ident "feven"), (Exp_ident "fodd"), [])))) - }, - []) - )) - ] |}] -;; - -let%expect_test "keyword" = - test_program {|type 'a foo = Foo;; -type bar = Bar of foo;; |}; - [%expect - {| - [(Str_adt (["a"], "foo", (("Foo", None), []))); - (Str_adt ([], "bar", (("Bar", (Some (Type_construct ("foo", [])))), [])))] |}] -;; - -let%expect_test "keyword" = - test_program {|let (x: (int*char) option) = Some 5;; |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = - (Pat_constraint ((Pat_var "x"), - (Type_construct ("option", - [(Type_tuple - ((Type_construct ("int", [])), - (Type_construct ("char", [])), [])) - ] - )) - )); - expr = - (Exp_construct ("Some", (Some (Exp_constant (Const_integer 5))))) }, - []) - )) - ] |}] -;; - -(*lists*) -let%expect_test "list1" = - test_program - {|let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl;; |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "length"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_constant (Const_integer 0)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_apply ((Exp_ident "length"), (Exp_ident "tl"))), - [])) - )) - } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list2" = - test_program - {|let length_tail = - let rec helper acc xs = - match xs with - | [] -> acc - | h::tl -> helper (acc + 1) tl - in - helper 0 -;; |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "length_tail"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "acc"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "acc") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "helper"), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_ident "acc"), - (Exp_constant (Const_integer 1)), - [])) - )) - )), - (Exp_ident "tl"))) - } - ]) - )) - )) - }, - []), - (Exp_apply ((Exp_ident "helper"), (Exp_constant (Const_integer 0)) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list3" = - test_program - {|let rec map f xs = - match xs with - | [] -> [] - | a::[] -> [f a] - | a::b::[] -> [f a; f b] - | a::b::c::[] -> [f a; f b; f c] - | a::b::c::d::tl -> f a :: f b :: f c :: f d :: map f tl -|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "map"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), (Pat_construct ("[]", None)), []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("[]", None)), []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("[]", None)), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c"))), - (Exp_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "::", - (Some (Pat_tuple - (( - Pat_var - "d"), - (Pat_var - "tl"), - []))) - )), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c"))), - (Exp_construct ( - "::", - (Some (Exp_tuple - (( - Exp_apply ( - (Exp_ident - "f"), - (Exp_ident - "d"))), - (Exp_apply ( - (Exp_apply ( - (Exp_ident - "map"), - (Exp_ident - "f"))), - (Exp_ident - "tl"))), - []))) - )), - []))) - )), - []))) - )), - []))) - )) - } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list4" = - test_program - {|let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys);; -|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "append"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "ys") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "x"), (Pat_var "xs"), []))))); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_ident "x"), - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_ident "xs"))), - (Exp_ident "ys"))), - []))) - )) - } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list5" = - test_program - {|let concat = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper -;; -|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "concat"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), (Exp_ident "h"))), - (Exp_apply ((Exp_ident "helper"), (Exp_ident "tl") - )) - )) - } - ]) - )) - )) - }, - []), - (Exp_ident "helper"))) - }, - []) - )) - ] |}] -;; - -let%expect_test "list6" = - test_program {|(1 :: 2) :: [] -;; -|}; - [%expect - {| - [(Str_eval - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_constant (Const_integer 2)), []))) - )), - (Exp_construct ("[]", None)), []))) - ))) - ] |}] -;; - -let%expect_test "list7" = - test_program - {|let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter f tl;; -|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "iter"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("()", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = (Exp_apply ((Exp_ident "f"), (Exp_ident "h"))) - }, - []), - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "f"))), - (Exp_ident "tl"))) - )) - } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list8" = - test_program - {|let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys);; -|}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "cartesian"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_apply ( - (Exp_apply ((Exp_ident "map"), - (Exp_fun (((Pat_var "a"), []), - (Exp_tuple - ((Exp_ident "h"), (Exp_ident "a"), [])) - )) - )), - (Exp_ident "ys"))) - )), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), (Exp_ident "tl") - )), - (Exp_ident "ys"))) - )) - } - ]) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list9" = - test_program - {|let main = - let () = iter print_int [1;2;3] in - let () = print_int (length (cartesian [1;2] [1;2;3;4])) in - 0 -;; -|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "print_int"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 3)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )), - []))) - )) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "length"), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )) - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer - 3)), - (Exp_construct ( - "::", - (Some ( - Exp_tuple - (( - Exp_constant - (Const_integer - 4)), - (Exp_construct ( - "[]", - None)), - []))) - )), - []))) - )), - []))) - )), - []))) - )) - )) - )) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list9" = - test_program {|type 'a list = - Cons of 'a * 'a list - | Nil;;|}; - [%expect - {| - [(Str_adt (["a"], "list", - (("Cons", - (Some (Type_tuple - ((Type_var "a"), (Type_construct ("list", [(Type_var "a")])), - [])))), - [("Nil", None)]) - )) - ] |}] -;; - -let%expect_test "list9" = - test_program - {| -let _1 = fun x y (a, _) -> (x + y - a) = 1 - -let _2 = - let x, Some f = 1, Some ( "p1onerka was here" ) - in x - -let _3 = Some (1, "hi") - -let _4 = let rec f x = f 5 in f - -let _5 = - let id x = x in - match Some id with - | Some f -> let _ = f "42" in f 42 - | None -> 0 - -let _6 = fun arg -> match arg with Some x -> let y = x in y;; - -let int_of_option = function -Some x -> x -| None -> 0 - -let _42 = function 42 -> true | _ -> false - -let id1, id2 = let id x = x in (id, id) - - - |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "_1"); - expr = - (Exp_fun ( - ((Pat_var "x"), - [(Pat_var "y"); (Pat_tuple ((Pat_var "a"), Pat_any, []))]), - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_apply ((Exp_ident "+"), - (Exp_tuple ((Exp_ident "x"), (Exp_ident "y"), [])) - )), - (Exp_ident "a"), [])) - )), - (Exp_constant (Const_integer 1)), [])) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_2"); - expr = - (Exp_let (Nonrecursive, - ({ pat = - (Pat_tuple - ((Pat_var "x"), - (Pat_construct ("Some", (Some (Pat_var "f")))), [])); - expr = - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("Some", - (Some (Exp_constant (Const_string "p1onerka was here"))) - )), - [])) - }, - []), - (Exp_ident "x"))) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_3"); - expr = - (Exp_construct ("Some", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_constant (Const_string "hi")), []))) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_4"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "f"); - expr = - (Exp_fun (((Pat_var "x"), []), - (Exp_apply ((Exp_ident "f"), - (Exp_constant (Const_integer 5)))) - )) - }, - []), - (Exp_ident "f"))) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_5"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "id"); - expr = (Exp_fun (((Pat_var "x"), []), (Exp_ident "x"))) }, - []), - (Exp_match ((Exp_construct ("Some", (Some (Exp_ident "id")))), - ({ first = (Pat_construct ("Some", (Some (Pat_var "f")))); - second = - (Exp_let (Nonrecursive, - ({ pat = Pat_any; - expr = - (Exp_apply ((Exp_ident "f"), - (Exp_constant (Const_string "42")))) - }, - []), - (Exp_apply ((Exp_ident "f"), - (Exp_constant (Const_integer 42)))) - )) - }, - [{ first = (Pat_construct ("None", None)); - second = (Exp_constant (Const_integer 0)) } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_6"); - expr = - (Exp_fun (((Pat_var "arg"), []), - (Exp_match ((Exp_ident "arg"), - ({ first = (Pat_construct ("Some", (Some (Pat_var "x")))); - second = - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "y"); expr = (Exp_ident "x") }, []), - (Exp_ident "y"))) - }, - []) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "int_of_option"); - expr = - (Exp_function - ({ first = (Pat_construct ("Some", (Some (Pat_var "x")))); - second = (Exp_ident "x") }, - [{ first = (Pat_construct ("None", None)); - second = (Exp_constant (Const_integer 0)) } - ])) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "_42"); - expr = - (Exp_function - ({ first = (Pat_constant (Const_integer 42)); - second = (Exp_construct ("true", None)) }, - [{ first = Pat_any; second = (Exp_construct ("false", None)) }])) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "id1"), (Pat_var "id2"), [])); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "id"); - expr = (Exp_fun (((Pat_var "x"), []), (Exp_ident "x"))) }, - []), - (Exp_tuple ((Exp_ident "id"), (Exp_ident "id"), [])))) - }, - []) - )) - ] |}] -;; - -let%expect_test "list9" = - test_program - {| -let rec fix f x = f (fix f) x -let map f p = let (a,b) = p in (f a, f b) -let fixpoly l = - fix (fun self l -> map (fun li x -> li (self l) x) l) l -let feven p n = - let (e, o) = p in - if n = 0 then 1 else o (n - 1) -let fodd p n = - let (e, o) = p in - if n = 0 then 0 else e (n - 1) -let tie = fixpoly (feven, fodd) - -let rec meven n = if n = 0 then 1 else modd (n - 1) -and modd n = if n = 0 then 1 else meven (n - 1) -let main = - let () = print_int (modd 1) in - let () = print_int (meven 2) in - let (even,odd) = tie in - let () = print_int (odd 3) in - let () = print_int (even 4) in - 0 - - - - |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "fix"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "x")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "f"), - (Exp_apply ((Exp_ident "fix"), (Exp_ident "f"))))), - (Exp_ident "x"))) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "map"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "p")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "a"), (Pat_var "b"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_apply ((Exp_ident "f"), (Exp_ident "b"))), [])) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "fixpoly"); - expr = - (Exp_fun (((Pat_var "l"), []), - (Exp_apply ( - (Exp_apply ((Exp_ident "fix"), - (Exp_fun (((Pat_var "self"), [(Pat_var "l")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "map"), - (Exp_fun (((Pat_var "li"), [(Pat_var "x")]), - (Exp_apply ( - (Exp_apply ((Exp_ident "li"), - (Exp_apply ((Exp_ident "self"), - (Exp_ident "l"))) - )), - (Exp_ident "x"))) - )) - )), - (Exp_ident "l"))) - )) - )), - (Exp_ident "l"))) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "feven"); - expr = - (Exp_fun (((Pat_var "p"), [(Pat_var "n")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "e"), (Pat_var "o"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "o"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "fodd"); - expr = - (Exp_fun (((Pat_var "p"), [(Pat_var "n")]), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "e"), (Pat_var "o"), [])); - expr = (Exp_ident "p") }, - []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 0)), - (Some (Exp_apply ((Exp_ident "e"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "tie"); - expr = - (Exp_apply ((Exp_ident "fixpoly"), - (Exp_tuple ((Exp_ident "feven"), (Exp_ident "fodd"), [])))) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "meven"); - expr = - (Exp_fun (((Pat_var "n"), []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "modd"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - }, - [{ pat = (Pat_var "modd"); - expr = - (Exp_fun (((Pat_var "n"), []), - (Exp_if ( - (Exp_apply ((Exp_ident "="), - (Exp_tuple - ((Exp_ident "n"), (Exp_constant (Const_integer 0)), [])) - )), - (Exp_constant (Const_integer 1)), - (Some (Exp_apply ((Exp_ident "meven"), - (Exp_apply ((Exp_ident "-"), - (Exp_tuple - ((Exp_ident "n"), - (Exp_constant (Const_integer 1)), [])) - )) - ))) - )) - )) - } - ]) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "modd"), - (Exp_constant (Const_integer 1)))) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "meven"), - (Exp_constant (Const_integer 2)))) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_tuple ((Pat_var "even"), (Pat_var "odd"), [])); - expr = (Exp_ident "tie") }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "odd"), - (Exp_constant (Const_integer 3)))) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "even"), - (Exp_constant (Const_integer 4)))) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - )) - )) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list9" = - test_program - {| -let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl - -let length_tail = - let rec helper acc xs = - match xs with - | [] -> acc - | h::tl -> helper (acc + 1) tl - in - helper 0 - -let rec map f xs = - match xs with - | [] -> [] - | a::[] -> [f a] - | a::b::[] -> [f a; f b] - | a::b::c::[] -> [f a; f b; f c] - | a::b::c::d::tl -> f a :: f b :: f c :: f d :: map f tl - -let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys) - -let concat = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper - -let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter f tl - -let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - -let main = - let () = iter print_int [1;2;3] in - let () = print_int (length (cartesian [1;2] [1;2;3;4])) in - 0 - - - |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "length"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_constant (Const_integer 0)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_apply ((Exp_ident "length"), (Exp_ident "tl"))), - [])) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "length_tail"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "acc"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "acc") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "helper"), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_ident "acc"), - (Exp_constant (Const_integer 1)), - [])) - )) - )), - (Exp_ident "tl"))) - } - ]) - )) - )) - }, - []), - (Exp_apply ((Exp_ident "helper"), (Exp_constant (Const_integer 0)) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "map"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), (Pat_construct ("[]", None)), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("[]", None)), []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("[]", None)), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c") - )), - (Exp_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "::", - (Some (Pat_tuple - (( - Pat_var - "d"), - (Pat_var - "tl"), - []))) - )), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c") - )), - (Exp_construct ( - "::", - (Some (Exp_tuple - (( - Exp_apply ( - (Exp_ident - "f"), - (Exp_ident - "d"))), - (Exp_apply ( - (Exp_apply ( - (Exp_ident - "map"), - (Exp_ident - "f"))), - (Exp_ident - "tl"))), - []))) - )), - []))) - )), - []))) - )), - []))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "append"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "ys") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "x"), (Pat_var "xs"), []))))); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_ident "x"), - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_ident "xs"))), - (Exp_ident "ys"))), - []))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "concat"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), (Exp_ident "h") - )), - (Exp_apply ((Exp_ident "helper"), (Exp_ident "tl") - )) - )) - } - ]) - )) - )) - }, - []), - (Exp_ident "helper"))) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "iter"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("()", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = (Exp_apply ((Exp_ident "f"), (Exp_ident "h"))) - }, - []), - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "f"))), - (Exp_ident "tl"))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "cartesian"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_apply ( - (Exp_apply ((Exp_ident "map"), - (Exp_fun (((Pat_var "a"), []), - (Exp_tuple - ((Exp_ident "h"), (Exp_ident "a"), [])) - )) - )), - (Exp_ident "ys"))) - )), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), (Exp_ident "tl") - )), - (Exp_ident "ys"))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "print_int"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 3)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )), - []))) - )) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "length"), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )) - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - ( - Const_integer - 3)), - (Exp_construct ( - "::", - (Some ( - Exp_tuple - (( - Exp_constant - (Const_integer - 4)), - (Exp_construct ( - "[]", - None)), - []))))), - []))) - )), - []))) - )), - []))) - )) - )) - )) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "list6" = - test_program "(1 :: 2) :: []"; - [%expect - {| - [(Str_eval - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_constant (Const_integer 2)), []))) - )), - (Exp_construct ("[]", None)), []))) - ))) - ] |}] -;; - -let%expect_test "list5" = - test_program - "let concat = let rec helper xs = match xs with | [] -> [] | h::tl -> append h \ - (helper tl) in helper"; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "concat"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), (Exp_ident "h"))), - (Exp_apply ((Exp_ident "helper"), (Exp_ident "tl") - )) - )) - } - ]) - )) - )) - }, - []), - (Exp_ident "helper"))) - }, - []) - )) - ] |}] -;; - -let%expect_test "list_basic" = - test_program "let lst = 1 :: 2 :: 3 :: [] in lst"; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "lst"); - expr = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 3)), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )), - []))) - )) - }, - []), - (Exp_ident "lst")))) - ] |}] -;; - -let%expect_test "list_match" = - test_program "match 1 :: 2 :: 3 :: [] with | [] -> 0 | h :: _ -> h"; - [%expect - {| - [(Str_eval - (Exp_match ( - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 3)), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )), - []))) - )), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_constant (Const_integer 0)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), Pat_any, []))))); - second = (Exp_ident "h") } - ]) - ))) - ] |}] -;; - -let%expect_test "list_append" = - test_program - "let append xs ys = match xs with | [] -> ys | h :: t -> h :: append t ys in append \ - [1; 2] [3; 4]"; - [%expect - {| - [(Str_eval - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "append"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "ys") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "t"), []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_ident "h"), - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_ident "t"))), - (Exp_ident "ys"))), - []))) - )) - } - ]) - )) - )) - }, - []), - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )) - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 3)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 4)), - (Exp_construct ("[]", None)), []))) - )), - []))) - )) - )) - ))) - ] |}] -;; - -let%expect_test "()" = - test_program - {| - let a = - let b = - let rec f = (let x = 3 in x) + 1 - in f - in ();; - let s = "string";; - |}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "a"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_var "b"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "f"); - expr = - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_let (Nonrecursive, - ({ pat = (Pat_var "x"); - expr = (Exp_constant (Const_integer 3)) }, - []), - (Exp_ident "x"))), - (Exp_constant (Const_integer 1)), [])) - )) - }, - []), - (Exp_ident "f"))) - }, - []), - (Exp_construct ("()", None)))) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "s"); expr = (Exp_constant (Const_string "string")) }, - []) - )) - ] |}] -;; - -let%expect_test "()" = - test_program {| - let rec iter f xs = match xs with [] -> () - |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "iter"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("()", None)) }, - []) - )) - )) - }, - []) - )) - ] |}] -;; - -let%expect_test "()" = - test_program - {| -let rec length xs = - match xs with - | [] -> 0 - | h::tl -> 1 + length tl - -let length_tail = - let rec helper acc xs = - match xs with - | [] -> acc - | h::tl -> helper (acc + 1) tl - in - helper 0 - -let rec map f xs = - match xs with - | [] -> [] - | a::[] -> [f a] - | a::b::[] -> [f a; f b] - | a::b::c::[] -> [f a; f b; f c] - | a::b::c::d::tl -> f a :: f b :: f c :: f d :: map f tl - -let rec append xs ys = match xs with [] -> ys | x::xs -> x::(append xs ys) - -let concat = - let rec helper xs = - match xs with - | [] -> [] - | h::tl -> append h (helper tl) - in helper - -let rec iter f xs = match xs with [] -> () | h::tl -> let () = f h in iter f tl - -let rec cartesian xs ys = - match xs with - | [] -> [] - | h::tl -> append (map (fun a -> (h,a)) ys) (cartesian tl ys) - -let main = - let () = iter print_int [1;2;3] in - let () = print_int (length (cartesian [1;2] [1;2;3;4])) in - 0 - |}; - [%expect - {| - [(Str_value (Recursive, - ({ pat = (Pat_var "length"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_constant (Const_integer 0)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_apply ((Exp_ident "length"), (Exp_ident "tl"))), - [])) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "length_tail"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "acc"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "acc") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "helper"), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_ident "acc"), - (Exp_constant (Const_integer 1)), - [])) - )) - )), - (Exp_ident "tl"))) - } - ]) - )) - )) - }, - []), - (Exp_apply ((Exp_ident "helper"), (Exp_constant (Const_integer 0)) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "map"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), (Pat_construct ("[]", None)), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a"))), - (Exp_construct ("[]", None)), []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("[]", None)), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("[]", None)), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c") - )), - (Exp_construct ( - "[]", None)), - []))) - )), - []))) - )), - []))) - )) - }; - { first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "a"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "b"), - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "c"), - (Pat_construct ( - "::", - (Some (Pat_tuple - (( - Pat_var - "d"), - (Pat_var - "tl"), - []))) - )), - []))) - )), - []))) - )), - []))) - )); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), (Exp_ident "a") - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ((Exp_ident "f"), - (Exp_ident "b"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_apply ( - (Exp_ident "f"), - (Exp_ident "c") - )), - (Exp_construct ( - "::", - (Some (Exp_tuple - (( - Exp_apply ( - (Exp_ident - "f"), - (Exp_ident - "d"))), - (Exp_apply ( - (Exp_apply ( - (Exp_ident - "map"), - (Exp_ident - "f"))), - (Exp_ident - "tl"))), - []))) - )), - []))) - )), - []))) - )), - []))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "append"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_ident "ys") }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "x"), (Pat_var "xs"), []))))); - second = - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_ident "x"), - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_ident "xs"))), - (Exp_ident "ys"))), - []))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "concat"); - expr = - (Exp_let (Recursive, - ({ pat = (Pat_var "helper"); - expr = - (Exp_fun (((Pat_var "xs"), []), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple - ((Pat_var "h"), (Pat_var "tl"), []))) - )); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), (Exp_ident "h") - )), - (Exp_apply ((Exp_ident "helper"), (Exp_ident "tl") - )) - )) - } - ]) - )) - )) - }, - []), - (Exp_ident "helper"))) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "iter"); - expr = - (Exp_fun (((Pat_var "f"), [(Pat_var "xs")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("()", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = (Exp_apply ((Exp_ident "f"), (Exp_ident "h"))) - }, - []), - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "f"))), - (Exp_ident "tl"))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Recursive, - ({ pat = (Pat_var "cartesian"); - expr = - (Exp_fun (((Pat_var "xs"), [(Pat_var "ys")]), - (Exp_match ((Exp_ident "xs"), - ({ first = (Pat_construct ("[]", None)); - second = (Exp_construct ("[]", None)) }, - [{ first = - (Pat_construct ("::", - (Some (Pat_tuple ((Pat_var "h"), (Pat_var "tl"), []))))); - second = - (Exp_apply ( - (Exp_apply ((Exp_ident "append"), - (Exp_apply ( - (Exp_apply ((Exp_ident "map"), - (Exp_fun (((Pat_var "a"), []), - (Exp_tuple - ((Exp_ident "h"), (Exp_ident "a"), [])) - )) - )), - (Exp_ident "ys"))) - )), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), (Exp_ident "tl") - )), - (Exp_ident "ys"))) - )) - } - ]) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ( - (Exp_apply ((Exp_ident "iter"), (Exp_ident "print_int"))), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 3)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )), - []))) - )) - )) - }, - []), - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "length"), - (Exp_apply ( - (Exp_apply ((Exp_ident "cartesian"), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("[]", - None)), - []))) - )), - []))) - )) - )), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant (Const_integer 1)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - (Const_integer 2)), - (Exp_construct ("::", - (Some (Exp_tuple - ((Exp_constant - ( - Const_integer - 3)), - (Exp_construct ( - "::", - (Some ( - Exp_tuple - (( - Exp_constant - (Const_integer - 4)), - (Exp_construct ( - "[]", - None)), - []))))), - []))) - )), - []))) - )), - []))) - )) - )) - )) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - )) - }, - []) - )) - ] - - |}] -;; - -let%expect_test "simple adt with pattern matching function (else case) + printing" = - test_program {| -type shape = Circle of int - | Rectangle of (int*int) * int -;; - |}; - [%expect - {| - [(Str_adt ([], "shape", - (("Circle", (Some (Type_construct ("int", [])))), - [("Rectangle", - (Some (Type_tuple - ((Type_tuple - ((Type_construct ("int", [])), - (Type_construct ("int", [])), [])), - (Type_construct ("int", [])), [])))) - ]) - )) - ] |}] -;; - -let%expect_test "one arg adt v2" = - test_program {| -type ('a) shape = Circle of int - | Rectangle of (int*int) * int -;; - |}; - [%expect - {| - [(Str_adt (["a"], "shape", - (("Circle", (Some (Type_construct ("int", [])))), - [("Rectangle", - (Some (Type_tuple - ((Type_tuple - ((Type_construct ("int", [])), - (Type_construct ("int", [])), [])), - (Type_construct ("int", [])), [])))) - ]) - )) - ] |}] -;; - -let%expect_test "multiple args adt v2" = - test_program {| - type ('a, 'b) s9CG0K = - | R - | F - | H of f -;; -|}; - [%expect - {| - [(Str_adt (["a"; "b"], "s9CG0K", - (("R", None), [("F", None); ("H", (Some (Type_construct ("f", []))))]))) - ] |}] -;; - -let%expect_test "multiple args adt v3" = - test_program {| - type ('a, 'b, 'c, 'd) s9CG0K = - | R - | F - | H of f -;; -|}; - [%expect - {| - [(Str_adt (["a"; "b"; "c"; "d"], "s9CG0K", - (("R", None), [("F", None); ("H", (Some (Type_construct ("f", []))))]))) - ] |}] -;; - -let%expect_test "multiple args adt v4" = - test_program {| - type '_3d f = - | J of _f - | K -;; -|}; - [%expect - {| - [(Str_adt (["_3d"], "f", - (("J", (Some (Type_construct ("_f", [])))), [("K", None)]))) - ] |}] -;; - -let%expect_test "multiple args adt v4 (capitalized idents in constr_args)" = - test_program - {| - type ('ot, '_a, 't, '_v) i_ = - | L_ of Z - | Dl of _f - | G of uG_ - | Egd of _a -;; -|}; - [%expect - {| - [(Str_adt (["ot"; "_a"; "t"; "_v"], "i_", - (("L_", (Some (Type_construct ("Z", [])))), - [("Dl", (Some (Type_construct ("_f", [])))); - ("G", (Some (Type_construct ("uG_", [])))); - ("Egd", (Some (Type_construct ("_a", []))))]) - )) - ] |}] -;; - -let%expect_test "adt from default types" = - test_program {| -type point = int * int;; -|}; - [%expect - {| - [(Str_adt ([], "point", - (("", - (Some (Type_tuple - ((Type_construct ("int", [])), (Type_construct ("int", [])), - [])))), - []) - )) - ] - |}] -;; - -let%expect_test "adt match case (pat_any)" = - test_program - {| -let area s = - match s with - | Square c -> 0 - | Circle c -> 3 - | _ -> 10 -;; -|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "area"); - expr = - (Exp_fun (((Pat_var "s"), []), - (Exp_match ((Exp_ident "s"), - ({ first = (Pat_construct ("Square", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 0)) }, - [{ first = (Pat_construct ("Circle", (Some (Pat_var "c")))); - second = (Exp_constant (Const_integer 3)) }; - { first = Pat_any; second = (Exp_constant (Const_integer 10)) - } - ]) - )) - )) - }, - []) - )) - ] - |}] -;; - -let%expect_test "006partial2" = - test_program - {| -let foo b = if b then (fun foo -> foo+2) else (fun foo -> foo*10) - -let foo x = foo true (foo false (foo true (foo false x))) -let main = - let () = print_int (foo 11) in - 0 -|}; - [%expect - {| - [(Str_value (Nonrecursive, - ({ pat = (Pat_var "foo"); - expr = - (Exp_fun (((Pat_var "b"), []), - (Exp_if ((Exp_ident "b"), - (Exp_fun (((Pat_var "foo"), []), - (Exp_apply ((Exp_ident "+"), - (Exp_tuple - ((Exp_ident "foo"), (Exp_constant (Const_integer 2)), - [])) - )) - )), - (Some (Exp_fun (((Pat_var "foo"), []), - (Exp_apply ((Exp_ident "*"), - (Exp_tuple - ((Exp_ident "foo"), - (Exp_constant (Const_integer 10)), [])) - )) - ))) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "foo"); - expr = - (Exp_fun (((Pat_var "x"), []), - (Exp_apply ( - (Exp_apply ((Exp_ident "foo"), (Exp_construct ("true", None)))), - (Exp_apply ( - (Exp_apply ((Exp_ident "foo"), - (Exp_construct ("false", None)))), - (Exp_apply ( - (Exp_apply ((Exp_ident "foo"), - (Exp_construct ("true", None)))), - (Exp_apply ( - (Exp_apply ((Exp_ident "foo"), - (Exp_construct ("false", None)))), - (Exp_ident "x"))) - )) - )) - )) - )) - }, - []) - )); - (Str_value (Nonrecursive, - ({ pat = (Pat_var "main"); - expr = - (Exp_let (Nonrecursive, - ({ pat = (Pat_construct ("()", None)); - expr = - (Exp_apply ((Exp_ident "print_int"), - (Exp_apply ((Exp_ident "foo"), - (Exp_constant (Const_integer 11)))) - )) - }, - []), - (Exp_constant (Const_integer 0)))) - }, - []) - )) - ] |}] -;; diff --git a/OcamlADT/tests/parser.mli b/OcamlADT/tests/parser.mli deleted file mode 100644 index eabf8ddd5..000000000 --- a/OcamlADT/tests/parser.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Ast - -val test_program : ident -> unit diff --git a/OcamlADT/tests/pprinter.ml b/OcamlADT/tests/pprinter.ml deleted file mode 100644 index d9b3e464a..000000000 --- a/OcamlADT/tests/pprinter.ml +++ /dev/null @@ -1,615 +0,0 @@ -(** Copyright 2024, Rodion Suvorov, Mikhail Gavrilenko*) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Ast.Expression -open Ocamladt_lib.Ast.Constant -open Ocamladt_lib.Ast.Pattern -open Ocamladt_lib.Pprinter -open Ocamladt_lib.Ast.Structure -open Ocamladt_lib.Ast.TypeExpr -open Format - -let test_pprint_expression input_expr = - let actual_output = asprintf "%a" (fun fmt -> pprint_expression fmt 0) input_expr in - print_endline actual_output -;; - -let%expect_test "simple addition" = - let expr = - Exp_apply - ( Exp_ident "+" - , Exp_tuple (Exp_constant (Const_integer 1), Exp_constant (Const_integer 2), []) ) - in - test_pprint_expression expr; - [%expect {| 1 + 2 |}] -;; - -let%expect_test "nested expressions with precedence handling" = - let expr = - Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_apply - ( Exp_ident "*" - , Exp_tuple - (Exp_constant (Const_integer 3), Exp_constant (Const_integer 4), []) ) - , Exp_constant (Const_integer 5) - , [] ) ) - in - test_pprint_expression expr; - [%expect {| 3 * 4 + 5 |}] -;; - -let%expect_test "parentheses for lower precedence" = - let expr = - Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_apply - ( Exp_ident "+" - , Exp_tuple - (Exp_constant (Const_integer 1), Exp_constant (Const_integer 2), []) ) - , Exp_constant (Const_integer 3) - , [] ) ) - in - test_pprint_expression expr; - [%expect {| (1 + 2) * 3 |}] -;; - -let%expect_test "simple nested addition expression" = - let expr = - Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_constant (Const_integer 1) - , Exp_apply - ( Exp_ident "+" - , Exp_tuple - (Exp_constant (Const_integer 2), Exp_constant (Const_integer 3), []) ) - , [] ) ) - in - test_pprint_expression expr; - [%expect {| 1 + (2 + 3) |}] -;; - -let%expect_test "subtraction" = - let expr = - Exp_apply - ( Exp_ident "-" - , Exp_tuple (Exp_constant (Const_integer 5), Exp_constant (Const_integer 1), []) ) - in - test_pprint_expression expr; - [%expect {| 5 - 1 |}] -;; - -let%expect_test "division with parentheses" = - let expr = - Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_constant (Const_integer 8) - , Exp_apply - ( Exp_ident "+" - , Exp_tuple - (Exp_constant (Const_integer 2), Exp_constant (Const_integer 1), []) ) - , [] ) ) - in - test_pprint_expression expr; - [%expect {| 8 / (2 + 1) |}] -;; - -let%expect_test "nested expression with division" = - let expr4 = - Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_apply - ( Exp_ident "+" - , Exp_tuple - (Exp_constant (Const_integer 10), Exp_constant (Const_integer 5), []) ) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - (Exp_constant (Const_integer 2), Exp_constant (Const_integer 3), []) ) - , [] ) ) - in - pprint_expression std_formatter 0 expr4; - [%expect {| (10 + 5) / (2 * 3) |}] -;; - -let%expect_test "nested function calls with precedence" = - let expr5 = - Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_constant (Const_integer 8) - , Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_constant (Const_integer 2) - , Exp_constant (Const_integer 3) - , [] ) ) - , [] ) ) - , Exp_constant (Const_integer 4) - , [] ) ) - in - pprint_expression std_formatter 0 expr5; - [%expect {| (8 - (2 + 3)) * 4 |}] -;; - -let%expect_test "nested operations with multi-level tuples" = - let expr6 = - Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_apply - ( Exp_ident "/" - , Exp_tuple - (Exp_constant (Const_integer 18), Exp_constant (Const_integer 3), []) ) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - (Exp_constant (Const_integer 2), Exp_constant (Const_integer 4), []) ) - , [] ) ) - in - pprint_expression std_formatter 0 expr6; - [%expect {| 18 / 3 + 2 * 4 |}] -;; - -let%expect_test "chained operations requiring multiple parentheses" = - let expr7 = - Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_constant (Const_integer 10) - , Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_constant (Const_integer 9) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 2) - , Exp_constant (Const_integer 3) - , [] ) ) - , [] ) ) - , [] ) ) - , Exp_constant (Const_integer 5) - , [] ) ) - in - pprint_expression std_formatter 0 expr7; - [%expect {| 10 - 9 / (2 * 3) + 5 |}] -;; - -let%expect_test "complex nested arithmetic expression" = - let expr8 = - Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 105) - , Exp_constant (Const_integer 64) - , [] ) ) - , Exp_constant (Const_integer 27) - , [] ) ) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 2) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 5) - , Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_constant (Const_integer 5) - , Exp_constant (Const_integer 1) - , [] ) ) - , [] ) ) - , [] ) ) - , [] ) ) - , Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_constant (Const_integer 47) - , Exp_constant (Const_integer 64) - , [] ) ) - , [] ) ) - , Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 56) - , Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 57) - , Exp_constant (Const_integer 4) - , [] ) ) - , [] ) ) - , Exp_constant (Const_integer 5) - , [] ) ) - , [] ) ) - in - pprint_expression std_formatter 0 expr8; - [%expect {| 105 * 64 / 27 - 2 * (5 * (5 - 1)) + 47 / 64 - (56 * (57 * 4) - 5) |}] -;; - -(* 105 * 64 / 27 - 2 * (5*(5-1)) + 47 / 64 - (56 * (57 *4) - 5) *) - -let%expect_test "deeply nested mixed operations with logical operators" = - let expr = - Exp_apply - ( Exp_ident "||" - , Exp_tuple - ( Exp_apply - ( Exp_ident "||" - , Exp_tuple - ( Exp_apply - ( Exp_ident "&&" - , Exp_tuple - ( Exp_apply - ( Exp_ident "<" - , Exp_tuple - ( Exp_apply - ( Exp_ident "*" - , Exp_tuple - ( Exp_constant (Const_integer 3) - , Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_constant (Const_integer 9) - , Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_constant (Const_integer 12) - , Exp_constant (Const_integer 4) - , [] ) ) - , [] ) ) - , [] ) ) - , Exp_constant (Const_integer 7) - , [] ) ) - , Exp_constant (Const_integer 1) - , [] ) ) - , Exp_apply - ( Exp_ident "&&" - , Exp_tuple - ( Exp_constant (Const_integer 1) - , Exp_apply - ( Exp_ident "<" - , Exp_tuple - ( Exp_constant (Const_integer 5) - , Exp_constant (Const_integer 6) - , [] ) ) - , [] ) ) - , [] ) ) - , Exp_apply - ( Exp_ident "&&" - , Exp_tuple - ( Exp_apply - ( Exp_ident "-" - , Exp_tuple - ( Exp_constant (Const_integer 20) - , Exp_apply - ( Exp_ident "/" - , Exp_tuple - ( Exp_constant (Const_integer 100) - , Exp_apply - ( Exp_ident "+" - , Exp_tuple - ( Exp_constant (Const_integer 4) - , Exp_constant (Const_integer 16) - , [] ) ) - , [] ) ) - , [] ) ) - , Exp_apply - ( Exp_ident "<" - , Exp_tuple - ( Exp_constant (Const_integer 10) - , Exp_constant (Const_integer 12) - , [] ) ) - , [] ) ) - , [] ) ) - (* At this point, you would typically evaluate or inspect `expr` *) - in - pprint_expression std_formatter 0 expr; - [%expect - {| (3 * (9 - 12 / 4) < 7 && 1 || 1 && 5 < 6) || 20 - 100 / (4 + 16) && 10 < 12 |}] -;; - -let%expect_test "let and construct" = - let program = - [ Str_eval - (Exp_apply - ( Exp_let - ( Nonrecursive - , ( { pat = Pat_any; expr = Exp_ident "s" } - , [ { pat = Pat_constant (Const_string "fgo"); expr = Exp_ident "ilm" } ] - ) - , Exp_ident "j_9" ) - , Exp_construct ("Tep", Some (Exp_ident "ha9")) )) - ] - in - pprint_program std_formatter program; - [%expect {| - (let _ = s and "fgo" = ilm in j_9) (Tep (ha9)) ;; |}] -;; - -(*(let _ s = "fgo" -> __im in j_9) Tep (ha9);;*) - -let%expect_test "if with parenthesis" = - let program = - [ Str_eval - (Exp_tuple - ( Exp_tuple - (Exp_ident "c6BR_J", Exp_constant (Const_string ""), [ Exp_ident "j_v_" ]) - , Exp_if - ( Exp_constant (Const_string "hgdpg") - , Exp_ident "_T" - , Some (Exp_constant (Const_integer 80)) ) - , [ Exp_let - ( Nonrecursive - , ( { pat = Pat_constant (Const_integer 69) - ; expr = Exp_constant (Const_integer 8) - } - , [ { pat = Pat_constant (Const_integer 5) - ; expr = Exp_constant (Const_char 'd') - } - ] ) - , Exp_constant (Const_integer 4) ) - ] )) - ] - in - pprint_program std_formatter program; - [%expect - {| - ((c6BR_J, "", j_v_), (if "hgdpg" - then _T - else 80), (let 69 = 8 and 5 = 'd' in 4)) ;; |}] -;; - -let%expect_test "let binding with integer" = - let program = - [ Str_value - (Nonrecursive, ({ pat = Pat_var "x"; expr = Exp_constant (Const_integer 42) }, [])) - ] - in - pprint_program std_formatter program; - [%expect {| - let x = 42;; - |}] -;; - -let%expect_test "if expression" = - let program = - [ Str_eval - (Exp_if - ( Exp_apply - ( Exp_ident ">" - , Exp_tuple (Exp_ident "x", Exp_constant (Const_integer 10), []) ) - , Exp_ident "large" - , Some (Exp_ident "small") )) - ] - in - pprint_program std_formatter program; - [%expect {| - if x > 10 - then large - else small ;; - |}] -;; - -let%expect_test "tuple and match expression" = - let program = - [ Str_eval - (Exp_match - ( Exp_tuple (Exp_ident "a", Exp_ident "b", [ Exp_ident "c" ]) - , ( { first = Pat_tuple (Pat_var "x", Pat_var "y", [ Pat_var "z" ]) - ; second = - Exp_apply (Exp_ident "f", Exp_tuple (Exp_ident "x", Exp_ident "y", [])) - } - , [] ) )) - ] - in - pprint_program std_formatter program; - [%expect {| - match (a, b, c) with - | (x, y, z) -> (f (x, y)) ;; - |}] -;; - -let%expect_test "nested constructs" = - let program = - [ Str_eval - (Exp_apply - ( Exp_ident "map" - , Exp_tuple - ( Exp_function - ( { first = Pat_var "x" - ; second = - Exp_apply - ( Exp_ident "*" - , Exp_tuple (Exp_ident "x", Exp_constant (Const_integer 2), []) - ) - } - , [] ) - , Exp_ident "list" - , [] ) )) - ] - in - pprint_program std_formatter program; - [%expect {| - map ((function - | x -> x * 2), list) ;; - |}] -;; - -let%expect_test "construct with optional arguments" = - let program = - [ Str_eval (Exp_construct ("Some", Some (Exp_constant (Const_string "Hello")))) ] - in - pprint_program std_formatter program; - [%expect {| - (Some ("Hello")) ;; - |}] -;; - -let%expect_test "complex program" = - let program = - [ Str_eval - (Exp_let - ( Nonrecursive - , ({ pat = Pat_var "x"; expr = Exp_constant (Const_integer 5) }, []) - , Exp_if - ( Exp_apply - ( Exp_ident ">" - , Exp_tuple (Exp_ident "x", Exp_constant (Const_integer 0), []) ) - , Exp_construct ("Some", Some (Exp_ident "x")) - , Some (Exp_construct ("None", None)) ) )) - ] - in - pprint_program std_formatter program; - [%expect {| - let x = 5 in (if x > 0 - then (Some (x)) - else (None)) ;; - |}] -;; - -let%expect_test "adt v1" = - let program = - [ Str_adt - ([], "shape", (("Circle", None), [ "Square", Some (Type_construct ("int", [])) ])) - ] - in - pprint_program std_formatter program; - [%expect {| - type shape = - | Circle - | Square of int - ;; - |}] -;; - -(*check this tests*) -let%expect_test "adt with poly" = - let program = - [ Str_adt ([ "a" ], "shape", (("Circle", None), [ "Square", Some (Type_var "a") ])) ] - in - pprint_program std_formatter program; - [%expect {| - type 'a shape = - | Circle - | Square of 'a - ;; - |}] -;; - -let%expect_test "adt v2" = - let program = [ Str_adt ([], "shape", (("Circle", None), [ "Square", None ])) ] in - pprint_program std_formatter program; - [%expect {| - type shape = - | Circle - | Square - ;; |}] -;; - -let%expect_test "adt v3" = - let program = - [ Str_adt - ( [] - , "shape" - , ( ("Circle", None) - , [ ( "Square" - , Some - (Type_tuple (Type_construct ("int", []), Type_construct ("int", []), [])) - ) - ] ) ) - ] - in - pprint_program std_formatter program; - [%expect {| - type shape = - | Circle - | Square of (int * int) - ;; |}] -;; - -let%expect_test "adt with poly" = - let program = - [ Str_adt ([ "a" ], "shape", (("Circle", None), [ "Square", Some (Type_var "a") ])) ] - in - pprint_program std_formatter program; - [%expect {| - type 'a shape = - | Circle - | Square of 'a - ;; |}] -;; - -let%expect_test "adt with poly (v.easy)" = - let program = [ Str_adt ([ "a" ], "shape", (("Circle", None), [])) ] in - pprint_program std_formatter program; - [%expect {| - type 'a shape = - | Circle - ;; |}] -;; - -let%expect_test "bad adt with multiple poly" = - let program = - [ Str_adt - ( [ "a"; "b" ] - , "shape" - , (("Circle", None), [ "Square", Some (Type_construct ("", [ Type_var "a" ])) ]) - ) - ] - in - pprint_program std_formatter program; - [%expect {| - type ('a, 'b) shape = - | Circle - | Square of 'a - ;; |}] -;; - -let%expect_test "adt with multiple poly v2" = - let program = - [ Str_adt - ( [ "a"; "b" ] - , "shape" - , ( ("Circle", None) - , [ "Square", Some (Type_construct ("shape", [ Type_var "a"; Type_var "b" ])) ] - ) ) - ] - in - pprint_program std_formatter program; - [%expect - {| - type ('a, 'b) shape = - | Circle - | Square of ('a, 'b) shape - ;; |}] -;; diff --git a/OcamlADT/tests/pprinter.mli b/OcamlADT/tests/pprinter.mli deleted file mode 100644 index d2293a6d1..000000000 --- a/OcamlADT/tests/pprinter.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val test_pprint_expression : Ocamladt_lib.Ast.Expression.t -> unit diff --git a/OcamlADT/tests/repl.t b/OcamlADT/tests/repl.t deleted file mode 100644 index 001fada90..000000000 --- a/OcamlADT/tests/repl.t +++ /dev/null @@ -1,152 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - - $ ../bin/interpret.exe manytests/typed/001fac.ml - Running... - 24 - val fac : int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/002fac.ml - Running... - 24 - val fac_cps : int -> (int -> 'a) -> 'a = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/003fib.ml - Running... - 3 - 3 - val fib_acc : int -> int -> int -> int = - val fib : int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/004manyargs.ml - Running... - 1111111111 - 1 - 10 - 100 - val wrap : 'a -> 'a = - val test3 : int -> int -> int -> int = - val test10 : int -> int -> int -> int -> int -> int -> int -> int -> int -> int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/005fix.ml - Running... - 720 - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = - val fac : (int -> int) -> int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/006partial.ml - Running... - 1122 - val foo : int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/006partial2.ml - Running... - 1 - 2 - 3 - 7 - val foo : int -> int -> int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/006partial3.ml - Running... - 4 - 8 - 9 - val foo : int -> int -> int -> unit = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/007order.ml - Running... - 1 - 2 - 4 - -1 - 103 - -555555 - 10000 - val _start : unit -> unit -> int -> unit -> int -> int -> unit -> int -> int -> int = - val main : unit = "" - - $ ../bin/interpret.exe manytests/typed/008ascription.ml - Running... - 8 - val addi : ('a -> bool -> int) -> ('a -> bool) -> 'a -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/009let_poly.ml - Running... - val temp : int * bool = (1, true) - - $ ../bin/interpret.exe manytests/typed/010sukharev.ml - Running... - val _1 : int -> int -> int * 'a -> bool = - val _2 : int = 1 - val _3 : (int * string) option = Some (1, "hi") - val _4 : int -> 'a = - val _5 : int = 42 - val _6 : 'a option -> 'a = - val int_of_option : int option -> int = - val _42 : int -> bool = - val id1 : 'a -> 'a = - val id2 : 'b -> 'b = - - $ ../bin/interpret.exe manytests/typed/015tuples.ml - Running... - 1 - 1 - 1 - 1 - val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = - val map : ('a -> 'b) -> 'a * 'a -> 'b * 'b = - val fixpoly : (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) * (('a -> 'b) * ('a -> 'b) -> 'a -> 'b) -> ('a -> 'b) * ('a -> 'b) = - val feven : 'a * (int -> int) -> int -> int = - val fodd : (int -> int) * 'a -> int -> int = - val tie : (int -> int) * (int -> int) = (, ) - val meven : int -> int = - val modd : int -> int = - val main : int = 0 - - $ ../bin/interpret.exe manytests/typed/016lists.ml - Running... - 1 - 2 - 3 - 8 - val length : 'a list -> int = - val length_tail : 'a list -> int = - val map : ('a -> 'b) -> 'a list -> 'b list = - val append : 'a list -> 'a list -> 'a list = - val concat : 'a list list -> 'a list = - val iter : ('a -> unit) -> 'a list -> unit = - val cartesian : 'a list -> 'b list -> ('a * 'b) list = - val main : int = 0 - - - $ ../bin/interpret.exe manytests/do_not_type/001.ml - Running... - Type error: Unbound_variable: "fac" - - $ ../bin/interpret.exe manytests/do_not_type/002if.ml - Running... - Type error: Unification_failed: int # bool - $ ../bin/interpret.exe manytests/do_not_type/003occurs.ml - Running... - Type error: Occurs_check: 'c and 'c -> 'b - - $ ../bin/interpret.exe manytests/do_not_type/004let_poly.ml - Running... - Type error: Unification_failed: int # bool - $ ../bin/interpret.exe manytests/do_not_type/015tuples.ml - Running... - Type error: Wrong right value in rec - $ ../bin/interpret.exe manytests/do_not_type/099.ml - Running... - Type error: Wrong right value in rec diff --git a/OcamlADT/tests/unittests/expressiont.ml b/OcamlADT/tests/unittests/expressiont.ml deleted file mode 100644 index e6c112ddb..000000000 --- a/OcamlADT/tests/unittests/expressiont.ml +++ /dev/null @@ -1,109 +0,0 @@ -(** Copyright 2024-2025, Rodion Suvorov, Mikhail Gavrilenko *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ocamladt_lib.Parser -open Ocamladt_lib.Ast -open Pprinter - -let%expect_test "parse_lambda_fun" = - pp pp_expression pexpr "fun x y -> x * y"; - [%expect - {| - (Exp_fun (((Pat_var "x"), [(Pat_var "y")]), - (Exp_apply ((Exp_ident "*"), - ((Exp_tuple ((Exp_ident "x"), (Exp_ident "y"), [])), []))) - )) |}] -;; - -let%expect_test "parse_apply_to_const" = - pp pp_expression pexpr "f 5"; - [%expect - {| - (Exp_apply ((Exp_ident "f"), ((Exp_constant (Const_integer 5)), []))) |}] -;; - -let%expect_test "parse_apply_to_const_par" = - pp pp_expression pexpr "f(5)"; - [%expect - {| - (Exp_apply ((Exp_ident "f"), ((Exp_constant (Const_integer 5)), []))) |}] -;; - -let%expect_test "parse_apply_to_var" = - pp pp_expression pexpr "f x"; - [%expect {| - (Exp_apply ((Exp_ident "f"), ((Exp_ident "x"), []))) |}] -;; - -let%expect_test "" = - pp pp_expression pexpr "fun x y -> x * y"; - [%expect - {| - (Exp_fun (((Pat_var "x"), [(Pat_var "y")]), - (Exp_apply ((Exp_ident "*"), - ((Exp_tuple ((Exp_ident "x"), (Exp_ident "y"), [])), []))) - )) |}] -;; - -let%expect_test "parse_function_pattern_matching" = - pp pp_expression pexpr "function | x -> true | y -> false"; - [%expect {| - Syntax error |}] -;; - -let%expect_test "parse_if_then_else_stmt" = - pp pp_expression pexpr "if a = 3 then 5 else x - 1"; - [%expect - {| - (Exp_if ( - (Exp_apply ((Exp_ident "="), - ((Exp_tuple ((Exp_ident "a"), (Exp_constant (Const_integer 3)), [])), - []) - )), - (Exp_constant (Const_integer 5)), - (Some (Exp_apply ((Exp_ident "-"), - ((Exp_tuple - ((Exp_ident "x"), (Exp_constant (Const_integer 1)), [])), - []) - ))) - )) |}] -;; - -let%expect_test "parse_if_then_stmt" = - pp pp_expression pexpr "if x < 5 then f(5)"; - [%expect - {| - (Exp_if ( - (Exp_apply ((Exp_ident "<"), - ((Exp_tuple ((Exp_ident "x"), (Exp_constant (Const_integer 5)), [])), - []) - )), - (Exp_apply ((Exp_ident "f"), ((Exp_constant (Const_integer 5)), []))), - None)) |}] -;; - -let%expect_test "parse_let_rec" = - pp pp_expression pexpr "let rec a = 2 in z"; - [%expect - {| - (Exp_let (Recursive, - ({ pat = (Pat_var "a"); expr = (Exp_constant (Const_integer 2)) }, []), - (Exp_ident "z"))) |}] -;; - -let%expect_test "parse_mul_let" = - pp pp_expression pexpr "let a = 2 and g = 7"; - [%expect {| - Syntax error |}] -;; - -let%expect_test "parse_match" = - pp pp_expression pexpr "match q with a -> h | h -> a"; - [%expect - {| - (Exp_match ((Exp_ident "q"), - ({ left = (Pat_var "a"); right = (Exp_ident "h") }, - [{ left = (Pat_var "h"); right = (Exp_ident "a") }]) - )) |}] -;; diff --git a/OcamlBR/.envrc b/OcamlBR/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/OcamlBR/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/OcamlBR/.gitignore b/OcamlBR/.gitignore deleted file mode 100644 index 5bd251038..000000000 --- a/OcamlBR/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs -.DS_Store -**/.DS_Store diff --git a/OcamlBR/.ocamlformat b/OcamlBR/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/OcamlBR/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/OcamlBR/.zanuda b/OcamlBR/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/OcamlBR/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/OcamlBR/COPYING b/OcamlBR/COPYING deleted file mode 100644 index f288702d2..000000000 --- a/OcamlBR/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OcamlBR/COPYING.CC0 b/OcamlBR/COPYING.CC0 deleted file mode 100644 index 0e259d42c..000000000 --- a/OcamlBR/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/OcamlBR/COPYING.LESSER b/OcamlBR/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/OcamlBR/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/OcamlBR/Makefile b/OcamlBR/Makefile deleted file mode 100644 index 79fbb624c..000000000 --- a/OcamlBR/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -.PHONY: repl tests test fmt lint celan - -all: - dune build - -repl: - dune build ./REPL.exe && rlwrap _build/default/REPL.exe - -tests: test -test: - dune runtest - -celan: clean -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/OcamlBR/OcamlBR.opam b/OcamlBR/OcamlBR.opam deleted file mode 100644 index e70defdc4..000000000 --- a/OcamlBR/OcamlBR.opam +++ /dev/null @@ -1,41 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for a subset of OCaml with bidirectional records" -description: - "An interpreter for a subset of OCaml with bidirectional records" -maintainer: [ - "Sofya Kozyreva " - "Maksim Shipilov " -] -authors: [ - "Sofya Kozyreva " - "Maksim Shipilov " -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/sofyak0zyreva/OcamlBR" -bug-reports: "https://github.com/sofyak0zyreva/OcamlBR" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_deriving" - "ppx_deriving_qcheck" - "bisect_ppx" - "odoc" {with-doc} - "ocamlformat" {build} - "qcheck-core" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] diff --git a/OcamlBR/bin/astEx.ml b/OcamlBR/bin/astEx.ml deleted file mode 100644 index 7c5a36a8f..000000000 --- a/OcamlBR/bin/astEx.ml +++ /dev/null @@ -1,25 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) -(* - open OCamlBR.Ast - - let () = - let fact_ast : expr = - Elet - ( Recursive - , "factorial" - , Evar "n" - , Eif_then_else - ( Ebin_op (Eq, Evar "n", Econst (Int 0)) - , Econst (Int 1) - , Some - (Ebin_op - ( Mult - , Evar "n" - , Efun_application - (Evar "factorial", Ebin_op (Sub, Evar "n", Econst (Int 1))) )) ) ) - in - print_endline (show_expr fact_ast) - ;; -*) diff --git a/OcamlBR/bin/dune b/OcamlBR/bin/dune deleted file mode 100644 index 32e7e50aa..000000000 --- a/OcamlBR/bin/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name astEx) - (public_name OCamlBR_ast) - (libraries OCamlBR) - (instrumentation - (backend bisect_ppx))) diff --git a/OcamlBR/dune b/OcamlBR/dune deleted file mode 100644 index fb27f6ecc..000000000 --- a/OcamlBR/dune +++ /dev/null @@ -1,10 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) - -(cram - (deps ./repl/repl.exe)) diff --git a/OcamlBR/dune-project b/OcamlBR/dune-project deleted file mode 100644 index c40573ad3..000000000 --- a/OcamlBR/dune-project +++ /dev/null @@ -1,39 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors - "Sofya Kozyreva " - "Maksim Shipilov ") - -(maintainers - "Sofya Kozyreva " - "Maksim Shipilov ") - -(bug_reports "https://github.com/sofyak0zyreva/OcamlBR") - -(homepage "https://github.com/sofyak0zyreva/OcamlBR") - -(package - (name OcamlBR) - (synopsis "An interpreter for a subset of OCaml with bidirectional records") - (description - "An interpreter for a subset of OCaml with bidirectional records") - ;(documentation "https://kakadu.github.io/fp2024/docs/OcamlBR") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_deriving - ppx_deriving_qcheck - bisect_ppx - (odoc :with-doc) - (ocamlformat :build) - qcheck-core - ; base - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/OcamlBR/lib/ast.ml b/OcamlBR/lib/ast.ml deleted file mode 100644 index 3e63fd1e5..000000000 --- a/OcamlBR/lib/ast.ml +++ /dev/null @@ -1,238 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Typedtree - -let gen_id_name = - let open QCheck.Gen in - let varname = - let first_char = oneof [ char_range 'a' 'z'; return '_' ] in - let rest_char = - frequency - [ 26, char_range 'a' 'z' - ; 26, char_range 'A' 'Z' - ; 10, char_range '0' '9' - ; 1, return '_' - ; 1, return '\'' - ] - in - (* limit the total length to 15 characters *) - let gen_rest = string_size ~gen:rest_char (int_range 1 14) in - (* combine the first character with the generated rest part *) - map2 (fun start rest -> String.make 1 start ^ rest) first_char gen_rest - in - let is_keyword = function - | "let" - | "in" - | "fun" - | "rec" - | "if" - | "then" - | "else" - | "true" - | "false" - | "Some" - | "None" - | "and" - | "match" - | "with" -> true - | _ -> false - in - (* unallow varname same as keyword *) - varname >>= fun name -> if is_keyword name then varname else return name -;; - -type id = Id of string [@@deriving show { with_path = false }] - -let gen_id = QCheck.Gen.map (fun name -> Id name) gen_id_name - -type const = - | Int of (int[@gen QCheck.Gen.int_range 0 1000]) - | String of - (string - [@gen - QCheck.Gen.( - let printable_without_quotes_and_backslash = - oneof - [ char_range '\032' '!' (* characters before '"' *) - ; char_range '#' '[' (* characters after '"' but before '\' *) - ; char_range ']' '\126' (* characters after '\' *) - ] - in - string_size ~gen:printable_without_quotes_and_backslash (0 -- 20))]) - (* remove double quote character and backslash *) - | Bool of (bool[@gen QCheck.Gen.bool]) - | Unit -(* language constants of type int, string, bool, and unit respectively *) -[@@deriving show { with_path = false }, qcheck] - -type bin_op = - | Add (* addition of two ints *) - | Mult (* multiplication of two ints *) - | Sub (* subtraction of two ints *) - | Div (* division of two ints *) - | Gt (* greater than *) - | Lt (* less than *) - | Eq (* equal *) - | Neq (* not equal *) - | Gte (* greater than or equal *) - | Lte (* less than or equal *) - | And (* logical AND *) - | Or (* logical OR *) - | Cons (* :: *) -[@@deriving show { with_path = false }, qcheck] - -type un_op = - | Negative - | Positive - | Not -(* unary minus, logical NOT *) -[@@deriving show { with_path = false }, qcheck] - -type rec_flag = - | Recursive - | Non_recursive -(* flag for let expressions *) -[@@deriving show { with_path = false }, qcheck] - -let divisor = 30 - -type pattern = - | PVar of id - | PConst of const - | PTuple of - (pattern[@gen gen_pattern_sized (n / divisor)]) - * (pattern[@gen gen_pattern_sized (n / divisor)]) - * (pattern list - [@gen QCheck.Gen.(list_size (0 -- 4) (gen_pattern_sized (n / divisor)))]) - | PAny (* wildcard pattern '_' *) - | PList of - (pattern list - [@gen QCheck.Gen.(list_size (0 -- 4) (gen_pattern_sized (n / divisor)))]) - | PCons of - (pattern[@gen gen_pattern_sized (n / divisor)]) - * (pattern[@gen gen_pattern_sized (n / divisor)]) - | POption of (pattern[@gen gen_pattern_sized (n / divisor)]) option - | PConstraint of (pattern[@gen gen_pattern_sized (n / divisor)]) * (ty[@gen gen_tprim]) -[@@deriving show { with_path = false }, qcheck] - -(* type label = Label of string [@@deriving show { with_path = false }] - - let gen_label = QCheck.Gen.map (fun name -> Label name) gen_id_name *) - -type expr = - | Econst of const (* constants, e.g. 10, "meow", true *) - | Evar of id (* identifiers, e.g. "x", "f"*) - (* maybe later switch to id, or even now *) - | Eif_then_else of - (expr[@gen gen_expr_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) option - (* if E0 then E1 else E2; else expression is optional *) - | Eoption of - (expr[@gen gen_expr_sized (n / divisor)]) option (* option type, Some e, None *) - | Etuple of - (expr[@gen gen_expr_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) - * (expr list[@gen QCheck.Gen.(list_size (0 -- 4) (gen_expr_sized (n / divisor)))]) - (* expressions (E0, .., En), n >= 2 *) - (* or expr * expr * expr list, cause invariant n >= 2 *) - | Elist of - (expr list[@gen QCheck.Gen.(list_size (0 -- 4) (gen_expr_sized (n / divisor)))]) - (* expressions [E0; ..; En], n >= 0 *) - | Ebin_op of - bin_op - * (expr[@gen gen_expr_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) - (** match E with P1 -> E1 ... Pn -> Pn *) - (* E0 bin_op E1, e.g. 1 + 3 *) - | Ematch of - (expr[@gen gen_expr_sized (n / divisor)]) - * (case[@gen gen_case_sized (n / divisor)]) - * (case list[@gen QCheck.Gen.(list_size (0 -- 4) (gen_case_sized (n / divisor)))]) - | Efunction of - (case[@gen gen_case_sized (n / divisor)]) - * (case list[@gen QCheck.Gen.(list_size (0 -- 4) (gen_case_sized (n / divisor)))]) - | Eun_op of un_op * (expr[@gen gen_expr_sized (n / divisor)]) - (* E0 un_op E1, e.g. Negative 2, Not true *) - | Elet of - rec_flag - * (value_binding[@gen gen_value_binding_sized (n / divisor)]) - * (value_binding list - [@gen QCheck.Gen.(list_size (0 -- 4) (gen_value_binding_sized (n / divisor)))]) - * (expr[@gen gen_expr_sized (n / divisor)]) - (* let (rec) P1 = E1 and P2 = E2 and ... and Pn = En in E, e.g. let x = 5 in x - 10 *) - | Efun_application of - (expr[@gen gen_expr_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) - (* E0 E1, e.g. f x *) - | Efun of - (pattern[@gen gen_pattern_sized (n / divisor)]) - * (pattern list - [@gen QCheck.Gen.(list_size (0 -- 4) (gen_pattern_sized (n / divisor)))]) - * (expr[@gen gen_expr_sized (n / divisor)]) - (* anonymous functions, e.g. fun x y -> x + 1 - y, arguments num >= 1 *) - | Econstraint of (expr[@gen gen_expr_sized (n / divisor)]) * (ty[@gen gen_tprim]) -(* | Efield_access of (expr[@gen gen_expr_sized (n / divisor)]) * label *) -(* m.aa *) -(* | Erecord of - (record_field[@gen gen_record_field_sized (n / divisor)]) - * (record_field list - [@gen QCheck.Gen.(list_size (0 -- 4) (gen_record_field_sized (n / divisor)))]) *) -(* let m = { aa = 5; bb = true } *) -[@@deriving show { with_path = false }, qcheck] - -and case = - | Ecase of - (pattern[@gen gen_pattern_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) -[@@deriving show { with_path = false }, qcheck] - -and value_binding = - | Evalue_binding of - (pattern[@gen gen_pattern_sized (n / divisor)]) - * (expr[@gen gen_expr_sized (n / divisor)]) -[@@deriving show { with_path = false }, qcheck] - -(* and record_field = Erecord_field of label * (expr[@gen gen_expr_sized (n / divisor)]) - [@@deriving show { with_path = false }, qcheck] *) - -let gen_expr = - QCheck.Gen.( - let* n = small_nat in - gen_expr_sized n) -;; - -let gen_value_binding = - QCheck.Gen.( - let* n = small_nat in - gen_value_binding_sized n) -;; - -(* let gen_record_field = - QCheck.Gen.( - let* n = small_nat in - gen_record_field_sized n) - ;; *) - -type structure_item = - | SEval of expr - | SValue of - rec_flag - * (value_binding[@gen gen_value_binding]) - * (value_binding list[@gen QCheck.Gen.(list_size (0 -- 4) gen_value_binding)]) -(* let (rec) P1 = E1 and P2 = E2 and ... and Pn = En e.g. let x = 5 *) -(* | SType of - (string[@gen gen_id_name]) - * (field_decl[@gen gen_field_decl]) - * (field_decl list[@gen QCheck.Gen.(list_size (0 -- 4) gen_field_decl)]) *) -(* type t = { aa : int ; bb : bool } *) -[@@deriving show { with_path = false }, qcheck] - -(* and field_decl = Sfield_decl of label * (ty[@gen gen_tprim]) - [@@deriving show { with_path = false }, qcheck] *) - -type structure = - (structure_item list[@gen QCheck.Gen.(list_size (1 -- 2) gen_structure_item)]) -[@@deriving show { with_path = false }, qcheck] diff --git a/OcamlBR/lib/ast.mli b/OcamlBR/lib/ast.mli deleted file mode 100644 index 44ed1569e..000000000 --- a/OcamlBR/lib/ast.mli +++ /dev/null @@ -1,98 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type id = Id of string (** identifier *) - -val show_id : id -> string - -type const = - | Int of int (** integer constant, e.g. 1 *) - | String of string (** string constant, e.g. "hello" *) - | Bool of bool (** boolean constant, e.g. true *) - | Unit (** unit constant, e.g. () *) - -(** language constants of type int, string, bool, and unit respectively *) -val show_const : const -> string - -type bin_op = - | Add (** addition of two ints *) - | Mult (** multiplication of two ints *) - | Sub (** subtraction of two ints *) - | Div (** division of two ints *) - | Gt (** greater than *) - | Lt (** less than *) - | Eq (** equal *) - | Neq (** not equal *) - | Gte (** greater than or equal *) - | Lte (** less than or equal *) - | And (** logical AND *) - | Or (** logical OR *) - | Cons (** :: *) - -val show_bin_op : bin_op -> string - -type un_op = - | Negative (** arithmetic unary - *) - | Positive (** arithmetic unary + *) - | Not (** logical not *) - -val show_un_op : un_op -> string - -(** flag for let expressions *) -type rec_flag = - | Recursive (** rec value *) - | Non_recursive (** plain value *) - -val show_rec_flag : rec_flag -> string - -type pattern = - | PVar of id (** variable pattern, e.g. x *) - | PConst of const (** pattern of a constant *) - | PTuple of pattern * pattern * pattern list (** patterns (P0, .., Pn), n >= 2 *) - | PAny (** wildcard pattern '_' *) - | PList of pattern list (** patterns [P0; ..; Pn], n >= 0 *) - | PCons of pattern * pattern (** P0 :: P1 :: .. :: Pn, n>= 2 *) - | POption of pattern option (** Some p, None *) - | PConstraint of pattern * Typedtree.ty (** P : T *) - -val show_pattern : pattern -> string - -type expr = - | Econst of const (** constants, e.g. 10, "meow", true *) - | Evar of id (** identifiers, e.g. "x", "f"*) - | Eif_then_else of expr * expr * expr option - (** if E0 then E1 else E2; else expression is optional *) - | Eoption of expr option (** option type, Some e, None *) - | Etuple of expr * expr * expr list (** expressions (E0, .., En), n >= 2 *) - | Elist of expr list (** expressions [E0; ..; En], n >= 0 *) - | Ebin_op of bin_op * expr * expr (** E0 bin_op E1, e.g. 1 + 3 *) - | Ematch of expr * case * case list (** match E with P1 -> E1 ... Pn -> Pn *) - | Efunction of case * case list (** function P1 -> E1 ... Pn -> Pn *) - | Eun_op of un_op * expr (** E0 un_op E1, e.g. Negative 2, Not true *) - | Elet of rec_flag * value_binding * value_binding list * expr - (** let (rec) P1 = E1 and P2 = E2 and ... and Pn = En in E, e.g. let x = 5 in x - 10 *) - | Efun_application of expr * expr (** E0 E1, e.g. f x *) - | Efun of pattern * pattern list * expr - (** anonymous functions, e.g. fun x y -> x + 1 - y, arguments num >= 1 *) - | Econstraint of expr * Typedtree.ty (** E : T *) - -and case = Ecase of pattern * expr (** pattern-matching case, e.g. | P -> E *) -and value_binding = Evalue_binding of pattern * expr (** P = E *) - -val show_expr : expr -> string -val show_case : case -> string -val show_value_binding : value_binding -> string - -type structure_item = - | SEval of expr (** plain expression E *) - | SValue of rec_flag * value_binding * value_binding list - (** let (rec) P1 = E1 and P2 = E2 and ... and Pn = En e.g. let x = 5 *) - -val show_structure_item : structure_item -> string - -type structure = structure_item list - -val show_structure : structure -> string -val gen_structure : structure QCheck.Gen.t -val arb_structure : structure QCheck.arbitrary diff --git a/OcamlBR/lib/dune b/OcamlBR/lib/dune deleted file mode 100644 index 099090d46..000000000 --- a/OcamlBR/lib/dune +++ /dev/null @@ -1,28 +0,0 @@ -(library - (name OCamlBR) - (public_name OcamlBR) - (modules - Ast - Parser - Parser_tests - Pr_printer - Pr_printer_tests - Qcheck - Typedtree - Inferencer - Inferencer_tests - Values - Interpreter - Interpreter_tests) - (libraries base angstrom qcheck-core qcheck-core.runner) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_deriving.show ppx_inline_test ppx_expect ppx_deriving_qcheck)) - (inline_tests)) - -(executable - (name run_qcheck) - (public_name run_qcheck) - (modules run_qcheck) - (libraries OcamlBR)) diff --git a/OcamlBR/lib/inferencer.ml b/OcamlBR/lib/inferencer.ml deleted file mode 100644 index 5fc535ca1..000000000 --- a/OcamlBR/lib/inferencer.ml +++ /dev/null @@ -1,805 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Typedtree - -module R : sig - type 'a t - - val return : 'a -> 'a t - val fail : error -> 'a t - - include Base.Monad.Infix with type 'a t := 'a t - - module Syntax : sig - val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t - end - - module RList : sig - val fold_left : 'a list -> init:'b t -> f:('b -> 'a -> 'b t) -> 'b t - val fold_right : 'a list -> init:'b t -> f:('a -> 'b -> 'b t) -> 'b t - end - - module RMap : sig - val fold_left - : ('a, 'b, 'c) Base.Map.t - -> init:'d t - -> f:('a -> 'b -> 'd -> 'd t) - -> 'd t - end - - val fresh : int t - val run : 'a t -> ('a, error) Result.t -end = struct - type 'a t = - int -> int * ('a, error) Result.t (* a composition of result and state monad *) - - let ( >>= ) : 'a 'b. 'a t -> ('a -> 'b t) -> 'b t = - fun m f state -> - let last, res = m state in - match res with - | Result.Error x -> - last, Error x (* if the first computation (m) fails, propagate the error *) - | Result.Ok a -> - f a last (* if it succeeds, pass the result (a) to the next computation (f) *) - ;; - - (* wraps a value x into the monad without modifying the state. It returns the current state (last) and a successful result (Ok x) *) - let return x last = last, Base.Result.return x - - (* creates a failed monadic computation, propagating the error (e) while leaving the state unchanged *) - let fail e st = st, Base.Result.fail e - let bind x ~f = x >>= f - - let ( >>| ) : 'a 'b. 'a t -> ('a -> 'b) -> 'b t = - fun x f st -> - match x st with - | st, Result.Ok x -> st, Ok (f x) - | st, Result.Error e -> st, Result.Error e - ;; - - (* syntatic sugar *) - module Syntax = struct - let ( let* ) x f = bind x ~f - end - - (* defines a monadic version of List.fold_left, can handle computations that may fail *) - (* e.g. for solving multiple type constraints during inference *) - module RList = struct - let fold_left xs ~init ~f = - Base.List.fold_left xs ~init ~f:(fun acc x -> - let open Syntax in - let* acc = acc in - f acc x) - ;; - - let fold_right xs ~init ~f = - let open Syntax in - Base.List.fold_right xs ~init ~f:(fun x acc -> - let* acc = acc in - f x acc) - ;; - end - - module RMap = struct - let fold_left map ~init ~f = - Base.Map.fold map ~init ~f:(fun ~key ~data acc -> - let open Syntax in - let* acc = acc in - f key data acc) - ;; - end - - (* generates new state for representing a new fresh variable *) - let fresh last = last + 1, Result.Ok last - - (* runs from initial state 0 and extracts the result from the monadic computation *) - let run monad = snd (monad 0) -end - -module Type = struct - (* checks if a type variable v occurs anywhere within a given type; primarily used during type unification *) - let rec occurs_in v = function - | TVar b -> b = v - | TPrim _ -> false - | TArrow (l, r) -> occurs_in v l || occurs_in v r - | TTuple (fst, snd, rest) -> - occurs_in v fst || occurs_in v snd || List.exists (occurs_in v) rest - | TList t -> occurs_in v t - | TOption t -> occurs_in v t - ;; - - (* | TRecord _ -> false *) - - (* computes the set of all type variables in a given type; primarily used to generalize types during type inference *) - let type_vars = - let rec helper acc = function - | TVar b -> VarSet.add b acc - | TPrim _ -> acc - | TArrow (l, r) -> helper (helper acc l) r - | TList t -> helper acc t - | TTuple (fst, snd, rest) -> List.fold_left helper acc (fst :: snd :: rest) - | TOption t -> helper acc t - (* | TRecord _ -> acc *) - in - helper VarSet.empty - ;; -end - -module Subst : sig - type t - - val empty : t - val apply : t -> ty -> ty - val singleton : type_var -> ty -> t R.t - val unify : ty -> ty -> t R.t - val compose : t -> t -> t R.t - val compose_all : t list -> t R.t - val remove : t -> type_var -> t - (* val pp_subst : Format.formatter -> t -> unit *) -end = struct - open R - open R.Syntax - open Base - - type t = (type_var, ty, Int.comparator_witness) Map.t - - (* let pp_subst ppf sub = - Base.Map.iteri sub ~f:(fun ~key ~data -> - Stdlib.Format.fprintf ppf "[%d = %a] " key pp_ty data) - ;; *) - - let empty = Map.empty (module Int) - - (* creates a substitution for variable [v] with type [ty] if no occurence is found *) - let mapping v ty = - if Type.occurs_in v ty - then fail (`Occurs_check ("type variable " ^ Int.to_string v ^ " inside type", ty)) - else return (v, ty) - ;; - - let singleton k v = - let* k, v = mapping k v in - return (Base.Map.singleton (module Base.Int) k v) - ;; - - let find = Map.find - let remove = Map.remove - - (* applies a substitution to a type *) - let apply subst = - let rec helper = function - | TVar v as ty -> - (match find subst v with - | Some ty' -> ty' - | None -> ty) - | TArrow (l, r) -> TArrow (helper l, helper r) - | TTuple (f, s, rest) -> TTuple (helper f, helper s, List.map ~f:helper rest) - | TList t -> TList (helper t) - | TPrim _ as ty -> ty - | TOption t -> TOption (helper t) - (* | TRecord _ as ty -> ty *) - in - helper - ;; - - (* attempts to unify two types [ty1] and [ty2], returning a substitution *) - let rec unify ty1 ty2 = - match ty1, ty2 with - | TPrim l, TPrim r when String.equal l r -> return empty - | TVar v1, TVar v2 when v1 = v2 -> return empty - | TVar v, ty | ty, TVar v -> singleton v ty - | TArrow (l1, r1), TArrow (l2, r2) -> - let* subs1 = unify l1 l2 in - let* subs2 = unify (apply subs1 r1) (apply subs1 r2) in - compose subs1 subs2 - | TTuple (f1, s1, rest1), TTuple (f2, s2, rest2) -> - let* rest_unified = - match List.map2 (f1 :: s1 :: rest1) (f2 :: s2 :: rest2) ~f:unify with - | Unequal_lengths -> - fail (`Unification_failed (TTuple (f1, s1, rest1), TTuple (f2, s2, rest2))) - | Ok res -> return res - in - List.fold_left rest_unified ~init:(return empty) ~f:(fun acc s -> - let* s = s in - let* acc = acc in - compose acc s) - | TList t1, TList t2 -> unify t1 t2 - | TOption t1, TOption t2 -> unify t1 t2 - (* | TRecord n1, TRecord n2 when String.equal n1 n2 -> return empty *) - | _, _ -> fail (`Unification_failed (ty1, ty2)) - - (* extends a substitution with a new mapping for variable [v] *) - and extend v ty subst = - match Map.find subst v with - | None -> - let ty = apply subst ty in - let* new_subs = singleton v ty in - let upd ~key ~data acc = - let* acc = acc in - let ty = apply new_subs data in - return (Map.update acc key ~f:(function _ -> ty)) - in - Map.fold subst ~init:(return new_subs) ~f:upd - | Some existing_ty -> - let* new_subs = unify ty existing_ty in - compose subst new_subs - - and compose s1 s2 = RMap.fold_left s2 ~init:(return s1) ~f:extend - - let compose_all subs_list = RList.fold_left subs_list ~init:(return empty) ~f:compose -end - -module VarSet = struct - include VarSet - - let fold_left_m f acc set = - fold - (fun x acc -> - let open R.Syntax in - let* acc = acc in - f acc x) - acc - set - ;; -end - -module Scheme = struct - (* let occurs_in v = function - | S (xs, t) -> (not (VarSet.mem v xs)) && Type.occurs_in v t - ;; *) - - let free_vars = function - | S (bs, t) -> VarSet.diff (Type.type_vars t) bs - ;; - - let apply sub (S (names, ty)) = - let s2 = VarSet.fold (fun k s -> Subst.remove s k) names sub in - S (names, Subst.apply s2 ty) - ;; - - (* let pp = pp_scheme *) -end - -module RecordEnv = struct - open Base - - type t = (string, (string * ty) list, String.comparator_witness) Map.t - - let empty : t = Map.empty (module String) -end - -module TypeEnv = struct - open Base - - type t = (string, scheme, String.comparator_witness) Map.t - - let empty = Map.empty (module String) - - let free_vars env = - Map.fold env ~init:VarSet.empty ~f:(fun ~key:_ ~data:s acc -> - VarSet.union acc (Scheme.free_vars s)) - ;; - - let apply s env = Map.map env ~f:(Scheme.apply s) - let extend key s env = Map.update env key ~f:(fun _ -> s) - - let extend_many list env = - List.fold list ~init:env ~f:(fun env (key, v) -> extend key v env) - ;; - - let find = Map.find - - let merge_envs subst acc_env env_pat = - let acc_env = apply subst acc_env in - let env_pat = apply subst env_pat in - Map.fold env_pat ~init:acc_env ~f:(fun ~key ~data acc_env -> extend key data acc_env) - ;; - - let remove = Map.remove - - let find_type_exn env key = - match Map.find_exn env key with - | S (_, typ) -> typ - ;; - - let pp ppf env = - Stdlib.Format.fprintf ppf "{| "; - Map.iteri env ~f:(fun ~key:name ~data:scheme -> - Stdlib.Format.fprintf ppf "%s -> %a; " name pp_scheme scheme); - Stdlib.Format.fprintf ppf "|}" - ;; -end - -module Infer = struct - open R - open R.Syntax - - let unify = Subst.unify - let fresh_var = fresh >>| fun n -> TVar n - - let instantiate : scheme -> ty R.t = - fun (S (bs, t)) -> - VarSet.fold_left_m - (fun typ name -> - let* f1 = fresh_var in - let* s = Subst.singleton name f1 in - return (Subst.apply s typ)) - bs - (return t) - ;; - - let generalize (env : TypeEnv.t) (ty : ty) : scheme = - let free = VarSet.diff (Type.type_vars ty) (TypeEnv.free_vars env) in - S (free, ty) - ;; - - let lookup_env e xs = - match TypeEnv.find xs e with - | None -> fail (`Undefined_variable e) - | Some scheme -> - let* ans = instantiate scheme in - return (Subst.empty, ans) - ;; - - let string_of_id (Ast.Id name) = name - - let infer_const = function - | Ast.Int _ -> tprim_int - | Ast.Bool _ -> tprim_bool - | Ast.String _ -> tprim_string - | Ast.Unit -> tprim_unit - ;; - - let rec infer_pattern env = function - | Ast.PVar id -> - let var_name = string_of_id id in - let* fresh = fresh_var in - let extended_env = TypeEnv.extend var_name (S (VarSet.empty, fresh)) env in - return (Subst.empty, fresh, extended_env) - | Ast.PAny -> - let* fresh = fresh_var in - return (Subst.empty, fresh, env) - | Ast.PConst c -> - let fresh = infer_const c in - return (Subst.empty, fresh, env) - | Ast.PTuple (p1, p2, pl) -> - let* sub1, typ1, env1 = infer_pattern env p1 in - let* sub2, typ2, env2 = infer_pattern (TypeEnv.apply sub1 env1) p2 in - let f1 (pat : Ast.pattern) (sub_prev, l, env) = - let* sub_cur, arg, env = infer_pattern env pat in - let* sub = Subst.compose sub_prev sub_cur in - return (sub, arg :: l, env) - in - let* sub, arg, env = RList.fold_right pl ~init:(return (sub2, [], env2)) ~f:f1 in - return (sub, TTuple (typ1, typ2, arg), env) - | Ast.PList pats -> - let* fresh_el_type = fresh_var in - let f1 (sub_acc, env_acc) pat = - let* sub_cur, el_type, env_cur = infer_pattern env_acc pat in - let* unified_sub = Subst.compose sub_acc sub_cur in - let* final_sub = Subst.unify (Subst.apply sub_cur fresh_el_type) el_type in - let combined_sub = Subst.compose unified_sub final_sub in - let* combined_sub = combined_sub in - return (combined_sub, TypeEnv.apply final_sub env_cur) - in - let* final_sub, final_env = - RList.fold_left pats ~init:(return (Subst.empty, env)) ~f:f1 - in - return (final_sub, TList (Subst.apply final_sub fresh_el_type), final_env) - | Ast.PCons (p1, p2) -> - let* sub1, typ1, env1 = infer_pattern env p1 in - let* _, typ2, env2 = infer_pattern (TypeEnv.apply sub1 env1) p2 in - let* subst = Subst.unify typ2 (TList typ1) in - let env = TypeEnv.apply subst env2 in - return (subst, Subst.apply subst typ2, env) - | Ast.POption None -> - let* fresh = fresh_var in - return (Subst.empty, TOption fresh, env) - | Ast.POption (Some p) -> - let* sub, typ, env = infer_pattern env p in - return (sub, TOption typ, env) - | Ast.PConstraint (pat, typ) -> - let* s, t, env = infer_pattern env pat in - let typ = Subst.apply s typ in - let* subst = unify typ t in - return (subst, Subst.apply subst typ, TypeEnv.apply subst env) - ;; - - let validate_let_rec_lhs pat = - match pat with - | Ast.PVar _ -> return pat - | _ -> fail (`Ill_left_hand_side ": only variables are allowed") - ;; - - let validate_let_rec_rhs expr = - match expr with - | Ast.Efun _ -> return expr - | _ -> fail (`Ill_right_hand_side "of let rec") - ;; - - let rec infer env record_env (expr : Ast.expr) : (Subst.t * ty) R.t = - match expr with - | Evar (Id x) -> lookup_env x env - | Econst (Int _) -> return (Subst.empty, tprim_int) - | Econst (Bool _) -> return (Subst.empty, tprim_bool) - | Econst (String _) -> return (Subst.empty, tprim_string) - | Econst Unit -> return (Subst.empty, tprim_unit) - | Ebin_op (op, e1, e2) -> - let* s1, t1 = infer env record_env e1 in - let* s2, t2 = infer (TypeEnv.apply s1 env) record_env e2 in - let* e1t, e2t, et = - match op with - | Mult | Div | Add | Sub -> return (tprim_int, tprim_int, tprim_int) - | Eq | Neq | Lt | Lte | Gt | Gte -> - let* fresh = fresh_var in - return (fresh, fresh, tprim_bool) - | And | Or -> return (tprim_bool, tprim_bool, tprim_bool) - | Cons -> - let* fresh = fresh_var in - return (fresh, TList fresh, TList fresh) - in - let* sub3 = Subst.unify (Subst.apply s2 t1) e1t in - let* sub4 = Subst.unify (Subst.apply sub3 t2) e2t in - let* sub = Subst.compose_all [ s1; s2; sub3; sub4 ] in - return (sub, Subst.apply sub et) - | Eun_op (op, e) -> - let* s, t = infer env record_env e in - let* op_type = - match op with - | Negative | Positive -> return (tprim_int @-> tprim_int) - | Not -> return (tprim_bool @-> tprim_bool) - in - let* s2 = - match op_type with - | TArrow (arg, _) -> unify t arg - | ty -> fail (`Unexpected_function_type ty) - in - let* s_final = Subst.compose_all [ s2; s ] in - (match op_type with - | TArrow (_, ret) -> return (s_final, Subst.apply s_final ret) - | ty -> fail (`Unexpected_function_type ty)) - | Eif_then_else (c, th, Some el) -> - let* s1, t1 = infer env record_env c in - let* s2, t2 = infer (TypeEnv.apply s1 env) record_env th in - let* s3, t3 = infer (TypeEnv.apply s2 env) record_env el in - let* s4 = unify t1 tprim_bool in - let* s5 = unify t2 t3 in - let* final_subst = Subst.compose_all [ s5; s4; s3; s2; s1 ] in - return (final_subst, Subst.apply final_subst t2) - | Eif_then_else (c, th, None) -> - let* s1, t1 = infer env record_env c in - let* s2, t2 = infer (TypeEnv.apply s1 env) record_env th in - let t3 = tprim_unit in - let* s4 = unify t1 tprim_bool in - let* s5 = Subst.unify t2 t3 in - let* final_subst = Subst.compose_all [ s5; s4; s2; s1 ] in - return (final_subst, Subst.apply final_subst t2) - | Elet (Non_recursive, Evalue_binding (PVar (Id x), e1), _, e2) -> - let* s1, t1 = infer env record_env e1 in - let env2 = TypeEnv.apply s1 env in - let t_gen = generalize env2 t1 in - let env3 = TypeEnv.extend x t_gen env in - let* s2, t2 = infer (TypeEnv.apply s1 env3) record_env e2 in - let* final_subst = Subst.compose s1 s2 in - return (final_subst, t2) - | Elet (Non_recursive, Evalue_binding (pattern, e1), bindings, e2) -> - let* s1, t1 = infer env record_env e1 in - let* s2, t_pat, env1 = infer_pattern env pattern in - let* subst1 = Subst.compose s1 s2 in - let* unified_subst = unify (Subst.apply subst1 t_pat) t1 in - let initial_env = TypeEnv.apply unified_subst env1 in - let* extended_env = - List.fold_left - (fun acc_env (Ast.Evalue_binding (p, expr)) -> - let* acc_env = acc_env in - let* s_bind, t_bind = infer acc_env record_env expr in - let* s_pat, t_pat, env_pat = infer_pattern acc_env p in - let* combined_subst = Subst.compose s_bind s_pat in - let* final_subst = unify (Subst.apply combined_subst t_pat) t_bind in - let updated_env = TypeEnv.merge_envs final_subst acc_env env_pat in - return updated_env) - (return initial_env) - bindings - in - let* s3, t2 = infer extended_env record_env e2 in - let* full_subst = Subst.compose_all [ s3; unified_subst; subst1 ] in - return (full_subst, t2) - | Elet (Recursive, Evalue_binding (PVar (Id x), e1), [], e2) -> - let* e1 = validate_let_rec_rhs e1 in - let* tv = fresh_var in - let env2 = TypeEnv.extend x (S (VarSet.empty, tv)) env in - let* s1, t1 = infer env2 record_env e1 in - let* s2 = unify (Subst.apply s1 tv) t1 in - let* s_final = Subst.compose s1 s2 in - let env3 = TypeEnv.apply s_final env in - let env4 = TypeEnv.apply s1 env3 in - let t_gen = generalize env4 (Subst.apply s_final tv) in - let* s3, t2 = infer (TypeEnv.extend x t_gen env4) record_env e2 in - let* s_final = Subst.compose s_final s3 in - return (s_final, t2) - | Elet (Recursive, value_binding, value_bindings, e2) -> - let* env_ext, s_acc = - List.fold_left - (fun acc_env (Ast.Evalue_binding (pattern, expr)) -> - let* expr = validate_let_rec_rhs expr in - let* pattern = validate_let_rec_lhs pattern in - let* env_acc, _ = acc_env in - let* s_expr, t_expr = infer env_acc record_env expr in - let* s_pat, t_pat, env_pat = infer_pattern env_acc pattern in - let* subst = Subst.compose s_expr s_pat in - let* unified_subst = unify t_expr t_pat in - let* combined_subst = Subst.compose subst unified_subst in - let extended_env = TypeEnv.apply combined_subst env_pat in - return (extended_env, combined_subst)) - (return (env, Subst.empty)) - (value_binding :: value_bindings) - in - let* s2, t2 = infer env_ext record_env e2 in - let* final_subst = Subst.compose s_acc s2 in - return (final_subst, t2) - | Efun (pattern, pattern_list, body) -> - let* env, pat_types = - RList.fold_left - (pattern :: pattern_list) - ~init:(return (env, [])) - ~f:(fun (env, pat_types) pat -> - let* _, typ, new_env = infer_pattern env pat in - return (new_env, typ :: pat_types)) - in - let* s_body, t_body = infer env record_env body in - let arrow_type = - List.fold_right - (fun pat_type acc -> TArrow (Subst.apply s_body pat_type, acc)) - (List.rev pat_types) - t_body - in - return (s_body, arrow_type) - | Efun_application (e1, e2) -> - let* s1, t1 = infer env record_env e1 in - let* s2, t2 = infer (TypeEnv.apply s1 env) record_env e2 in - let* tv = fresh_var in - let* s3 = unify (Subst.apply s2 t1) (TArrow (t2, tv)) in - let* s_final = Subst.compose_all [ s3; s2; s1 ] in - return (s_final, Subst.apply s_final tv) - | Eoption (Some e) -> - let* s, t = infer env record_env e in - return (s, TOption t) - | Eoption None -> - let* tv = fresh_var in - return (Subst.empty, TOption tv) - | Ematch (e, c, cl) -> - let* sub1, t1 = infer env record_env e in - let env = TypeEnv.apply sub1 env in - let* tv = fresh_var in - infer_match env record_env (c :: cl) sub1 t1 tv ~with_expr:true - | Efunction (c, cl) -> - let* t1 = fresh_var in - let* tv = fresh_var in - infer_match env record_env (c :: cl) Subst.empty t1 tv ~with_expr:false - | Etuple (e1, e2, es) -> - let* s1, t1 = infer env record_env e1 in - let* s2, t2 = infer (TypeEnv.apply s1 env) record_env e2 in - let infer_tuple_elements env es = - let rec aux env = function - | [] -> return ([], []) - | e :: es' -> - let* s, t = infer env record_env e in - let* s', ts = aux (TypeEnv.apply s env) es' in - return (s' @ [ s ], t :: ts) - in - aux env es - in - let* s3, ts = infer_tuple_elements (TypeEnv.apply s2 env) es in - let* s_final = Subst.compose_all (s3 @ [ s2; s1 ]) in - return (s_final, TTuple (t1, t2, ts)) - | Elist es -> - (match es with - | [] -> - let* fresh = fresh_var in - return (Subst.empty, tlist fresh) - | _ :: _ -> - let infer_list_elements env es = - let rec aux env = function - | [] -> return ([], []) - | e :: es' -> - let* s, t = infer env record_env e in - let* s', ts = aux (TypeEnv.apply s env) es' in - return (s' @ [ s ], t :: ts) - in - aux env es - in - let* s, ts = infer_list_elements env es in - let* s_final = Subst.compose_all s in - return (s_final, TList (List.hd ts))) - | Econstraint (e, t) -> - let* s1, t1 = infer env record_env e in - let* s2 = unify t1 (Subst.apply s1 t) in - let* s_final = Subst.compose s1 s2 in - return (s_final, Subst.apply s2 t1) - (* | Erecord (record_field, record_fields) -> - let* inferred_record_fields = - RList.fold_right - (record_field :: record_fields) - ~init:(return []) - ~f:(fun (Ast.Erecord_field (Label name, expr)) acc -> - let* _, t = infer env record_env expr in - Format.printf " %s: " name; - Format.printf " %a; \n " pp_ty t; - return ((name, t) :: acc)) - in - let* t = RecordEnv.find_record_name record_env inferred_record_fields in - Format.printf "t: %a; \n " pp_ty t; - return (Subst.empty, t) - | _ -> fail `Occurs_check *) - - and infer_match env record_env cases inferred_sub inferred_t ty_var ~with_expr = - let* s, final_t = - let f1 acc (Ast.Ecase (pat, expr)) = - let* s1, t = acc in - let f_with_expr = - let* _, pat_t, env = infer_pattern env pat in - let* subst = unify pat_t inferred_t in - let env = TypeEnv.apply subst env in - let name = - match pat with - | PVar (Id name) | POption (Some (PVar (Id name))) -> Some name - | _ -> None - in - let env = - match name with - | Some name -> - let found_t = TypeEnv.find_type_exn env name in - let env = TypeEnv.remove env name in - let t_gen = generalize env found_t in - TypeEnv.extend name t_gen env - | None -> env - in - return (env, subst) - in - let f_no_expr = - let* _, pat, env = infer_pattern env pat in - let* s2 = unify inferred_t pat in - return (env, s2) - in - let* env, s2 = if with_expr then f_with_expr else f_no_expr in - let* s3 = Subst.compose s1 s2 in - let* s4, t4 = infer (TypeEnv.apply s3 env) record_env expr in - let* s5 = unify t t4 in - let* subst = Subst.compose_all [ s3; s4; s5 ] in - return (subst, Subst.apply subst t) - in - Base.List.fold cases ~init:(return (inferred_sub, ty_var)) ~f:f1 - in - let final_t = - if with_expr then final_t else TArrow (Subst.apply s inferred_t, final_t) - in - return (s, final_t) - ;; - - (* and infer_typed_record env record_env expected_type = function - | Ast.Erecord (record_field, record_fields) -> - Format.printf "hiii \n "; - let* inferred_record_fields = - RList.fold_right - (record_field :: record_fields) - ~init:(return []) - ~f:(fun (Ast.Erecord_field (Label name, expr)) acc -> - let* _, t = infer env record_env expr in - Format.printf " %s: " name; - Format.printf " %a; \n " pp_ty t; - return ((name, t) :: acc)) - in - let* t = - RecordEnv.find_record_by_name record_env expected_type inferred_record_fields - in - Format.printf "t: %a; \n " pp_ty t; - return (Subst.empty, t) - | _ -> return (Subst.empty, TRecord expected_type) *) - - (* let infer_ty_opt env record_env t_opt expr = - match t_opt with - | Some expected_type -> - (match expected_type with - | TRecord t -> infer_typed_record env record_env t expr - | _ -> infer env record_env expr) - | None -> infer env record_env expr *) - let w expr = Result.map snd (run (infer TypeEnv.empty RecordEnv.empty expr)) - - let infer_structure_item env record_env = function - | Ast.SEval expr -> - let* subst, _ = infer env record_env expr in - let updated_env = TypeEnv.apply subst env in - return (subst, updated_env, record_env) - | Ast.SValue (Recursive, Evalue_binding (PVar (Id x), expr), []) -> - let* expr = validate_let_rec_rhs expr in - let* tv = fresh_var in - let env = TypeEnv.extend x (S (VarSet.empty, tv)) env in - let* subst, inferred_ty = infer env record_env expr in - let* subst2 = unify (Subst.apply subst tv) inferred_ty in - let* composed_subst = Subst.compose subst subst2 in - let env2 = TypeEnv.apply composed_subst env in - let generalized_ty = generalize env2 (Subst.apply composed_subst inferred_ty) in - let env = TypeEnv.extend x generalized_ty env2 in - (* Format.printf "composed_subst: %a\n" Subst.pp_subst composed_subst; *) - return (composed_subst, env, record_env) - | Ast.SValue (Recursive, value_binding, value_bindings) -> - let all_bindings = value_binding :: value_bindings in - let* env_with_placeholders = - List.fold_left - (fun acc_env (Ast.Evalue_binding (pattern, _)) -> - let* ty_pattern = validate_let_rec_lhs pattern in - let* env_acc = acc_env in - let* s_pat, _, env_pat = infer_pattern env_acc ty_pattern in - let extended_env = TypeEnv.apply s_pat env_pat in - return extended_env) - (return env) - all_bindings - in - let* env_ext, s_acc = - List.fold_left - (fun acc_env (Ast.Evalue_binding (ty_pattern, expr)) -> - let* expr = validate_let_rec_rhs expr in - let* env_acc, _ = acc_env in - let* s_expr, t_expr = infer env_acc record_env expr in - let* s_pat, t_pat, env_pat = infer_pattern env_acc ty_pattern in - let* subst = Subst.compose s_expr s_pat in - let* unified_subst = unify t_expr t_pat in - let* combined_subst = Subst.compose subst unified_subst in - let extended_env = TypeEnv.apply combined_subst env_pat in - return (extended_env, combined_subst)) - (return (env_with_placeholders, Subst.empty)) - all_bindings - in - return (s_acc, env_ext, record_env) - | Ast.SValue (Non_recursive, Evalue_binding (PVar (Id x), expr), _) -> - let* subst, inferred_ty = infer env record_env expr in - let env2 = TypeEnv.apply subst env in - let generalized_ty = generalize env2 inferred_ty in - let env = TypeEnv.extend x generalized_ty (TypeEnv.apply subst env) in - return (subst, env, record_env) - | Ast.SValue (Non_recursive, Evalue_binding (pattern, expr), _) -> - let* subst_expr, inferred_ty = infer env record_env expr in - let* subst_pat, t_pat, env_pat = infer_pattern env pattern in - let* combined_subst = - let* composed = Subst.compose subst_expr subst_pat in - return composed - in - let* unified_subst = unify (Subst.apply combined_subst t_pat) inferred_ty in - let updated_env = TypeEnv.apply unified_subst env_pat in - let* final_subst = Subst.compose unified_subst combined_subst in - return (final_subst, updated_env, record_env) - ;; - - (* | Ast.SType (record, field_decl, field_decls) -> - let fields = - List.map - (fun (Ast.Sfield_decl (Label name, t)) -> name, t) - (field_decl :: field_decls) - in - let* record_env = RecordEnv.add_record record_env record fields in - return (Subst.empty, env, record_env) *) - - let infer_structure env record_env structure = - let rec process_structure env record_env subst = function - | [] -> return (subst, env) - | item :: rest -> - let* subst', env', record_env' = infer_structure_item env record_env item in - let* composed_subst = Subst.compose subst subst' in - process_structure env' record_env' composed_subst rest - in - process_structure env record_env Subst.empty structure - ;; - - let env = - TypeEnv.extend_many - [ "print_int", S (VarSet.empty, TArrow (tprim_int, tprim_unit)) - ; "print_endline", S (VarSet.empty, TArrow (tprim_string, tprim_unit)) - ] - TypeEnv.empty - ;; - - let record_env = RecordEnv.empty - let infer_program str = Result.map snd (run (infer_structure env record_env str)) -end diff --git a/OcamlBR/lib/inferencer.mli b/OcamlBR/lib/inferencer.mli deleted file mode 100644 index 11a689e7a..000000000 --- a/OcamlBR/lib/inferencer.mli +++ /dev/null @@ -1,19 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -module TypeEnv : sig - type t - - val pp : Format.formatter -> t -> unit -end - -module Infer : sig - val w : Ast.expr -> (Typedtree.ty, Typedtree.error) result - - val infer_program - : Ast.structure - -> ( (string, Typedtree.scheme, Base.String.comparator_witness) Base.Map.t - , Typedtree.error ) - result -end diff --git a/OcamlBR/lib/inferencer_tests.ml b/OcamlBR/lib/inferencer_tests.ml deleted file mode 100644 index 615c4074a..000000000 --- a/OcamlBR/lib/inferencer_tests.ml +++ /dev/null @@ -1,136 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Inferencer.Infer -open Typedtree - -let infer_program_test s = - let open Stdlib.Format in - let open Interpreter in - match Parser.parse_expr s with - | Ok parsed -> - (match infer_program parsed with - | Ok env -> - Base.Map.iteri env ~f:(fun ~key ~data:(S (_, ty)) -> - if print_key key then printf "val %s : %a\n" key pp_ty ty) - | Error e -> printf "Infer error: %a\n" pp_error e) - | Error e -> printf "Parsing error: %s\n" e -;; - -let%expect_test "infer id function" = - let _ = infer_program_test {| let f x = x |} in - [%expect {| val f : '0 -> '0 |}] -;; - -let%expect_test "infer simple function with int args" = - let _ = infer_program_test {| let f x = x + 2 |} in - [%expect {| val f : int -> int|}] -;; - -let%expect_test "infer seval (no value)" = - let _ = infer_program_test {|let x = 2 in x = 1 |} in - [%expect {| |}] -;; - -let%expect_test "infer factorial function" = - let _ = infer_program_test {|let rec fac n = if n < 1 then 1 else n * fac (n - 1) |} in - [%expect {| val fac : int -> int |}] -;; - -let%expect_test "infer mutual recursion" = - let _ = - infer_program_test - {|let rec is_even n = if n = 0 then true else is_odd (n - 1) and is_odd n = if n = 0 then false else is_even (n - 1)|} - in - [%expect {| - val is_even : int -> bool - val is_odd : int -> bool |}] -;; - -let%expect_test "infer function with polymorphism" = - let _ = - infer_program_test {|let square x = x*x in let id x = x in (id square) (id 2) |} - in - [%expect {| |}] -;; - -let%expect_test "infer function that can't be unified" = - let _ = infer_program_test {|let x = 2 in let a = true in not a && x |} in - [%expect {| Infer error: Unification failed on int and bool |}] -;; - -let%expect_test "infer function with occures check" = - let _ = infer_program_test {| let rec f x = f |} in - [%expect {| Infer error: Occurs check failed: type variable 0 inside type '1 -> '0 |}] -;; - -let%expect_test "infer svalue with if-then-else" = - let _ = infer_program_test {| let a = if true then 2 + 9 else 1 |} in - [%expect {| val a : int |}] -;; - -let%expect_test "infer undefined variable" = - let _ = infer_program_test {| if a then 2 else 1 |} in - [%expect {| Infer error: Undefined variable "a" |}] -;; - -let%expect_test "infer function with 2 args" = - let _ = infer_program_test {| let a = fun x y -> x + y |} in - [%expect {| val a : int -> (int -> int) |}] -;; - -let%expect_test "infer function with many args" = - let _ = infer_program_test {| let f x y z w = if y&&z then x else w + 1 |} in - [%expect {| val f : int -> (bool -> (bool -> (int -> int))) |}] -;; - -let%expect_test "infer function with non-trivial arg" = - let _ = infer_program_test {| let a = fun x::y::z::w -> if z > 0 then y else x |} in - [%expect {| val a : int list -> int |}] -;; - -let%expect_test "infer function with another non-trivial arg" = - let _ = infer_program_test {| let b = fun (a,b,(2::t), d) -> a + d |} in - [%expect {| val b : (int * '1 * int list * int) -> int |}] -;; - -let%expect_test "infer prefix operator" = - let _ = infer_program_test {| let (<|>) a b = a/b + b*a |} in - [%expect {| val <|> : int -> (int -> int) |}] -;; - -let%expect_test "infer function with list and tuple args" = - let _ = infer_program_test {|let w [2; v] (y, dx, d) = (-4, 5+v, true&&d) |} in - [%expect {| val w : int list -> (('2 * '3 * bool) -> (int * int * bool)) |}] -;; - -let%expect_test "infer function with ascription" = - let _ = - infer_program_test {|let f = fun ((3, true): int*bool) x -> if x then 4 else 0 |} - in - [%expect {| val f : (int * bool) -> (bool -> int) |}] -;; - -let%expect_test "infer expr with unary and binary operations" = - let _ = - infer_program_test - {| - let rez = - let x = not true in - let y = 13 in if x || (10 >= y) && (5 <= y) && (y <> 6) || (y < 9) && (y > -1000) then +5 :: [] else [10] |} - in - [%expect {| val rez : int list |}] -;; - -let%expect_test "infer expr with multiple patterns" = - let _ = - infer_program_test - {| - let a : string = "fef" - let b : (string * int list * bool) = ("a", [4], not true) |} - in - [%expect {| - val a : string - val b : (string * int list * bool) |}] -;; diff --git a/OcamlBR/lib/inferencer_tests.mli b/OcamlBR/lib/inferencer_tests.mli deleted file mode 100644 index 4b1971460..000000000 --- a/OcamlBR/lib/inferencer_tests.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val infer_program_test : string -> unit diff --git a/OcamlBR/lib/interpreter.ml b/OcamlBR/lib/interpreter.ml deleted file mode 100644 index 8df9127eb..000000000 --- a/OcamlBR/lib/interpreter.ml +++ /dev/null @@ -1,341 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Values -open Ast - -module type MONAD = sig - (* a basic monad that has type of state * result *) - include Base.Monad.S2 - - (* error-handling *) - val fail : error -> ('a, error) t - - (* for readability *) - val ( let* ) : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t -end - -(* utility layer for handling environments, i.e. symbol tables *) -module Env (M : MONAD) = struct - (* for error propagation *) - open M - - (* creates an empty environment *) - let empty = Base.Map.empty (module Base.String) - - (* looks up a variable in the environment *) - let find env name = - match Base.Map.find env name with - | Some x -> return x - | None -> fail (`Unbound_variable name) - ;; - - (* adds or updates a binding in the environment *) - let extend env key value = Base.Map.update env key ~f:(fun _ -> value) - - (* composes two envs: if they have overlapping values, the latter is chosen *) - let compose env1 env2 = - Base.Map.fold env2 ~init:env1 ~f:(fun ~key ~data acc_env -> extend acc_env key data) - ;; -end - -module Eval (M : MONAD) : sig - val eval_structure : structure -> (environment, error) M.t -end = struct - open M - open Env (M) - - let rec match_pattern env = function - | PAny, _ -> Some env - | PConst (Int i1), VInt i2 when i1 = i2 -> Some env - | PConst (Bool b1), VBool b2 when Bool.equal b1 b2 -> Some env - | PConst (String s1), VString s2 when String.equal s1 s2 -> Some env - | PConst Unit, VUnit -> Some env - | PVar (Id name), v -> Some (extend env name v) - | PList patterns, VList values -> match_list_pattern env patterns values - | PTuple (p1, p2, p_rest), VTuple (v1, v2, v_rest) -> - match_list_pattern env (p1 :: p2 :: p_rest) (v1 :: v2 :: v_rest) - | PCons (p1, p2), VList (v1 :: v2) -> - (match match_pattern env (p1, v1) with - | Some env' -> match_pattern env' (p2, VList v2) - | None -> None) - | POption p, VOption v -> - (match p, v with - | Some p, Some v -> match_pattern env (p, v) - | None, None -> Some env - | _ -> None) - | _ -> None - - and match_list_pattern env patterns values = - let f1 acc p v = - match acc with - | None -> None - | Some env' -> match_pattern env' (p, v) - in - match Base.List.fold2 patterns values ~f:f1 ~init:(Some env) with - | Unequal_lengths -> None - | Ok rez -> rez - ;; - - (* let print_env env = - let open Stdlib.Format in - printf "{\n"; - Base.Map.iteri env ~f:(fun ~key ~data -> printf "%s = %a\n" key pp_value data); - printf "}\n" - ;; *) - - let eval_un_op = function - | Negative, VInt i -> return (VInt (-i)) - | Positive, VInt i -> return (VInt i) - | Not, VBool b -> return (VBool (not b)) - | _ -> fail `Type_error - ;; - - let rec eval_bin_op = function - | Add, VInt i1, VInt i2 -> return (VInt (i1 + i2)) - | Mult, VInt i1, VInt i2 -> return (VInt (i1 * i2)) - | Sub, VInt i1, VInt i2 -> return (VInt (i1 - i2)) - | Div, VInt _, VInt i2 when i2 = 0 -> fail `Division_by_zero - | Div, VInt i1, VInt i2 -> return (VInt (i1 / i2)) - | Cons, v, VList vl -> return (VList (v :: vl)) - | Gt, VInt i1, VInt i2 -> return (VBool (i1 > i2)) - | Lt, VInt i1, VInt i2 -> return (VBool (i1 < i2)) - | Gte, VInt i1, VInt i2 -> return (VBool (i1 >= i2)) - | Lte, VInt i1, VInt i2 -> return (VBool (i1 <= i2)) - | And, VBool b1, VBool b2 -> return (VBool (b1 && b2)) - | Or, VBool b1, VBool b2 -> return (VBool (b1 || b2)) - | Eq, VInt i1, VInt i2 -> return (VBool (i1 = i2)) - | Neq, VInt i1, VInt i2 -> return (VBool (i1 <> i2)) - | Eq, VString s1, VString s2 -> return (VBool (s1 = s2)) - | Neq, VString s1, VString s2 -> return (VBool (s1 <> s2)) - | Eq, VBool b1, VBool b2 -> return (VBool (b1 = b2)) - | Neq, VBool b1, VBool b2 -> return (VBool (b1 <> b2)) - | Eq, VUnit, VUnit -> return (VBool true) - | Neq, VUnit, VUnit -> return (VBool false) - | Eq, VList l1, VList l2 -> eval_eq_list Eq l1 l2 - | Neq, VList l1, VList l2 -> eval_eq_list Neq l1 l2 - | Eq, VTuple (v1, v2, v_rest), VTuple (v1', v2', v_rest') -> - eval_eq_list Eq (v1 :: v2 :: v_rest) (v1' :: v2' :: v_rest') - | Neq, VTuple (v1, v2, v_rest), VTuple (v1', v2', v_rest') -> - eval_eq_list Neq (v1 :: v2 :: v_rest) (v1' :: v2' :: v_rest') - | Eq, VOption o1, VOption o2 -> - (match o1, o2 with - | Some o1, Some o2 -> eval_bin_op (Eq, o1, o2) - | None, None -> return (VBool true) - | _ -> return (VBool false)) - | Neq, VOption o1, VOption o2 -> - (match o1, o2 with - | Some o1, Some o2 -> eval_bin_op (Neq, o1, o2) - | None, None -> return (VBool true) - | _ -> return (VBool false)) - | _ -> fail `Type_error - - and eval_eq_list op l1 l2 = - let f1 acc el1 el2 = - let* acc = acc in - match acc with - | VBool false -> return (VBool false) - | VBool true -> - let* res = eval_bin_op (op, el1, el2) in - (match res with - | VBool true -> return (VBool true) - | _ -> return (VBool false)) - | _ -> fail `Type_error - in - match Base.List.fold2 l1 l2 ~f:f1 ~init:(return (VBool true)) with - | Unequal_lengths -> return (VBool false) - | Ok rez -> rez - ;; - - let eval_const = function - | Int i -> return (VInt i) - | String s -> return (VString s) - | Bool b -> return (VBool b) - | Unit -> return VUnit - ;; - - let rec eval_expr env = function - | Econst c -> eval_const c - | Evar (Id name) -> find env name - | Eif_then_else (cond, t, Some e) -> - let* cond_value = eval_expr env cond in - (match cond_value with - | VBool true -> eval_expr env t - | VBool false -> eval_expr env e - | _ -> fail `Type_error) - | Eif_then_else (cond, t, None) -> - let* cond_value = eval_expr env cond in - (match cond_value with - | VBool true -> eval_expr env t - | VBool false -> return VUnit - | _ -> fail `Type_error) - | Eoption (Some e) -> - let* value = eval_expr env e in - return (VOption (Some value)) - | Eoption None -> return (VOption None) - | Etuple (e1, e2, e_rest) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - let* v_rest = - List.fold_left - (fun acc e -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - (return []) - e_rest - in - return (VTuple (v1, v2, List.rev v_rest)) - | Elist el -> - let* vl = - List.fold_left - (fun acc e -> - let* acc = acc in - let* v = eval_expr env e in - return (v :: acc)) - (return []) - el - in - return (VList (List.rev vl)) - | Ebin_op (op, e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - eval_bin_op (op, v1, v2) - | Eun_op (op, e) -> - let* v = eval_expr env e in - eval_un_op (op, v) - | Ematch (e, c, cl) -> - let* v = eval_expr env e in - eval_match_expr env v (c :: cl) - | Efunction (c, cl) -> return (VFunction (c, cl)) - | Efun (tp, tpl, e) -> return (VFun (Non_recursive, tp, tpl, e, env)) - | Efun_application (e1, e2) -> - let* v1 = eval_expr env e1 in - let* v2 = eval_expr env e2 in - (match v1 with - | VFun (_, pat, pats, body, func_env) -> - (* attempt to match the argument against the pattern *) - (match match_pattern func_env (pat, v2) with - | Some extended_env -> - let env' = compose env extended_env in - (match pats with - | [] -> - eval_expr - env' - body (* evaluate the function body with the updated environment *) - | p :: pl -> return (VFun (Non_recursive, p, pl, body, env'))) - | None -> fail `Pattern_matching_failure) - | VFunction (case, case_l) -> eval_match_expr env v2 (case :: case_l) - | VBuiltin builtin -> - (match builtin, v2 with - | BInt b, VInt i -> - b i; - return VUnit - | BString b, VString s -> - b s; - return VUnit - | _ -> fail `Type_error) - | _ -> fail `Type_error) - | Elet (Non_recursive, Evalue_binding (pat, e1), _, e2) -> - let* v = eval_expr env e1 in - (match match_pattern env (pat, v) with - | Some env' -> eval_expr env' e2 - | None -> fail `Pattern_matching_failure) - | Elet (Recursive, value_binding, value_bindings, e2) -> - let* final_env = eval_value_bindings env (value_binding :: value_bindings) in - eval_expr final_env e2 - | Econstraint (e, _) -> eval_expr env e - - and eval_match_expr env v = function - | Ecase (pat, expr) :: tl -> - let env' = match_pattern env (pat, v) in - (match env' with - (* new environment for evaluating the body of the case *) - | Some env' -> - let env'' = compose env env' in - let* result = eval_expr env'' expr in - return result - | None -> eval_match_expr env v tl) - | [] -> fail `Pattern_matching_failure - - and eval_value_bindings env value_bindings = - let bindings = List.map (fun (Evalue_binding (p, e)) -> p, e) value_bindings in - (* extend env with all names in mutual recursion *) - let rec update_env acc_env = function - | [] -> return acc_env - | (PVar (Id name), expr) :: tl -> - let* value = - match expr with - | Efun (p, pl, e) -> return (VFun (Recursive, p, pl, e, acc_env)) - | _ -> eval_expr acc_env expr - in - (* update env so all names in mutual recursion correspond to their real values *) - let updated_env = extend acc_env name value in - update_env updated_env tl - | _ -> fail (`Ill_left_hand_side "Pattern not acceptable for variable name") - in - let* final_env = update_env env bindings in - return final_env - ;; - - let eval_str_item env str_item = - let env = extend env "print_int" (VBuiltin (BInt print_int)) in - let env = extend env "print_endline" (VBuiltin (BString print_endline)) in - match str_item with - | SEval e -> - let* _ = eval_expr env e in - return env - | SValue (Non_recursive, Evalue_binding (pat, e), _) -> - let* v = eval_expr env e in - (match match_pattern env (pat, v) with - | Some env' -> return env' - | None -> fail `Pattern_matching_failure) - | SValue (Recursive, value_binding, value_bindings) -> - let* final_env = eval_value_bindings env (value_binding :: value_bindings) in - return final_env - ;; - - let eval_structure (structure : structure) = - List.fold_left - (fun env str_item -> - let* env = env in - let* env = eval_str_item env str_item in - return env) - (return empty) - structure - ;; -end - -module Interpreter = Eval (struct - include Base.Result - - let ( let* ) m f = bind m ~f - end) - -let print_key = function - | "print_int" | "print_endline" -> false - | _ -> true -;; - -let pp_env env_t env_v = - let open Stdlib.Format in - let open Typedtree in - printf "\n{\n"; - Base.Map.iteri - ~f:(fun ~key ~data -> - match Base.Map.find env_t key with - | Some (S (_, ty)) -> - if print_key key then printf "val %s : %a = %a\n" key pp_ty ty pp_value data - | None -> if print_key key then printf "val %s = %a\n" key pp_value data) - env_v; - printf "}\n" -;; - -(* let print_env env = - let open Stdlib.Format in - printf "\n{\n"; - Base.Map.iteri env ~f:(fun ~key ~data -> - if key <> "print_int" then printf "%s = %a\n" key pp_value data); - printf "}\n" -;; *) diff --git a/OcamlBR/lib/interpreter.mli b/OcamlBR/lib/interpreter.mli deleted file mode 100644 index d8a771b0b..000000000 --- a/OcamlBR/lib/interpreter.mli +++ /dev/null @@ -1,14 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -module Interpreter : sig - val eval_structure : Ast.structure -> (Values.environment, Values.error) result -end - -val pp_env - : (string, Typedtree.scheme, Base.String.comparator_witness) Base.Map.t - -> (string, Values.value, Base.String.comparator_witness) Base.Map.t - -> unit - -val print_key : string -> bool diff --git a/OcamlBR/lib/interpreter_tests.ml b/OcamlBR/lib/interpreter_tests.ml deleted file mode 100644 index 49a130bf3..000000000 --- a/OcamlBR/lib/interpreter_tests.ml +++ /dev/null @@ -1,264 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Interpreter - -let test_interpret s = - let open Stdlib.Format in - match Parser.parse_expr s with - | Ok parsed -> - (match Inferencer.Infer.infer_program parsed with - | Ok env_inf -> - (match Interpreter.eval_structure parsed with - | Ok env_int -> pp_env env_inf env_int - | Error e -> printf "Interpreter error: %a\n" Values.pp_error e) - | Error e -> printf "Infer error: %a\n" Typedtree.pp_error e) - | Error e -> printf "Parsing error: %s\n" e -;; - -let%expect_test "interpret pattern-matching" = - let _ = - test_interpret - {| - let a x = match x with 1 -> true | _ -> false - let b = a 3 - |} - in - [%expect {| - { - val a : int -> bool = - val b : bool = false - } |}] -;; - -let%expect_test "interpet non-exhaustive pattern-matching" = - let _ = test_interpret {| - let (0, b) = (4, 3) - |} in - [%expect {| Interpreter error: Pattern-matching failure |}] -;; - -let%expect_test "interpret tuple pattern" = - let _ = test_interpret {| - let (a, b) = (4, 3) - |} in - [%expect {| - { - val a : int = 4 - val b : int = 3 - } |}] -;; - -let%expect_test "interpret simple pattern-matching" = - let _ = - test_interpret - {| - let f = true - let g = - match f with - | true -> true - | false -> false - let n = not g - |} - in - [%expect - {| - { - val f : bool = true - val g : bool = true - val n : bool = false - } |}] -;; - -let%expect_test "interpret non-exhaustive match" = - let _ = - test_interpret - {| - let f x = - (match x with - | [] -> "" - | hd :: snd :: tl -> hd) - in - f ["oops"] - |} - in - [%expect {| Interpreter error: Pattern-matching failure |}] -;; - -let%expect_test "interpret correct match" = - let _ = - test_interpret - {| - let f x = - (match x with - | [] -> 0 - | h::tl -> 1 - | hd :: snd :: tl -> hd) - in - print_int (f [1]) - |} - in - [%expect {| - 1 - { - } |}] -;; - -let%expect_test "interpret values using cons" = - let _ = - test_interpret - {| - let a = 1 :: 2 :: 3 :: [] - let b = (1, "one") :: (2, "two") :: [(3, "three")] - let c = [1; 2] :: [3; 4] :: [] - |} - in - [%expect - {| - { - val a : int list = [1; 2; 3] - val b : (int * string) list = [(1, "one"); (2, "two"); (3, "three")] - val c : int list list = [[1; 2]; [3; 4]] - } |}] -;; - -let%expect_test "interpret mutual recursion" = - let _ = - test_interpret - {| - let rec is_even n = - if n = 0 then true else is_odd (n - 1) - and is_odd n = - if n = 0 then false else is_even (n - 1) - let a = is_even 4 - |} - in - [%expect - {| - { - val a : bool = true - val is_even : int -> bool = - val is_odd : int -> bool = - } |}] -;; - -let%expect_test "interpret simple function with fun" = - let _ = test_interpret {| - let f = fun x -> x + 3 - let a = f 3 - |} in - [%expect {| - { - val a : int = 6 - val f : int -> int = - } |}] -;; - -let%expect_test "interpret simple function" = - let _ = test_interpret {| - let f x y = x + y - let a = f 3 4 - |} in - [%expect {| - { - val a : int = 7 - val f : int -> (int -> int) = - } |}] -;; - -let%expect_test "interpret division by zero" = - let _ = test_interpret {| - let a = 0 - let b = 30 / a - |} in - [%expect {| Interpreter error: Division by zero |}] -;; - -let%expect_test "interpret multiple strucuture items" = - let _ = - test_interpret - {| - let g m = m*m - let f x = if x > 0 then h x else g x in - f 5 - |} - in - [%expect {| Infer error: Undefined variable "h" |}] -;; - -(* в OCaml также пишет 'Unbound variable y' *) -let%expect_test "from andrei" = - let _ = test_interpret {| - let f () = y in let y = 42 in f () - |} in - [%expect {| Infer error: Undefined variable "y" |}] -;; - -let%expect_test "interpret expr with unary and binary operations" = - let _ = - test_interpret - {| - let rez = - let x = not true in - let y = 13 in if x || (10 >= y) && (5 <= y) && (y <> 6) || (y < 9) && (y > -1000) then +5 :: [] else [10] |} - in - [%expect {| - { - val rez : int list = [10] - } |}] -;; - -let%expect_test "interpret expr with lists' comparison" = - let _ = - test_interpret - {| - let a = Some 4 - let b = (a, [], None) - let c = [1; 2; 3] - let d = if (c = [3; 2; 1]) then a else Some 5 - let e = if (c = [1; 2; 3]) then a else Some 6 - |} - in - [%expect - {| - { - val a : (int) option = Some 4 - val b : ((int) option * '0 list * ('1) option) = (Some 4, [], None) - val c : int list = [1; 2; 3] - val d : (int) option = Some 5 - val e : (int) option = Some 4 - } |}] -;; - -let%expect_test "interpret expr with None match" = - let _ = - test_interpret - {| - let a = Some 4 - let _ = match a with - | Some e -> print_int e - | None -> print_endline "None" - |} - in - [%expect {| - 4 - { - val a : (int) option = Some 4 - } |}] -;; - -let%expect_test "interpret expr with None match" = - let _ = - test_interpret - {| - let x = function | [] -> 10 | h::m::tl -> 30 | _ -> 20 - let y = x [1; 2; 3] - |} - in - [%expect {| - { - val x : '2 list -> int = - val y : int = 30 - } |}] -;; diff --git a/OcamlBR/lib/interpreter_tests.mli b/OcamlBR/lib/interpreter_tests.mli deleted file mode 100644 index e24c2802e..000000000 --- a/OcamlBR/lib/interpreter_tests.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val test_interpret : string -> unit diff --git a/OcamlBR/lib/parser.ml b/OcamlBR/lib/parser.ml deleted file mode 100644 index 55f3b607f..000000000 --- a/OcamlBR/lib/parser.ml +++ /dev/null @@ -1,504 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Base -open Ast -open Typedtree - -(*---------------------Check conditions---------------------*) - -let is_keyword = function - | "let" - | "in" - | "fun" - | "rec" - | "if" - | "then" - | "else" - | "true" - | "false" - | "Some" - | "None" - | "and" - | "match" - | "with" - | "function" - | "type" -> true - | _ -> false -;; - -(*---------------------Control characters---------------------*) - -let pwhitespace = take_while Char.is_whitespace -let pws1 = take_while1 Char.is_whitespace -let pstoken s = pwhitespace *> string s -let ptoken s = pwhitespace *> s -let pparens p = pstoken "(" *> p <* pstoken ")" -let psqparens p = pstoken "[" *> p <* pstoken "]" - -(*------------------Prefix operators-----------------*) - -let ppref_op = - let pref_op = - ptoken - (let* first_char = - take_while1 (function - | '|' - | '~' - | '?' - | '<' - | '>' - | '!' - | '&' - | '*' - | '/' - | '=' - | '+' - | '-' - | '@' - | '^' -> true - | _ -> false) - in - let* rest = - take_while (function - | '.' - | ':' - | '|' - | '~' - | '?' - | '<' - | '>' - | '!' - | '&' - | '*' - | '/' - | '=' - | '+' - | '-' - | '@' - | '^' -> true - | _ -> false) - in - match first_char, rest with - | "|", "" -> fail "Prefix operator cannot be called | " - | "~", "" -> fail "Prefix operator cannot be called ~ " - | "?", "" -> fail "Prefix operator cannot be called ? " - | _ -> return (Id (first_char ^ rest))) - in - pparens pref_op -;; - -let pEinf_op pexpr = - ppref_op - >>= fun inf_op -> - lift2 - (fun left right -> Efun_application (Efun_application (Evar inf_op, left), right)) - (pws1 *> pexpr) - (pwhitespace *> pexpr) -;; - -(* let pEinf_op = - pwhitespace *> pinf_op >>= fun inf_op -> return (fun e1 e2 -> Efun_application (Efun_application (Evar inf_op, e1), e2)) - ;; *) - -(*-------------------------Constants/Variables-------------------------*) - -let pint = - pwhitespace *> take_while1 Char.is_digit - >>= fun str -> - match Stdlib.int_of_string_opt str with - | Some n -> return (Int n) - | None -> fail "Integer value exceeds the allowable range for the int type" -;; - -let pbool = - choice [ pstoken "true" *> return true; pstoken "false" *> return false ] - >>| fun x -> Bool x -;; - -let pstr = - pwhitespace *> char '"' *> take_till (Char.equal '"') <* char '"' >>| fun x -> String x -;; - -let punit = pstoken "()" *> return Unit -let const = choice [ pint; pbool; pstr; punit ] - -let varname = - ptoken - (let* first_char = - take_while1 (fun ch -> Char.is_lowercase ch || Char.equal ch '_') - in - let* rest = - take_while (fun ch -> - Char.is_alpha ch || Char.is_digit ch || Char.equal ch '_' || Char.equal ch '\'') - in - match first_char, rest with - | _, _ when is_keyword (first_char ^ rest) -> - fail "Variable name conflicts with a keyword" - | "_", "" -> fail "Variable cannot be called _" - | _ -> return (first_char ^ rest)) -;; - -let patomic_type = - choice - [ pstoken "int" *> return (TPrim "int") - ; pstoken "string" *> return (TPrim "string") - ; pstoken "bool" *> return (TPrim "bool") - ; pstoken "unit" *> return (TPrim "unit") - ] -;; - -let plist_type ptype_opt = ptype_opt >>= fun t -> pstoken "list" *> return (TList t) - -let ptuple_type ptype_opt = - let star = pstoken "*" in - lift3 - (fun t1 t2 rest -> TTuple (t1, t2, rest)) - ptype_opt - (star *> ptype_opt) - (many (star *> ptype_opt)) -;; - -let rec pfun_type ptype_opt = - ptype_opt - >>= fun left -> - pstoken "->" *> pfun_type ptype_opt - >>= (fun right -> return (TArrow (left, right))) - <|> return left -;; - -let poption_type ptype_opt = ptype_opt >>= fun t -> pstoken "option" *> return (TOption t) -(* let precord_type = varname >>= fun t -> return (TRecord t) *) - -let ptype_helper = - fix (fun typ -> - (* let atom = patomic_type <|> pparens typ <|> precord_type in *) - let atom = patomic_type <|> pparens typ in - let list = plist_type atom <|> atom in - let option = poption_type list <|> list in - let tuple = ptuple_type option <|> option in - let func = pfun_type tuple <|> tuple in - func) -;; - -let ptype = - let t = ptype_helper in - pstoken ":" *> t -;; - -let pident = lift (fun t -> Id t) varname <|> ppref_op -let pat_var = pident >>| fun x -> PVar x -let pat_const = const >>| fun x -> PConst x -let pat_any = pstoken "_" *> return PAny - -let pat_tuple pat = - let commas = pstoken "," in - let tuple = - lift3 - (fun p1 p2 rest -> PTuple (p1, p2, rest)) - pat - (commas *> pat) - (many (commas *> pat)) - <* pwhitespace - in - pparens tuple <|> tuple -;; - -let pat_list pat = - let semicols = pstoken ";" in - psqparens (sep_by semicols pat >>| fun patterns -> PList patterns) -;; - -let rec pat_cons pat = - let cons = - pat - >>= fun head -> - pstoken "::" *> pat_cons pat - >>= (fun tail -> return (PCons (head, tail))) - <|> return head - in - pparens cons <|> cons -;; - -let pat_option pat = - lift - (fun e -> POption e) - (pstoken "Some" *> pat >>| (fun e -> Some e) <|> (pstoken "None" >>| fun _ -> None)) -;; - -let pat_ty pat = - let ty_pat = lift2 (fun pat ty -> PConstraint (pat, ty)) pat ptype in - ty_pat <|> pparens ty_pat -;; - -let ppattern = - fix (fun pat -> - let patom = - pat_const <|> pat_var <|> pat_any <|> pparens pat <|> pparens (pat_ty pat) - in - let poption = pat_option patom <|> patom in - let pptuple = pat_tuple poption <|> poption in - let pplist = pat_list pptuple <|> pptuple in - let pcons = pat_cons pplist <|> pplist in - let pty = pat_ty pcons <|> pcons in - pty) -;; - -(*------------------Binary operators-----------------*) - -let pbinop op token = - pwhitespace *> pstoken token *> return (fun e1 e2 -> Ebin_op (op, e1, e2)) -;; - -let add = pbinop Add "+" -let sub = pbinop Sub "-" -let mult = pbinop Mult "*" -let div = pbinop Div "/" - -let relation = - choice - [ pbinop Eq "=" - ; pbinop Neq "<>" - ; pbinop Lte "<=" - ; pbinop Gte ">=" - ; pbinop Lt "<" - ; pbinop Gt ">" - ] -;; - -let logic = choice [ pbinop And "&&"; pbinop Or "||" ] -let cons = pbinop Cons "::" - -(*------------------Unary operators-----------------*) - -let punop op token = pwhitespace *> pstoken token *> return (fun e1 -> Eun_op (op, e1)) -let negation = punop Not "not" <* pws1 -let neg_sign = punop Negative "-" -let pos_sign = punop Positive "+" - -(*------------------------Expressions----------------------*) - -let chain e op = - let rec go acc = lift2 (fun f x -> f acc x) op e >>= go <|> return acc in - e >>= go -;; - -let rec chainr e op = - let* left = e in - (let* f = op in - let* right = chainr e op in - return (f left right)) - <|> return left -;; - -let un_chain e op = - fix (fun self -> op >>= (fun unop -> self >>= fun e -> return (unop e)) <|> e) -;; - -let rec pbody pexpr = - ppattern - >>= fun p -> - many ppattern - >>= fun patterns -> - pbody pexpr <|> (pstoken "=" *> pexpr >>| fun e -> Efun (p, patterns, e)) -;; - -let pvalue_binding pexpr = - lift2 - (fun ty_pattern expr -> Evalue_binding (ty_pattern, expr)) - ppattern - (pstoken "=" *> pexpr <|> pbody pexpr) -;; - -let plet pexpr = - pstoken "let" - *> lift4 - (fun rec_flag value_bindings and_bindings body -> - Elet (rec_flag, value_bindings, and_bindings, body)) - (pstoken "rec" *> (pws1 *> return Recursive) <|> return Non_recursive) - (pvalue_binding pexpr) - (many (pstoken "and" *> pvalue_binding pexpr)) - (pstoken "in" *> pexpr) -;; - -let pEfun pexpr = - (* if there's only one argument, ascription without parentheses is possible *) - let single_arg = - lift2 - (fun arg body -> Efun (arg, [], body)) - (pstoken "fun" *> pws1 *> ppattern) - (pstoken "->" *> pexpr) - in - let mult_args = - lift3 - (fun arg args body -> Efun (arg, args, body)) - (pstoken "fun" *> pws1 *> ppattern) - (many ppattern) - (pstoken "->" *> pexpr) - in - single_arg <|> mult_args -;; - -let pElist pexpr = - let semicols = pstoken ";" in - psqparens (sep_by semicols pexpr <* (semicols <|> pwhitespace) >>| fun x -> Elist x) -;; - -let pEtuple pexpr = - let commas = pstoken "," in - let tuple = - lift3 - (fun e1 e2 rest -> Etuple (e1, e2, rest)) - (pexpr <* commas) - pexpr - (many (commas *> pexpr)) - <* pwhitespace - in - pparens tuple <|> tuple -;; - -let pEconst = const >>| fun x -> Econst x -let pEvar = pident >>| fun x -> Evar x -let pEapp e = chain e (return (fun e1 e2 -> Efun_application (e1, e2))) - -let pEoption pexpr = - lift - (fun e -> Eoption e) - (pstoken "Some" *> pexpr >>| (fun e -> Some e) <|> (pstoken "None" >>| fun _ -> None)) -;; - -let pbranch pexpr = - lift3 - (fun e1 e2 e3 -> Eif_then_else (e1, e2, e3)) - (pstoken "if" *> pexpr) - (pstoken "then" *> pexpr) - (pstoken "else" *> pexpr >>| (fun e3 -> Some e3) <|> return None) -;; - -let pEmatch pexpr = - let parse_case = - lift2 - (fun pat exp -> Ecase (pat, exp)) - (ppattern <* pstoken "->") - (pwhitespace *> pexpr) - in - let match_cases = - lift3 - (fun e case case_l -> Ematch (e, case, case_l)) - (pstoken "match" *> pexpr <* pstoken "with") - ((pstoken "|" <|> pwhitespace) *> parse_case) - (many (pstoken "|" *> parse_case)) - in - let function_cases = - lift2 - (fun case case_l -> Efunction (case, case_l)) - (pstoken "function" *> pstoken "|" *> parse_case - <|> pstoken "function" *> pwhitespace *> parse_case) - (many (pstoken "|" *> parse_case)) - in - function_cases <|> match_cases -;; - -let pEconstraint pexpr = lift2 (fun expr t -> Econstraint (expr, t)) pexpr ptype - -(*------------------Records-----------------*) - -(* let pbraces p = pstoken "{" *> p <* pstoken "}" -let plabel_name = lift (fun t -> Label t) varname - -let pErecord pexpr = - let precord_field = - lift2 - (fun label_name expr -> Erecord_field (label_name, expr)) - plabel_name - (pstoken "=" *> pexpr) - in - pbraces - (lift2 - (fun record_field record_fields -> Erecord (record_field, record_fields)) - precord_field - (many (pstoken ";" *> precord_field)) - <* (pstoken ";" <|> pwhitespace)) -;; - -let pfield pexpr = pparens (pEconstraint pexpr) <|> pexpr - - let pEfield_access pexpr = - let base_expr = pfield pexpr in - let rec parse_fields acc = - pstoken "." *> plabel_name - >>= fun field_name -> - let new_expr = Efield_access (acc, field_name) in - parse_fields new_expr <|> return new_expr - in - base_expr >>= fun base -> parse_fields base -;; *) - -let pexpr = - fix (fun expr -> - let atom_expr = - choice - [ pEconst - ; pEvar - ; pparens expr - ; pElist expr - ; pEfun expr - ; pEoption expr - ; pEmatch expr (* ; pErecord expr *) - ; pparens (pEconstraint expr) - ] - in - let let_expr = plet expr in - let ite_expr = pbranch (expr <|> atom_expr) <|> atom_expr in - let inf_op = pEinf_op (ite_expr <|> atom_expr) <|> ite_expr in - let app_expr = pEapp (inf_op <|> atom_expr) <|> inf_op in - let un_expr = - choice - [ un_chain app_expr negation - ; un_chain app_expr neg_sign - ; un_chain app_expr pos_sign - ] - in - let factor_expr = chain un_expr (mult <|> div) in - let sum_expr = chain factor_expr (add <|> sub) in - let rel_expr = chain sum_expr relation in - let log_expr = chain rel_expr logic in - let tuple_expr = pEtuple log_expr <|> log_expr in - (* let field_expr = pEfield_access tuple_expr <|> tuple_expr in - let cons_expr = chainr field_expr cons in *) - let cons_expr = chainr tuple_expr cons in - choice [ let_expr; cons_expr ]) -;; - -(* let pfield_decl = - lift2 (fun label_name t -> Sfield_decl (label_name, t)) plabel_name ptype - ;; *) - -let pstructure = - let pseval = pexpr >>| fun e -> SEval e in - let psvalue = - pstoken "let" - *> lift3 - (fun r id id_list -> SValue (r, id, id_list)) - (pstoken "rec" *> (pws1 *> return Recursive) <|> return Non_recursive) - (pvalue_binding pexpr) - (many (pstoken "and" *> pvalue_binding pexpr)) - in - (* let pstype = - lift3 - (fun name field fields -> SType (name, field, fields)) - (pstoken "type" *> varname) - (pstoken "=" *> pstoken "{" *> pfield_decl) - (many (pstoken ";" *> pfield_decl) <* (pstoken ";" <|> pwhitespace) <* pstoken "}") - in *) - choice [ pseval; psvalue ] -;; - -let structure : structure t = - let semicolons = many (pstoken ";;") in - sep_by semicolons pstructure <* semicolons <* pwhitespace -;; - -let parse_expr str = parse_string ~consume:All structure str diff --git a/OcamlBR/lib/parser.mli b/OcamlBR/lib/parser.mli deleted file mode 100644 index 67e4f7bf8..000000000 --- a/OcamlBR/lib/parser.mli +++ /dev/null @@ -1,7 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val parse_expr : string -> (structure, string) result diff --git a/OcamlBR/lib/parser_tests.ml b/OcamlBR/lib/parser_tests.ml deleted file mode 100644 index 231c18be6..000000000 --- a/OcamlBR/lib/parser_tests.ml +++ /dev/null @@ -1,284 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Parser -open Ast - -let parse str = - match parse_expr str with - | Ok ast -> Stdlib.print_endline (show_structure ast) - | _ -> Stdlib.print_endline "Parsing failed" -;; - -let%expect_test "parse factorial" = - parse "let rec factorial n = if n = 0 then 1 else n * factorial (n - 1) in factorial 5"; - [%expect - {| - [(SEval - (Elet (Recursive, - (Evalue_binding ((PVar (Id "factorial")), - (Efun ((PVar (Id "n")), [], - (Eif_then_else ( - (Ebin_op (Eq, (Evar (Id "n")), (Econst (Int 0)))), - (Econst (Int 1)), - (Some (Ebin_op (Mult, (Evar (Id "n")), - (Efun_application ((Evar (Id "factorial")), - (Ebin_op (Sub, (Evar (Id "n")), (Econst (Int 1)) - )) - )) - ))) - )) - )) - )), - [], (Efun_application ((Evar (Id "factorial")), (Econst (Int 5))))))) - ] - |}] -;; - -let%expect_test "parse calculation sequence" = - parse "1234 + 676 - 9002 * (52 / 2)"; - [%expect - {| - [(SEval - (Ebin_op (Sub, (Ebin_op (Add, (Econst (Int 1234)), (Econst (Int 676)))), - (Ebin_op (Mult, (Econst (Int 9002)), - (Ebin_op (Div, (Econst (Int 52)), (Econst (Int 2)))))) - ))) - ] - |}] -;; - -let%expect_test "parse complex if-then-else" = - parse "if 1234 + 1 = 1235 then let x = 4 in x * 2"; - [%expect - {| - [(SEval - (Eif_then_else ( - (Ebin_op (Eq, (Ebin_op (Add, (Econst (Int 1234)), (Econst (Int 1)))), - (Econst (Int 1235)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 4)))), [], - (Ebin_op (Mult, (Evar (Id "x")), (Econst (Int 2)))))), - None))) - ] - |}] -;; - -let%expect_test "parse unallowable range for the int type" = - parse "39482309482390842309482438208 + 2"; - [%expect {| - Parsing failed - |}] -;; - -let%expect_test "parse nested let-in" = - parse "let x = 5 in let y = 3 in x + y;; if 13 > 12 then let a = 2 in a - 4"; - [%expect - {| - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "y")), (Econst (Int 3)))), [], - (Ebin_op (Add, (Evar (Id "x")), (Evar (Id "y")))))) - ))); - (SEval - (Eif_then_else ((Ebin_op (Gt, (Econst (Int 13)), (Econst (Int 12)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Econst (Int 2)))), [], - (Ebin_op (Sub, (Evar (Id "a")), (Econst (Int 4)))))), - None))) - ] |}] -;; - -let%expect_test "parse multiple structure items" = - parse "let x = 5 ;; if 13 > 12 then let a = 2 in a + x"; - [%expect - {| - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [])); - (SEval - (Eif_then_else ((Ebin_op (Gt, (Econst (Int 13)), (Econst (Int 12)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Econst (Int 2)))), [], - (Ebin_op (Add, (Evar (Id "a")), (Evar (Id "x")))))), - None))) - ] |}] -;; - -let%expect_test "parse incorrect pattern-matching" = - parse "let rec factorial n = match n with 5 0 -> 1 5 1 -> 1 5 _ -> n * factorial(n - 1)"; - [%expect {| - Parsing failed - |}] -;; - -let%expect_test "parse correct pattern-matching" = - parse "let x = match 3 with | 1 -> -10 | 2 -> +20 | _ -> 30 ;;"; - [%expect - {| - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), - (Ematch ((Econst (Int 3)), - (Ecase ((PConst (Int 1)), (Eun_op (Negative, (Econst (Int 10)))))), - [(Ecase ((PConst (Int 2)), (Eun_op (Positive, (Econst (Int 20)))))); - (Ecase (PAny, (Econst (Int 30))))] - )) - )), - [])) - ] - |}] -;; - -let%expect_test "parse parenthesised expression" = - parse "(5 + 6) * 4"; - [%expect - {| - [(SEval - (Ebin_op (Mult, (Ebin_op (Add, (Econst (Int 5)), (Econst (Int 6)))), - (Econst (Int 4))))) - ] - |}] -;; - -let%expect_test "parse prefix operators" = - parse "let (|?) a b = a/b + b*a in (|?) 3 ((|?) 5 6)"; - [%expect - {| - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "|?")), - (Efun ((PVar (Id "a")), [(PVar (Id "b"))], - (Ebin_op (Add, - (Ebin_op (Div, (Evar (Id "a")), (Evar (Id "b")))), - (Ebin_op (Mult, (Evar (Id "b")), (Evar (Id "a")))))) - )) - )), - [], - (Efun_application ( - (Efun_application ((Evar (Id "|?")), (Econst (Int 3)))), - (Efun_application ( - (Efun_application ((Evar (Id "|?")), (Econst (Int 5)))), - (Econst (Int 6)))) - )) - ))) - ] - |}] -;; - -let%expect_test "parse match with function keyword" = - parse "let x = function | [] -> 10 | h::tl -> 20 | h::m::tl -> 30 ;;"; - [%expect - {| - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), - (Efunction ((Ecase ((PList []), (Econst (Int 10)))), - [(Ecase ((PCons ((PVar (Id "h")), (PVar (Id "tl")))), - (Econst (Int 20)))); - (Ecase ( - (PCons ((PVar (Id "h")), - (PCons ((PVar (Id "m")), (PVar (Id "tl")))))), - (Econst (Int 30)))) - ] - )) - )), - [])) - ] - |}] -;; - -let%expect_test "parse pattern with arguments" = - parse "let (w : int) (Some c) (2::v) (a, b, d) = c"; - [%expect - {| - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "w")), int)), - (Efun ((POption (Some (PVar (Id "c")))), - [(PCons ((PConst (Int 2)), (PVar (Id "v")))); - (PTuple ((PVar (Id "a")), (PVar (Id "b")), [(PVar (Id "d"))]))], - (Evar (Id "c")))) - )), - [])) - ] - |}] -;; - -let%expect_test "parse expr with unary and binary operations" = - parse - "let x = not true in let y = 13 in if x || (10 >= y) && (5 <= y) && (y <> 6) || (y < \ - 9) && (y > -1000) then +5 :: [] else [10] ;;"; - [%expect - {| - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Eun_op (Not, (Econst (Bool true)))) - )), - [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "y")), (Econst (Int 13)))), [], - (Eif_then_else ( - (Ebin_op (And, - (Ebin_op (Or, - (Ebin_op (And, - (Ebin_op (And, - (Ebin_op (Or, (Evar (Id "x")), - (Ebin_op (Gte, (Econst (Int 10)), (Evar (Id "y")) - )) - )), - (Ebin_op (Lte, (Econst (Int 5)), (Evar (Id "y")))))), - (Ebin_op (Neq, (Evar (Id "y")), (Econst (Int 6)))))), - (Ebin_op (Lt, (Evar (Id "y")), (Econst (Int 9)))))), - (Ebin_op (Gt, (Evar (Id "y")), - (Eun_op (Negative, (Econst (Int 1000)))))) - )), - (Ebin_op (Cons, (Eun_op (Positive, (Econst (Int 5)))), - (Elist []))), - (Some (Elist [(Econst (Int 10))])))) - )) - ))) - ] - |}] -;; - -let%expect_test "parse multiple patterns" = - parse "let a = Some 4 in let b = (c, [], not true) in c :: [a]"; - [%expect - {| - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Eoption (Some (Econst (Int 4)))))), - [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "b")), - (Etuple ((Evar (Id "c")), (Elist []), - [(Eun_op (Not, (Econst (Bool true))))])) - )), - [], (Ebin_op (Cons, (Evar (Id "c")), (Elist [(Evar (Id "a"))]))))) - ))) - ] - |}] -;; - -let%expect_test "parse expr with constraint" = - parse "let addi = fun f g x -> (f x (g x: bool) : int) "; - [%expect - {| - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "addi")), - (Efun ((PVar (Id "f")), [(PVar (Id "g")); (PVar (Id "x"))], - (Econstraint ( - (Efun_application ( - (Efun_application ((Evar (Id "f")), (Evar (Id "x")))), - (Econstraint ( - (Efun_application ((Evar (Id "g")), (Evar (Id "x")))), - bool)) - )), - int)) - )) - )), - [])) - ] - |}] -;; diff --git a/OcamlBR/lib/parser_tests.mli b/OcamlBR/lib/parser_tests.mli deleted file mode 100644 index 435b54ba2..000000000 --- a/OcamlBR/lib/parser_tests.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> unit diff --git a/OcamlBR/lib/pr_printer.ml b/OcamlBR/lib/pr_printer.ml deleted file mode 100644 index e3f98e5d8..000000000 --- a/OcamlBR/lib/pr_printer.ml +++ /dev/null @@ -1,240 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Base -open Ast -open Stdlib.Format -open Typedtree - -let pp_id ppf = function - | Id name -> fprintf ppf "%s" name -;; - -let pp_const ppf = function - | Int i -> fprintf ppf "%d" i - | String s -> fprintf ppf "%S" s - | Bool b -> fprintf ppf "%b" b - | Unit -> fprintf ppf "()" -;; - -let pp_bin_op ppf = function - | Add -> fprintf ppf "+" - | Mult -> fprintf ppf "*" - | Sub -> fprintf ppf "-" - | Div -> fprintf ppf "/" - | Gt -> fprintf ppf ">" - | Lt -> fprintf ppf "<" - | Eq -> fprintf ppf "=" - | Neq -> fprintf ppf "<>" - | Gte -> fprintf ppf ">=" - | Lte -> fprintf ppf "<=" - | And -> fprintf ppf "&&" - | Or -> fprintf ppf "||" - | Cons -> fprintf ppf "::" -;; - -let pp_un_op ppf = function - | Negative -> fprintf ppf "-" - | Positive -> fprintf ppf "+" - | Not -> fprintf ppf "not " -;; - -let pp_rec_flag ppf = function - | Recursive -> fprintf ppf "rec" - | Non_recursive -> () -;; - -let rec pp_pattern ppf = function - | PVar id -> pp_id ppf id - | PConst c -> pp_const ppf c - | PAny -> fprintf ppf "_" - | PTuple (p1, p2, rest) -> - let patterns = - String.concat ~sep:", " (List.map ~f:(asprintf "%a" pp_pattern) (p1 :: p2 :: rest)) - in - fprintf ppf "(%s)" patterns - | PList patterns -> - let patterns_str = - String.concat ~sep:"; " (List.map ~f:(asprintf "%a" pp_pattern) patterns) - in - fprintf ppf "[%s]" patterns_str - | PCons (p1, p2) -> fprintf ppf "%a :: %a" pp_pattern p1 pp_pattern p2 - | POption (Some p) -> fprintf ppf "(Some %a)" pp_pattern p - | POption None -> fprintf ppf "None" - | PConstraint (p, t) -> fprintf ppf "(%a : %a)" pp_pattern p pp_ty t -;; - -let precedence_bin_op = function - | Mult | Div -> 2 - | Add | Sub -> 1 - | And | Or -> 0 - | Gt | Lt | Eq | Neq | Gte | Lte | Cons -> -1 -;; - -(* let pp_label ppf = function - | Label name -> fprintf ppf "%s" name - ;; *) - -let rec pp_expr ppf expr = - let needs_parens parent_prec child_prec = child_prec < parent_prec || child_prec = -1 in - match expr with - | Econst c -> pp_const ppf c - | Evar id -> pp_id ppf id - | Eif_then_else (e1, e2, None) -> fprintf ppf "if %a then %a" pp_expr e1 pp_expr e2 - | Eif_then_else (e1, e2, Some e3) -> - fprintf ppf "if %a then %a else %a" pp_expr e1 pp_expr e2 pp_expr e3 - | Ematch (exp, Ecase (first_pat, first_expr), rest_cases) -> - let case_to_string (Ecase (pat, expr)) = - asprintf "| %a -> %a" pp_pattern pat pp_expr expr - in - let case_list_str = - String.concat - ~sep:" " - (case_to_string (Ecase (first_pat, first_expr)) - :: List.map ~f:case_to_string rest_cases) - in - fprintf ppf "match %a with %s" pp_expr exp case_list_str - | Efunction (Ecase (first_pat, first_expr), rest_cases) -> - let case_to_string (Ecase (pat, expr)) = - asprintf "| %a -> %a" pp_pattern pat pp_expr expr - in - let case_list_str = - String.concat - ~sep:" " - (case_to_string (Ecase (first_pat, first_expr)) - :: List.map ~f:case_to_string rest_cases) - in - fprintf ppf "function %s" case_list_str - | Eoption (Some e) -> fprintf ppf "(Some %a)" pp_expr e - | Eoption None -> fprintf ppf "None" - | Etuple (e1, e2, es) -> - fprintf - ppf - "(%a, %a%a)" - pp_expr - e1 - pp_expr - e2 - (fun ppf -> List.iter ~f:(fprintf ppf ", %a" pp_expr)) - es - | Elist es -> - fprintf - ppf - "[%a]" - (fun ppf -> - List.iteri ~f:(fun i e -> - if i > 0 then fprintf ppf "; %a" pp_expr e else pp_expr ppf e)) - es - | Efun (first_pattern, rest_patterns, e) -> - fprintf - ppf - "(fun %a%a -> %a)" - pp_pattern - first_pattern - (fun ppf patterns -> - List.iter patterns ~f:(fun pat -> fprintf ppf " %a" pp_pattern pat)) - rest_patterns - pp_expr - e - | Ebin_op (op, e1, e2) -> - let op_prec = precedence_bin_op op in - fprintf - ppf - "%a %a %a" - (fun ppf e -> - if needs_parens op_prec (precedence e) - then fprintf ppf "(%a)" pp_expr e - else pp_expr ppf e) - e1 - pp_bin_op - op - (fun ppf e -> - if needs_parens op_prec (precedence e) - then fprintf ppf "(%a)" pp_expr e - else pp_expr ppf e) - e2 - | Eun_op (op, e) -> fprintf ppf "%a(%a)" pp_un_op op pp_expr e - | Elet (rec_flag, vb, vb_l, e) -> - fprintf - ppf - "let %a %a in %a" - pp_rec_flag - rec_flag - (fun ppf () -> - fprintf ppf "%a" pp_value_binding vb; - List.iter vb_l ~f:(fun vb' -> fprintf ppf " and %a" pp_value_binding vb')) - () - pp_expr - e - | Efun_application (e1, e2) -> - let needs_parens = function - | Econst _ | Evar _ | Ebin_op _ -> false - | _ -> true - in - fprintf - ppf - "%a %a" - (fun ppf e -> - if needs_parens e then fprintf ppf "(%a)" pp_expr e else pp_expr ppf e) - e1 - (fun ppf e -> - if needs_parens e then fprintf ppf "(%a)" pp_expr e else pp_expr ppf e) - e2 - | Econstraint (e, t) -> fprintf ppf "(%a : %a)" pp_expr e pp_ty t -(* | Efield_access (e, label) -> fprintf ppf "(%a.%a)" pp_expr e pp_label label - | Erecord (field, fields) -> - fprintf - ppf - "{ %a }" - (fun ppf () -> - fprintf ppf "%a" pp_record_field field; - List.iter fields ~f:(fun field' -> fprintf ppf " ; %a" pp_record_field field')) - () *) - -and precedence = function - | Ebin_op (op, _, _) -> precedence_bin_op op - | _ -> 2 - -and pp_value_binding ppf = function - | Evalue_binding (pattern, e) -> fprintf ppf "%a = %a" pp_pattern pattern pp_expr e -;; - -(* and pp_record_field ppf = function - | Erecord_field (label, e) -> fprintf ppf "%a = %a" pp_label label pp_expr e - ;; *) - -let pp_structure_item ppf (item : structure_item) = - match item with - | SEval e -> fprintf ppf "%a ;;" pp_expr e - | SValue (rec_flag, vb, vb_l) -> - fprintf - ppf - "let %a %a ;;" - pp_rec_flag - rec_flag - (fun ppf () -> - fprintf ppf "%a" pp_value_binding vb; - List.iter vb_l ~f:(fun vb' -> fprintf ppf " and %a" pp_value_binding vb')) - () -;; - -(* | SType (name, field_decl, field_decls) -> - fprintf - ppf - "type %s = { %a } ;;" - name - (fun ppf () -> - fprintf ppf "%a" pr_field_decl field_decl; - List.iter field_decls ~f:(fun field_decl' -> - fprintf ppf " ; %a" pr_field_decl field_decl')) - () *) - -(* and pr_field_decl ppf = function - | Sfield_decl (label, ty) -> fprintf ppf "%a : %a" pp_label label pp_ty ty *) - -let pp_new_line ppf () = fprintf ppf "\n" - -let prpr_structure ppf = - fprintf ppf "%a" (pp_print_list ~pp_sep:pp_new_line pp_structure_item) -;; diff --git a/OcamlBR/lib/pr_printer.mli b/OcamlBR/lib/pr_printer.mli deleted file mode 100644 index bf0b59ce6..000000000 --- a/OcamlBR/lib/pr_printer.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val prpr_structure : Format.formatter -> Ast.structure -> unit diff --git a/OcamlBR/lib/pr_printer_tests.ml b/OcamlBR/lib/pr_printer_tests.ml deleted file mode 100644 index 32eb42455..000000000 --- a/OcamlBR/lib/pr_printer_tests.ml +++ /dev/null @@ -1,457 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -open Base -open Parser -open Pr_printer - -let parse str = - match parse_expr str with - | Ok structure -> - Stdlib.print_endline (Stdlib.Format.asprintf "%a" prpr_structure structure); - Stdlib.print_endline (show_structure structure) - | Error _ -> Stdlib.print_endline "Parsing failed" -;; - -let%expect_test "print factorial" = - parse "let rec factorial n = if n = 0 then 1 else n * factorial (n - 1) in factorial 5"; - [%expect - {| - let rec factorial = (fun n -> if n = 0 then 1 else n * factorial n - 1) in factorial 5 ;; - [(SEval - (Elet (Recursive, - (Evalue_binding ((PVar (Id "factorial")), - (Efun ((PVar (Id "n")), [], - (Eif_then_else ( - (Ebin_op (Eq, (Evar (Id "n")), (Econst (Int 0)))), - (Econst (Int 1)), - (Some (Ebin_op (Mult, (Evar (Id "n")), - (Efun_application ((Evar (Id "factorial")), - (Ebin_op (Sub, (Evar (Id "n")), (Econst (Int 1)) - )) - )) - ))) - )) - )) - )), - [], (Efun_application ((Evar (Id "factorial")), (Econst (Int 5))))))) - ] - |}] -;; - -let%expect_test "print if-then-else" = - parse "if 5 > 6 then let x = 5 in x + 5"; - [%expect - {| - if 5 > 6 then let x = 5 in x + 5 ;; - [(SEval - (Eif_then_else ((Ebin_op (Gt, (Econst (Int 5)), (Econst (Int 6)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [], - (Ebin_op (Add, (Evar (Id "x")), (Econst (Int 5)))))), - None))) - ] - |}] -;; - -let%expect_test "print nested let-ins" = - parse "let x = 5 in let y = 6 in (x < y) and (x = y)"; - [%expect {| - Parsing failed - |}] -;; - -let%expect_test "print nested lists" = - parse "[1; [2; 3]; 4]"; - [%expect - {| - [1; [2; 3]; 4] ;; - [(SEval - (Elist - [(Econst (Int 1)); (Elist [(Econst (Int 2)); (Econst (Int 3))]); - (Econst (Int 4))])) - ] - |}] -;; - -let%expect_test "print list with arithemtic expressions" = - parse "[1 + 2; 3 * 4; 5 - 6]"; - [%expect - {| - [1 + 2; 3 * 4; 5 - 6] ;; - [(SEval - (Elist - [(Ebin_op (Add, (Econst (Int 1)), (Econst (Int 2)))); - (Ebin_op (Mult, (Econst (Int 3)), (Econst (Int 4)))); - (Ebin_op (Sub, (Econst (Int 5)), (Econst (Int 6))))])) - ] - |}] -;; - -let%expect_test "print tuple value" = - parse "let a = (1, 2, 3)"; - [%expect - {| - let a = (1, 2, 3) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "a")), - (Etuple ((Econst (Int 1)), (Econst (Int 2)), [(Econst (Int 3))])))), - [])) - ] - |}] -;; - -let%expect_test "print arithemtic calculations" = - parse "1234 + 676 - 9002 * (52 / 2)"; - [%expect - {| - 1234 + 676 - 9002 * 52 / 2 ;; - [(SEval - (Ebin_op (Sub, (Ebin_op (Add, (Econst (Int 1234)), (Econst (Int 676)))), - (Ebin_op (Mult, (Econst (Int 9002)), - (Ebin_op (Div, (Econst (Int 52)), (Econst (Int 2)))))) - ))) - ] - |}] -;; - -let%expect_test "print complex if-then-else" = - parse "if 1234 + 1 = 1235 then let x = 4 in (x, 2)"; - [%expect - {| - if 1234 + 1 = 1235 then let x = 4 in (x, 2) ;; - [(SEval - (Eif_then_else ( - (Ebin_op (Eq, (Ebin_op (Add, (Econst (Int 1234)), (Econst (Int 1)))), - (Econst (Int 1235)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 4)))), [], - (Etuple ((Evar (Id "x")), (Econst (Int 2)), [])))), - None))) - ] - |}] -;; - -let%expect_test "print unallowed int" = - parse "39482309482390842309482438208 + 2"; - [%expect {| - Parsing failed - |}] -;; - -let%expect_test "print nested let-ins" = - parse "let x = 5 in let y = 3 in x + y;; if 13 > 12 then let a = 2 in a - 4"; - [%expect - {| - let x = 5 in let y = 3 in x + y ;; - if 13 > 12 then let a = 2 in a - 4 ;; - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "y")), (Econst (Int 3)))), [], - (Ebin_op (Add, (Evar (Id "x")), (Evar (Id "y")))))) - ))); - (SEval - (Eif_then_else ((Ebin_op (Gt, (Econst (Int 13)), (Econst (Int 12)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Econst (Int 2)))), [], - (Ebin_op (Sub, (Evar (Id "a")), (Econst (Int 4)))))), - None))) - ] - |}] -;; - -let%expect_test "print multiple structure items" = - parse "let x = 5 ;; if 13 > 12 then let a = 2 in a + x"; - [%expect - {| - let x = 5 ;; - if 13 > 12 then let a = 2 in a + x ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [])); - (SEval - (Eif_then_else ((Ebin_op (Gt, (Econst (Int 13)), (Econst (Int 12)))), - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Econst (Int 2)))), [], - (Ebin_op (Add, (Evar (Id "a")), (Evar (Id "x")))))), - None))) - ] - |}] -;; - -let%expect_test "print correct pattern-matching" = - parse "let x = match 3 with | 1 -> 10 | 2 -> 20 | _ -> 30 ;;"; - [%expect - {| - let x = match 3 with | 1 -> 10 | 2 -> 20 | _ -> 30 ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), - (Ematch ((Econst (Int 3)), - (Ecase ((PConst (Int 1)), (Econst (Int 10)))), - [(Ecase ((PConst (Int 2)), (Econst (Int 20)))); - (Ecase (PAny, (Econst (Int 30))))] - )) - )), - [])) - ] - |}] -;; - -let%expect_test "print parenthesised expression" = - parse "((5 + 6) * (4 - 7)) - 1232"; - [%expect - {| - (5 + 6) * (4 - 7) - 1232 ;; - [(SEval - (Ebin_op (Sub, - (Ebin_op (Mult, (Ebin_op (Add, (Econst (Int 5)), (Econst (Int 6)))), - (Ebin_op (Sub, (Econst (Int 4)), (Econst (Int 7)))))), - (Econst (Int 1232))))) - ] - |}] -;; - -let%expect_test "print simple svalue" = - parse "let x = 5"; - [%expect - {| - let x = 5 ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Econst (Int 5)))), [])) - ] - |}] -;; - -let%expect_test "print list pattern" = - parse "[1; 2; 3] = 1"; - [%expect - {| - [1; 2; 3] = 1 ;; - [(SEval - (Ebin_op (Eq, - (Elist [(Econst (Int 1)); (Econst (Int 2)); (Econst (Int 3))]), - (Econst (Int 1))))) - ] - |}] -;; - -let%expect_test "print value with ascription" = - parse "let x : int = 42;;"; - [%expect - {| - let (x : int) = 42 ;; - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "x")), int)), (Econst (Int 42)) - )), - [])) - ] - |}] -;; - -let%expect_test "print function with ascription" = - parse "let f : int -> string = fun x -> string_of_int x;;"; - [%expect - {| - let (f : int -> string) = (fun x -> string_of_int x) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "f")), int -> string)), - (Efun ((PVar (Id "x")), [], - (Efun_application ((Evar (Id "string_of_int")), (Evar (Id "x")))))) - )), - [])) - ] - |}] -;; - -let%expect_test "print tuple with ascription" = - parse "let y : (int * string * bool) = (1, \"hello\", true);;"; - [%expect - {| - let (y : (int * string * bool)) = (1, "hello", true) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "y")), (int * string * bool))), - (Etuple ((Econst (Int 1)), (Econst (String "hello")), - [(Econst (Bool true))])) - )), - [])) - ] - |}] -;; - -let%expect_test "print list with ascription" = - parse "let l : int list = [1; 2; 3];;"; - [%expect - {| - let (l : int list) = [1; 2; 3] ;; - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "l")), int list)), - (Elist [(Econst (Int 1)); (Econst (Int 2)); (Econst (Int 3))]))), - [])) - ] - |}] -;; - -let%expect_test "print value with complex ascription" = - parse "let g : (int -> bool) list = [(fun x -> x > 0); (fun x -> x < 0)];;"; - [%expect - {| - let (g : (int -> bool) list) = [(fun x -> x > 0); (fun x -> x < 0)] ;; - [(SValue (Non_recursive, - (Evalue_binding ((PConstraint ((PVar (Id "g")), (int -> bool) list)), - (Elist - [(Efun ((PVar (Id "x")), [], - (Ebin_op (Gt, (Evar (Id "x")), (Econst (Int 0)))))); - (Efun ((PVar (Id "x")), [], - (Ebin_op (Lt, (Evar (Id "x")), (Econst (Int 0)))))) - ]) - )), - [])) - ] - |}] -;; - -let%expect_test "print function with ascription, multiple arguments" = - parse "let f : string -> (int -> bool) = fun x -> fun y -> x + y"; - [%expect - {| - let (f : string -> (int -> bool)) = (fun x -> (fun y -> x + y)) ;; - [(SValue (Non_recursive, - (Evalue_binding ( - (PConstraint ((PVar (Id "f")), string -> (int -> bool))), - (Efun ((PVar (Id "x")), [], - (Efun ((PVar (Id "y")), [], - (Ebin_op (Add, (Evar (Id "x")), (Evar (Id "y")))))) - )) - )), - [])) - ] - |}] -;; - -let%expect_test "print function with ascription using fun" = - parse "let f = fun (3, true): int*bool -> 4"; - [%expect - {| - let f = (fun ((3, true) : (int * bool)) -> 4) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "f")), - (Efun ( - (PConstraint ( - (PTuple ((PConst (Int 3)), (PConst (Bool true)), [])), - (int * bool))), - [], (Econst (Int 4)))) - )), - [])) - ] - |}] -;; - -let%expect_test "print function with ascription for arguments" = - parse "let f ((3, true) : int * bool) x ([ 7; 5 ] : int list) = 4"; - [%expect - {| - let f = (fun ((3, true) : (int * bool)) x ([7; 5] : int list) -> 4) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "f")), - (Efun ( - (PConstraint ( - (PTuple ((PConst (Int 3)), (PConst (Bool true)), [])), - (int * bool))), - [(PVar (Id "x")); - (PConstraint ((PList [(PConst (Int 7)); (PConst (Int 5))]), - int list)) - ], - (Econst (Int 4)))) - )), - [])) - ] - |}] -;; - -let%expect_test "print expr with unary and binary operations" = - parse - "let x = not true in let y = 13 in if x || (10 >= y) && (5 <= y) && (y <> 6) || (y < \ - 9) && (y > -1000) then +5 :: [] else [10] ;;"; - [%expect - {| - let x = not (true) in let y = 13 in if x || (10 >= y) && (5 <= y) && (y <> 6) || (y < 9) && (y > -(1000)) then +(5) :: [] else [10] ;; - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "x")), (Eun_op (Not, (Econst (Bool true)))) - )), - [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "y")), (Econst (Int 13)))), [], - (Eif_then_else ( - (Ebin_op (And, - (Ebin_op (Or, - (Ebin_op (And, - (Ebin_op (And, - (Ebin_op (Or, (Evar (Id "x")), - (Ebin_op (Gte, (Econst (Int 10)), (Evar (Id "y")) - )) - )), - (Ebin_op (Lte, (Econst (Int 5)), (Evar (Id "y")))))), - (Ebin_op (Neq, (Evar (Id "y")), (Econst (Int 6)))))), - (Ebin_op (Lt, (Evar (Id "y")), (Econst (Int 9)))))), - (Ebin_op (Gt, (Evar (Id "y")), - (Eun_op (Negative, (Econst (Int 1000)))))) - )), - (Ebin_op (Cons, (Eun_op (Positive, (Econst (Int 5)))), - (Elist []))), - (Some (Elist [(Econst (Int 10))])))) - )) - ))) - ] - |}] -;; - -let%expect_test "print expr with multiple patterns" = - parse "let a = Some 4 in let b = (c, [], not true) in let d = None in c :: [a]"; - [%expect - {| - let a = (Some 4) in let b = (c, [], not (true)) in let d = None in c :: [a] ;; - [(SEval - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "a")), (Eoption (Some (Econst (Int 4)))))), - [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "b")), - (Etuple ((Evar (Id "c")), (Elist []), - [(Eun_op (Not, (Econst (Bool true))))])) - )), - [], - (Elet (Non_recursive, - (Evalue_binding ((PVar (Id "d")), (Eoption None))), [], - (Ebin_op (Cons, (Evar (Id "c")), (Elist [(Evar (Id "a"))]))))) - )) - ))) - ] - |}] -;; - -let%expect_test "print expr with constraint" = - parse "let addi = fun f g x -> (f x (g x: bool) : int) "; - [%expect - {| - let addi = (fun f g x -> ((f x) ((g x : bool)) : int)) ;; - [(SValue (Non_recursive, - (Evalue_binding ((PVar (Id "addi")), - (Efun ((PVar (Id "f")), [(PVar (Id "g")); (PVar (Id "x"))], - (Econstraint ( - (Efun_application ( - (Efun_application ((Evar (Id "f")), (Evar (Id "x")))), - (Econstraint ( - (Efun_application ((Evar (Id "g")), (Evar (Id "x")))), - bool)) - )), - int)) - )) - )), - [])) - ] - |}] -;; diff --git a/OcamlBR/lib/pr_printer_tests.mli b/OcamlBR/lib/pr_printer_tests.mli deleted file mode 100644 index 435b54ba2..000000000 --- a/OcamlBR/lib/pr_printer_tests.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse : string -> unit diff --git a/OcamlBR/lib/qcheck.ml b/OcamlBR/lib/qcheck.ml deleted file mode 100644 index 2e395f282..000000000 --- a/OcamlBR/lib/qcheck.ml +++ /dev/null @@ -1,195 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open QCheck -open Ast -open Pr_printer -open Parser - -let rec shrink_pattern = function - | PVar _ -> Iter.empty - | PAny -> Iter.empty - | PConst (Int _) -> Iter.return (PConst (Int 1)) - | PConst (Bool b) -> Iter.return (PConst (Bool b)) - | PConst _ -> Iter.empty - | PList ls -> - Iter.( - let shrink_list_length = - map (fun ls' -> PList ls') (QCheck.Shrink.list ~shrink:shrink_pattern ls) - in - let shrink_elements = - List.fold_right - (fun e acc -> - map - (fun e' -> PList (List.map2 (fun x y -> if x = e then e' else y) ls ls)) - (shrink_pattern e) - <+> acc) - ls - empty - in - shrink_list_length <+> shrink_elements) - | PTuple (p1, p2, p3) -> - Iter.( - map (fun p1' -> PTuple (p1', p2, p3)) (shrink_pattern p1) - <+> map (fun p2' -> PTuple (p1, p2', p3)) (shrink_pattern p2) - <+> map - (fun p3' -> PTuple (p1, p2, p3')) - (QCheck.Shrink.list ~shrink:shrink_pattern p3)) - | PCons (p1, p2) -> - Iter.( - map (fun p1' -> PCons (p1', p2)) (shrink_pattern p1) - <+> map (fun p2' -> PCons (p1, p2')) (shrink_pattern p2)) - | POption (Some p) -> shrink_pattern p - | POption None -> Iter.empty - | PConstraint (p, t) -> Iter.(map (fun p' -> PConstraint (p', t)) (shrink_pattern p)) -;; - -let rec shrink_expr = function - | Econst (Int _) -> Iter.return (Econst (Int 1)) - | Econst (Bool b) -> Iter.return (Econst (Bool b)) - | Econst _ -> Iter.empty - | Ebin_op (op, e1, e2) -> - Iter.( - return e1 - <+> return e2 - <+> map (fun e1' -> Ebin_op (op, e1', e2)) (shrink_expr e1) - <+> map (fun e2' -> Ebin_op (op, e1, e2')) (shrink_expr e2) - <+> return (Ebin_op (Add, e1, e2))) - | Eun_op (_, e) -> - Iter.(return e <+> map (fun e' -> Eun_op (Negative, e')) (shrink_expr e)) - | Eif_then_else (cond_e, then_e, Some else_e) -> - Iter.( - return then_e - <+> return else_e - <+> map - (fun cond_e' -> Eif_then_else (cond_e', then_e, Some else_e)) - (shrink_expr cond_e) - <+> map - (fun then_e' -> Eif_then_else (cond_e, then_e', Some else_e)) - (shrink_expr then_e) - <+> map - (fun else_e' -> Eif_then_else (cond_e, then_e, Some else_e')) - (shrink_expr else_e)) - | Eif_then_else (cond_e, then_e, None) -> - Iter.( - return then_e - <+> map (fun cond_e' -> Eif_then_else (cond_e', then_e, None)) (shrink_expr cond_e) - <+> map (fun then_e' -> Eif_then_else (cond_e, then_e', None)) (shrink_expr then_e)) - | Eoption (Some e) -> shrink_expr e - | Eoption None -> Iter.empty - | Elist es -> - Iter.( - (*removing elements from the list *) - let shrink_list_length = - map (fun es' -> Elist es') (QCheck.Shrink.list ~shrink:shrink_expr es) - in - (* shrink each element within the list *) - let shrink_elements = - List.fold_right - (fun e acc -> - map - (fun e' -> Elist (List.map2 (fun x y -> if x = e then e' else y) es es)) - (shrink_expr e) - <+> acc) - es - empty - in - shrink_list_length <+> shrink_elements) - | Etuple (e1, e2, e3) -> - Iter.( - map (fun e1' -> Etuple (e1', e2, e3)) (shrink_expr e1) - <+> map (fun e2' -> Etuple (e1, e2', e3)) (shrink_expr e2) - <+> map - (fun e3' -> Etuple (e1, e2, e3')) - (QCheck.Shrink.list ~shrink:shrink_expr e3)) - | Elet (flag, vb, vb_l, e) -> - Iter.( - let shrink_value_binding_length = - map (fun vb_l' -> Elet (flag, vb, vb_l', e)) (QCheck.Shrink.list vb_l) - in - let shrink_elements = - List.fold_right - (fun a acc -> - map - (fun e' -> - Elet - (flag, vb, List.map2 (fun x y -> if x = a then e' else y) vb_l vb_l, e)) - (shrink_value_binding a) - <+> acc) - vb_l - empty - in - return e - <+> map (fun e' -> Elet (flag, vb, vb_l, e')) (shrink_expr e) - <+> shrink_value_binding_length - <+> map (fun vb' -> Elet (flag, vb', vb_l, e)) (shrink_value_binding vb) - <+> shrink_elements) - | Efun (pattern, patterns, body) -> - Iter.( - map (fun body' -> Efun (pattern, patterns, body')) (shrink_expr body) - <+> map (fun pattern' -> Efun (pattern', patterns, body)) (shrink_pattern pattern) - <+> map - (fun patterns' -> Efun (pattern, patterns', body)) - (QCheck.Shrink.list patterns)) - | Efun_application (e1, e2) -> - Iter.( - return e1 - <+> return e2 - <+> map (fun e1' -> Efun_application (e1', e2)) (shrink_expr e1) - <+> map (fun e2' -> Efun_application (e1, e2')) (shrink_expr e2)) - | Ematch (e, case, case_l) -> - Iter.( - let shrink_cases_length = - map (fun cases' -> Ematch (e, case, cases')) (QCheck.Shrink.list case_l) - in - map (fun e' -> Ematch (e', case, case_l)) (shrink_expr e) <+> shrink_cases_length) - | Econstraint (e, _) -> shrink_expr e - | _ -> Iter.empty - -and shrink_value_binding = function - | Evalue_binding (id, e) -> - Iter.(map (fun e' -> Evalue_binding (id, e')) (shrink_expr e)) -;; - -let shrink_structure_item = function - | SEval e -> Iter.(map (fun e' -> SEval e') (shrink_expr e)) - | SValue (r, vb, vb_l) -> - Iter.( - let shrink_value_binding_length = - map (fun vb_l' -> SValue (r, vb, vb_l')) (QCheck.Shrink.list vb_l) - in - map (fun vb' -> SValue (r, vb', vb_l)) (shrink_value_binding vb) - <+> shrink_value_binding_length) -;; - -let shrink_structure structure : structure Iter.t = - match structure with - | [] -> Iter.empty - | _ -> - Iter.( - let shrink_elements = - List.fold_right - (fun e acc -> - map - (fun e' -> - List.map2 (fun x y -> if x = e then e' else y) structure structure) - (shrink_structure_item e) - <+> acc) - structure - empty - in - QCheck.Shrink.list structure <+> shrink_elements) -;; - -let arbitrary_structure = - make gen_structure ~print:(Format.asprintf "%a" prpr_structure) ~shrink:shrink_structure -;; - -let run_auto n = - QCheck_base_runner.run_tests - [ QCheck.( - Test.make arbitrary_structure ~count:n (fun structure -> - Result.ok structure = parse_expr (Format.asprintf "%a" prpr_structure structure))) - ] -;; diff --git a/OcamlBR/lib/qcheck.mli b/OcamlBR/lib/qcheck.mli deleted file mode 100644 index 900c8429e..000000000 --- a/OcamlBR/lib/qcheck.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run_auto : int -> int diff --git a/OcamlBR/lib/run_qcheck.ml b/OcamlBR/lib/run_qcheck.ml deleted file mode 100644 index ea1ee7b80..000000000 --- a/OcamlBR/lib/run_qcheck.ml +++ /dev/null @@ -1,20 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlBR.Qcheck - -let run_tests n = - let _ = run_auto n in - () -;; - -let () = - Arg.parse - [ "-seed", Arg.Int QCheck_base_runner.set_seed, " Set seed" - ; "-stop", Arg.Unit (fun _ -> exit 0), " Exit" - ; "-gen", Arg.Int run_tests, " Number of runs" - ] - (fun _ -> assert false) - "help" -;; diff --git a/OcamlBR/lib/typedtree.ml b/OcamlBR/lib/typedtree.ml deleted file mode 100644 index 56796fc2f..000000000 --- a/OcamlBR/lib/typedtree.ml +++ /dev/null @@ -1,104 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type type_var = int [@@deriving show { with_path = false }] - -module VarSet = struct - include Stdlib.Set.Make (Int) - - let pp ppf s = - Format.fprintf ppf "[ "; - iter (Format.fprintf ppf "%d; ") s; - Format.fprintf ppf "]" - ;; -end - -(* actual types *) -type ty = - | TPrim of string - | TVar of type_var - | TArrow of ty * ty - | TTuple of ty * ty * ty list - | TList of ty - | TOption of ty (* | TRecord of string *) -[@@deriving show { with_path = false }] - -let gen_tprim = - let open QCheck.Gen in - let tprim = oneofl [ "int"; "string"; "bool"; "unit" ] in - map (fun t -> TPrim t) tprim -;; - -type scheme = S of VarSet.t * ty [@@deriving show { with_path = false }] - -(* utility functions *) -let tprim_int = TPrim "int" -let tprim_string = TPrim "string" -let tprim_bool = TPrim "bool" -let tprim_unit = TPrim "unit" -let tarrow l r = TArrow (l, r) -let ( @-> ) = tarrow -let tlist ty = TList ty -(* let trecord s = TRecord s *) - -let rec pp_ty ppf = - let open Format in - function - | TVar n -> fprintf ppf "'%d" n - | TPrim s -> fprintf ppf "%s" s - | TArrow (l, r) -> - fprintf - ppf - "%a -> %a" - (fun ppf l -> - match l with - | TArrow _ -> fprintf ppf "(%a)" pp_ty l - | _ -> pp_ty ppf l) - l - (fun ppf r -> - match r with - | TArrow _ -> fprintf ppf "(%a)" pp_ty r - | _ -> pp_ty ppf r) - r - | TList t -> - (match t with - | TArrow _ -> fprintf ppf "(%a) list" pp_ty t - | _ -> fprintf ppf "%a list" pp_ty t) - | TTuple (t1, t2, rest) -> - let tuple_content = - String.concat " * " (List.map (Format.asprintf "%a" pp_ty) (t1 :: t2 :: rest)) - in - fprintf ppf "(%s)" tuple_content - | TOption t -> fprintf ppf "(%a) option" pp_ty t -;; - -(* | TRecord s -> fprintf ppf "%s" s *) - -(* errors *) -type error = - [ `Occurs_check of string * ty - | `Undefined_variable of string - | `Unification_failed of ty * ty - | `Ill_left_hand_side of string (* e.g. let 0 = 1, let rec (a, b) = <..> *) - | `Ill_right_hand_side of string (* e.g. let rec x = x + 1 *) - | `Duplicate_field_labels of string - | `Undefined_type of string - | `Multiple_definition_of_type of string - | `Unexpected_function_type of ty - ] - -let pp_error ppf = function - | `Occurs_check (s, t) -> Format.fprintf ppf {|Occurs check failed: %s %a|} s pp_ty t - | `Undefined_variable s -> Format.fprintf ppf {|Undefined variable %S|} s - | `Unification_failed (l, r) -> - Format.fprintf ppf {|Unification failed on %a and %a|} pp_ty l pp_ty r - | `Ill_left_hand_side s -> Format.fprintf ppf {|Ill left-hand side %s|} s - | `Ill_right_hand_side s -> Format.fprintf ppf {|Ill right-hand side %s|} s - | `Duplicate_field_labels s -> Format.fprintf ppf {|Duplicate field labels: %s|} s - | `Undefined_type s -> Format.fprintf ppf {|Undefined type: %s|} s - | `Multiple_definition_of_type s -> - Format.fprintf ppf {|Multiple definition of type name %s|} s - | `Unexpected_function_type t -> - Format.fprintf ppf {|Expected function type, got: %a|} pp_ty t -;; diff --git a/OcamlBR/lib/typedtree.mli b/OcamlBR/lib/typedtree.mli deleted file mode 100644 index cb5300f4a..000000000 --- a/OcamlBR/lib/typedtree.mli +++ /dev/null @@ -1,75 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type type_var = int - -val pp_type_var : Format.formatter -> type_var -> unit -val show_type_var : type_var -> string - -module VarSet : sig - type elt = type_var - type t = Set.Make(Int).t - - val empty : t - val is_empty : t -> bool - val mem : elt -> t -> bool - val add : elt -> t -> t - val singleton : elt -> t - val remove : elt -> t -> t - val union : t -> t -> t - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a - val diff : t -> t -> t - val inter : t -> t -> t -end - -type ty = - | TPrim of string - | TVar of type_var - | TArrow of ty * ty - | TTuple of ty * ty * ty list - | TList of ty - | TOption of ty -(* | TRecord of string *) - -val pp_ty : Format.formatter -> ty -> unit -val show_ty : ty -> string -val gen_tprim : ty QCheck.Gen.t - -type scheme = S of VarSet.t * ty - -val pp_scheme : Format.formatter -> scheme -> unit -val show_scheme : scheme -> string -val tprim_int : ty -val tprim_string : ty -val tprim_bool : ty -val tprim_unit : ty -val tarrow : ty -> ty -> ty -val ( @-> ) : ty -> ty -> ty -val tlist : ty -> ty - -type error = - [ `Occurs_check of string * ty - | `Undefined_variable of string - | `Unification_failed of ty * ty - | `Ill_left_hand_side of string - | `Ill_right_hand_side of string - | `Duplicate_field_labels of string - | `Undefined_type of string - | `Multiple_definition_of_type of string - | `Unexpected_function_type of ty - ] - -val pp_error - : Format.formatter - -> [< `Occurs_check of string * ty - | `Undefined_variable of string - | `Unification_failed of ty * ty - | `Ill_left_hand_side of string - | `Ill_right_hand_side of string - | `Duplicate_field_labels of string - | `Undefined_type of string - | `Multiple_definition_of_type of string - | `Unexpected_function_type of ty - ] - -> unit diff --git a/OcamlBR/lib/values.ml b/OcamlBR/lib/values.ml deleted file mode 100644 index 20fc30759..000000000 --- a/OcamlBR/lib/values.ml +++ /dev/null @@ -1,78 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -type builtin = - | BInt of (int -> unit) - | BString of (string -> unit) - -type value = - | VInt of int - | VBool of bool - | VString of string - | VUnit - | VList of value list - | VTuple of value * value * value list - | VFun of rec_flag * pattern * pattern list * expr * environment - | VOption of value option - | VBuiltin of builtin - | VFunction of case * case list -(* | VRecord of string * (label * value) * (label * value) list *) - -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -let rec pp_value ppf = - let open Stdlib.Format in - function - | VInt x -> fprintf ppf "%d" x - | VBool b -> fprintf ppf "%b" b - | VString s -> fprintf ppf "%S" s - | VUnit -> fprintf ppf "()" - | VList vl -> - fprintf - ppf - "[%a]" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf "; ") pp_value) - vl - | VTuple (v1, v2, vl) -> - fprintf - ppf - "(%a, %a%a)" - pp_value - v1 - pp_value - v2 - (fun ppf -> function - | [] -> () - | rest -> - fprintf - ppf - ", %a" - (pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ", ") pp_value) - rest) - vl - | VFun _ | VFunction _ -> fprintf ppf "" - | VOption v -> - (match v with - | Some v -> fprintf ppf "Some %a" pp_value v - | None -> fprintf ppf "None") - | VBuiltin _ -> fprintf ppf "" -;; - -type error = - [ `Division_by_zero - | `Unbound_variable of string - | `Pattern_matching_failure - | `Type_error - | `Ill_left_hand_side of string - ] - -let pp_error ppf : error -> unit = function - | `Division_by_zero -> Format.fprintf ppf {|Division by zero|} - | `Unbound_variable s -> Format.fprintf ppf {|Unbound variable: %s|} s - | `Pattern_matching_failure -> Format.fprintf ppf {|Pattern-matching failure|} - | `Type_error -> Format.fprintf ppf {|Type error|} - | `Ill_left_hand_side s -> Format.fprintf ppf {|Ill left-hand side %s|} s -;; diff --git a/OcamlBR/lib/values.mli b/OcamlBR/lib/values.mli deleted file mode 100644 index ee207b204..000000000 --- a/OcamlBR/lib/values.mli +++ /dev/null @@ -1,33 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -type builtin = - | BInt of (int -> unit) - | BString of (string -> unit) - -type value = - | VInt of int - | VBool of bool - | VString of string - | VUnit - | VList of value list - | VTuple of value * value * value list - | VFun of Ast.rec_flag * Ast.pattern * Ast.pattern list * Ast.expr * environment - | VOption of value option - | VBuiltin of builtin - | VFunction of Ast.case * Ast.case list - -and environment = (string, value, Base.String.comparator_witness) Base.Map.t - -val pp_value : Format.formatter -> value -> unit - -type error = - [ `Division_by_zero - | `Unbound_variable of string - | `Pattern_matching_failure - | `Type_error - | `Ill_left_hand_side of string - ] - -val pp_error : Format.formatter -> error -> unit diff --git a/OcamlBR/repl/dune b/OcamlBR/repl/dune deleted file mode 100644 index 147a7d160..000000000 --- a/OcamlBR/repl/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name repl) - (public_name OCamlBR_main) - (libraries OCamlBR base stdio) - (instrumentation - (backend bisect_ppx))) diff --git a/OcamlBR/repl/input.txt b/OcamlBR/repl/input.txt deleted file mode 100644 index 230388ae6..000000000 --- a/OcamlBR/repl/input.txt +++ /dev/null @@ -1,2 +0,0 @@ -let rec factorial n = if n = 0 then 1 else n * factorial (n - 1) in -factorial 5 diff --git a/OcamlBR/repl/repl.ml b/OcamlBR/repl/repl.ml deleted file mode 100644 index 0802580a5..000000000 --- a/OcamlBR/repl/repl.ml +++ /dev/null @@ -1,90 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open OCamlBR.Ast -open OCamlBR.Parser -open OCamlBR.Interpreter_tests -open OCamlBR.Inferencer_tests -open Base -open Stdio - -type stop_after = - | SA_parsing - | SA_never - -type opts = - { mutable dump_parsetree : bool - ; mutable stop_after : stop_after - ; mutable input_file : string option - ; mutable interpret : bool - ; mutable inference : bool - } - -let eval ast = - ignore (show_structure ast); - (* eval will be here soon *) - () -;; - -let run_single dump_parsetree stop_after interpret inference eval input_source = - let text = - match input_source with - | Some file_name -> In_channel.read_all file_name |> Stdlib.String.trim - | None -> In_channel.input_all stdin |> Stdlib.String.trim - in - match parse_expr text with - | Error e -> Stdlib.Format.printf "Parsing error: %s\n%!" e - | Ok ast -> - if dump_parsetree then print_endline (show_structure ast); - (match stop_after with - | SA_parsing -> () - | SA_never -> - if inference then infer_program_test text; - if interpret then test_interpret text; - eval ast) -;; - -let () = - let opts = - { dump_parsetree = false - ; stop_after = SA_never - ; input_file = None - ; interpret = false - ; inference = false - } - in - let () = - Stdlib.Arg.parse - [ ( "-dparsetree" - , Stdlib.Arg.Unit (fun () -> opts.dump_parsetree <- true) - , "Dump parse tree, don't evaluate anything" ) - ; ( "-stop-after" - , Stdlib.Arg.String - (function - | "parsing" -> opts.stop_after <- SA_parsing - | _ -> failwith "Bad argument for -stop-after") - , "Stop after parsing" ) - ; ( "-fromfile" - , Stdlib.Arg.String (fun filename -> opts.input_file <- Some filename) - , "Read code from the specified file" ) - ; ( "-interpret" - , Stdlib.Arg.Unit (fun () -> opts.interpret <- true) - , "Interpret the parsed code" ) - ; ( "-inference" - , Stdlib.Arg.Unit (fun () -> opts.inference <- true) - , "Perform type inference on the parsed code" ) - ] - (fun _ -> - Stdlib.Format.eprintf "Positional arguments are not supported\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for custom language" - in - run_single - opts.dump_parsetree - opts.stop_after - opts.interpret - opts.inference - (fun ast -> eval ast) - opts.input_file -;; diff --git a/OcamlBR/tests/.ocamlformat b/OcamlBR/tests/.ocamlformat deleted file mode 100644 index e7dae9c54..000000000 --- a/OcamlBR/tests/.ocamlformat +++ /dev/null @@ -1 +0,0 @@ -disable=true \ No newline at end of file diff --git a/OcamlBR/tests/dune b/OcamlBR/tests/dune deleted file mode 100644 index 3fbbb27ab..000000000 --- a/OcamlBR/tests/dune +++ /dev/null @@ -1,11 +0,0 @@ -(cram - (applies_to qcheck) - (deps ../lib/run_qcheck.exe)) - -(cram - (applies_to run) - (deps ../repl/repl.exe)) - -(cram - (applies_to infer) - (deps ../repl/repl.exe)) diff --git a/OcamlBR/tests/infer.t b/OcamlBR/tests/infer.t deleted file mode 100644 index 3ec8e5194..000000000 --- a/OcamlBR/tests/infer.t +++ /dev/null @@ -1,163 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -Test '001fac': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/001fac.ml - val fac : int -> int - val main : int - -Test '002fac': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/002fac.ml - val fac_cps : int -> ((int -> int) -> int) - val main : int - -Test '003fib': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/003fib.ml - val fib : int -> int - val fib_acc : int -> (int -> (int -> int)) - val main : int - -Test '004manyargs': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/004manyargs.ml - val main : int - val test10 : int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> int))))))))) - val test3 : int -> (int -> (int -> int)) - val wrap : '0 -> '0 - -Test '005fix': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/005fix.ml - val fac : (int -> int) -> (int -> int) - val fix : ((int -> int) -> (int -> int)) -> (int -> int) - val main : int - -Test '006partial': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/006partial.ml - val foo : int -> int - val main : int - -Test '006partial2': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/006partial2.ml - val foo : int -> (int -> (int -> int)) - val main : int - -Test '006partial3': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/006partial3.ml - val foo : int -> (int -> (int -> unit)) - val main : int - -Test '007order': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/007order.ml - val _start : unit -> (unit -> (int -> (unit -> (int -> (int -> (unit -> (int -> (int -> int)))))))) - val main : unit - -Test '008ascription': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/008ascription.ml - val addi : ('2 -> (bool -> int)) -> (('2 -> bool) -> ('2 -> int)) - val main : int - -Test '009letpoly': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/009let_poly.ml - val temp : (int * bool) - -Test '010': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/010sukharev.ml - val _1 : int -> (int -> ((int * '3) -> bool)) - val _2 : int - val _3 : ((int * string)) option - val _4 : int -> '10 - val _42 : int -> bool - val _5 : int - val _6 : ('23) option -> '23 - val id1 : '32 -> '32 - val id2 : '33 -> '33 - val int_of_option : (int) option -> int - -Test '015tuples': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/015tuples.ml - val feven : ('29 * int -> int) -> (int -> int) - val fix : ((((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int)) -> (((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int))) -> (((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int)) - val fixpoly : ((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int) - val fodd : (int -> int * '36) -> (int -> int) - val main : int - val map : ('9 -> '11) -> (('9 * '9) -> ('10 * '11)) - val meven : int -> int - val modd : int -> int - val tie : (int -> int * int -> int) - -Test '016lists': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/typed/016lists.ml - val append : (int * int) list -> ((int * int) list -> (int * int) list) - val cartesian : int list -> (int list -> (int * int) list) - val concat : (int * int) list list -> (int * int) list - val iter : (int -> unit) -> (int list -> unit) - val length : (int * int) list -> int - val length_tail : '16 list -> int - val main : int - val map : (int -> (int * int)) -> (int list -> (int * int) list) - -Test '001': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/001.ml - Infer error: Undefined variable "fac" - -Test '002if': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/002if.ml - Infer error: Unification failed on int and bool - -Test '003occurs': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/003occurs.ml - Infer error: Occurs check failed: type variable 1 inside type '1 -> '3 - -Test '004let_poly': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/004let_poly.ml - Infer error: Unification failed on int and bool - -Test '015tuples': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/015tuples.ml - Infer error: Ill left-hand side : only variables are allowed - -Test '016tuples_mismatch': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/016tuples_mismatch.ml - Infer error: Unification failed on ('0 * '1) and (int * int * int) - -Test '097fun_vs_list': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/097fun_vs_list.ml - Infer error: Unification failed on '2 list and '0 -> '0 - -Test '097fun_vs_unit': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/097fun_vs_unit.ml - Infer error: Unification failed on unit and '0 -> '0 - -Test '098rec_int': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/098rec_int.ml - Infer error: Ill right-hand side of let rec - -Test '099': - - $ dune exec ../repl/repl.exe -- -inference -fromfile ../../../../../../manytests/do_not_type/099.ml - Infer error: Ill left-hand side : only variables are allowed - - diff --git a/OcamlBR/tests/manytests b/OcamlBR/tests/manytests deleted file mode 120000 index 0bd48791d..000000000 --- a/OcamlBR/tests/manytests +++ /dev/null @@ -1 +0,0 @@ -../../manytests \ No newline at end of file diff --git a/OcamlBR/tests/qcheck.t b/OcamlBR/tests/qcheck.t deleted file mode 100644 index 5cbd3b929..000000000 --- a/OcamlBR/tests/qcheck.t +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2024, Sofya Kozyreva, Maksim Shipilov -SPDX-License-Identifier: LGPL-3.0-or-later - - $ ../lib/run_qcheck.exe -seed 485903 -gen 3 -stop - random seed: 485903 - ================================================================================ - success (ran 1 tests) diff --git a/OcamlBR/tests/run.t b/OcamlBR/tests/run.t deleted file mode 100644 index f92548dba..000000000 --- a/OcamlBR/tests/run.t +++ /dev/null @@ -1,205 +0,0 @@ -(** Copyright 2024, Sofya Kozyreva, Maksim Shipilov *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -Test '001fac': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/001fac.ml - 24 - { - val fac : int -> int = - val main : int = 0 - } - -Test '002fac': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/002fac.ml - 24 - { - val fac_cps : int -> ((int -> int) -> int) = - val main : int = 0 - } - -Test '003fib': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/003fib.ml - 33 - { - val fib : int -> int = - val fib_acc : int -> (int -> (int -> int)) = - val main : int = 0 - } - -Test '004manyargs': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/004manyargs.ml - 1111111111110100 - { - val main : int = 0 - val test10 : int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> (int -> int))))))))) = - val test3 : int -> (int -> (int -> int)) = - val wrap : '0 -> '0 = - } - -Test '005fix': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/005fix.ml - 720 - { - val fac : (int -> int) -> (int -> int) = - val fix : ((int -> int) -> (int -> int)) -> (int -> int) = - val main : int = 0 - } - -Test '006partial': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/006partial.ml - 1122 - { - val foo : int -> int = - val main : int = 0 - } - -Test '006partial2': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/006partial2.ml - 1237 - { - val foo : int -> (int -> (int -> int)) = - val main : int = 0 - } - -Test '006partial3': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/006partial3.ml - 489 - { - val foo : int -> (int -> (int -> unit)) = - val main : int = 0 - } - -Test '007order': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/007order.ml - 124-1103-55555510000 - { - val _start : unit -> (unit -> (int -> (unit -> (int -> (int -> (unit -> (int -> (int -> int)))))))) = - val main : unit = () - } - -Test '008ascription': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/008ascription.ml - 8 - { - val addi : ('2 -> (bool -> int)) -> (('2 -> bool) -> ('2 -> int)) = - val main : int = 0 - } - -Test '009letpoly': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/009let_poly.ml - - { - val temp : (int * bool) = (1, true) - } - -Test '010': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/010sukharev.ml - - { - val _1 : int -> (int -> ((int * '3) -> bool)) = - val _2 : int = 1 - val _3 : ((int * string)) option = Some (1, "hi") - val _4 : int -> '10 = - val _42 : int -> bool = - val _5 : int = 42 - val _6 : ('23) option -> '23 = - val id1 : '32 -> '32 = - val id2 : '33 -> '33 = - val int_of_option : (int) option -> int = - } - -Test '015tuples': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/015tuples.ml - 1111 - { - val feven : ('29 * int -> int) -> (int -> int) = - val fix : ((((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int)) -> (((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int))) -> (((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int)) = - val fixpoly : ((int -> int * int -> int) -> (int -> int) * (int -> int * int -> int) -> (int -> int)) -> (int -> int * int -> int) = - val fodd : (int -> int * '36) -> (int -> int) = - val main : int = 0 - val map : ('9 -> '11) -> (('9 * '9) -> ('10 * '11)) = - val meven : int -> int = - val modd : int -> int = - val tie : (int -> int * int -> int) = (, ) - } - -Test '016lists': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/typed/016lists.ml - 1238 - { - val append : (int * int) list -> ((int * int) list -> (int * int) list) = - val cartesian : int list -> (int list -> (int * int) list) = - val concat : (int * int) list list -> (int * int) list = - val iter : (int -> unit) -> (int list -> unit) = - val length : (int * int) list -> int = - val length_tail : '16 list -> int = - val main : int = 0 - val map : (int -> (int * int)) -> (int list -> (int * int) list) = - } - -Test '001': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/001.ml - Infer error: Undefined variable "fac" - -Test '002if': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/002if.ml - Infer error: Unification failed on int and bool - -Test '003occurs': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/003occurs.ml - Infer error: Occurs check failed: type variable 1 inside type '1 -> '3 - -Test '004let_poly': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/004let_poly.ml - Infer error: Unification failed on int and bool - -Test '015tuples': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/015tuples.ml - Infer error: Ill left-hand side : only variables are allowed - -Test '016tuples_mismatch': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/016tuples_mismatch.ml - Infer error: Unification failed on ('0 * '1) and (int * int * int) - -Test '097fun_vs_list': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/097fun_vs_list.ml - Infer error: Unification failed on '2 list and '0 -> '0 - -Test '097fun_vs_unit': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/097fun_vs_unit.ml - Infer error: Unification failed on unit and '0 -> '0 - -Test '098rec_int': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/098rec_int.ml - Infer error: Ill right-hand side of let rec - -Test '099': - - $ dune exec ../repl/repl.exe -- -interpret -fromfile ../../../../../../manytests/do_not_type/099.ml - Infer error: Ill left-hand side : only variables are allowed - - diff --git a/README.md b/README.md deleted file mode 100644 index b432f2b19..000000000 --- a/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# ФП 2024. Репо для домашек - -Домашки по курсу ФП 2024 оформлять **в виде пулл-реквестов к этому репо**. -Если у вас уже был PR с некоторой подзадачей, допушивать изменения надо в тот PR. Создавать новый c тем же самым неправильно, нельзя, запрещено. -История изненений должна быть линейной, то есть **merge-коммиты запрещены** (научитесь пользоваться `git rebase`) - -Учебная группа имеет чатик в мессенджере. Все вопросы писать туда. В личку писать нельзя -- буду банить. - -В директории `/Lambda` лежит шаблон-скелет, его нужно скопипастить и исправить под свои нужды: -- Указать автора (я должен быть способен сопоставить решение с ФИО в ведомости) -- Переименовать проект под свой мини-язык и пересобрать dune'ой. CI при сборке ожидает имя проекта, совпадающее с именем директории. **И так как имя проекта это `[a-zA-Z_]+`, то у директорий с пробелами и символами `#` шансов пройти CI нет** -- Cделать реализацию. Разработку рекомендуется вести итеративной моделью, а не водопадной. -- Изменять или удалять шаблон `Lambda` нельзя (буду рисовать минус баллы). - -Ожидается примерно следующая структура репозитория -- `/Lambda` -- шаблон проекта домашки, который редактирует только препод (вам необходимо будет его скопировать и переименовать, редактировать нельзя, удалившим его буду ставить минус баллы); -- `/CSharpExc` -- реализация мини-С# c исключениями, на основе шаблона `/Lambda`; -- `/Java` -- реализация мини-Java, снова на основе шаблона `/Lambda`; -- и т.д. - -Для Merge Requests (a.k.a. pull requests) настроен CI, который смотрит *в какой директории* (проекте) *произошли последние изменения*, -*и именно в этой директории запускает сборку и тесты*. -Например, если поменялся файл `Lambda/src/Parser.ml`, то запустятся все тесты из директории проекта `Lambda`, -а тесты из проекта `Java` запускаться не будут. - - -Также CI собирает документацию к миниязыку и выкладывает её в https://kakadu.github.io/fp2024/doc/LANGUAGE (например, [вот так](https://kakadu.github.io/fp2024/doc/Lambda)). -А ещё измеряется покрытие тестами (например, [так](https://kakadu.github.io/fp2024/cov/Lambda)). - -###### N.B. Не удаляйте директорию Lambda. Это шаблон! - - -### Подготовка окружения - -Далее инструкции по найстройки всего под GNU/Linux. Но на Windows+WSL2 тоже должно работать. - -Во-первых, нужен пакетный менеджер opam версии 2.х. С помощью него будем устанавливать OCaml 4.14.1 и необходимые пакеты. -Системный OCaml (установленный, например, из репозиториев Ubuntu) использовать не рекомендуется. - -После установки opam следует его проинициализировать и установить правильный компилятор (у меня обычно вместо SWITCHNAME используется `4.14.2+flambda`) - -Для opam >= 2.1: - - opam init --bare - opam update - opam switch create SWITCHNAME --packages=ocaml-variants.4.14.2+options,ocaml-option-flambda --yes - -Перед этим можно удалить другие switch'и, если они есть, с помощью команды `opam switch remove SWITCHNAME`. - -После установки у вас будет рабочий компилятор по-умолчанию в директории `~/.opam/SWITCHNAME/bin`. В конце установки opam вам предложит что-то добавить в ~/.bashrc, чтобы пути к компилятору автоматически подхватывались. Рекомендую это сделать. - -Если что-то пошло не так, то всегда можно указать нужный свитч руками командой, например: - - export OPAMSWITCH=SWITCHNAME && eval $(opam env) - -и затем убедиться, что путь до компилятора правильный - - $ which ocamlopt - /home/username/.opam/SWITCHNAME/bin/ocamlopt - - -#### VsCode - -В процессе работы вам также понадобится пакеты из опам в том числе для разработки в VsCode. -Скорее всего необходимый минимум установится с помощью `make deps` - - $ which ocamlformat - /home/username/.opam/SWITCHNAME/bin/ocamlformat - -Когда вы будете запускать VsCode, то информация об окружении opam из файла `~/.bashrc` автоматически применяться не будет, потому что так это работает в UNIX системах из покон веков. -Чтобы облегчить себе возню с окружением, рекомендуется пользоваться утилитой `direnv`. -Подробнее читать [here](https://ocaml.org/docs/opam-path#using-direnv). - -Если `direnv` пока не установили, но хочется попробовать VsCode, то нужно его запускать из-под opam командой `opam exec -- code`, либо прописать в месте запуска правильную переменную среды OPAMSWITCH, и запускать opam через sh: `sh -c 'eval $(opam env) && code'` - -Когда VsCode запустится, её плагин https://marketplace.visualstudio.com/items?itemName=ocamllabs.ocaml-platform слева снизу должен показать, что правильная версия компилятора подцепилась. - -![alt text](https://github.com/Kakadu/fp2024/blob/master/vscode.png?raw=true) - - -Необходимо также в VsCode включить автоформатирование: `Settings`->`Text Editor`->`Formatting`->`Format On Paste` и `Format on Save`. - -### Приёмка задач - -Система оценивания подробно описана в [`grading.md`](grading.md). - -Решения принимаются в виде пулл-реквестов к этому репо. -* В названии надо указать задачу, которую реализовывали, идентифицировать себя (фамилия, имя и курс, если возможны неоднозначности). -* Пулл-реквесты должны проходить CI - * Ворнинги и ошибки компилятора должны быть исправлены - * В том числе линтер (его замечания **нужно** исправлять); - * проверку, что автоформатирование через ocamlformat настроено и соблюдается; - * Все мои замечания по коду должны быть исправлены. - - Если уверены, что исправили, пометьте как resolved - - Если не уверены или они непонятны/некорректны, то опишитесь в комменте - - * [DCO](https://github.com/apps/dco); скорее всего осилить [Git aliases](https://gist.github.com/josegonzalez/565837) и добавить +1 сокращение будет достаточно: - - ```` - [alias] - ci = commit -s - ```` - -* К дереву абстрактного синтаксиса (AST) должны быть написаны комменты, какой конструтор за что отвечает. (Например, [как здесь](https://github.com/ocaml/ocaml/blob/4.14/parsing/parsetree.mli#L323).) -* Используйте [quoted string literals](https://batsov.com/articles/2023/04/20/learning-ocaml-quoted-string-literals), чтобы не экранировать длинные строки руками - - ```` - let quoted_greeting = {|"Hello, World!"|} - val quoted_greeting : string = "\"Hello, World!\"" - ```` - -* Да, объекты и присваивание запрещены. -* Иимена типов и функций -- snake_case -* Имена типов модулей и модулей -- CamelCase - -Тесты нужны, чтобы убедить преподавателя, что вы таки запускали свою поделку на адекватных примерах. -Большинство тестов будут интеграционные: запустил самописный интерпретатор миниязыка и сравнил с результатом (например, с поведением интерпретатора оригинального языка). -В CI измеряeтся тестовое покрытие в процентах. Чем больше покрытие --- тем лучше. -Если код не вызывается в тестах, то либо он не нужен, либо на него не написан тест, либо (в редких случаях) это бага `ppx_bisect`, который измеряет покрытие. Чтобы покрытие тестами таки считалось, не забывайте приписывать к своим библиотекам/исполняемым файлом заклинание в dune-файлах: - - (instrumentation - (backend bisect_ppx)) diff --git a/RISCV_ASM/.envrc b/RISCV_ASM/.envrc deleted file mode 100644 index e6bd6786d..000000000 --- a/RISCV_ASM/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -export OPAMSWITCH=4.14.2+flambda -eval $(opam env) - diff --git a/RISCV_ASM/.gitignore b/RISCV_ASM/.gitignore deleted file mode 100644 index 7102a822c..000000000 --- a/RISCV_ASM/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_build -_coverage -/_esy -/node_modules -/esy.lock -/.melange.eobjs diff --git a/RISCV_ASM/.ocamlformat b/RISCV_ASM/.ocamlformat deleted file mode 100644 index 97f970802..000000000 --- a/RISCV_ASM/.ocamlformat +++ /dev/null @@ -1,2 +0,0 @@ -profile=janestreet -version=0.26.2 diff --git a/RISCV_ASM/.vscode/settings.json b/RISCV_ASM/.vscode/settings.json deleted file mode 100644 index b0d06989d..000000000 --- a/RISCV_ASM/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "makefile.configureOnOpen": true -} \ No newline at end of file diff --git a/RISCV_ASM/.zanuda b/RISCV_ASM/.zanuda deleted file mode 100644 index 0f09b19b2..000000000 --- a/RISCV_ASM/.zanuda +++ /dev/null @@ -1 +0,0 @@ -forward mutability_check ignore REPL.ml diff --git a/RISCV_ASM/COPYING b/RISCV_ASM/COPYING deleted file mode 100644 index 6c1a68339..000000000 --- a/RISCV_ASM/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - RISC-V_ASM_interpreter is a interpreter of a mini-language similiar to RISC-V ASM. - Copyright (C) <2024-2025> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/RISCV_ASM/COPYING.LESSER b/RISCV_ASM/COPYING.LESSER deleted file mode 100644 index 0a041280b..000000000 --- a/RISCV_ASM/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/RISCV_ASM/Makefile b/RISCV_ASM/Makefile deleted file mode 100644 index 727baa915..000000000 --- a/RISCV_ASM/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -.PHONY: tests test fmt lint celan - -all: - dune build - -tests: test -test: - dune runtest - -clean: - @$(RM) -r _build _coverage - -fmt: - dune build @fmt --auto-promote - -lint: - dune build @lint --force - -release: - dune build --profile=release - dune runtest --profile=release - -install: - dune b @install --profile=release - dune install - -ODIG_SWITCHES = --odoc-theme=odig.gruvbox.light -ODIG_SWITCHES += --no-tag-index -ODIG_SWITCHES += --no-pkg-deps -odig: - odig odoc $(ODIG_SWITCHES) Lambda - -TEST_COV_D = /tmp/cov -COVERAGE_OPTS = --coverage-path $(TEST_COV_D) --expect lib/ --expect tests/ - -.PHONY: test_coverage coverage -test_coverage: coverage -coverage: - $(RM) -r $(TEST_COV_D) - mkdir -p $(TEST_COV_D) - BISECT_FILE=$(TEST_COV_D)/langauge dune runtest --no-print-directory \ - --instrument-with bisect_ppx --force - bisect-ppx-report html $(COVERAGE_OPTS) - bisect-ppx-report summary $(COVERAGE_OPTS) - @echo "Use 'xdg-open _coverage/index.html' to see coverage report" diff --git a/RISCV_ASM/README.md b/RISCV_ASM/README.md deleted file mode 100644 index 3f14274f5..000000000 --- a/RISCV_ASM/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# RISC-V 64 ASM Mini-Language - -## Functionality and status -* AST - complete -* Parser (with prettyprinter & quickcheck) - complete -* Interpreter - complete - -## Authors -* Vyacheslav Kochergin. [GitHub](https://github.com/VyacheslavIurevich), [Telegram](https://t.me/se4life). -* Roman Mukovenkov. [GitHub](https://github.com/Mukovenkov-Roman-Sergeyevich), [Telegram](https://t.me/RISCVEnjoyer). -* Yuliana Ementyan. [GitHub](https://github.com/lublu-pitsu), [Telegram](https://t.me/lublu_pitsy). diff --git a/RISCV_ASM/RISCV_ASM.opam b/RISCV_ASM/RISCV_ASM.opam deleted file mode 100644 index ad1c8bdd1..000000000 --- a/RISCV_ASM/RISCV_ASM.opam +++ /dev/null @@ -1,45 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -version: "0.1" -synopsis: "An interpreter for mini-language similiar to RISC-V ASM" -description: - "An interpreter for mini-language similiar to RISC-V ASM. Bitmanip and RVV subsets supported." -maintainer: [ - "Vyacheslav Kochergin vyacheslav.kochergin1@gmail.com, Roman Mukovenkov roman.mukovenkov@gmail.com, Yuliana Ementyan ementyan.yuliana@gmail.com" -] -authors: [ - "Vyacheslav Kochergin vyacheslav.kochergin1@gmail.com, Roman Mukovenkov roman.mukovenkov@gmail.com, Yuliana Ementyan ementyan.yuliana@gmail.com" -] -license: "LGPL-3.0-or-later" -homepage: "https://github.com/VyacheslavIurevich/fp2024" -doc: "https://kakadu.github.io/fp2024/docs/RISC-V_ASM_interpreter" -bug-reports: "https://github.com/VyacheslavIurevich/fp2024" -depends: [ - "dune" {>= "3.7"} - "ppx_inline_test" {with-test} - "ppx_expect" - "ppx_deriving" - "bisect_ppx" - "qcheck-core" - "ppx_deriving_qcheck" - "odoc" {with-doc} - "ocamlformat" {build} - "containers-data" -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] -depexts: [ - [ "gcc-riscv64-unknown-elf" "qemu-user" ] {os-distribution = "ubuntu"} -] diff --git a/RISCV_ASM/RISCV_ASM.opam.template b/RISCV_ASM/RISCV_ASM.opam.template deleted file mode 100644 index 0d6f17fef..000000000 --- a/RISCV_ASM/RISCV_ASM.opam.template +++ /dev/null @@ -1,3 +0,0 @@ -depexts: [ - [ "gcc-riscv64-unknown-elf" "qemu-user" ] {os-distribution = "ubuntu"} -] diff --git a/RISCV_ASM/dune b/RISCV_ASM/dune deleted file mode 100644 index 98e54536a..000000000 --- a/RISCV_ASM/dune +++ /dev/null @@ -1,7 +0,0 @@ -(env - (dev - (flags - (:standard -alert @deprecated -warn-error -A -w -3-9-32-34-58))) - (release - (flags - (:standard -alert @deprecated -warn-error +A -w +A-4-40-42-44-70)))) diff --git a/RISCV_ASM/dune-project b/RISCV_ASM/dune-project deleted file mode 100644 index 685dc57c0..000000000 --- a/RISCV_ASM/dune-project +++ /dev/null @@ -1,37 +0,0 @@ -(lang dune 3.7) - -(generate_opam_files true) - -(cram enable) - -(license LGPL-3.0-or-later) - -(authors "Vyacheslav Kochergin vyacheslav.kochergin1@gmail.com, Roman Mukovenkov roman.mukovenkov@gmail.com, Yuliana Ementyan ementyan.yuliana@gmail.com") - -(maintainers "Vyacheslav Kochergin vyacheslav.kochergin1@gmail.com, Roman Mukovenkov roman.mukovenkov@gmail.com, Yuliana Ementyan ementyan.yuliana@gmail.com") - -(bug_reports "https://github.com/VyacheslavIurevich/fp2024") - -(homepage "https://github.com/VyacheslavIurevich/fp2024") - -(package - (name RISCV_ASM) ; FIXME and regenerate .opam file using 'dune build @install' - (synopsis "An interpreter for mini-language similiar to RISC-V ASM") - (description - "An interpreter for mini-language similiar to RISC-V ASM. Bitmanip and RVV subsets supported.") - (documentation "https://kakadu.github.io/fp2024/docs/RISC-V_ASM_interpreter") - (version 0.1) - (depends - dune - (ppx_inline_test :with-test) - ppx_expect - ppx_deriving - bisect_ppx - qcheck-core - ppx_deriving_qcheck - (odoc :with-doc) - (ocamlformat :build) - containers-data - ; base - ; After adding dependencies to 'dune' files and the same dependecies here too - )) diff --git a/RISCV_ASM/examples/bitmanip/bitmanip.s b/RISCV_ASM/examples/bitmanip/bitmanip.s deleted file mode 100644 index 57b157640..000000000 --- a/RISCV_ASM/examples/bitmanip/bitmanip.s +++ /dev/null @@ -1,72 +0,0 @@ -.globl _start - -.section .data -buffer: .space 32 - -.section .text - -_start: - li a7, 63 - li a0, 0 - la a1, buffer - li a2, 32 - ecall - - la t0, buffer - mv a0, zero - li t2, 10 -convert_string_to_number: - lb t1, 0(t0) - beqz t1, end_convert - addi t1, t1, -48 - bltz t1, end_convert - bge t1, t2, end_convert - mul a0, a0, t2 - add a0, a0, t1 - addi t0, t0, 1 - j convert_string_to_number -end_convert: - li t1, 15 - sh1add t1, t1, a0 - orn t1, t1, a0 - sh2add.uw t1, t1, a0 - andn t1, t1, a0 - add.uw t1, t1, a0 -exit: - la t0, buffer - addi t2, zero, 10 - mv a0, t1 - addi t3, zero, 0 -convert_loop: - rem t4, a0, t2 - div a0, a0, t2 - addi t4, t4, 48 - sb t4, 0(t0) - addi t0, t0, 1 - addi t3, t3, 1 - bnez a0, convert_loop - - la t0, buffer - mv t4, t0 - add t5, t0, t3 - addi t5, t5, -1 -reverse_loop: - bge t4, t5, end_reverse - lb t6, 0(t4) - lb t1, 0(t5) - sb t1, 0(t4) - sb t6, 0(t5) - addi t4, t4, 1 - addi t5, t5, -1 - j reverse_loop -end_reverse: - add t0, t0, t3 - li a7, 64 - li a0, 1 - la a1, buffer - mv a2, t3 - ecall - li a7, 93 - li a0, 0 - ecall - diff --git a/RISCV_ASM/examples/factorial/factorial.s b/RISCV_ASM/examples/factorial/factorial.s deleted file mode 100644 index aa1ff4a70..000000000 --- a/RISCV_ASM/examples/factorial/factorial.s +++ /dev/null @@ -1,71 +0,0 @@ -.globl _start - -.section .data -buffer: .space 32 - -.section .text - -_start: - li a7, 63 - li a0, 0 - la a1, buffer - li a2, 32 - ecall - - la t0, buffer - mv a0, zero - li t2, 10 -convert_string_to_number: - lb t1, 0(t0) - beqz t1, end_convert - addi t1, t1, -48 - bltz t1, end_convert - bge t1, t2, end_convert - mul a0, a0, t2 - add a0, a0, t1 - addi t0, t0, 1 - j convert_string_to_number -end_convert: - addi t1, zero, 1 -loop: - beqz a0, exit - mul t1, t1, a0 - addi a0, a0, -1 - j loop -exit: - la t0, buffer - addi t2, zero, 10 - mv a0, t1 - addi t3, zero, 0 -convert_loop: - rem t4, a0, t2 - div a0, a0, t2 - addi t4, t4, 48 - sb t4, 0(t0) - addi t0, t0, 1 - addi t3, t3, 1 - bnez a0, convert_loop - - la t0, buffer - mv t4, t0 - add t5, t0, t3 - addi t5, t5, -1 -reverse_loop: - bge t4, t5, end_reverse - lb t6, 0(t4) - lb t1, 0(t5) - sb t1, 0(t4) - sb t6, 0(t5) - addi t4, t4, 1 - addi t5, t5, -1 - j reverse_loop -end_reverse: - add t0, t0, t3 - li a7, 64 - li a0, 1 - la a1, buffer - mv a2, t3 - ecall - li a7, 93 - li a0, 0 - ecall diff --git a/RISCV_ASM/examples/io/io.s b/RISCV_ASM/examples/io/io.s deleted file mode 100644 index 26f3afa15..000000000 --- a/RISCV_ASM/examples/io/io.s +++ /dev/null @@ -1,25 +0,0 @@ -.globl _start - -.section .data -buffer: .space 32 - -.section .text - -_start: - li a7, 63 - li a0, 0 - la a1, buffer - li a2, 32 - ecall - - mv t0, a0 - - li a7, 64 - li a0, 1 - la a1, buffer - mv a2, t0 - ecall - - li a7, 93 - li a0, 0 - ecall diff --git a/RISCV_ASM/examples/rvv/rvv.s b/RISCV_ASM/examples/rvv/rvv.s deleted file mode 100644 index c723b7824..000000000 --- a/RISCV_ASM/examples/rvv/rvv.s +++ /dev/null @@ -1,73 +0,0 @@ -.globl _start - -.section .data -buffer: - .word 1 - .word 2 - .word 3 - .word 4 - .word 5 - -.section .text - -_start: - li t0, 4 - vsetvli t1, t0, e32 - la t2, buffer - vle32.v v0, 0(t2) - addi t3, t2, 4 - vle32.v v1, 0(t3) - vadd.vv v2, v0, v1 - la t4, buffer - vse32.v v2, 0(t4) - li t6, 4 - vadd.vv v0, v0, v0 - vadd.vx v0, v0, t6 - li t6, 1 - vsub.vx v0, v0, t6 - vmul.vv v0, v0, v0 - li t6, 4 - vmul.vx v0, v0, t6 - li t6, 2 - vdiv.vx v0, v0, t6 - li t6, 55 - vor.vx v0, v0, t6 - li t6, 12 - vxor.vx v0, v0, t6 - vredsum.vs v3, v0, v0 - la t5, buffer - vse32.v v3, 0(t5) - lw a0, 0(t5) - la t0, buffer - addi t2, zero, 10 - mv t3, zero -convert_loop: - rem t4, a0, t2 - div a0, a0, t2 - addi t4, t4, 48 - sb t4, 0(t0) - addi t0, t0, 1 - addi t3, t3, 1 - bnez a0, convert_loop - la t0, buffer - mv t4, t0 - add t5, t0, t3 - addi t5, t5, -1 -reverse_loop: - bge t4, t5, end_reverse - lb t6, 0(t4) - lb t1, 0(t5) - sb t1, 0(t4) - sb t6, 0(t5) - addi t4, t4, 1 - addi t5, t5, -1 - j reverse_loop -end_reverse: - li a7, 64 - li a0, 1 - la a1, buffer - mv a2, t3 - ecall - li a7, 93 - li a0, 0 - ecall diff --git a/RISCV_ASM/lib/ast.ml b/RISCV_ASM/lib/ast.ml deleted file mode 100644 index ce8e54429..000000000 --- a/RISCV_ASM/lib/ast.ml +++ /dev/null @@ -1,528 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -(** Integer Registers *) -type register = - | X0 (** zero - Zero Constant *) - | X1 (** ra - Return Address *) - | X2 (** sp - Stack Pointer *) - | X3 (** gp - Global Pointer *) - | X4 (** tp - Thread Pointer *) - | X5 (** t0 - Temporary *) - | X6 (** t1 - Temporary *) - | X7 (** t2 - Temporary *) - | X8 (** s0/fp - Saved/Frame Pointer *) - | X9 (** s1 - Saved Register *) - | X10 (** a0 - Function Argument or Return Value *) - | X11 (** a1 - Function Argument or Return Value *) - | X12 (** a2 - Function Argument *) - | X13 (** a3 - Function Argument *) - | X14 (** a4 - Function Argument *) - | X15 (** a5 - Function Argument *) - | X16 (** a6 - Function Argument *) - | X17 (** a7 - Function Argument *) - | X18 (** s2 - Saved Register *) - | X19 (** s3 - Saved Register *) - | X20 (** s4 - Saved Register *) - | X21 (** s5 - Saved Register *) - | X22 (** s6 - Saved Register *) - | X23 (** s7 - Saved Register *) - | X24 (** s8 - Saved Register *) - | X25 (** s9 - Saved Register *) - | X26 (** s10 - Saved Register *) - | X27 (** s11 - Saved Register *) - | X28 (** t3 - Temporary *) - | X29 (** t4 - Temporary *) - | X30 (** t5 - Temporary *) - | X31 (** t6 - Temporary *) - | Zero (** a.k.a. X0 *) - | Ra (** a.k.a. X1 *) - | Sp (** a.k.a. X2 *) - | Gp (** a.k.a. X3 *) - | Tp (** a.k.a. X4 *) - | T0 (** a.k.a. X5 *) - | T1 (** a.k.a. X6 *) - | T2 (** a.k.a. X7 *) - | S0 (** a.k.a. X8 *) - | Fp (** a.k.a. X8 *) - | S1 (** a.k.a. X9 *) - | A0 (** a.k.a. X10 *) - | A1 (** a.k.a. X11 *) - | A2 (** a.k.a. X12 *) - | A3 (** a.k.a. X13 *) - | A4 (** a.k.a. X14 *) - | A5 (** a.k.a. X15 *) - | A6 (** a.k.a. X16 *) - | A7 (** a.k.a. X17 *) - | S2 (** a.k.a. X18 *) - | S3 (** a.k.a. X19 *) - | S4 (** a.k.a. X20 *) - | S5 (** a.k.a. X21 *) - | S6 (** a.k.a. X22 *) - | S7 (** a.k.a. X23 *) - | S8 (** a.k.a. X24 *) - | S9 (** a.k.a. X25 *) - | S10 (** a.k.a. X26 *) - | S11 (** a.k.a. X27 *) - | T3 (** a.k.a. X28 *) - | T4 (** a.k.a. X29 *) - | T5 (** a.k.a. X30 *) - | T6 (** a.k.a. X31 *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Vector Registers *) -type vector_register = - | V0 (** Vector Register 0 *) - | V1 (** Vector Register 1 *) - | V2 (** Vector Register 2 *) - | V3 (** Vector Register 3 *) - | V4 (** Vector Register 4 *) - | V5 (** Vector Register 5 *) - | V6 (** Vector Register 6 *) - | V7 (** Vector Register 7 *) - | V8 (** Vector Register 8 *) - | V9 (** Vector Register 9 *) - | V10 (** Vector Register 10 *) - | V11 (** Vector Register 11 *) - | V12 (** Vector Register 12 *) - | V13 (** Vector Register 13 *) - | V14 (** Vector Register 14 *) - | V15 (** Vector Register 15 *) - | V16 (** Vector Register 16 *) - | V17 (** Vector Register 17 *) - | V18 (** Vector Register 18 *) - | V19 (** Vector Register 19 *) - | V20 (** Vector Register 20 *) - | V21 (** Vector Register 21 *) - | V22 (** Vector Register 22 *) - | V23 (** Vector Register 23 *) - | V24 (** Vector Register 24 *) - | V25 (** Vector Register 25 *) - | V26 (** Vector Register 26 *) - | V27 (** Vector Register 27 *) - | V28 (** Vector Register 28 *) - | V29 (** Vector Register 29 *) - | V30 (** Vector Register 30 *) - | V31 (** Vector Register 31 *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Float Registers *) -type float_register = - | F0 (** ft0 - Temporary *) - | F1 (** ft1 - Temporary *) - | F2 (** ft2 - Temporary *) - | F3 (** ft3 - Temporary *) - | F4 (** ft4 - Temporary *) - | F5 (** ft5 - Temporary *) - | F6 (** ft6 - Temporary *) - | F7 (** ft7 - Temporary *) - | F8 (** fs0 - Saved Register *) - | F9 (** fs1 - Saved Register *) - | F10 (** fa0 - Function Argument or Return Value *) - | F11 (** fa1 - Function Argument or Return Value *) - | F12 (** fa2 - Function Argument *) - | F13 (** fa3 - Function Argument *) - | F14 (** fa4 - Function Argument *) - | F15 (** fa5 - Function Argument *) - | F16 (** fa6 - Function Argument *) - | F17 (** fa7 - Function Argument *) - | F18 (** fs2 - Saved Register *) - | F19 (** fs3 - Saved Register *) - | F20 (** fs4 - Saved Register *) - | F21 (** fs5 - Saved Register *) - | F22 (** fs6 - Saved Register *) - | F23 (** fs7 - Saved Register *) - | F24 (** fs8 - Saved Register *) - | F25 (** fs9 - Saved Register *) - | F26 (** fs10 - Saved Register *) - | F27 (** fs11 - Saved Register *) - | F28 (** t8 - Temporary *) - | F29 (** t9 - Temporary *) - | F30 (** t10 - Temporary *) - | F31 (** t11 - Temporary *) - | Ft0 (** a.k.a F0 *) - | Ft1 (** a.k.a F1 *) - | Ft2 (** a.k.a F2 *) - | Ft3 (** a.k.a F3 *) - | Ft4 (** a.k.a F4 *) - | Ft5 (** a.k.a F5 *) - | Ft6 (** a.k.a F6 *) - | Ft7 (** a.k.a F7 *) - | Fs0 (** a.k.a F8 *) - | Fs1 (** a.k.a F9 *) - | Fa0 (** a.k.a F10 *) - | Fa1 (** a.k.a F11 *) - | Fa2 (** a.k.a F12 *) - | Fa3 (** a.k.a F13 *) - | Fa4 (** a.k.a F14 *) - | Fa5 (** a.k.a F15 *) - | Fa6 (** a.k.a F16 *) - | Fa7 (** a.k.a F17 *) - | Fs2 (** a.k.a F18 *) - | Fs3 (** a.k.a F19 *) - | Fs4 (** a.k.a F20 *) - | Fs5 (** a.k.a F21 *) - | Fs6 (** a.k.a F22 *) - | Fs7 (** a.k.a F23 *) - | Fs8 (** a.k.a F24 *) - | Fs9 (** a.k.a F25 *) - | Fs10 (** a.k.a F26 *) - | Fs11 (** a.k.a F27 *) - | Ft8 (** a.k.a F28 *) - | Ft9 (** a.k.a F29 *) - | Ft10 (** a.k.a F30 *) - | Ft11 (** a.k.a F31 *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Label Type *) -type label = (string[@gen Generators.gen_my_label]) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Address12 Type to Jump to *) -type address12 = - | ImmediateAddress12 of (int[@gen QCheck.Gen.(-2048 -- 2047)]) - (** Immediate12 to Jump to*) - | LabelAddress12 of label (** Label to Jump to *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Address20 Type to Jump to *) -type address20 = - | ImmediateAddress20 of (int[@gen QCheck.Gen.(-524288 -- 524287)]) - (** Immediate20 to Jump to*) - | LabelAddress20 of label (** Label to Jump to *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Address32 Type to Jump to *) -type address32 = - | ImmediateAddress32 of (int[@gen QCheck.Gen.(-2147483648 -- 2147483647)]) - (** Immediate32 to Jump to *) - | LabelAddress32 of label (** Label to Jump to *) -[@@deriving eq, show { with_path = false }, qcheck] - -type instruction = - | Add of register * register * register (** Addition. rd = rs1 + rs2 *) - | Sub of register * register * register (** Subtraction. rd = rs1 - rs2 *) - | Xor of register * register * register (** Exclusive OR. rd = rs1 ^ rs2 *) - | Or of register * register * register (** OR. rd = rs1 | rs2 *) - | And of register * register * register (** AND. rd = rs1 & rs2 *) - | Sll of register * register * register (** Shift Left Logical. rd = rs1 << rs2 *) - | Srl of register * register * register (** Shift Right Logical. rd = rs1 >> rs2 *) - | Sra of register * register * register (** Shift Right Arithmetic. rd = rs1 >> rs2 *) - | Slt of register * register * register (** Set Less Than. rd = (rs1 < rs2) ? 1 : 0 *) - | Sltu of register * register * register (** Set Less Than (Unsigned) *) - | Addi of register * register * address12 (** Addition of Immediate. rd = rs1 + imm *) - | Xori of register * register * address12 (** XOR with Immediate. rd = rs1 ^ imm *) - | Ori of register * register * address12 (** OR with Immediate. rd = rs1 | imm *) - | Andi of register * register * address12 (** AND with Immediate. rd = rs1 & imm *) - | Slli of register * register * address12 - (** Shift Left Logical with Immediate. rd = rs1 << shamt[0:4] *) - | Srli of register * register * address12 - (** Shift Right Logical with Immediate. rd = rs1 >> shamt[0:4] logical *) - | Srai of register * register * address12 - (** Shift Right Arithmetic with Immediate. rd = rs1 >> shamt[0:4] arithmetical *) - | Slti of register * register * address12 - (** Set Less Than Imm. rd = (rs1 < imm) ? 1 : 0 *) - | Sltiu of register * register * address12 (** Set Less Than Imm (Unsigned) *) - | Lb of register * register * address12 (** Load Byte. rd = M[rs1 + imm][0:7] *) - | Lh of register * register * address12 (** Load Half. rd = M[rs1 + imm][0:15] *) - | Lw of register * register * address12 (** Load Word. rd = M[rs1 + imm][0:31] *) - | Lbu of register * register * address12 (** Load Byte Unsigned *) - | Lhu of register * register * address12 (** Load Half Unsigned *) - | Sb of register * register * address12 (** Store Byte. M[rs1 + imm][0:7] = rs2[0:7] *) - | Sh of register * register * address12 - (** Store Half. M[rs1 + imm][0:15] = rs2[0:15] *) - | Sw of register * register * address12 - (** Store Word. M[rs1 + imm][0:31] = rs2[0:31] *) - | Beq of register * register * address12 - (** Branch ==. if (rs1 == rs2) PC += imm. PC is a program counter *) - | Beqz of register * address12 - (** Branch == 0. if (rs1 == 0) PC += imm. PC is a program counter *) - | Bne of register * register * address12 (** Branch !=. if (rs1 != rs2) PC += imm. *) - | Bnez of register * address12 (** Branch != 0. if (rs1 != 0) PC += imm. *) - | Blt of register * register * address12 (** Branch <. if (rs1 < rs2) PC += imm. *) - | Bltz of register * address12 (** Branch < 0. if (rs1 < 0) PC += imm. *) - | Bgt of register * register * address12 (** Branch >. if (rs1 > rs2) PC += imm. *) - | Bgtz of register * address12 (** Branch > 0. if (rs1 > 0) PC += imm. *) - | Bge of register * register * address12 (** Branch >=. if (rs1 >= rs2) PC += imm. *) - | Bltu of register * register * address12 - (** Branch < (Unsigned). if (rs1 < rs2) PC += imm. *) - | Bgeu of register * register * address12 - (** Branch >= (Unsigned). if (rs1 >= rs2) PC += imm. *) - | Jal of register * address20 - (** Jump and Link. rd = PC + 4; PC += imm. 4 bytes = 32 bits - instuction size *) - | Jalr of register * register * address12 - (** Jump and Link register. rd = PC + 4, PC = rs1 + imm *) - | Jr of register (** Jump Reg. jalr x0, rs1, 0 *) - | J of address20 (** Jump. jal x0, 2 * offset *) - | Lui of register * address20 (** Load Upper Immediate. rd = imm << 12 *) - | Auipc of register * address20 (** Add Upper Immediate to PC. rd = PC + (imm << 12) *) - | Ecall (** EnvironmentCall - a syscall *) - | Call of (string[@gen Generators.gen_my_string]) (** call. - a syscall *) - | Mul of register * register * register (** Multiply. rd = (rs1 * rs2)[31:0] *) - | Mulh of register * register * register (** Multiply High. rd = (rs1 * rs2)[63:32] *) - | Mulhsu of register * register * register - (** Multiply High (Signed * Unsigned). rd = (rs1 * rs2)[63:32] *) - | Mulhu of register * register * register - (** Multiply High (Unsigned * Unsigned). rd = (rs1 * rs2)[63:32] *) - | Div of register * register * register (** Division. rd = rs1 / rs2 *) - | Divu of register * register * register (** Division (Unsigned). rd = rs1 / rs2 *) - | Rem of register * register * register (** Remainder. rd = rs1 % rs2 *) - | Remu of register * register * register (** Remainder (Unsigned). rd = rs1 % rs2 *) - | Lwu of register * register * address12 - (** Load Word (Unsigned). rd = M[rs1 + imm][0:31] *) - | Ld of register * register * address12 - (** Load Doubleword (Unsigned). rd = M[rs1 + imm][0:63] *) - | La of register * address32 - (** Load Address. auipc rd, symbol[31:12]; addi rd, rd, symbol[11:0] *) - | Lla of register * address32 - (** Load Local Address. auipc rd, %pcrel_hi(symbol); addi rd, rd, %pcrel_lo(label) *) - | Sd of register * register * address12 - (** Store Doubleword. M[rs1 + imm][0:63] = rs2[0:63] *) - | Addiw of register * register * address12 - (** Addition of Immediate Word. rd = (rs1 + imm)[31:0] *) - | Slliw of register * register * address12 - (** Shift Left Logical with Immediate Word. rd = (rs1 << shamt)[31:0] *) - | Srliw of register * register * address12 - (** Shift Right Logical with Immediate Word. rd = (rs1 >> shamt)[31:0] *) - | Sraiw of register * register * address12 - (** Shift Right Arithmetic with Immediate Word. rd = (rs1 >> shamt)[31:0] *) - | Addw of register * register * register (** Add Word. rd = (rs1 + rs2)[31:0] *) - | Subw of register * register * register (** Add Word. rd = (rs1 - rs2)[31:0] *) - | Sllw of register * register * register - (** Shifl Left Logical Word. rd = (rs1 << rs2)[31:0] *) - | Srlw of register * register * register - (** Shifl Right Logical Word. rd = (rs1 >> rs2)[31:0] *) - | Sraw of register * register * register - (** Shifl Right Arithmetical Word. rd = (rs1 >> rs2)[31:0] *) - | Mulw of register * register * register (** Multiply Word. rd = (rs1 * rs2)[31:0] *) - | Divw of register * register * register (** Division Word. rd = (rs1 / rs2)[31:0] *) - | Divuw of register * register * register - (** Division Word (Unsigned). rd = (rs1 / rs2)[31:0] *) - | Remw of register * register * register (** Remainder Word. rd = (rs1 % rs2)[31:0] *) - | Remwu of register * register * register - (** Remainder Word (Unsigned). rd = (rs1 % rs2)[31:0] *) - | Mv of register * register (** Copy from rs1 to rd. addi rd, rs1, 0 *) - | Li of register * address32 - (** Load Immediate. lui rd, immediate20; addi rd, rd, immediate12 *) - | Ret (** Return. Jalr x0, x1, 0 *) - | FmaddS of float_register * float_register * float_register * float_register - (** Fused Mul-Add Single precision. rd = rs1 * rs2 + rs3 *) - | FmsubS of float_register * float_register * float_register * float_register - (** Fused Mul-Sub Single precision. rd = rs1 * rs2 - rs3 *) - | FnmsubS of float_register * float_register * float_register * float_register - (** Fused Negative Mul-Sub Single precision. rd = -rs1 * rs2 + rs3 *) - | FnmaddS of float_register * float_register * float_register * float_register - (** Fused Negative Mul-Sub Single precision. rd = -rs1 * rs2 - rs3 *) - | FaddS of float_register * float_register * float_register - (** Addition Single precision. rd = rs1 + rs2 *) - | FsubS of float_register * float_register * float_register - (** Subtraction Single precision. rd = rs1 - rs2 *) - | FmulS of float_register * float_register * float_register - (** Multiplication Single precision. rd = rs1 * rs2 *) - | FdivS of float_register * float_register * float_register - (** Division Single precision. rd = rs1 / rs2 *) - | FsqrtS of float_register * float_register - (** Square root Single precision. rd = sqrt(rs1) *) - | FsgnjS of float_register * float_register * float_register - (** Sign Injection Single precision. rd = [rs2[31], rs1[30:0]]. Sign bit from rs2, other bits from rs1 *) - | FsgnjnS of float_register * float_register * float_register - (** Sign Injection Negative Single precision. rd = [~rs2[31], rs1[30:0]] *) - | FsgnjxS of float_register * float_register * float_register - (** Sign Injection Xor Single precision. rd = [rs1[31] ^ rs2[31], rs1[30:0]] *) - | FminS of float_register * float_register * float_register - (** Min Single precision. rd = min(rs1, rs2) *) - | FmaxS of float_register * float_register * float_register - (** Max Single precision. rd = max(rs1, rs2) *) - | FcvtWS of register * float_register - (** Convert single precision float to signed 32-bit integer *) - | FcvtWuS of register * float_register - (** Convert single precision float to unsigned 32-bit integer *) - | FmvXW of register * float_register - (** Move single precision float to lower 32 bits of integer register *) - | FeqS of register * float_register * float_register - (** Equality Single precision. Result stored in integer register. rd = (rs1 == rs2) *) - | FltS of register * float_register * float_register - (** Less Single precision. rd = (rs1 < rs2) *) - | FleS of register * float_register * float_register - (** Less or Equal Single precision. rd = (rs1 <= rs2) *) - | FclassS of register * float_register (** Classification of Single precision float *) - | FcvtSW of float_register * register - (** Converts 32-bit signed integer to Single precision float *) - | FcvtSWu of float_register * register - (** Converts 32-bit unsigned integer to Single precision float *) - | FmvWX of float_register * register - (** Move single precision float from lower 32 bits of integer register to float register *) - | FmaddD of float_register * float_register * float_register * float_register - (** Fused Mul-Add Single precision. rd = rs1 * rs2 + rs3 *) - | FmsubD of float_register * float_register * float_register * float_register - (** Fused Mul-Sub Single precision. rd = rs1 * rs2 - rs3 *) - | FnmsubD of float_register * float_register * float_register * float_register - (** Fused Negative Mul-Sub Single precision. rd = -rs1 * rs2 + rs3 *) - | FnmaddD of float_register * float_register * float_register * float_register - (** Fused Negative Mul-Sub Single precision. rd = -rs1 * rs2 - rs3 *) - | FaddD of float_register * float_register * float_register - (** Addition Single precision. rd = rs1 + rs2 *) - | FsubD of float_register * float_register * float_register - (** Subtraction Single precision. rd = rs1 - rs2 *) - | FmulD of float_register * float_register * float_register - (** Multiplication Single precision. rd = rs1 * rs2 *) - | FdivD of float_register * float_register * float_register - (** Division Single precision. rd = rs1 / rs2 *) - | FsqrtD of float_register * float_register - (** Square root Single precision. rd = sqrt(rs1) *) - | FsgnjD of float_register * float_register * float_register - (** Sign Injection Single precision. rd = [rs2[63], rs1[62:0]]. Sign bit from rs2, other bits from rs1 *) - | FsgnjnD of float_register * float_register * float_register - (** Sign Injection Negative Single precision. rd = [~rs2[63], rs1[62:0]] *) - | FsgnjxD of float_register * float_register * float_register - (** Sign Injection Xor Single precision. rd = [rs1[63] ^ rs2[63], rs1[62:0]] *) - | FminD of float_register * float_register * float_register - (** Min Single precision. rd = min(rs1, rs2) *) - | FmaxD of float_register * float_register * float_register - (** Max Single precision. rd = max(rs1, rs2) *) - | FcvtSD of float_register * float_register - (** Converts double floating-point register into a floating-point number *) - | FcvtDS of float_register * float_register - (** Converts single floating-point register into a double floating-point number *) - | FeqD of register * float_register * float_register - (** Equality Single precision. Result stored in integer register. rd = (rs1 == rs2) *) - | FltD of register * float_register * float_register - (** Less Single precision. rd = (rs1 < rs2) *) - | FleD of register * float_register * float_register - (** Less or Equal Single precision. rd = (rs1 <= rs2) *) - | FclassD of register * float_register - | FcvtWD of register * float_register - (** Converts a double-precision floating-point number to a signed 32-bit integer *) - | FcvtWuD of register * float_register - (** Converts a double-precision floating-point number to a unsigned 32-bit integer *) - | FcvtDW of float_register * register - (** Converts a 32-bit signed integer into a double-precision floating-point number *) - | FcvtDWu of float_register * register - (** Converts a 32-bit unsigned integer into a double-precision floating-point number *) - | Flw of float_register * float_register * address12 - (** Load a single-precision floating-point value from memory into floating-point register. f[rd] = M[x[rs1] + sext(offset)][31:0] *) - | Fsw of float_register * float_register * address12 - (** Store a single-precision value from floating-point register rs2 to memory. M[x[rs1] + sext(offset)] = f[rs2][31:0] *) - | Fld of float_register * float_register * address12 - (** Load a double-precision floating-point value from memory into floating-point register rd. f[rd] = M[x[rs1] + sext(offset)][63:0] *) - | Fsd of float_register * float_register * address12 - (** Store a double-precision value from the floating-point registers to memory. M[x[rs1] + sext(offset)] = f[rs2][63:0] *) - | FcvtLS of register * float_register - (** Convert single-precision floating-point to 64-bit integer *) - | FcvtLuS of register * float_register - (** Convert single-precision floating-point to unsigned 64-bit integer *) - | FcvtSL of float_register * register - (** Convert 64-bit integer to single-precision floating-point *) - | FcvtSLu of float_register * register - (** Convert 64-bit unsigned integer to single-precision floating-point *) - | FcvtLD of register * float_register - (** Convert double-precision floating-point to 64-bit integer *) - | FcvtLuD of register * float_register - (** Convert double-precision floating-point to unsigned 64-bit integer *) - | FcvtDL of float_register * register - (** Convert 64-bit integer to double-precision floating-point *) - | FcvtDLu of float_register * register - (** Convert 64-bit unsigned integer to double-precision floating-point *) - | Adduw of register * register * register - (** Add unsigned word. rd = ZEXT(rs1 + rs2)[31:0]*) - | Sh1add of register * register * register - (** Shift left by 1 and add. rd = rs2 + (rs1 << 1) *) - | Sh1adduw of register * register * register - (** Shift unsigned word left by 1 and add. rd = rs2 + (ZEXT(rs1) << 1) *) - | Sh2add of register * register * register - (** Shift left by 2 and add. rd = rs2 + (rs1 << 2) *) - | Sh2adduw of register * register * register - (** Shift unsigned word left by 2 and add. rd = rs2 + (ZEXT(rs1) << 2) *) - | Sh3add of register * register * register - (** Shift left by 3 and add. rd = rs2 + (rs1 << 3) *) - | Sh3adduw of register * register * register - (** Shift unsigned word left by 3 and add. rd = rs2 + (ZEXT(rs1) << 3) *) - | Andn of register * register * register - (** AND with inverted operand. rd = rs1 & ~rs2 *) - | Orn of register * register * register (** OR with inverted operand. rd = rs1 | ~rs2 *) - | Xnor of register * register * register (** Exclusive NOR. ~(rs1 ^ rs2) *) - | Vle32v of vector_register * register * address12 - (** Load Vector from Memory. vle32.v vd, (rs1) *) - | Vse32v of vector_register * register * address12 - (** Store Vector to Memory. vse32.v vs, (rs1) *) - | Vaddvv of vector_register * vector_register * vector_register - (** Vector Addition. Vadd.vv vd, vs1, vs2 *) - | Vaddvx of vector_register * vector_register * register - (** Vector Addition with Scalar. vadd.vx vd, vs1, rs2 *) - | Vsubvv of vector_register * vector_register * vector_register - (** Vector Subtraction. Vsub.vv vd, vs1, vs2 *) - | Vsubvx of vector_register * vector_register * register - (** Vector Subtraction with Scalar. vsub.vx vd, vs1, rs2 *) - | Vmulvv of vector_register * vector_register * vector_register - (** Vector Multiplication. Vmul.vv vd, vs1, vs2 *) - | Vmulvx of vector_register * vector_register * register - (** Vector Multiplication with Scalar. vmul.vx vd, vs1, rs2 *) - | Vdivvv of vector_register * vector_register * vector_register - (** Vector Division. Vdiv.vv vd, vs1, vs2 *) - | Vdivvx of vector_register * vector_register * register - (** Vector Division with Scalar. vdiv.vx vd, vs1, rs2 *) - | Vandvv of vector_register * vector_register * vector_register - (** Vector Logical AND. Vand.vv vd, vs1, vs2 *) - | Vandvx of vector_register * vector_register * register - (** Vector Logical AND with Scalar. vand.vx vd, vs1, rs2 *) - | Vorvv of vector_register * vector_register * vector_register - (** Vector Logical OR. Vor.vv vd, vs1, vs2 *) - | Vorvx of vector_register * vector_register * register - (** Vector Logical OR with Scalar. vor.vx vd, vs1, rs2 *) - | Vxorvv of vector_register * vector_register * vector_register - (** Vector Logical XOR. Vxor.vv vd, vs1, vs2 *) - | Vxorvx of vector_register * vector_register * register - (** Vector Logical XOR with Scalar. vxor.vx vd, vs1, rs2 *) - | Vminvv of vector_register * vector_register * vector_register - (** Vector Minimum. Vmin.vv vd, vs1, vs2 *) - | Vminvx of vector_register * vector_register * register - (** Vector Minimum with Scalar. vmin.vx vd, vs1, rs2 *) - | Vmaxvv of vector_register * vector_register * vector_register - (** Vector Maximum. Vmax.vv vd, vs1, vs2 *) - | Vmaxvx of vector_register * vector_register * register - (** Vector Maximum with Scalar. vmax.vx vd, vs1, rs2 *) - | Vmseqvv of vector_register * vector_register * vector_register - (** Vector Equals. Vmseq.vv vd, vs1, vs2 *) - | Vmseqvx of vector_register * vector_register * register - (** Vector Equals with Scalar. vmseq.vx vd, vs1, rs2 *) - | Vsetvli of register * register - (** RVV Configuration. rd = new vl, rs1 = AVL (application vector length) *) - | Vredsumvs of vector_register * vector_register * vector_register - (** vd[0] = sum( vs1[0] , vs2[*] ), where [*] denotes all active elements *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Attribute can either take in a string or an int as its value *) -type string_or_int_value = - | StrValue of (string[@gen Generators.gen_my_string]) (** A string value *) - | IntValue of (int[@gen QCheck.Gen.(-2147483648 -- 2147483647)]) (** An integer value*) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Types that are assigned to symbols for the logic of the compiler*) -type type_dir = Type of (string[@gen Generators.gen_my_string]) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Compiler directive (most of them are not needed while interpreting) *) -type directive = - | Text (** .text subsection *) - | Globl of address12 (** .globl symbol *) - | TypeDir of (string[@gen Generators.gen_my_string]) * type_dir - (** .type assigns type to a symbol *) - | Section of - (string[@gen Generators.gen_my_string]) - * ((string[@gen Generators.gen_my_string]) * (type_dir * int option) option) option - (** .section name *) - | StringDir of (string[@gen Generators.gen_my_string]) (** .string "str" *) - | Word of Int32.t (** .word stores data in memory*) - | Space of int (** .space allocates unitialized space for data in memory *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** Expression in AST *) -type expr = - | InstructionExpr of instruction (** Instruction *) - | LabelExpr of label (** Label *) - | DirectiveExpr of directive (** Directive *) -[@@deriving eq, show { with_path = false }, qcheck] - -(** AST is Presented by a List of Expressions *) -type ast = expr list [@@deriving eq, show { with_path = false }, qcheck] diff --git a/RISCV_ASM/lib/dune b/RISCV_ASM/lib/dune deleted file mode 100644 index b9d668a5b..000000000 --- a/RISCV_ASM/lib/dune +++ /dev/null @@ -1,9 +0,0 @@ -(library - (name riscv_asm_interpreter_lib) - (public_name RISCV_ASM.Lib) - (libraries angstrom containers-data) - (inline_tests) - (preprocess - (pps ppx_deriving.show ppx_deriving.eq ppx_deriving_qcheck ppx_expect)) - (instrumentation - (backend bisect_ppx))) diff --git a/RISCV_ASM/lib/generators.ml b/RISCV_ASM/lib/generators.ml deleted file mode 100644 index 548855642..000000000 --- a/RISCV_ASM/lib/generators.ml +++ /dev/null @@ -1,48 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open QCheck.Gen - -let gen_alpha = - oneof - [ map Char.chr (int_range (Char.code 'a') (Char.code 'z')) - ; map Char.chr (int_range (Char.code 'A') (Char.code 'Z')) - ; return '.' - ] -;; - -let gen_alpha_or_digit = - oneof - [ map Char.chr (int_range (Char.code 'a') (Char.code 'z')) - ; map Char.chr (int_range (Char.code 'A') (Char.code 'Z')) - ; map Char.chr (int_range (Char.code '0') (Char.code '9')) - ] -;; - -let gen_my_label = - let* length = int_range 2 50 in - let* first_char = gen_alpha in - let* rest_chars = list_repeat (length - 1) gen_alpha_or_digit in - let all_chars = first_char :: rest_chars in - return (String.concat "" (List.map (String.make 1) all_chars)) -;; - -let gen_char_for_string = - oneof - [ map Char.chr (int_range (Char.code 'a') (Char.code 'z')) - ; map Char.chr (int_range (Char.code 'A') (Char.code 'Z')) - ; map Char.chr (int_range (Char.code '0') (Char.code '9')) - ; return '_' - ; return ':' - ; return '(' - ; return ')' - ; return '.' - ] -;; - -let gen_my_string = - let* length = int_range 1 50 in - let* chars = list_repeat length gen_char_for_string in - return (String.concat "" (List.map (String.make 1) chars)) -;; diff --git a/RISCV_ASM/lib/generators.mli b/RISCV_ASM/lib/generators.mli deleted file mode 100644 index abecd8ee5..000000000 --- a/RISCV_ASM/lib/generators.mli +++ /dev/null @@ -1,6 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val gen_my_label : string QCheck.Gen.t -val gen_my_string : string QCheck.Gen.t diff --git a/RISCV_ASM/lib/interpreter.ml b/RISCV_ASM/lib/interpreter.ml deleted file mode 100644 index 03eadb9f4..000000000 --- a/RISCV_ASM/lib/interpreter.ml +++ /dev/null @@ -1,1341 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -module StringMap = Map.Make (String) -module Int64Map = Map.Make (Int64) - -type state = - { program : ast - ; registers : int64 StringMap.t - ; vregisters : int64 list StringMap.t - ; max_vector_length : int - ; vector_element_length : int - ; vector_length : int - ; memory : char Int64Map.t - ; program_idx : int64 - } - -module type CombinedMonadType = sig - type ('s, 'a) t - - val return : 'a -> ('s, 'a) t - val ( >>= ) : ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t - val fail : string -> ('s, 'a) t - val read : ('s, 's) t - val write : 's -> ('s, unit) t - val run : ('s, 'a) t -> 's -> ('s * 'a, string) result - - module Syntax : sig - val ( let* ) : ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t - end -end - -module CombinedMonad : CombinedMonadType = struct - type ('s, 'a) t = 's -> ('s * 'a, string) result - - let return x s = Ok (s, x) - - let ( >>= ) m f s = - match m s with - | Ok (s', x) -> f x s' - | Error e -> Error e - ;; - - let fail e _ = Error e - let read s = Ok (s, s) - let write s _ = Ok (s, ()) - let run m s = m s - - module Syntax = struct - let ( let* ) = ( >>= ) - end -end - -open CombinedMonad -open CombinedMonad.Syntax - -let handle_alternative_register_names = function - | Zero -> X0 - | Ra -> X1 - | Sp -> X2 - | Gp -> X3 - | Tp -> X4 - | T0 -> X5 - | T1 -> X6 - | T2 -> X7 - | S0 | Fp -> X8 - | S1 -> X9 - | A0 -> X10 - | A1 -> X11 - | A2 -> X12 - | A3 -> X13 - | A4 -> X14 - | A5 -> X15 - | A6 -> X16 - | A7 -> X17 - | S2 -> X18 - | S3 -> X19 - | S4 -> X20 - | S5 -> X21 - | S6 -> X22 - | S7 -> X23 - | S8 -> X24 - | S9 -> X25 - | S10 -> X26 - | S11 -> X27 - | T3 -> X28 - | T4 -> X29 - | T5 -> X30 - | T6 -> X31 - | x -> x -;; - -let resolve_label_address label = - let* state = read in - let rec traverse_program idx = function - | [] -> fail "Label cannot be resolved" - | LabelExpr lbl :: _ when lbl = label -> return idx - | InstructionExpr _ :: tl -> - traverse_program - (Int64.add idx 4L) - tl (* each supported instruction is stored in 4 bytes *) - | DirectiveExpr (Word _) :: tl -> - traverse_program (Int64.add idx 4L) tl (* each word is stored in 4 bytes *) - | DirectiveExpr (Space amount) :: tl -> - traverse_program - (Int64.add idx (Int64.of_int amount)) - tl (* space A takes A bytes *) - | DirectiveExpr (StringDir str) :: tl -> - traverse_program - (Int64.add idx (Int64.of_int (String.length str))) - tl (* string takes amount of bytes equal to its length *) - | _ :: tl -> traverse_program idx tl - in - traverse_program 0L state.program -;; - -(** Information about some address can be stored in 2 variants *) -type address_info = - | Immediate of int64 (** Immediate value *) - | LabelAddress of int64 (** Label (resolved in terms of addresses) *) - -let get_address12_value = function - | ImmediateAddress12 value -> return (Immediate (Int64.of_int value)) - | LabelAddress12 label -> - let* label_address = resolve_label_address label in - return (LabelAddress label_address) -;; - -let get_address20_value = function - | ImmediateAddress20 value -> return (Immediate (Int64.of_int value)) - | LabelAddress20 label -> - let* label_address = resolve_label_address label in - return (LabelAddress label_address) -;; - -let get_address32_value = function - | ImmediateAddress32 value -> return (Immediate (Int64.of_int value)) - | LabelAddress32 label -> - let* label_address = resolve_label_address label in - return (LabelAddress label_address) -;; - -let put_bytes_to_memory get_byte size addr memory = - let rec put_bytes memory current_addr = - let n = Int64.to_int (Int64.sub current_addr addr) in - if n < size - then ( - let byte = get_byte n in - let new_memory = Int64Map.add current_addr byte memory in - put_bytes new_memory (Int64.succ current_addr)) - else memory - in - put_bytes memory addr -;; - -let put_word_to_memory word = - let get_word_byte n = - Char.chr (Int32.to_int (Int32.logand (Int32.shift_right word (n * 8)) 0xFFl)) - in - put_bytes_to_memory get_word_byte 4 -;; - -let put_string_to_memory str = - let get_string_byte = String.get str in - put_bytes_to_memory get_string_byte (String.length str) -;; - -(* used to initialize memory from directives *) -let init_data program = - let rec traverse_program program addr memory = - match program with - | [] -> memory - | DirectiveExpr (Word word) :: rest -> - let memory = put_word_to_memory word addr memory in - traverse_program rest (Int64.add addr 4L) memory - | DirectiveExpr (Space amount) :: rest -> - (* skip amount of bytes used by space *) - traverse_program rest (Int64.add addr (Int64.of_int amount)) memory - | DirectiveExpr (StringDir str) :: rest -> - let memory = put_string_to_memory str addr memory in - traverse_program rest (Int64.add addr (Int64.of_int (String.length str))) memory - | _ :: rest -> traverse_program rest addr memory - in - traverse_program program 0L Int64Map.empty -;; - -let init_registers = - List.fold_left - (fun acc reg -> StringMap.add (show_register reg) 0L acc) - StringMap.empty - [ X0 - ; X1 - ; X2 - ; X3 - ; X4 - ; X5 - ; X6 - ; X7 - ; X8 - ; X9 - ; X10 - ; X11 - ; X12 - ; X13 - ; X14 - ; X15 - ; X16 - ; X17 - ; X18 - ; X19 - ; X20 - ; X21 - ; X22 - ; X23 - ; X24 - ; X25 - ; X26 - ; X27 - ; X28 - ; X29 - ; X30 - ; X31 - ] -;; - -let init_vregisters vector_length = - List.fold_left - (fun acc reg -> - StringMap.add (show_vector_register reg) (List.init vector_length (fun _ -> 0L)) acc) - StringMap.empty - [ V0 - ; V1 - ; V2 - ; V3 - ; V4 - ; V5 - ; V6 - ; V7 - ; V8 - ; V9 - ; V10 - ; V11 - ; V12 - ; V13 - ; V14 - ; V15 - ; V16 - ; V17 - ; V18 - ; V19 - ; V20 - ; V21 - ; V22 - ; V23 - ; V24 - ; V25 - ; V26 - ; V27 - ; V28 - ; V29 - ; V30 - ; V31 - ] -;; - -let init_state program = - let registers = init_registers in - let max_vector_length = 128 in - let vector_element_length = 4 in - let vector_length = 4 in - let vregisters = init_vregisters vector_length in - let memory = init_data program in - { program - ; registers - ; vregisters - ; max_vector_length - ; vector_element_length - ; vector_length - ; memory - ; program_idx = 0L - } -;; - -let get_register_value reg = - let* state = read in - return - (StringMap.find_opt - (show_register (handle_alternative_register_names reg)) - state.registers - |> Option.value ~default:0L) -;; - -let set_register_value reg value = - let* state = read in - let new_state = - match reg with - | X0 -> state - | _ -> - { state with - registers = - StringMap.add - (show_register (handle_alternative_register_names reg)) - value - state.registers - } - in - write new_state -;; - -let get_vregister_value vreg = - let* state = read in - return - (StringMap.find_opt (show_vector_register vreg) state.vregisters - |> Option.value ~default:(List.init state.vector_length (fun _ -> 0L))) -;; - -let set_vregister_value vreg value = - let* state = read in - let new_state = - { state with - vregisters = StringMap.add (show_vector_register vreg) value state.vregisters - } - in - write new_state -;; - -let set_program_idx new_idx = - let* state = read in - let new_state = { state with program_idx = new_idx } in - write new_state -;; - -let increment_program_idx () = - let* state = read in - let new_state = { state with program_idx = Int64.add state.program_idx 4L } in - write new_state -;; - -(* index is expr index in AST (= expr list) *) -(* address is a kind of expression's physical address (but all instructions are considered 4-byte, even compressed (for convenience)) *) - -(* translates expr index in AST to its "physical address" *) -let translate_index_to_address immediate64_value = - let* state = read in - let rec traverse_program address remaining_value = function - | [] -> - (match remaining_value with - | 0L -> return address - | _ -> fail "End of program reached before resolving address from index") - | InstructionExpr _ :: _ when remaining_value = 0L -> return address - | DirectiveExpr (Word _) :: _ when remaining_value = 0L -> return address - | DirectiveExpr (Space _) :: _ when remaining_value = 0L -> return address - | DirectiveExpr (StringDir _) :: _ when remaining_value = 0L -> return address - | DirectiveExpr (Word _) :: rest | InstructionExpr _ :: rest -> - (* make one step and subtract needed amount of bytes (word/instruction size) from remaining value *) - traverse_program (Int64.add address 4L) (Int64.sub remaining_value 4L) rest - | DirectiveExpr (Space amount) :: rest -> - (* make one step and subtract needed amount of bytes (space size) from remaining value *) - traverse_program - (Int64.add address 4L) - (Int64.sub remaining_value (Int64.of_int amount)) - rest - | DirectiveExpr (StringDir str) :: rest -> - (* make one step and subtract needed amount of bytes (string size) from remaining value *) - traverse_program - (Int64.add address 4L) - (Int64.sub remaining_value (Int64.of_int (String.length str))) - rest - | DirectiveExpr _ :: rest | LabelExpr _ :: rest -> - (* other directives and labels don't have own address, so we just make a step for indices *) - traverse_program address (Int64.sub remaining_value 4L) rest - in - traverse_program 0L immediate64_value state.program -;; - -(* translates expr "physical address" to its index in ast *) -let translate_address_to_index immediate64_value = - let* state = read in - let rec traverse_program index remaining_value = function - | [] -> - (match remaining_value with - | 0L -> return index - | _ -> fail "End of program reached before resolving index from address") - | InstructionExpr _ :: _ when remaining_value = 0L -> return index - | DirectiveExpr (Word _) :: _ when remaining_value = 0L -> return index - | DirectiveExpr (Space _) :: _ when remaining_value = 0L -> return index - | DirectiveExpr (StringDir _) :: _ when remaining_value = 0L -> return index - | DirectiveExpr (Word _) :: rest | InstructionExpr _ :: rest -> - (* make one step and subtract needed amount of bytes (word/instruction size) from remaining value *) - traverse_program (Int64.add index 4L) (Int64.sub remaining_value 4L) rest - | DirectiveExpr (Space amount) :: rest -> - (* make one step and subtract needed amount of bytes (space size) from remaining value *) - traverse_program - (Int64.add index 4L) - (Int64.sub remaining_value (Int64.of_int amount)) - rest - | DirectiveExpr (StringDir str) :: rest -> - (* make one step and subtract needed amount of bytes (string size) from remaining value *) - traverse_program - (Int64.add index 4L) - (Int64.sub remaining_value (Int64.of_int (String.length str))) - rest - | DirectiveExpr _ :: rest | LabelExpr _ :: rest -> - (* other directives and labels don't have own address, so we just make a step for indices *) - traverse_program (Int64.add index 4L) remaining_value rest - in - traverse_program 0L immediate64_value state.program -;; - -let sext x = Int64.shift_right (Int64.shift_left (Int64.logand x 0xFFFFFFFFL) 32) 32 - -let zext x = - Int64.shift_right_logical (Int64.shift_left (Int64.logand x 0xFFFFFFFFL) 32) 32 -;; - -let handle_branch_condition rs1 rs2 address_value comparison_fn = - let* state = read in - let* val_rs1 = get_register_value rs1 in - let* val_rs2 = - match rs2 with - | Some rs -> get_register_value rs - | None -> return 0L - in - let* address_info = get_address12_value address_value in - let* new_program_idx = - match address_info with - | Immediate imm_value when comparison_fn val_rs1 val_rs2 -> - let* current_address = translate_index_to_address state.program_idx in - let* target_index = - translate_address_to_index (Int64.add imm_value (sext current_address)) - in - return (Int64.sub target_index 4L) - | LabelAddress label_address when comparison_fn val_rs1 val_rs2 -> - let* target_index = translate_address_to_index label_address in - return (Int64.sub target_index 4L) - | _ -> return state.program_idx - in - set_program_idx new_program_idx -;; - -let execute_arithmetic_op rd rs1 rs2 op to_sext = - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = op val1 val2 in - let result_final = if to_sext then sext result else result in - set_register_value rd result_final -;; - -let execute_shift_op rd rs1 rs2 op = - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let val2_lower_5bits = Int64.logand val2 0x1FL in - let result = op val1 (Int64.to_int val2_lower_5bits) in - set_register_value rd result -;; - -let execute_comparison_op rd rs1 rs2 compare_fn = - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = if compare_fn val1 val2 then 1L else 0L in - set_register_value rd result -;; - -let execute_immediate_op rd rs1 imm op to_sext = - let* val1 = get_register_value rs1 in - let* address_info = get_address12_value imm in - let address_value = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let result = op val1 (sext address_value) in - let result_final = if to_sext then sext result else result in - set_register_value rd result_final -;; - -let execute_shift_immediate_op rd rs1 imm op = - let* val1 = get_register_value rs1 in - let* address_info = get_address12_value imm in - let shamt = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let shamt = Int64.to_int (Int64.logand shamt 0x3FL) in - let result = op val1 shamt in - set_register_value rd result -;; - -let execute_shnadd rd rs1 rs2 n to_zext = - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let arg1 = if to_zext then zext val1 else val1 in - let result = Int64.add val2 (Int64.shift_left arg1 n) in - set_register_value rd result -;; - -let load_byte_from_memory address = - let* state = read in - let byte = Int64Map.find_opt address state.memory in - match byte with - | None -> return '\000' - | Some byte -> return byte -;; - -let load_from_memory address size = - let rec read_bytes acc offset = - if offset < size - then ( - let byte_addr = Int64.add address (Int64.of_int offset) in - let* byte = load_byte_from_memory byte_addr in - let byte_value = Int64.of_int (Char.code byte) in - let shifted_byte = Int64.shift_left byte_value (offset * 8) in - read_bytes (Int64.logor acc shifted_byte) (offset + 1)) - else return acc - in - match size with - | 1 | 2 | 4 | 8 -> read_bytes 0L 0 - | _ -> fail "Unsupported load size" -;; - -let store_in_memory address value size = - let get_int64_byte n = - Char.chr (Int64.to_int (Int64.logand (Int64.shift_right value (n * 8)) 0xFFL)) - in - let* state = read in - let new_memory = put_bytes_to_memory get_int64_byte size address state.memory in - let new_state = { state with memory = new_memory } in - write new_state -;; - -let execute_load_int rd rs1 imm size is_signed = - let* base_address = get_register_value rs1 in - let* address_info = get_address12_value imm in - let offset = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let address = Int64.add base_address (sext offset) in - let* value = load_from_memory address size in - let result = if is_signed then sext value else zext value in - set_register_value rd result -;; - -let execute_store_int rs1 rs2 imm size = - let* base_address = get_register_value rs2 in - let* address_info = get_address12_value imm in - let offset = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let address = Int64.add base_address (sext offset) in - let* value = get_register_value rs1 in - store_in_memory address value size -;; - -let execute_vle32v vd rs1 imm = - let* state = read in - let* base_address = get_register_value rs1 in - let* address_info = get_address12_value imm in - let offset = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let address = Int64.add base_address offset in - let vector_length = state.vector_length in - let rec load_values address element_idx acc = - if element_idx < vector_length - then - let* value = load_from_memory address state.vector_element_length in - let next_address = Int64.add address (Int64.of_int state.vector_element_length) in - load_values next_address (element_idx + 1) (value :: acc) - else return (List.rev acc) - in - let* vector_values = load_values address 0 [] in - set_vregister_value vd vector_values -;; - -let execute_vse32v vs rs1 imm = - let* base_address = get_register_value rs1 in - let* address_info = get_address12_value imm in - let offset = - match address_info with - | Immediate imm_value -> imm_value - | LabelAddress label_address -> label_address - in - let address = Int64.add base_address offset in - let* vector_value = get_vregister_value vs in - let rec store_values element_idx addr = - let* state = read in - if element_idx < state.vector_length - then ( - let element = List.nth vector_value element_idx in - let* () = store_in_memory addr element state.vector_element_length in - store_values (element_idx + 1) (Int64.add addr 4L)) - else return () - in - store_values 0 address -;; - -let execute_vector_arithmetic vd vs1 vs2 op = - let* vec1 = get_vregister_value vs1 in - let* vec2 = get_vregister_value vs2 in - let result = List.map2 op vec1 vec2 in - set_vregister_value vd result -;; - -let execute_vector_scalar vd vs1 rs2 op = - let* vec = get_vregister_value vs1 in - let* scalar = get_register_value rs2 in - let result = List.map (fun x -> op x scalar) vec in - set_vregister_value vd result -;; - -let load_string_from_memory address size = - let rec load_chars acc offset = - if offset < size - then ( - let char_addr = Int64.add address (Int64.of_int offset) in - let* char = load_byte_from_memory char_addr in - match char with - | '\000' -> return acc - | _ -> load_chars (acc ^ String.make 1 char) (offset + 1)) - else return acc - in - load_chars "" 0 -;; - -let handle_syscall = - let* state = read in - let* syscall_number = get_register_value A7 in - let* arg1 = get_register_value A0 in - let* arg2 = get_register_value A1 in - let* arg3 = get_register_value A2 in - match syscall_number with - | 93L -> - (* perform exit *) - let exit_code = Int64.to_int arg1 in - exit exit_code - | 64L -> - (* perform write - take information from memory and put in fd (only stdout supported) *) - let fd = Int64.to_int arg1 in - let address = arg2 in - let size = arg3 in - (match fd with - | 1 -> - let* output = load_string_from_memory address (Int64.to_int size) in - return (Printf.printf "%s\n" output) - | _ -> fail "Unsupported file descriptor for write syscall") - | 63L -> - (* perform read - read line and put input string into memory *) - let fd = Int64.to_int arg1 in - let buf = arg2 in - (match fd with - | 0 -> - let str = read_line () in - let new_memory = put_string_to_memory str buf state.memory in - let new_state = { state with memory = new_memory } in - let* () = write new_state in - set_register_value A0 (Int64.of_int (String.length str)) - | _ -> fail "Unsupported file descriptor for read syscall") - | _ -> fail "Unsupported syscall" -;; - -let execute_j imm_value = - let* state = read in - let* address_info = get_address20_value imm_value in - let* new_program_idx = - match address_info with - | Immediate imm_value -> - let* current_address = translate_index_to_address state.program_idx in - let* target_index = - translate_address_to_index (Int64.add (sext imm_value) current_address) - in - return target_index - | LabelAddress label_address -> - let* target_index = translate_address_to_index label_address in - return target_index - in - set_program_idx (Int64.sub new_program_idx 4L) -;; - -let execute_jalr rd rs1 imm = - let* state = read in - let* val_rs1 = get_register_value rs1 in - let* address_info = get_address12_value imm in - let* target_idx = - match address_info with - | Immediate imm_value -> translate_address_to_index (Int64.add val_rs1 imm_value) - | LabelAddress label_address -> translate_address_to_index label_address - in - let* () = set_register_value rd (Int64.add state.program_idx 4L) in - (* last bit of result is set 0 according to specification *) - let new_program_idx = Int64.logand (Int64.sub target_idx 4L) (Int64.neg 1L) in - set_program_idx new_program_idx -;; - -let get_upper_immediate = function - | ImmediateAddress20 value -> return (Int64.shift_left (Int64.of_int value) 12) - | LabelAddress20 label -> - let* label_address = resolve_label_address label in - return (sext (Int64.shift_left label_address 12)) -;; - -let execute_instruction instr = - let* state = read in - match instr with - | Add (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.add false - | Sub (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.sub false - | Xor (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.logxor false - | Or (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.logor false - | And (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.logand false - | Sll (rd, rs1, rs2) -> execute_shift_op rd rs1 rs2 Int64.shift_left - | Srl (rd, rs1, rs2) -> execute_shift_op rd rs1 rs2 Int64.shift_right_logical - | Sra (rd, rs1, rs2) -> execute_shift_op rd rs1 rs2 Int64.shift_right - | Slt (rd, rs1, rs2) -> - execute_comparison_op rd rs1 rs2 (fun arg1 arg2 -> Int64.compare arg1 arg2 < 0) - | Sltu (rd, rs1, rs2) -> - execute_comparison_op rd rs1 rs2 (fun arg1 arg2 -> - Int64.unsigned_compare arg1 arg2 < 0) - | Addi (rd, rs1, imm) -> execute_immediate_op rd rs1 imm Int64.add false - | Xori (rd, rs1, imm) -> execute_immediate_op rd rs1 imm Int64.logxor false - | Ori (rd, rs1, imm) -> execute_immediate_op rd rs1 imm Int64.logor false - | Andi (rd, rs1, imm) -> execute_immediate_op rd rs1 imm Int64.logand false - | Slli (rd, rs1, imm) -> execute_shift_immediate_op rd rs1 imm Int64.shift_left - | Srli (rd, rs1, imm) -> execute_shift_immediate_op rd rs1 imm Int64.shift_right_logical - | Srai (rd, rs1, imm) -> execute_shift_immediate_op rd rs1 imm Int64.shift_right - | Slti (rd, rs1, imm) -> - execute_immediate_op - rd - rs1 - imm - (fun arg1 imm_value -> - match Int64.compare arg1 imm_value with - | x when x < 0 -> 1L - | _ -> 0L) - false - | Sltiu (rd, rs1, imm) -> - execute_immediate_op - rd - rs1 - imm - (fun arg1 imm_value -> - match Int64.unsigned_compare arg1 imm_value with - | x when x < 0 -> 1L - | _ -> 0L) - false - | Lb (rd, rs1, imm) -> execute_load_int rd rs1 imm 1 true - | Lh (rd, rs1, imm) -> execute_load_int rd rs1 imm 2 true - | Lw (rd, rs1, imm) -> execute_load_int rd rs1 imm 4 true - | Lbu (rd, rs1, imm) -> execute_load_int rd rs1 imm 1 false - | Lhu (rd, rs1, imm) -> execute_load_int rd rs1 imm 2 false - | Sb (rs1, rs2, imm) -> execute_store_int rs1 rs2 imm 1 - | Sh (rs1, rs2, imm) -> execute_store_int rs1 rs2 imm 2 - | Sw (rs1, rs2, imm) -> execute_store_int rs1 rs2 imm 4 - | Beq (rs1, rs2, imm_value) -> handle_branch_condition rs1 (Some rs2) imm_value ( = ) - | Beqz (rs1, imm_value) -> handle_branch_condition rs1 None imm_value ( = ) - | Bne (rs1, rs2, imm_value) -> handle_branch_condition rs1 (Some rs2) imm_value ( <> ) - | Bnez (rs1, imm_value) -> handle_branch_condition rs1 None imm_value ( <> ) - | Blt (rs1, rs2, imm_value) -> handle_branch_condition rs1 (Some rs2) imm_value ( < ) - | Bltz (rs1, imm_value) -> handle_branch_condition rs1 None imm_value ( < ) - | Bgt (rs1, rs2, imm_value) -> handle_branch_condition rs1 (Some rs2) imm_value ( > ) - | Bgtz (rs1, imm_value) -> handle_branch_condition rs1 None imm_value ( > ) - | Bge (rs1, rs2, imm_value) -> handle_branch_condition rs1 (Some rs2) imm_value ( >= ) - | Bltu (rs1, rs2, imm_value) -> - let comparison_fn arg1 arg2 = Int64.unsigned_compare arg1 arg2 < 0 in - handle_branch_condition rs1 (Some rs2) imm_value comparison_fn - | Bgeu (rs1, rs2, imm_value) -> - let comparison_fn arg1 arg2 = Int64.unsigned_compare arg1 arg2 >= 0 in - handle_branch_condition rs1 (Some rs2) imm_value comparison_fn - | Jal (rd, imm_value) -> - let* address_info = get_address20_value imm_value in - let* target_idx = - match address_info with - | Immediate imm_value -> - let* current_address = translate_index_to_address state.program_idx in - translate_address_to_index (Int64.add imm_value (sext current_address)) - | LabelAddress label_address -> translate_address_to_index label_address - in - let* () = set_register_value rd (Int64.add state.program_idx 4L) in - set_program_idx (Int64.sub target_idx 4L) - | Jalr (rd, rs1, imm) -> execute_jalr rd rs1 imm - | Jr rs1 -> - let* val_rs1 = get_register_value rs1 in - let* target_idx = translate_address_to_index val_rs1 in - set_program_idx (Int64.sub target_idx 4L) - | J imm_value -> execute_j imm_value - | Lui (rd, imm) -> - let* imm_value = get_upper_immediate imm in - set_register_value rd imm_value - | Auipc (rd, imm) -> - let* imm_value = get_upper_immediate imm in - let new_value = Int64.add state.program_idx imm_value in - set_register_value rd new_value - | Ecall -> handle_syscall - | Mul (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.mul false - | Div (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.div false - | Rem (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.rem false - | Mv (rd, rs) -> execute_immediate_op rd rs (ImmediateAddress12 0) Int64.add false - | Li (rd, imm) -> - let* imm_value = - match imm with - | ImmediateAddress32 value -> return (Int64.of_int value) - | LabelAddress32 label -> resolve_label_address label - in - set_register_value rd (sext imm_value) - | Addiw (rd, rs1, imm) -> execute_immediate_op rd rs1 imm Int64.add true - | Mulw (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.mul true - | Addw (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.add true - | Subw (rd, rs1, rs2) -> execute_arithmetic_op rd rs1 rs2 Int64.sub true - | Ret -> execute_jalr X0 X1 (ImmediateAddress12 0) - | La (rd, imm) -> - let* address_info = get_address32_value imm in - let* new_address = - match address_info with - | Immediate imm_value -> - let* current_address = translate_index_to_address state.program_idx in - let* resolved_address = - translate_address_to_index (Int64.add imm_value current_address) - in - return resolved_address - | LabelAddress label_address -> return label_address - in - set_register_value rd new_address - | Adduw (rd, rs1, rs2) -> - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = Int64.add val1 val2 in - let result = zext result in - set_register_value rd result - | Sh1add (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 1 false - | Sh1adduw (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 1 true - | Sh2add (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 2 false - | Sh2adduw (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 2 true - | Sh3add (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 3 false - | Sh3adduw (rd, rs1, rs2) -> execute_shnadd rd rs1 rs2 3 true - | Andn (rd, rs1, rs2) -> - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = Int64.logand val1 (Int64.lognot val2) in - set_register_value rd result - | Orn (rd, rs1, rs2) -> - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = Int64.logor val1 (Int64.lognot val2) in - set_register_value rd result - | Xnor (rd, rs1, rs2) -> - let* val1 = get_register_value rs1 in - let* val2 = get_register_value rs2 in - let result = Int64.logxor val1 val2 in - let result_final = Int64.lognot result in - set_register_value rd result_final - | Lwu (rd, rs1, imm) -> execute_load_int rd rs1 imm 4 false - | Vle32v (vd, rs1, imm) -> execute_vle32v vd rs1 imm - | Vse32v (vs, rs1, imm) -> execute_vse32v vs rs1 imm - | Vaddvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.add - | Vaddvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.add - | Vsubvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.sub - | Vsubvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.sub - | Vmulvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.mul - | Vmulvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.mul - | Vdivvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.div - | Vdivvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.div - | Vandvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.logand - | Vandvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.logand - | Vorvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.logor - | Vorvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.logor - | Vxorvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.logxor - | Vxorvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.logxor - | Vminvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.min - | Vminvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.min - | Vmaxvv (vd, vs1, vs2) -> execute_vector_arithmetic vd vs1 vs2 Int64.max - | Vmaxvx (vd, vs1, rs2) -> execute_vector_scalar vd vs1 rs2 Int64.max - | Vmseqvv (vd, vs1, vs2) -> - execute_vector_arithmetic vd vs1 vs2 (fun x y -> if x = y then 1L else 0L) - | Vmseqvx (vd, vs1, rs2) -> - execute_vector_scalar vd vs1 rs2 (fun x y -> if x = y then 1L else 0L) - | Vsetvli _ -> return () - | Vredsumvs (vd, vs1, vs2) -> - let* vec1 = get_vregister_value vs1 in - let* vec2 = get_vregister_value vs2 in - let* vecd = get_vregister_value vd in - let vec1_first = List.hd vec1 in - let vec2_sum = List.fold_left Int64.add 0L vec2 in - let result_first = Int64.add vec2_sum vec1_first in - let result_rest = List.tl vecd in - let result = result_first :: result_rest in - set_vregister_value vd result - | _ -> fail "Unsupported instruction" -;; - -let nth_opt_int64 l n = - (* similar to List.nth_opt function, but we make steps of 4L *) - match n with - | x when x < 0 -> fail "Index cannot be negative" - | _ -> - let rec nth_aux l n = - match l with - | [] -> return None - | a :: l -> - (match n with - | 0L -> return (Some a) - | _ -> nth_aux l (Int64.sub n 4L)) - in - nth_aux l (Int64.of_int n) -;; - -let show_memory state = - let memory_string = - Int64Map.fold - (fun address value acc -> - acc ^ Printf.sprintf "%Ld: %d\n" address (int_of_char value)) - state.memory - "Memory:\n" - in - memory_string -;; - -let show_state state = - let registers_str = - let rec loop acc i = - if i > 31 - then acc - else ( - let reg = "X" ^ string_of_int i in - let value = StringMap.find_opt reg state.registers |> Option.value ~default:0L in - loop (acc ^ Printf.sprintf "%s: %Ld\n" reg value) (i + 1)) - in - loop "" 0 - in - let vector_registers_str = - let rec loop acc i = - if i > 31 - then acc - else ( - let vreg = "V" ^ string_of_int i in - let values = - StringMap.find_opt vreg state.vregisters |> Option.value ~default:[] - in - let values_str = - List.fold_left (fun acc value -> acc ^ Printf.sprintf "%Ld " value) "" values - in - loop (acc ^ Printf.sprintf "%s: [%s]\n" vreg values_str) (i + 1)) - in - loop "" 0 - in - let memory_str = show_memory state in - let program_idx_str = Printf.sprintf "Program index: %Ld" state.program_idx in - let result = registers_str in - let result = result ^ vector_registers_str in - let result = result ^ memory_str in - let result = result ^ program_idx_str in - result -;; - -let traverse_program () = - let rec prog_trav_helper () = - let* state = read in - let* expr_opt = nth_opt_int64 state.program (Int64.to_int state.program_idx) in - match expr_opt with - | None -> return state - | Some (InstructionExpr instr) -> - let* () = execute_instruction instr in - let* () = increment_program_idx () in - prog_trav_helper () - | Some (LabelExpr _) | Some (DirectiveExpr _) -> - let* () = increment_program_idx () in - prog_trav_helper () - in - let* () = execute_j (LabelAddress20 "_start") in - prog_trav_helper () -;; - -let interpret program = - let initial_state = init_state program in - run (traverse_program ()) initial_state -;; - -let%expect_test "test_arithmetic" = - let program = - [ LabelExpr "_start" - ; InstructionExpr (Li (A0, ImmediateAddress32 0b1010)) - ; InstructionExpr (Li (A1, ImmediateAddress32 0b1100)) - ; InstructionExpr (Sll (A2, A0, A1)) - ; InstructionExpr (Srl (A3, A2, A1)) - ; InstructionExpr (Sra (A4, A2, A1)) - ; InstructionExpr (Slli (A5, A0, ImmediateAddress12 2)) - ; InstructionExpr (Srli (A6, A5, ImmediateAddress12 2)) - ; InstructionExpr (Srai (A7, A5, ImmediateAddress12 2)) - ; InstructionExpr (Sub (S2, A1, A0)) - ; InstructionExpr (Xor (S3, A0, A1)) - ; InstructionExpr (Or (S4, A0, A1)) - ; InstructionExpr (And (S5, A0, A1)) - ] - in - match interpret program with - | Ok (_, final_state) -> - let state_str = show_state final_state in - print_string state_str; - [%expect - {| - X0: 0 - X1: 0 - X2: 0 - X3: 0 - X4: 0 - X5: 0 - X6: 0 - X7: 0 - X8: 0 - X9: 0 - X10: 10 - X11: 12 - X12: 40960 - X13: 10 - X14: 10 - X15: 40 - X16: 10 - X17: 10 - X18: 2 - X19: 6 - X20: 14 - X21: 8 - X22: 0 - X23: 0 - X24: 0 - X25: 0 - X26: 0 - X27: 0 - X28: 0 - X29: 0 - X30: 0 - X31: 0 - V0: [0 0 0 0 ] - V1: [0 0 0 0 ] - V2: [0 0 0 0 ] - V3: [0 0 0 0 ] - V4: [0 0 0 0 ] - V5: [0 0 0 0 ] - V6: [0 0 0 0 ] - V7: [0 0 0 0 ] - V8: [0 0 0 0 ] - V9: [0 0 0 0 ] - V10: [0 0 0 0 ] - V11: [0 0 0 0 ] - V12: [0 0 0 0 ] - V13: [0 0 0 0 ] - V14: [0 0 0 0 ] - V15: [0 0 0 0 ] - V16: [0 0 0 0 ] - V17: [0 0 0 0 ] - V18: [0 0 0 0 ] - V19: [0 0 0 0 ] - V20: [0 0 0 0 ] - V21: [0 0 0 0 ] - V22: [0 0 0 0 ] - V23: [0 0 0 0 ] - V24: [0 0 0 0 ] - V25: [0 0 0 0 ] - V26: [0 0 0 0 ] - V27: [0 0 0 0 ] - V28: [0 0 0 0 ] - V29: [0 0 0 0 ] - V30: [0 0 0 0 ] - V31: [0 0 0 0 ] - Memory: - Program index: 52 - |}] - | Error e -> print_string ("Error: " ^ e) -;; - -let%expect_test "test_jalr" = - let program = - [ LabelExpr "_start" - ; InstructionExpr (Li (Ra, ImmediateAddress32 4)) - ; InstructionExpr (Jalr (Sp, X1, ImmediateAddress12 8)) - ; InstructionExpr (Li (Gp, ImmediateAddress32 10)) - ; LabelExpr "target" - ; InstructionExpr (Li (Tp, ImmediateAddress32 20)) - ] - in - match interpret program with - | Ok (_, final_state) -> - let state_str = show_state final_state in - print_string state_str; - [%expect - {| - X0: 0 - X1: 4 - X2: 12 - X3: 0 - X4: 20 - X5: 0 - X6: 0 - X7: 0 - X8: 0 - X9: 0 - X10: 0 - X11: 0 - X12: 0 - X13: 0 - X14: 0 - X15: 0 - X16: 0 - X17: 0 - X18: 0 - X19: 0 - X20: 0 - X21: 0 - X22: 0 - X23: 0 - X24: 0 - X25: 0 - X26: 0 - X27: 0 - X28: 0 - X29: 0 - X30: 0 - X31: 0 - V0: [0 0 0 0 ] - V1: [0 0 0 0 ] - V2: [0 0 0 0 ] - V3: [0 0 0 0 ] - V4: [0 0 0 0 ] - V5: [0 0 0 0 ] - V6: [0 0 0 0 ] - V7: [0 0 0 0 ] - V8: [0 0 0 0 ] - V9: [0 0 0 0 ] - V10: [0 0 0 0 ] - V11: [0 0 0 0 ] - V12: [0 0 0 0 ] - V13: [0 0 0 0 ] - V14: [0 0 0 0 ] - V15: [0 0 0 0 ] - V16: [0 0 0 0 ] - V17: [0 0 0 0 ] - V18: [0 0 0 0 ] - V19: [0 0 0 0 ] - V20: [0 0 0 0 ] - V21: [0 0 0 0 ] - V22: [0 0 0 0 ] - V23: [0 0 0 0 ] - V24: [0 0 0 0 ] - V25: [0 0 0 0 ] - V26: [0 0 0 0 ] - V27: [0 0 0 0 ] - V28: [0 0 0 0 ] - V29: [0 0 0 0 ] - V30: [0 0 0 0 ] - V31: [0 0 0 0 ] - Memory: - Program index: 24 - |}] - | Error e -> print_string ("Error: " ^ e) -;; - -let%expect_test "test_jal" = - let program = - [ LabelExpr "_start" - ; InstructionExpr (Jal (T0, LabelAddress20 "target")) - ; InstructionExpr (Li (T1, ImmediateAddress32 10)) - ; LabelExpr "target" - ; InstructionExpr (Li (T2, ImmediateAddress32 20)) - ] - in - match interpret program with - | Ok (_, final_state) -> - let state_str = show_state final_state in - print_string state_str; - [%expect - {| - X0: 0 - X1: 0 - X2: 0 - X3: 0 - X4: 0 - X5: 8 - X6: 0 - X7: 20 - X8: 0 - X9: 0 - X10: 0 - X11: 0 - X12: 0 - X13: 0 - X14: 0 - X15: 0 - X16: 0 - X17: 0 - X18: 0 - X19: 0 - X20: 0 - X21: 0 - X22: 0 - X23: 0 - X24: 0 - X25: 0 - X26: 0 - X27: 0 - X28: 0 - X29: 0 - X30: 0 - X31: 0 - V0: [0 0 0 0 ] - V1: [0 0 0 0 ] - V2: [0 0 0 0 ] - V3: [0 0 0 0 ] - V4: [0 0 0 0 ] - V5: [0 0 0 0 ] - V6: [0 0 0 0 ] - V7: [0 0 0 0 ] - V8: [0 0 0 0 ] - V9: [0 0 0 0 ] - V10: [0 0 0 0 ] - V11: [0 0 0 0 ] - V12: [0 0 0 0 ] - V13: [0 0 0 0 ] - V14: [0 0 0 0 ] - V15: [0 0 0 0 ] - V16: [0 0 0 0 ] - V17: [0 0 0 0 ] - V18: [0 0 0 0 ] - V19: [0 0 0 0 ] - V20: [0 0 0 0 ] - V21: [0 0 0 0 ] - V22: [0 0 0 0 ] - V23: [0 0 0 0 ] - V24: [0 0 0 0 ] - V25: [0 0 0 0 ] - V26: [0 0 0 0 ] - V27: [0 0 0 0 ] - V28: [0 0 0 0 ] - V29: [0 0 0 0 ] - V30: [0 0 0 0 ] - V31: [0 0 0 0 ] - Memory: - Program index: 20 - |}] - | Error e -> print_string ("Error: " ^ e) -;; - -let%expect_test "test_j_immediate" = - let program = - [ DirectiveExpr (Word 1l) - ; DirectiveExpr (StringDir "abcd") - ; DirectiveExpr (Space 4) - ; LabelExpr "_start" - ; InstructionExpr (J (ImmediateAddress20 8)) - ; InstructionExpr (Li (S0, ImmediateAddress32 10)) - ; InstructionExpr (Li (S1, ImmediateAddress32 20)) - ] - in - match interpret program with - | Ok (_, final_state) -> - let state_str = show_state final_state in - print_string state_str; - [%expect - {| - X0: 0 - X1: 0 - X2: 0 - X3: 0 - X4: 0 - X5: 0 - X6: 0 - X7: 0 - X8: 0 - X9: 20 - X10: 0 - X11: 0 - X12: 0 - X13: 0 - X14: 0 - X15: 0 - X16: 0 - X17: 0 - X18: 0 - X19: 0 - X20: 0 - X21: 0 - X22: 0 - X23: 0 - X24: 0 - X25: 0 - X26: 0 - X27: 0 - X28: 0 - X29: 0 - X30: 0 - X31: 0 - V0: [0 0 0 0 ] - V1: [0 0 0 0 ] - V2: [0 0 0 0 ] - V3: [0 0 0 0 ] - V4: [0 0 0 0 ] - V5: [0 0 0 0 ] - V6: [0 0 0 0 ] - V7: [0 0 0 0 ] - V8: [0 0 0 0 ] - V9: [0 0 0 0 ] - V10: [0 0 0 0 ] - V11: [0 0 0 0 ] - V12: [0 0 0 0 ] - V13: [0 0 0 0 ] - V14: [0 0 0 0 ] - V15: [0 0 0 0 ] - V16: [0 0 0 0 ] - V17: [0 0 0 0 ] - V18: [0 0 0 0 ] - V19: [0 0 0 0 ] - V20: [0 0 0 0 ] - V21: [0 0 0 0 ] - V22: [0 0 0 0 ] - V23: [0 0 0 0 ] - V24: [0 0 0 0 ] - V25: [0 0 0 0 ] - V26: [0 0 0 0 ] - V27: [0 0 0 0 ] - V28: [0 0 0 0 ] - V29: [0 0 0 0 ] - V30: [0 0 0 0 ] - V31: [0 0 0 0 ] - Memory: - 0: 1 - 1: 0 - 2: 0 - 3: 0 - 4: 97 - 5: 98 - 6: 99 - 7: 100 - Program index: 28 - |}] - | Error e -> print_string ("Error: " ^ e) -;; diff --git a/RISCV_ASM/lib/interpreter.mli b/RISCV_ASM/lib/interpreter.mli deleted file mode 100644 index d918dbd87..000000000 --- a/RISCV_ASM/lib/interpreter.mli +++ /dev/null @@ -1,40 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast -module StringMap : Map.S with type key = string (* used to organize registers *) -module Int64Map : Map.S with type key = Int64.t (* used to organize memory *) - -type state = - { program : ast - ; registers : int64 StringMap.t - ; vregisters : int64 list StringMap.t - ; max_vector_length : int - ; vector_element_length : int - ; vector_length : int - ; memory : char Int64Map.t - ; program_idx : int64 - (* index of current expr in program, used as analogy of Program Counter, each expr step is 4 *) - } - -(* Combined monad for errors and state *) -module type CombinedMonadType = sig - type ('s, 'a) t - - val return : 'a -> ('s, 'a) t - val ( >>= ) : ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t - val fail : string -> ('s, 'a) t - val read : ('s, 's) t - val write : 's -> ('s, unit) t - val run : ('s, 'a) t -> 's -> ('s * 'a, string) result - - module Syntax : sig - val ( let* ) : ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t - end -end - -module CombinedMonad : CombinedMonadType - -val interpret : ast -> (state * state, label) result -val show_state : state -> string diff --git a/RISCV_ASM/lib/parser.ml b/RISCV_ASM/lib/parser.ml deleted file mode 100644 index d7896566f..000000000 --- a/RISCV_ASM/lib/parser.ml +++ /dev/null @@ -1,1326 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Angstrom -open Ast - -let parse_number = - let sign = option "" (string "-") in - let digits = - take_while1 (function - | '0' .. '9' -> true - | _ -> false) - in - lift2 ( ^ ) sign digits >>= fun num_str -> return (int_of_string num_str) -;; - -let ws = - take_while (function - | ' ' | '\t' | '\n' | '\r' -> true - | _ -> false) -;; - -let parse_string = - take_while1 (function - | ' ' | '\t' | '\n' | '\r' | ',' -> false - | _ -> true) -;; - -let parse_escaped_char = char '\\' *> (char 'n' *> return '\n') - -let parse_regular_char = - satisfy (function - | '"' | '\\' -> false - | _ -> true) -;; - -let char_list_to_string char_list = - let len = List.length char_list in - String.init len (List.nth char_list) -;; - -let parse_quoted_string = - char '"' *> many (parse_escaped_char <|> parse_regular_char) - <* char '"' - >>| char_list_to_string -;; - -let parse_type = char '@' *> parse_string >>= fun str -> return (Type str) - -let parse_label_string = - take_while1 (function - | ' ' | '\t' | '\n' | '\r' | ',' | ':' | '(' -> false - | _ -> true) -;; - -let ws_opt p = ws *> p <* ws - -let parse_register = - ws_opt - (choice - [ string "x10" *> return X10 - ; string "x11" *> return X11 - ; string "x12" *> return X12 - ; string "x13" *> return X13 - ; string "x14" *> return X14 - ; string "x15" *> return X15 - ; string "x16" *> return X16 - ; string "x17" *> return X17 - ; string "x18" *> return X18 - ; string "x19" *> return X19 - ; string "x20" *> return X20 - ; string "x21" *> return X21 - ; string "x22" *> return X22 - ; string "x23" *> return X23 - ; string "x24" *> return X24 - ; string "x25" *> return X25 - ; string "x26" *> return X26 - ; string "x27" *> return X27 - ; string "x28" *> return X28 - ; string "x29" *> return X29 - ; string "x30" *> return X30 - ; string "x31" *> return X31 - ; string "x0" *> return X0 - ; string "x1" *> return X1 - ; string "x2" *> return X2 - ; string "x3" *> return X3 - ; string "x4" *> return X4 - ; string "x5" *> return X5 - ; string "x6" *> return X6 - ; string "x7" *> return X7 - ; string "x8" *> return X8 - ; string "x9" *> return X9 - ; string "zero" *> return Zero - ; string "ra" *> return Ra - ; string "sp" *> return Sp - ; string "gp" *> return Gp - ; string "tp" *> return Tp - ; string "t0" *> return T0 - ; string "t1" *> return T1 - ; string "t2" *> return T2 - ; string "s0" *> return S0 - ; string "fp" *> return Fp - ; string "s10" *> return S10 - ; string "s11" *> return S11 - ; string "s1" *> return S1 - ; string "a0" *> return A0 - ; string "a1" *> return A1 - ; string "a2" *> return A2 - ; string "a3" *> return A3 - ; string "a4" *> return A4 - ; string "a5" *> return A5 - ; string "a6" *> return A6 - ; string "a7" *> return A7 - ; string "s2" *> return S2 - ; string "s3" *> return S3 - ; string "s4" *> return S4 - ; string "s5" *> return S5 - ; string "s6" *> return S6 - ; string "s7" *> return S7 - ; string "s8" *> return S8 - ; string "s9" *> return S9 - ; string "t3" *> return T3 - ; string "t4" *> return T4 - ; string "t5" *> return T5 - ; string "t6" *> return T6 - ]) -;; - -let parse_vector_register = - ws_opt - (choice - [ string "v10" *> return V10 - ; string "v11" *> return V11 - ; string "v12" *> return V12 - ; string "v13" *> return V13 - ; string "v14" *> return V14 - ; string "v15" *> return V15 - ; string "v16" *> return V16 - ; string "v17" *> return V17 - ; string "v18" *> return V18 - ; string "v19" *> return V19 - ; string "v20" *> return V20 - ; string "v21" *> return V21 - ; string "v22" *> return V22 - ; string "v23" *> return V23 - ; string "v24" *> return V24 - ; string "v25" *> return V25 - ; string "v26" *> return V26 - ; string "v27" *> return V27 - ; string "v28" *> return V28 - ; string "v29" *> return V29 - ; string "v30" *> return V30 - ; string "v31" *> return V31 - ; string "v0" *> return V0 - ; string "v1" *> return V1 - ; string "v2" *> return V2 - ; string "v3" *> return V3 - ; string "v4" *> return V4 - ; string "v5" *> return V5 - ; string "v6" *> return V6 - ; string "v7" *> return V7 - ; string "v8" *> return V8 - ; string "v9" *> return V9 - ]) -;; - -let parse_float_register = - ws_opt - (choice - [ string "f10" *> return F10 - ; string "f11" *> return F11 - ; string "f12" *> return F12 - ; string "f13" *> return F13 - ; string "f14" *> return F14 - ; string "f15" *> return F15 - ; string "f16" *> return F16 - ; string "f17" *> return F17 - ; string "f18" *> return F18 - ; string "f19" *> return F19 - ; string "f20" *> return F20 - ; string "f21" *> return F21 - ; string "f22" *> return F22 - ; string "f23" *> return F23 - ; string "f24" *> return F24 - ; string "f25" *> return F25 - ; string "f26" *> return F26 - ; string "f27" *> return F27 - ; string "f28" *> return F28 - ; string "f29" *> return F29 - ; string "f30" *> return F30 - ; string "f31" *> return F31 - ; string "f0" *> return F0 - ; string "f1" *> return F1 - ; string "f2" *> return F2 - ; string "f3" *> return F3 - ; string "f4" *> return F4 - ; string "f5" *> return F5 - ; string "f6" *> return F6 - ; string "f7" *> return F7 - ; string "f8" *> return F8 - ; string "f9" *> return F9 - ; string "ft10" *> return Ft10 - ; string "ft11" *> return Ft11 - ; string "ft0" *> return Ft0 - ; string "ft1" *> return Ft1 - ; string "ft2" *> return Ft2 - ; string "ft3" *> return Ft3 - ; string "ft4" *> return Ft4 - ; string "ft5" *> return Ft5 - ; string "ft6" *> return Ft6 - ; string "ft7" *> return Ft7 - ; string "ft8" *> return Ft8 - ; string "ft9" *> return Ft9 - ; string "fa0" *> return Fa0 - ; string "fa1" *> return Fa1 - ; string "fa2" *> return Fa2 - ; string "fa3" *> return Fa3 - ; string "fa4" *> return Fa4 - ; string "fa5" *> return Fa5 - ; string "fa6" *> return Fa6 - ; string "fa7" *> return Fa7 - ; string "fs10" *> return Fs10 - ; string "fs11" *> return Fs11 - ; string "fs0" *> return Fs0 - ; string "fs1" *> return Fs1 - ; string "fs2" *> return Fs2 - ; string "fs3" *> return Fs3 - ; string "fs4" *> return Fs4 - ; string "fs5" *> return Fs5 - ; string "fs6" *> return Fs6 - ; string "fs7" *> return Fs7 - ; string "fs8" *> return Fs8 - ; string "fs9" *> return Fs9 - ]) -;; - -let parse_immediate12 = ws_opt (lift (fun imm -> ImmediateAddress12 imm) parse_number) -let parse_immediate20 = ws_opt (lift (fun imm -> ImmediateAddress20 imm) parse_number) -let parse_immediate32 = ws_opt (lift (fun imm -> ImmediateAddress32 imm) parse_number) - -let parse_label_address12 = - ws_opt (lift (fun str -> LabelAddress12 str) parse_label_string) -;; - -let parse_label_address20 = - ws_opt (lift (fun str -> LabelAddress20 str) parse_label_string) -;; - -let parse_label_address32 = - ws_opt (lift (fun str -> LabelAddress32 str) parse_label_string) -;; - -let parse_label_expr = - ws_opt (lift (fun str -> LabelExpr str) (parse_label_string <* ws_opt (char ':'))) -;; - -let parse_address12 = ws_opt (choice [ parse_immediate12; parse_label_address12 ]) -let parse_address20 = ws_opt (choice [ parse_immediate20; parse_label_address20 ]) -let parse_address32 = ws_opt (choice [ parse_immediate32; parse_label_address32 ]) - -let parse_string_with_spaces str = - string str - *> (peek_char - >>= function - | Some (' ' | '\n' | '\t') -> return () - | None -> return () - | _ -> fail "") -;; - -let parse_section_subargs = - lift2 - (fun section_arg3 i -> section_arg3, i) - parse_type - (peek_char - >>= function - | Some ',' -> ws_opt (char ',') *> ws_opt (parse_number >>| fun i -> Some i) - | _ -> return None) -;; - -let parse_section_args = - lift2 - (fun section_arg2 section_subargs -> section_arg2, section_subargs) - parse_quoted_string - (ws_opt - (peek_char - >>= function - | Some ',' -> - ws_opt (char ',') *> ws_opt (parse_section_subargs >>| fun t -> Some t) - | _ -> return None)) -;; - -let parse_section = - parse_string_with_spaces ".section" - *> ws_opt - (lift2 - (fun section_arg1 section_args -> - DirectiveExpr (Section (section_arg1, section_args))) - parse_string - (ws_opt - (peek_char - >>= function - | Some ',' -> - ws_opt (char ',') *> ws_opt (parse_section_args >>| fun s -> Some s) - | _ -> return None))) -;; - -let parse_directive = - ws_opt - (choice - [ parse_string_with_spaces ".text" *> return (DirectiveExpr Text) - ; parse_string_with_spaces ".globl" - *> ws_opt (lift (fun label -> DirectiveExpr (Globl label)) parse_address12) - ; parse_string_with_spaces ".type" - *> ws_opt - (lift2 - (fun str type_str -> DirectiveExpr (TypeDir (str, type_str))) - parse_string - (ws_opt (char ',') *> parse_type)) - ; parse_section - ; parse_string_with_spaces ".string" - *> ws_opt (lift (fun str -> DirectiveExpr (StringDir str)) parse_quoted_string) - ; parse_string_with_spaces ".word" - *> ws_opt - (lift (fun int -> DirectiveExpr (Word (Int32.of_int int))) parse_number) - ; parse_string_with_spaces ".space" - *> ws_opt (lift (fun int -> DirectiveExpr (Space int)) parse_number) - ]) -;; - -let parse_instruction = - ws_opt - (choice - [ parse_string_with_spaces "add" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Add (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sub" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sub (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "xor" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Xor (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "or" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Or (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "and" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (And (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sll" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sll (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "srl" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Srl (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sra" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sra (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "slt" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Slt (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sltu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sltu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "addi" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Addi (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "xori" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Xori (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "ori" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Ori (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "andi" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Andi (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "slli" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Slli (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "srli" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Srli (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "srai" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Srai (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "slti" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Slti (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "sltiu" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Sltiu (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "lb" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lb (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "lh" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lh (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "lw" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lw (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "lbu" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lbu (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "lhu" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lhu (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "sb" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Sb (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "sh" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Sh (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "sw" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Sw (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "beq" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Beq (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "beqz" - *> ws_opt - (lift2 - (fun r1 addr12 -> InstructionExpr (Beqz (r1, addr12))) - parse_register - (char ',' *> parse_address12)) - ; parse_string_with_spaces "bne" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Bne (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "bnez" - *> ws_opt - (lift2 - (fun r1 addr12 -> InstructionExpr (Bnez (r1, addr12))) - parse_register - (char ',' *> parse_address12)) - ; parse_string_with_spaces "blt" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Blt (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "bltz" - *> ws_opt - (lift2 - (fun r1 addr12 -> InstructionExpr (Bltz (r1, addr12))) - parse_register - (char ',' *> parse_address12)) - ; parse_string_with_spaces "bgt" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Bgt (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "bgtz" - *> ws_opt - (lift2 - (fun r1 addr12 -> InstructionExpr (Bgtz (r1, addr12))) - parse_register - (char ',' *> parse_address12)) - ; parse_string_with_spaces "bge" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Bge (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "bltu" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Bltu (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "bgeu" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Bgeu (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "jal" - *> lift2 - (fun r1 addr20 -> InstructionExpr (Jal (r1, addr20))) - parse_register - (char ',' *> parse_address20) - ; parse_string_with_spaces "jalr" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Jalr (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "jr" - *> lift (fun r1 -> InstructionExpr (Jr r1)) parse_register - ; parse_string_with_spaces "j" - *> lift (fun addr20 -> InstructionExpr (J addr20)) parse_address20 - ; parse_string_with_spaces "lui" - *> lift2 - (fun r1 addr20 -> InstructionExpr (Lui (r1, addr20))) - parse_register - (char ',' *> parse_address20) - ; parse_string_with_spaces "li" - *> lift2 - (fun r1 addr32 -> InstructionExpr (Li (r1, addr32))) - parse_register - (char ',' *> parse_address32) - ; parse_string_with_spaces "auipc" - *> lift2 - (fun r1 addr20 -> InstructionExpr (Auipc (r1, addr20))) - parse_register - (char ',' *> parse_address20) - ; parse_string_with_spaces "ecall" *> return (InstructionExpr Ecall) - ; parse_string_with_spaces "call" - *> ws_opt (lift (fun str -> InstructionExpr (Call str)) parse_string) - ; parse_string_with_spaces "mul" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Mul (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "mulh" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Mulh (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "mulhsu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Mulhsu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "mulhu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Mulhu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "div" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Div (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "divu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Divu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "rem" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Rem (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "remu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Remu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "lwu" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Lwu (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "ld" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Ld (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "la" - *> ws_opt - (lift2 - (fun r1 addr32 -> InstructionExpr (La (r1, addr32))) - parse_register - (char ',' *> parse_address32)) - ; parse_string_with_spaces "lla" - *> ws_opt - (lift2 - (fun r1 addr32 -> InstructionExpr (Lla (r1, addr32))) - parse_register - (char ',' *> parse_address32)) - ; parse_string_with_spaces "sd" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Sd (r1, r2, addr12))) - parse_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "addiw" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Addiw (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "slliw" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Slliw (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "srliw" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Srliw (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "sraiw" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Sraiw (r1, r2, addr12))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_address12) - ; parse_string_with_spaces "addw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Addw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "subw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Subw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sllw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sllw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "srlw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Srlw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sraw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sraw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "mulw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Mulw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "divw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Divw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "divuw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Divuw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "remw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Remw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "remwu" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Remwu (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "mv" - *> lift2 - (fun r1 r2 -> InstructionExpr (Mv (r1, r2))) - parse_register - (char ',' *> parse_register) - ; parse_string_with_spaces "ret" *> return (InstructionExpr Ret) - ; parse_string_with_spaces "fmadd.s" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FmaddS (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmsub.s" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FmsubS (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fnmsub.s" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FnmsubS (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fnmadd.s" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FnmaddS (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fadd.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FaddS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsub.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsubS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmul.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FmulS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fdiv.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FdivS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsqrt.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FsqrtS (r1, r2))) - parse_float_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnj.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnjn.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjnS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnjx.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjxS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmin.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FminS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmax.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FmaxS (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.w.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtWS (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.wu.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtWuS (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmv.x.w" - *> lift2 - (fun r1 r2 -> InstructionExpr (FmvXW (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "feq.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FeqS (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "flt.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FltS (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fle.s" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FleS (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fclass.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FclassS (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.s.w" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtSW (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fcvt.s.wu" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtSWu (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fmv.w.x" - *> lift2 - (fun r1 r2 -> InstructionExpr (FmvWX (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fmadd.d" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FmaddD (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmsub.d" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FmsubD (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fnmadd.d" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FnmaddD (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fnmsub.d" - *> lift4 - (fun r1 r2 r3 r4 -> InstructionExpr (FnmsubD (r1, r2, r3, r4))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fadd.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FaddD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsub.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsubD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmul.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FmulD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fdiv.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FdivD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsqrt.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FsqrtD (r1, r2))) - parse_float_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnj.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnjn.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjnD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fsgnjx.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FsgnjxD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmin.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FminD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fmax.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FmaxD (r1, r2, r3))) - parse_float_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.s.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtSD (r1, r2))) - parse_float_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.d.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtDS (r1, r2))) - parse_float_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "feq.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FeqD (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "flt.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FltD (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fle.d" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (FleD (r1, r2, r3))) - parse_register - (char ',' *> parse_float_register) - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.w.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtWD (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.wu.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtWuD (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fclass.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FclassD (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.d.wu" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtDWu (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fcvt.d.w" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtDW (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "flw" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Flw (r1, r2, addr12))) - parse_float_register - (char ',' *> parse_address12) - (char '(' *> parse_float_register <* char ')') - ; parse_string_with_spaces "fsw" - *> lift3 - (fun r1 r2 addr12 -> InstructionExpr (Fsw (r1, addr12, r2))) - parse_float_register - (char ',' *> parse_address12) - (char '(' *> parse_float_register <* char ')') - ; parse_string_with_spaces "fld" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Fld (r1, r2, addr12))) - parse_float_register - (char ',' *> parse_address12) - (char '(' *> parse_float_register <* char ')') - ; parse_string_with_spaces "fsd" - *> lift3 - (fun r1 addr12 r2 -> InstructionExpr (Fsd (r1, r2, addr12))) - parse_float_register - (char ',' *> parse_address12) - (char '(' *> parse_float_register <* char ')') - ; parse_string_with_spaces "fcvt.l.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtLS (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.lu.s" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtLuS (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.s.l" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtSL (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fcvt.s.lu" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtSLu (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fcvt.l.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtLD (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.lu.d" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtLuD (r1, r2))) - parse_register - (char ',' *> parse_float_register) - ; parse_string_with_spaces "fcvt.d.l" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtDL (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "fcvt.d.lu" - *> lift2 - (fun r1 r2 -> InstructionExpr (FcvtDLu (r1, r2))) - parse_float_register - (char ',' *> parse_register) - ; parse_string_with_spaces "add.uw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Adduw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh1add" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh1add (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh1add.uw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh1adduw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh2add" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh2add (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh2add.uw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh2adduw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh3add" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh3add (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "sh3add.uw" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Sh3adduw (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "andn" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Andn (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "orn" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Orn (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "xnor" - *> lift3 - (fun r1 r2 r3 -> InstructionExpr (Xnor (r1, r2, r3))) - parse_register - (char ',' *> parse_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vle32.v" - *> lift3 - (fun vd addr12 rs1 -> InstructionExpr (Vle32v (vd, rs1, addr12))) - parse_vector_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "vse32.v" - *> lift3 - (fun vs addr12 rs1 -> InstructionExpr (Vse32v (vs, rs1, addr12))) - parse_vector_register - (char ',' *> parse_address12) - (char '(' *> parse_register <* char ')') - ; parse_string_with_spaces "vadd.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vaddvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vadd.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vaddvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vsub.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vsubvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vsub.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vsubvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vmul.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vmulvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vmul.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vmulvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vdiv.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vdivvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vdiv.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vdivvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vand.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vandvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vand.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vandvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vor.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vorvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vor.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vorvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vxor.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vxorvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vxor.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vxorvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vmax.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vmaxvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vmax.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vmaxvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vmin.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vminvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vmin.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vminvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vmseq.vv" - *> lift3 - (fun vd vs1 vs2 -> InstructionExpr (Vmseqvv (vd, vs1, vs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ; parse_string_with_spaces "vmseq.vx" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vmseqvx (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_register) - ; parse_string_with_spaces "vsetvli" - *> lift3 - (fun r1 r2 _ -> InstructionExpr (Vsetvli (r1, r2))) - parse_register - (char ',' *> parse_register) - (string ", e32" *> return ()) - ; parse_string_with_spaces "vredsum.vs" - *> lift3 - (fun vd vs1 rs2 -> InstructionExpr (Vredsumvs (vd, vs1, rs2))) - parse_vector_register - (char ',' *> parse_vector_register) - (char ',' *> parse_vector_register) - ]) -;; - -let parse_expr = ws_opt (choice [ parse_directive; parse_instruction; parse_label_expr ]) - -let parse_ast = - ws_opt (many parse_expr) - <* (end_of_input - <|> (Angstrom.pos - >>= fun pos -> - Angstrom.peek_char - >>= function - | None -> return () - | Some c -> - fail (Printf.sprintf "Unexpected character: '%c' at position %d" c pos))) -;; diff --git a/RISCV_ASM/lib/parser.mli b/RISCV_ASM/lib/parser.mli deleted file mode 100644 index 7eaef0274..000000000 --- a/RISCV_ASM/lib/parser.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val parse_ast : Ast.expr list Angstrom.t diff --git a/RISCV_ASM/lib/prettyprinter.ml b/RISCV_ASM/lib/prettyprinter.ml deleted file mode 100644 index 7041077d4..000000000 --- a/RISCV_ASM/lib/prettyprinter.ml +++ /dev/null @@ -1,575 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -let pp_register ppf = function - | X0 -> Format.fprintf ppf "x0" - | X1 -> Format.fprintf ppf "x1" - | X2 -> Format.fprintf ppf "x2" - | X3 -> Format.fprintf ppf "x3" - | X4 -> Format.fprintf ppf "x4" - | X5 -> Format.fprintf ppf "x5" - | X6 -> Format.fprintf ppf "x6" - | X7 -> Format.fprintf ppf "x7" - | X8 -> Format.fprintf ppf "x8" - | X9 -> Format.fprintf ppf "x9" - | X10 -> Format.fprintf ppf "x10" - | X11 -> Format.fprintf ppf "x11" - | X12 -> Format.fprintf ppf "x12" - | X13 -> Format.fprintf ppf "x13" - | X14 -> Format.fprintf ppf "x14" - | X15 -> Format.fprintf ppf "x15" - | X16 -> Format.fprintf ppf "x16" - | X17 -> Format.fprintf ppf "x17" - | X18 -> Format.fprintf ppf "x18" - | X19 -> Format.fprintf ppf "x19" - | X20 -> Format.fprintf ppf "x20" - | X21 -> Format.fprintf ppf "x21" - | X22 -> Format.fprintf ppf "x22" - | X23 -> Format.fprintf ppf "x23" - | X24 -> Format.fprintf ppf "x24" - | X25 -> Format.fprintf ppf "x25" - | X26 -> Format.fprintf ppf "x26" - | X27 -> Format.fprintf ppf "x27" - | X28 -> Format.fprintf ppf "x28" - | X29 -> Format.fprintf ppf "x29" - | X30 -> Format.fprintf ppf "x30" - | X31 -> Format.fprintf ppf "x31" - | Zero -> Format.fprintf ppf "zero" - | Ra -> Format.fprintf ppf "ra" - | Sp -> Format.fprintf ppf "sp" - | Gp -> Format.fprintf ppf "gp" - | Tp -> Format.fprintf ppf "tp" - | T0 -> Format.fprintf ppf "t0" - | T1 -> Format.fprintf ppf "t1" - | T2 -> Format.fprintf ppf "t2" - | S0 -> Format.fprintf ppf "s0" - | Fp -> Format.fprintf ppf "fp" - | S1 -> Format.fprintf ppf "s1" - | A0 -> Format.fprintf ppf "a0" - | A1 -> Format.fprintf ppf "a1" - | A2 -> Format.fprintf ppf "a2" - | A3 -> Format.fprintf ppf "a3" - | A4 -> Format.fprintf ppf "a4" - | A5 -> Format.fprintf ppf "a5" - | A6 -> Format.fprintf ppf "a6" - | A7 -> Format.fprintf ppf "a7" - | S2 -> Format.fprintf ppf "s2" - | S3 -> Format.fprintf ppf "s3" - | S4 -> Format.fprintf ppf "s4" - | S5 -> Format.fprintf ppf "s5" - | S6 -> Format.fprintf ppf "s6" - | S7 -> Format.fprintf ppf "s7" - | S8 -> Format.fprintf ppf "s8" - | S9 -> Format.fprintf ppf "s9" - | S10 -> Format.fprintf ppf "s10" - | S11 -> Format.fprintf ppf "s11" - | T3 -> Format.fprintf ppf "t3" - | T4 -> Format.fprintf ppf "t4" - | T5 -> Format.fprintf ppf "t5" - | T6 -> Format.fprintf ppf "t6" -;; - -let pp_vector_register ppf = function - | V0 -> Format.fprintf ppf "v0" - | V1 -> Format.fprintf ppf "v1" - | V2 -> Format.fprintf ppf "v2" - | V3 -> Format.fprintf ppf "v3" - | V4 -> Format.fprintf ppf "v4" - | V5 -> Format.fprintf ppf "v5" - | V6 -> Format.fprintf ppf "v6" - | V7 -> Format.fprintf ppf "v7" - | V8 -> Format.fprintf ppf "v8" - | V9 -> Format.fprintf ppf "v9" - | V10 -> Format.fprintf ppf "v10" - | V11 -> Format.fprintf ppf "v11" - | V12 -> Format.fprintf ppf "v12" - | V13 -> Format.fprintf ppf "v13" - | V14 -> Format.fprintf ppf "v14" - | V15 -> Format.fprintf ppf "v15" - | V16 -> Format.fprintf ppf "v16" - | V17 -> Format.fprintf ppf "v17" - | V18 -> Format.fprintf ppf "v18" - | V19 -> Format.fprintf ppf "v19" - | V20 -> Format.fprintf ppf "v20" - | V21 -> Format.fprintf ppf "v21" - | V22 -> Format.fprintf ppf "v22" - | V23 -> Format.fprintf ppf "v23" - | V24 -> Format.fprintf ppf "v24" - | V25 -> Format.fprintf ppf "v25" - | V26 -> Format.fprintf ppf "v26" - | V27 -> Format.fprintf ppf "v27" - | V28 -> Format.fprintf ppf "v28" - | V29 -> Format.fprintf ppf "v29" - | V30 -> Format.fprintf ppf "v30" - | V31 -> Format.fprintf ppf "v31" -;; - -let pp_float_register ppf = function - | F0 -> Format.fprintf ppf "f0" - | F1 -> Format.fprintf ppf "f1" - | F2 -> Format.fprintf ppf "f2" - | F3 -> Format.fprintf ppf "f3" - | F4 -> Format.fprintf ppf "f4" - | F5 -> Format.fprintf ppf "f5" - | F6 -> Format.fprintf ppf "f6" - | F7 -> Format.fprintf ppf "f7" - | F8 -> Format.fprintf ppf "f8" - | F9 -> Format.fprintf ppf "f9" - | F10 -> Format.fprintf ppf "f10" - | F11 -> Format.fprintf ppf "f11" - | F12 -> Format.fprintf ppf "f12" - | F13 -> Format.fprintf ppf "f13" - | F14 -> Format.fprintf ppf "f14" - | F15 -> Format.fprintf ppf "f15" - | F16 -> Format.fprintf ppf "f16" - | F17 -> Format.fprintf ppf "f17" - | F18 -> Format.fprintf ppf "f18" - | F19 -> Format.fprintf ppf "f19" - | F20 -> Format.fprintf ppf "f20" - | F21 -> Format.fprintf ppf "f21" - | F22 -> Format.fprintf ppf "f22" - | F23 -> Format.fprintf ppf "f23" - | F24 -> Format.fprintf ppf "f24" - | F25 -> Format.fprintf ppf "f25" - | F26 -> Format.fprintf ppf "f26" - | F27 -> Format.fprintf ppf "f27" - | F28 -> Format.fprintf ppf "f28" - | F29 -> Format.fprintf ppf "f29" - | F30 -> Format.fprintf ppf "f30" - | F31 -> Format.fprintf ppf "f31" - | Ft0 -> Format.fprintf ppf "ft0" - | Ft1 -> Format.fprintf ppf "ft1" - | Ft2 -> Format.fprintf ppf "ft2" - | Ft3 -> Format.fprintf ppf "ft3" - | Ft4 -> Format.fprintf ppf "ft4" - | Ft5 -> Format.fprintf ppf "ft5" - | Ft6 -> Format.fprintf ppf "ft6" - | Ft7 -> Format.fprintf ppf "ft7" - | Fs0 -> Format.fprintf ppf "fs0" - | Fs1 -> Format.fprintf ppf "fs1" - | Fa0 -> Format.fprintf ppf "fa0" - | Fa1 -> Format.fprintf ppf "fa1" - | Fa2 -> Format.fprintf ppf "fa2" - | Fa3 -> Format.fprintf ppf "fa3" - | Fa4 -> Format.fprintf ppf "fa4" - | Fa5 -> Format.fprintf ppf "fa5" - | Fa6 -> Format.fprintf ppf "fa6" - | Fa7 -> Format.fprintf ppf "fa7" - | Fs2 -> Format.fprintf ppf "fs2" - | Fs3 -> Format.fprintf ppf "fs3" - | Fs4 -> Format.fprintf ppf "fs4" - | Fs5 -> Format.fprintf ppf "fs5" - | Fs6 -> Format.fprintf ppf "fs6" - | Fs7 -> Format.fprintf ppf "fs7" - | Fs8 -> Format.fprintf ppf "fs8" - | Fs9 -> Format.fprintf ppf "fs9" - | Fs10 -> Format.fprintf ppf "fs10" - | Fs11 -> Format.fprintf ppf "fs11" - | Ft8 -> Format.fprintf ppf "ft8" - | Ft9 -> Format.fprintf ppf "ft9" - | Ft10 -> Format.fprintf ppf "ft10" - | Ft11 -> Format.fprintf ppf "ft11" -;; - -type address = - | Address12 of address12 - | Address20 of address20 - | Address32 of address32 - -let pp_instruction_3reg_helper ppf mnemonic r1 r2 r3 = - Format.fprintf ppf "%s %a, %a, %a" mnemonic pp_register r1 pp_register r2 pp_register r3 -;; - -let pp_instruction_3vreg_helper ppf mnemonic v1 v2 v3 = - Format.fprintf - ppf - "%s %a, %a, %a" - mnemonic - pp_vector_register - v1 - pp_vector_register - v2 - pp_vector_register - v3 -;; - -let pp_instruction_3f_reg_helper ppf mnemonic r1 r2 r3 = - Format.fprintf - ppf - "%s %a, %a, %a" - mnemonic - pp_float_register - r1 - pp_float_register - r2 - pp_float_register - r3 -;; - -let pp_instruction_2f_1_reg_helper ppf mnemonic r1 r2 r3 = - Format.fprintf - ppf - "%s %a, %a, %a" - mnemonic - pp_register - r1 - pp_float_register - r2 - pp_float_register - r3 -;; - -let pp_instruction_4f_reg_helper ppf mnemonic r1 r2 r3 r4 = - Format.fprintf - ppf - "%s %a, %a, %a, %a" - mnemonic - pp_float_register - r1 - pp_float_register - r2 - pp_float_register - r3 - pp_float_register - r4 -;; - -let pp_address ppf = function - | Address12 (LabelAddress12 str) -> Format.fprintf ppf "%s" str - | Address20 (LabelAddress20 str) -> Format.fprintf ppf "%s" str - | Address32 (LabelAddress32 str) -> Format.fprintf ppf "%s" str - | Address12 (ImmediateAddress12 imm) -> Format.fprintf ppf "%d" imm - | Address20 (ImmediateAddress20 imm) -> Format.fprintf ppf "%d" imm - | Address32 (ImmediateAddress32 imm) -> Format.fprintf ppf "%d" imm -;; - -let pp_instruction_2reg_1imm_helper ppf mnemonic r1 r2 addr = - Format.fprintf ppf "%s %a,%a,%a" mnemonic pp_register r1 pp_register r2 pp_address addr -;; - -let pp_instruction_2vreg_1reg_helper ppf mnemonic v1 v2 r3 = - Format.fprintf - ppf - "%s %a, %a, %a" - mnemonic - pp_vector_register - v1 - pp_vector_register - v2 - pp_register - r3 -;; - -let pp_instruction_2reg_1offset_helper ppf mnemonic r1 r2 addr = - Format.fprintf ppf "%s %a,%a(%a)" mnemonic pp_register r1 pp_address addr pp_register r2 -;; - -let pp_instruction_1vreg_1reg_1offset_helper ppf mnemonic v1 r2 addr = - Format.fprintf - ppf - "%s %a,%a(%a)" - mnemonic - pp_vector_register - v1 - pp_address - addr - pp_register - r2 -;; - -let pp_instruction_2freg_1offset_helper ppf mnemonic r1 r2 addr = - Format.fprintf - ppf - "%s %a,%a(%a)" - mnemonic - pp_float_register - r1 - pp_address - addr - pp_float_register - r2 -;; - -let pp_instruction ppf = function - | Add (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "add" rd rs1 rs2 - | Sub (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sub" rd rs1 rs2 - | Xor (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "xor" rd rs1 rs2 - | Or (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "or" rd rs1 rs2 - | And (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "and" rd rs1 rs2 - | Sll (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sll" rd rs1 rs2 - | Srl (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "srl" rd rs1 rs2 - | Sra (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sra" rd rs1 rs2 - | Slt (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "slt" rd rs1 rs2 - | Sltu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sltu" rd rs1 rs2 - | Mul (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "mul" rd rs1 rs2 - | Mulh (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "mulh" rd rs1 rs2 - | Mulhsu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "mulhsu" rd rs1 rs2 - | Mulhu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "mulhu" rd rs1 rs2 - | Div (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "div" rd rs1 rs2 - | Divu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "divu" rd rs1 rs2 - | Rem (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "rem" rd rs1 rs2 - | Remu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "remu" rd rs1 rs2 - | Addw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "addw" rd rs1 rs2 - | Subw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "subw" rd rs1 rs2 - | Sllw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sllw" rd rs1 rs2 - | Srlw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "srlw" rd rs1 rs2 - | Sraw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sraw" rd rs1 rs2 - | Mulw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "mulw" rd rs1 rs2 - | Divw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "divw" rd rs1 rs2 - | Divuw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "divuw" rd rs1 rs2 - | Remw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "remw" rd rs1 rs2 - | Remwu (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "remwu" rd rs1 rs2 - | Lwu (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lwu" rd rs1 (Address12 imm) - | Addi (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "addi" rd rs1 (Address12 imm) - | Xori (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "xori" rd rs1 (Address12 imm) - | Ori (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "ori" rd rs1 (Address12 imm) - | Andi (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "andi" rd rs1 (Address12 imm) - | Slli (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "slli" rd rs1 (Address12 imm) - | Srli (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "srli" rd rs1 (Address12 imm) - | Srai (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "srai" rd rs1 (Address12 imm) - | Slti (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "slti" rd rs1 (Address12 imm) - | Sltiu (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "sltiu" rd rs1 (Address12 imm) - | Lb (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lb" rd rs1 (Address12 imm) - | Lh (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lh" rd rs1 (Address12 imm) - | Lw (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lw" rd rs1 (Address12 imm) - | Lbu (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lbu" rd rs1 (Address12 imm) - | Lhu (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "lhu" rd rs1 (Address12 imm) - | Sb (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "sb" rd rs1 (Address12 imm) - | Sh (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "sh" rd rs1 (Address12 imm) - | Sw (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "sw" rd rs1 (Address12 imm) - | Beq (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "beq" rd rs1 (Address12 imm) - | Beqz (rs1, imm) -> - Format.fprintf ppf "beqz %a,%a" pp_register rs1 pp_address (Address12 imm) - | Bne (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "bne" rd rs1 (Address12 imm) - | Bnez (rs1, imm) -> - Format.fprintf ppf "bnez %a,%a" pp_register rs1 pp_address (Address12 imm) - | Blt (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "blt" rd rs1 (Address12 imm) - | Bltz (rs1, imm) -> - Format.fprintf ppf "bltz %a,%a" pp_register rs1 pp_address (Address12 imm) - | Bgt (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "bgt" rd rs1 (Address12 imm) - | Bgtz (rs1, imm) -> - Format.fprintf ppf "bgtz %a,%a" pp_register rs1 pp_address (Address12 imm) - | Bge (rd, rs1, imm) -> pp_instruction_2reg_1imm_helper ppf "bge" rd rs1 (Address12 imm) - | Bltu (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "bltu" rd rs1 (Address12 imm) - | Bgeu (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "bgeu" rd rs1 (Address12 imm) - | Jalr (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "jalr" rd rs1 (Address12 imm) - | Ld (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "ld" rd rs1 (Address12 imm) - | Sd (rd, rs1, imm) -> - pp_instruction_2reg_1offset_helper ppf "sd" rd rs1 (Address12 imm) - | Addiw (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "addiw" rd rs1 (Address12 imm) - | Slliw (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "slliw" rd rs1 (Address12 imm) - | Srliw (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "srliw" rd rs1 (Address12 imm) - | Sraiw (rd, rs1, imm) -> - pp_instruction_2reg_1imm_helper ppf "sraiw" rd rs1 (Address12 imm) - | Jal (rd, imm) -> - Format.fprintf ppf "jal %a, %a" pp_register rd pp_address (Address20 imm) - | Jr rs1 -> Format.fprintf ppf "jr %a" pp_register rs1 - | J imm -> Format.fprintf ppf "j %a" pp_address (Address20 imm) - | Lui (rd, imm) -> - Format.fprintf ppf "lui %a,%a" pp_register rd pp_address (Address20 imm) - | Auipc (rd, imm) -> - Format.fprintf ppf "auipc %a,%a" pp_register rd pp_address (Address20 imm) - | Ecall -> Format.fprintf ppf "ecall" - | Call str -> Format.fprintf ppf "call %s" str - | La (rd, imm) -> - Format.fprintf ppf "la %a,%a" pp_register rd pp_address (Address32 imm) - | Lla (rd, imm) -> - Format.fprintf ppf "lla %a,%a" pp_register rd pp_address (Address32 imm) - | Mv (rd, rs1) -> Format.fprintf ppf "mv %a,%a" pp_register rd pp_register rs1 - | Li (rd, imm) -> - Format.fprintf ppf "li %a,%a" pp_register rd pp_address (Address32 imm) - | Ret -> Format.fprintf ppf "ret" - | FmaddS (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fmadd.s" rd rs1 rs2 rs3 - | FmsubS (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fmsub.s" rd rs1 rs2 rs3 - | FnmsubS (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fnmsub.s" rd rs1 rs2 rs3 - | FnmaddS (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fnmadd.s" rd rs1 rs2 rs3 - | FaddS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fadd.s" rd rs1 rs2 - | FsubS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsub.s" rd rs1 rs2 - | FmulS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmul.s" rd rs1 rs2 - | FdivS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fdiv.s" rd rs1 rs2 - | FsqrtS (rd, rs1) -> - Format.fprintf ppf "fsqrt.s %a,%a" pp_float_register rd pp_float_register rs1 - | FsgnjS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnj.s" rd rs1 rs2 - | FsgnjnS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnjn.s" rd rs1 rs2 - | FsgnjxS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnjx.s" rd rs1 rs2 - | FminS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmin.s" rd rs1 rs2 - | FmaxS (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmax.s" rd rs1 rs2 - | FcvtWS (rd, rs1) -> - Format.fprintf ppf "fcvt.w.s %a,%a" pp_register rd pp_float_register rs1 - | FcvtWuS (rd, rs1) -> - Format.fprintf ppf "fcvt.wu.s %a,%a" pp_register rd pp_float_register rs1 - | FmvXW (rd, rs1) -> - Format.fprintf ppf "fmv.x.w %a,%a" pp_register rd pp_float_register rs1 - | FeqS (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "feq.s" rd rs1 rs2 - | FltS (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "flt.s" rd rs1 rs2 - | FleS (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "fle.s" rd rs1 rs2 - | FclassS (rd, rs1) -> - Format.fprintf ppf "fclass.s %a,%a" pp_register rd pp_float_register rs1 - | FcvtSW (rd, rs1) -> - Format.fprintf ppf "fcvt.s.w %a,%a" pp_float_register rd pp_register rs1 - | FcvtSWu (rd, rs1) -> - Format.fprintf ppf "fcvt.s.wu %a,%a" pp_float_register rd pp_register rs1 - | FmvWX (rd, rs1) -> - Format.fprintf ppf "fmv.w.x %a,%a" pp_float_register rd pp_register rs1 - | FmaddD (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fmadd.d" rd rs1 rs2 rs3 - | FmsubD (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fmsub.d" rd rs1 rs2 rs3 - | FnmsubD (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fnmsub.d" rd rs1 rs2 rs3 - | FnmaddD (rd, rs1, rs2, rs3) -> - pp_instruction_4f_reg_helper ppf "fnmadd.d" rd rs1 rs2 rs3 - | FaddD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fadd.d" rd rs1 rs2 - | FsubD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsub.d" rd rs1 rs2 - | FmulD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmul.d" rd rs1 rs2 - | FdivD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fdiv.d" rd rs1 rs2 - | FsqrtD (rd, rs1) -> - Format.fprintf ppf "fsqrt.d %a,%a" pp_float_register rd pp_float_register rs1 - | FsgnjD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnj.d" rd rs1 rs2 - | FsgnjnD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnjn.d" rd rs1 rs2 - | FsgnjxD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fsgnjx.d" rd rs1 rs2 - | FminD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmin.d" rd rs1 rs2 - | FmaxD (rd, rs1, rs2) -> pp_instruction_3f_reg_helper ppf "fmax.d" rd rs1 rs2 - | FcvtSD (rd, rs1) -> - Format.fprintf ppf "fcvt.s.d %a,%a" pp_float_register rd pp_float_register rs1 - | FcvtDS (rd, rs1) -> - Format.fprintf ppf "fcvt.d.s %a,%a" pp_float_register rd pp_float_register rs1 - | FeqD (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "feq.d" rd rs1 rs2 - | FltD (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "flt.d" rd rs1 rs2 - | FleD (rd, rs1, rs2) -> pp_instruction_2f_1_reg_helper ppf "fle.d" rd rs1 rs2 - | FcvtWD (rd, rs1) -> - Format.fprintf ppf "fcvt.w.d %a,%a" pp_register rd pp_float_register rs1 - | FcvtWuD (rd, rs1) -> - Format.fprintf ppf "fcvt.wu.d %a,%a" pp_register rd pp_float_register rs1 - | FclassD (rd, rs1) -> - Format.fprintf ppf "fclass.d %a,%a" pp_register rd pp_float_register rs1 - | FcvtDW (rd, rs1) -> - Format.fprintf ppf "fcvt.d.w %a,%a" pp_float_register rd pp_register rs1 - | FcvtDWu (rd, rs1) -> - Format.fprintf ppf "fcvt.d.wu %a,%a" pp_float_register rd pp_register rs1 - | Flw (rd, rs1, imm) -> - pp_instruction_2freg_1offset_helper ppf "flw" rd rs1 (Address12 imm) - | Fsw (rd, rs1, imm) -> - pp_instruction_2freg_1offset_helper ppf "fsw" rd rs1 (Address12 imm) - | Fld (rd, rs1, imm) -> - pp_instruction_2freg_1offset_helper ppf "fld" rd rs1 (Address12 imm) - | Fsd (rd, rs1, imm) -> - pp_instruction_2freg_1offset_helper ppf "fsd" rd rs1 (Address12 imm) - | FcvtLS (rd, rs1) -> - Format.fprintf ppf "fcvt.l.s %a,%a" pp_register rd pp_float_register rs1 - | FcvtLuS (rd, rs1) -> - Format.fprintf ppf "fcvt.lu.s %a,%a" pp_register rd pp_float_register rs1 - | FcvtSL (rd, rs1) -> - Format.fprintf ppf "fcvt.s.l %a,%a" pp_float_register rd pp_register rs1 - | FcvtSLu (rd, rs1) -> - Format.fprintf ppf "fcvt.s.lu %a,%a" pp_float_register rd pp_register rs1 - | FcvtLD (rd, rs1) -> - Format.fprintf ppf "fcvt.l.d %a,%a" pp_register rd pp_float_register rs1 - | FcvtLuD (rd, rs1) -> - Format.fprintf ppf "fcvt.lu.d %a,%a" pp_register rd pp_float_register rs1 - | FcvtDL (rd, rs1) -> - Format.fprintf ppf "fcvt.d.l %a,%a" pp_float_register rd pp_register rs1 - | FcvtDLu (rd, rs1) -> - Format.fprintf ppf "fcvt.d.lu %a,%a" pp_float_register rd pp_register rs1 - | Adduw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "add.uw" rd rs1 rs2 - | Sh1add (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh1add" rd rs1 rs2 - | Sh1adduw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh1add.uw" rd rs1 rs2 - | Sh2add (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh2add" rd rs1 rs2 - | Sh2adduw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh2add.uw" rd rs1 rs2 - | Sh3add (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh3add" rd rs1 rs2 - | Sh3adduw (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "sh3add.uw" rd rs1 rs2 - | Andn (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "andn" rd rs1 rs2 - | Orn (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "orn" rd rs1 rs2 - | Xnor (rd, rs1, rs2) -> pp_instruction_3reg_helper ppf "xnor" rd rs1 rs2 - | Vle32v (vd, rs1, imm) -> - pp_instruction_1vreg_1reg_1offset_helper ppf "vle32.v" vd rs1 (Address12 imm) - | Vse32v (vs, rs1, imm) -> - pp_instruction_1vreg_1reg_1offset_helper ppf "vse32.v" vs rs1 (Address12 imm) - | Vaddvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vadd.vv" vd vs1 vs2 - | Vaddvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vadd.vx" vd vs1 rs2 - | Vsubvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vsub.vv" vd vs1 vs2 - | Vsubvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vsub.vx" vd vs1 rs2 - | Vmulvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vmul.vv" vd vs1 vs2 - | Vmulvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vmul.vx" vd vs1 rs2 - | Vdivvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vdiv.vv" vd vs1 vs2 - | Vdivvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vdiv.vx" vd vs1 rs2 - | Vandvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vand.vv" vd vs1 vs2 - | Vandvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vand.vx" vd vs1 rs2 - | Vorvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vor.vv" vd vs1 vs2 - | Vorvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vor.vx" vd vs1 rs2 - | Vxorvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vxor.vv" vd vs1 vs2 - | Vxorvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vxor.vx" vd vs1 rs2 - | Vminvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vmin.vv" vd vs1 vs2 - | Vminvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vmin.vx" vd vs1 rs2 - | Vmaxvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vmax.vv" vd vs1 vs2 - | Vmaxvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vmax.vx" vd vs1 rs2 - | Vmseqvv (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vmseq.vv" vd vs1 vs2 - | Vmseqvx (vd, vs1, rs2) -> pp_instruction_2vreg_1reg_helper ppf "vmseq.vx" vd vs1 rs2 - | Vsetvli (r1, r2) -> - Format.fprintf ppf "vsetvli %a,%a, e32" pp_register r1 pp_register r2 - | Vredsumvs (vd, vs1, vs2) -> pp_instruction_3vreg_helper ppf "vredsum.vs" vd vs1 vs2 -;; - -let pp_type_dir ppf = function - | Type str -> Format.fprintf ppf "%s" str -;; - -let pp_directive ppf = function - | Text -> Format.fprintf ppf ".text" - | Globl imm -> Format.fprintf ppf ".globl %a" pp_address (Address12 imm) - | TypeDir (str, str_type) -> Format.fprintf ppf ".type %s,@%a" str pp_type_dir str_type - | Section (str1, None) -> Format.fprintf ppf ".section %s" str1 - | Section (str1, Some (str2, None)) -> Format.fprintf ppf ".section %s,%S" str1 str2 - | Section (str1, Some (str2, Some (typ, None))) -> - Format.fprintf ppf ".section %s,%S,@%a" str1 str2 pp_type_dir typ - | Section (str1, Some (str2, Some (typ, Some i))) -> - Format.fprintf ppf ".section %s,%S,@%a,%d" str1 str2 pp_type_dir typ i - | StringDir str -> Format.fprintf ppf ".string %S" (String.escaped str) - | Word imm -> Format.fprintf ppf ".word %d" (Int32.to_int imm) - | Space imm -> Format.fprintf ppf ".space %d" imm -;; - -let pp_label ppf label = Format.fprintf ppf "%s:" label - -let pp_expr ppf = function - | InstructionExpr instruction -> pp_instruction ppf instruction - | LabelExpr label -> pp_label ppf label - | DirectiveExpr directive -> pp_directive ppf directive -;; - -let pp_ast ppf (ast : ast) = - Format.pp_print_list ~pp_sep:(fun ppf () -> Format.fprintf ppf "\n") pp_expr ppf ast -;; - -let print_ast ast = pp_ast Format.std_formatter ast diff --git a/RISCV_ASM/lib/prettyprinter.mli b/RISCV_ASM/lib/prettyprinter.mli deleted file mode 100644 index 1d7843cb3..000000000 --- a/RISCV_ASM/lib/prettyprinter.mli +++ /dev/null @@ -1,8 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Ast - -val pp_ast : Format.formatter -> expr list -> unit -val print_ast : expr list -> unit diff --git a/RISCV_ASM/quickcheck/dune b/RISCV_ASM/quickcheck/dune deleted file mode 100644 index c16979ae3..000000000 --- a/RISCV_ASM/quickcheck/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name quickcheck) - (public_name RISCV_ASM.Quickcheck) - (libraries RISCV_ASM.Lib qcheck-core qcheck-core.runner) - (instrumentation - (backend bisect_ppx))) diff --git a/RISCV_ASM/quickcheck/quickcheck.ml b/RISCV_ASM/quickcheck/quickcheck.ml deleted file mode 100644 index e7bd72f55..000000000 --- a/RISCV_ASM/quickcheck/quickcheck.ml +++ /dev/null @@ -1,40 +0,0 @@ -(** Copyright 2024, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Riscv_asm_interpreter_lib.Ast -open Riscv_asm_interpreter_lib.Parser -open Riscv_asm_interpreter_lib.Prettyprinter -open QCheck.Shrink - -let shrink_ast ast = list ast - -let arbitrary_ast = - let open QCheck.Gen in - let ast_gen = list gen_expr in - QCheck.make - ast_gen - ~print: - (Format.asprintf - "%a" - (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "\n") pp_expr)) - ~shrink:shrink_ast -;; - -let run () = - QCheck_base_runner.run_tests - [ QCheck.( - Test.make arbitrary_ast (fun ast -> - Result.ok ast - = Angstrom.parse_string ~consume:All parse_ast (Format.asprintf "%a" pp_ast ast))) - ] -;; - -let () = - Arg.parse - [ "-seed", Arg.Int QCheck_base_runner.set_seed, " Set seed" ] - print_endline - "Testing derived generator."; - let _ : int = run () in - () -;; diff --git a/RISCV_ASM/quickcheck/quickcheck.mli b/RISCV_ASM/quickcheck/quickcheck.mli deleted file mode 100644 index dbc896711..000000000 --- a/RISCV_ASM/quickcheck/quickcheck.mli +++ /dev/null @@ -1,5 +0,0 @@ -(** Copyright 2024, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -val run : unit -> int diff --git a/RISCV_ASM/repl/REPL.ml b/RISCV_ASM/repl/REPL.ml deleted file mode 100644 index 0f474b163..000000000 --- a/RISCV_ASM/repl/REPL.ml +++ /dev/null @@ -1,47 +0,0 @@ -(** Copyright 2024-2025, Vyacheslav Kochergin, Roman Mukovenkov, Yuliana Ementyan *) - -(** SPDX-License-Identifier: LGPL-3.0-or-later *) - -open Riscv_asm_interpreter_lib.Ast -open Riscv_asm_interpreter_lib.Parser -open Riscv_asm_interpreter_lib.Interpreter -open Angstrom -open Printf -open Stdio - -type opts = - { mutable dump_parse_tree : bool - ; mutable file_path : string option - ; mutable eval : bool - } - -let () = - let opts = { dump_parse_tree = false; file_path = None; eval = false } in - let _ = - Arg.parse - [ "-dparsetree", Arg.Unit (fun () -> opts.dump_parse_tree <- true), "Dump AST\n" - ; ( "-filepath" - , Arg.String (fun file_path -> opts.file_path <- Some file_path) - , "Input code in file\n" ) - ; "-eval", Arg.Unit (fun () -> opts.eval <- true), "Run interpreter\n" - ] - (fun _ -> - Stdlib.Format.eprintf "Wrong arguments\n"; - Stdlib.exit 1) - "Read-Eval-Print-Loop for RISC-V 64 ASM\n" - in - let input = - match opts.file_path with - | None -> In_channel.(input_all stdin) |> String.trim - | Some path -> In_channel.read_all path |> String.trim - in - match parse_string ~consume:All parse_ast input with - | Ok ast -> - if opts.dump_parse_tree then print_endline (show_ast ast); - if opts.eval - then ( - match interpret ast with - | Ok (_, final_state) -> print_endline (show_state final_state) - | Error msg -> failwith (sprintf "Interpretation error: %s" msg)) - | Error msg -> failwith (sprintf "Failed to parse file: %s" msg) -;; diff --git a/RISCV_ASM/repl/dune b/RISCV_ASM/repl/dune deleted file mode 100644 index b42fd7ff3..000000000 --- a/RISCV_ASM/repl/dune +++ /dev/null @@ -1,6 +0,0 @@ -(executable - (name REPL) - (public_name REPL) - (libraries RISCV_ASM.Lib stdio) - (instrumentation - (backend bisect_ppx))) diff --git a/RISCV_ASM/tests/bitmanip_test.t b/RISCV_ASM/tests/bitmanip_test.t deleted file mode 100644 index fde12731c..000000000 --- a/RISCV_ASM/tests/bitmanip_test.t +++ /dev/null @@ -1,8 +0,0 @@ - $ riscv64-unknown-elf-as -march=rv64gc_zbb_zba -o ../examples/bitmanip/bitmanip.o ../examples/bitmanip/bitmanip.s - $ riscv64-unknown-elf-ld -o ../examples/bitmanip/bitmanip ../examples/bitmanip/bitmanip.o - $ qemu-riscv64 ../examples/bitmanip/bitmanip < 5351 - 5631 - $ ../repl/REPL.exe -eval -filepath="../examples/bitmanip/bitmanip.s" < 5351 - 5631 diff --git a/RISCV_ASM/tests/dune b/RISCV_ASM/tests/dune deleted file mode 100644 index 1f862d548..000000000 --- a/RISCV_ASM/tests/dune +++ /dev/null @@ -1,19 +0,0 @@ -(cram - (applies_to factorial_test) - (deps ../repl/REPL.exe ../examples/factorial/factorial.s)) - -(cram - (applies_to qc) - (deps ../quickcheck/quickcheck.exe)) - -(cram - (applies_to io_test) - (deps ../repl/REPL.exe ../examples/io/io.s)) - -(cram - (applies_to bitmanip_test) - (deps ../repl/REPL.exe ../examples/bitmanip/bitmanip.s)) - -(cram - (applies_to rvv_test) - (deps ../repl/REPL.exe ../examples/rvv/rvv.s)) diff --git a/RISCV_ASM/tests/factorial_test.t b/RISCV_ASM/tests/factorial_test.t deleted file mode 100644 index f21f8e549..000000000 --- a/RISCV_ASM/tests/factorial_test.t +++ /dev/null @@ -1,66 +0,0 @@ - $ ../repl/REPL.exe -dparsetree -filepath="../examples/factorial/factorial.s" - [(DirectiveExpr (Globl (LabelAddress12 "_start"))); - (DirectiveExpr (Section (".data", None))); (LabelExpr "buffer"); - (DirectiveExpr (Space 32)); (DirectiveExpr (Section (".text", None))); - (LabelExpr "_start"); (InstructionExpr (Li (A7, (ImmediateAddress32 63)))); - (InstructionExpr (Li (A0, (ImmediateAddress32 0)))); - (InstructionExpr (La (A1, (LabelAddress32 "buffer")))); - (InstructionExpr (Li (A2, (ImmediateAddress32 32)))); - (InstructionExpr Ecall); - (InstructionExpr (La (T0, (LabelAddress32 "buffer")))); - (InstructionExpr (Mv (A0, Zero))); - (InstructionExpr (Li (T2, (ImmediateAddress32 10)))); - (LabelExpr "convert_string_to_number"); - (InstructionExpr (Lb (T1, T0, (ImmediateAddress12 0)))); - (InstructionExpr (Beqz (T1, (LabelAddress12 "end_convert")))); - (InstructionExpr (Addi (T1, T1, (ImmediateAddress12 -48)))); - (InstructionExpr (Bltz (T1, (LabelAddress12 "end_convert")))); - (InstructionExpr (Bge (T1, T2, (LabelAddress12 "end_convert")))); - (InstructionExpr (Mul (A0, A0, T2))); (InstructionExpr (Add (A0, A0, T1))); - (InstructionExpr (Addi (T0, T0, (ImmediateAddress12 1)))); - (InstructionExpr (J (LabelAddress20 "convert_string_to_number"))); - (LabelExpr "end_convert"); - (InstructionExpr (Addi (T1, Zero, (ImmediateAddress12 1)))); - (LabelExpr "loop"); (InstructionExpr (Beqz (A0, (LabelAddress12 "exit")))); - (InstructionExpr (Mul (T1, T1, A0))); - (InstructionExpr (Addi (A0, A0, (ImmediateAddress12 -1)))); - (InstructionExpr (J (LabelAddress20 "loop"))); (LabelExpr "exit"); - (InstructionExpr (La (T0, (LabelAddress32 "buffer")))); - (InstructionExpr (Addi (T2, Zero, (ImmediateAddress12 10)))); - (InstructionExpr (Mv (A0, T1))); - (InstructionExpr (Addi (T3, Zero, (ImmediateAddress12 0)))); - (LabelExpr "convert_loop"); (InstructionExpr (Rem (T4, A0, T2))); - (InstructionExpr (Div (A0, A0, T2))); - (InstructionExpr (Addi (T4, T4, (ImmediateAddress12 48)))); - (InstructionExpr (Sb (T4, T0, (ImmediateAddress12 0)))); - (InstructionExpr (Addi (T0, T0, (ImmediateAddress12 1)))); - (InstructionExpr (Addi (T3, T3, (ImmediateAddress12 1)))); - (InstructionExpr (Bnez (A0, (LabelAddress12 "convert_loop")))); - (InstructionExpr (La (T0, (LabelAddress32 "buffer")))); - (InstructionExpr (Mv (T4, T0))); (InstructionExpr (Add (T5, T0, T3))); - (InstructionExpr (Addi (T5, T5, (ImmediateAddress12 -1)))); - (LabelExpr "reverse_loop"); - (InstructionExpr (Bge (T4, T5, (LabelAddress12 "end_reverse")))); - (InstructionExpr (Lb (T6, T4, (ImmediateAddress12 0)))); - (InstructionExpr (Lb (T1, T5, (ImmediateAddress12 0)))); - (InstructionExpr (Sb (T1, T4, (ImmediateAddress12 0)))); - (InstructionExpr (Sb (T6, T5, (ImmediateAddress12 0)))); - (InstructionExpr (Addi (T4, T4, (ImmediateAddress12 1)))); - (InstructionExpr (Addi (T5, T5, (ImmediateAddress12 -1)))); - (InstructionExpr (J (LabelAddress20 "reverse_loop"))); - (LabelExpr "end_reverse"); (InstructionExpr (Add (T0, T0, T3))); - (InstructionExpr (Li (A7, (ImmediateAddress32 64)))); - (InstructionExpr (Li (A0, (ImmediateAddress32 1)))); - (InstructionExpr (La (A1, (LabelAddress32 "buffer")))); - (InstructionExpr (Mv (A2, T3))); (InstructionExpr Ecall); - (InstructionExpr (Li (A7, (ImmediateAddress32 93)))); - (InstructionExpr (Li (A0, (ImmediateAddress32 0)))); - (InstructionExpr Ecall)] - $ riscv64-unknown-elf-as -o ../examples/factorial/factorial.o ../examples/factorial/factorial.s - $ riscv64-unknown-elf-ld -o ../examples/factorial/factorial ../examples/factorial/factorial.o - $ qemu-riscv64 ../examples/factorial/factorial < 8 - 40320 - $ ../repl/REPL.exe -eval -filepath="../examples/factorial/factorial.s" < 8 - 40320 diff --git a/RISCV_ASM/tests/io_test.t b/RISCV_ASM/tests/io_test.t deleted file mode 100644 index 804b86131..000000000 --- a/RISCV_ASM/tests/io_test.t +++ /dev/null @@ -1,8 +0,0 @@ - $ riscv64-unknown-elf-as -o ../examples/io/io.o ../examples/io/io.s - $ riscv64-unknown-elf-ld -o ../examples/io/io ../examples/io/io.o - $ qemu-riscv64 ../examples/io/io < abcd1234 - abcd1234 - $ ../repl/REPL.exe -eval -filepath="../examples/io/io.s" < abcd1234 - abcd1234 diff --git a/RISCV_ASM/tests/qc.t b/RISCV_ASM/tests/qc.t deleted file mode 100644 index 0eedcf5ab..000000000 --- a/RISCV_ASM/tests/qc.t +++ /dev/null @@ -1,4 +0,0 @@ - $ ../quickcheck/quickcheck.exe -seed 513426560 - random seed: 513426560 - ================================================================================ - success (ran 1 tests) diff --git a/RISCV_ASM/tests/rvv_test.t b/RISCV_ASM/tests/rvv_test.t deleted file mode 100644 index 84ddd4fd3..000000000 --- a/RISCV_ASM/tests/rvv_test.t +++ /dev/null @@ -1,6 +0,0 @@ - $ riscv64-unknown-elf-as -march=rv64gcv -o ../examples/rvv/rvv.o ../examples/rvv/rvv.s - $ riscv64-unknown-elf-ld -o ../examples/rvv/rvv ../examples/rvv/rvv.o - $ qemu-riscv64 ../examples/rvv/rvv < \ No newline at end of file diff --git a/grading.md b/grading.md deleted file mode 100644 index 7273242f2..000000000 --- a/grading.md +++ /dev/null @@ -1,55 +0,0 @@ -# Система оценивания допуска к экзамену - -Получениe допуска необходимо для сдачи экзамена.
-Оценка за допуск ограничивает максимальную оценку, которую будет возможно получить на экзамене. - -В решениях *задачи на E* проверяются **только тесты**.
-Решения крайне желательно сдать до какой-то пока неопределенной даты в декабре.
-**Промежуточных дедлайнов нет**. - - -## Дедлайны - -Для всех остальных задач предлагается следующая система оценивания: - -Каждая выданная задача разделена на **5 подзадач**.
-Незачет подзадачи снижает максимальную оценку на указанное количество баллов. - -Каждая подзадача имеет свой дедлайн, состоящий из двух отметок времени: -- Дата, к которой необходимо выполнить подзадачу; -- Дата, к которой необходимо исправить замечания, указанные в ревью. - -Таким образом если подзадача выдана на `(1 неделя на выполнение; 1 на исправление)`, то -- Необходимо создать PR c выполненной задачей и пройти CI в течение недели, после чего ожидать ревью; -- После получения ревью исправить замечания в течение недели. - -**Пропуск любого из дедлайнов** ведет к **незачету** подзадачи, а соответственно снижению максимальной оценки.
-Если студент пытается исправить решение в срок, но никак не получается :(, то зачет/незачет ставится на усмотрение проверяющего (для зачета должна быть хотя бы одна попытка сдачи исправленного решения). - - -*Дедлайны предлагается устанавливать сразу после прочтения лекции по соответствующей теме. -При этом требуемый срок выполнения может различаться от темы к теме в зависимости от трудоемкости конкретных подзадач.* - -## Разделение на подзадачи -Требуемый **минимальный процент покрытия** тестами для всех задач кроме первой - **80%**. - -- `AST` (-0.5 балла)
- Необходимо спроектировать AST выбранного ЯП.
Должно быть возможно представить реализацию функции факториала.
- Пример представления факториала должен быть в проекте и успешно компилироваться. - -- `Parsing 1` (-0.5 балла)
- Необходимо реализовать часть парсера выбранного ЯП.
- Парсер должен корректно обрабатывать реализацию функции факториала.
- -- `Parsing 2` (-1 балл)
- Необходимо доработать парсер выбранного ЯП.
- Парсер должен корректно обрабатывать заранее предоставленный проверяющими модуль.
- Парсер должен быть автоматически протестирован QuickCheck-подобным способом. - -- `Type check / type inference` (-1 балл)
- Необходимо разработать type checker / inferencer для выбранного ЯП.
- Type checker должен корректно обрабатывать заранее предоставленный проверяющими модуль. - -- `Eval` (-1 балл)
- Необходимо разработать непосредственно интерпретатор выбранного ЯП.
- Интерпретатор должен корректно обрабатывать заранее предоставленный проверяющими модуль. diff --git a/FSharpUnitsOfMeasure/lib/ast/ast.ml b/lib/ast/ast.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/ast/ast.ml rename to lib/ast/ast.ml diff --git a/FSharpUnitsOfMeasure/lib/ast/dune b/lib/ast/dune similarity index 100% rename from FSharpUnitsOfMeasure/lib/ast/dune rename to lib/ast/dune diff --git a/FSharpUnitsOfMeasure/lib/checks/checks.ml b/lib/checks/checks.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/checks/checks.ml rename to lib/checks/checks.ml diff --git a/FSharpUnitsOfMeasure/lib/checks/checks.mli b/lib/checks/checks.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/checks/checks.mli rename to lib/checks/checks.mli diff --git a/FSharpUnitsOfMeasure/lib/checks/dune b/lib/checks/dune similarity index 100% rename from FSharpUnitsOfMeasure/lib/checks/dune rename to lib/checks/dune diff --git a/FSharpUnitsOfMeasure/lib/inference/dune b/lib/inference/dune similarity index 100% rename from FSharpUnitsOfMeasure/lib/inference/dune rename to lib/inference/dune diff --git a/FSharpUnitsOfMeasure/lib/inference/inference.ml b/lib/inference/inference.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/inference/inference.ml rename to lib/inference/inference.ml diff --git a/FSharpUnitsOfMeasure/lib/interpret/dune b/lib/interpret/dune similarity index 100% rename from FSharpUnitsOfMeasure/lib/interpret/dune rename to lib/interpret/dune diff --git a/FSharpUnitsOfMeasure/lib/interpret/interpret.ml b/lib/interpret/interpret.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/interpret/interpret.ml rename to lib/interpret/interpret.ml diff --git a/FSharpUnitsOfMeasure/lib/interpret/interpret.mli b/lib/interpret/interpret.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/interpret/interpret.mli rename to lib/interpret/interpret.mli diff --git a/FSharpUnitsOfMeasure/lib/interpret/misc.ml b/lib/interpret/misc.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/interpret/misc.ml rename to lib/interpret/misc.ml diff --git a/FSharpUnitsOfMeasure/lib/interpret/misc.mli b/lib/interpret/misc.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/interpret/misc.mli rename to lib/interpret/misc.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/common.ml b/lib/parse/common.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/common.ml rename to lib/parse/common.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/common.mli b/lib/parse/common.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/common.mli rename to lib/parse/common.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/constants.ml b/lib/parse/constants.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/constants.ml rename to lib/parse/constants.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/constants.mli b/lib/parse/constants.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/constants.mli rename to lib/parse/constants.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/dune b/lib/parse/dune similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/dune rename to lib/parse/dune diff --git a/FSharpUnitsOfMeasure/lib/parse/expressions.ml b/lib/parse/expressions.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/expressions.ml rename to lib/parse/expressions.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/expressions.mli b/lib/parse/expressions.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/expressions.mli rename to lib/parse/expressions.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/patterns.ml b/lib/parse/patterns.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/patterns.ml rename to lib/parse/patterns.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/patterns.mli b/lib/parse/patterns.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/patterns.mli rename to lib/parse/patterns.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/structure.ml b/lib/parse/structure.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/structure.ml rename to lib/parse/structure.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/structure.mli b/lib/parse/structure.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/structure.mli rename to lib/parse/structure.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/types.ml b/lib/parse/types.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/types.ml rename to lib/parse/types.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/types.mli b/lib/parse/types.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/types.mli rename to lib/parse/types.mli diff --git a/FSharpUnitsOfMeasure/lib/parse/units_of_measure.ml b/lib/parse/units_of_measure.ml similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/units_of_measure.ml rename to lib/parse/units_of_measure.ml diff --git a/FSharpUnitsOfMeasure/lib/parse/units_of_measure.mli b/lib/parse/units_of_measure.mli similarity index 100% rename from FSharpUnitsOfMeasure/lib/parse/units_of_measure.mli rename to lib/parse/units_of_measure.mli diff --git a/tasks.md b/tasks.md deleted file mode 100644 index 8eea0da86..000000000 --- a/tasks.md +++ /dev/null @@ -1,899 +0,0 @@ -## Темы задач на самостоятельную работу - -Ниже нарочито неформально даны описания мини-языков, интерпретатор которых вам предстоит реализовать на OCaml, чтобы получить допуск к финальной аттестации (экзамену). - -Я рассчитываю, что сами разделите темы с помощью Excel-подобной таблички. - -Темы задач выдаются на двоих, т.е. почти у всех самостоятельная работа будет разная. -Если вера в собственные силы крайне мала, есть **одна отдельная тема для всех** тех, **кому достаточно** получить после экзамена максимальную оценку **E**. Потом можно передумать и переписаться на другую незанятую задачу (в том числе и на максимум E). - -В том году темы выдавались на одного, потому хвостисты страдают. - -Во всех работах, где надо писать инерпретатор типизированного языка, надо писать тайпчекер тоже. Скорее всего он будет запускаться до интерпретатора. Проверки типов, которые можно сделать на фазе типизации, нужно делать на фазе типизации, их нельзя делать в интерпретаторе. - - -### Тема для допуска на E - -Задача выдается, если вас устраивает итоговая оценка не выше E. Данная тема выдается неограниченному кругу студентов. Я в свою очередь не буду смотреть код и запускать линтер --- проверяться будет только прохождение тестов. - -Реализовать для языка miniML: -* синтаксический анализатор (парсер), - * Он должен работать шустро, а не парсить объявления факториала 10 секунд. -* type checker -* интерпретатор. - -Должны обрабатываться ошибки процессе парсинга/типизации/интерпретации (ДЗ не должно крешиться). - -### Описание MiniML - -В язык включаются: -* Целые числа, булевы значения и сравнения чисел и прочая арифметика - * Идентификаторы должны быть как в OCaml, запрещено резервировать какие-то имена, чтобы их порождать по ходу дела. - * К идентификатором разрешено приписывать типы явно -* Рекурсивные функции (в компиляторе, объявленные глобально называются [structure_item](https://github.com/ocaml/ocaml/blob/5.2.0/parsing/parsetree.mli#L1029)). - * First-class функции, с частичным примерением и взаимной рекурсией. - * Каррирования и замыкания - * Вложенные let-определения - * Не должно быть никакого ограничения сверху на количество аргументов у функций. -* Стандартные типы данных: bool, int и n-ки (англ. tuples), списки и option. - * Полноценные алгебраические типы не надо. -* Стандартные функции, чтобы что-нибудь напечатать по ходу интепретации (печать строки, печать числа и т.п.). - * Во всех задачах про OCaml, аргумент ~~анонимной~~ функции является так называемым паттерном (англ. pattern). - Выражения там разрешать писать нельзя! - * Захардкаживать стандартные функции (а ля print_int) в отдельные виды узлов AST нельзя. - -Для этой задачи выбирайте имя директории в виде ``[E]Фамилии'' латиницей. - -### Основные домашки - -1. OCaml + ADT
Подробнее - * Всё, что есть в теме для E - * алгебраические типы как основной способ проектирования типов; учтите, что - * в OCaml и Haskell типы int и float -- примитивные (встроенные) - * тип списков алгебраический и там, и там; в AST не должно быть, что списки отдельно, а алгебраические значения отдельно - * в OCaml тип bool примитивный, а в Haskell -- алгебраический - * разумеется, объявления типов, паттерн-мэтчинг и типизация - * присваивание не надо - * исключения не надо -
-1. OCaml + Extensible variant types
Подробнее - * Всё, что есть в теме для E - * алгебраические типы заменены на extensible variants -
-1. OCaml + Recursive values
Подробнее - * Всё, что есть в теме для E - * [Recursive definitions of values](https://v2.ocaml.org/manual/letrecvalues.html). В простенькие бесконечные списки должно быть можно заглядывать. - * Плохой синтаксис должен выдавать ошибку типизации: this expression is not allowe on RHS of let rec -
-1. OCaml + полиморфные вариантые типы
Подробнее - * Всё, что есть в теме для E - * [Глава про полиморфные варианты в мануале OCaml](https://v2.ocaml.org/manual/polyvariant.html) - * Объявления типов можно не делать - * Стандартные типы (пары, списки, option) можно делать, а можно не делать, выразив через полиморфные варианты -
-1. OCaml + bidirectional records
Подробнее - * Всё, что есть в теме для E - * поддержать синтаксис приписывания (англ. ascription) типов переменным - * records (a.k.a. записи, структуры) c полями из базовых типов или других записей. - * в случае перекрытия имен интерпретатор должен учесть приписанные типы. В примере ниже без аннотаций типов результат вывода будет другой - ```ocaml - type t = { aa: int; bb: bool } - type s = { aa: float; cc: int } - let f (x : t) = x.aa - let g (x : s) = x.aa - ``` -
-1. OCaml + [labelled tuples](https://github.com/ocaml/ocaml/pull/13498) -1. F# + active patterns
Подробнее - * Всё, что есть в теме для E - * возможность описывать [активные паттерны](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/active-patterns), которые выглядят как алгебраические конструкторы - ``` - let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd - ``` - * Возможность использования активных паттернов в сопоставлении с образцом - ``` - let TestNumber = function - | Even -> printf "%d is even\n" input - | Odd -> printf "%d is odd\n" input - ``` -
-1. F# + Units of Measure
Подробнее - * Всё, что есть в теме для E - * Вещественные числа (обосновано следующим пунктом) - * Возможность объявлять и использовать [Units of Measure](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure) -
-1. Haskell + стандартные типы данных + ленивость
Подробнее - * Всё, что есть в теме для E - * С ленивостью надо будет продемонстрировать работоспособность - * Лямбда-исчисления с call-by-name - * ленивых списков и операция над ними (в том числе, фибоначчи, решето Эратосфена и т.п.) - * прочие ленивые задачи (например, за один проход заменить все числа в дереве на их минимум и вернуть новое дерево) -
-1. Haskell + [Pattern Synonyms](https://gitlab.haskell.org/ghc/ghc/-/wikis/pattern-synonyms) + [View Patterns](https://gitlab.haskell.org/ghc/ghc/-/wikis/view-patterns)
Подробнее - * Всё, что есть в теме для E - * Два расширения Haskell на тему сопоставления с образцом. - * Это очень похоже на тему про F# + Active patterns. - * Хоть это и хаскель, для упрощения жизни, я не планирую проверять ленивость стратегии. Можете делать вид, что это скорее PureScript -
-1. Purescript + простые классы типов
Подробнее - * Всё, что есть в теме для E - * Синтаксис не как в OCaml, а скорее как в Haskell, вычисления строги - * Простая поддержка классов типов --- средства для overloading. -
-1. OCaml + [ООП](https://v2.ocaml.org/manual/objectexamples.html)
Подробнее - * Всё, что есть в теме для E, кроме n-ок. - * в OCaml есть интересные объекты и их типизация, нужно поддержать объекты+методы+поля. - * (может быть классы и наследование тоже надо будет, но пока не уверен) - * как тесты предлагаю реализовать некоторые структуры данных как камлёвые объекты и посмотреть, что будет -
-1. OCaml + printf
Подробнее - * Всё, что есть в теме для E - * Поддержка типов char, string и операций с ними - * Поддержка в компиляторе функции форматированой печати (по аналогии с камлёвым модулем Printf/Format). - * printf, sprintf, ksprintf, конкатенация форматированных строк - * Разумеется, всё должно быть type safe. -
-1. OCaml, именованые и опциональные аргументы
Подробнее - * Всё, что есть в теме для E - * Захардкоженный тип option - * Именованные и опциональные аргументы. Функции должны типизироваться и исполняться как в настоящем OCaml. -
-1. OCaml + weak type variables
Подробнее - * Всё, что есть в теме для E - * https://ocamlverse.net/content/weak_type_variables.html. Присваивание неоходимо, так как без него тема бессодержательна. -
-1. SML + equality types + value restriction
Подробнее - + Почти предыдущая задача, но проще - + Немножко другой парсер, потому что SML немножко отличается - + Еquality types: - * в типах функций появляются типовые переменные с двумя апострофами, что означает, что туда можно подставлять только типы, на которых работает функция проверки на равенство (функции и вещественные числа нельзя сравнивать) - + Value restiction - * Заставляет выводить менее полиморфные типы, потому что присваивание может нарушать типовую безопасность - * https://users.cs.fiu.edu/~smithg/cop4555/valrestr.html -
- -1. Scala + By-name Parameters
Подробнее - * Всё, что есть в теме для E - * Другой парсер (!) - * [Параметры функций](https://docs.scala-lang.org/tour/by-name-parameters.html), которые не Call-by-Value (как в OCaml/Scala), а call-by-name (как в Haskell) -
-1. Scheme + call/cc
Подробнее - * относительно легко гуглящаяся особенность Scheme - * call/cc - * целые числа, рекурсия, списки, печать на консоль - * функции обычные и анонимные, замыкания и рекурсия - * присваивание не надо - * quote/unquote - * парсер очень простой - * никаких статических типов, разумеется, нет -
-1. Scheme + delim/cc
Подробнее - * почти как предыдущая задача, только понятней - * Кратко про delim/cc - + есть две новые конструкции в языке: `reset (fun () -> M)` и `shift (fun k -> M)` - + Пример: `reset (fun () -> 2 + 2 * shift (fun k -> k 20))` - + Наличие одинокого `reset` не влияет на вычисление - + Когда исполнение доходит до `shift`, то вместо аргумета подставляется функция, которая "зажата" между этим `shift` и ближайшим `reset`, В данном случае это `fun y -> 2 + 2 * y` - + таким образом, выражение выше вычисляется в 42 -
-1. Ассемблер RISC-V 64
Подробнее - * Очень простой язык и для парсинга, не особо сложный для интерпретации. - * Язык должен быть настоящим ассемблером, т.е. входные программы должны компилироваться соответствующим (кросс)компилятором и выдавать ответ как в интерпретаторе. Сделайте cram тесты, демонстрирующие это. - * Нужно поддержать некоторые системные вызовы Linux для отладки программ, на подобие выхода и печати в stdout. - * Так как язык простой, нужны расширения Bitmanip и RVV, в мере, достаточной для интересных тестов. - * Опыты прошлых лет показывает, что написание AST в лоб оставляет большое пространство для плохих программ, представимых в AST. Например, 64битные команды никак не должны принимать 32битные операнды-регистры как аргументы. Потребуется обмазаться фантомными-типами и/или GADT, чтобы не нужно было писать гавнокод. Буду следить! -
-1. Go с горутинами
Подробнее - * Стандартные типы данных (int, bool, string) - * Циклы - * Условный оператор (if) - * Массивы - * Функции (обычные, рекурсивные, замыкания (в том числе с поддержкой присваивания)) - * Каналы (достать, положить, закрыть) - * Горутины (переключение по ожиданию данных из канала) - * Замечания: - * используется урезанная версия Go 1.17 - * в string нету доступа по индексу (т.к. нету символьного типа) - * ключевые слова: break func defer go chan if else continue for return var - * предопределенные идентификаторы: bool int string true false nil make close len panic print println recover -
- -### Посложнее - -1. OCaml с типизированными эффектами
Подробнее - * Всё, что есть в теме для E - * C эффектами: присваивание, печать на консоль и try/catch/raise для пары захардкоженных в язык исключений. Из-за присваивания -- два человека - * С системой типов в описанном выше смысле. - * https://www.janestreet.com/tech-talks/effective-programming - * Идея заключается в том, что теперь мы будем перечислять в типе функции-стрелке эффекты, которые совершает функция - * Обычная стрелка `->` делает что угодно - * Длинная стрелка `-->` (или `-[]->`) -- это чистая функция: ни присваиваний, ни ввода-вывода. Ничего не делает такого. - * Над стрелкой можно перечислять, что она делает: - * `-[IO]->` делает ввод-вывод - * `-[exc Not_found]->` кидает исключение `Not_found` - * `-['a]->` совершает какой-то эффект, но он не указан (полиморфизм) - * Пример: - - ```ocaml - val id : 'a --> 'a - val print_int: int -[IO]-> unit - - let map : ('a -['e]-> 'b) --> 'a list -['e]-> 'b list = fun f xs -> - match xs with - | [] -> [] - | x::xs -> (f x) :: (map f xs) - - let _ : 'a list --> 'b list = map id - let _ : int list -[IO]-> int list = - map (fun n -> print_int n; n+1) - ``` - - Фунция `id` чистая, поэтому над стрелочкой ничего не написано. - - Функция `print_int` совершает ввод-вывод, что указано в типе. - - `List.map` полиморфна (как обычно) по типу элементу списка, но также полиморфная по типу эффекта переданной функции, что указано в стрелке, которая выдает результат. Первая стреклка в типе `map` чистая, так как при передаче аргументов ничего не вычисляется и эффектов не совершается. В `map id` не совешается эффектов, поэтому типовая переменная `'e` сунифицировалась с отсутсвием эффектов. Во втором примере из-за того, что переданная функция совершает ввод-вывод, система типов догадывается, что и вычисление `map` совершает ввод-вывод. - - Вы уже видели приписывание эффектов к функциям, а именно, приписывание бросаемых исключений в языке Java. Но так как там не было полиморфизма по этим "эффектам", то люди ненавидели эту штуку и поэтому, на сколько я знаю, в идеалогических наследниках Java этого нет. -
-1. OCaml + GADT
Подробнее - * Всё, что есть в задаче OCaml+ADT - * OCaml где алгебраические типы заменены на обобщенные (generalized) алгебраические типы - * Интерпретатор точно будет такой же, как в задаче про обычные алгебраические типы - * Вывод/проверка типов (сильно) сложнее, чем для обычных алгебраических, поэтому два человека - * Нужно поддержать явные аннотации типов, потому что автоматический вывод типов не могёт - * Типовые переменные могут убегать из области видимости и т.д. - * [Умная сслыка, описывающая что примерно вас ждет](https://ocaml.org/releases/4.12/manual/gadts.html) - * Если будут работать гетерогенные списки и равенство по Лейбинцу, то можно и С поставить без экзамено обоим -
-1. OCaml + effects
Подробнее - * Всё, что есть в теме для E - * Cупер-модное в наши дни движение в мире ФП - * По сути, это исключения, но в момент обработки которых у нас есть функция, которой можно был передать значение, которое должно было бы быть вместо бросания исключения, и продолжить исполнение с места бросания исключения. - * Туториал в контексте OCaml https://github.com/ocamllabs/ocaml-effects-tutorial -
- - -##### Прочие замечания - -Тема "на двоих" означает, что делаете в двоем, вместе, одно и то же. В конце я буду ожидать, что оба разбираются в коде и смогут объяснить, что там происходит. Не сможете продемонстрировать, что знаете код напарника как свой --- пинайте на себя - -Если у Вас есть предложения по добавлению других языков -- пишите. diff --git a/FSharpUnitsOfMeasure/tests/dune b/tests/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/dune rename to tests/dune diff --git a/FSharpUnitsOfMeasure/tests/inference/dune b/tests/inference/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/inference/dune rename to tests/inference/dune diff --git a/FSharpUnitsOfMeasure/tests/inference/tests_inference.ml b/tests/inference/tests_inference.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/inference/tests_inference.ml rename to tests/inference/tests_inference.ml diff --git a/FSharpUnitsOfMeasure/tests/inference/tests_inference.mli b/tests/inference/tests_inference.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/inference/tests_inference.mli rename to tests/inference/tests_inference.mli diff --git a/FSharpUnitsOfMeasure/tests/interpret/dune b/tests/interpret/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/interpret/dune rename to tests/interpret/dune diff --git a/FSharpUnitsOfMeasure/tests/interpret/tests_interpr.ml b/tests/interpret/tests_interpr.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/interpret/tests_interpr.ml rename to tests/interpret/tests_interpr.ml diff --git a/FSharpUnitsOfMeasure/tests/interpret/tests_interpr.mli b/tests/interpret/tests_interpr.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/interpret/tests_interpr.mli rename to tests/interpret/tests_interpr.mli diff --git a/EChirkov/tests/manytests b/tests/manytests similarity index 100% rename from EChirkov/tests/manytests rename to tests/manytests diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/dune b/tests/parse/pprint/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/dune rename to tests/parse/pprint/dune diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/pp.ml b/tests/parse/pprint/pp.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/pp.ml rename to tests/parse/pprint/pp.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/pp.mli b/tests/parse/pprint/pp.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/pp.mli rename to tests/parse/pprint/pp.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/pprinter.ml b/tests/parse/pprint/pprinter.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/pprinter.ml rename to tests/parse/pprint/pprinter.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/pprinter.mli b/tests/parse/pprint/pprinter.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/pprinter.mli rename to tests/parse/pprint/pprinter.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/pprint/tests_pprinter.ml b/tests/parse/pprint/tests_pprinter.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/pprint/tests_pprinter.ml rename to tests/parse/pprint/tests_pprinter.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/qcheck/dune b/tests/parse/qcheck/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/qcheck/dune rename to tests/parse/qcheck/dune diff --git a/FSharpUnitsOfMeasure/tests/parse/qcheck/qCheckRun.ml b/tests/parse/qcheck/qCheckRun.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/qcheck/qCheckRun.ml rename to tests/parse/qcheck/qCheckRun.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/qcheck/qcheck.t b/tests/parse/qcheck/qcheck.t similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/qcheck/qcheck.t rename to tests/parse/qcheck/qcheck.t diff --git a/FSharpUnitsOfMeasure/tests/parse/qcheck/shrinker.ml b/tests/parse/qcheck/shrinker.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/qcheck/shrinker.ml rename to tests/parse/qcheck/shrinker.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/qcheck/shrinker.mli b/tests/parse/qcheck/shrinker.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/qcheck/shrinker.mli rename to tests/parse/qcheck/shrinker.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/dune b/tests/parse/unitTests/dune similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/dune rename to tests/parse/unitTests/dune diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_constants.ml b/tests/parse/unitTests/tests_constants.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_constants.ml rename to tests/parse/unitTests/tests_constants.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_constants.mli b/tests/parse/unitTests/tests_constants.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_constants.mli rename to tests/parse/unitTests/tests_constants.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_expressions.ml b/tests/parse/unitTests/tests_expressions.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_expressions.ml rename to tests/parse/unitTests/tests_expressions.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_expressions.mli b/tests/parse/unitTests/tests_expressions.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_expressions.mli rename to tests/parse/unitTests/tests_expressions.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_patterns.ml b/tests/parse/unitTests/tests_patterns.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_patterns.ml rename to tests/parse/unitTests/tests_patterns.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_patterns.mli b/tests/parse/unitTests/tests_patterns.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_patterns.mli rename to tests/parse/unitTests/tests_patterns.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_structure.ml b/tests/parse/unitTests/tests_structure.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_structure.ml rename to tests/parse/unitTests/tests_structure.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_structure.mli b/tests/parse/unitTests/tests_structure.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_structure.mli rename to tests/parse/unitTests/tests_structure.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_types.ml b/tests/parse/unitTests/tests_types.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_types.ml rename to tests/parse/unitTests/tests_types.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_types.mli b/tests/parse/unitTests/tests_types.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_types.mli rename to tests/parse/unitTests/tests_types.mli diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_units_of_measure.ml b/tests/parse/unitTests/tests_units_of_measure.ml similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_units_of_measure.ml rename to tests/parse/unitTests/tests_units_of_measure.ml diff --git a/FSharpUnitsOfMeasure/tests/parse/unitTests/tests_units_of_measure.mli b/tests/parse/unitTests/tests_units_of_measure.mli similarity index 100% rename from FSharpUnitsOfMeasure/tests/parse/unitTests/tests_units_of_measure.mli rename to tests/parse/unitTests/tests_units_of_measure.mli diff --git a/FSharpUnitsOfMeasure/tests/repl.t b/tests/repl.t similarity index 100% rename from FSharpUnitsOfMeasure/tests/repl.t rename to tests/repl.t diff --git a/vscode.png b/vscode.png deleted file mode 100644 index e1ae1b351..000000000 Binary files a/vscode.png and /dev/null differ