From 8c3261073723b17d421b6822b52f2dc457baf54f Mon Sep 17 00:00:00 2001 From: Leo dev Date: Fri, 24 May 2024 22:51:25 +0200 Subject: [PATCH] for, while, if, else --- src/lexer.rs | 156 ++++++++++------ src/parser.rs | 121 ++++++++---- src/transpiler.rs | 464 +++++++++++++++++++++++++++++++++------------- 3 files changed, 526 insertions(+), 215 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 728e3d2..e006c09 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -1,16 +1,18 @@ -use regex::Regex; use once_cell::sync::Lazy; +use regex::Regex; use std::fmt; #[derive(Debug, PartialEq, Clone, Copy)] pub struct LexerState { pub line: usize, - pub column: usize + pub column: usize, } // Define token types #[derive(Debug, PartialEq, Clone, Copy)] pub enum TokenType { Keyword, + Keyword1, + Keyword2, Newline, Whitespace, Number, @@ -34,12 +36,19 @@ pub struct Token { pub token_type: TokenType, pub value: String, pub line: usize, - pub column: usize + pub column: usize, } impl fmt::Debug for Token { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "(TokenType: {:?}, TokenValue: {}, Line: {}, Column {})", self.token_type, self.value.replace("\n", "\\n"), self.line, self.column) + write!( + f, + "(TokenType: {:?}, TokenValue: {}, Line: {}, Column {})", + self.token_type, + self.value.replace("\n", "\\n"), + self.line, + self.column + ) } } @@ -51,73 +60,87 @@ impl fmt::Display for Token { pub struct Node { token_type: TokenType, - token_regex: Lazy + token_regex: Lazy, } -const SYNTAX: [Node; 14] = [ +const SYNTAX: [Node; 16] = [ Node { token_type: TokenType::Semicolon, - token_regex: Lazy::new(|| Regex::new(r"^\;").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^\;").unwrap()), }, Node { token_type: TokenType::SecondOperator, - token_regex: Lazy::new(|| Regex::new(r"^,").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^,").unwrap()), }, Node { token_type: TokenType::String, - token_regex: Lazy::new(|| Regex::new("^\"").unwrap()) + token_regex: Lazy::new(|| Regex::new("^\"").unwrap()), }, Node { token_type: TokenType::Whitespace, - token_regex: Lazy::new(|| Regex::new(r"^\s+").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^\s+").unwrap()), }, Node { token_type: TokenType::Keyword, - token_regex: Lazy::new(|| Regex::new(r"^(pub|mut|try|catch|return|fn|let|use|cb|struct|impl|for|in|as)\b").unwrap()) + token_regex: Lazy::new(|| { + Regex::new(r"^(pub|mut|try|catch|return|fn|let|use|cb|struct|impl|in|as)\b").unwrap() + }), + }, + Node { + token_type: TokenType::Keyword1, + token_regex: Lazy::new(|| Regex::new(r"^(if|for|while|else *if)\b").unwrap()), + }, + Node { + token_type: TokenType::Keyword2, + token_regex: Lazy::new(|| Regex::new(r"^(else)\b").unwrap()), }, Node { token_type: TokenType::Identifier, - token_regex: Lazy::new(|| Regex::new(r"^[._a-zA-Z][a-zA-Z0-9_]*").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^[._a-zA-Z][a-zA-Z0-9_]*").unwrap()), }, Node { token_type: TokenType::Number, - token_regex: Lazy::new(|| Regex::new(r"^\d+").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^\d+").unwrap()), }, Node { token_type: TokenType::Ptr, - token_regex: Lazy::new(|| Regex::new(r"^->").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^->").unwrap()), }, Node { token_type: TokenType::Operator, - token_regex: Lazy::new(|| Regex::new(r"^[|\-|\+|\*|\=|\!|\&|\:]").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^[|\-|\+|\*|\=|\!|\&|\:]").unwrap()), }, Node { token_type: TokenType::Round, - token_regex: Lazy::new(|| Regex::new(r"^[\(|\)]").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^[\(|\)]").unwrap()), }, Node { token_type: TokenType::Curly, - token_regex: Lazy::new(|| Regex::new(r"^[\{|\}]").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^[\{|\}]").unwrap()), }, Node { token_type: TokenType::Square, - token_regex: Lazy::new(|| Regex::new(r"^[\[|\]]").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^[\[|\]]").unwrap()), }, Node { token_type: TokenType::Include, - token_regex: Lazy::new(|| Regex::new(r"^#include *<(.*?)>").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^#include *<(.*?)>").unwrap()), }, Node { token_type: TokenType::Include, - token_regex: Lazy::new(|| Regex::new(r#"^#include *"(.*?)""#).unwrap()) - } + token_regex: Lazy::new(|| Regex::new(r#"^#include *"(.*?)""#).unwrap()), + }, ]; fn get_first_char(value: &str) -> String { value.chars().next().unwrap().to_string() } -pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result, (LexerState, Vec)> { +pub fn lex( + mut code: &str, + use_whitespace: bool, + state: LexerState, +) -> Result, (LexerState, Vec)> { let mut state = state; let mut tokens: Vec = Vec::new(); let mut brstr: String = String::new(); @@ -131,10 +154,10 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { brstr += "/"; code = code.strip_prefix(fch.as_str()).expect(""); - if brln == 0 { + if brln == 0 { if code.len() > 0 { let sch = get_first_char(code); - if sch=="/" { + if sch == "/" { code = code.strip_prefix(sch.as_str()).expect(""); brstr += &sch; brtp.push(4); @@ -144,7 +167,7 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result Result Result Result 0 { let sch = get_first_char(code); - if sch=="/" && brtp[brln-1]==5 { + if sch == "/" && brtp[brln - 1] == 5 { code = code.strip_prefix(sch.as_str()).expect(""); brstr += &sch; brtp.pop(); @@ -185,7 +208,7 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result Result Result { brstr += "\""; code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 0 { + if brln > 0 && brtp[brln - 1] == 0 { brtp.pop(); tokens.push(Token { token_type: TokenType::String, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); } else if brln == 0 { @@ -226,13 +249,13 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { brstr += "'"; code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 1 { + if brln > 0 && brtp[brln - 1] == 1 { brtp.pop(); tokens.push(Token { token_type: TokenType::String, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); } else if brln == 0 { @@ -253,18 +276,22 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 2 { + if brln > 0 && brtp[brln - 1] == 2 { brtp.pop(); if brln == 1 { tokens.push(Token { token_type: TokenType::Round, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); - } else {brstr += fch.as_str();} - } else {brstr += fch.as_str();} + } else { + brstr += fch.as_str(); + } + } else { + brstr += fch.as_str(); + } } "{" => { code = code.strip_prefix(fch.as_str()).expect(""); @@ -278,18 +305,22 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 3 { + if brln > 0 && brtp[brln - 1] == 3 { brtp.pop(); if brln == 1 { tokens.push(Token { token_type: TokenType::Curly, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); - } else {brstr += fch.as_str();} - } else {brstr += fch.as_str();} + } else { + brstr += fch.as_str(); + } + } else { + brstr += fch.as_str(); + } } "[" => { code = code.strip_prefix(fch.as_str()).expect(""); @@ -303,18 +334,22 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 3 { + if brln > 0 && brtp[brln - 1] == 3 { brtp.pop(); if brln == 1 { tokens.push(Token { token_type: TokenType::Square, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); - } else {brstr += fch.as_str();} - } else {brstr += fch.as_str();} + } else { + brstr += fch.as_str(); + } + } else { + brstr += fch.as_str(); + } } "<" => { code = code.strip_prefix(fch.as_str()).expect(""); @@ -328,18 +363,22 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result" => { code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln-1] == 6 { + if brln > 0 && brtp[brln - 1] == 6 { brtp.pop(); if brln == 1 { tokens.push(Token { token_type: TokenType::Angle, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); - } else {brstr += fch.as_str();} - } else {brstr += fch.as_str();} + } else { + brstr += fch.as_str(); + } + } else { + brstr += fch.as_str(); + } } "\\" => { brstr += "\\"; @@ -354,13 +393,14 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result 0 { brstr += "\n"; - } if brln==1 && brtp[0]==4 { + } + if brln == 1 && brtp[0] == 4 { brtp.pop(); tokens.push(Token { token_type: TokenType::Comment, value: brstr.clone(), column: br_state.column, - line: br_state.line + line: br_state.line, }); brstr = String::new(); } @@ -376,7 +416,9 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { @@ -384,7 +426,7 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { @@ -392,7 +434,7 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result { @@ -400,7 +442,7 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result, - pub ast_type: AstType + pub ast_type: AstType, } impl fmt::Display for Ast { @@ -58,7 +60,7 @@ pub struct Parser { pub index: u32, pub include_regex: Lazy, pub include_regex_local: Lazy, - pub json: bool + pub json: bool, } impl Parser { @@ -68,56 +70,98 @@ impl Parser { index: 0, include_regex: Lazy::new(|| Regex::new(r"^(#include *)<(.*?)>").unwrap()), include_regex_local: Lazy::new(|| Regex::new(r#"^(#include *)"(.*?)""#).unwrap()), - json: false + json: false, } } pub fn next(&mut self) -> Ast { - let mut ast_res: Ast = Ast {tokens: vec![], ast_type: AstType::Other}; + let mut ast_res: Ast = Ast { + tokens: vec![], + ast_type: AstType::Other, + }; let index = self.index as usize; - if index == self.tokens.len() {panic!("Reached the end of tokens")} + if index == self.tokens.len() { + panic!("Reached the end of tokens") + } let token = &self.tokens[index]; - if self.json && self.tokens.len() - (self.index as usize) > 2 && self.tokens[index+1].value == ":" { + if self.json + && self.tokens.len() - (self.index as usize) > 2 + && self.tokens[index + 1].value == ":" + { ast_res.ast_type = AstType::Json; ast_res.tokens.push(self.tokens[index].clone()); - ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.tokens.push(self.tokens[index + 2].clone()); self.index += 2; - } else if self.tokens.len()-index > 2 && self.tokens[index].value == "struct" && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); - ast_res.tokens.push(self.tokens[index+2].clone()); + } else if self.tokens.len() - index > 2 + && self.tokens[index].value == "struct" + && self.tokens[index + 1].token_type == TokenType::Identifier + && self.tokens[index + 2].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index + 1].clone()); + ast_res.tokens.push(self.tokens[index + 2].clone()); ast_res.ast_type = AstType::StructDeceleration; self.index += 2; + } else if self.tokens.len() - index > 2 + && self.tokens[index].token_type == TokenType::Keyword1 + && self.tokens[index + 1].token_type == TokenType::Round + && self.tokens[index + 2].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index].clone()); + ast_res.tokens.push(self.tokens[index + 1].clone()); + ast_res.tokens.push(self.tokens[index + 2].clone()); + ast_res.ast_type = AstType::State3; + self.index += 2; + } else if self.tokens.len() - index > 1 + && self.tokens[index].token_type == TokenType::Keyword2 + && self.tokens[index + 1].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index].clone()); + ast_res.tokens.push(self.tokens[index + 1].clone()); + ast_res.ast_type = AstType::State2; + self.index += 1; } else { match token.token_type { TokenType::Identifier => { ast_res.tokens.push(self.tokens[index].clone()); - if self.tokens.len()-index > 3 && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Round && self.tokens[index+3].token_type==TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); - ast_res.tokens.push(self.tokens[index+2].clone()); - ast_res.tokens.push(self.tokens[index+3].clone()); + if self.tokens.len() - index > 3 + && self.tokens[index + 1].token_type == TokenType::Identifier + && self.tokens[index + 2].token_type == TokenType::Round + && self.tokens[index + 3].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index + 1].clone()); + ast_res.tokens.push(self.tokens[index + 2].clone()); + ast_res.tokens.push(self.tokens[index + 3].clone()); if token.value == "void" { ast_res.ast_type = AstType::VoidFunctionDeceleration; } else { ast_res.ast_type = AstType::FunctionDeceleration; } self.index += 3; - } else if self.tokens.len()-index > 1 && self.tokens[index+1].token_type==TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); + } else if self.tokens.len() - index > 1 + && self.tokens[index + 1].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index + 1].clone()); ast_res.ast_type = AstType::StructCall; self.index += 1; - } else if self.tokens.len()-index > 2 && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); - ast_res.tokens.push(self.tokens[index+2].clone()); + } else if self.tokens.len() - index > 2 + && self.tokens[index + 1].token_type == TokenType::Identifier + && self.tokens[index + 2].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index + 1].clone()); + ast_res.tokens.push(self.tokens[index + 2].clone()); ast_res.ast_type = AstType::StructVar; self.index += 2; - } else if self.tokens.len()-index > 1 { - if self.tokens[index+1].token_type==TokenType::Identifier { - ast_res.tokens.push(self.tokens[index+1].clone()); + } else if self.tokens.len() - index > 1 { + if self.tokens[index + 1].token_type == TokenType::Identifier { + ast_res.tokens.push(self.tokens[index + 1].clone()); ast_res.ast_type = AstType::VariableDeceleration; self.index += 1; - } else if self.tokens.len()-index > 2 && self.tokens[index+2].token_type==TokenType::Identifier && self.tokens[index+1].token_type==TokenType::Angle { - ast_res.tokens.push(self.tokens[index+2].clone()); + } else if self.tokens.len() - index > 2 + && self.tokens[index + 2].token_type == TokenType::Identifier + && self.tokens[index + 1].token_type == TokenType::Angle + { + ast_res.tokens.push(self.tokens[index + 2].clone()); ast_res.tokens[0].value += "<"; - ast_res.tokens[0].value += self.tokens[index+1].value.as_str(); + ast_res.tokens[0].value += self.tokens[index + 1].value.as_str(); ast_res.tokens[0].value += ">"; ast_res.ast_type = AstType::VariableDeceleration; self.index += 2; @@ -126,10 +170,20 @@ impl Parser { } TokenType::Include => { if let Some(caps) = self.include_regex.captures(&token.value) { - ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); + ast_res.tokens.push(Token { + token_type: TokenType::String, + value: caps[2].to_owned().to_string(), + line: 0, + column: 0, + }); ast_res.ast_type = AstType::Include; } else if let Some(caps) = self.include_regex_local.captures(&token.value) { - ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); + ast_res.tokens.push(Token { + token_type: TokenType::String, + value: caps[2].to_owned().to_string(), + line: 0, + column: 0, + }); ast_res.ast_type = AstType::IncludeLocal; } else { ast_res.tokens.push(token.clone()); @@ -137,8 +191,9 @@ impl Parser { } } TokenType::Keyword => { - if token.value == "cb" && self.tokens[index+1].token_type == TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); + if token.value == "cb" && self.tokens[index + 1].token_type == TokenType::Curly + { + ast_res.tokens.push(self.tokens[index + 1].clone()); ast_res.ast_type = AstType::CodeBlock; self.index += 1; } else { @@ -153,4 +208,4 @@ impl Parser { self.index += 1; ast_res } -} \ No newline at end of file +} diff --git a/src/transpiler.rs b/src/transpiler.rs index 29b0a83..59a9905 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,80 +1,115 @@ -use std::fs; use crate::lexer::{lex, LexerState, TokenType}; use crate::parser::{Ast, AstType, Parser}; +use std::fs; #[derive(Debug, PartialEq, Clone)] pub struct Options { auto_mut: bool, auto_macro: bool, macros: Vec, - modnum: u32 + modnum: u32, } impl Default for Options { fn default() -> Options { - Options { auto_mut: true, auto_macro: true, macros: vec![String::from("println")], modnum: 0 } + Options { + auto_mut: true, + auto_macro: true, + macros: vec![String::from("println")], + modnum: 0, + } } } fn clean_incl(input: &str) -> String { input .chars() - .map(|c| if c.is_alphanumeric() || c == '_' { c } else { '_' }) + .map(|c| { + if c.is_alphanumeric() || c == '_' { + c + } else { + '_' + } + }) .collect() } pub fn transpile_mod(ast: Ast, options: &mut Options, s: &str) -> String { let modfile = ast.tokens[0].value.as_str(); - let modname = format!("{}_{}", clean_incl(modfile.split(".").collect::>()[0]), options.clone().modnum); - println!("{}", s.to_string()+modfile); - let file_content = fs::read_to_string(s.to_string()+modfile) - .expect("Error reading file"); - let transpiled_code = transpile(file_content, 0, LexerState { line: 1, column: 0 }, &mut Options::default()); - fs::write(("wyst_tmp/".to_string()+modname.as_str())+".rs", - transpiled_code) - .expect("Error writing file"); + let modname = format!( + "{}_{}", + clean_incl(modfile.split(".").collect::>()[0]), + options.clone().modnum + ); + println!("{}", s.to_string() + modfile); + let file_content = fs::read_to_string(s.to_string() + modfile).expect("Error reading file"); + let transpiled_code = transpile( + file_content, + 0, + LexerState { line: 1, column: 0 }, + &mut Options::default(), + ); + fs::write( + ("wyst_tmp/".to_string() + modname.as_str()) + ".rs", + transpiled_code, + ) + .expect("Error writing file"); modname } pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Options) -> String { let mut result = String::new(); - + if indent == 0 { // result += "type int = i32;\n"; } else { result += " ".repeat((indent as usize) * 2).as_str(); } - + let lexer_out = lex(input.as_str(), false, state); - + match lexer_out { Ok(tokens) => { let mut full_ast = Parser::new(tokens.clone()); - let mut last_ast = Ast {ast_type: AstType::Other, tokens: vec![]}; + let mut last_ast = Ast { + ast_type: AstType::Other, + tokens: vec![], + }; while full_ast.tokens.len() > full_ast.index as usize { let ast = full_ast.next(); println!("{ast}"); if last_ast.tokens.len() > 0 { let mut fl = 0; - for t in &last_ast.tokens { fl+=t.value.len() } - // if ast.tokens[ast.tokens.len()-1].line > last_ast.tokens[last_ast.tokens.len()-1].line { - // // result += ("\n".to_string() + " ".repeat(((indent+1) as usize)*2).as_str()).repeat(ast.tokens[ast.tokens.len()-1].line - last_ast.tokens[last_ast.tokens.len()-1].line).as_str(); - // result += "\n".repeat(ast.tokens[ast.tokens.len()-1].line - last_ast.tokens[last_ast.tokens.len()-1].line).as_str(); - // } - if ast.tokens[ast.tokens.len()-1].column > last_ast.tokens[last_ast.tokens.len()-1].column+fl { - result += " ".repeat(ast.tokens[ast.tokens.len()-1].column - (last_ast.tokens[last_ast.tokens.len()-1].column+fl)).as_str(); + for t in &last_ast.tokens { + fl += t.value.len() + } + if ast.tokens[ast.tokens.len() - 1].column + > last_ast.tokens[last_ast.tokens.len() - 1].column + fl + { + result += " " + .repeat( + ast.tokens[ast.tokens.len() - 1].column + - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), + ) + .as_str(); } } - last_ast = Ast {ast_type: ast.ast_type.clone(), tokens: ast.tokens.clone()}; + last_ast = Ast { + ast_type: ast.ast_type.clone(), + tokens: ast.tokens.clone(), + }; if ast.ast_type == AstType::FunctionDeceleration { result += format!( "fn {}({}) -> {} {}", ast.tokens[1].value, - transpile_round(ast.tokens[2].value.clone(), LexerState { - line: ast.tokens[2].line, - column: ast.tokens[2].column - }), + transpile_round( + ast.tokens[2].value.clone(), + LexerState { + line: ast.tokens[2].line, + column: ast.tokens[2].column + } + ), ast.tokens[0].value, transpile( ast.tokens[3].value.clone(), @@ -91,10 +126,13 @@ pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Op result += format!( "fn {}({}) {}", ast.tokens[1].value, - transpile_round(ast.tokens[2].value.clone(), LexerState { - line: ast.tokens[2].line, - column: ast.tokens[2].column - }), + transpile_round( + ast.tokens[2].value.clone(), + LexerState { + line: ast.tokens[2].line, + column: ast.tokens[2].column + } + ), transpile( ast.tokens[3].value.clone(), indent + 1, @@ -117,61 +155,92 @@ pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Op line: ast.tokens[1].line, column: ast.tokens[1].column } - ).trim_end() - ).replace("\n", ("\n".to_string() + " ".repeat(((indent+1) as usize)*2).as_str()).as_str()) + ) + .trim_end() + ) + .replace( + "\n", + ("\n".to_string() + " ".repeat(((indent + 1) as usize) * 2).as_str()) + .as_str(), + ) .as_str(); result += "\n}\n"; } else if ast.ast_type == AstType::VariableDeceleration { if options.clone().auto_mut { - result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += + format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value) + .as_str(); } else { - result += format!("let {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += format!("let {}: {}", ast.tokens[1].value, ast.tokens[0].value) + .as_str(); } } else if ast.ast_type == AstType::MutVariableDeceleration { - result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); - } else if ast.ast_type == AstType::Other && ast.tokens[0].token_type == TokenType::Round { + result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value) + .as_str(); + } else if ast.ast_type == AstType::Other + && ast.tokens[0].token_type == TokenType::Round + { result += format!( "({})", - transpile_round(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_round( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square { result += format!( "[{}]", - transpile_square(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_square( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.ast_type == AstType::CodeBlock { - result+="{"; - result+=ast.tokens[0].value.as_str(); - result+="}"; + result += "{"; + result += ast.tokens[0].value.as_str(); + result += "}"; } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { // if ast.tokens[0].token_type == TokenType::Newline { // result += (ast.tokens[0].value.as_str().to_owned() // + (" ".repeat((indent as usize) * 2).as_str())) // .as_str(); // } else { - // result += ast.tokens[0].value.as_str(); - result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { + // result += ast.tokens[0].value.as_str(); + result += transpile_json( + ast.tokens[0].value.as_str().to_string(), + LexerState { line: ast.tokens[0].line, - column: ast.tokens[0].column - }).as_str(); + column: ast.tokens[0].column, + }, + ) + .as_str(); // } } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { - result+="."; + result += "."; } else if ast.ast_type == AstType::StructCall { result += ast.tokens[0].value.as_str(); result += " {"; result += ast.tokens[1].value.as_str(); result += "}"; } else if ast.ast_type == AstType::StructVar { - result += format!("let mut {}: {} = {} {}{}{}", ast.tokens[1].value.as_str(), ast.tokens[0].value.as_str(), ast.tokens[0].value.as_str(), "{", ast.tokens[2].value.as_str(), "}").as_str(); + result += format!( + "let mut {}: {} = {} {}{}{}", + ast.tokens[1].value.as_str(), + ast.tokens[0].value.as_str(), + ast.tokens[0].value.as_str(), + "{", + ast.tokens[2].value.as_str(), + "}" + ) + .as_str(); } else if ast.ast_type == AstType::Include { let modname = transpile_mod(ast, options, "lib/"); result += "mod "; @@ -190,7 +259,45 @@ pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Op result += modname.as_str(); result += "::*;\n"; options.modnum += 1; - } // flp + } else if ast.ast_type == AstType::State3 { + result += format!( + "{} {} {}", + ast.tokens[0].value.clone(), + transpile_round( + ast.tokens[1].value.clone(), + LexerState { + line: ast.tokens[1].line, + column: ast.tokens[1].column + } + ), + transpile( + ast.tokens[2].value.clone(), + indent + 1, + LexerState { + line: ast.tokens[2].line, + column: ast.tokens[2].column + }, + options + ), + ) + .as_str(); + } else if ast.ast_type == AstType::State2 { + result += format!( + "{} {}", + ast.tokens[0].value.clone(), + transpile( + ast.tokens[1].value.clone(), + indent + 1, + LexerState { + line: ast.tokens[1].line, + column: ast.tokens[1].column + }, + options + ), + ) + .as_str(); + } + // flp else { if ast.tokens[0].token_type == TokenType::Newline { result += (ast.tokens[0].value.as_str().to_owned() @@ -200,27 +307,31 @@ pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Op result += ";\n"; result += " ".repeat((indent as usize) * 2).as_str(); } else { - // if last_ast.tokens.len() > 0 && ( - // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Identifier || - // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Keyword || - // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Number + // if last_ast.tokens.len() > 0 && ( + // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Identifier || + // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Keyword || + // last_ast.tokens[last_ast.tokens.len()-1].token_type == TokenType::Number // ) { - // let ltkn = last_ast.tokens[last_ast.tokens.len()-1].token_type; - // if ltkn == TokenType::Identifier || - // ltkn == TokenType::Keyword || - // ltkn == TokenType::Number { - // } + // let ltkn = last_ast.tokens[last_ast.tokens.len()-1].token_type; + // if ltkn == TokenType::Identifier || + // ltkn == TokenType::Keyword || + // ltkn == TokenType::Number { + // } // } result += ast.tokens[0].value.as_str(); - if options.auto_macro && options.macros.contains(&ast.tokens[0].value.as_str().to_string()) { + if options.auto_macro + && options + .macros + .contains(&ast.tokens[0].value.as_str().to_string()) + { result += "!"; } } } } - + result = result.trim_end().to_string(); - + if indent > 0 { result += "\n"; result += " ".repeat((indent as usize - 1) * 2).as_str(); @@ -238,55 +349,91 @@ pub fn transpile(input: String, indent: u32, state: LexerState, options: &mut Op pub fn transpile_round(input: String, state: LexerState) -> String { let mut result = String::new(); let lexer_out = lex(input.as_str(), false, state); - + match lexer_out { Ok(tokens) => { let mut full_ast = Parser::new(tokens.clone()); + let mut last_ast = Ast { + ast_type: AstType::Other, + tokens: vec![], + }; while full_ast.tokens.len() > full_ast.index as usize { let ast = full_ast.next(); + if last_ast.tokens.len() > 0 { + let mut fl = 0; + for t in &last_ast.tokens { + fl += t.value.len() + } + if ast.tokens[ast.tokens.len() - 1].column + > last_ast.tokens[last_ast.tokens.len() - 1].column + fl + { + result += " " + .repeat( + ast.tokens[ast.tokens.len() - 1].column + - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), + ) + .as_str(); + } + } + last_ast = Ast { + ast_type: ast.ast_type.clone(), + tokens: ast.tokens.clone(), + }; if ast.ast_type == AstType::VariableDeceleration { result += format!("{}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.ast_type == AstType::MutVariableDeceleration { - result += format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += + format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.ast_type == AstType::PointerDeceleration { - result += format!("{}: &mut {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += + format!("{}: &mut {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { result += format!( "({})", - transpile_round(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_round( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square { result += format!( "[{}]", - transpile_square(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_square( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { - result+="."; + result += "."; } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }).as_str(); + result += transpile_json( + ast.tokens[0].value.as_str().to_string(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column, + }, + ) + .as_str(); } else if ast.ast_type == AstType::StructCall { result += ast.tokens[0].value.as_str(); result += " {"; result += ast.tokens[1].value.as_str(); result += "}"; - } // flp + } + // flp else { result += ast.tokens[0].value.as_str(); - result += " "; } } - + result = result.trim_end().to_string(); result } @@ -299,58 +446,92 @@ pub fn transpile_round(input: String, state: LexerState) -> String { pub fn transpile_square(input: String, state: LexerState) -> String { let mut result = String::new(); let lexer_out = lex(input.as_str(), false, state); - + match lexer_out { Ok(tokens) => { let mut full_ast = Parser::new(tokens.clone()); - + let mut last_ast = Ast { + ast_type: AstType::Other, + tokens: vec![], + }; while full_ast.tokens.len() > full_ast.index as usize { let ast = full_ast.next(); - println!("{ast}"); - + if last_ast.tokens.len() > 0 { + let mut fl = 0; + for t in &last_ast.tokens { + fl += t.value.len() + } + if ast.tokens[ast.tokens.len() - 1].column + > last_ast.tokens[last_ast.tokens.len() - 1].column + fl + { + result += " " + .repeat( + ast.tokens[ast.tokens.len() - 1].column + - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), + ) + .as_str(); + } + } + last_ast = Ast { + ast_type: ast.ast_type.clone(), + tokens: ast.tokens.clone(), + }; + if ast.ast_type == AstType::VariableDeceleration { result += format!("{}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.ast_type == AstType::MutVariableDeceleration { - result += format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += + format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.ast_type == AstType::PointerDeceleration { - result += format!("{}: &mut {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += + format!("{}: &mut {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { result += format!( "({})", - transpile_round(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_round( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square { result += format!( "[{}]", - transpile_square(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_square( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { - result+="."; + result += "."; } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }).as_str(); + result += transpile_json( + ast.tokens[0].value.as_str().to_string(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column, + }, + ) + .as_str(); } else if ast.ast_type == AstType::StructCall { result += ast.tokens[0].value.as_str(); result += " {"; result += ast.tokens[1].value.as_str(); result += "}"; - } // flp + } + // flp else { result += ast.tokens[0].value.as_str(); - result += " "; } } - + result = result.trim_end().to_string(); result } @@ -363,15 +544,39 @@ pub fn transpile_square(input: String, state: LexerState) -> String { pub fn transpile_json(input: String, state: LexerState) -> String { let mut result = String::new(); let lexer_out = lex(input.as_str(), false, state); - + match lexer_out { Ok(tokens) => { let mut full_ast = Parser::new(tokens.clone()); full_ast.json = true; result += "HashMap::from(["; + let mut last_ast = Ast { + ast_type: AstType::Other, + tokens: vec![], + }; while full_ast.tokens.len() > full_ast.index as usize { let ast = full_ast.next(); - println!("{ast}"); + if last_ast.tokens.len() > 0 { + let mut fl = 0; + for t in &last_ast.tokens { + fl += t.value.len() + } + if ast.tokens[ast.tokens.len() - 1].column + > last_ast.tokens[last_ast.tokens.len() - 1].column + fl + { + result += " " + .repeat( + ast.tokens[ast.tokens.len() - 1].column + - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), + ) + .as_str(); + } + } + last_ast = Ast { + ast_type: ast.ast_type.clone(), + tokens: ast.tokens.clone(), + }; + if ast.ast_type == AstType::Json { result += "("; result += ast.tokens[0].value.as_str(); @@ -381,29 +586,38 @@ pub fn transpile_json(input: String, state: LexerState) -> String { } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { result += format!( "({})", - transpile_round(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_round( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square { result += format!( "[{}]", - transpile_square(ast.tokens[0].value.clone(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }) + transpile_square( + ast.tokens[0].value.clone(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + } + ) ) .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }).as_str(); + result += transpile_json( + ast.tokens[0].value.as_str().to_string(), + LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column, + }, + ) + .as_str(); } else { result += ast.tokens[0].value.as_str(); - result += " "; } } result += "])"; @@ -414,4 +628,4 @@ pub fn transpile_json(input: String, state: LexerState) -> String { panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); } } -} \ No newline at end of file +}