commit 0b664bea7b06c53222bece61c6d68598f613573a Author: CrossNox Date: Sat Nov 26 22:07:19 2022 -0300 rust int init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d956ab0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/target +/classes +/checkouts +profiles.clj +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port +/.prepl-port +.hgignore +.hg/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b038051 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Change Log +All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). + +## [Unreleased] +### Changed +- Add a new arity to `make-widget-async` to provide a different widget shape. + +## [0.1.1] - 2022-11-26 +### Changed +- Documentation on how to make the widgets. + +### Removed +- `make-widget-sync` - we're all async, all the time. + +### Fixed +- Fixed widget maker to keep working when daylight savings switches over. + +## 0.1.0 - 2022-11-26 +### Added +- Files from the new template. +- Widget maker public API - `make-widget-sync`. + +[Unreleased]: https://sourcehost.site/your-name/rustint/compare/0.1.1...HEAD +[0.1.1]: https://sourcehost.site/your-name/rustint/compare/0.1.0...0.1.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2315126 --- /dev/null +++ b/LICENSE @@ -0,0 +1,280 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public +License as published by the Free Software Foundation, either version 2 +of the License, or (at your option) any later version, with the GNU +Classpath Exception which is available at +https://www.gnu.org/software/classpath/license.html." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae34286 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# rustint + +FIXME: description + +## Installation + +Download from http://example.com/FIXME. + +## Usage + +FIXME: explanation + + $ java -jar rustint-0.1.0-standalone.jar [args] + +## Options + +FIXME: listing of options this app accepts. + +## Examples + +... + +### Bugs + +... + +### Any Other Sections +### That You Think +### Might be Useful + +## License + +Copyright © 2022 FIXME + +This program and the accompanying materials are made available under the +terms of the Eclipse Public License 2.0 which is available at +http://www.eclipse.org/legal/epl-2.0. + +This Source Code may also be made available under the following Secondary +Licenses when the conditions for such availability set forth in the Eclipse +Public License, v. 2.0 are satisfied: GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or (at your +option) any later version, with the GNU Classpath Exception which is available +at https://www.gnu.org/software/classpath/license.html. diff --git a/doc/intro.md b/doc/intro.md new file mode 100644 index 0000000..aedb8aa --- /dev/null +++ b/doc/intro.md @@ -0,0 +1,3 @@ +# Introduction to rustint + +TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..154540b --- /dev/null +++ b/project.clj @@ -0,0 +1,10 @@ +(defproject rustint "0.1.0-SNAPSHOT" + :description "Interprete de Rust" + :url "http://example.com/FIXME" + :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" + :url "https://www.eclipse.org/legal/epl-2.0/"} + :dependencies [[org.clojure/clojure "1.11.1"]] + :main ^:skip-aot rustint.core + :target-path "target/%s" + :profiles {:uberjar {:aot :all + :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}) diff --git a/src/rustint/core.clj b/src/rustint/core.clj new file mode 100644 index 0000000..9a6f5e2 --- /dev/null +++ b/src/rustint/core.clj @@ -0,0 +1,2244 @@ +(ns rustint.core + (:gen-class)) + +(declare driver-loop) +(declare escanear-arch) +(declare listar) +(declare buscar-mensaje) +(declare agregar-ptocoma) +(declare escanear) +(declare dar-error) +(declare parsear) +(declare simb-actual) +(declare simb-no-parseados-aun) +(declare simb-ya-parseados) +(declare estado) +(declare contexto) +(declare prox-var) +(declare bytecode) +(declare mapa-regs-de-act) +(declare palabra-reservada?) +(declare booleano?) +(declare numero?) +(declare identificador?) +(declare cadena?) +(declare procesar-terminal) +(declare generar) +(declare dump) +(declare ya-declarado-localmente?) +(declare controlar-duplicado) +(declare buscar-coincidencias) +(declare verificar-que-sea) +(declare verificar-que-sea-var) +(declare verificar-que-sea-var-mut) +(declare verificar-que-sea-var-ref) +(declare verificar-que-sea-fn) +(declare verificar-que-sea-string) +(declare verificar-que-sea-const-o-var) +(declare cargar-lib-en-tabla) +(declare cargar-const-en-tabla) +(declare cargar-fn-en-tabla) +(declare cargar-var-mut-en-tabla) +(declare cargar-var-inmut-en-tabla) +(declare inicializar-contexto-global) +(declare inicializar-contexto-local) +(declare restaurar-contexto-anterior) +(declare preparar-mapa-regs-de-act) +(declare programa) +(declare procesar-opcional-declaraciones-use) +(declare procesar-opcional-declaraciones-const) +(declare procesar-opciones-use-std) +(declare procesar-opcional-en-std-io) +(declare declaracion-use) +(declare declaracion-const) +(declare procesar-mas-param) +(declare procesar-tipo-param) +(declare procesar-opcional-mut-param) +(declare declarar-opcional-param) +(declare procesar-tipo-retorno) +(declare declarar-mas-fn) +(declare cargar-params-en-tabla) +(declare hacer-fixup-si-es-main) +(declare hace-push-implicito?) +(declare buscar-tipo-de-retorno) +(declare confirmar-retorno) +(declare confirmar-no-retorno) +(declare declarar-opcional-tipo-retorno) +(declare declarar-fn) +(declare procesar-declaraciones-fn) +(declare procesar-mas-opcional-bloque) +(declare procesar-opcional-mut-let) +(declare procesar-tipo-const) +(declare procesar-opcional-asignacion) +(declare procesar-tipo-variable) +(declare procesar-opcional-bloque) +(declare bloque) +(declare procesar-stdout-stdin) +(declare procesar-opcional-expresiones-a-imprimir) +(declare generar-pushfi-cadena) +(declare procesar-opcional-cadena-expresiones-a-imprimir) +(declare procesar-string-new-from) +(declare procesar-string-punto-as-str-trim) +(declare procesar-to-string) +(declare procesar-parse) +(declare procesar-string-punto-to-string-parse) +(declare procesar-trim) +(declare procesar-as-str) +(declare procesar-opcional-string-punto) +(declare procesar-tipo-as) +(declare procesar-opcional-as) +(declare procesar-f64-funcion) +(declare procesar-ident-punto-parse-to-string) +(declare procesar-ident-punto) +(declare procesar-opcional-as-punto) +(declare procesar-mas-opcional-expresion) +(declare procesar-opcional-expresion) +(declare generar-factor-const-o-var) +(declare procesar-opcional-asignacion-llamada) +(declare generar-ref) +(declare expresion-atomica) +(declare expresion-unaria) +(declare procesar-mas-expresion-unaria) +(declare expresion-multiplicativa) +(declare procesar-mas-expresion-multiplicativa) +(declare expresion-aditiva) +(declare procesar-mas-expresion-aditiva) +(declare expresion-relacional) +(declare procesar-mas-expresion-relacional) +(declare expresion-igualdad) +(declare procesar-mas-expresion-igualdad) +(declare expresion-and) +(declare procesar-mas-expresion-and) +(declare expresion) +(declare fixup) +(declare generar-operador-relacional) +(declare generar-con-valor) +(declare convertir-formato-impresion) +(declare dividir) +(declare aplicar-operador-monadico) +(declare aplicar-operador-diadico) +(declare compatibles?) +(declare pasar-a-int) +(declare pasar-a-float) +(declare cargar-en-ult-reg) +(declare cargar-en-reg-dest) +(declare asignar-aritmetico) +(declare asignar-aritmetico-ref) +(declare params-args) +(declare generar-print!) +(declare generar-format!) +(declare interpretar) + +(defn driver-loop + ([] + (prn) + (println "Interprete de RUST en Clojure") + (println "Trabajo Practico de 75.14/95.48 - Lenguajes Formales - 2022") + (println) + (println "Inspirado en: rustc 1.64.0 (2022-09-22)") + (prn) + (println "Lista de comandos posibles:") + (println "AYUDA: volver a este menu") + (println "SALIR: volver al REPL de Clojure") + (println "ESCAN : mostrar los tokens de un programa escrito en Rust") + (println "VIRTU : mostrar la RI de un programa escrito en Rust") + (println "INTER : interpretar la RI de un programa escrito en Rust") + (prn) + (driver-loop :iniciado)) + ([status] + (print "Rust> ") (flush) + (try (let [linea (clojure.string/split (clojure.string/trim (read-line)) #" "), + cabeza (clojure.string/upper-case (first linea))] + (cond + (= cabeza "SALIR") 'CHAU + (= cabeza "AYUDA") (driver-loop) + (= cabeza "ESCAN") (let [nom (second linea)] + (if (not (.exists (clojure.java.io/file nom))) + (do (print "ERROR: ") (println (buscar-mensaje 2) (str (symbol "(") nom (symbol ")"))) (flush) (driver-loop status)) + (do (listar (escanear-arch nom)) (driver-loop status)))) + (= cabeza "VIRTU") (let [nom (second linea)] + (if (not (.exists (clojure.java.io/file nom))) + (do (print "ERROR: ") (println (buscar-mensaje 2)) (flush) (driver-loop status)) + (let [res (parsear (agregar-ptocoma (escanear-arch nom)))] + (do (if (= (estado res) :sin-errores) + (dump (bytecode res))) + (driver-loop status))))) + (= cabeza "INTER") (let [nom (second linea)] + (if (not (.exists (clojure.java.io/file nom))) + (do (print "ERROR: ") (println (buscar-mensaje 2)) (flush) (driver-loop status)) + (let [res (parsear (agregar-ptocoma (escanear-arch nom)))] + (do (if (= (estado res) :sin-errores) + (interpretar (bytecode res) [] 0 [] (mapa-regs-de-act res))) + ; IMPORTANTE + ; Este es el AMBIENTE inicial del interprete en su fase interpretativa. + ; [cod regs-de-act cont-prg pila mapa-regs] + (driver-loop status))))) + (= cabeza "") (driver-loop status) + :else (do (print "ERROR: ") (println (buscar-mensaje 1) (str (symbol "(") (first linea) (symbol ")"))) (flush) (driver-loop status)))) + (catch Exception e (println "ERROR ->" (clojure.string/trim (clojure.string/upper-case (let [msg-err (get (Throwable->map e) :cause)] (if (nil? msg-err) "desconocido" msg-err))))) (driver-loop status)))) +) + +(defn escanear-arch [nom] + (map #(let [aux (try (clojure.edn/read-string %) (catch Exception e (symbol %)))] (if (or (number? aux) (string? aux) (instance? Boolean aux)) aux (symbol %))) + (remove empty? (with-open [rdr (clojure.java.io/reader nom)] + (flatten (doall (map #(re-seq #"print!|println!|format!|\:\:|\<\=|\>\=|\-\>|\=\=|\!\=|\+\=|\-\=|\*\=|\/\=|\%\=|\&\&|\|\||\<|\>|\=|\(|\)|\,|\;|\+|\-|\*|\/|\[|\]|\{|\}|\%|\&|\!|\:|\"[^\"]*\"|\d+\.\d+E[+-]?\d+|\d+\.E[+-]?\d+|\.\d+E[+-]?\d+|\d+E[+-]?\d+|\d+\.\d+|\d+\.|\.\d+|\.|\d+|\_[A-Za-z0-9\_]+|[A-Za-z][A-Za-z0-9\_]*|\.|\'|\"|\||\#|\$|\@|\?|\^|\\|\~" %) (line-seq rdr))))))) +) + +(defn buscar-mensaje [cod] + (case cod + 1 "COMANDO DESCONOCIDO" + 2 "ARCHIVO NO ENCONTRADO" + 3 "SE ENCONTRO PREMATURAMENTE EL FIN DEL ARCHIVO: EOF" + 4 "SE ESPERABA std" + 5 "SE ESPERABA UN OPERADOR DE RESOLUCION DE AMBITO: ::" + 6 "SE ESPERABA LA PALABRA RESERVADA io" + 7 "SE ESPERABA UNA DE LAS PALABRAS RESERVADAS Write O process" + 8 "SE ESPERABA UN PUNTO Y COMA: ;" + 9 "SE ESPERABA UN IGUAL: =" + 10 "SE ESPERABA UN IDENTIFICADOR" + 11 "SE ESPERABA ABRIR UN PARENTESIS: (" + 12 "SE ESPERABA CERRAR UN PARENTESIS: )" + 13 "SE ESPERABA UN TIPO DE RETORNO: i64, f64, bool O String" + 14 "SE ESPERABAN DOS PUNTOS: :" + 15 "SE ESPERABA UN TIPO DE PARAMETRO: i64 O f64" + 16 "SE ESPERABA LA PALABRA RESERVADA mut" + 17 "SE ESPERABA ABRIR UNA LLAVE: {" + 18 "SE ESPERABA UN PUNTO Y COMA O CERRAR UNA LLAVE: ; O }" + 19 "SE ESPERABA UN TIPO DE VARIABLE: i64, f64, bool, char O String" + 20 "SE ESPERABA UN TIPO DE CONSTANTE: i64 O f64" + 21 "SE ESPERABA UN INICIO DE EXPRESION" + 22 "SE ESPERABA LA PALABRA RESERVADA exit" + 23 "SE ESPERABA UN PUNTO: ." + 24 "SE ESPERABA LA PALABRA RESERVADA expect" + 25 "SE ESPERABA UNA CADENA" + 26 "SE ESPERABA UNA DE LAS PALABRAS RESERVADAS stdin O stdout" + 27 "SE ESPERABA LA PALABRA RESERVADA flush" + 28 "SE ESPERABA LA PALABRA RESERVADA read_line" + 29 "SE ESPERABA UN AMPERSAND: &" + 30 "SE ESPERABA UN IDENTIFICADOR O LA PALABRA RESERVADA mut" + 31 "SE ESPERABA LA PALABRA RESERVADA chars" + 32 "SE ESPERABA LA PALABRA RESERVADA nth" + 33 "SE ESPERABA LA PALABRA RESERVADA unwrap" + 34 "SE ESPERABA UNA DE LAS PALABRAS RESERVADAS new O from" + 35 "SE ESPERABA UNA DE LAS PALABRAS RESERVADAS as_str O trim" + 36 "SE ESPERABA UNA DE LAS PALABRAS RESERVADAS to_string O parse" + 37 "SE ESPERABA UN TIPO NUMERICO: i64, f64 O usize" + 38 "SE ESPERABA UNA FUNCION MATEMATICA: sqrt, sin, atan O abs" + 39 "SE ESPERABA UN NUMERO" + 40 "SE ESPERABA LA PALABRA RESERVADA fn" + 41 "DECLARACION DUPLICADA DE IDENTIFICADOR DE BIBLIOTECA, CONSTANTE O FUNCION" + 42 "IDENTIFICADOR NO DECLARADO" + 43 "SE ESPERABA UN IDENTIFICADOR DE VARIABLE" + 44 "SE ESPERABA UN IDENTIFICADOR DE VARIABLE MUTABLE" + 45 "SE ESPERABA UN IDENTIFICADOR DE FUNCION" + 46 "SE ESPERABA UN IDENTIFICADOR DE CONSTANTE O VARIABLE" + 47 "SE ESPERABA QUE LA FUNCION RETORNE UN VALOR" + 48 "SE ESPERABA QUE LA FUNCION NO RETORNE NINGUN VALOR" + 49 "SE ESPERABA UNA COMA O CERRAR UN PARENTESIS: , O )" + 50 "TIPOS INCOMPATIBLES" + 51 "SE ESPERABA UN IDENTIFICADOR DE VARIABLE DE TIPO String" + 52 "SE ESPERABA ABRIR UN CORCHETE ANGULAR: <" + 53 "SE ESPERABA CERRAR UN CORCHETE ANGULAR: >" + 54 "SE ESPERABA UN IDENTIFICADOR DE PUNTERO" + 55 "FALLO EN UNA OPERACION MONADICA" + 56 "FALLO EN UNA OPERACION DIADICA" + cod) +) + +(defn escanear [amb] + (if (= (estado amb) :sin-errores) + [(let [simb (first (simb-no-parseados-aun amb))] + (if (nil? simb) 'EOF simb)) (rest (simb-no-parseados-aun amb)) (conj (simb-ya-parseados amb) (simb-actual amb)) (estado amb) (contexto amb) (prox-var amb) (bytecode amb) (mapa-regs-de-act amb)] + amb) +) + +(defn dar-error [amb cod] + (if (= (estado amb) :sin-errores) + (do (prn) + (println "ERROR AL INTERPRETAR EL PROGRAMA!") + (println "*********************************") + (prn) + (listar (simb-ya-parseados amb)) + (prn) (println ">") (println ">>" (buscar-mensaje cod)) (println ">") (prn) + (pr (simb-actual amb)) (print " ") + (listar (simb-no-parseados-aun amb)) (prn) + (flush) + [(simb-actual amb) '() (simb-ya-parseados amb) cod]) + amb) +) + +(defn parsear [tokens] + (let [simbolo-inicial (first tokens)] + (if (nil? simbolo-inicial) + (dar-error ['EOF '() [] :sin-errores] 3) + (programa [simbolo-inicial (rest tokens) [] :sin-errores [] 0 [] []]))) + ; IMPORTANTE + ; Este es el AMBIENTE inicial del interprete en su fase compilativa. + ; [simb-actual simb-no-parseados-aun simb-ya-parseados estado contexto prox-var bytecode mapa-regs-de-act] +) + +(defn simb-actual [amb] + (amb 0) +) + +(defn simb-no-parseados-aun [amb] + (amb 1) +) + +(defn simb-ya-parseados [amb] + (amb 2) +) + +(defn estado [amb] + (amb 3) +) + +(defn contexto [amb] + (amb 4) +) + +(defn prox-var [amb] + (amb 5) +) + +(defn bytecode [amb] + (amb 6) +) + +(defn mapa-regs-de-act [amb] + (amb 7) +) + +(defn booleano? [x] + (contains? #{"true" "false"} (str x)) +) + +(defn numero? [x] + (number? x) +) + +(defn cadena? [x] + (string? x) +) + +(defn procesar-terminal [amb x cod-err] + (if (= (estado amb) :sin-errores) + (if (or (and (symbol? x) (= (simb-actual amb) x)) (x (simb-actual amb))) + (escanear amb) + (dar-error amb cod-err)) + amb) +) + +(defn generar + ([amb instr] + (if (= (estado amb) :sin-errores) + (assoc amb 6 (conj (bytecode amb) instr)) + amb)) + ([amb instr val] + (if (= (estado amb) :sin-errores) + (assoc amb 6 (conj (bytecode amb) [instr val])) + amb)) +) + +(defn controlar-duplicado [amb] + (if (= (estado amb) :sin-errores) + (if (ya-declarado-localmente? (last (simb-ya-parseados amb)) (contexto amb)) + (let [coincidencias (buscar-coincidencias amb), + tipo (second (last coincidencias))] + (if (not (contains? (hash-set 'var-mut 'var-inmut) tipo)) + (dar-error amb 41) + amb)) + amb) + amb) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Recibe un ambiente y devuelve una lista con las ternas [identificador, tipo, valor] provenientes del segundo +; subvector del vector contexto que tengan como identificador al ultimo simbolo ubicado en el vector de simbolos ya +; escaneados. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defn buscar-coincidencias + ([amb] (filter #(= (first %) (last (simb-ya-parseados amb))) (second (contexto amb)))) + ([amb elem] (filter #(= (first %) elem) (second (contexto amb)))) +) + +(defn verificar-que-sea [amb fn-control] + (if (= (estado amb) :sin-errores) + (let [coincidencias (buscar-coincidencias amb)] + (if (empty? coincidencias) + (dar-error amb 42) + (fn-control amb coincidencias))) + amb) +) + +(defn verificar-que-sea-var [amb] + (verificar-que-sea amb #(if (not (contains? (hash-set 'var-mut 'var-inmut 'var-ref) (first (second (last %2))))) + (dar-error %1 43) + %1)) +) + +(defn verificar-que-sea-var-mut [amb] + (verificar-que-sea amb #(if (not (contains? (hash-set 'var-mut 'var-ref) (first (second (last %2))))) + (dar-error %1 44) + %1)) +) + +(defn verificar-que-sea-var-ref [amb] + (verificar-que-sea amb #(if (not= 'var-ref (first (second (last %2)))) + (dar-error %1 54) + %1)) +) + +(defn verificar-que-sea-fn [amb] + (verificar-que-sea amb #(if (not= 'fn (first (second (last %2)))) + (dar-error %1 45) + %1)) +) + +(defn verificar-que-sea-string [amb] + (verificar-que-sea amb #(if (not= 'String (second (second (last %2)))) + (dar-error %1 51) + %1)) +) + +(defn verificar-que-sea-const-o-var [amb] + (verificar-que-sea amb #(if (not (contains? (hash-set 'const 'var-mut 'var-inmut 'var-ref) (first (second (last %2))))) + (dar-error %1 46) + %1)) +) + +(defn cargar-lib-en-tabla [amb] + (if (= (estado amb) :sin-errores) + (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [(last (simb-ya-parseados amb)) + ['lib ()] + 0])]) + amb) +) + +(defn cargar-fn-en-tabla [amb] + (if (= (estado amb) :sin-errores) + (let [simbolos-ya (simb-ya-parseados amb), + nombre (second (drop-while #(not= % (symbol "(")) (reverse simbolos-ya))), + tipo-dato (if (contains? (hash-set 'i64 'f64 'bool 'String) (last simbolos-ya)) + [(params-args (drop-last 2 simbolos-ya)) (last simbolos-ya)] + [(params-args simbolos-ya) ()]), + valor (count (bytecode amb))] + (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['fn tipo-dato] + valor])])) + amb) +) + +(defn cargar-var-mut-en-tabla [amb] + (if (= (estado amb) :sin-errores) + (let [simbolos-ya (simb-ya-parseados amb), + nombre (last (butlast (butlast simbolos-ya))), + tipo-dato (last simbolos-ya), + valor (prox-var amb), + nuevo (assoc (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['var-mut tipo-dato] + valor])]) 5 (inc valor)), + vars (mapa-regs-de-act amb)] + (assoc nuevo 7 (conj (vec (butlast vars)) (conj (last vars) [tipo-dato nil])))) + amb) +) + +(defn cargar-var-inmut-en-tabla [amb] + (if (= (estado amb) :sin-errores) + (let [simbolos-ya (simb-ya-parseados amb), + nombre (last (butlast (butlast simbolos-ya))), + tipo-dato (last simbolos-ya), + valor (prox-var amb), + nuevo (assoc (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['var-inmut tipo-dato] + valor])]) 5 (inc valor)), + vars (mapa-regs-de-act amb)] + (assoc nuevo 7 (conj (vec (butlast vars)) (conj (last vars) [tipo-dato nil])))) + amb) +) + +(defn inicializar-contexto-global [amb] + (if (= (estado amb) :sin-errores) + (assoc amb 4 [[0] []]) ; [fronteras tabla] + amb) +) + +(defn preparar-mapa-regs-de-act [amb] + (if (= (estado amb) :sin-errores) + (assoc amb 7 (zipmap (map first (mapa-regs-de-act amb)) (map vec (map rest (mapa-regs-de-act amb))))) + amb) +) + +(defn programa [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (inicializar-contexto-global) + (generar ,,, 'CAL 0) + (generar ,,, 'HLT) + (procesar-opcional-declaraciones-use) + (procesar-opcional-declaraciones-const) + (procesar-declaraciones-fn) + (preparar-mapa-regs-de-act)) + amb) +) + +(defn procesar-opcional-declaraciones-use [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) 'use) + (-> amb + (escanear) + (declaracion-use) + (procesar-terminal ,,, (symbol ";") 8) + (recur)) + amb) + amb) +) + +(defn procesar-opcional-declaraciones-const [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) 'const) + (-> amb + (escanear) + (declaracion-const) + (procesar-terminal ,,, (symbol ";") 8) + (recur)) + amb) + amb) +) + +(defn procesar-opciones-use-std [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + io (-> amb + (escanear) + (procesar-opcional-en-std-io)) + process (-> amb + (escanear)) + (dar-error amb 6)) + amb) +) + +(defn procesar-opcional-en-std-io [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "::")) + (-> amb + (escanear) + (procesar-terminal ,,, 'Write 7)) + amb) + amb) +) + +(defn declaracion-use [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, 'std 4) + (procesar-terminal ,,, (symbol "::") 5) + (procesar-opciones-use-std) + (controlar-duplicado) + (cargar-lib-en-tabla)) + amb) +) + +(defn declaracion-const [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, identificador? 10) + (controlar-duplicado) + (procesar-terminal ,,, (symbol ":") 14) + (procesar-tipo-const) + (procesar-terminal ,,, (symbol "=") 9) + (procesar-terminal ,,, numero? 39) + (cargar-const-en-tabla)) + amb) +) + +(defn procesar-mas-param [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ",")) + (-> amb + (escanear) + (declarar-opcional-param) + (recur)) + amb) + amb) +) + +(defn procesar-tipo-param [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + i64 (-> amb + (escanear)) + f64 (-> amb + (escanear)) + (dar-error amb 15)) + amb) +) + +(defn procesar-opcional-mut-param [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "&")) + (-> amb + (escanear) + (procesar-terminal ,,, 'mut 16)) + amb) + amb) +) + +(defn declarar-opcional-param [amb] + (if (= (estado amb) :sin-errores) + (cond + (= (simb-actual amb) 'mut) + (-> amb + (escanear) + (procesar-terminal ,,, identificador? 10) + (procesar-terminal ,,, (symbol ":") 14) + (procesar-tipo-param) + (procesar-mas-param)) + (identificador? (simb-actual amb)) + (-> amb + (escanear) + (procesar-terminal ,,, (symbol ":") 14) + (procesar-opcional-mut-param) + (procesar-tipo-param) + (procesar-mas-param)) + :else amb) + amb) +) + +(defn procesar-tipo-retorno [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + i64 (-> amb + (escanear)) + f64 (-> amb + (escanear)) + bool (-> amb + (escanear)) + String (-> amb + (escanear)) + (dar-error amb 13)) + amb) +) + +(defn declarar-mas-fn [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) 'fn) + (-> amb + (escanear) + (declarar-fn) + (recur)) + amb) + amb) +) + +(defn cargar-params-en-tabla + ([amb] + (if (= (estado amb) :sin-errores) + (let [simbolos-ya (simb-ya-parseados amb), + params (if (contains? (hash-set 'i64 'f64 'bool 'String) (last simbolos-ya)) + (params-args (drop-last 2 simbolos-ya)) + (params-args simbolos-ya)), + proto-amb (vec (conj (map #(if (empty? %) % [(last %) nil]) params) (count (bytecode amb)))), + args (map #(conj ['POPARG] %) (range (dec (count params)) -1 -1))] + (cargar-params-en-tabla (assoc (assoc amb 7 (conj (mapa-regs-de-act amb) + (if (and (= (count proto-amb) 2) (= (second proto-amb) [])) + [(first proto-amb)] + proto-amb))) 6 (into (bytecode amb) args)) + params)) + amb)) + ([amb params] + (if (empty? params) + amb + (let [param (first params), + tam (count param)] + (case tam + 0 (cargar-params-en-tabla amb (rest params)) + 3 (cargar-params-en-tabla (let [nombre (first param), + tipo-dato (last param), + valor (prox-var amb)] + (assoc (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['var-inmut tipo-dato] + valor])]) 5 (inc valor))) (rest params)) + 4 (cargar-params-en-tabla (let [nombre (second param), + tipo-dato (last param), + valor (prox-var amb)] + (assoc (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['var-mut tipo-dato] + valor])]) 5 (inc valor))) (rest params)) + 5 (cargar-params-en-tabla (let [nombre (first param), + tipo-dato (last param), + valor (prox-var amb)] + (assoc (assoc amb 4 [((contexto amb) 0) + (conj ((contexto amb) 1) [nombre + ['var-ref tipo-dato] + valor])]) 5 (inc valor))) (rest params)))))) +) + +(defn hacer-fixup-si-es-main [amb] + (if (= (estado amb) :sin-errores) + (let [simbolos-ya (simb-ya-parseados amb), + firma (take-last 3 simbolos-ya)] + (if (= firma (list 'main (symbol"(") (symbol")"))) + (let [bc (bytecode amb)] + (assoc amb 6 (assoc bc 0 ['CAL (count bc)]))) + amb)) + amb) +) + +(defn hace-push-implicito? [instr] + (contains? #{'ADD 'SUB 'MUL 'DIV 'MOD 'OR 'AND 'EQ 'NEQ 'GT 'GTE 'LT 'LTE 'NEG 'NOT 'SQRT 'SIN 'ATAN 'ABS 'TOI 'TOF} instr) +) + +(defn confirmar-retorno [amb] + (if (= (estado amb) :sin-errores) + (let [ultimo (last (bytecode amb)), + no-simb-ult (not (symbol? ultimo))] + (cond + (hace-push-implicito? ultimo) amb + (and no-simb-ult (= (first ultimo) 'PUSHFM)) amb + (and no-simb-ult (= (first ultimo) 'PUSHFI)) amb + (and no-simb-ult (= (first ultimo) 'CAL) (not= (buscar-tipo-de-retorno amb (second ultimo)) ())) amb + :else (dar-error amb 47)) + ) + amb) +) + +(defn confirmar-no-retorno [amb] + (if (= (estado amb) :sin-errores) + (let [ultimo (last (bytecode amb)), + no-simb-ult (not (symbol? ultimo))] + (cond + (hace-push-implicito? ultimo) (dar-error amb 48) + (and no-simb-ult (= (first ultimo) 'PUSHFM)) (dar-error amb 48) + (and no-simb-ult (= (first ultimo) 'PUSHFI)) (dar-error amb 48) + (and no-simb-ult (= (first ultimo) 'CAL) (not= (buscar-tipo-de-retorno amb (second ultimo)) ())) (dar-error amb 48) + :else amb) + ) + amb) +) + +(defn declarar-opcional-tipo-retorno [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "->")) + (-> amb + (escanear) + (procesar-tipo-retorno) + (cargar-fn-en-tabla) + (hacer-fixup-si-es-main) + (inicializar-contexto-local) + (cargar-params-en-tabla) + (bloque) + (confirmar-retorno) + (restaurar-contexto-anterior) + (generar ,,, 'RET)) + (-> amb + (cargar-fn-en-tabla) + (hacer-fixup-si-es-main) + (inicializar-contexto-local) + (cargar-params-en-tabla) + (bloque) + (confirmar-no-retorno) + (restaurar-contexto-anterior) + (generar ,,, 'RETN))) + amb) +) + +(defn declarar-fn [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (assoc ,,, 5 0) + (procesar-terminal ,,, identificador? 10) + (controlar-duplicado) + (procesar-terminal ,,, (symbol "(") 11) + (declarar-opcional-param) + (procesar-terminal ,,, (symbol ")") 49) + (declarar-opcional-tipo-retorno)) + amb) +) + +(defn procesar-declaraciones-fn [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, 'fn 9) + (declarar-fn) + (declarar-mas-fn)) + amb) +) + +(defn procesar-mas-opcional-bloque [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ";")) + (let [ultimo (last (bytecode amb)), + usar-amb (cond (hace-push-implicito? ultimo) + (generar amb 'POP) + (and (not (symbol? ultimo)) (= (first ultimo) 'CAL) (not= (buscar-tipo-de-retorno amb (second ultimo)) ())) + (generar amb 'POP) + (and (not (symbol? ultimo)) (= (first ultimo) 'PUSHFM)) + (generar amb 'POP) + (and (not (symbol? ultimo)) (= (first ultimo) 'PUSHFI)) + (generar amb 'POP) + :else amb)] + (-> usar-amb + (escanear) + (procesar-opcional-bloque) + (recur))) + amb) + amb) +) + +(defn procesar-opcional-mut-let [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) 'mut) + (-> amb + (escanear) + (procesar-terminal ,,, identificador? 10) + (procesar-terminal ,,, (symbol ":") 14) + (procesar-tipo-variable) + (cargar-var-mut-en-tabla) + (procesar-opcional-asignacion) + (procesar-mas-opcional-bloque)) + (-> amb + (procesar-terminal ,,, identificador? 10) + (procesar-terminal ,,, (symbol ":") 14) + (procesar-tipo-variable) + (cargar-var-inmut-en-tabla) + (procesar-opcional-asignacion) + (procesar-mas-opcional-bloque)) + ) + amb) +) + +(defn procesar-tipo-const [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + i64 (-> amb + (escanear)) + f64 (-> amb + (escanear)) + (dar-error amb 20)) + amb) +) + +(defn procesar-opcional-asignacion [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "=")) + (let [direc (dec (prox-var amb))] + (-> amb + (escanear) + (expresion) + (generar ,,, 'POP direc))) + amb) + amb) +) + +(defn procesar-tipo-variable [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + i64 (-> amb + (escanear)) + f64 (-> amb + (escanear)) + bool (-> amb + (escanear)) + char (-> amb + (escanear)) + String (-> amb + (escanear)) + (dar-error amb 19)) + amb) +) + +(defn procesar-opcional-bloque [amb] + (if (= (estado amb) :sin-errores) + (cond + (= (simb-actual amb) (symbol "}")) + amb + (= (simb-actual amb) 'let) + (-> amb + (escanear) + (procesar-opcional-mut-let)) + :else + (-> amb + (expresion) + (procesar-mas-opcional-bloque))) + amb) +) + +(defn bloque [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, (symbol "{") 17) + (procesar-opcional-bloque) + (procesar-terminal ,,, (symbol "}") 18)) + amb) +) + +(defn procesar-stdout-stdin [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + stdout (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'flush 27) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'FLUSH)) + stdin (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'read_line 28) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol "&") 29) + (procesar-terminal ,,, 'mut 16) + (procesar-terminal ,,, identificador? 10) + (verificar-que-sea-var-mut) + (verificar-que-sea-string) + (generar-con-valor ,,, 'IN) + (procesar-terminal ,,, (symbol ")") 12)) + (dar-error amb 26)) + amb) +) + +(defn procesar-opcional-expresiones-a-imprimir [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ",")) + (-> amb + (escanear) + (expresion) + (recur)) + amb) + amb) +) + +(defn generar-pushfi-cadena [amb] + (generar amb 'PUSHFI (last (simb-ya-parseados amb))) +) + +(defn procesar-opcional-cadena-expresiones-a-imprimir [amb] + (if (= (estado amb) :sin-errores) + (if (cadena? (simb-actual amb)) + (-> amb + (escanear) + (generar-pushfi-cadena) + (procesar-opcional-expresiones-a-imprimir)) + amb) + amb) +) + +(defn procesar-string-new-from [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + new (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'PUSHFI "")) + from (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, cadena? 25) + (generar-pushfi-cadena) + (procesar-terminal ,,, (symbol ")") 12)) + (dar-error amb 34)) + amb) +) + +(defn procesar-string-punto-as-str-trim [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + as_str (-> amb + (escanear) + (procesar-as-str)) + trim (-> amb + (escanear) + (procesar-trim) + (procesar-string-punto-to-string-parse)) + (dar-error amb 35)) + amb) +) + +(defn procesar-to-string [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12)) + amb) +) + +(defn procesar-parse [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, (symbol "::") 5) + (procesar-terminal ,,, (symbol "<") 52) + (procesar-tipo-as) + (procesar-terminal ,,, (symbol ">") 53) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'expect 24) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, cadena? 25) + (procesar-terminal ,,, (symbol ")") 12)) + amb) +) + +(defn procesar-string-punto-to-string-parse [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + to_string (-> amb + (escanear) + (procesar-to-string)) + parse (-> amb + (escanear) + (procesar-parse)) + (dar-error amb 36)) + amb) +) + +(defn procesar-trim [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23)) + amb) +) + +(defn procesar-as-str [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'chars 31) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'nth 32) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'unwrap 33) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'CHR)) + amb) +) + +(defn procesar-opcional-string-punto [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ".")) + (-> amb + (escanear) + (procesar-string-punto-as-str-trim)) + amb) + amb) +) + +(defn procesar-tipo-as [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + i64 (-> amb + (escanear) + (generar ,,, 'TOI)) + f64 (-> amb + (escanear) + (generar ,,, 'TOF)) + usize (-> amb + (escanear) + (generar ,,, 'TOI)) + (dar-error amb 37)) + amb) +) + +(defn procesar-opcional-as [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) 'as) + (-> amb + (escanear) + (procesar-tipo-as)) + amb) + amb) +) + +(defn procesar-f64-funcion [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + sqrt (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'SQRT)) + sin (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'SIN)) + atan (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'ATAN)) + abs (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'ABS)) + (dar-error amb 38)) + amb) +) + +(defn procesar-ident-punto-parse-to-string [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + parse (-> amb + (escanear) + (procesar-parse)) + to_string (-> amb + (escanear) + (procesar-to-string)) + (dar-error amb 36)) + amb) +) + +(defn procesar-ident-punto [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + as_str (-> amb + (escanear) + (procesar-as-str)) + trim (-> amb + (escanear) + (procesar-trim) + (procesar-ident-punto-parse-to-string)) + (dar-error amb 35)) + amb) +) + +(defn procesar-opcional-as-punto [amb] + (if (= (estado amb) :sin-errores) + (cond + (= (simb-actual amb) 'as) + (-> amb + (escanear) + (procesar-tipo-as)) + (= (simb-actual amb) (symbol ".")) + (-> amb + (escanear) + (procesar-ident-punto)) + :else amb) + amb) +) + +(defn procesar-mas-opcional-expresion [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ",")) + (-> amb + (escanear) + (procesar-opcional-expresion) + (recur)) + amb) + amb) +) + +(defn procesar-opcional-expresion [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol ")")) + amb + (-> amb + (expresion) + (procesar-mas-opcional-expresion))) + amb) +) + +(defn generar-factor-const-o-var [amb puntero?] + (if (= (estado amb) :sin-errores) + (let [coincidencias (buscar-coincidencias amb), + tipo (first (second (last coincidencias))), + valor (nth (last coincidencias) 2)] + (if (= tipo 'const) + (generar amb 'PUSHFI valor) + (if (not puntero?) + (generar amb 'PUSHFM valor) + (generar amb 'PUSHREF valor)))) + amb) +) + +(defn procesar-opcional-asignacion-llamada [amb puntero?] + (if (= (estado amb) :sin-errores) + (let [ident (last (simb-ya-parseados amb))] + (cond + (= (simb-actual amb) (symbol "=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POP ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPREF ident))) + (= (simb-actual amb) (symbol "+=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPADD ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPADDREF ident))) + (= (simb-actual amb) (symbol "-=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPSUB ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPSUBREF ident))) + (= (simb-actual amb) (symbol "*=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPMUL ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPMULREF ident))) + (= (simb-actual amb) (symbol "/=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPDIV ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPDIVREF ident))) + (= (simb-actual amb) (symbol "%=")) + (if (not puntero?) + (-> amb + (verificar-que-sea-var) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPMOD ident)) + (-> amb + (verificar-que-sea-var-ref) + (escanear) + (expresion) + (generar-con-valor ,,, 'POPMODREF ident))) + (= (simb-actual amb) (symbol "(")) + (-> amb + (verificar-que-sea-fn) + (escanear) + (procesar-opcional-expresion) + (procesar-terminal ,,, (symbol ")") 49) + (generar-con-valor ,,, 'CAL ident)) + :else (-> amb + (verificar-que-sea-const-o-var) + (generar-factor-const-o-var ,,, puntero?)))) + amb) +) + +(defn expresion-atomica [amb] + (if (= (estado amb) :sin-errores) + (cond + (numero? (simb-actual amb)) + (-> amb + (generar ,,, 'PUSHFI (simb-actual amb)) + (escanear) + (procesar-opcional-as)) + (booleano? (simb-actual amb)) + (-> amb + (generar ,,, 'PUSHFI (simb-actual amb)) + (escanear) + (procesar-opcional-as)) + (cadena? (simb-actual amb)) + (-> amb + (generar ,,, 'PUSHFI (simb-actual amb)) + (escanear) + (procesar-opcional-string-punto)) + (identificador? (simb-actual amb)) + (-> amb + (escanear) + (procesar-opcional-asignacion-llamada ,,, false) + (procesar-opcional-as-punto)) + (= (simb-actual amb) (symbol"(")) + (-> amb + (escanear) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (procesar-opcional-as-punto)) + :else + (case (simb-actual amb) + if (let [primera-fase (-> amb + (escanear) + (expresion))] + (if (= (estado primera-fase) :sin-errores) + (let [segunda-fase (-> primera-fase + (generar ,,, 'JC (+ 2 (count (bytecode primera-fase)))) + (generar ,,, 'JMP '?))] + (if (= (estado segunda-fase) :sin-errores) + (let [tercera-fase (-> segunda-fase + (inicializar-contexto-local) + (bloque) + (restaurar-contexto-anterior))] + (if (= (estado tercera-fase) :sin-errores) + (if (= (simb-actual tercera-fase) 'else) + (-> tercera-fase + (escanear) + (generar ,,, 'JMP '?) + (inicializar-contexto-local) + (fixup ,,, (inc (count (bytecode primera-fase)))) + (bloque) + (fixup ,,, (count (bytecode tercera-fase))) + (restaurar-contexto-anterior)) + (fixup tercera-fase (inc (count (bytecode primera-fase))))) + tercera-fase)) + segunda-fase)) + primera-fase)) + while (let [primera-fase (escanear amb), + segunda-fase (expresion primera-fase)] + (if (= (estado segunda-fase) :sin-errores) + (-> segunda-fase + (generar ,,, 'JC (+ 2 (count (bytecode segunda-fase)))) + (generar ,,, 'JMP '?) + (inicializar-contexto-local) + (bloque) + (generar ,,, 'JMP (count (bytecode primera-fase))) + (fixup ,,, (inc (count (bytecode segunda-fase)))) + (restaurar-contexto-anterior)) + segunda-fase)) + return (-> amb + (escanear) + (expresion) + (generar ,,, 'RET)) + process (-> amb + (escanear) + (procesar-terminal ,,, (symbol "::") 5) + (procesar-terminal ,,, 'exit 22) + (procesar-terminal ,,, (symbol "(") 11) + (expresion) + (procesar-terminal ,,, (symbol ")") 12) + (generar ,,, 'HLT)) + format! (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, cadena? 25) + (generar-pushfi-cadena) + (procesar-opcional-expresiones-a-imprimir) + (procesar-terminal ,,, (symbol ")") 49) + (generar-format!)) + print! (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, cadena? 25) + (generar-pushfi-cadena) + (procesar-opcional-expresiones-a-imprimir) + (procesar-terminal ,,, (symbol ")") 49) + (generar-print!)) + println! (-> amb + (escanear) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-opcional-cadena-expresiones-a-imprimir) + (procesar-terminal ,,, (symbol ")") 49) + (generar-print!) + (generar ,,, 'NL)) + io (-> amb + (escanear) + (procesar-terminal ,,, (symbol "::") 5) + (procesar-stdout-stdin) + (procesar-terminal ,,, (symbol ".") 23) + (procesar-terminal ,,, 'expect 24) + (procesar-terminal ,,, (symbol "(") 11) + (procesar-terminal ,,, cadena? 25) + (procesar-terminal ,,, (symbol ")") 12)) + & (-> amb + (escanear) + (procesar-terminal ,,, 'mut 16) + (procesar-terminal ,,, identificador? 10) + (verificar-que-sea-var-mut) + (generar-ref)) + String (-> amb + (escanear) + (procesar-terminal ,,, (symbol "::") 5) + (procesar-string-new-from) + (procesar-opcional-string-punto)) + f64 (-> amb + (escanear) + (procesar-terminal ,,, (symbol "::") 5) + (procesar-f64-funcion) + (procesar-opcional-as)) + * (-> amb + (escanear) + (procesar-terminal ,,, identificador? 10) + (procesar-opcional-asignacion-llamada ,,, true) + (procesar-opcional-as-punto)) + (dar-error amb 21))) + amb) +) + +(defn expresion-unaria [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + + (-> amb + (escanear) + (expresion-atomica)) + - (-> amb + (escanear) + (expresion-atomica) + (generar ,,, 'NEG)) + ! (-> amb + (escanear) + (expresion-atomica) + (generar ,,, 'NOT)) + (expresion-atomica amb)) + amb) +) + +(defn procesar-mas-expresion-unaria [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + * (-> amb + (escanear) + (expresion-unaria) + (generar ,,, 'MUL) + (recur)) + / (-> amb + (escanear) + (expresion-unaria) + (generar ,,, 'DIV) + (recur)) + % (-> amb + (escanear) + (expresion-unaria) + (generar ,,, 'MOD) + (recur)) + amb) + amb) +) + +(defn expresion-multiplicativa [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-unaria) + (procesar-mas-expresion-unaria)) + amb) +) + +(defn procesar-mas-expresion-multiplicativa [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + + (-> amb + (escanear) + (expresion-multiplicativa) + (generar ,,, 'ADD) + (recur)) + - (-> amb + (escanear) + (expresion-multiplicativa) + (generar ,,, 'SUB) + (recur)) + amb) + amb) +) + +(defn expresion-aditiva [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-multiplicativa) + (procesar-mas-expresion-multiplicativa)) + amb) +) + +(defn procesar-mas-expresion-aditiva [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + <= (-> amb + (escanear) + (expresion-aditiva) + (generar ,,, 'LTE) + (recur)) + < (-> amb + (escanear) + (expresion-aditiva) + (generar ,,, 'LT) + (recur)) + >= (-> amb + (escanear) + (expresion-aditiva) + (generar ,,, 'GTE) + (recur)) + > (-> amb + (escanear) + (expresion-aditiva) + (generar ,,, 'GT) + (recur)) + amb) + amb) +) + +(defn expresion-relacional [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-aditiva) + (procesar-mas-expresion-aditiva)) + amb) +) + +(defn procesar-mas-expresion-relacional [amb] + (if (= (estado amb) :sin-errores) + (case (simb-actual amb) + != (-> amb + (escanear) + (expresion-relacional) + (generar ,,, 'NEQ) + (recur)) + == (-> amb + (escanear) + (expresion-relacional) + (generar ,,, 'EQ) + (recur)) + amb) + amb) +) + +(defn expresion-igualdad [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-relacional) + (procesar-mas-expresion-relacional)) + amb) +) + +(defn procesar-mas-expresion-igualdad [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "&&")) + (-> amb + (escanear) + (expresion-igualdad) + (generar ,,, 'AND) + (recur)) + amb) + amb) +) + +(defn expresion-and [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-igualdad) + (procesar-mas-expresion-igualdad)) + amb) +) + +(defn procesar-mas-expresion-and [amb] + (if (= (estado amb) :sin-errores) + (if (= (simb-actual amb) (symbol "||")) + (-> amb + (escanear) + (expresion-and) + (generar ,,, 'OR) + (recur)) + amb) + amb) +) + +(defn expresion [amb] + (if (= (estado amb) :sin-errores) + (-> amb + (expresion-and) + (procesar-mas-expresion-and)) + amb) +) + +(defn generar-operador-relacional [amb operador] + (if (= (estado amb) :sin-errores) + (case operador + = (generar amb 'EQ) + <> (generar amb 'NEQ) + > (generar amb 'GT) + >= (generar amb 'GTE) + < (generar amb 'LT) + <= (generar amb 'LTE)) + amb) +) + +(defn generar-con-valor + ([amb instr] + (if (= (estado amb) :sin-errores) + (let [coincidencias (buscar-coincidencias amb), + valor (nth (last coincidencias) 2)] + (generar amb instr valor)) + amb)) + ([amb instr ident] + (if (= (estado amb) :sin-errores) + (let [coincidencias (buscar-coincidencias amb ident), + valor (nth (last coincidencias) 2)] + (generar amb instr valor)) + amb)) +) + +(defn aplicar-operador-monadico [op pila] + (try (vec (conj (vec (butlast pila)) (op (last pila)))) + (catch Exception e (print "ERROR: ") (println (buscar-mensaje 55)) nil)) +) + +(defn aplicar-operador-diadico [op pila] + (try (vec (conj (vec (drop-last 2 pila)) (op (last (butlast pila)) (last pila)))) + (catch Exception e (print "ERROR: ") (println (buscar-mensaje 56)) nil)) +) + +(defn asignar-aritmetico [regs-de-act pila reg-actual fetched op] + (let [direc (second fetched), + tipo-en-reg (first (reg-actual direc)), + dato-en-reg (second (reg-actual direc)), + dato-en-pila (last pila)] + (if (compatibles? tipo-en-reg dato-en-pila) + (cargar-en-ult-reg regs-de-act direc tipo-en-reg (op dato-en-reg dato-en-pila)) + (do (print "ERROR: ") (println (buscar-mensaje 50)) nil))) +) + +(defn asignar-aritmetico-ref [regs-de-act pila reg-actual fetched op] + (let [direc (second fetched), + destino (second (reg-actual direc)), + dato-en-pila (last pila), + dato-en-dest (second ((regs-de-act (first destino)) (second destino))) + tipo-en-dest (first ((regs-de-act (first destino)) (second destino)))] + (if (compatibles? tipo-en-dest dato-en-pila) + (cargar-en-reg-dest regs-de-act destino tipo-en-dest (op dato-en-dest dato-en-pila)) + (do (print "ERROR: ") (println (buscar-mensaje 50)) nil))) +) + +(defn params-args [cad] + (let [res (map vec + (map reverse + (reverse + (reduce #(if (neg? (first %1)) + (reduced (conj (vec (butlast (second %1))) (vec (butlast (last (second %1)))))) + (cond + (= %2 (symbol ")")) [(+ (first %1) 1) (conj (vec (butlast (second %1))) (conj (last (second %1)) %2))] + (= %2 (symbol "(")) [(- (first %1) 1) (conj (vec (butlast (second %1))) (conj (last (second %1)) %2))] + (and (= %2 (symbol ",")) (zero? (first %1))) [(first %1) (conj (second %1) [])] + :else [(first %1) (conj (vec (butlast (second %1))) (conj (last (second %1)) %2))])) + [0 [[]]] (rest (reverse cad))))))] + (if (= res '([])) () res)) +) + +(defn generar-print! [amb] + (if (= (estado amb) :sin-errores) + (let [args (params-args (simb-ya-parseados amb))] + (-> amb + (generar ,,, 'PUSHFI (count args)) + (generar ,,, 'OUT))) + amb + ) +) + +(defn generar-format! [amb] + (if (= (estado amb) :sin-errores) + (let [args (params-args (simb-ya-parseados amb))] + (-> amb + (generar ,,, 'PUSHFI (count args)) + (generar ,,, 'FMT))) + amb + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; LA SIGUIENTE FUNCION DEBERA SER COMPLETADA PARA QUE ANDE EL INTERPRETE DE RUST +; FALTAN IMPLEMENTAR (todas como llamados recursivos a la funcion interpretar, con recur y argumentos actualizados): +; +; PUSHFI: PUSH FROM INSTRUCTION. Direccionamiento inmediato. Incrementa cont-prg en 1 y agrega al final de pila el valor del argumento. +; PUSHFM: PUSH FROM MEMORY. Direccionamiento directo. Incrementa cont-prg en 1 y agrega al final de pila el elemento ubicado en la posicion de reg-actual indicada por el valor del argumento. +; JMP: Salto incondicional. Cambia cont-prg por el valor del argumento. +; JC: Salto condicional. Quita el ultimo valor de la pila. Si este es true, cambia cont-prg por el valor del argumento. Si no, incrementa cont-prg en 1. +; CAL: Llamada a una funcion. Agrega al final de regs-de-act el reg-de-act (proveniente de mapa-regs) indicado por el argumento, cambia cont-prg por el valor del argumento y coloca al final de la pila la direccion de retorno (el valor del argumento incrementado en 1). +; RETN: Indica el retorno de la llamada a un procedimiento (no funcion). Llama recursivamente a interpretar con valores actualizados de regs-de-act (se elimina el ultimo de ellos), cont-prg (pasa a ser el ultimo valor en la pila) y pila (se quita de ella el nuevo cont-prg). +; NL: New line. Imprime un salto de linea e incrementa cont-prg en 1. +; FLUSH: Purga la salida e incrementa cont-prg en 1. +; POPSUB: Como POPADD, pero resta. +; POPMUL: Como POPADD, pero multiplica. +; POPDIV: Como POPADD, pero divide. +; POPMOD: Como POPADD, pero calcula el resto de la division. +; POPSUBREF: Como POPADDREF, pero resta. +; POPMULREF: Como POPADDREF, pero multiplica. +; POPDIVREF: Como POPADDREF, pero divide. +; POPMODREF: Como POPADDREF, pero calcula el resto de la division. +; SUB: Como ADD, pero resta. +; MUL: Como ADD, pero multiplica. +; DIV: Como ADD, pero divide. +; MOD: Como ADD, pero calcula el resto de la division. +; CHR: Incrementa cont-prg en 1, quita de la pila dos elementos (un string y un indice), selecciona el char del string indicado por el indice y lo coloca al final de la pila. +; OR: Como ADD, pero calcula el or entre los dos valores. +; AND: Como ADD, pero calcula el and entre los dos valores. +; EQ: Como ADD, pero calcula la operacion relacional = entre los dos valores. +; NEQ: Como ADD, pero calcula la operacion relacional != entre los dos valores. +; GT: Como ADD, pero calcula la operacion relacional > entre los dos valores. +; GTE: Como ADD, pero calcula la operacion relacional >= entre los dos valores. +; LT: Como ADD, pero calcula la operacion relacional < entre los dos valores. +; LTE: Como ADD, pero calcula la operacion relacional <= entre los dos valores. +; NEG: Incrementa cont-prg en 1, quita de la pila un elemento numerico, le cambia el signo y lo coloca al final de la pila. +; NOT: Incrementa cont-prg en 1, quita de la pila un elemento booleano, lo niega y lo coloca al final de la pila. +; TOI: Incrementa cont-prg en 1, quita de la pila un elemento numerico, lo convierte a entero y lo coloca al final de la pila. +; TOF: Incrementa cont-prg en 1, quita de la pila un elemento numerico, lo convierte a punto flotante y lo coloca al final de la pila. +; SQRT: Incrementa cont-prg en 1, quita de la pila un elemento numerico, calcula su raiz cuadrada y la coloca al final de la pila. +; SIN: Incrementa cont-prg en 1, quita de la pila un elemento numerico, calcula su seno y lo coloca al final de la pila. +; ATAN: Incrementa cont-prg en 1, quita de la pila un elemento numerico, calcula su arcotangente y la coloca al final de la pila. +; ABS: Incrementa cont-prg en 1, quita de la pila un elemento numerico, calcula su valor absoluto y lo coloca al final de la pila. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defn interpretar [cod regs-de-act cont-prg pila mapa-regs] + (let [fetched (cod cont-prg), + opcode (if (symbol? fetched) fetched (first fetched)), + reg-actual (last regs-de-act)] + (case opcode + + ; Detiene la ejecucion (deja de llamar recursivamente a interpretar) + HLT nil + + ; Incrementa cont-prg en 1 y agrega al final de pila un valor proveniente de regs-de-act cuyas coordenadas [#reg-act, offset] provienen de reg-actual. + ; Por ejemplo: + ; fetched: [PUSHREF 3] + ; reg-actual: [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]] + ; 3:^^^^^^^^^^^ + ; destino = [0 4] + ; regs-de-act: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 23]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]]] + ; 4:^^^^^^^^ + ; 0:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ; pila recibida: [1 150] + ; pila al llamar recursivamente a interpretar: [1 150 23] + PUSHREF (let [destino (second (reg-actual (second fetched)))] + (recur cod regs-de-act (inc cont-prg) (conj pila (second ((regs-de-act (first destino)) (second destino)))) mapa-regs)) + + ; Incrementa cont-prg en 1 y agrega al final de pila unas coordenadas [#reg-act, offset] + ; Por ejemplo: + ; fetched: [PUSHADDR 3] + ; reg-actual: [[String "5"] [i64 23] [i64 5] [i64 0] [i64 0]] + ; regs-de-act: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 0]]] + ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ count = 1 + ; pila recibida: [1 23 5] + ; pila al llamar recursivamente a interpretar: [1 23 5 [0 3]] + PUSHADDR (recur cod regs-de-act (inc cont-prg) (conj pila [(dec (count regs-de-act)) (second fetched)]) mapa-regs) + + ; Incrementa cont-prg en 1 y quita el ultimo elemento de pila. Si hay un argumento, este indica donde colocar el elemento en el ultimo de los regs-de-act al llamar recursivamente a interpretar (verificando la compatibilidad de los tipos) + ; Si no lo hay, solo incrementa cont-prg en 1 y quita el elemento de la pila. + ; Por ejemplo: + ; fetched: [POP 4] + ; regs-de-act recibido: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 23]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]]] + ; reg-actual: [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]] + ; pila recibida: [1 150 5] + ; pila al llamar recursivamente a interpretar: [1 150] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 23]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 5] [i64 nil]]] + ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ultimo reg-act + ; 4:^^^^^^^ + POP (if (symbol? fetched) + (recur cod regs-de-act (inc cont-prg) (vec (butlast pila)) mapa-regs) + (let [direc (second fetched), + tipo-en-reg (first (reg-actual direc)), + dato-en-pila (last pila)] + (if (compatibles? tipo-en-reg dato-en-pila) + (recur cod (cargar-en-ult-reg regs-de-act direc tipo-en-reg dato-en-pila) (inc cont-prg) (vec (butlast pila)) mapa-regs) + (do (print "ERROR: ") (println (buscar-mensaje 50)) nil)))) + + ; Incrementa cont-prg en 1 y quita el penultimo elemento de pila. El argumento indica donde colocar el elemento en el ultimo de los regs-de-act al llamar recursivamente a interpretar (verificando la compatibilidad de los tipos) + ; Por ejemplo: + ; fetched: [POPARG 3] + ; regs-de-act recibido: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 0]] [[i64 nil] [i64 nil] [i64 nil] [i64 nil] [i64 nil] [i64 nil]]] + ; reg-actual: [[i64 nil] [i64 nil] [i64 nil] [i64 nil] [i64 nil] [i64 nil]] + ; pila recibida: [1 23 5 [0 3] [0 4] 150] + ; pila al llamar recursivamente a interpretar: [1 23 5 [0 3] 150] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 0]] [[i64 nil] [i64 nil] [i64 nil] [i64 [0 4]] [i64 nil] [i64 nil]]] + ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ultimo reg-act + ; 3:^^^^^^^^^^^ + POPARG (let [direc (second fetched), + tipo-en-reg (first (reg-actual direc)), + dato-en-pila (last (butlast pila))] + (if (compatibles? tipo-en-reg dato-en-pila) + (recur cod (cargar-en-ult-reg regs-de-act direc tipo-en-reg dato-en-pila) (inc cont-prg) (conj (vec (drop-last 2 pila)) (last pila)) mapa-regs) + (do (print "ERROR: ") (println (buscar-mensaje 50)) nil))) + + ; Incrementa cont-prg en 1 y quita el ultimo elemento de pila. El argumento indica en reg-actual las coordenadas [#reg-act, offset] donde colocar el elemento en regs-de-act al llamar recursivamente a interpretar (verificando la compatibilidad de los tipos) + ; Por ejemplo: + ; fetched: [POPREF 3] + ; regs-de-act recibido: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 0]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]]] + ; reg-actual: [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]] + ; 3:^^^^^^^^^^^ + ; pila recibida: [1 150 23] + ; pila al llamar recursivamente a interpretar: [1 150] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 23]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 nil] [i64 nil]]] + ; 4:^^^^^^^^ + ; 0:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + POPREF (let [direc (second fetched), + destino (second (reg-actual direc)), + dato-en-pila (last pila), + tipo-en-dest (first ((regs-de-act (first destino)) (second destino)))] + (if (compatibles? tipo-en-dest dato-en-pila) + (recur cod (cargar-en-reg-dest regs-de-act destino tipo-en-dest dato-en-pila) (inc cont-prg) (vec (butlast pila)) mapa-regs) + (do (print "ERROR: ") (println (buscar-mensaje 50)) nil))) + + ; Incrementa cont-prg en 1, lee un string desde el teclado y lo coloca en el ultimo de los regs-de-act al llamar recursivamente a interpretar + ; Por ejemplo: + ; fetched: [IN 0] + ; regs-de-act recibido: [[[String ""] [i64 23] [i64 nil] [i64 nil] [i64 nil]]] + ; reg-actual: [[String ""] [i64 23] [i64 nil] [i64 nil] [i64 nil]] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "5"] [i64 23] [i64 nil] [i64 nil] [i64 nil]]] + ; 0:^^^^^^^^^^^^ + IN (let [entr (read-line)] + (recur cod (cargar-en-ult-reg regs-de-act (second fetched) 'String entr) (inc cont-prg) pila mapa-regs)) + + ; Incrementa cont-prg en 1, quita de la pila el contador de argumentos y los argumentos, y coloca al final de la pila un string con estos ultimos (correctamente formateados) + ; Por ejemplo: + ; fetched: FMT + ; pila recibida: [1 153 "Resto: {}" 9 2] + ; pila: [1 153 "Resto: 9"] + FMT (let [cant-args (last pila), + args (take-last cant-args (butlast pila)), + res (if (pos? cant-args) (apply format (convertir-formato-impresion args)) "")] + (recur cod regs-de-act (inc cont-prg) (conj (vec (drop-last (+ cant-args 1) pila)) res) mapa-regs)) + + ; Incrementa cont-prg en 1, quita de la pila el contador de argumentos y los argumentos, e imprime estos ultimos (correctamente formateados) + ; Por ejemplo: + ; fetched: OUT + ; pila recibida: [1 153 "Resto: {}" 9 2] + ; pila: [1 153] + ; Imprime: + ; Resto: 9 + OUT (let [cant-args (last pila), + args (take-last cant-args (butlast pila))] + (do (if (pos? cant-args) (apply printf (convertir-formato-impresion args))) + (recur cod regs-de-act (inc cont-prg) (vec (drop-last (+ cant-args 1) pila)) mapa-regs))) + + ; Indica el retorno de la llamada a una funcion (no procedimiento). Llama recursivamente a interpretar con valores actualizados de regs-de-act (se elimina el ultimo de ellos), cont-prg (pasa a ser el penultimo valor en la pila) y pila (se quita de ella el nuevo cont-prg). + ; Por ejemplo: + ; fetched: RET + ; regs-de-act recibido: [[[String "15"] [i64 12] [i64 15]] [[i64 3] [i64 3]]] + ; cont-prg recibido: 40 + ; pila recibida: [1 "{} es el MCD entre " 81 3] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "15"] [i64 12] [i64 15]]] + ; cont-prg al llamar recursivamente a interpretar: 81 + ; pila al llamar recursivamente a interpretar: [1 "{} es el MCD entre " 3] + RET (recur cod (vec (butlast regs-de-act)) (last (butlast pila)) (vec (conj (vec (drop-last 2 pila)) (last pila))) mapa-regs) + + + ; Incrementa cont-prg en 1 y quita el ultimo elemento de pila. El argumento indica donde sumar el elemento en el ultimo de los regs-de-act al llamar recursivamente a interpretar (verificando la compatibilidad de los tipos) + ; Por ejemplo: + ; fetched: [POPADD 2] + ; regs-de-act recibido: [[[String "6"] [i64 6] [i64 5]]] + ; reg-actual: [[String "6"] [i64 6] [i64 5]] + ; pila recibida: [1 2] + ; pila al llamar recursivamente a interpretar: [1] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "6"] [i64 6] [i64 7]]] + ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ultimo reg-act + ; 2:^^^^^^^ + POPADD (let [res (asignar-aritmetico regs-de-act pila reg-actual fetched +)] + (if (nil? res) res (recur cod res (inc cont-prg) (vec (butlast pila)) mapa-regs))) + + ; Incrementa cont-prg en 1 y quita el ultimo elemento de pila. El argumento indica en reg-actual las coordenadas [#reg-act, offset] donde sumar el elemento en regs-de-act al llamar recursivamente a interpretar (verificando la compatibilidad de los tipos) + ; Por ejemplo: + ; fetched: [POPADDREF 2] + ; regs-de-act recibido: [[[String "5"] [i64 23] [i64 5] [i64 0] [i64 3]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 5] [i64 20]]] + ; reg-actual: [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 5] [i64 20]] + ; 2:^^^^^^^^^^^ + ; pila recibida: [1 150 1] + ; pila al llamar recursivamente a interpretar: [1 150] + ; regs-de-act al llamar recursivamente a interpretar: [[[String "5"] [i64 23] [i64 5] [i64 1] [i64 3]] [[i64 23] [i64 5] [i64 [0 3]] [i64 [0 4]] [i64 5] [i64 20]]] + ; 3:^^^^^^^ + ; 0:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + POPADDREF (let [res (asignar-aritmetico-ref regs-de-act pila reg-actual fetched +)] + (if (nil? res) res (recur cod res (inc cont-prg) (vec (butlast pila)) mapa-regs))) + + ; Incrementa cont-prg en 1, quita de la pila dos elementos, calcula su suma y la coloca al final de la pila + ; fetched: ADD + ; pila recibida: [1 0 0 3 4] + ; pila al llamar recursivamente a interpretar: [1 0 0 7] + ADD (let [res (aplicar-operador-diadico + pila)] + (if (nil? res) res (recur cod regs-de-act (inc cont-prg) res mapa-regs))) + + ) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; LAS FUNCIONES QUE SIGUEN DEBERAN SER IMPLEMENTADAS PARA QUE ANDE EL INTERPRETE DE RUST +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; LISTAR: Recibe una lista con los tokens de un programa en Rust (o de parte de un programa) y muestra el codigo fuente formateado. Retorna nil. +; Por ejemplo: +; user=> (listar (list 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'println! (symbol "(") "Hola, mundo!" (symbol ")") (symbol "}"))) +; fn main ( ) +; { +; println! ( "Hola, mundo!" ) +; } +; +; nil +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn listar +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; AGREGAR-PTOCOMA: Recibe una lista con los tokens de un programa en Rust y la devuelve con un token ; insertado a continuacion de ciertas } (llaves de cierre, pero no a continuacion de todas ellas). +; Esto se debe a que los programas correctos de Rust no separan con ; las expresiones presentes dentro de un bloque cuando estas terminan en }. +; Por ejemplo: +; user=> (agregar-ptocoma (list 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'if 'x '< '0 (symbol "{") 'x '= '- 'x (symbol ";") (symbol "}") 'renglon '= 'x (symbol ";") 'if 'z '< '0 (symbol "{") 'z '= '- 'z (symbol ";") (symbol "}") (symbol "}") 'fn 'foo (symbol "(") (symbol ")") (symbol "{") 'if 'y '> '0 (symbol "{") 'y '= '- 'y (symbol ";") (symbol "}") 'else (symbol "{") 'x '= '- 'y (symbol ";") (symbol "}") (symbol "}"))) +; (fn main ( ) { if x < 0 { x = - x ; } ; renglon = x ; if z < 0 { z = - z ; } } fn foo ( ) { if y > 0 { y = - y ; } else { x = - y ; } }) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn agregar-ptocoma +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PALABRA-RESERVADA?: Recibe un elemento y devuelve true si es una palabra reservada de Rust; si no, false. +; Por ejemplo: +; user=> (palabra-reservada? 'while) +; true +; user=> (palabra-reservada? 'until) +; false +; user=> (palabra-reservada? 13) +; false +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn palabra-reservada? +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; IDENTIFICADOR?: Recibe un elemento y devuelve true si es un identificador valido en Rust; si no, false. +; Por ejemplo: +; user=> (identificador? 'boolean) +; true +; user=> (identificador? 'bool) +; false +; user=> (identificador? 'e120) +; true +; user=> (identificador? '12e0) +; false +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn identificador? +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; DUMP: Recibe un vector con instrucciones de la RI y las imprime numeradas a partir de 0. Siempre devuelve nil. +; Por ejemplo: +; user=> (dump '[[POPREF 2] [PUSHFI 2] MUL [PUSHFI 1] ADD NEG]) +; 0 [POPREF 2] +; 1 [PUSHFI 2] +; 2 MUL +; 3 [PUSHFI 1] +; 4 ADD +; 5 NEG +; nil +; user=> (dump '[HLT]) +; 0 HLT +; nil +; user=> (dump nil) +; 0 nil +; nil +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn dump +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; YA-DECLARADO-LOCALMENTE?: Recibe un identificador y un contexto (un vector formado por dos subvectores: el primero +; con las sucesivas posiciones de inicio de los distintos ambitos/scopes y el segundo con ternas +; [identificador, tipo, valor] resultantes de las declaraciones efectuadas, y devuelve true si el identificador esta +; declarado en el segundo subvector a partir de la ultima posicion guardada en el primer subvector (o sea, en el +; ambito/scope local); si no, devuelve false. +; Por ejemplo: +; user=> (ya-declarado-localmente? 'Write [[0] [['io ['lib '()] 0] ['Write ['lib '()] 0] ['entero_a_hexa ['fn [(list ['n (symbol ":") 'i64]) 'String]] 2]]]) +; true +; user=> (ya-declarado-localmente? 'Read [[0] [['io ['lib '()] 0] ['Write ['lib '()] 0] ['entero_a_hexa ['fn [(list ['n (symbol ":") 'i64]) 'String]] 2]]]) +; false +; user=> (ya-declarado-localmente? 'Write [[0 1] [['io ['lib '()] 0] ['Write ['lib '()] 0] ['entero_a_hexa ['fn [(list ['n (symbol ":") 'i64]) 'String]] 2]]]) +; true +; user=> (ya-declarado-localmente? 'Write [[0 2] [['io ['lib '()] 0] ['Write ['lib '()] 0] ['entero_a_hexa ['fn [(list ['n (symbol ":") 'i64]) 'String]] 2]]]) +; false +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn ya-declarado-localmente? +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CARGAR-CONST-EN-TABLA: Recibe un ambiente +; [simb-actual simb-no-parseados-aun simb-ya-parseados estado contexto prox-var bytecode mapa-regs-de-act] +; Si su estado no es :sin-errores, lo devuelve intacto. De lo contrario, lo devuelve modificado con la constante +; declarada como terna [identificador, tipo, valor] en el segundo subvector del vector contexto. +; Por ejemplo: +; user=> (cargar-const-en-tabla [(symbol ";") (list 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'println! (symbol "(") "{}" (symbol ",") 'TRES (symbol ")") (symbol "}")) ['use 'std (symbol "::") 'io (symbol ";") 'const 'TRES (symbol ":") 'i64 (symbol "=") 3] 8 [[0] [['io ['lib '()] 0]]] 0 [['CAL 0] 'HLT] []]) +; [; (fn main ( ) { println! ( "{}" , TRES ) }) [use std :: io ; const TRES : i64 = 3] 8 [[0] [[io [lib ()] 0]]] 0 [[CAL 0] HLT] []] +; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^ +; user=> (cargar-const-en-tabla [(symbol ";") (list 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'println! (symbol "(") "{}" (symbol ",") 'TRES (symbol ")") (symbol "}")) ['use 'std (symbol "::") 'io (symbol ";") 'const 'TRES (symbol ":") 'i64 (symbol "=") 3] :sin-errores [[0] [['io ['lib '()] 0]]] 0 [['CAL 0] 'HLT] []]) +; [; (fn main ( ) { println! ( "{}" , TRES ) }) [use std :: io ; const TRES : i64 = 3] :sin-errores [[0] [[io [lib ()] 0] [TRES [const i64] 3]]] 0 [[CAL 0] HLT] []] +; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +; (defn cargar-const-en-tabla +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; INICIALIZAR-CONTEXTO-LOCAL: Recibe un ambiente y, si su estado no es :sin-errores, lo devuelve intacto. +; De lo contrario, lo devuelve modificado con el tamano del segundo subvector del vector contexto agregado al final +; del primer subvector del vector contexto. +; Por ejemplo: +; user=> (inicializar-contexto-local [(symbol "{") (list 'let 'x (symbol ":") 'i64 (symbol "=") 10 (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x (symbol ")") (symbol "}")) ['fn 'main (symbol "(") (symbol ")")] 8 [[0] [['main ['fn [() ()]] 2]]] 0 [['CAL 2] 'HLT] []]) +; [{ (let x : i64 = 10 ; println! ( "{}" , x ) }) [fn main ( )] 8 [[0] [[main [fn [() ()]] 2]]] 0 [[CAL 2] HLT] []] +; ^ +; user=> (inicializar-contexto-local [(symbol "{") (list 'let 'x (symbol ":") 'i64 (symbol "=") 10 (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x (symbol ")") (symbol "}")) ['fn 'main (symbol "(") (symbol ")")] :sin-errores [[0] [['main ['fn [() ()]] 2]]] 0 [['CAL 2] 'HLT] []]) +; [{ (let x : i64 = 10 ; println! ( "{}" , x ) }) [fn main ( )] :sin-errores [[0 1] [[main [fn [() ()]] 2]]] 0 [[CAL 2] HLT] []] +; ^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +; (defn inicializar-contexto-local +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESTAURAR-CONTEXTO-ANTERIOR: Recibe un ambiente y, si su estado no es :sin-errores, lo devuelve intacto. +; De lo contrario, lo devuelve modificado, quitando la ultima frontera en el primer subvector del vector contexto, +; y sacando del final del segundo subvector del vector contexto los elementos ubicados a partir de la frontera quitada. +; Por ejemplo: +; user=> (restaurar-contexto-anterior ['EOF () ['fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'x (symbol ":") 'i64 (symbol "=") 10 (symbol ";") 'let 'y (symbol ":") 'i64 (symbol "=") 20 (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x '+ 'y (symbol ")") (symbol "}")] 8 [[0 1] [['main ['fn [() ()]] 2] ['x ['var-inmut 'i64] 0] ['y ['var-inmut 'i64] 1]]] 2 [['CAL 2] 'HLT ['PUSHFI 10] ['POP 0] ['PUSHFI 20] ['POP 1] ['PUSHFI "{}"] ['PUSHFM 0] ['PUSHFM 1] 'ADD ['PUSHFI 2] 'OUT 'NL] [[2 ['i64 nil] ['i64 nil]]]]) +; [EOF () [fn main ( ) { let x : i64 = 10 ; let y : i64 = 20 ; println! ( "{}" , x + y ) }] 8 [[0 1] [[main [fn [() ()]] 2] [x [var-inmut i64] 0] [y [var-inmut i64] 1]]] 2 [[CAL 2] HLT [PUSHFI 10] [POP 0] [PUSHFI 20] [POP 1] [PUSHFI "{}"] [PUSHFM 0] [PUSHFM 1] ADD [PUSHFI 2] OUT NL] [[2 [i64 nil] [i64 nil]]]] +; ^ +; user=> (restaurar-contexto-anterior ['EOF () ['fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'x (symbol ":") 'i64 (symbol "=") 10 (symbol ";") 'let 'y (symbol ":") 'i64 (symbol "=") 20 (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x '+ 'y (symbol ")") (symbol "}")] :sin-errores [[0 1] [['main ['fn [() ()]] 2] ['x ['var-inmut 'i64] 0] ['y ['var-inmut 'i64] 1]]] 2 [['CAL 2] 'HLT ['PUSHFI 10] ['POP 0] ['PUSHFI 20] ['POP 1] ['PUSHFI "{}"] ['PUSHFM 0] ['PUSHFM 1] 'ADD ['PUSHFI 2] 'OUT 'NL] [[2 ['i64 nil] ['i64 nil]]]]) +; [EOF () [fn main ( ) { let x : i64 = 10 ; let y : i64 = 20 ; println! ( "{}" , x + y ) }] :sin-errores [[0] [[main [fn [() ()]] 2]]] 2 [[CAL 2] HLT [PUSHFI 10] [POP 0] [PUSHFI 20] [POP 1] [PUSHFI "{}"] [PUSHFM 0] [PUSHFM 1] ADD [PUSHFI 2] OUT NL] [[2 [i64 nil] [i64 nil]]]] +; ^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +; (defn restaurar-contexto-anterior +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; BUSCAR-TIPO-DE-RETORNO: Recibe un ambiente y la direccion de una funcion a ser buscada en el segundo subvector del +; vector contexto. Si la encuentra, devuelve el tipo de dato de retorno de la funcion o la lista vacia si se trata de +; un procedimiento. Si no, devuelve nil. +; Por ejemplo: +; user=> (buscar-tipo-de-retorno [(symbol ";") (list 'println! (symbol "(") "La suma de 5 mas 7 es {}" (symbol ",") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")") (symbol ")") (symbol ";") (symbol "}")) ['fn 'suma (symbol "(") 'x (symbol ":") 'i64 (symbol ",") 'y (symbol ":") 'i64 (symbol ")") (symbol "->") 'i64 (symbol "{") 'x '+ 'y (symbol "}") 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")")] :sin-errores [[0 2] [['suma ['fn [(list ['x (symbol ":") 'i64] ['y (symbol ":") 'i64]) 'i64]] 2] ['main ['fn [() ()]] 8]]] 0 [['CAL 8] 'HLT ['POPARG 1] ['POPARG 0] ['PUSHFM 0] ['PUSHFM 1] 'ADD 'RET ['PUSHFI 5] ['PUSHFI 7] ['CAL 2]] [[2 ['i64 nil] ['i64 nil]] [8]]] 2) +; i64 ^^^ ^ ^ +; user=> (buscar-tipo-de-retorno [(symbol ";") (list 'println! (symbol "(") "La suma de 5 mas 7 es {}" (symbol ",") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")") (symbol ")") (symbol ";") (symbol "}")) ['fn 'suma (symbol "(") 'x (symbol ":") 'i64 (symbol ",") 'y (symbol ":") 'i64 (symbol ")") (symbol "->") 'i64 (symbol "{") 'x '+ 'y (symbol "}") 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")")] :sin-errores [[0 2] [['suma ['fn [(list ['x (symbol ":") 'i64] ['y (symbol ":") 'i64]) 'i64]] 2] ['main ['fn [() ()]] 8]]] 0 [['CAL 8] 'HLT ['POPARG 1] ['POPARG 0] ['PUSHFM 0] ['PUSHFM 1] 'ADD 'RET ['PUSHFI 5] ['PUSHFI 7] ['CAL 2]] [[2 ['i64 nil] ['i64 nil]] [8]]] 8) +; () ^^ ^ ^ +; user=> (buscar-tipo-de-retorno [(symbol ";") (list 'println! (symbol "(") "La suma de 5 mas 7 es {}" (symbol ",") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")") (symbol ")") (symbol ";") (symbol "}")) ['fn 'suma (symbol "(") 'x (symbol ":") 'i64 (symbol ",") 'y (symbol ":") 'i64 (symbol ")") (symbol "->") 'i64 (symbol "{") 'x '+ 'y (symbol "}") 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'suma (symbol "(") 5 (symbol ",") 7 (symbol ")")] :sin-errores [[0 2] [['suma ['fn [(list ['x (symbol ":") 'i64] ['y (symbol ":") 'i64]) 'i64]] 2] ['main ['fn [() ()]] 8]]] 0 [['CAL 8] 'HLT ['POPARG 1] ['POPARG 0] ['PUSHFM 0] ['PUSHFM 1] 'ADD 'RET ['PUSHFI 5] ['PUSHFI 7] ['CAL 2]] [[2 ['i64 nil] ['i64 nil]] [8]]] 1) +; nil +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;TODO +;(defn buscar-tipo-de-retorno +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GENERAR-REF: Recibe un ambiente y, si su estado no es :sin-errores, lo devuelve intacto. +; De lo contrario, lo devuelve modificado, generando (llamando a generar) una instruccion PUSHADDR con la direccion +; de la ultima variable proveniente de simb-ya-parseados. Esta direccion sera la de la ultima coincidencia de la +; variable anterior en el segundo subvector del vector contexto. +; Por ejemplo: +; user=> (generar-ref [(symbol ")") (list (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'v (symbol ")") (symbol ";") (symbol "}")) ['fn 'inc (symbol "(") 'v (symbol ":") (symbol "&") 'mut 'i64 (symbol ")") (symbol "{") '* 'v (symbol "+=") 1 (symbol ";") (symbol "}") 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'mut 'v (symbol ":") 'i64 (symbol "=") 5 (symbol ";") 'inc (symbol "(") (symbol "&") 'mut 'v] 8 [[0 2] [['inc ['fn [(list ['v (symbol ":") (symbol "&") 'mut 'i64]) ()]] 2] ['main ['fn [() ()]] 6] ['v ['var-mut 'i64] 0]]] 1 [['CAL 6] 'HLT ['POPARG 0] ['PUSHFI 1] ['POPADDREF 0] 'RETN ['PUSHFI 5] ['POP 0]] [[2 ['i64 nil]] [6 ['i64 nil]]]]) +; [) (; println! ( "{}" , v ) ; }) [fn inc ( v : & mut i64 ) { * v += 1 ; } fn main ( ) { let mut v : i64 = 5 ; inc ( & mut v] 8 [[0 2] [[inc [fn [([v : & mut i64]) ()]] 2] [main [fn [() ()]] 6] [v [var-mut i64] 0]]] 1 [[CAL 6] HLT [POPARG 0] [PUSHFI 1] [POPADDREF 0] RETN [PUSHFI 5] [POP 0]] [[2 [i64 nil]] [6 [i64 nil]]]] +; ^ +; user=> (generar-ref [(symbol ")") (list (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'v (symbol ")") (symbol ";") (symbol "}")) ['fn 'inc (symbol "(") 'v (symbol ":") (symbol "&") 'mut 'i64 (symbol ")") (symbol "{") '* 'v (symbol "+=") 1 (symbol ";") (symbol "}") 'fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'mut 'v (symbol ":") 'i64 (symbol "=") 5 (symbol ";") 'inc (symbol "(") (symbol "&") 'mut 'v] :sin-errores [[0 2] [['inc ['fn [(list ['v (symbol ":") (symbol "&") 'mut 'i64]) ()]] 2] ['main ['fn [() ()]] 6] ['v ['var-mut 'i64] 0]]] 1 [['CAL 6] 'HLT ['POPARG 0] ['PUSHFI 1] ['POPADDREF 0] 'RETN ['PUSHFI 5] ['POP 0]] [[2 ['i64 nil]] [6 ['i64 nil]]]]) +; [) (; println! ( "{}" , v ) ; }) [fn inc ( v : & mut i64 ) { * v += 1 ; } fn main ( ) { let mut v : i64 = 5 ; inc ( & mut v] :sin-errores [[0 2] [[inc [fn [([v : & mut i64]) ()]] 2] [main [fn [() ()]] 6] [v [var-mut i64] 0]]] 1 [[CAL 6] HLT [POPARG 0] [PUSHFI 1] [POPADDREF 0] RETN [PUSHFI 5] [POP 0] [PUSHADDR 0]] [[2 [i64 nil]] [6 [i64 nil]]]] +; ^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn generar-ref +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; FIXUP: Recibe un ambiente y la ubicacion de un JMP ? a corregir en el vector de bytecode. Si el estado no es +; :sin-errores, devuelve el ambiente intacto. De lo contrario, lo devuelve con el JMP corregido con el tamano del +; vector de bytecode. +; Por ejemplo: +; user=> (fixup [(symbol "{") (list 'x '= 20 (symbol ";") (symbol "}") (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x (symbol ")") (symbol "}")) ['fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'x (symbol ":") 'i64 (symbol ";") 'if false (symbol "{") 'x '= 10 (symbol ";") (symbol "}") 'else] 8 [[0 1 2] [['main ['fn [() ()]] 2] ['x ['var-inmut 'i64] 0]]] 1 [['CAL 2] 'HLT ['PUSHFI false] ['JC 5] ['JMP '?] ['PUSHFI 10] ['POP 0] ['JMP '?]] [[2 ['i64 nil]]]] 4) +; [{ (x = 20 ; } ; println! ( "{}" , x ) }) [fn main ( ) { let x : i64 ; if false { x = 10 ; } else] 8 [[0 1 2] [[main [fn [() ()]] 2] [x [var-inmut i64] 0]]] 1 [[CAL 2] HLT [PUSHFI false] [JC 5] [JMP ?] [PUSHFI 10] [POP 0] [JMP ?]] [[2 [i64 nil]]]] +; ^ +; user=> (fixup [(symbol "{") (list 'x '= 20 (symbol ";") (symbol "}") (symbol ";") 'println! (symbol "(") "{}" (symbol ",") 'x (symbol ")") (symbol "}")) ['fn 'main (symbol "(") (symbol ")") (symbol "{") 'let 'x (symbol ":") 'i64 (symbol ";") 'if false (symbol "{") 'x '= 10 (symbol ";") (symbol "}") 'else] :sin-errores [[0 1 2] [['main ['fn [() ()]] 2] ['x ['var-inmut 'i64] 0]]] 1 [['CAL 2] 'HLT ['PUSHFI false] ['JC 5] ['JMP '?] ['PUSHFI 10] ['POP 0] ['JMP '?]] [[2 ['i64 nil]]]] 4) +; [{ (x = 20 ; } ; println! ( "{}" , x ) }) [fn main ( ) { let x : i64 ; if false { x = 10 ; } else] :sin-errores [[0 1 2] [[main [fn [() ()]] 2] [x [var-inmut i64] 0]]] 1 [[CAL 2] HLT [PUSHFI false] [JC 5] [JMP 8] [PUSHFI 10] [POP 0] [JMP ?]] [[2 [i64 nil]]]] +; ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^: tamano 8 ^ ubicacion de JMP ? en contexto +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +; (defn fixup +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONVERTIR-FORMATO-IMPRESION: Recibe una lista con los argumentos de print! de Rust y devuelve una lista con los +; argumentos equivalentes de printf de Clojure. +; Por ejemplo: +; user=> (convertir-formato-impresion '("Hola, mundo!")) +; ("Hola, mundo!") +; user=> (convertir-formato-impresion '("- My name is {}, James {}.\n- Hello, {}{}{}!" "Bond" "Bond" 0 0 7)) +; ("- My name is %s, James %s.\n- Hello, %d%d%d!" "Bond" "Bond" 0 0 7) +; user=> (convertir-formato-impresion '("{} elevado a la {} es\t{}" 2.0 2 4.0)) +; ("%.0f elevado a la %d es\t%.0f" 2.0 2 4.0) +; user=> (convertir-formato-impresion '("Las raices cuadradas de {} son +{:.8} y -{:.8}" 4.0 1.999999999985448 1.999999999985448)) +; ("Las raices cuadradas de %.0f son +%.8f y -%.8f" 4.0 1.999999999985448 1.999999999985448) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn convertir-formato-impresion +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; DIVIDIR: Recibe dos numeros y devuelve su cociente, manteniendo su tipo. +; Por ejemplo: +; user=> (dividir 12 3) +; 4 +; user=> (dividir 12.0 3) +; 4.0 +; user=> (dividir 12 3.0) +; 4.0 +; user=> (dividir 12.0 3.0) +; 4.0 +; user=> (dividir 1 2) +; 0 +; user=> (dividir 1 2.0) +; 0.5 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn dividir +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; COMPATIBLES?: Recibe dos elementos. Si el primero es un tipo de dato de Rust y el segundo es un valor de Clojure +; de un tipo de dato compatible con el mismo o un vector, devuelve true. Si no, false. +; Por ejemplo: +; user=> (compatibles? 'i64 5) +; true +; user=> (compatibles? 'i64 5.0) +; false +; user=> (compatibles? 'i64 [5.0]) +; true +; user=> (compatibles? 'f64 5.0) +; true +; user=> (compatibles? 'String "Hola") +; true +; user=> (compatibles? 'bool true) +; true +; user=> (compatibles? 'bool 1) +; false +; user=> (compatibles? 'usize 1) +; true +; user=> (compatibles? 'char \a) +; true +; user=> (compatibles? 'char 'a) +; false +; user=> (compatibles? 'char ['a]) +; true +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn compatibles? +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PASAR-A-INT: Recibe un elemento. Si puede devolverlo expresado como un entero, lo hace. Si no, lo devuelve intacto. +; Por ejemplo: +; user=> (pasar-a-int "10") +; 10 +; user=> (pasar-a-int 10.0) +; 10 +; user=> (pasar-a-int 10) +; 10 +; user=> (pasar-a-int 'a) +; a +; user=> (pasar-a-int [10.0]) +; [10.0] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn pasar-a-int +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PASAR-A-FLOAT: Recibe un elemento. Si puede devolverlo expresado como un numero de punto flotante, lo hace. Si no, +; lo devuelve intacto. +; Por ejemplo: +; user=> (pasar-a-float "10") +; 10.0 +; user=> (pasar-a-float 10) +; 10.0 +; user=> (pasar-a-float 10.0) +; 10.0 +; user=> (pasar-a-float 'a) +; a +; user=> (pasar-a-float [10]) +; [10] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defn pasar-a-float [arg] + (int arg) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CARGAR-EN-ULT-REG: Recibe un vector de registros de activacion, una direccion, un tipo y un valor. Devuelve el +; vector de registros de activacion con el ultimo registro actualizado, en la direccion indicada, con el nuevo tipo +; y el nuevo valor. +; Por ejemplo: +; user=> (cargar-en-ult-reg [[['String "2"] ['i64 6] ['i64 2] ['i64 3] ['i64 0]] [['i64 nil] ['i64 nil]]] 1 'i64 0) +; [[[String "2"] [i64 6] [i64 2] [i64 3] [i64 0]] [[i64 nil] [i64 0]]] +; ^^^ ^ +; user=> (cargar-en-ult-reg [[['String "2"] ['i64 6] ['i64 2] ['i64 3] ['i64 0]] [['i64 nil] ['i64 0]]] 0 'f64 3) +; [[[String "2"] [i64 6] [i64 2] [i64 3] [i64 0]] [[f64 3] [i64 0]]] +; ^^^ ^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +; (defn cargar-en-ult-reg +; +;) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CARGAR-EN-REG-DEST: Recibe un vector de registros de activacion, coordenadas, un tipo y un valor. Devuelve el +; vector de registros de activacion con el registro indicado por las coordenadas actualizado, con el nuevo tipo +; y el nuevo valor. +; +; Por ejemplo: +; user=> (cargar-en-reg-dest [[['String "2"] ['i64 6] ['i64 2] ['i64 2] ['i64 2]] [['i64 6] ['i64 2] ['i64 [0 3]] ['i64 [0 4]] ['i64 2] ['i64 2]]] [0 4] 'i64 0) +; [[[String "2"] [i64 6] [i64 2] [i64 2] [i64 0]] [[i64 6] [i64 2] [i64 [0 3]] [i64 [0 4]] [i64 2] [i64 2]]] +; ^^^ ^ +; user=> (cargar-en-reg-dest [[['String "2"] ['i64 6] ['i64 2] ['i64 2] ['i64 0]] [['i64 6] ['i64 2] ['i64 [0 3]] ['i64 [0 4]] ['i64 2] ['i64 2]]] [0 3] 'f64 3) +; [[[String "2"] [i64 6] [i64 2] [f64 3] [i64 0]] [[i64 6] [i64 2] [i64 [0 3]] [i64 [0 4]] [i64 2] [i64 2]]] +; ^^^ ^ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO +;(defn cargar-en-reg-dest +; +;) + +true diff --git a/test/rustint/core_test.clj b/test/rustint/core_test.clj new file mode 100644 index 0000000..d686343 --- /dev/null +++ b/test/rustint/core_test.clj @@ -0,0 +1,9 @@ +(ns rustint.core-test + (:require [clojure.test :refer :all] + [rustint.core :refer :all])) + +(deftest pasar-a-float-test01 + (testing "Test 01 pasar-a-float" + (pasar-a-float 10) + ) +)