├── src ├── doc │ ├── .lock │ ├── main │ │ ├── sidebar-items.js │ │ ├── all.html │ │ └── index.html │ ├── token │ │ ├── sidebar-items.js │ │ ├── token │ │ │ ├── sidebar-items.js │ │ │ ├── fn.lookup_ident.html │ │ │ └── index.html │ │ ├── all.html │ │ └── index.html │ ├── rust-logo.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── FiraSans-Medium.woff │ ├── FiraSans-Regular.woff │ ├── SourceCodePro-Regular.woff │ ├── SourceSerifPro-It.ttf.woff │ ├── SourceCodePro-Semibold.woff │ ├── SourceSerifPro-Bold.ttf.woff │ ├── SourceSerifPro-Regular.ttf.woff │ ├── noscript.css │ ├── implementors │ │ ├── core │ │ │ ├── clone │ │ │ │ └── trait.Clone.js │ │ │ ├── fmt │ │ │ │ └── trait.Debug.js │ │ │ ├── marker │ │ │ │ ├── trait.Send.js │ │ │ │ ├── trait.Sync.js │ │ │ │ ├── trait.Unpin.js │ │ │ │ ├── trait.Freeze.js │ │ │ │ └── trait.StructuralPartialEq.js │ │ │ └── cmp │ │ │ │ └── trait.PartialEq.js │ │ └── std │ │ │ └── panic │ │ │ ├── trait.UnwindSafe.js │ │ │ └── trait.RefUnwindSafe.js │ ├── brush.svg │ ├── source-files.js │ ├── down-arrow.svg │ ├── settings.js │ ├── settings.css │ ├── README.html │ ├── LICENSE-MIT.txt │ ├── theme.js │ ├── search-index.js │ ├── normalize.css │ ├── COPYRIGHT.txt │ ├── storage.js │ ├── src │ │ ├── main │ │ │ ├── repl │ │ │ │ ├── mod.rs.html │ │ │ │ └── repl.rs.html │ │ │ ├── token │ │ │ │ ├── mod.rs.html │ │ │ │ └── token.rs.html │ │ │ ├── eval │ │ │ │ ├── mod.rs.html │ │ │ │ └── env.rs.html │ │ │ ├── parser │ │ │ │ ├── mod.rs.html │ │ │ │ └── ast.rs.html │ │ │ ├── lexer │ │ │ │ ├── mod.rs.html │ │ │ │ └── lexer_test.rs.html │ │ │ └── main.rs.html │ │ └── token │ │ │ └── token.rs.html │ ├── source-script.js │ ├── wheel.svg │ ├── favicon.svg │ ├── FiraSans-LICENSE.txt │ ├── SourceSerifPro-LICENSE.md │ ├── SourceCodePro-LICENSE.txt │ ├── settings.html │ ├── light.css │ ├── dark.css │ ├── ayu.css │ └── LICENSE-APACHE.txt ├── tests │ ├── mod.rs │ ├── token_test.rs │ └── lexer_test.rs ├── lexer │ ├── mod.rs │ └── lexer.rs ├── eval │ ├── mod.rs │ └── env.rs ├── repl │ ├── mod.rs │ ├── repl.rs │ └── interpreter.rs ├── parser │ ├── mod.rs │ ├── ast.rs │ └── parser.rs ├── token │ ├── mod.rs │ └── token.rs └── main.rs ├── examples ├── prints.uwu ├── fib.uwu ├── factorial.uwu └── rec_fizzbuzz.uwu ├── images └── uwucode_logo.png ├── Cargo.toml ├── .gitignore ├── LICENSE └── README.md /src/doc/.lock: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/doc/main/sidebar-items.js: -------------------------------------------------------------------------------- 1 | initSidebarItems({}); -------------------------------------------------------------------------------- /examples/prints.uwu: -------------------------------------------------------------------------------- 1 | 2 | 3 | dprint("Hello world!"); 4 | 5 | dprint(2+5); -------------------------------------------------------------------------------- /src/doc/token/sidebar-items.js: -------------------------------------------------------------------------------- 1 | initSidebarItems({"mod":[["token","token docs"]]}); -------------------------------------------------------------------------------- /src/tests/mod.rs: -------------------------------------------------------------------------------- 1 | //! Self explanatory. 2 | mod lexer_test; 3 | mod token_test; 4 | -------------------------------------------------------------------------------- /src/doc/rust-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/rust-logo.png -------------------------------------------------------------------------------- /src/lexer/mod.rs: -------------------------------------------------------------------------------- 1 | //! The lexer module turns input into a vector of tokens. 2 | pub mod lexer; 3 | -------------------------------------------------------------------------------- /images/uwucode_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/images/uwucode_logo.png -------------------------------------------------------------------------------- /src/doc/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/favicon-16x16.png -------------------------------------------------------------------------------- /src/doc/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/favicon-32x32.png -------------------------------------------------------------------------------- /src/doc/token/token/sidebar-items.js: -------------------------------------------------------------------------------- 1 | initSidebarItems({"enum":[["Token",""]],"fn":[["lookup_ident",""]]}); -------------------------------------------------------------------------------- /src/doc/FiraSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/FiraSans-Medium.woff -------------------------------------------------------------------------------- /src/doc/FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/FiraSans-Regular.woff -------------------------------------------------------------------------------- /src/doc/SourceCodePro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/SourceCodePro-Regular.woff -------------------------------------------------------------------------------- /src/doc/SourceSerifPro-It.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/SourceSerifPro-It.ttf.woff -------------------------------------------------------------------------------- /src/doc/SourceCodePro-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/SourceCodePro-Semibold.woff -------------------------------------------------------------------------------- /src/doc/SourceSerifPro-Bold.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/SourceSerifPro-Bold.ttf.woff -------------------------------------------------------------------------------- /src/doc/SourceSerifPro-Regular.ttf.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saikumarmk/uwucode/HEAD/src/doc/SourceSerifPro-Regular.ttf.woff -------------------------------------------------------------------------------- /src/eval/mod.rs: -------------------------------------------------------------------------------- 1 | //! The eval module evaluates parsed statements and returns object enums. 2 | //! 3 | 4 | pub mod env; 5 | pub mod eval; 6 | -------------------------------------------------------------------------------- /src/repl/mod.rs: -------------------------------------------------------------------------------- 1 | //! The REPL module contains the code that creates a REPL or evaluates a file. 2 | 3 | pub mod interpreter; 4 | pub mod repl; 5 | -------------------------------------------------------------------------------- /src/parser/mod.rs: -------------------------------------------------------------------------------- 1 | //! The parser joins together tokens to create statements that consist of expressions. 2 | //! 3 | 4 | pub mod ast; 5 | pub mod parser; 6 | -------------------------------------------------------------------------------- /src/doc/noscript.css: -------------------------------------------------------------------------------- 1 | #main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;}#main>h2+div,#main>h3+div{display:block;}#main>h2+h3{display:flex;} -------------------------------------------------------------------------------- /src/token/mod.rs: -------------------------------------------------------------------------------- 1 | //! 2 | //! The token module stores the atomic elements require to interpret user input. That means keywords, primitives and everything else is stored in some form of a token. 3 | //! 4 | 5 | pub mod token; 6 | -------------------------------------------------------------------------------- /examples/fib.uwu: -------------------------------------------------------------------------------- 1 | 2 | 3 | uwu fib(x) { 4 | nuzzles (x<=1) { 5 | sugoi x; 6 | } 7 | rawr { 8 | sugoi fib(x-1)+fib(x-2); 9 | }; 10 | }; 11 | 12 | dprint(fib(10)); 13 | dprint(fib(20)); /* This takes a very long time to evaluate. */ -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uwucode" 3 | version = "0.1.0" 4 | authors = ["Sai kumar Murali krishnan "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | colored = "2" -------------------------------------------------------------------------------- /src/doc/implementors/core/clone/trait.Clone.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Clone for Token","synthetic":false,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/fmt/trait.Debug.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Debug for Token","synthetic":false,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/marker/trait.Send.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Send for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/marker/trait.Sync.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Sync for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/marker/trait.Unpin.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Unpin for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/marker/trait.Freeze.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl Freeze for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/std/panic/trait.UnwindSafe.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl UnwindSafe for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/std/panic/trait.RefUnwindSafe.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl RefUnwindSafe for Token","synthetic":true,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/cmp/trait.PartialEq.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl PartialEq<Token> for Token","synthetic":false,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /src/doc/implementors/core/marker/trait.StructuralPartialEq.js: -------------------------------------------------------------------------------- 1 | (function() {var implementors = {}; 2 | implementors["token"] = [{"text":"impl StructuralPartialEq for Token","synthetic":false,"types":[]}]; 3 | if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() -------------------------------------------------------------------------------- /examples/factorial.uwu: -------------------------------------------------------------------------------- 1 | owo hehexd = 1; 2 | 3 | /* Comments can be written similar to Rust/C++. */ 4 | uwu fact(lel) { 5 | nuzzles (lel==hehexd) { 6 | sugoi lel; 7 | } 8 | rawr { 9 | sugoi lel*fact(lel-hehexd); 10 | }; 11 | }; 12 | 13 | /* One can use dprint to print function values */ 14 | dprint(fact(4)); 15 | dprint(fact(20)); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # vscode 13 | /.vscode/ 14 | -------------------------------------------------------------------------------- /src/doc/brush.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/doc/source-files.js: -------------------------------------------------------------------------------- 1 | var N = null;var sourcesIndex = {}; 2 | sourcesIndex["main"] = {"name":"","dirs":[{"name":"eval","files":["env.rs","eval.rs","mod.rs"]},{"name":"lexer","files":["lexer.rs","lexer_test.rs","mod.rs"]},{"name":"parser","files":["ast.rs","mod.rs","parser.rs"]},{"name":"repl","files":["mod.rs","repl.rs"]},{"name":"token","files":["mod.rs","token.rs"]}],"files":["main.rs","tests.rs"]}; 3 | sourcesIndex["token"] = {"name":"","files":["token.rs"]}; 4 | createSourceSidebar(); 5 | -------------------------------------------------------------------------------- /src/doc/down-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/doc/settings.js: -------------------------------------------------------------------------------- 1 | (function(){function changeSetting(settingName,isEnabled){updateLocalStorage('rustdoc-'+settingName,isEnabled)}function getSettingValue(settingName){return getCurrentValue('rustdoc-'+settingName)}function setEvents(){var elems=document.getElementsByClassName("slider");if(!elems||elems.length===0){return}for(var i=0;idiv{max-width:calc(100% - 74px);display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.setting-line>.title{font-size:19px;width:100%;max-width:none;border-bottom:1px solid;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{display:none;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 1px #2196F3;}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;} -------------------------------------------------------------------------------- /src/doc/README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Docs 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 |

