From dab2851ee4342ca67de74b51d86aaabf44af0666 Mon Sep 17 00:00:00 2001 From: kyle Date: Sun, 15 Sep 2024 16:23:18 -0700 Subject: [PATCH] Add CST data structure --- Cargo.lock | 15 + Cargo.toml | 1 + compiler/cst/Cargo.toml | 56 ++ compiler/cst/LICENSE.md | 596 ++++++++++++++++++ compiler/cst/README.md | 6 + compiler/cst/src/access/array_access.rs | 22 + .../src/access/associated_constant_access.rs | 21 + .../src/access/associated_function_access.rs | 24 + compiler/cst/src/access/member_access.rs | 22 + compiler/cst/src/access/mod.rs | 16 + compiler/cst/src/access/tuple_access.rs | 22 + compiler/cst/src/common/comment.rs | 8 + compiler/cst/src/common/identifier.rs | 19 + compiler/cst/src/common/import_module.rs | 8 + compiler/cst/src/common/location.rs | 5 + compiler/cst/src/common/mod.rs | 22 + compiler/cst/src/common/node.rs | 62 ++ compiler/cst/src/common/positive_number.rs | 10 + compiler/cst/src/common/space.rs | 37 ++ compiler/cst/src/expressions/access.rs | 22 + compiler/cst/src/expressions/array.rs | 15 + compiler/cst/src/expressions/binary.rs | 90 +++ compiler/cst/src/expressions/call.rs | 23 + compiler/cst/src/expressions/cast.rs | 20 + compiler/cst/src/expressions/err.rs | 15 + compiler/cst/src/expressions/literal.rs | 28 + compiler/cst/src/expressions/locator.rs | 22 + compiler/cst/src/expressions/mod.rs | 80 +++ compiler/cst/src/expressions/struct_init.rs | 39 ++ compiler/cst/src/expressions/ternary.rs | 20 + compiler/cst/src/expressions/tuple.rs | 18 + compiler/cst/src/expressions/unary.rs | 43 ++ compiler/cst/src/expressions/unit.rs | 14 + compiler/cst/src/functions/annotation.rs | 19 + compiler/cst/src/functions/input.rs | 19 + compiler/cst/src/functions/mod.rs | 117 ++++ compiler/cst/src/functions/mode.rs | 18 + compiler/cst/src/functions/output.rs | 17 + compiler/cst/src/functions/variant.rs | 16 + compiler/cst/src/lib.rs | 32 + compiler/cst/src/mapping/mod.rs | 45 ++ compiler/cst/src/program/mod.rs | 71 +++ compiler/cst/src/program/program_id.rs | 10 + compiler/cst/src/program/program_scope.rs | 58 ++ compiler/cst/src/statement/assert.rs | 28 + compiler/cst/src/statement/assign.rs | 23 + compiler/cst/src/statement/block.rs | 63 ++ compiler/cst/src/statement/conditional.rs | 24 + .../src/statement/console/console_function.rs | 41 ++ .../statement/console/console_statement.rs | 46 ++ compiler/cst/src/statement/console/mod.rs | 21 + compiler/cst/src/statement/const_.rs | 37 ++ .../statement/definition/declaration_type.rs | 36 ++ compiler/cst/src/statement/definition/mod.rs | 52 ++ compiler/cst/src/statement/expression.rs | 18 + compiler/cst/src/statement/iteration.rs | 37 ++ compiler/cst/src/statement/mod.rs | 62 ++ compiler/cst/src/statement/return_.rs | 19 + compiler/cst/src/struct/member.rs | 40 ++ compiler/cst/src/struct/mod.rs | 81 +++ compiler/cst/src/types/array.rs | 8 + compiler/cst/src/types/core_constant.rs | 5 + compiler/cst/src/types/future.rs | 13 + compiler/cst/src/types/integer_type.rs | 17 + compiler/cst/src/types/mapping.rs | 12 + compiler/cst/src/types/mod.rs | 23 + compiler/cst/src/types/struct_type.rs | 14 + compiler/cst/src/types/tuple.rs | 9 + compiler/cst/src/types/type_.rs | 44 ++ 69 files changed, 2616 insertions(+) create mode 100644 compiler/cst/Cargo.toml create mode 100644 compiler/cst/LICENSE.md create mode 100644 compiler/cst/README.md create mode 100644 compiler/cst/src/access/array_access.rs create mode 100644 compiler/cst/src/access/associated_constant_access.rs create mode 100644 compiler/cst/src/access/associated_function_access.rs create mode 100644 compiler/cst/src/access/member_access.rs create mode 100644 compiler/cst/src/access/mod.rs create mode 100644 compiler/cst/src/access/tuple_access.rs create mode 100644 compiler/cst/src/common/comment.rs create mode 100644 compiler/cst/src/common/identifier.rs create mode 100644 compiler/cst/src/common/import_module.rs create mode 100644 compiler/cst/src/common/location.rs create mode 100644 compiler/cst/src/common/mod.rs create mode 100644 compiler/cst/src/common/node.rs create mode 100644 compiler/cst/src/common/positive_number.rs create mode 100644 compiler/cst/src/common/space.rs create mode 100644 compiler/cst/src/expressions/access.rs create mode 100644 compiler/cst/src/expressions/array.rs create mode 100644 compiler/cst/src/expressions/binary.rs create mode 100644 compiler/cst/src/expressions/call.rs create mode 100644 compiler/cst/src/expressions/cast.rs create mode 100644 compiler/cst/src/expressions/err.rs create mode 100644 compiler/cst/src/expressions/literal.rs create mode 100644 compiler/cst/src/expressions/locator.rs create mode 100644 compiler/cst/src/expressions/mod.rs create mode 100644 compiler/cst/src/expressions/struct_init.rs create mode 100644 compiler/cst/src/expressions/ternary.rs create mode 100644 compiler/cst/src/expressions/tuple.rs create mode 100644 compiler/cst/src/expressions/unary.rs create mode 100644 compiler/cst/src/expressions/unit.rs create mode 100644 compiler/cst/src/functions/annotation.rs create mode 100644 compiler/cst/src/functions/input.rs create mode 100644 compiler/cst/src/functions/mod.rs create mode 100644 compiler/cst/src/functions/mode.rs create mode 100644 compiler/cst/src/functions/output.rs create mode 100644 compiler/cst/src/functions/variant.rs create mode 100644 compiler/cst/src/lib.rs create mode 100644 compiler/cst/src/mapping/mod.rs create mode 100644 compiler/cst/src/program/mod.rs create mode 100644 compiler/cst/src/program/program_id.rs create mode 100644 compiler/cst/src/program/program_scope.rs create mode 100644 compiler/cst/src/statement/assert.rs create mode 100644 compiler/cst/src/statement/assign.rs create mode 100644 compiler/cst/src/statement/block.rs create mode 100644 compiler/cst/src/statement/conditional.rs create mode 100644 compiler/cst/src/statement/console/console_function.rs create mode 100644 compiler/cst/src/statement/console/console_statement.rs create mode 100644 compiler/cst/src/statement/console/mod.rs create mode 100644 compiler/cst/src/statement/const_.rs create mode 100644 compiler/cst/src/statement/definition/declaration_type.rs create mode 100644 compiler/cst/src/statement/definition/mod.rs create mode 100644 compiler/cst/src/statement/expression.rs create mode 100644 compiler/cst/src/statement/iteration.rs create mode 100644 compiler/cst/src/statement/mod.rs create mode 100644 compiler/cst/src/statement/return_.rs create mode 100644 compiler/cst/src/struct/member.rs create mode 100644 compiler/cst/src/struct/mod.rs create mode 100644 compiler/cst/src/types/array.rs create mode 100644 compiler/cst/src/types/core_constant.rs create mode 100644 compiler/cst/src/types/future.rs create mode 100644 compiler/cst/src/types/integer_type.rs create mode 100644 compiler/cst/src/types/mapping.rs create mode 100644 compiler/cst/src/types/mod.rs create mode 100644 compiler/cst/src/types/struct_type.rs create mode 100644 compiler/cst/src/types/tuple.rs create mode 100644 compiler/cst/src/types/type_.rs diff --git a/Cargo.lock b/Cargo.lock index 6723bf257e..4d1b6d83a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1587,6 +1587,21 @@ dependencies = [ "tempfile", ] +[[package]] +name = "leo-cst" +version = "2.1.0" +dependencies = [ + "criterion", + "indexmap 1.9.3", + "itertools 0.13.0", + "leo-errors", + "leo-span", + "serde", + "serde_json", + "smallvec", + "snarkvm", +] + [[package]] name = "leo-disassembler" version = "2.1.0" diff --git a/Cargo.toml b/Cargo.toml index d1d224a3c1..1169070bb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ edition = "2021" members = [ "compiler/ast", "compiler/compiler", + "compiler/cst", "compiler/parser", "compiler/passes", "compiler/span", diff --git a/compiler/cst/Cargo.toml b/compiler/cst/Cargo.toml new file mode 100644 index 0000000000..4e1746b5ba --- /dev/null +++ b/compiler/cst/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "leo-cst" +version = "2.1.0" +authors = [ "The Aleo Team " ] +description = "Concrete syntax tree (CST) for the Leo programming language" +homepage = "https://aleo.org" +repository = "https://github.com/AleoHQ/leo" +keywords = [ + "aleo", + "cryptography", + "leo", + "programming-language", + "zero-knowledge" +] +categories = [ "compilers", "cryptography", "web-programming" ] +include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ] +license = "GPL-3.0" +edition = "2021" +rust-version = "1.69" + +[dependencies.snarkvm] +workspace = true + +[dependencies.leo-errors] +path = "../../errors" +version = "2.1.0" + +[dependencies.leo-span] +path = "../span" +version = "2.1.0" + +[dependencies.indexmap] +version = "1.9" +features = [ "serde-1" ] + +[dependencies.itertools] +version = "0.13.0" + +[dependencies.serde] +version = "1.0" +features = [ "derive", "rc" ] + +[dependencies.serde_json] +version = "1.0" +features = [ "preserve_order" ] + +[dependencies.smallvec] +version = "1.13.1" +features = [ "serde" ] + +[dev-dependencies.criterion] +version = "0.5" + +[features] +default = [ ] +ci_skip = [ ] diff --git a/compiler/cst/LICENSE.md b/compiler/cst/LICENSE.md new file mode 100644 index 0000000000..b95c626e2a --- /dev/null +++ b/compiler/cst/LICENSE.md @@ -0,0 +1,596 @@ +GNU General Public License +========================== + +Version 3, 29 June 2007 + +Copyright © 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/compiler/cst/README.md b/compiler/cst/README.md new file mode 100644 index 0000000000..7455debf6c --- /dev/null +++ b/compiler/cst/README.md @@ -0,0 +1,6 @@ +# leo-cst + +[![Crates.io](https://img.shields.io/crates/v/leo-cst.svg?color=neon)](https://crates.io/crates/leo-cst) +[![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](../AUTHORS) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md) + diff --git a/compiler/cst/src/access/array_access.rs b/compiler/cst/src/access/array_access.rs new file mode 100644 index 0000000000..0e4672f97f --- /dev/null +++ b/compiler/cst/src/access/array_access.rs @@ -0,0 +1,22 @@ + + +use crate::{Expression, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An array access expression, e.g., `foo[index]`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ArrayAccess { + /// An expression evaluating to some array type, e.g., `[false, true]`. + pub array: Box, + /// The index to access in the array expression. E.g., `0` for `[false, true]` would yield `false`. + pub index: Box, + /// The span for the entire expression `foo[index]`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(ArrayAccess); diff --git a/compiler/cst/src/access/associated_constant_access.rs b/compiler/cst/src/access/associated_constant_access.rs new file mode 100644 index 0000000000..b27c1cb502 --- /dev/null +++ b/compiler/cst/src/access/associated_constant_access.rs @@ -0,0 +1,21 @@ + +use crate::{Identifier, Node, NodeID, Type}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An access expression to an struct constant., e.g. `u8::MAX`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AssociatedConstant { + /// The inner struct type. + pub ty: Type, + /// The struct constant that is being accessed. + pub name: Identifier, + /// The span for the entire expression `Foo::bar()`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(AssociatedConstant); diff --git a/compiler/cst/src/access/associated_function_access.rs b/compiler/cst/src/access/associated_function_access.rs new file mode 100644 index 0000000000..1d65078d88 --- /dev/null +++ b/compiler/cst/src/access/associated_function_access.rs @@ -0,0 +1,24 @@ + + +use crate::{Expression, Identifier, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An access expression to an associated function in a struct, e.g.`Pedersen64::hash()`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AssociatedFunction { + /// The inner struct variant. + pub variant: Identifier, + /// The static struct member function that is being accessed. + pub name: Identifier, + /// The arguments passed to the function `name`. + pub arguments: Vec, + /// The span for the entire expression `Foo::bar()`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(AssociatedFunction); diff --git a/compiler/cst/src/access/member_access.rs b/compiler/cst/src/access/member_access.rs new file mode 100644 index 0000000000..c24c7c48be --- /dev/null +++ b/compiler/cst/src/access/member_access.rs @@ -0,0 +1,22 @@ + +use crate::{Expression, Identifier, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A struct member access expression `inner.name` to some structure with *named members*. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct MemberAccess { + /// The inner struct that is being accessed. + pub inner: Box, + /// The name of the struct member to access. + pub name: Identifier, + /// The span covering all of `inner.name`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(MemberAccess); diff --git a/compiler/cst/src/access/mod.rs b/compiler/cst/src/access/mod.rs new file mode 100644 index 0000000000..6dcf245d23 --- /dev/null +++ b/compiler/cst/src/access/mod.rs @@ -0,0 +1,16 @@ + + +mod array_access; +pub use array_access::*; + +mod associated_constant_access; +pub use associated_constant_access::*; + +mod associated_function_access; +pub use associated_function_access::*; + +mod member_access; +pub use member_access::*; + +mod tuple_access; +pub use tuple_access::*; diff --git a/compiler/cst/src/access/tuple_access.rs b/compiler/cst/src/access/tuple_access.rs new file mode 100644 index 0000000000..8ee4290407 --- /dev/null +++ b/compiler/cst/src/access/tuple_access.rs @@ -0,0 +1,22 @@ + + +use crate::{Expression, Node, NodeID, NonNegativeNumber}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// A tuple access expression, e.g., `tuple.index`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TupleAccess { + /// An expression evaluating to some tuple type, e.g., `(5, 2)`. + pub tuple: Box, + /// The index to access in the tuple expression. E.g., `0` for `(5, 2)` would yield `5`. + pub index: NonNegativeNumber, + /// The span for the entire expression `tuple.index`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(TupleAccess); diff --git a/compiler/cst/src/common/comment.rs b/compiler/cst/src/common/comment.rs new file mode 100644 index 0000000000..19dba3f248 --- /dev/null +++ b/compiler/cst/src/common/comment.rs @@ -0,0 +1,8 @@ + +use super::*; +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] + +pub enum Comment { + Line(String, #[serde(with = "leo_span::span_json")] Span, NodeID), + Block(String, #[serde(with = "leo_span::span_json")] Span, NodeID), +} \ No newline at end of file diff --git a/compiler/cst/src/common/identifier.rs b/compiler/cst/src/common/identifier.rs new file mode 100644 index 0000000000..262eae38a8 --- /dev/null +++ b/compiler/cst/src/common/identifier.rs @@ -0,0 +1,19 @@ +use crate::{simple_node_impl, Node, NodeID}; +use leo_span::{Span, Symbol}; + +use super::Space; + +#[derive(Clone, Copy)] +pub struct Identifier { + /// The symbol that the user wrote, e.g., `foo`. + pub pl_name: Space, + pub name: Symbol, + pub pr_name: Space, + + /// A span locating where the identifier occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +simple_node_impl!(Identifier); \ No newline at end of file diff --git a/compiler/cst/src/common/import_module.rs b/compiler/cst/src/common/import_module.rs new file mode 100644 index 0000000000..d5bc1f0d4c --- /dev/null +++ b/compiler/cst/src/common/import_module.rs @@ -0,0 +1,8 @@ +use super::Identifier; + +#[derive(Debug, Clone)] +pub struct ImportModule { + pub module: Identifier, + pub span: Span, + pub id: NodeID, +} diff --git a/compiler/cst/src/common/location.rs b/compiler/cst/src/common/location.rs new file mode 100644 index 0000000000..3f0f02f253 --- /dev/null +++ b/compiler/cst/src/common/location.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Location { + pub program: Option, + pub name: Symbol, +} \ No newline at end of file diff --git a/compiler/cst/src/common/mod.rs b/compiler/cst/src/common/mod.rs new file mode 100644 index 0000000000..7a36c2e80c --- /dev/null +++ b/compiler/cst/src/common/mod.rs @@ -0,0 +1,22 @@ +use leo_span::Span; + +pub mod comment; +pub use comment::*; + +pub mod import_module; +pub use import_module::*; + +pub mod node; +pub use node::*; + +pub mod positive_number; +pub use positive_number::*; + +pub mod location; +pub use location::*; + +pub mod identifier; +pub use identifier::*; + +pub mod space; +pub use space::*; \ No newline at end of file diff --git a/compiler/cst/src/common/node.rs b/compiler/cst/src/common/node.rs new file mode 100644 index 0000000000..a0a5080cc9 --- /dev/null +++ b/compiler/cst/src/common/node.rs @@ -0,0 +1,62 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use leo_span::Span; + +/// A node ID. +// Development Note: +// A `NodeID` must implement: `Copy`, `Default`, among others. +pub type NodeID = usize; + +/// A node in the AST. +pub trait Node: + std::fmt::Debug + std::fmt::Display + Clone + PartialEq + Eq + serde::Serialize + serde::de::DeserializeOwned +{ + /// Returns the span of the node. + fn span(&self) -> Span; + + /// Sets the span of the node. + fn set_span(&mut self, span: Span); + + /// Returns the ID of the node. + fn id(&self) -> NodeID; + + /// Sets the ID of the node. + fn set_id(&mut self, id: NodeID); +} + +#[macro_export] +macro_rules! simple_node_impl { + ($ty:ty) => { + impl Node for $ty { + fn span(&self) -> Span { + self.span + } + + fn set_span(&mut self, span: Span) { + self.span = span; + } + + fn id(&self) -> NodeID { + self.id + } + + fn set_id(&mut self, id: NodeID) { + self.id = id; + } + } + }; +} diff --git a/compiler/cst/src/common/positive_number.rs b/compiler/cst/src/common/positive_number.rs new file mode 100644 index 0000000000..980eda6c95 --- /dev/null +++ b/compiler/cst/src/common/positive_number.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +/// A number string guaranteed to be non-negative. +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] +pub struct NonNegativeNumber { + /// The string representation of the non-negative number. + string: String, + /// The numeric value of the non-negative number. + value: usize, +} \ No newline at end of file diff --git a/compiler/cst/src/common/space.rs b/compiler/cst/src/common/space.rs new file mode 100644 index 0000000000..2233179b38 --- /dev/null +++ b/compiler/cst/src/common/space.rs @@ -0,0 +1,37 @@ +use crate::{simple_node_impl, Node, NodeID, Comment}; + +#[derive(Clone, Copy)] +pub struct Tab { + /// '\t' + /// A span locating where the identifier occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +#[derive(Clone, Copy)] +pub struct NewLine { + /// '\n' + /// A span locating where the identifier occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +#[derive(Clone, Copy)] +pub struct WhiteSpace { + /// '\t' + /// A span locating where the identifier occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +pub enum Space { + Tab(Tab), + WhiteSpace(WhiteSpace), + NewLine(NewLine), + Comment(Comment), + None +} +simple_node_impl!(WhiteSpace); +simple_node_impl!(NewLine); +simple_node_impl!(Tab); \ No newline at end of file diff --git a/compiler/cst/src/expressions/access.rs b/compiler/cst/src/expressions/access.rs new file mode 100644 index 0000000000..d10c79f248 --- /dev/null +++ b/compiler/cst/src/expressions/access.rs @@ -0,0 +1,22 @@ + +use crate::{access::*, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An access expressions, extracting a smaller part out of a whole. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum AccessExpression { + /// An `array[index]` expression. + Array(ArrayAccess), + // /// An expression accessing a range of an array. + // ArrayRange(ArrayRangeAccess), + /// Access to an associated variable of a struct e.g `u8::MAX`. + AssociatedConstant(AssociatedConstant), + /// Access to an associated function of a struct e.g `Pedersen64::hash()`. + AssociatedFunction(AssociatedFunction), + /// An expression accessing a field in a structure, e.g., `struct_var.field`. + Member(MemberAccess), + /// Access to a tuple field using its position, e.g., `tuple.1`. + Tuple(TupleAccess), +} \ No newline at end of file diff --git a/compiler/cst/src/expressions/array.rs b/compiler/cst/src/expressions/array.rs new file mode 100644 index 0000000000..5cd3de2a2e --- /dev/null +++ b/compiler/cst/src/expressions/array.rs @@ -0,0 +1,15 @@ + +use super::*; +use serde::{Deserialize, Serialize}; + +/// An array expression, e.g., `[true, false, true, false]`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ArrayExpression { + /// The elements of the array. + pub elements: Vec, + /// The span from `[` to `]`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +crate::simple_node_impl!(ArrayExpression); diff --git a/compiler/cst/src/expressions/binary.rs b/compiler/cst/src/expressions/binary.rs new file mode 100644 index 0000000000..0ac2d17d94 --- /dev/null +++ b/compiler/cst/src/expressions/binary.rs @@ -0,0 +1,90 @@ + + +use super::*; +use leo_span::{sym, Symbol}; +use serde::{Deserialize, Serialize}; + +/// A binary operator. +/// +/// Precedence is defined in the parser. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum BinaryOperation { + /// Addition, i.e. `+`, `.add()`. + Add, + /// Wrapping addition, i.e. `.add_wrapped()`. + AddWrapped, + /// Logical AND, i.e. `&&`. + And, + /// Bitwise AND, i.e. `&`, `.and()`. + BitwiseAnd, + /// Division, i.e. `/`, `.div()`. + Div, + /// Wrapping division, i.e. `.div_wrapped()`. + DivWrapped, + /// Equality relation, i.e. `==`, `.eq()`. + Eq, + /// Greater-or-equal relation, i.e. `>=`, `.gte()`. + Gte, + /// Greater-than relation, i.e. `>`, `.gt()`. + Gt, + /// Lesser-or-equal relation, i.e. `<=`, `.lte()`. + Lte, + /// Lesser-than relation, i.e. `<`, `.lt()`. + Lt, + /// Arithmetic modulo, i.e. `.mod()` + Mod, + /// Multiplication, i.e. `*`, `.mul()`. + Mul, + /// Wrapping multiplication, i.e. `.mul_wrapped()`. + MulWrapped, + /// Boolean NAND, i.e. `.nand()`. + Nand, + /// In-equality relation, i.e. `!=`, `.neq()`. + Neq, + /// Boolean NOR, i.e. `.nor()`. + Nor, + /// Logical OR, i.e. `||`. + Or, + /// Bitwise OR, i.e. `|`, `.or()`. + BitwiseOr, + /// Exponentiation, i.e. `**` in `a ** b`, `.pow()`. + Pow, + /// Wrapping exponentiation, i.e. `.pow_wrapped()`. + PowWrapped, + /// Remainder, i.e. `%`, `.rem()`. + Rem, + /// Wrapping remainder, i.e. `.rem_wrapped()`. + RemWrapped, + /// Shift left operation, i.e. `<<`, `.shl()`. + Shl, + /// Wrapping shift left operation, i.e. `.shl_wrapped()`. + ShlWrapped, + /// Shift right operation, i.e. >>, `.shr()`. + Shr, + /// Wrapping shift right operation, i.e. `.shr_wrapped()`. + ShrWrapped, + /// Subtraction, i.e. `-`, `.sub()`. + Sub, + /// Wrapped subtraction, i.e. `.sub_wrapped()`. + SubWrapped, + /// Bitwise XOR, i.e. `.xor()`. + Xor, +} + +/// A binary expression `left op right` of two operands separated by some operator. +/// For example, `foo + bar`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct BinaryExpression { + /// The left operand of the expression. + pub left: Box, + /// The right operand of the expression. + pub right: Box, + /// The operand defining the meaning of the resulting binary expression. + pub op: BinaryOperation, + /// The span from `left` to `right`. + pub span: Span, + /// The ID of the expression. + pub id: NodeID, +} + +crate::simple_node_impl!(BinaryExpression); diff --git a/compiler/cst/src/expressions/call.rs b/compiler/cst/src/expressions/call.rs new file mode 100644 index 0000000000..a2aeb5f7b2 --- /dev/null +++ b/compiler/cst/src/expressions/call.rs @@ -0,0 +1,23 @@ + + +use super::*; +use leo_span::Symbol; +use serde::{Deserialize, Serialize}; + +/// A function call expression, e.g.`foo(args)` or `Foo::bar(args)`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct CallExpression { + /// An expression evaluating to a callable function, + /// either a member of a structure or a free function. + pub function: Box, // todo: make this identifier? + /// Expressions for the arguments passed to the functions parameters. + pub arguments: Vec, + /// The name of the parent program call, e.g.`bar` in `bar.aleo`. + pub program: Option, + /// Span of the entire call `function(arguments)`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(CallExpression); diff --git a/compiler/cst/src/expressions/cast.rs b/compiler/cst/src/expressions/cast.rs new file mode 100644 index 0000000000..20a32f0218 --- /dev/null +++ b/compiler/cst/src/expressions/cast.rs @@ -0,0 +1,20 @@ + + +use super::*; +use serde::{Deserialize, Serialize}; +use crate::Type; + +/// A cast expression, e.g. `42u8 as u16`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct CastExpression { + /// The expression to be casted, e.g.`42u8` in `42u8 as u16`. + pub expression: Box, + /// The type to be casted to, e.g. `u16` in `42u8 as u16`. + pub type_: Type, + /// Span of the entire cast `42u8 as u16`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(CastExpression); diff --git a/compiler/cst/src/expressions/err.rs b/compiler/cst/src/expressions/err.rs new file mode 100644 index 0000000000..924c487327 --- /dev/null +++ b/compiler/cst/src/expressions/err.rs @@ -0,0 +1,15 @@ + + +use super::*; +use serde::{Deserialize, Serialize}; + +/// Represents a syntactically invalid expression. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ErrExpression { + /// The span of the invalid expression. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(ErrExpression); diff --git a/compiler/cst/src/expressions/literal.rs b/compiler/cst/src/expressions/literal.rs new file mode 100644 index 0000000000..1989595c9b --- /dev/null +++ b/compiler/cst/src/expressions/literal.rs @@ -0,0 +1,28 @@ + + +use crate::{GroupLiteral, IntegerType}; +use serde::{Deserialize, Serialize}; +use super::*; + +/// A literal. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum Literal { + // todo: deserialize values here + /// An address literal, e.g., `aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8s7pyjh9` or `hello.aleo`. + Address(String, #[serde(with = "leo_span::span_json")] Span, NodeID), + /// A boolean literal, either `true` or `false`. + Boolean(bool, #[serde(with = "leo_span::span_json")] Span, NodeID), + /// A field literal, e.g., `42field`. + /// A signed number followed by the keyword `field`. + Field(String, #[serde(with = "leo_span::span_json")] Span, NodeID), + /// A group literal, either product or affine. + /// For example, `42group` or `(12, 52)group`. + Group(Box), + /// An integer literal, e.g., `42`. + Integer(IntegerType, String, #[serde(with = "leo_span::span_json")] Span, NodeID), + /// A scalar literal, e.g. `1scalar`. + /// An unsigned number followed by the keyword `scalar`. + Scalar(String, #[serde(with = "leo_span::span_json")] Span, NodeID), + /// A string literal, e.g., `"foobar"`. + String(String, #[serde(with = "leo_span::span_json")] Span, NodeID), +} diff --git a/compiler/cst/src/expressions/locator.rs b/compiler/cst/src/expressions/locator.rs new file mode 100644 index 0000000000..09d1db802a --- /dev/null +++ b/compiler/cst/src/expressions/locator.rs @@ -0,0 +1,22 @@ + + +use leo_span::{Span, Symbol}; + +use crate::{simple_node_impl, Node, NodeID, ProgramId}; +use serde::{Deserialize, Serialize}; +use std::{fmt, hash::Hash}; + +/// A locator that references an external resource. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct LocatorExpression { + /// The program that the resource is in. + pub program: ProgramId, + /// The name of the resource. + pub name: Symbol, + /// A span indicating where the locator occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +simple_node_impl!(LocatorExpression); diff --git a/compiler/cst/src/expressions/mod.rs b/compiler/cst/src/expressions/mod.rs new file mode 100644 index 0000000000..508adcf505 --- /dev/null +++ b/compiler/cst/src/expressions/mod.rs @@ -0,0 +1,80 @@ + + +use crate::{Identifier, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +mod access; +pub use access::*; + +mod array; +pub use array::*; + +mod binary; +pub use binary::*; + +mod call; +pub use call::*; + +mod cast; +pub use cast::*; + +mod struct_init; +pub use struct_init::*; + +mod err; +pub use err::*; + +mod ternary; +pub use ternary::*; + +mod tuple; +pub use tuple::*; + +mod unary; +pub use unary::*; + +mod unit; +pub use unit::*; + +mod literal; +pub use literal::*; + +pub mod locator; +pub use locator::*; + +/// Expression that evaluates to a value. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum Expression { + /// A struct access expression, e.g. `Foo.bar`. + Access(AccessExpression), + /// An array expression, e.g., `[true, false, true, false]`. + Array(ArrayExpression), + /// A binary expression, e.g., `42 + 24`. + Binary(BinaryExpression), + /// A call expression, e.g., `my_fun(args)`. + Call(CallExpression), + /// A cast expression, e.g., `42u32 as u8`. + Cast(CastExpression), + /// An expression of type "error". + /// Will result in a compile error eventually. + Err(ErrExpression), + /// An identifier. + Identifier(Identifier), + /// A literal expression. + Literal(Literal), + /// A locator expression, e.g., `hello.aleo/foo`. + Locator(LocatorExpression), + /// An expression constructing a struct like `Foo { bar: 42, baz }`. + Struct(StructExpression), + /// A ternary conditional expression `cond ? if_expr : else_expr`. + Ternary(TernaryExpression), + /// A tuple expression e.g., `(foo, 42, true)`. + Tuple(TupleExpression), + /// An unary expression. + Unary(UnaryExpression), + /// A unit expression e.g. `()` + Unit(UnitExpression), +} diff --git a/compiler/cst/src/expressions/struct_init.rs b/compiler/cst/src/expressions/struct_init.rs new file mode 100644 index 0000000000..054cd00f0a --- /dev/null +++ b/compiler/cst/src/expressions/struct_init.rs @@ -0,0 +1,39 @@ + +use super::*; +use leo_span::sym; + +/// An initializer for a single field / variable of a struct initializer expression. +/// That is, in `Foo { bar: 42, baz }`, this is either `bar: 42`, or `baz`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct StructVariableInitializer { + /// The name of the field / variable to be initialized. + pub identifier: Identifier, + /// The expression to initialize the field with. + /// When `None`, a binding, in scope, with the name will be used instead. + pub expression: Option, + /// The span of the node. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(StructVariableInitializer); + +/// A struct initialization expression, e.g., `Foo { bar: 42, baz }`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct StructExpression { + /// The name of the structure type to initialize. + pub name: Identifier, + /// Initializer expressions for each of the fields in the struct. + /// + /// N.B. Any functions or member constants in the struct definition + /// are excluded from this list. + pub members: Vec, + /// A span from `name` to `}`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(StructExpression); diff --git a/compiler/cst/src/expressions/ternary.rs b/compiler/cst/src/expressions/ternary.rs new file mode 100644 index 0000000000..ae604a29fc --- /dev/null +++ b/compiler/cst/src/expressions/ternary.rs @@ -0,0 +1,20 @@ + + +use super::*; + +/// A ternary conditional expression, that is, `condition ? if_true : if_false`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TernaryExpression { + /// The condition determining which branch to pick. + pub condition: Box, + /// The branch the expression evaluates to if `condition` evaluates to true. + pub if_true: Box, + /// The branch the expression evaluates to if `condition` evaluates to false. + pub if_false: Box, + /// The span from `condition` to `if_false`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(TernaryExpression); diff --git a/compiler/cst/src/expressions/tuple.rs b/compiler/cst/src/expressions/tuple.rs new file mode 100644 index 0000000000..85ae868dec --- /dev/null +++ b/compiler/cst/src/expressions/tuple.rs @@ -0,0 +1,18 @@ + +use super::*; + +// TODO: Consider a restricted interface for constructing a tuple expression. + +/// A tuple expression, e.g., `(foo, false, 42)`. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TupleExpression { + /// The elements of the tuple. + /// In the example above, it would be `foo`, `false`, and `42`. + pub elements: Vec, + /// The span from `(` to `)`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(TupleExpression); diff --git a/compiler/cst/src/expressions/unary.rs b/compiler/cst/src/expressions/unary.rs new file mode 100644 index 0000000000..60bff05d6a --- /dev/null +++ b/compiler/cst/src/expressions/unary.rs @@ -0,0 +1,43 @@ + +use super::*; +use leo_span::{sym, Symbol}; + +/// A unary operator for a unary expression. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum UnaryOperation { + /// Absolute value checking for overflow, i.e. `.abs()`. + Abs, + /// Absolute value wrapping around at the boundary of the type, i.e. `.abs_wrapped()`. + AbsWrapped, + /// Double operation, i.e. `.double()`. + Double, + /// Multiplicative inverse, i.e. `.inv()`. + Inverse, + /// Negate operation, i.e. `.neg()`. + Negate, + /// Bitwise NOT, i.e. `!`, `.not()`. + Not, + /// Square operation, i.e. `.square()`. + Square, + /// Square root operation, i.e. `.sqrt()`. + SquareRoot, + /// Converts a group element to its x-coordinate, i.e. `.to_x_coordinate()`. + ToXCoordinate, + /// Converts a group element to its y-coordinate, i.e. `.to_y_coordinate()`. + ToYCoordinate, +} + +/// An unary expression applying an operator to an inner expression. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct UnaryExpression { + /// The inner expression `op` is applied to. + pub receiver: Box, + /// The unary operator to apply to `inner`. + pub op: UnaryOperation, + /// The span covering `op inner`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(UnaryExpression); diff --git a/compiler/cst/src/expressions/unit.rs b/compiler/cst/src/expressions/unit.rs new file mode 100644 index 0000000000..9e37ea218f --- /dev/null +++ b/compiler/cst/src/expressions/unit.rs @@ -0,0 +1,14 @@ + +use super::*; + +/// Represents a unit expression. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct UnitExpression { + /// The span of the unit expression. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + + +crate::simple_node_impl!(UnitExpression); diff --git a/compiler/cst/src/functions/annotation.rs b/compiler/cst/src/functions/annotation.rs new file mode 100644 index 0000000000..518101c06e --- /dev/null +++ b/compiler/cst/src/functions/annotation.rs @@ -0,0 +1,19 @@ +use crate::{simple_node_impl, Identifier, Node, NodeID}; + +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An annotation, e.g. @program. +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub struct Annotation { + // TODO: Consider using a symbol instead of an identifier. + /// The name of the annotation. + pub identifier: Identifier, + /// A span locating where the annotation occurred in the source. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +simple_node_impl!(Annotation); \ No newline at end of file diff --git a/compiler/cst/src/functions/input.rs b/compiler/cst/src/functions/input.rs new file mode 100644 index 0000000000..881dbebc1f --- /dev/null +++ b/compiler/cst/src/functions/input.rs @@ -0,0 +1,19 @@ + +use crate::{Identifier, Mode, Node, NodeID, Type}; +use leo_span::Span; +use serde::{Deserialize, Serialize}; + +/// A function parameter. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Input { + /// The name the parameter is accessible as in the function's body. + pub identifier: Identifier, + /// The mode of the function parameter. + pub mode: Mode, + /// What's the parameter's type? + pub type_: Type, + /// The parameters span from any annotations to its type. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} diff --git a/compiler/cst/src/functions/mod.rs b/compiler/cst/src/functions/mod.rs new file mode 100644 index 0000000000..e00e825430 --- /dev/null +++ b/compiler/cst/src/functions/mod.rs @@ -0,0 +1,117 @@ +pub mod mode; +use crate::Space; + +pub use self::mode::*; + +pub mod annotation; +pub use self::annotation::*; + +pub mod input; +pub use self::input::*; + +pub mod output; +pub use self::output::*; + +pub mod variant; +pub use self::variant::*; + +use crate::{Identifier, Type, Block}; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A function definition. +#[derive(Clone, Serialize, Deserialize)] +pub struct Function { + /// Annotations on the function. + pub annotations: Vec, + /// Is this function a transition, inlined, or a regular function?. + pub variant: Variant, + /// The function identifier, e.g., `foo` in `function foo(...) { ... }`. + pub identifier: Identifier, + /// The function's input parameters. + pub input: Vec, + /// The function's output declarations. + pub output: Vec, + /// The function's output type. + pub output_type: Type, + /// The body of the function. + pub block: Block, + /// The entire span of the function definition. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +/* +function compute(a: u64, b: u64) -> u64 {// ===> This part will be defined in cst/src/statement/block.rs + return a + b; +} +================================================================ + +Function { + annotations: vec![], + variant: Variant::Regular, + identifier: Identifier { + pl_name: Space::None, + name: "compute", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + input: vec![ + Input { + identifier: Identifier { + pl_name: Space::None, + name: "a", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + mode: Mode { + pl_name: Space::None, + name: ModeEnum.None, + pr_name: Space::None, + }, + type_: Type { + pl_name: Space::WhiteSpace(WhiteSpace(....)), + name: TypeEnum::Integer(IntegerType::U64), + pr_name: Space::None, + }, + span: Span { ... }, + id: NodeID { ... }, + }, + Input { + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace(....)), + name: "b", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + mode: Mode { + pl_name: Space::None, + name: ModeEnum.None, + pr_name: Space::None, + }, + type_: Type { + pl_name: Space::WhiteSpace(WhiteSpace(....)), + name: TypeEnum::Integer(IntegerType::U64), + pr_name: Space::None, + }, + span: Span { ... }, + id: NodeID { ... }, + }, + ], + output: vec![], + output_type: Type { + pl_name: Space::WhiteSpace(WhiteSpace(....)), + name: TypeEnum::Integer(IntegerType::U64), + pr_name: Space::WhiteSpace(WhiteSpace(....)), + }, + block: Block { ... }, + span: Span { ... }, + id: NodeID { ... }, +} + +*/ \ No newline at end of file diff --git a/compiler/cst/src/functions/mode.rs b/compiler/cst/src/functions/mode.rs new file mode 100644 index 0000000000..7729caf880 --- /dev/null +++ b/compiler/cst/src/functions/mode.rs @@ -0,0 +1,18 @@ +use serde::{Deserialize, Serialize}; + +use crate::Space; + +/// The mode associated with a type. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + +pub struct Mode { + pub pl_space: Space, + pub mode: ModeEnum, + pub pr_space: Space, +} +pub enum ModeEnum { + None, + Constant, + Private, + Public, +} \ No newline at end of file diff --git a/compiler/cst/src/functions/output.rs b/compiler/cst/src/functions/output.rs new file mode 100644 index 0000000000..d302bed557 --- /dev/null +++ b/compiler/cst/src/functions/output.rs @@ -0,0 +1,17 @@ +use crate::{Mode, Node, NodeID, Type}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// A function output. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Output { + /// The mode of the function output. + pub mode: Mode, + /// The type of the function output. + pub type_: Type, + /// The parameters span from any annotations to its type. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} \ No newline at end of file diff --git a/compiler/cst/src/functions/variant.rs b/compiler/cst/src/functions/variant.rs new file mode 100644 index 0000000000..34d4678311 --- /dev/null +++ b/compiler/cst/src/functions/variant.rs @@ -0,0 +1,16 @@ +use serde::{Deserialize, Serialize}; +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] + +pub struct Variant { + pub pl_name: Space, + pub name: VariantEnum, + pub pr_name: Space, +} + +pub enum VariantEnum { + Inline, + Function, + Transition, + AsyncTransition, + AsyncFunction, +} \ No newline at end of file diff --git a/compiler/cst/src/lib.rs b/compiler/cst/src/lib.rs new file mode 100644 index 0000000000..3890522b36 --- /dev/null +++ b/compiler/cst/src/lib.rs @@ -0,0 +1,32 @@ + +pub mod program; +pub use self::program::*; + +pub mod common; +pub use self::common::*; + +pub mod mapping; +pub use self::mapping::*; + +pub mod types; +pub use self::types::*; + +pub mod r#struct; +pub use self::r#struct::*; + +pub mod functions; +pub use self::functions::*; + +pub mod statement; +pub use self::statement::*; + +pub mod access; +pub use self::access::*; + +pub mod expressions; +pub use self::expressions::*; + +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct Cst { + pub cst: Program, +} \ No newline at end of file diff --git a/compiler/cst/src/mapping/mod.rs b/compiler/cst/src/mapping/mod.rs new file mode 100644 index 0000000000..87163cae66 --- /dev/null +++ b/compiler/cst/src/mapping/mod.rs @@ -0,0 +1,45 @@ + + +use crate::{Identifier, Node, NodeID, Type}; +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Mapping { + /// The name of the mapping. + pub identifier: Identifier, + /// The type of the key. + pub key_type: Type, + /// The type of the value. + pub value_type: Type, + /// The entire span of the mapping declaration. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +crate::simple_node_impl!(Mapping); + + +/* + mapping balances: address => u64; + ========================================================================================================== + Mapping { + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: "balances", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + key_type: Type { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: TypeEnum::Address, + pr_name: Space::WhiteSpace(WhiteSpace { ... }), + }, + value_type: Type { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: TypeEnum::Integer(IntegerType::U64), + pr_name: Space::WhiteSpace(WhiteSpace { ... }), + }, + span: Span { ... }, + id: NodeID { ... }, + } +*/ \ No newline at end of file diff --git a/compiler/cst/src/program/mod.rs b/compiler/cst/src/program/mod.rs new file mode 100644 index 0000000000..45bd3141d4 --- /dev/null +++ b/compiler/cst/src/program/mod.rs @@ -0,0 +1,71 @@ + +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +//! A Leo program consists of import statements and program scopes. +//! + +pub mod program_scope; +pub use program_scope::*; + +pub mod program_id; +pub use program_id::*; + +use crate::{Comment, ImportModule, Space}; + +use leo_span::{Span, Symbol}; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct Program { + body: Vec, +} + + +pub enum ProgramBox { + Import (ImportModule), + Space (Space), + Body (ProgramScope) +} +/* + import foo.aleo; + import hello.aleo; + + //hello + import aaa.aleo; + //hello world + /* + Test Program + */ + program abc.aleo { // this part will be defined in the program_scope.rs file + ... + } + ========================================================================================================== + + let program = Program { + body: vec![ + ProgramBox::Space(Space::Comment(Comment::Line("hello".to_string(), ...))), + ProgramBox::Import(ImportModule { ... aaa.aleo ...}), + ProgramBox::Space(Space::Comment(Comment::Line("hello world".to_string(), ...))), + ProgramBox::Space(Space::Comment(Comment::Block("Test Program".to_string(), ...))), + ProgramBox::Body(ProgramScope {...}), + ], + }; + + +*/ \ No newline at end of file diff --git a/compiler/cst/src/program/program_id.rs b/compiler/cst/src/program/program_id.rs new file mode 100644 index 0000000000..81886e3b9b --- /dev/null +++ b/compiler/cst/src/program/program_id.rs @@ -0,0 +1,10 @@ +use crate::Identifier; + + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct ProgramId { + /// The name of the program. + pub name: Identifier, + /// The network associated with the program. + pub network: Identifier, +} \ No newline at end of file diff --git a/compiler/cst/src/program/program_scope.rs b/compiler/cst/src/program/program_scope.rs new file mode 100644 index 0000000000..8fd4a4719b --- /dev/null +++ b/compiler/cst/src/program/program_scope.rs @@ -0,0 +1,58 @@ + + +use crate::{Comment, Composite, Function, ImportModule, Mapping, NewLine, Space, Tab, WhiteSpace, ProgramId}; +use leo_span::{Span, Symbol}; + + +#[derive(Debug, Clone)] +pub struct ProgramScope { + /// The program id of the program scope. + pub program_id: ProgramId, + pub body: Vec, + pub span: Span, +} +enum ProgramBody { + Mapping(Mapping), + Struct(Composite), + Function(Function), + Const((Symbol, ConstDeclaration)), + Space(Space) +} + +/* + program abc.aleo { + mapping balances: address => u64; // ===> This part will be defined in cst/src/mapping/mod.rs + + record token { // ===> This part will be defined in cst/src/struct/mod.rs + owner: address, + amount: u64, + } + + //hello world + struct message { + sender: address, + object: u64, + } + + function compute(a: u64, b: u64) -> u64 {// ===> This part will be defined in cst/src/functions/mod.rs + return a + b; + } + } + ========================================================================================================== + ProgramScope { + program_id: ProgramId { ... }, + body: vec![ + ProgramBody::Mapping(Mapping { ... }), + ProgramBody::Space(Space::WhiteSpace(WhiteSpace { ... })), + ProgramBody::Space(Space::Comment(Comment::Line(" ===> This part will be defined in cst/src/mapping/mod.rs".to_string(), ...))), + ProgramBody::Space(Space::NewLine(NewLine { ... })), + ProgramBody::Struct(Composite { ... record token ... }), + ProgramBody::Space(Space::NewLine(NewLine { ... })), + ProgramBody::Space(Space::Comment(Comment::Line("hello world".to_string(), ...))), + ProgramBody::Struct(Composite { ... struct message ... }), + ProgramBody::Space(Space::Comment(NewLine { ... })), + ProgramBody::Function(Function { ... function compute ... }) + ], + span: Span { ... }, + } +*/ \ No newline at end of file diff --git a/compiler/cst/src/statement/assert.rs b/compiler/cst/src/statement/assert.rs new file mode 100644 index 0000000000..de0dbbf03c --- /dev/null +++ b/compiler/cst/src/statement/assert.rs @@ -0,0 +1,28 @@ + + +use crate::{Expression, Node, NodeID}; +use leo_span::Span; +use serde::{Deserialize, Serialize}; + +/// A variant of an assert statement. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum AssertVariant { + /// A `assert(expr)` variant, asserting that the expression evaluates to true. + Assert(Expression), + /// A `assert_eq(expr1, expr2)` variant, asserting that the operands are equal. + AssertEq(Expression, Expression), + /// A `assert_neq(expr1, expr2)` variant, asserting that the operands are not equal. + AssertNeq(Expression, Expression), +} + +/// An assert statement, `assert()`, `assert_eq()` or `assert_neq()`. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct AssertStatement { + /// The variant of the assert statement. + pub variant: AssertVariant, + /// The span, excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +crate::simple_node_impl!(AssertStatement); diff --git a/compiler/cst/src/statement/assign.rs b/compiler/cst/src/statement/assign.rs new file mode 100644 index 0000000000..9fa06ddc16 --- /dev/null +++ b/compiler/cst/src/statement/assign.rs @@ -0,0 +1,23 @@ + +use crate::{Expression, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// An assignment statement, `assignee = value`. +/// Note that there is no operation associated with the assignment. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct AssignStatement { + /// The place to assign to. + /// Note that `place` can either be an identifier or tuple. + pub place: Expression, + /// The value to assign to the `assignee`. + pub value: Expression, + /// The span, excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(AssignStatement); diff --git a/compiler/cst/src/statement/block.rs b/compiler/cst/src/statement/block.rs new file mode 100644 index 0000000000..779f861d42 --- /dev/null +++ b/compiler/cst/src/statement/block.rs @@ -0,0 +1,63 @@ + + +use crate::{Comment, Node, NodeID, Space, Statement}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// A block `{ [stmt]* }` consisting of a list of statements to execute in order. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, Default)] +pub struct Block { + /// The list of statements to execute. + pub body: Vec, + /// The span from `{` to `}`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, + +} +enum BlockBody { + Space(Space), + Statement(Statement), +} + +crate::simple_node_impl!(Block); + +/* + function compute(a: u64, b: u64) -> u64 {// ===> This part will be defined in cst/src/statement/block.rs + return a + b; + } +================================================ + block: { + body: vec![ + BlockBody::Space(Space::Comment(Comment::Line("This part will be defined in cst/src/statement/block.rs", ...))) + BlockBody::Statement(Statement::Return { + value: Expression::Binary { + left: Expression::Identifier { + identifier: Identifier { + pl_name: Space::None, + name: "a", + pr_name: Space::WhiteSpace(WhiteSpace(....)), + span: Span { ... }, + id: NodeID { ... }, + }, + operator: Operator::Plus, + right: Expression::Identifier { + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace(....)), + name: "b", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + }, + }, + }), + }), + ], + span: Span { ... }, + id: NodeID { ... }, + }, + + +*/ \ No newline at end of file diff --git a/compiler/cst/src/statement/conditional.rs b/compiler/cst/src/statement/conditional.rs new file mode 100644 index 0000000000..6767f9b8df --- /dev/null +++ b/compiler/cst/src/statement/conditional.rs @@ -0,0 +1,24 @@ + + +use crate::{Block, Expression, Node, NodeID, Statement}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// An `if condition block (else next)?` statement. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct ConditionalStatement { + /// The `bool`-typed condition deciding what to evaluate. + pub condition: Expression, + /// The block to evaluate in case `condition` yields `true`. + pub then: Block, + /// The statement, if any, to evaluate when `condition` yields `false`. + pub otherwise: Option>, + /// The span from `if` to `next` or to `block`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(ConditionalStatement); diff --git a/compiler/cst/src/statement/console/console_function.rs b/compiler/cst/src/statement/console/console_function.rs new file mode 100644 index 0000000000..e71c2894b0 --- /dev/null +++ b/compiler/cst/src/statement/console/console_function.rs @@ -0,0 +1,41 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use crate::Expression; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A console logging function to invoke. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum ConsoleFunction { + /// A `console.assert(expr)` call to invoke, asserting that the expression evaluates to true. + Assert(Expression), + /// A `console.assert_eq(expr1, expr2)` call to invoke, asserting that the operands are equal. + AssertEq(Expression, Expression), + /// A `console.assert_neq(expr1, expr2)` call to invoke, asserting that the operands are not equal. + AssertNeq(Expression, Expression), +} + +impl fmt::Display for ConsoleFunction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ConsoleFunction::Assert(expr) => write!(f, "assert({expr})"), + ConsoleFunction::AssertEq(expr1, expr2) => write!(f, "assert_eq({expr1}, {expr2})"), + ConsoleFunction::AssertNeq(expr1, expr2) => write!(f, "assert_neq({expr1}, {expr2})"), + } + } +} diff --git a/compiler/cst/src/statement/console/console_statement.rs b/compiler/cst/src/statement/console/console_statement.rs new file mode 100644 index 0000000000..f305510a32 --- /dev/null +++ b/compiler/cst/src/statement/console/console_statement.rs @@ -0,0 +1,46 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use crate::{ConsoleFunction, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A console logging statement like `console.log(...);`. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct ConsoleStatement { + /// The logging function to run. + pub function: ConsoleFunction, + /// The span excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +impl fmt::Display for ConsoleStatement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "console.{};", self.function) + } +} + +impl fmt::Debug for ConsoleStatement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "console.{};", self.function) + } +} + +crate::simple_node_impl!(ConsoleStatement); diff --git a/compiler/cst/src/statement/console/mod.rs b/compiler/cst/src/statement/console/mod.rs new file mode 100644 index 0000000000..02dec1bb1c --- /dev/null +++ b/compiler/cst/src/statement/console/mod.rs @@ -0,0 +1,21 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +pub mod console_function; +pub use console_function::*; + +pub mod console_statement; +pub use console_statement::*; diff --git a/compiler/cst/src/statement/const_.rs b/compiler/cst/src/statement/const_.rs new file mode 100644 index 0000000000..66e47f0338 --- /dev/null +++ b/compiler/cst/src/statement/const_.rs @@ -0,0 +1,37 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use crate::{Expression, Identifier, Node, NodeID, Type}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// A constant declaration statement. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct ConstDeclaration { + /// The place to assign to. As opposed to `DefinitionStatement`, this can only be an identifier + pub place: Identifier, + /// The type of the binding, if specified, or inferred otherwise. + pub type_: Type, + /// An initializer value for the binding. + pub value: Expression, + /// The span excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(ConstDeclaration); diff --git a/compiler/cst/src/statement/definition/declaration_type.rs b/compiler/cst/src/statement/definition/declaration_type.rs new file mode 100644 index 0000000000..d737b5355d --- /dev/null +++ b/compiler/cst/src/statement/definition/declaration_type.rs @@ -0,0 +1,36 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// The sort of bindings to introduce, either `let` or `const`. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum DeclarationType { + /// This is a `const` binding. + Const, + /// This is a `let` binding. + Let, +} + +impl fmt::Display for DeclarationType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + DeclarationType::Const => write!(f, "const"), + DeclarationType::Let => write!(f, "let"), + } + } +} diff --git a/compiler/cst/src/statement/definition/mod.rs b/compiler/cst/src/statement/definition/mod.rs new file mode 100644 index 0000000000..aaf67a5202 --- /dev/null +++ b/compiler/cst/src/statement/definition/mod.rs @@ -0,0 +1,52 @@ +// Copyright (C) 2019-2023 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library 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. + +// The Leo library 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 the Leo library. If not, see . + +use crate::{Expression, Node, NodeID, Type}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +mod declaration_type; +pub use declaration_type::*; + +/// A `let` or `const` declaration statement. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct DefinitionStatement { + /// What sort of declaration is this? `let` or `const`?. + pub declaration_type: DeclarationType, + /// The bindings / variable names to declare. + pub place: Expression, + /// The types of the bindings, if specified, or inferred otherwise. + pub type_: Type, + /// An initializer value for the bindings. + pub value: Expression, + /// The span excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +impl fmt::Display for DefinitionStatement { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} ", self.declaration_type)?; + write!(f, "{}", self.place)?; + write!(f, ": {}", self.type_)?; + write!(f, " = {};", self.value) + } +} + +crate::simple_node_impl!(DefinitionStatement); diff --git a/compiler/cst/src/statement/expression.rs b/compiler/cst/src/statement/expression.rs new file mode 100644 index 0000000000..008d6b6814 --- /dev/null +++ b/compiler/cst/src/statement/expression.rs @@ -0,0 +1,18 @@ + +use crate::{Expression, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// An expression statement, `foo(a);`. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct ExpressionStatement { + /// The expression associated with the statement. + pub expression: Expression, + /// The span. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(ExpressionStatement); diff --git a/compiler/cst/src/statement/iteration.rs b/compiler/cst/src/statement/iteration.rs new file mode 100644 index 0000000000..f5f573fe77 --- /dev/null +++ b/compiler/cst/src/statement/iteration.rs @@ -0,0 +1,37 @@ + +use crate::{Block, Expression, Identifier, Node, NodeID, Type, Value}; + +use leo_span::Span; + +use serde::{Deserialize, Serialize}; +use std::{cell::RefCell, fmt}; + +/// A bounded `for` loop statement `for variable in start .. =? stop block`. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct IterationStatement { + /// The binding / variable to introduce in the body `block`. + pub variable: Identifier, + /// The type of the iteration. + pub type_: Type, + /// The start of the iteration. + pub start: Expression, + /// The concrete value of `start`. + #[serde(skip)] + pub start_value: RefCell>, + /// The end of the iteration, possibly `inclusive`. + pub stop: Expression, + /// The concrete value of `stop`. + #[serde(skip)] + pub stop_value: RefCell>, + /// Whether `stop` is inclusive or not. + /// Signified with `=` when parsing. + pub inclusive: bool, + /// The block to run on each iteration. + pub block: Block, + /// The span from `for` to `block`. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(IterationStatement); diff --git a/compiler/cst/src/statement/mod.rs b/compiler/cst/src/statement/mod.rs new file mode 100644 index 0000000000..bfd4d0b88e --- /dev/null +++ b/compiler/cst/src/statement/mod.rs @@ -0,0 +1,62 @@ + + +pub mod assert; +pub use assert::*; + +pub mod assign; +pub use assign::*; + +pub mod block; +pub use block::*; + +pub mod conditional; +pub use conditional::*; + +pub mod console; +pub use console::*; + +pub mod const_; +pub use const_::*; + +pub mod definition; +pub use definition::*; + +pub mod expression; +pub use expression::*; + +pub mod iteration; +pub use iteration::*; + +pub mod return_; +pub use return_::*; + +use crate::{Node, NodeID}; + +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// Program statement that defines some action (or expression) to be carried out. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum Statement { + /// An assert statement. + Assert(AssertStatement), + /// An assignment statement. + Assign(Box), + /// A block statement. + Block(Block), + /// An `if` statement. + Conditional(ConditionalStatement), + /// A console logging statement. + Console(ConsoleStatement), + /// A binding from identifier to constant value. + Const(ConstDeclaration), + /// A binding or set of bindings / variables to declare. + Definition(DefinitionStatement), + /// An expression statement + Expression(ExpressionStatement), + /// A `for` statement. + Iteration(Box), + /// A return statement `return expr;`. + Return(ReturnStatement), +} diff --git a/compiler/cst/src/statement/return_.rs b/compiler/cst/src/statement/return_.rs new file mode 100644 index 0000000000..c77244d0a3 --- /dev/null +++ b/compiler/cst/src/statement/return_.rs @@ -0,0 +1,19 @@ + + +use crate::{Expression, Node, NodeID}; +use leo_span::Span; + +use serde::{Deserialize, Serialize}; + +/// A return statement `return expression;`. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct ReturnStatement { + /// The expression to return to the function caller. + pub expression: Expression, + /// The span of `return expression` excluding the semicolon. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} + +crate::simple_node_impl!(ReturnStatement); diff --git a/compiler/cst/src/struct/member.rs b/compiler/cst/src/struct/member.rs new file mode 100644 index 0000000000..a2a8cce1fe --- /dev/null +++ b/compiler/cst/src/struct/member.rs @@ -0,0 +1,40 @@ +use crate::{Identifier, Mode, Node, NodeID, Type, Space}; + +use leo_span::{Span, Symbol}; + +use serde::{Deserialize, Serialize}; + +/// A member of a structured data type, e.g `foobar: u8` or `private baz: bool` . +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Member { + /// The mode of the member. + pub mode: Mode, + /// The identifier of the member. + pub identifier: Identifier, + /// The type of the member. + pub type_: Type, + /// The span of the member. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +crate::simple_node_impl!(Member); + +/* + owner: address, + ======================== + Member { + mode: Mode::Public, + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: "owner", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + type_: Type::Address, + span: Span { ... }, + id: NodeID { ... }, + } + +*/ \ No newline at end of file diff --git a/compiler/cst/src/struct/mod.rs b/compiler/cst/src/struct/mod.rs new file mode 100644 index 0000000000..10cf470a6a --- /dev/null +++ b/compiler/cst/src/struct/mod.rs @@ -0,0 +1,81 @@ +pub mod member; +pub use member::*; + +use crate::{Identifier, Mode, Node, NodeID, Space, Type}; +use serde::{Deserialize, Serialize}; +#[derive(Clone, Serialize, Deserialize)] +pub struct Composite { + /// The name of the type in the type system in this module. + pub identifier: Identifier, + /// The fields, constant variables, and functions of this structure. + pub body: Vec, + /// The external program the struct is defined in. + pub external: Option, + /// Was this a `record Foo { ... }`? + /// If so, it wasn't a composite. + pub is_record: bool, + /// The entire span of the composite definition. + pub span: Span, + /// The ID of the node. + pub id: NodeID, +} +enum CompositeBody { + Member(Member), + Space(Space), +} +crate::simple_node_impl!(Composite); + + +/* + record token { // ===> This part will be defined in member.rs + owner: address, + + //amount value + amount: u64, + } + + ========================================================================================================== + Composite { + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: "token", + pr_name: Space::WhiteSpace(WhiteSpace { ... }), + span: Span { ... }, + id: NodeID { ... }, + }, + body: vec![ + Member { + mode: Mode::Public, + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: "owner", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + type_: Type::Address, + span: Span { ... }, + id: NodeID { ... }, + }, + Space::NewLine(NewLine { ... }), + Space::Comment(Comment::Line("amount value", ...)), + Member { + mode: Mode::Public, + identifier: Identifier { + pl_name: Space::WhiteSpace(WhiteSpace { ... }), + name: "amount", + pr_name: Space::None, + span: Span { ... }, + id: NodeID { ... }, + }, + type_: Type::U64, + span: Span { ... }, + id: NodeID { ... }, + }, + ] + external: None, + is_record: true, + span: Span { ... }, + id: NodeID { ... }, + } +*/ diff --git a/compiler/cst/src/types/array.rs b/compiler/cst/src/types/array.rs new file mode 100644 index 0000000000..cb8e8c9683 --- /dev/null +++ b/compiler/cst/src/types/array.rs @@ -0,0 +1,8 @@ +use crate::{NonNegativeNumber, Type}; +use serde::{Deserialize, Serialize}; +/// An array type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct ArrayType { + element_type: Box, + length: NonNegativeNumber, +} \ No newline at end of file diff --git a/compiler/cst/src/types/core_constant.rs b/compiler/cst/src/types/core_constant.rs new file mode 100644 index 0000000000..423358af0e --- /dev/null +++ b/compiler/cst/src/types/core_constant.rs @@ -0,0 +1,5 @@ +/// A core constant that maps directly to an AVM bytecode constant. +#[derive(Clone, PartialEq, Eq)] +pub enum CoreConstant { + GroupGenerator, +} diff --git a/compiler/cst/src/types/future.rs b/compiler/cst/src/types/future.rs new file mode 100644 index 0000000000..37e9619bb4 --- /dev/null +++ b/compiler/cst/src/types/future.rs @@ -0,0 +1,13 @@ +use crate::{Location, Type}; +use serde::{Deserialize, Serialize}; + +/// A future type consisting of the type of the inputs. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct FutureType { + // Optional type specification of inputs. + pub inputs: Vec, + // The location of the function that produced the future. + pub location: Option, + // Whether or not the type has been explicitly specified. + pub is_explicit: bool, +} \ No newline at end of file diff --git a/compiler/cst/src/types/integer_type.rs b/compiler/cst/src/types/integer_type.rs new file mode 100644 index 0000000000..3cfc34be5b --- /dev/null +++ b/compiler/cst/src/types/integer_type.rs @@ -0,0 +1,17 @@ + +use serde::{Deserialize, Serialize}; +/// Explicit integer type. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum IntegerType { + U8, + U16, + U32, + U64, + U128, + + I8, + I16, + I32, + I64, + I128, +} \ No newline at end of file diff --git a/compiler/cst/src/types/mapping.rs b/compiler/cst/src/types/mapping.rs new file mode 100644 index 0000000000..37df1d0a13 --- /dev/null +++ b/compiler/cst/src/types/mapping.rs @@ -0,0 +1,12 @@ +use crate::Type; + +use leo_span::Symbol; +use serde::{Deserialize, Serialize}; + +/// A mapping type of a key and value type. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct MappingType { + pub key: Box, + pub value: Box, + pub program: Symbol, +} \ No newline at end of file diff --git a/compiler/cst/src/types/mod.rs b/compiler/cst/src/types/mod.rs new file mode 100644 index 0000000000..5ca4f20460 --- /dev/null +++ b/compiler/cst/src/types/mod.rs @@ -0,0 +1,23 @@ +pub mod array; +pub use array::*; + +pub mod core_constant; +pub use core_constant::*; + +pub mod future; +pub use future::*; + +pub mod integer_type; +pub use integer_type::*; + +pub mod mapping; +pub use mapping::*; + +pub mod struct_type; +pub use struct_type::*; + +pub mod tuple; +pub use tuple::*; + +pub mod type_; +pub use type_::*; \ No newline at end of file diff --git a/compiler/cst/src/types/struct_type.rs b/compiler/cst/src/types/struct_type.rs new file mode 100644 index 0000000000..1bc90dce6a --- /dev/null +++ b/compiler/cst/src/types/struct_type.rs @@ -0,0 +1,14 @@ + +use crate::Identifier; + +use leo_span::Symbol; +use serde::{Deserialize, Serialize}; + +/// A composite type of a identifier and external program name. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Copy)] +pub struct CompositeType { + // The identifier of the composite definition. + pub id: Identifier, + // The external program that this composite is defined in. + pub program: Option, +} \ No newline at end of file diff --git a/compiler/cst/src/types/tuple.rs b/compiler/cst/src/types/tuple.rs new file mode 100644 index 0000000000..92c409b020 --- /dev/null +++ b/compiler/cst/src/types/tuple.rs @@ -0,0 +1,9 @@ +use crate::Type; + +use serde::{Deserialize, Serialize}; + +/// A type list of at least two types. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct TupleType { + elements: Vec, +} \ No newline at end of file diff --git a/compiler/cst/src/types/type_.rs b/compiler/cst/src/types/type_.rs new file mode 100644 index 0000000000..97d9bba1c5 --- /dev/null +++ b/compiler/cst/src/types/type_.rs @@ -0,0 +1,44 @@ +use crate::{common, ArrayType, CompositeType, FutureType, Identifier, IntegerType, MappingType, Space, TupleType}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] + +pub struct Type { + pub pl_name: Space, + name: TypeEnum, + pub pr_name: Space, +} +pub enum TypeEnum { + /// The `address` type. + Address, + /// The array type. + Array(ArrayType), + /// The `bool` type. + Boolean, + /// The `struct` type. + Composite(CompositeType), + /// The `field` type. + Field, + /// The `future` type. + Future(FutureType), + /// The `group` type. + Group, + /// A reference to a built in type. + Identifier(Identifier), + /// An integer type. + Integer(IntegerType), + /// A mapping type. + Mapping(MappingType), + /// The `scalar` type. + Scalar, + /// The `signature` type. + Signature, + /// The `string` type. + String, + /// A static tuple of at least one type. + Tuple(TupleType), + /// The `unit` type. + Unit, + /// Placeholder for a type that could not be resolved or was not well-formed. + /// Will eventually lead to a compile error. + Err, +} \ No newline at end of file