diff --git a/Cargo.toml b/Cargo.toml index 2ddaf24..bf50572 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,6 @@ once_cell = "1.19.0" clap = { version = "4.0", features = ["derive"] } lspower = "1.5.0" tokio = { version = "1.38.0", features = ["full"] } -tokio-macros = "2.3.0" \ No newline at end of file +tokio-macros = "2.3.0" +rand = "0.8.5" +lsp-client-rs = "0.1.0" diff --git a/src/lsp.rs b/src/lsp.rs index bc775ae..284f5f7 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -1,12 +1,13 @@ -use std::collections::HashMap; +// use std::collections::HashMap; +// use std::fs; + use std::fs; +use lspower; use lspower::jsonrpc::Result; use lspower::lsp::{self, *}; use lspower::{Client, LanguageServer}; -use lspower; -use crate::lexer::LexerState; use crate::transpiler::Transpiler; #[derive(Debug)] @@ -41,7 +42,7 @@ impl LanguageServer for Backend { _params: lsp::CompletionParams, ) -> lspower::jsonrpc::Result> { Ok(Some(CompletionResponse::Array(vec![ - CompletionItem::new_simple("mylabel".to_string(), "mydetail".to_string()) + CompletionItem::new_simple("mylabel".to_string(), "mydetail".to_string()), ]))) } @@ -50,7 +51,6 @@ impl LanguageServer for Backend { } } -// #[tokio::main] // pub async fn run_lsp_server() { // let stdin = tokio::io::stdin(); // let stdout = tokio::io::stdout(); @@ -62,22 +62,12 @@ impl LanguageServer for Backend { // .await; // } -pub fn run_lsp_server() { - let mut options = Transpiler { - auto_mut: true, - auto_macro: true, - auto_pub: false, - macros: vec![String::from("println")], - modnum: 0, +#[tokio::main] +pub async fn run_lsp_server() { + let mut transpiler = Transpiler { var_match: String::from("x"), - var_state: LexerState { line: 4, column: 4 }, - matched_vars: HashMap::new() + ..Default::default() }; - let file_content = fs::read_to_string("main.wt") - .expect("Error reading file"); - let _ = options.transpile(file_content.to_string(), - 0, - LexerState { line: 1, column: 0 }, - ); - println!("{:?}", options.matched_vars); -} \ No newline at end of file + let file_content = fs::read_to_string("main.wt").expect("Error reading file"); + transpiler.transpile(file_content, 0); +} diff --git a/src/main.rs b/src/main.rs index 558ed72..c28678f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,10 @@ -mod transpiler; -mod parser; -mod lexer; mod compile; +mod lexer; mod lsp; -use std::{fs, path::Path}; +mod parser; +mod transpiler; use clap::Parser; -use lexer::LexerState; +use std::{fs, path::Path}; use transpiler::Transpiler; use crate::lsp::run_lsp_server; @@ -28,22 +27,24 @@ fn main() { match args.stdio { true => { run_lsp_server(); - }, + } false => { - let file_content = fs::read_to_string("main.wt") - .expect("Error reading file"); + let file_content = fs::read_to_string("main.wt").expect("Error reading file"); if Path::new("build").exists() { fs::remove_dir_all("build").expect("err rm build"); } fs::create_dir("build").expect("error making build"); let mut trsp = Transpiler::default(); - let transpiled_code = trsp.transpile(file_content, 0, LexerState { line: 1, column: 0 }); + let transpiled_code = trsp.transpile(file_content, 0); match args.rust { Some(ref rust_file_name) => { // Write transpiled code to Rust file - compile::write_to_rust_file(&transpiled_code, ("build/".to_string()+rust_file_name).as_str()) - .expect("Error writing to Rust file"); + compile::write_to_rust_file( + &transpiled_code, + ("build/".to_string() + rust_file_name).as_str(), + ) + .expect("Error writing to Rust file"); println!("Transpiled code written to {}", rust_file_name); } None => { diff --git a/src/parser.rs b/src/parser.rs index 9615bbb..347038e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ use crate::lexer::{Token, TokenType}; use once_cell::sync::Lazy; use regex::Regex; -use std::fmt; +use std::{collections::HashMap, fmt}; #[derive(Clone, Debug, PartialEq, Eq)] pub enum AstType { @@ -64,181 +64,211 @@ pub struct Parser { pub include_regex: Lazy, pub include_regex_local: Lazy, pub json: bool, + pub variables: HashMap, +} +#[derive(Debug, PartialEq, Clone)] +pub enum VariableType { + Func, + Var, +} +#[derive(Debug, PartialEq, Clone)] +pub struct Variable { + pub vtype: VariableType, + pub indent: u32, + pub line: usize, + pub column: usize, } impl Parser { - pub fn new(tokens: Vec) -> Parser { + pub fn new(tokens: Vec, variables: HashMap) -> Parser { Parser { tokens: tokens, index: 0, include_regex: Lazy::new(|| Regex::new(r"^(#include *)<(.*?)>").unwrap()), include_regex_local: Lazy::new(|| Regex::new(r#"^(#include *)"(.*?)""#).unwrap()), + variables: variables, json: false, } } - pub fn next(&mut self) -> Ast { - 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") - } - let token = &self.tokens[index]; - 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()); - self.index += 2; - } else if self.tokens.len() - index > 1 - && self.tokens[index].value == "&" - && self.tokens[index + 1].token_type == TokenType::Identifier { + pub fn parse(&mut self) -> Vec { + let mut full_ast: Vec = Vec::new(); + while self.tokens.len() > self.index as usize { + 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") + } + let token = &self.tokens[index]; + 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()); + self.index += 2; + } else if self.tokens.len() - index > 1 + && self.tokens[index].value == "&" + && self.tokens[index + 1].token_type == TokenType::Identifier + { ast_res.tokens.push(self.tokens[index + 1].clone()); ast_res.ast_type = AstType::Ref; self.index += 1; - } 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].value == "namespace" - && 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::Namespace; - self.index += 2; - } else if self.tokens.len() - index > 2 - && self.tokens[index].value == "impl" - && 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::Impl; - 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 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()); - 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()); - 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 { + } 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].value == "namespace" + && 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::Namespace; + self.index += 2; + } else if self.tokens.len() - index > 2 + && self.tokens[index].value == "impl" + && 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::Impl; + 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.ast_type = AstType::VariableDeceleration; + 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.variables.insert( + self.tokens[index + 1].value.clone(), + Variable { + vtype: VariableType::Func, + indent: 0, + line: self.tokens[index + 1].line.clone(), + column: self.tokens[index + 1].column.clone(), + }, + ); + 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()); + ast_res.ast_type = AstType::StructCall; 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 + && 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.tokens[0].value += "<"; - 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; - } else if self.tokens.len() - index > 2 - && self.tokens[index + 1].value == "*" - && self.tokens[index + 2].token_type == TokenType::Identifier { - ast_res.tokens.push(self.tokens[index + 2].clone()); - ast_res.ast_type = AstType::PointerDeceleration; + 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()); + 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()); + ast_res.tokens[0].value += "<"; + 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; + } else if self.tokens.len() - index > 2 + && self.tokens[index + 1].value == "*" + && self.tokens[index + 2].token_type == TokenType::Identifier + { + ast_res.tokens.push(self.tokens[index + 2].clone()); + ast_res.ast_type = AstType::PointerDeceleration; + self.index += 2; + } } } - } - 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.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.ast_type = AstType::IncludeLocal; - } else { - ast_res.tokens.push(token.clone()); - ast_res.ast_type = AstType::Include; + 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.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.ast_type = AstType::IncludeLocal; + } else { + ast_res.tokens.push(token.clone()); + ast_res.ast_type = AstType::Include; + } } - } - TokenType::Keyword => { - 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 { + TokenType::Keyword => { + 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 { + ast_res.tokens.push(token.clone()); + } + } + _ => { ast_res.tokens.push(token.clone()); } } - _ => { - ast_res.tokens.push(token.clone()); - } } + self.index += 1; + full_ast.push(ast_res); } - self.index += 1; - ast_res + full_ast } } diff --git a/src/transpiler.rs b/src/transpiler.rs index acb18a7..458b1f5 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,21 +1,11 @@ use crate::lexer::{lex, LexerState, TokenType}; -use crate::parser::{Ast, AstType, Parser}; +use crate::parser::{Ast, AstType, Parser, Variable, VariableType}; use std::collections::HashMap; use std::fs; -#[derive(Debug, PartialEq, Clone)] -pub enum VarTypes { - Var -} - -#[derive(Debug, PartialEq, Clone)] -pub struct Var { - vtype: VarTypes, - state: LexerState -} - #[derive(Debug, PartialEq, Clone)] pub struct Transpiler { + pub state: LexerState, pub auto_mut: bool, pub auto_macro: bool, pub auto_pub: bool, @@ -23,12 +13,13 @@ pub struct Transpiler { pub modnum: u32, pub var_match: String, pub var_state: LexerState, - pub matched_vars: HashMap, + pub matched_vars: HashMap, } impl Default for Transpiler { fn default() -> Transpiler { Transpiler { + state: LexerState { line: 1, column: 0 }, auto_mut: true, auto_macro: true, auto_pub: false, @@ -36,33 +27,33 @@ impl Default for Transpiler { modnum: 0, var_state: LexerState { line: 0, column: 0 }, var_match: String::new(), - matched_vars: HashMap::new() + matched_vars: HashMap::new(), } } } impl Transpiler { - pub fn transpile(&mut self, input: String, indent: u32, state: LexerState) -> String { + pub fn transpile(&mut self, input: String, indent: u32) -> String { let mut result = String::new(); - let mut variables: HashMap = HashMap::new(); - + let mut variables: HashMap = HashMap::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); - + let lexer_out = lex(input.as_str(), false, self.state); + match lexer_out { Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone()); + let mut full_ast = Parser::new(tokens.clone(), variables); 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(); + for ast in full_ast.parse() { + let variables = full_ast.variables.clone(); + println!("{:?}", variables); if last_ast.tokens.len() > 0 { let mut fl = 0; for t in &last_ast.tokens { @@ -83,7 +74,7 @@ impl Transpiler { ast_type: ast.ast_type.clone(), tokens: ast.tokens.clone(), }; - + if ast.ast_type == AstType::FunctionDeceleration { if self.auto_pub { result += "pub "; @@ -91,22 +82,9 @@ impl Transpiler { result += format!( "fn {}({}) -> {} {}", ast.tokens[1].value, - self.transpile_round( - ast.tokens[2].value.clone(), - LexerState { - line: ast.tokens[2].line, - column: ast.tokens[2].column - } - ), + self.transpile_round(ast.tokens[2].value.clone(),), ast.tokens[0].value, - self.transpile( - ast.tokens[3].value.clone(), - indent + 1, - LexerState { - line: ast.tokens[3].line, - column: ast.tokens[3].column - } - ) + self.transpile(ast.tokens[3].value.clone(), indent + 1) ) .as_str(); } else if ast.ast_type == AstType::VoidFunctionDeceleration { @@ -116,21 +94,8 @@ impl Transpiler { result += format!( "fn {}({}) {}", ast.tokens[1].value, - self.transpile_round( - ast.tokens[2].value.clone(), - LexerState { - line: ast.tokens[2].line, - column: ast.tokens[2].column - } - ), - self.transpile( - ast.tokens[3].value.clone(), - indent + 1, - LexerState { - line: ast.tokens[3].line, - column: ast.tokens[3].column - }, - ) + self.transpile_round(ast.tokens[2].value.clone(),), + self.transpile(ast.tokens[3].value.clone(), indent + 1,) ) .as_str(); } else if ast.ast_type == AstType::StructDeceleration { @@ -141,14 +106,8 @@ impl Transpiler { "struct {} {} {}", ast.tokens[0].value, "{\n", - self.transpile_round( - ast.tokens[1].value.clone(), - LexerState { - line: ast.tokens[1].line, - column: ast.tokens[1].column - } - ) - .trim_end() + self.transpile_round(ast.tokens[1].value.clone(),) + .trim_end() ) .replace( "\n", @@ -158,36 +117,27 @@ impl Transpiler { .as_str(); result += "\n}\n"; } else if ast.ast_type == AstType::VariableDeceleration { - variables.insert(ast.tokens[1].value.clone(), Var {vtype: VarTypes::Var, state: LexerState { - line: ast.tokens[1].line, - column: ast.tokens[1].column, - }}); if self.clone().auto_mut { 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(); + 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!( - "({})", - self.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!("({})", self.transpile_round(ast.tokens[0].value.clone(),)) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square + { result += format!( "[{}]", self.transpile_square( @@ -203,21 +153,23 @@ impl Transpiler { result += "{"; result += ast.tokens[0].value.as_str(); result += "}"; - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { + } 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 += self.transpile_json( - ast.tokens[0].value.as_str().to_string(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column, - }, - ) - .as_str(); + result += self + .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.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result += "."; @@ -259,35 +211,15 @@ impl Transpiler { result += format!( "{} {} {}", ast.tokens[0].value.clone(), - self.transpile_round( - ast.tokens[1].value.clone(), - LexerState { - line: ast.tokens[1].line, - column: ast.tokens[1].column - } - ), - self.transpile( - ast.tokens[2].value.clone(), - indent + 1, - LexerState { - line: ast.tokens[2].line, - column: ast.tokens[2].column - } - ), + self.transpile_round(ast.tokens[1].value.clone(),), + self.transpile(ast.tokens[2].value.clone(), indent + 1,), ) .as_str(); } else if ast.ast_type == AstType::State2 { result += format!( "{} {}", ast.tokens[0].value.clone(), - self.transpile( - ast.tokens[1].value.clone(), - indent + 1, - LexerState { - line: ast.tokens[1].line, - column: ast.tokens[1].column - }, - ), + self.transpile(ast.tokens[1].value.clone(), indent + 1,), ) .as_str(); } else if ast.ast_type == AstType::Namespace { @@ -295,11 +227,7 @@ impl Transpiler { "mod {} {}{}{}", &ast.tokens[0].value.clone(), "{", - self.transpile( - ast.tokens[1].value.clone(), - 0, - state, - ), + self.transpile(ast.tokens[1].value.clone(), 0), "}" ) .as_str(); @@ -308,21 +236,23 @@ impl Transpiler { "impl {} {}{}{}", &ast.tokens[0].value.clone(), "{", - self.transpile( - ast.tokens[1].value.clone(), - 0, - state, - ), + self.transpile(ast.tokens[1].value.clone(), 0,), "}" ) .as_str(); } else if ast.ast_type == AstType::PointerDeceleration { if self.auto_mut { - result += - format!("let mut {}: &mut {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + result += format!( + "let mut {}: &mut {}", + ast.tokens[1].value, ast.tokens[0].value + ) + .as_str(); } else { - 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(); } } // flp @@ -357,20 +287,22 @@ impl Transpiler { } } } - + result = result.trim_end().to_string(); - - if self.var_match != "" && (state.line + input.len()) > self.var_state.line { - for (name, var) in variables { - if (self.var_state.line > var.state.line || - (self.var_state.line == var.state.line && self.var_state.column > var.state.column)) && - name.to_lowercase().starts_with(&self.var_match) { - self.matched_vars.insert(name, var); - } - } + + if self.var_match != "" && (self.state.line + input.len()) > self.var_state.line { + // for (name, var) in variables { + // if (self.var_state.line > var.line + // || (self.var_state.line == var.line + // && self.var_state.column > var.column)) + // && name.to_lowercase().starts_with(&self.var_match) + // { + // self.matched_vars.insert(name, var); + // } + // } self.var_match = String::new(); } - + if indent > 0 { result += "\n"; result += " ".repeat((indent as usize - 1) * 2).as_str(); @@ -387,16 +319,12 @@ impl Transpiler { pub fn transpile_mod(&mut self, ast: Ast, s: &str) -> String { let modfile = ast.tokens[0].value.as_str(); let modname = format!( - "{}_{}", - clean_incl(modfile.split(".").collect::>()[0]), + "mod_{}", + // clean_incl(modfile.split(".").collect::>()[0]), self.clone().modnum ); let file_content = fs::read_to_string(s.to_string() + modfile).expect("Error reading file"); - let transpiled_code = self.transpile( - file_content, - 0, - LexerState { line: 1, column: 0 } - ); + let transpiled_code = self.transpile(file_content, 0); fs::write( ("build/".to_string() + modname.as_str()) + ".rs", transpiled_code, @@ -404,19 +332,19 @@ impl Transpiler { .expect("Error writing file"); modname } - pub fn transpile_round(&mut self, input: String, state: LexerState) -> String { + pub fn transpile_round(&mut self, input: String) -> String { let mut result = String::new(); - let lexer_out = lex(input.as_str(), false, state); - + let lexer_out = lex(input.as_str(), false, self.state); + let mut variables: HashMap = HashMap::new(); + match lexer_out { Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone()); + let mut full_ast = Parser::new(tokens.clone(), variables); 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(); + for ast in full_ast.parse() { if last_ast.tokens.len() > 0 { let mut fl = 0; for t in &last_ast.tokens { @@ -438,26 +366,21 @@ impl Transpiler { tokens: ast.tokens.clone(), }; if ast.ast_type == AstType::VariableDeceleration { - result += format!("{}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + 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(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round + { 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!( - "({})", - self.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 { + format!("({})", self.transpile_round(ast.tokens[0].value.clone(),)) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square + { result += format!( "[{}]", self.transpile_square( @@ -471,15 +394,17 @@ impl Transpiler { .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result += "."; - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += self.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.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly + { + result += self + .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 += " {"; @@ -494,7 +419,7 @@ impl Transpiler { result += ast.tokens[0].value.as_str(); } } - + result = result.trim_end().to_string(); result } @@ -503,20 +428,20 @@ impl Transpiler { } } } - + pub fn transpile_square(&mut self, input: String, state: LexerState) -> String { let mut result = String::new(); let lexer_out = lex(input.as_str(), false, state); - + let mut variables: HashMap = HashMap::new(); + match lexer_out { Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone()); + let mut full_ast = Parser::new(tokens.clone(), variables); 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(); + for ast in full_ast.parse() { if last_ast.tokens.len() > 0 { let mut fl = 0; for t in &last_ast.tokens { @@ -537,25 +462,20 @@ impl Transpiler { 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(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { - result += format!( - "({})", - self.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 { + 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(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round + { + result += + format!("({})", self.transpile_round(ast.tokens[0].value.clone(),)) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square + { result += format!( "[{}]", self.transpile_square( @@ -569,15 +489,17 @@ impl Transpiler { .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result += "."; - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += self.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.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly + { + result += self + .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 += " {"; @@ -589,7 +511,7 @@ impl Transpiler { result += ast.tokens[0].value.as_str(); } } - + result = result.trim_end().to_string(); result } @@ -598,22 +520,22 @@ impl Transpiler { } } } - + pub fn transpile_json(&mut self, input: String, state: LexerState) -> String { let mut result = String::new(); let lexer_out = lex(input.as_str(), false, state); - + let mut variables: HashMap = HashMap::new(); + match lexer_out { Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone()); + let mut full_ast = Parser::new(tokens.clone(), variables); 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(); + for ast in full_ast.parse() { if last_ast.tokens.len() > 0 { let mut fl = 0; for t in &last_ast.tokens { @@ -634,26 +556,20 @@ impl Transpiler { ast_type: ast.ast_type.clone(), tokens: ast.tokens.clone(), }; - + if ast.ast_type == AstType::Json { result += "("; result += ast.tokens[0].value.as_str(); result += ","; result += ast.tokens[1].value.as_str(); result += ")"; - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { - result += format!( - "({})", - self.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 { + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round + { + result += + format!("({})", self.transpile_round(ast.tokens[0].value.clone(),)) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square + { result += format!( "[{}]", self.transpile_square( @@ -665,15 +581,17 @@ impl Transpiler { ) ) .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - result += self.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.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly + { + result += self + .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(); } @@ -686,18 +604,18 @@ impl Transpiler { panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); } } - } + } } -fn clean_incl(input: &str) -> String { - input - .chars() - .map(|c| { - if c.is_alphanumeric() || c == '_' { - c - } else { - '_' - } - }) - .collect() -} \ No newline at end of file +// fn clean_incl(input: &str) -> String { +// input +// .chars() +// .map(|c| { +// if c.is_alphanumeric() || c == '_' { +// c +// } else { +// '_' +// } +// }) +// .collect() +// }