Docs

22 |

This is the documentation for uwucode.

24 |

0.1 Introduction

25 |
26 | owo var_name = value;
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/doc/LICENSE-MIT.txt: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Theorvolt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/repl/repl.rs: -------------------------------------------------------------------------------- 1 | use crate::eval::eval::{eval_return, Env, Object}; 2 | use crate::lexer::lexer::Lexer; 3 | use crate::parser::parser::parse; 4 | use ::std::io::Write; 5 | use std::io; 6 | use std::process; 7 | 8 | use colored::*; 9 | 10 | const PROMPT: &str = "( ᴜ ω ᴜ )⭜"; 11 | 12 | pub fn start() { 13 | println!("uwu *nuzzles* wewcome to uwucode! Is for me..? 🥺👉👈"); 14 | let mut env = Env::new(); 15 | loop { 16 | print!("{} ", PROMPT.truecolor(255, 69, 0)); 17 | std::io::stdout().flush().expect("Flushing failed"); 18 | let mut user_in: String = String::new(); 19 | io::stdin().read_line(&mut user_in).expect("Could not read"); 20 | let mut lexer = Lexer::new(&user_in as &str); 21 | let mut token_vec = lexer.lex(); 22 | 23 | let parsed = parse(&mut token_vec); 24 | 25 | let evaluated = match eval_return(parsed, &mut env) { 26 | Object::Terminate => { 27 | println!("{}", Object::Terminate); 28 | process::exit(69); 29 | } 30 | val => val, 31 | }; 32 | println!("{}", evaluated); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/doc/theme.js: -------------------------------------------------------------------------------- 1 | var themes=document.getElementById("theme-choices");var themePicker=document.getElementById("theme-picker");function showThemeButtonState(){themes.style.display="block";themePicker.style.borderBottomRightRadius="0";themePicker.style.borderBottomLeftRadius="0"}function hideThemeButtonState(){themes.style.display="none";themePicker.style.borderBottomRightRadius="3px";themePicker.style.borderBottomLeftRadius="3px"}function switchThemeButtonState(){if(themes.style.display==="block"){hideThemeButtonState()}else{showThemeButtonState()}};function handleThemeButtonsBlur(e){var active=document.activeElement;var related=e.relatedTarget;if(active.id!=="themePicker"&&(!active.parentNode||active.parentNode.id!=="theme-choices")&&(!related||(related.id!=="themePicker"&&(!related.parentNode||related.parentNode.id!=="theme-choices")))){hideThemeButtonState()}}themePicker.onclick=switchThemeButtonState;themePicker.onblur=handleThemeButtonsBlur;["ayu","dark","light"].forEach(function(item){var but=document.createElement('button');but.textContent=item;but.onclick=function(el){switchTheme(currentTheme,mainTheme,item,true)};but.onblur=handleThemeButtonsBlur;themes.appendChild(but)}) -------------------------------------------------------------------------------- /src/repl/interpreter.rs: -------------------------------------------------------------------------------- 1 | use crate::eval::eval::{eval_return_single, Env, Object}; 2 | use crate::lexer::lexer::Lexer; 3 | use crate::parser::parser::parse; 4 | use std::fs; 5 | use std::process; 6 | 7 | pub fn file_interpret(file_name: &str) { 8 | println!("uwu *nuzzles* wewcome to uwucode! Is for me..? 🥺👉👈"); 9 | let mut env = Env::new(); 10 | 11 | let file_str = match fs::read_to_string(file_name) { 12 | Ok(val) => val, 13 | Err(_) => panic!("File not found, or unreadable"), 14 | }; 15 | 16 | let mut lexer = Lexer::new(&file_str); 17 | let mut token_vec = lexer.lex(); 18 | 19 | let parsed = parse(&mut token_vec); 20 | /* 21 | Match action, i.e Print, Terminate, or Exit 22 | */ 23 | for parsed_expr in parsed.iter() { 24 | match eval_return_single(parsed_expr, &mut env) { 25 | Object::Terminate => { 26 | println!("{}", Object::Terminate); 27 | process::exit(69); 28 | } 29 | Object::Print(value) => { 30 | println!("{}", value); 31 | } 32 | _ => print!(""), 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //! # What is uwucode? 2 | //! uwucode is an atrocity. In all seriousness, uwucode is a satirical programming language that incorporates egirl slang to make it nearly unreadable. Take for example the following: 3 | //! ``` 4 | //! owo hehexd = 1; 5 | //! uwu nya(lel) {nuzzles (lel==hehexd) {sugoi hehexd;} rawr {sugoi lel*nya(lel-hehexd);};}; 6 | //! nya(5); // -> 120 7 | //! ``` 8 | //! Of course, one may recognize this is a recursive implementation of the factorial function, however it looks like a mess to anyone else. 9 | 10 | mod eval; 11 | mod lexer; 12 | mod parser; 13 | mod repl; 14 | mod tests; 15 | mod token; 16 | use std::env; 17 | 18 | /// uwucode takes in the following arguments: 19 | /// repl | open 20 | /// # repl 21 | /// Opens a REPl to evaluate uwucode. Takes in no additional arguments. 22 | /// 23 | /// # open 24 | /// Takes in one argument, which is the filepath. 25 | fn main() { 26 | let args: Vec = env::args().collect(); 27 | match args[1].as_ref() { 28 | "repl" => repl::repl::start(), 29 | "open" => repl::interpreter::file_interpret(args[2].as_ref()), 30 | 31 | val => panic!("{} is not a recognized argument", val), 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tests/token_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | use crate::token::token::*; 4 | 5 | #[test] 6 | fn test_lookup_ident() { 7 | struct TestingStruct { 8 | token_vec: Vec, 9 | } 10 | let inputs: Vec<&str> = vec![ 11 | "uwu", "owo", "nuzzles", "dab", "rawr", "sugoi", "truwu", "fowose", "Hello!", 12 | ]; 13 | 14 | let tests: TestingStruct = TestingStruct { 15 | token_vec: vec![ 16 | Token::FUNCTION, 17 | Token::LET, 18 | Token::IF, 19 | Token::ELIF, 20 | Token::ELSE, 21 | Token::RETURN, 22 | Token::TRUE, 23 | Token::FALSE, 24 | Token::IDENT(String::from("Hello!")), 25 | ], 26 | }; 27 | // You may ask, what the hell is the resultant iterator here?? Tbh, I'm not sure as well... 28 | // In all seriousness,unlike Python, zip is a method for tying iterators, where the argument (not self!) is the second element. 29 | // Diagram: A.iter().zip(B.iter()) -> iter(a,b). 30 | for (input, test) in inputs.iter().zip(tests.token_vec.iter()) { 31 | assert_eq!(&lookup_ident(input), test); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/doc/search-index.js: -------------------------------------------------------------------------------- 1 | var searchIndex = JSON.parse('{\ 2 | "main":{"doc":"","i":[],"p":[]},\ 3 | "token":{"doc":"","i":[[0,"token","token","token docs",null,null],[4,"Token","token::token","",null,null],[13,"ILLEGAL","","",0,null],[13,"EOF","","",0,null],[13,"IDENT","","",0,null],[13,"ASSIGN","","",0,null],[13,"PLUS","","",0,null],[13,"MINUS","","",0,null],[13,"ASTERISK","","",0,null],[13,"SLASH","","",0,null],[13,"EQ","","",0,null],[13,"LEQ","","",0,null],[13,"LE","","",0,null],[13,"GEQ","","",0,null],[13,"GE","","",0,null],[13,"NEQ","","",0,null],[13,"COMMA","","",0,null],[13,"SEMICOLON","","",0,null],[13,"LPAR","","",0,null],[13,"RPAR","","",0,null],[13,"LBRA","","",0,null],[13,"RBRA","","",0,null],[13,"BANG","","",0,null],[13,"FUNCTION","","",0,null],[13,"LET","","",0,null],[13,"RETURN","","",0,null],[13,"IF","","",0,null],[13,"ELIF","","",0,null],[13,"ELSE","","",0,null],[13,"INT","","",0,null],[13,"STRING","","",0,null],[13,"TRUE","","",0,null],[13,"FALSE","","",0,null],[5,"lookup_ident","","",null,[[],["token",4]]],[11,"from","","",0,[[]]],[11,"into","","",0,[[]]],[11,"to_owned","","",0,[[]]],[11,"clone_into","","",0,[[]]],[11,"borrow","","",0,[[]]],[11,"borrow_mut","","",0,[[]]],[11,"try_from","","",0,[[],["result",4]]],[11,"try_into","","",0,[[],["result",4]]],[11,"type_id","","",0,[[],["typeid",3]]],[11,"clone","","",0,[[],["token",4]]],[11,"eq","","",0,[[["token",4]]]],[11,"ne","","",0,[[["token",4]]]],[11,"fmt","","",0,[[["formatter",3]],["result",6]]]],"p":[[4,"Token"]]}\ 4 | }'); 5 | addSearchOptions(searchIndex);initSearch(searchIndex); -------------------------------------------------------------------------------- /src/eval/env.rs: -------------------------------------------------------------------------------- 1 | //! Handles the scoping of functions and various contexts. 2 | use crate::eval::eval::Object; 3 | use std::collections::HashMap; 4 | 5 | /// Scopes contain bound variables and expressions. 6 | #[derive(Clone)] 7 | pub struct Env { 8 | pub space: HashMap, 9 | pub enclosing: Option>, // Pointer to a scope or nothing. 10 | } 11 | 12 | impl Env { 13 | /// Instantiates a new environment object with no outer scope. 14 | pub fn new() -> Self { 15 | Env { 16 | space: HashMap::new(), 17 | enclosing: None, 18 | } 19 | } 20 | 21 | /// Defines a variable/function in the current scope. 22 | pub fn set(&mut self, key: String, value: Object) { 23 | self.space.insert(key, value); 24 | } 25 | 26 | /// Recursively attempts to get a variable/functions value. 27 | pub fn get(&self, key: &str) -> Option { 28 | match (self.space.get(key), &self.enclosing) { 29 | (Some(val), _) => Some(val.clone()), // Variable found 30 | (None, Some(enclose)) => enclose.get(key), // Query outer scope 31 | (None, _) => None, // Variable not found at outermost scope 32 | } 33 | } 34 | 35 | // Enclosing = outer or global typically. 36 | pub fn new_enclosing(outer: Self) -> Self { 37 | let mut env = Self::new(); 38 | env.enclosing = Some(Box::new(outer)); // Pointer to original object 39 | env // Return the inner environment 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/token/token.rs: -------------------------------------------------------------------------------- 1 | /// 2 | /// Maps an identifier to a keyword or a variable/function. 3 | /// # Examples 4 | /// 5 | /// Various keywords are mapped to a respective action. 6 | /// ``` 7 | /// let result = lookup_ident("uwu"); // Returns Token::FUNCTION 8 | /// assert_eq!(Token::FUNCTION,result); 9 | /// ``` 10 | /// 11 | /// If the keyword is not recognized, it gets mapped to an identifier. 12 | /// ``` 13 | /// let result = lookup_ident("random_thing"); 14 | /// assert_eq!(Token::IDENT(String::from("random_thing")),result); 15 | /// ``` 16 | /// 17 | /// 18 | pub fn lookup_ident(ident: &str) -> Token { 19 | match ident { 20 | "uwu" => Token::FUNCTION, 21 | "owo" => Token::LET, 22 | "nuzzles" => Token::IF, 23 | "dab" => Token::ELIF, 24 | "rawr" => Token::ELSE, 25 | "sugoi" => Token::RETURN, 26 | "truwu" => Token::TRUE, 27 | "fowose" => Token::FALSE, 28 | "nyaa" => Token::WHILE, 29 | _ => Token::IDENT(String::from(ident)), 30 | } 31 | } 32 | 33 | /// The Token enum is used in the parsing process. It could be called the atomic element of a programming language. 34 | /// 35 | #[derive(PartialEq, Clone, Debug)] 36 | pub enum Token { 37 | ILLEGAL(String), 38 | EOF, 39 | 40 | IDENT(String), 41 | 42 | ASSIGN, 43 | PLUS, 44 | MINUS, 45 | ASTERISK, 46 | SLASH, 47 | MOD, 48 | 49 | EQ, 50 | LEQ, 51 | LE, 52 | GEQ, 53 | GR, 54 | NEQ, 55 | 56 | COMMA, 57 | SEMICOLON, 58 | 59 | LPAR, 60 | RPAR, 61 | LBRA, 62 | RBRA, 63 | 64 | BANG, 65 | 66 | FUNCTION, 67 | LET, 68 | RETURN, 69 | 70 | IF, 71 | ELIF, 72 | ELSE, 73 | 74 | WHILE, 75 | 76 | INT(i64), 77 | STRING(String), 78 | TRUE, 79 | FALSE, 80 | } 81 | -------------------------------------------------------------------------------- /src/doc/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */ 2 | html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} -------------------------------------------------------------------------------- /src/doc/COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | These documentation pages include resources by third parties. This copyright 2 | file applies only to those resources. The following third party resources are 3 | included, and carry their own copyright notices and license terms: 4 | 5 | * Fira Sans (FiraSans-Regular.woff, FiraSans-Medium.woff): 6 | 7 | Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ 8 | with Reserved Font Name Fira Sans. 9 | 10 | Copyright (c) 2014, Telefonica S.A. 11 | 12 | Licensed under the SIL Open Font License, Version 1.1. 13 | See FiraSans-LICENSE.txt. 14 | 15 | * rustdoc.css, main.js, and playpen.js: 16 | 17 | Copyright 2015 The Rust Developers. 18 | Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or 19 | the MIT license (LICENSE-MIT.txt) at your option. 20 | 21 | * normalize.css: 22 | 23 | Copyright (c) Nicolas Gallagher and Jonathan Neal. 24 | Licensed under the MIT license (see LICENSE-MIT.txt). 25 | 26 | * Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff): 27 | 28 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), 29 | with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark 30 | of Adobe Systems Incorporated in the United States and/or other countries. 31 | 32 | Licensed under the SIL Open Font License, Version 1.1. 33 | See SourceCodePro-LICENSE.txt. 34 | 35 | * Source Serif Pro (SourceSerifPro-Regular.ttf.woff, 36 | SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff): 37 | 38 | Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with 39 | Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of 40 | Adobe Systems Incorporated in the United States and/or other countries. 41 | 42 | Licensed under the SIL Open Font License, Version 1.1. 43 | See SourceSerifPro-LICENSE.txt. 44 | 45 | This copyright file is intended to be distributed with rustdoc output. 46 | -------------------------------------------------------------------------------- /src/doc/storage.js: -------------------------------------------------------------------------------- 1 | var resourcesSuffix="";var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;var i;if(reversed!==true){for(i=0;i=0;--i){if(func(arr[i])===true){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function hasOwnProperty(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function usableLocalStorage(){if(typeof Storage==="undefined"){return false}try{return window.localStorage!==null&&window.localStorage!==undefined}catch(err){return false}}function updateLocalStorage(name,value){if(usableLocalStorage()){localStorage[name]=value}else{}}function getCurrentValue(name){if(usableLocalStorage()&&localStorage[name]!==undefined){return localStorage[name]}return null}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(styleElem.href===newHref){return}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href)})}onEach(savedHref,function(el){if(el===newHref){found=true;return true}});if(found===true){styleElem.href=newHref;if(saveTheme===true){updateLocalStorage("rustdoc-theme",newTheme)}}}function getSystemValue(){var property=getComputedStyle(document.documentElement).getPropertyValue('content');return property.replace(/[\"\']/g,"")}switchTheme(currentTheme,mainTheme,getCurrentValue("rustdoc-theme")||getSystemValue()||"light",false) -------------------------------------------------------------------------------- /src/doc/main/all.html: -------------------------------------------------------------------------------- 1 | List of all items in this crate 2 | 3 |

[] 5 | 6 | List of all items

-------------------------------------------------------------------------------- /src/doc/src/main/repl/mod.rs.html: -------------------------------------------------------------------------------- 1 | mod.rs.html -- source 2 | 3 |
1
5 | 
6 | pub mod repl;
7 | 
8 |
-------------------------------------------------------------------------------- /src/doc/src/main/token/mod.rs.html: -------------------------------------------------------------------------------- 1 | mod.rs.html -- source 2 | 3 |
1
5 | 
6 | pub mod token;
7 | 
8 |
-------------------------------------------------------------------------------- /src/doc/token/all.html: -------------------------------------------------------------------------------- 1 | List of all items in this crate 2 | 3 |

[] 5 | 6 | List of all items

Enums

Functions

-------------------------------------------------------------------------------- /src/doc/src/main/eval/mod.rs.html: -------------------------------------------------------------------------------- 1 | mod.rs.html -- source 2 | 3 |
1
 5 | 2
 6 | 
 7 | pub mod env;
 8 | pub mod eval;
 9 | 
10 |
-------------------------------------------------------------------------------- /src/doc/src/main/parser/mod.rs.html: -------------------------------------------------------------------------------- 1 | mod.rs.html -- source 2 | 3 |
1
 5 | 2
 6 | 
 7 | pub mod ast;
 8 | pub mod parser;
 9 | 
10 |
-------------------------------------------------------------------------------- /src/doc/src/main/lexer/mod.rs.html: -------------------------------------------------------------------------------- 1 | mod.rs.html -- source 2 | 3 |
1
 5 | 2
 6 | 
 7 | pub mod lexer;
 8 | pub mod lexer_test;
 9 | 
10 |
-------------------------------------------------------------------------------- /src/doc/main/index.html: -------------------------------------------------------------------------------- 1 | main - Rust 2 | 3 |

[][src]Crate main

-------------------------------------------------------------------------------- /src/doc/source-script.js: -------------------------------------------------------------------------------- 1 | function getCurrentFilePath(){var parts=window.location.pathname.split("/");var rootPathParts=window.rootPath.split("/");for(var i=0;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<"}else{inner2.innerText=">";sidebarToggle.style.left="0"}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/"}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px"}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});main.insertBefore(sidebar,main.firstChild);var selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}} -------------------------------------------------------------------------------- /src/doc/token/index.html: -------------------------------------------------------------------------------- 1 | token - Rust 2 | 3 |

[][src]Crate token

Modules

5 |
token

token docs

6 |
-------------------------------------------------------------------------------- /src/doc/token/token/fn.lookup_ident.html: -------------------------------------------------------------------------------- 1 | token::token::lookup_ident - Rust 2 | 3 |

[][src]Function token::token::lookup_ident

pub fn lookup_ident(ident: &str) -> Token
-------------------------------------------------------------------------------- /src/tests/lexer_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | use crate::lexer; 4 | use crate::token::token::Token; 5 | struct TestingStruct { 6 | token_vec: Vec, 7 | } 8 | #[test] 9 | fn test_token_basic() { 10 | let input: &str = "=+(){},;"; 11 | 12 | let mut test_lexer = lexer::lexer::Lexer::new(input); 13 | 14 | let tests: TestingStruct = TestingStruct { 15 | token_vec: vec![ 16 | Token::ASSIGN, 17 | Token::PLUS, 18 | Token::LPAR, 19 | Token::RPAR, 20 | Token::LBRA, 21 | Token::RBRA, 22 | Token::COMMA, 23 | Token::SEMICOLON, 24 | ], 25 | }; 26 | for test in tests.token_vec.iter() { 27 | let current_token = test_lexer.next_token(); 28 | assert_eq!(test, ¤t_token); 29 | } 30 | } 31 | // Note: The structure below need not follow the syntax of uwucode. 32 | #[test] 33 | fn test_token_strings() { 34 | let input: &str = "owo five = 5; 35 | owo ten = 10; 36 | owo add = uwu(x,y) { 37 | x+y; 38 | }; 39 | "; 40 | 41 | let mut test_lexer = lexer::lexer::Lexer::new(input); 42 | 43 | let tests: TestingStruct = TestingStruct { 44 | token_vec: vec![ 45 | Token::LET, 46 | Token::IDENT(String::from("five")), 47 | Token::ASSIGN, 48 | Token::INT(5), 49 | Token::SEMICOLON, 50 | Token::LET, 51 | Token::IDENT(String::from("ten")), 52 | Token::ASSIGN, 53 | Token::INT(10), 54 | Token::SEMICOLON, 55 | Token::LET, 56 | Token::IDENT(String::from("add")), 57 | Token::ASSIGN, 58 | Token::FUNCTION, 59 | Token::LPAR, 60 | Token::IDENT(String::from("x")), 61 | Token::COMMA, 62 | Token::IDENT(String::from("y")), 63 | Token::RPAR, 64 | Token::LBRA, 65 | Token::IDENT(String::from("x")), 66 | Token::PLUS, 67 | Token::IDENT(String::from("y")), 68 | Token::SEMICOLON, 69 | Token::RBRA, 70 | Token::SEMICOLON, 71 | ], 72 | }; 73 | for test in tests.token_vec.iter() { 74 | let current_token = test_lexer.next_token(); 75 | assert_eq!(test, ¤t_token); 76 | } 77 | } 78 | 79 | #[test] 80 | fn test_keywords() { 81 | let input: &str = "owo uwu nuzzles dab rawr sugoi truwu fowose"; 82 | 83 | let mut test_lexer = lexer::lexer::Lexer::new(input); 84 | let mut tests: TestingStruct = TestingStruct { 85 | token_vec: vec![ 86 | Token::LET, 87 | Token::FUNCTION, 88 | Token::IF, 89 | Token::ELIF, 90 | Token::ELSE, 91 | Token::RETURN, 92 | Token::TRUE, 93 | Token::FALSE, 94 | Token::EOF, 95 | ], 96 | }; 97 | tests.token_vec.reverse(); 98 | 99 | for (test, token) in tests.token_vec.iter().zip(test_lexer.lex().iter()) { 100 | assert_eq!(test, token); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/doc/wheel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/parser/ast.rs: -------------------------------------------------------------------------------- 1 | //! The abstract syntax tree is built of enums within enums. For instance, a let statement, for example: 2 | //! ```no_run 3 | //! let three = 3; 4 | //! ``` 5 | //! This would turn into the tree: 6 | //! ```no_run 7 | //! Let(three,Expr(3)) 8 | //! ``` 9 | //! 10 | //! The complexity of these trees grow, especially when dealing with function calls. 11 | use crate::token::token::Token; 12 | 13 | // TODO: Implement fmt methods for the statements. 14 | 15 | /// Statement enums effectively compose the structure of a line of code. 16 | /// These could be considered the roots of an AST, typically with Expr being the children. 17 | #[derive(Debug, Clone, PartialEq)] 18 | pub enum Statement { 19 | Let { name: String, value: Expr }, 20 | Define { func_name: String, func: Expr }, 21 | Return { value: Expr }, 22 | Expression(Expr), 23 | } 24 | 25 | /// Expressions typically consist of other expressions, and can be considered the children of statements. Any expression type that involves other expressions stores a smart pointer to them. 26 | #[derive(Debug, Clone, PartialEq)] 27 | pub enum Expr { 28 | String(String), 29 | Variable(String), 30 | Boolean(bool), 31 | Integer(i64), 32 | Prefix { 33 | prefix: Prefix, 34 | value: Box, 35 | }, 36 | Infix { 37 | left: Box, 38 | operator: Operator, 39 | right: Box, 40 | }, 41 | If { 42 | condition: Box, 43 | consequence: Vec, 44 | alternative: Vec, 45 | }, 46 | While { 47 | condition: Box, 48 | instruction: Vec, 49 | }, 50 | Function { 51 | parameters: Vec, 52 | body: Vec, 53 | }, 54 | Call { 55 | function: Box, // Function name 56 | arguments: Vec, 57 | }, 58 | 59 | Builtin { 60 | function_name: String, 61 | arguments: Vec, 62 | }, 63 | } 64 | 65 | #[derive(Debug, Clone, PartialEq, Copy)] 66 | pub enum Prefix { 67 | Bang, 68 | Minus, 69 | } 70 | 71 | #[derive(PartialOrd, PartialEq, Debug, Clone, Copy)] 72 | pub enum Precedence { 73 | Lowest, 74 | Equals, 75 | LessGreater, 76 | Sum, 77 | Product, 78 | Prefix, 79 | } 80 | #[derive(Debug, Clone, PartialEq, Copy)] 81 | pub enum Operator { 82 | Plus, 83 | Minus, 84 | Multiply, 85 | Divide, 86 | Modulo, 87 | GreaterThan, 88 | GreaterThanEqual, 89 | LessThan, 90 | LessThanEqual, 91 | Equals, 92 | NotEquals, 93 | } 94 | 95 | pub fn is_builtin(func_name: &str) -> bool { 96 | match func_name { 97 | "len" | "quwuit" | "dprint" => true, 98 | _ => false, 99 | } 100 | } 101 | 102 | impl Token { 103 | /// The priority system determines whether an expression is evaluated as Infix or Prefix. 104 | pub fn priority(&self) -> Precedence { 105 | match self { 106 | Token::PLUS => Precedence::Sum, 107 | Token::MINUS => Precedence::Sum, 108 | Token::SLASH => Precedence::Product, 109 | Token::ASTERISK => Precedence::Product, 110 | Token::MOD => Precedence::Product, 111 | Token::LEQ => Precedence::LessGreater, 112 | Token::LE => Precedence::LessGreater, 113 | Token::GEQ => Precedence::LessGreater, 114 | Token::GR => Precedence::LessGreater, 115 | Token::EQ => Precedence::Equals, 116 | Token::NEQ => Precedence::Equals, 117 | _ => Precedence::Lowest, 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/doc/src/main/main.rs.html: -------------------------------------------------------------------------------- 1 | main.rs.html -- source 2 | 3 |
 1
 5 |  2
 6 |  3
 7 |  4
 8 |  5
 9 |  6
10 |  7
11 |  8
12 |  9
13 | 10
14 | 11
15 | 
16 | mod eval;
17 | mod lexer;
18 | mod parser;
19 | mod repl;
20 | mod tests;
21 | mod token;
22 | 
23 | fn main() {
24 |     println!("uwu *nuzzles* wewcome to uwucode! Is for me..? 🥺👉👈");
25 |     repl::repl::start();
26 | }
27 | 
28 |
-------------------------------------------------------------------------------- /src/doc/token/token/index.html: -------------------------------------------------------------------------------- 1 | token::token - Rust 2 | 3 |

[][src]Module token::token

token docs

5 |

Enums

6 |
Token

Functions

7 |
lookup_ident
-------------------------------------------------------------------------------- /src/doc/src/main/lexer/lexer_test.rs.html: -------------------------------------------------------------------------------- 1 | lexer_test.rs.html -- source 2 | 3 |
 1
 5 |  2
 6 |  3
 7 |  4
 8 |  5
 9 |  6
10 |  7
11 |  8
12 |  9
13 | 10
14 | 11
15 | 12
16 | 13
17 | 14
18 | 15
19 | 16
20 | 17
21 | 18
22 | 19
23 | 20
24 | 
25 | /*
26 | #[cfg(test)]
27 | mod tests {
28 | 
29 |     use super::*;
30 |     #[test]
31 |     fn test_tokens()
32 |     {
33 |         let input:&str = "=+(){},;";
34 |         struct testing_struct {
35 |             token_vec: Vec<(token::token_type,&'static str)>
36 |         }
37 | 
38 |         let tests:testing_struct = testing_struct{
39 |             token_vec: vec![
40 |                 (token.ASSIGN,"=")]
41 |         };
42 |         assert!(token_vec[0][1]=="=");
43 |     }
44 | }*/
45 | 
46 |
-------------------------------------------------------------------------------- /src/doc/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/doc/FiraSans-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. 2 | with Reserved Font Name < Fira >, 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /src/doc/SourceSerifPro-LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2014-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | 5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /src/doc/SourceCodePro-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | 5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /src/doc/settings.html: -------------------------------------------------------------------------------- 1 | Rustdoc settings 2 | 3 |

Rustdoc settings

Auto-hide item declarations
Auto-hide structs declaration
Auto-hide enums declaration
Auto-hide unions declaration
Auto-hide traits declaration
Auto-hide macros declaration
5 |
Auto-hide item attributes.
Auto-hide item methods' documentation
Auto-hide trait implementation documentation
Auto-hide implementors of a trait
Directly go to item in search if there is only one result
Show line numbers on code examples
Disable keyboard shortcuts
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | 5 | Logo 6 | 7 | 8 |

uwucode

9 | 10 |

11 | A language based around egirl slang... 12 |
13 |
14 | Report Bug / Request Feature 15 |

16 |

17 | 18 | 19 | # Table of Contents 20 | 21 | 1. [What is uwucode?](#what-is-uwucode?) 22 | 1. [Technical details](##technical-details) 23 | 24 | 2. [Getting started](#getting-started) 25 | 1. [Cargo requirements](##cargo-requirements) 26 | 2. [Building](##build-instructions) 27 | 28 | 3. [Writing with uwucode](#writing-with-uwucode) 29 | 1. [Syntax](##syntax) 30 | 31 | 4. [Future plans](#future-plans) 32 | 33 | 5. [Contributing](#contributing) 34 | 35 | 6. [License](#license) 36 | 37 | 7. [Contact](#contact) 38 | 39 | 8. [Extra](#extra) 40 | 1. [Why?](#why?) 41 | 42 | 9. [Acknowledgements](#acknowledgements) 43 | 44 | 45 | 46 | # What is uwucode? 47 | 48 | uwucode is an interpreted language written in Rust and consists of a nonsensical grammar for keywords, for instance uwu and owo are used for function and variable declarations respectively. While the language itself brings no unique features, the code used to interpret the language is good for beginners who wish to learn about language design. 49 | 50 | ## Technical details 51 | 52 | TBA. 53 | 54 | 55 | # Getting Started 56 | 57 | To get a local copy up and running follow these simple steps. 58 | 59 | ## Cargo requirements 60 | 61 | The toml file contains information on any dependencies which are automatically fetched. 62 | 63 | ## Build Instructions 64 | 65 | 1. Use Cargo to build uwucode. 66 | ``` 67 | cargo build 68 | ``` 69 | 2. Done. 70 | 71 | 72 | # Writing with uwucode 73 | 74 | Note: uwucode output often contains characters (emojis and colored text) that may not be readable by some terminals. 75 | 76 | Upon building uwucode, one may open a REPL by passing in the argument repl as follows: 77 | ``` 78 | uwucode repl 79 | ``` 80 | 81 | Alternatively, you can execute a file by using the open argument, supplying a file path, for instance: 82 | ``` 83 | uwucode open example.uwu 84 | ``` 85 | 86 | ## Syntax 87 | 88 | uwucode does not enforce typing and is interpreted. It is also independent of whitespace, which means indenting and spaces don't matter, but you must terminate the end of a statement. To define a variable, one would write: 89 | 90 | ```owo var = value :3``` 91 | 92 | For the sake of reference, `:3` can be replaced with `;`. For defining functions, the keyword `uwu` is utilised: 93 | 94 | ``` 95 | uwu square(x) {sugoi x*x;}; 96 | ``` 97 | 98 | There are more examples in the examples folder, however a list of all keywords include: 99 | 100 | * owo - let 101 | * uwu - define 102 | * sugoi - return 103 | * nuzzles - if 104 | * dab - elif 105 | * rawr - else 106 | * truwu - true 107 | * fowose - false 108 | 109 | As of now, there are also three builtins: 110 | 111 | * quwuit - Takes in zero arguments, terminates the program. 112 | * len - Returns the length of a string. 113 | * dprint - Takes in one argument, prints the object. 114 | 115 | _For more examples, please refer to the [Documentation](https://github.com/Theorvolt/uwucode/doc)_ 116 | 117 | 118 | 119 | # Roadmap 120 | 121 | TBD, but there's a lot I have in mind. As of now, a few things that will come are: 122 | 123 | * while loops 124 | * a more robust interpreter 125 | * inputs 126 | * basic logical operations 127 | * compilation to bytecode 128 | 129 | # Contributing 130 | 131 | You forfeit any right to sue me should your sanity disappear while contributing to this code. Follow standard procedure if you wish to contribute, i.e fork->commit->pull request. You can also ask for a feature in the issues section. 132 | 133 | 134 | # License 135 | 136 | Distributed under the MIT License. See `LICENSE` for more information. 137 | 138 | 139 | # Contact 140 | 141 | Sai kumar Murali krishnan - [LinkedIn](https://www.linkedin.com/in/sai-kumar-murali-krishnan/) - theorvoltbusiness@gmail.com 142 | 143 | Project Link: [https://github.com/Theorvolt/uwucode](https://github.com/Theorvolt/uwucode) 144 | 145 | 146 | # Extra 147 | 148 | ## Why? 149 | 150 | The inspiration for this language came about since a friend of mine had made a relatively simple gag language primarily using the letter X [over here](https://github.com/lduck11007/x/). I also wanted to learn a bit about language design and manually designing a parser was a painful but worthwhile experience. As for the actual language itself, we found it a funny idea to write docstrings in uwu speak, something I intend to add in the future. Either way, this language serves no practical use but is a great way to break into language design. I highly recommend checking out the following: [https://interpreterbook.com/](https://interpreterbook.com/). 151 | 152 | # Acknowledgements 153 | 154 | * Thanks to Satya for inspiration on keywords for the language and designing the logo. 155 | * 156 | * 157 | 158 | 159 | -------------------------------------------------------------------------------- /src/doc/src/main/eval/env.rs.html: -------------------------------------------------------------------------------- 1 | env.rs.html -- source 2 | 3 |
 1
 5 |  2
 6 |  3
 7 |  4
 8 |  5
 9 |  6
10 |  7
11 |  8
12 |  9
13 | 10
14 | 11
15 | 12
16 | 13
17 | 14
18 | 15
19 | 16
20 | 17
21 | 18
22 | 19
23 | 20
24 | 21
25 | 22
26 | 
27 | use super::eval::Object;
28 | use std::collections::HashMap;
29 | 
30 | pub struct Env {
31 |     pub env: HashMap<String, Object>,
32 | }
33 | 
34 | impl Env {
35 |     pub fn new() -> Self {
36 |         Env {
37 |             env: HashMap::new(),
38 |         }
39 |     }
40 | 
41 |     pub fn set(&mut self, key: String, value: Object) {
42 |         self.env.insert(key, value);
43 |     }
44 | 
45 |     pub fn get(&self, key: &str) -> Option<Object> {
46 |         self.env.get(key).map(|val| val.clone())
47 |     }
48 | }
49 | 
50 |
-------------------------------------------------------------------------------- /src/doc/light.css: -------------------------------------------------------------------------------- 1 | body{background-color:white;color:black;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:black;}h1.fqn{border-bottom-color:#D5D5D5;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre{background-color:#F5F5F5;}.sidebar{background-color:#F1F1F1;}*{scrollbar-color:rgba(36,37,39,0.6) #e6e6e6;}.sidebar{scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;}.logo-container.rust-logo>img{}::-webkit-scrollbar-track{background-color:#ecebeb;}::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar::-webkit-scrollbar-track{background-color:#dcdcdc;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#fff;}.sidebar .location{border-color:#000;background-color:#fff;color:#333;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav:not(.sidebar){border-bottom-color:#e0e0e0;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#000;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#3873AD;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}.search-focus:disabled{background-color:#e6e6e6;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{color:#000;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;border-right:3px solid #ffb44c;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.5);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.5);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:#000;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#eee;border-color:#999;}#titles>div:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} -------------------------------------------------------------------------------- /src/doc/src/main/token/token.rs.html: -------------------------------------------------------------------------------- 1 | token.rs.html -- source 2 | 3 |
 1
  5 |  2
  6 |  3
  7 |  4
  8 |  5
  9 |  6
 10 |  7
 11 |  8
 12 |  9
 13 | 10
 14 | 11
 15 | 12
 16 | 13
 17 | 14
 18 | 15
 19 | 16
 20 | 17
 21 | 18
 22 | 19
 23 | 20
 24 | 21
 25 | 22
 26 | 23
 27 | 24
 28 | 25
 29 | 26
 30 | 27
 31 | 28
 32 | 29
 33 | 30
 34 | 31
 35 | 32
 36 | 33
 37 | 34
 38 | 35
 39 | 36
 40 | 37
 41 | 38
 42 | 39
 43 | 40
 44 | 41
 45 | 42
 46 | 43
 47 | 44
 48 | 45
 49 | 46
 50 | 47
 51 | 48
 52 | 49
 53 | 50
 54 | 51
 55 | 52
 56 | 53
 57 | 54
 58 | 55
 59 | 56
 60 | 
 61 | pub fn lookup_ident(ident: &str) -> Token {
 62 |     match ident {
 63 |         "uwu" => Token::FUNCTION,
 64 |         "owo" => Token::LET,
 65 |         "nuzzles" => Token::IF,
 66 |         "dab" => Token::ELIF,
 67 |         "rawr" => Token::ELSE,
 68 |         "sugoi" => Token::RETURN,
 69 |         "truwu" => Token::TRUE,
 70 |         "fowose" => Token::FALSE,
 71 |         _ => Token::IDENT(String::from(ident)),
 72 |     }
 73 | }
 74 | 
 75 | #[derive(PartialEq, Clone, Debug)]
 76 | pub enum Token {
 77 |     ILLEGAL(String),
 78 |     EOF,
 79 |     IDENT(String),
 80 | 
 81 |     ASSIGN,
 82 |     PLUS,
 83 |     MINUS,
 84 |     ASTERISK,
 85 |     SLASH,
 86 | 
 87 |     EQ,
 88 |     LEQ,
 89 |     LE,
 90 |     GEQ,
 91 |     GE,
 92 |     NEQ,
 93 | 
 94 |     COMMA,
 95 |     SEMICOLON,
 96 | 
 97 |     LPAR,
 98 |     RPAR,
 99 |     LBRA,
100 |     RBRA,
101 | 
102 |     BANG,
103 | 
104 |     FUNCTION,
105 |     LET,
106 |     RETURN,
107 | 
108 |     IF,
109 |     ELIF,
110 |     ELSE,
111 | 
112 |     INT(i64),
113 |     STRING(String),
114 |     TRUE,
115 |     FALSE,
116 | }
117 | 
118 |
-------------------------------------------------------------------------------- /src/lexer/lexer.rs: -------------------------------------------------------------------------------- 1 | use crate::token::token::{lookup_ident, Token}; 2 | use ::std::iter::Peekable; 3 | use std::str; 4 | use std::str::Chars; 5 | 6 | pub struct Lexer<'a> { 7 | /* 8 | Takes in a string then stores its iterator. 9 | Info: <'a> indicates a speciifed lifetime. 10 | */ 11 | pub chr_iter: Peekable>, 12 | } 13 | 14 | /// Initializes an instance of a lexer which returns a vector of tokens on a string. 15 | /// 16 | /// # Examples 17 | /// 18 | /// Initialize a lexer as follows: 19 | /// ``` 20 | /// let mut lexer = Lexer::new("owo five = 5;"); 21 | /// ``` 22 | impl<'a> Lexer<'a> { 23 | /// Calls next on the char iterator. 24 | pub fn read_char(&mut self) -> Option { 25 | // Returns the next item in the iterator. 26 | self.chr_iter.next() 27 | } 28 | 29 | pub fn peek_char(&mut self) -> Option<&char> { 30 | self.chr_iter.peek() 31 | } 32 | 33 | /// Instantiates a new lexer instance with a char iterator. 34 | pub fn new(file_string: &'a str) -> Lexer<'a> { 35 | Lexer { 36 | chr_iter: file_string.chars().peekable(), 37 | } 38 | } 39 | 40 | /// Consumes all whitespace characters by peaking, making the language independent of whitespace. 41 | pub fn skip_whitespace(&mut self) { 42 | // While not perfect, it's better to use Some over unwrap to avoid None issues. 43 | while let Some(&chr) = self.peek_char() { 44 | if chr.is_whitespace() { 45 | self.read_char(); 46 | } else { 47 | break; 48 | } 49 | } 50 | } 51 | 52 | /// Reads in keywords, variables and function names. 53 | pub fn read_identifier(&mut self, first_letter: char) -> String { 54 | let mut expression: String = String::from(first_letter); 55 | 56 | // Peek at top element, determine if alphabetic then add. 57 | while let Some(&chr) = self.peek_char() { 58 | if chr.is_alphabetic() || chr == '_' { 59 | expression.push(self.read_char().unwrap()); 60 | } else { 61 | break; 62 | } 63 | } 64 | expression 65 | } 66 | 67 | /// Reads in a string which has a specific terminator. 68 | pub fn read_string(&mut self) -> String { 69 | let mut expression: String = String::new(); 70 | 71 | // Peek at top element, determine if alphabetic then add. 72 | while let Some(&chr) = self.peek_char() { 73 | if chr == '"' { 74 | self.read_char(); 75 | break; 76 | } else { 77 | expression.push(self.read_char().unwrap()); 78 | } 79 | } 80 | expression 81 | } 82 | 83 | /// Reads in a sequence of integers and returns an integer. 84 | pub fn read_number(&mut self, first_chr: char) -> i64 { 85 | // TODO: Prefix notation, i.e 0x, 0b, 0o, 0f 86 | let mut expression: String = String::from(first_chr); 87 | 88 | while let Some(&chr) = self.peek_char() { 89 | if char::is_digit(chr, 10) { 90 | expression.push(self.read_char().unwrap()); 91 | } else { 92 | break; 93 | } 94 | } 95 | 96 | expression.parse().unwrap() 97 | } 98 | 99 | /// Reads from the iterator to create the next token. 100 | pub fn next_token(&mut self) -> Token { 101 | self.skip_whitespace(); 102 | 103 | /* 104 | Matching process: 105 | For single character tokens, immediately process. 106 | However for multi-leter tokens, use peak to determine if the next character links up. 107 | */ 108 | match self.read_char() { 109 | // = first, into ASSIGN and EQUAL 110 | Some('=') => { 111 | // Comparison operator 112 | if self.peek_char().unwrap() == &'=' { 113 | self.read_char(); 114 | Token::EQ 115 | } else { 116 | Token::ASSIGN 117 | } 118 | } 119 | Some(',') => Token::COMMA, 120 | Some(';') => Token::SEMICOLON, 121 | 122 | // Alternative (or soon to be default) line end :3 123 | Some(':') => { 124 | if self.peek_char().unwrap() == &'3' { 125 | self.read_char(); 126 | Token::SEMICOLON 127 | } else { 128 | Token::ILLEGAL(String::from(":")) 129 | } 130 | } 131 | 132 | Some('+') => Token::PLUS, 133 | Some('-') => Token::MINUS, 134 | Some('%') => Token::MOD, 135 | 136 | // TODO: implement power 137 | Some('*') => Token::ASTERISK, 138 | // TODO: implement integer division, comments 139 | Some('/') => { 140 | if self.peek_char().unwrap() == &'*' { 141 | // comments 142 | self.read_char(); 143 | loop { 144 | if self.peek_char().unwrap() == &'*' { 145 | self.read_char(); 146 | if self.peek_char().unwrap() == &'/' { 147 | self.read_char(); 148 | return self.next_token(); 149 | } 150 | } 151 | self.read_char(); 152 | } 153 | } else { 154 | Token::SLASH 155 | } 156 | } 157 | 158 | Some('(') => Token::LPAR, 159 | Some(')') => Token::RPAR, 160 | Some('{') => Token::LBRA, 161 | Some('}') => Token::RBRA, 162 | 163 | Some('>') => { 164 | if self.peek_char().unwrap() == &'=' { 165 | self.read_char(); 166 | Token::GEQ 167 | } else { 168 | Token::GR 169 | } 170 | } 171 | 172 | Some('<') => { 173 | if self.peek_char().unwrap() == &'=' { 174 | self.read_char(); 175 | Token::LEQ 176 | } else { 177 | Token::LE 178 | } 179 | } 180 | 181 | Some('!') => { 182 | if self.peek_char().unwrap() == &'=' { 183 | self.read_char(); 184 | Token::NEQ 185 | } else { 186 | Token::BANG 187 | } 188 | } 189 | 190 | None => Token::EOF, 191 | 192 | Some('"') => Token::STRING(self.read_string()), 193 | 194 | // Deal with expressions and primitives 195 | Some(chr) => { 196 | if chr.is_alphabetic() { 197 | // Converts to either keyword or identifier 198 | let token = self.read_identifier(chr); 199 | lookup_ident(&token as &str) 200 | } 201 | // Could be an integer 202 | else if char::is_digit(chr, 10) { 203 | Token::INT(self.read_number(chr)) 204 | } 205 | // Nothing recognized, spit illegal. 206 | else { 207 | Token::ILLEGAL(String::from(chr)) 208 | } 209 | } 210 | } 211 | } 212 | 213 | /// Returns the vector of tokens from an input. 214 | pub fn lex(&mut self) -> Vec { 215 | let mut token_vec: Vec = Vec::new(); 216 | 217 | loop { 218 | match self.chr_iter.peek() { 219 | None => break, 220 | _ => token_vec.push(self.next_token()), 221 | } 222 | } 223 | if token_vec.last() != Some(&Token::EOF) { 224 | token_vec.push(Token::EOF); 225 | } 226 | // Important, I'm reversing the list because implementation from the back is much better in terms of time complexity. Pop better than remove. 227 | // Potential TODO: Change to stack? 228 | token_vec.reverse(); 229 | token_vec 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/doc/dark.css: -------------------------------------------------------------------------------- 1 | body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.logo-container.rust-logo>img{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) transparent;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav:not(.sidebar){border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#D2991D;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}.search-focus:disabled{background-color:#c5c4c4;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{color:#ddd;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);color:black;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:#000;color:#fff;border-color:#000;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}#titles>div:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;} -------------------------------------------------------------------------------- /src/doc/src/token/token.rs.html: -------------------------------------------------------------------------------- 1 | token.rs.html -- source 2 | 3 |
 1
  5 |  2
  6 |  3
  7 |  4
  8 |  5
  9 |  6
 10 |  7
 11 |  8
 12 |  9
 13 | 10
 14 | 11
 15 | 12
 16 | 13
 17 | 14
 18 | 15
 19 | 16
 20 | 17
 21 | 18
 22 | 19
 23 | 20
 24 | 21
 25 | 22
 26 | 23
 27 | 24
 28 | 25
 29 | 26
 30 | 27
 31 | 28
 32 | 29
 33 | 30
 34 | 31
 35 | 32
 36 | 33
 37 | 34
 38 | 35
 39 | 36
 40 | 37
 41 | 38
 42 | 39
 43 | 40
 44 | 41
 45 | 42
 46 | 43
 47 | 44
 48 | 45
 49 | 46
 50 | 47
 51 | 48
 52 | 49
 53 | 50
 54 | 51
 55 | 52
 56 | 53
 57 | 54
 58 | 55
 59 | 56
 60 | 57
 61 | 58
 62 | 59
 63 | 60
 64 | 61
 65 | 62
 66 | 
 67 | /// token docs
 68 | 
 69 | pub mod token {
 70 | 
 71 | pub fn lookup_ident(ident: &str) -> Token {
 72 | 
 73 |     match ident {
 74 |         "uwu" => Token::FUNCTION,
 75 |         "owo" => Token::LET,
 76 |         "nuzzles" => Token::IF,
 77 |         "dab" => Token::ELIF,
 78 |         "rawr" => Token::ELSE,
 79 |         "sugoi" => Token::RETURN,
 80 |         "truwu" => Token::TRUE,
 81 |         "fowose" => Token::FALSE,
 82 |         _ => Token::IDENT(String::from(ident)),
 83 |     }
 84 | }
 85 | 
 86 | #[derive(PartialEq, Clone, Debug)]
 87 | pub enum Token {
 88 |     ILLEGAL(String),
 89 |     EOF,
 90 |     IDENT(String),
 91 | 
 92 |     ASSIGN,
 93 |     PLUS,
 94 |     MINUS,
 95 |     ASTERISK,
 96 |     SLASH,
 97 | 
 98 |     EQ,
 99 |     LEQ,
100 |     LE,
101 |     GEQ,
102 |     GE,
103 |     NEQ,
104 | 
105 |     COMMA,
106 |     SEMICOLON,
107 | 
108 |     LPAR,
109 |     RPAR,
110 |     LBRA,
111 |     RBRA,
112 | 
113 |     BANG,
114 | 
115 |     FUNCTION,
116 |     LET,
117 |     RETURN,
118 | 
119 |     IF,
120 |     ELIF,
121 |     ELSE,
122 | 
123 |     INT(i64),
124 |     STRING(String),
125 |     TRUE,
126 |     FALSE,
127 | }
128 | }
129 |
-------------------------------------------------------------------------------- /src/doc/src/main/repl/repl.rs.html: -------------------------------------------------------------------------------- 1 | repl.rs.html -- source 2 | 3 |
 1
 5 |  2
 6 |  3
 7 |  4
 8 |  5
 9 |  6
10 |  7
11 |  8
12 |  9
13 | 10
14 | 11
15 | 12
16 | 13
17 | 14
18 | 15
19 | 16
20 | 17
21 | 18
22 | 19
23 | 20
24 | 21
25 | 22
26 | 23
27 | 24
28 | 25
29 | 26
30 | 27
31 | 28
32 | 29
33 | 30
34 | 31
35 | 32
36 | 33
37 | 34
38 | 35
39 | 36
40 | 37
41 | 38
42 | 39
43 | 40
44 | 41
45 | 42
46 | 
47 | use crate::eval::eval::{eval_return_scope, Env, Object};
48 | use crate::lexer::lexer::Lexer;
49 | use crate::parser::parser::{parse};
50 | use ::std::io::Write;
51 | use std::io;
52 | 
53 | //use colored::*;
54 | 
55 | const PROMPT: &str = "( ᴜ ω ᴜ )⭜";
56 | 
57 | pub fn start() {
58 |     let mut env = Env::new();
59 |     loop {
60 |         print!("{}  ", PROMPT);//.truecolor(255, 69, 0));
61 |         std::io::stdout().flush().expect("Flushing failed");
62 |         let mut user_in: String = String::new();
63 |         io::stdin().read_line(&mut user_in).expect("Could not read");
64 |         let mut lexer = Lexer::new(&user_in as &str);
65 |         let mut token_vec = lexer.lex();
66 | 
67 |         let parsed = parse(&mut token_vec);
68 |         //println!("{:?}",parsed);
69 |         display_object(eval_return_scope(parsed, &mut env));
70 |     }
71 | }
72 | 
73 | fn display_object(obj: Object) {
74 |     match obj {
75 |         Object::Integer(num) => println!("{}", num),
76 |         Object::String(string) => println!("{}", string),
77 |         Object::Boolean(val) => match val { 
78 |             true=> println!("truwu"),
79 |             false=> println!("fowose"),
80 |         },
81 |         Object::Function {
82 |             parameters: _,
83 |             body: _,
84 |         } => println!("function"),
85 |         Object::Null => println!("null"),
86 |         Object::Return(obj) => display_object(*obj),
87 |     }
88 | }
89 | 
90 |
-------------------------------------------------------------------------------- /src/doc/ayu.css: -------------------------------------------------------------------------------- 1 | body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod){border-bottom-color:#5c6773;}h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}code{color:#ffb454;}h3>code,h4>code,h5>code{color:#e6e1cf;}pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre{color:#e6e1cf;background-color:#191f26;}.sidebar{background-color:#14191f;}.logo-container.rust-logo>img{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);}*{scrollbar-color:#5c6773 transparent;}.sidebar{scrollbar-color:#5c6773 transparent;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#0f1419;}.sidebar .location{border-color:#000;background-color:#0f1419;color:#fff;}.sidebar-elems .location{color:#ff7733;}.sidebar-elems .location a{color:#fff;}.sidebar .version{border-bottom-color:#424c57;}.sidebar-title{border-top-color:#5c6773;border-bottom-color:#5c6773;}.block a:hover{background:transparent;color:#ffb44c;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#5c6773;}.docblock table,.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.content .highlighted{color:#000 !important;background-color:#c6afb3;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted{background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a span.desc{color:#c5c5c5;}.content .stability::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ef57ff;}.content span.union,.content a.union{color:#98a01c;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#6380a0;}.content span.primitive,.content a.primitive{color:#32889b;}.content span.traitalias,.content a.traitalias{color:#57d399;}.content span.keyword,.content a.keyword{color:#de5249;}.content span.externcrate,.content span.mod,.content a.mod{color:#acccf9;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#99e0c9;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#cfbcf5;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav:not(.sidebar){border-bottom-color:#424c57;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#c5c5c5;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#39AFD7;}.collapse-toggle{color:#999;}#crate-search{color:#c5c5c5;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;border-color:#424c57;}.search-input{color:#ffffff;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;transition:box-shadow 150ms ease-in-out;}#crate-search+.search-input:focus{box-shadow:0 0 0 1px #148099,0 0 0 2px transparent;}.search-focus:disabled{color:#929292;}.module-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background-color:transparent;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip .tooltiptext{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip .tooltiptext::after{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}#titles>div.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>div:not(.selected){background-color:transparent !important;border:none;}#titles>div:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>div>div.count{color:#888;}.content .highlighted.mod,.content .highlighted.externcrate{}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content .highlighted.trait{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>div:hover,#titles>div.selected{}.content .highlighted.traitalias{}.content span.type,.content a.type,.block a.current.type{}.content span.union,.content a.union,.block a.current.union{}.content .highlighted.foreigntype{}pre.rust .lifetime{}.content .highlighted.primitive{}.content .highlighted.constant,.content .highlighted.static{}.stab.unstable{}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content .highlighted.enum{}.content .highlighted.struct{}.content .highlighted.keyword{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{}.stab.portability{}.content .highlighted.union{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}.content .highlighted.type{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}#all-types{background-color:#14191f;}#all-types:hover{background-color:rgba(70,70,70,0.33);}.search-results td span.alias{color:#c5c5c5;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;} -------------------------------------------------------------------------------- /src/doc/LICENSE-APACHE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/parser/parser.rs: -------------------------------------------------------------------------------- 1 | //! Handles the parsing of tokens that come from the lexer. 2 | use crate::parser::ast::{is_builtin, Expr, Operator, Precedence, Prefix, Statement}; 3 | use crate::token::token::Token; 4 | 5 | /// The parse function turns a vector of tokens into a vector of statements. This is done by grouping them into one of several categories. 6 | /// 7 | /// # Parse categories 8 | /// - Let (define) 9 | /// - Function (define) 10 | /// - Right brace (end body) 11 | /// - Return (return statement) 12 | /// - EOF (end of file) 13 | /// - Expressions (everything else) 14 | pub fn parse(input: &mut Vec) -> Vec { 15 | let mut statements = vec![]; 16 | 17 | // Process each statement here 18 | loop { 19 | let top_token = match input.last() { 20 | Some(token) => token, 21 | None => panic!("Vec list found empty."), 22 | }; 23 | 24 | match top_token { 25 | Token::EOF => break, // We've reached the end of line or file 26 | Token::LET => parse_let(input, &mut statements), // Define a variable 27 | Token::FUNCTION => parse_function(input, &mut statements), // Define a function 28 | Token::RBRA => break, // We've reached the end of an enclosing 29 | Token::RETURN => parse_return(input, &mut statements), // We've hit a return statement 30 | _ => statements.push(Statement::Expression(parse_expression( 31 | input, 32 | Precedence::Lowest, 33 | ))), // Deal with an expression 34 | } 35 | 36 | // Since the subcalls modify the vector of tokens, we should reach a semicolon at the end. 37 | assert_eq!(input.pop(), Some(Token::SEMICOLON)); 38 | } 39 | 40 | return statements; 41 | } 42 | 43 | /// Parses let statement by resolving an identifier name and an expression. 44 | /// 45 | /// # Technical information 46 | /// The function effectively transforms a line with a let statement into a let expression. 47 | fn parse_let(input: &mut Vec, statements: &mut Vec) { 48 | assert_eq!(input.pop(), Some(Token::LET)); // Sanity check 49 | 50 | // wtfs going on here lol, double enum extraction 51 | let var_name: String = match input.pop() { 52 | Some(Token::IDENT(var)) => var, 53 | _ => panic!("String type not found for variable name."), 54 | }; 55 | 56 | // We're at = stage 57 | assert_eq!(input.pop(), Some(Token::ASSIGN)); 58 | // Now we're at the expression eval stage, leave it to parse expr 59 | let value = parse_expression(input, Precedence::Lowest); 60 | statements.push(Statement::Let { 61 | name: var_name, 62 | value, 63 | }); 64 | } 65 | 66 | fn parse_return(input: &mut Vec, statements: &mut Vec) { 67 | /* 68 | Let's have a look at our Return enum now. Return {value:Expr} which means 69 | we need to just parse the expression. 70 | */ 71 | assert_eq!(input.pop(), Some(Token::RETURN)); 72 | // Now evaluate the expression 73 | let value = parse_expression(input, Precedence::Lowest); 74 | statements.push(Statement::Return { value }); 75 | } 76 | 77 | /// Parses a function definition, which consists of statements from the other categories. 78 | /// 79 | /// # Technical Information 80 | /// The ideal structure of a function takes the following form: 81 | /// DEFINE function_name(args..) { 82 | /// body 83 | /// } 84 | /// This means that each argument and the body have to be individually parsed. 85 | /// 86 | fn parse_function(input: &mut Vec, statements: &mut Vec) { 87 | assert_eq!(input.pop(), Some(Token::FUNCTION)); 88 | 89 | // Next thing is the function name, add it in 90 | let func_name: String = match input.pop() { 91 | Some(Token::IDENT(name)) => name, 92 | a => panic!( 93 | "String not found for the function name, instead found {:?}", 94 | a 95 | ), 96 | }; 97 | 98 | // Now we're at args, first thing is the LPAR 99 | assert_eq!(input.pop(), Some(Token::LPAR)); 100 | 101 | // Read arguments 102 | let mut parameters = vec![]; 103 | 104 | loop { 105 | match input.pop() { 106 | Some(Token::RPAR) => break, 107 | Some(Token::IDENT(var)) => { 108 | // Find an arg, add then proceed 109 | parameters.push(var); // push to vec list 110 | // Either separate the argument, finish reading or panic. 111 | match input.pop() { 112 | Some(Token::RPAR) => break, 113 | Some(Token::COMMA) => continue, 114 | _ => panic!("Object after parameter was not comma or bracket"), 115 | }; 116 | } 117 | _ => panic!("Object after param was not comma or bracket"), 118 | } 119 | } 120 | 121 | // Parse the body 122 | assert_eq!(input.pop(), Some(Token::LBRA)); // { 123 | let body = parse(input); // will return code of inside 124 | assert_eq!(input.pop(), Some(Token::RBRA)); // } 125 | 126 | statements.push(Statement::Define { 127 | func_name, 128 | func: Expr::Function { parameters, body }, 129 | }); 130 | } 131 | 132 | /// Parses most expressions that involve primitives, operators or basic conditionals. 133 | /// 134 | /// # Technical Information 135 | /// 136 | fn parse_expression(input: &mut Vec, precedence: Precedence) -> Expr { 137 | let mut left_expr = match input.pop() { 138 | Some(val) => { 139 | match val { 140 | // This is a Token type 141 | // Primitives 142 | Token::INT(value) => Expr::Integer(value), 143 | Token::TRUE => Expr::Boolean(true), 144 | Token::FALSE => Expr::Boolean(false), 145 | Token::IDENT(value) => { 146 | // for implementing builtin, do a logic check here 147 | if input.last() == Some(&Token::LPAR) { 148 | input.pop(); 149 | let mut args = vec![]; 150 | 151 | loop { 152 | match input.last() { 153 | Some(Token::RPAR) => { 154 | input.pop(); 155 | break; 156 | } 157 | None => panic!("weird stuff happened"), 158 | _ => args.push(parse_expression(input, Precedence::Lowest)), 159 | } 160 | 161 | match input.pop() { 162 | Some(Token::RPAR) => break, 163 | Some(Token::COMMA) => continue, 164 | _ => panic!("Unexpected parameter"), 165 | } 166 | } 167 | if is_builtin(&value as &str) { 168 | Expr::Builtin { 169 | function_name: value, 170 | arguments: args, 171 | } 172 | } else { 173 | Expr::Call { 174 | function: Box::new(Expr::Variable(value)), 175 | arguments: args, 176 | } 177 | } 178 | } else { 179 | Expr::Variable(value) 180 | } 181 | } 182 | Token::STRING(value) => Expr::String(value), 183 | 184 | // Prefix types [A B] 185 | Token::BANG => Expr::Prefix { 186 | prefix: Prefix::Bang, 187 | value: Box::new(parse_expression(input, Precedence::Prefix)), 188 | }, 189 | 190 | Token::MINUS => Expr::Prefix { 191 | prefix: Prefix::Minus, 192 | value: Box::new(parse_expression(input, Precedence::Prefix)), 193 | }, 194 | 195 | // conditional 196 | Token::IF => { 197 | assert_eq!(Some(Token::LPAR), input.pop()); 198 | let condition = parse_expression(input, Precedence::Lowest); 199 | assert_eq!(Some(Token::RPAR), input.pop()); 200 | 201 | // Parse body 202 | assert_eq!(Some(Token::LBRA), input.pop()); 203 | let consequence = parse(input); 204 | assert_eq!(Some(Token::RBRA), input.pop()); 205 | 206 | let alternative = if input.last() == Some(&Token::ELSE) { 207 | // ELSE CONDITION 208 | input.pop(); 209 | assert_eq!(Some(Token::LBRA), input.pop()); 210 | let alternative = parse(input); 211 | assert_eq!(Some(Token::RBRA), input.pop()); 212 | alternative 213 | } else { 214 | // No alternative 215 | Vec::new() 216 | }; 217 | 218 | Expr::If { 219 | condition: Box::new(condition), 220 | consequence, 221 | alternative, 222 | } 223 | } 224 | 225 | // while, control flow 1 226 | Token::WHILE => { 227 | // While (THING) { do thing} 228 | assert_eq!(Some(Token::LPAR), input.pop()); 229 | let condition = parse_expression(input, Precedence::Lowest); 230 | assert_eq!(Some(Token::RPAR), input.pop()); 231 | 232 | // Parse body 233 | assert_eq!(Some(Token::LBRA), input.pop()); 234 | let instruction = parse(input); 235 | assert_eq!(Some(Token::RBRA), input.pop()); 236 | 237 | Expr::While { 238 | condition: Box::new(condition), 239 | instruction, 240 | } 241 | } 242 | 243 | // Error 244 | _ => panic!("Parser error: Not recognized!"), 245 | } 246 | } 247 | _ => panic!("The vector is empty"), 248 | }; 249 | 250 | // Depending on whether we have a prefix/infix expression, we need to modify evaluation order. 251 | while precedence < input.last().unwrap().priority() { 252 | left_expr = parse_infix(left_expr, input); 253 | } 254 | 255 | left_expr 256 | } 257 | 258 | /// Parses expressions involving an operator in the middle, for instance a OP b. 259 | /// 260 | /// # Technical Information 261 | /// The left token is passed in, then the right token is popped, which results in a new infix expression, with pointers to the left and right expressions. 262 | fn parse_infix(left: Expr, input: &mut Vec) -> Expr { 263 | let next_token = match input.pop() { 264 | Some(value) => value, 265 | None => panic!("Empty list..."), 266 | }; 267 | 268 | let operator = match next_token { 269 | Token::PLUS => Operator::Plus, 270 | Token::MINUS => Operator::Minus, 271 | Token::SLASH => Operator::Divide, 272 | Token::MOD => Operator::Modulo, 273 | Token::ASTERISK => Operator::Multiply, 274 | Token::LEQ => Operator::LessThanEqual, 275 | Token::LE => Operator::LessThan, 276 | Token::GEQ => Operator::GreaterThanEqual, 277 | Token::GR => Operator::GreaterThan, 278 | Token::EQ => Operator::Equals, 279 | Token::NEQ => Operator::NotEquals, 280 | _ => panic!("parse infix called on invalid operator"), 281 | }; 282 | 283 | Expr::Infix { 284 | left: Box::new(left), 285 | operator, 286 | right: Box::new(parse_expression(input, next_token.priority())), 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /src/doc/src/main/parser/ast.rs.html: -------------------------------------------------------------------------------- 1 | ast.rs.html -- source 2 | 3 |
 1
  5 |  2
  6 |  3
  7 |  4
  8 |  5
  9 |  6
 10 |  7
 11 |  8
 12 |  9
 13 | 10
 14 | 11
 15 | 12
 16 | 13
 17 | 14
 18 | 15
 19 | 16
 20 | 17
 21 | 18
 22 | 19
 23 | 20
 24 | 21
 25 | 22
 26 | 23
 27 | 24
 28 | 25
 29 | 26
 30 | 27
 31 | 28
 32 | 29
 33 | 30
 34 | 31
 35 | 32
 36 | 33
 37 | 34
 38 | 35
 39 | 36
 40 | 37
 41 | 38
 42 | 39
 43 | 40
 44 | 41
 45 | 42
 46 | 43
 47 | 44
 48 | 45
 49 | 46
 50 | 47
 51 | 48
 52 | 49
 53 | 50
 54 | 51
 55 | 52
 56 | 53
 57 | 54
 58 | 55
 59 | 56
 60 | 57
 61 | 58
 62 | 59
 63 | 60
 64 | 61
 65 | 62
 66 | 63
 67 | 64
 68 | 65
 69 | 66
 70 | 67
 71 | 68
 72 | 69
 73 | 70
 74 | 71
 75 | 72
 76 | 73
 77 | 74
 78 | 75
 79 | 76
 80 | 77
 81 | 78
 82 | 79
 83 | 80
 84 | 81
 85 | 82
 86 | 83
 87 | 84
 88 | 
 89 | use crate::token::token:: {Token};
 90 | 
 91 | #[derive(Debug, Clone, PartialEq)]
 92 | pub enum Statement {
 93 |     Let { name: String, value: Expr },
 94 |     Define { func_name: String, func: Expr },
 95 |     Return { value: Expr },
 96 |     Expression(Expr),
 97 | }
 98 | 
 99 | #[derive(Debug, Clone, PartialEq)]
100 | pub enum Expr {
101 |     String(String),
102 |     Variable(String),
103 |     Boolean(bool),
104 |     Integer(i64),
105 |     Prefix {
106 |         prefix: Prefix,
107 |         value: Box<Expr>,
108 |     },
109 |     Infix {
110 |         left: Box<Expr>,
111 |         operator: Operator,
112 |         right: Box<Expr>,
113 |     },
114 |     If {
115 |         condition: Box<Expr>,
116 |         consequence: Vec<Statement>,
117 |         alternative: Vec<Statement>,
118 |     },
119 |     Function {
120 |         parameters: Vec<String>,
121 |         body: Vec<Statement>,
122 |     },
123 |     Call {
124 |         function: Box<Expr>,
125 |         arguments: Vec<Expr>,
126 |     },
127 | }
128 | 
129 | #[derive(Debug, Clone, PartialEq)]
130 | pub enum Prefix {
131 |     Bang,
132 |     Minus,
133 | }
134 | 
135 | #[derive(PartialOrd, PartialEq,Debug)]
136 | pub enum Precedence {
137 |     Lowest,
138 |     Equals,
139 |     LessGreater,
140 |     Sum,
141 |     Product,
142 |     Prefix,
143 | }
144 | #[derive(Debug, Clone, PartialEq)]
145 | pub enum Operator {
146 |     Plus,
147 |     Minus,
148 |     Multiply,
149 |     Divide,
150 |     GreaterThan,
151 |     LessThan,
152 |     Equals,
153 |     NotEquals,
154 | }
155 | 
156 | impl Token {
157 |     pub fn priority(&self) -> Precedence {
158 |         match self {
159 |             Token::PLUS => Precedence::Sum,
160 |             Token::MINUS => Precedence::Sum,
161 |             Token::SLASH => Precedence::Product,
162 |             Token::ASTERISK => Precedence::Product,
163 |             Token::LEQ => Precedence::LessGreater,
164 |             Token::LE => Precedence::LessGreater,
165 |             Token::GEQ => Precedence::LessGreater,
166 |             Token::GE => Precedence::LessGreater,
167 |             Token::EQ => Precedence::Equals,
168 |             Token::NEQ => Precedence::Equals,
169 |             _ => Precedence::Lowest,
170 |         }
171 |     }
172 | }
173 | 
174 |
--------------------------------------------------------------------------------