From 1edc714213a3ea21e9b04a955fdd5fdbc441dfa5 Mon Sep 17 00:00:00 2001 From: Leo Dev Date: Thu, 20 Jun 2024 16:10:10 +0200 Subject: [PATCH] better module system --- .vscode/settings.json | 3 ++- src/compile.rs | 22 ++++++++++--------- src/lspcom.rs | 5 +++-- src/main.rs | 19 +++++++++++++---- src/transpiler.rs | 49 ++++++++++++++++++++++++++++++------------- src/variable.rs | 33 ++++++++++++++++------------- 6 files changed, 86 insertions(+), 45 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4c9aee3..36979dc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "rust-analyzer.linkedProjects": [ "./Cargo.toml" ], - "rust-analyzer.showUnlinkedFileNotification": false + "rust-analyzer.showUnlinkedFileNotification": false, + "cSpell.enabled": false } \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 610fcbd..032a5f1 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -1,7 +1,7 @@ use std::fs; +use std::io::{Error, ErrorKind}; use std::path::Path; use std::process::Command; -use std::io::{Error, ErrorKind}; pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Error> { // Determine the file extension based on the provided file_name @@ -24,11 +24,11 @@ pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Ok(()) } -pub fn compile_to_executable(rust_file: &str, output_exe: &str) -> Result<(), Error> { +pub fn compile_to_executable(output_exe: &str) -> Result<(), Error> { let output = Command::new("rustc") - .arg(rust_file) + .arg("main.rs".to_string()) .arg("-o") - .arg(output_exe) + .arg(output_exe) .output()?; // Check if compilation was successful @@ -39,14 +39,16 @@ pub fn compile_to_executable(rust_file: &str, output_exe: &str) -> Result<(), Er eprintln!("Compilation failed with error code: {}", code); } if !output.stdout.is_empty() { - eprintln!("Compiler output:\n{}", String::from_utf8_lossy(&output.stdout)); + eprintln!( + "Compiler output:\n{}", + String::from_utf8_lossy(&output.stdout) + ); } if !output.stderr.is_empty() { - eprintln!("Compiler errors:\n{}", String::from_utf8_lossy(&output.stderr)); - } - // Compilation failed, delete the temporary Rust file - if let Err(err) = fs::remove_file(rust_file) { - eprintln!("Failed to delete temporary Rust file: {}", err); + eprintln!( + "Compiler errors:\n{}", + String::from_utf8_lossy(&output.stderr) + ); } return Err(Error::new(ErrorKind::Other, "Compilation failed")); } diff --git a/src/lspcom.rs b/src/lspcom.rs index 798515b..09f710d 100644 --- a/src/lspcom.rs +++ b/src/lspcom.rs @@ -33,7 +33,8 @@ pub fn get_completion(input: String, line: usize, column: usize) -> Variables { peek: rand_id.clone(), ..Default::default() }; - transpiler.transpile(place_at(input, rand_id, line, column), 0, Variables::new()); + let mut vars = Variables::new(); + transpiler.transpile(place_at(input, rand_id, line, column), 0, &mut vars); transpiler.matched_vars } @@ -109,4 +110,4 @@ pub struct Problem { pub code: u32, pub problem_type: ProblemType, pub problem_msg: String, -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index bd5f66a..6a61db2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod compile; +mod file_writer; mod lexer; mod lsp; mod lspcom; @@ -38,17 +39,23 @@ fn main() { } fs::create_dir("build").expect("error making build"); let mut trsp = Transpiler::default(); - let transpiled_code = trsp.transpile(file_content, 0, Variables::new()); + let mut vars = Variables::new(); + let mut transpiled_code = trsp.transpile(file_content, 0, &mut vars); + transpiled_code += "\nfn main() {std::process::exit("; + transpiled_code += vars.get_var("main".to_string(), &mut trsp).as_str(); + transpiled_code += "())}"; for problem in trsp.problems { println!("{}", problem.problem_msg) } + trsp.writer.write(); + 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(), + ("build/".to_string() + "main.rs").as_str(), ) .expect("Error writing to Rust file"); println!("Transpiled code written to {}", rust_file_name); @@ -63,10 +70,14 @@ fn main() { match args.compile { Some(ref exe_name) => { - compile::write_to_rust_file(&transpiled_code, "build/temp.rs") + compile::write_to_rust_file(&transpiled_code, "build/main.rs") .expect("Error writing to temporary Rust file"); - compile::compile_to_executable("build/temp.rs", exe_name) + std::env::set_current_dir("build").expect("setDir err: "); + compile::compile_to_executable(exe_name) .expect("Error compiling to executable"); + std::env::set_current_dir("..").expect("setDir0 err: "); + fs::rename(Path::new("build").join(exe_name).as_path(), exe_name) + .expect("RenameErrBuld: "); fs::remove_dir_all("build").expect("err rm build"); } None => {} diff --git a/src/transpiler.rs b/src/transpiler.rs index a1f1925..dc024a6 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,11 +1,12 @@ use crate::{ + file_writer::FileWriter, lexer::{lex, LexerState, TokenType}, lspcom::Problem, parser::{is_decl, Ast, AstType, Parser}, variable::{VariableType, Variables}, }; -use std::fs; +use std::{fs, path::Path}; #[derive(Debug, Clone)] pub struct Transpiler { @@ -18,11 +19,13 @@ pub struct Transpiler { pub peek: String, pub matched_vars: Variables, pub problems: Vec, + pub writer: FileWriter, } impl Default for Transpiler { fn default() -> Transpiler { - Transpiler { + let transpiler = Transpiler { + writer: FileWriter::new(".".to_string()), state: LexerState { line: 1, column: 0 }, auto_mut: true, auto_macro: true, @@ -32,12 +35,13 @@ impl Default for Transpiler { peek: String::new(), matched_vars: Variables::new(), problems: Vec::new(), - } + }; + transpiler } } impl Transpiler { - pub fn transpile(&mut self, input: String, indent: u32, variables: Variables) -> String { + pub fn transpile(&mut self, input: String, indent: u32, variables: &mut Variables) -> String { let mut result = String::new(); if indent == 0 { // result += "type int = i32;\n"; @@ -54,7 +58,9 @@ impl Transpiler { tokens: vec![], }; let f_ast = full_ast.parse(); - let mut variables = full_ast.variables.clone(); + //variables.expand(full_ast.variables.clone()); + *variables = full_ast.variables.clone(); + //let mut variables = full_ast.variables.clone(); for ast in f_ast { let mut ast = ast; if ast.ast_type == AstType::Other @@ -119,7 +125,11 @@ impl Transpiler { ast.tokens[1].value, round, ast.tokens[0].value, - self.transpile(ast.tokens[3].value.clone(), indent + 1, vars.clone()) + self.transpile( + ast.tokens[3].value.clone(), + indent + 1, + &mut (vars.clone()) + ) ) .as_str(); } else if ast.ast_type == AstType::VoidFunctionDeceleration { @@ -132,7 +142,11 @@ impl Transpiler { "fn {}({}) {}", ast.tokens[1].value, round, - self.transpile(ast.tokens[3].value.clone(), indent + 1, vars.clone()) + self.transpile( + ast.tokens[3].value.clone(), + indent + 1, + &mut (vars.clone()) + ) ) .as_str(); } else if ast.ast_type == AstType::StructDeceleration { @@ -246,7 +260,14 @@ impl Transpiler { ) .as_str(); } else if ast.ast_type == AstType::Include { - let modname = self.transpile_mod(ast, "lib/"); + let modname = self.writer.add( + Path::new("lib") + .join(&ast.tokens[0].value.clone()) + .to_str() + .expect("ErrConvStr0") + .to_string(), + variables, + ); result += "mod "; result += modname.as_str(); result += ";\n"; @@ -255,7 +276,7 @@ impl Transpiler { result += "::*;\n"; self.modnum += 1; } else if ast.ast_type == AstType::IncludeLocal { - let modname = self.transpile_mod(ast, ""); + let modname = self.writer.add(ast.tokens[0].value.clone(), variables); result += "mod "; result += modname.as_str(); result += ";\n"; @@ -274,7 +295,7 @@ impl Transpiler { self.transpile( ast.tokens[2].value.clone(), indent + 1, - variables.clone() + &mut variables.clone() ), ) .as_str(); @@ -285,7 +306,7 @@ impl Transpiler { self.transpile( ast.tokens[1].value.clone(), indent + 1, - variables.clone() + &mut variables.clone() ), ) .as_str(); @@ -294,7 +315,7 @@ impl Transpiler { "mod {} {}{}{}", &ast.tokens[0].value.clone(), "{", - self.transpile(ast.tokens[1].value.clone(), 0, variables.clone()), + self.transpile(ast.tokens[1].value.clone(), 0, &mut variables.clone()), "}" ) .as_str(); @@ -303,7 +324,7 @@ impl Transpiler { "impl {} {}{}{}", &ast.tokens[0].value.clone(), "{", - self.transpile(ast.tokens[1].value.clone(), 0, variables.clone()), + self.transpile(ast.tokens[1].value.clone(), 0, &mut variables.clone()), "}" ) .as_str(); @@ -368,7 +389,7 @@ impl Transpiler { 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, Variables::new()); + let transpiled_code = self.transpile(file_content, 0, &mut Variables::new()); fs::write( ("build/".to_string() + modname.as_str()) + ".rs", transpiled_code, diff --git a/src/variable.rs b/src/variable.rs index 0f45336..98be19a 100644 --- a/src/variable.rs +++ b/src/variable.rs @@ -93,20 +93,20 @@ impl Variables { ); } - pub fn new_keyword(&mut self, name: String, state: LexerState, desc: String) { - self.vars.insert( - name, - Variable { - vtype: VariableType::Keyword, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: generate_varname(), - }, - ); - } + // pub fn new_keyword(&mut self, name: String, state: LexerState, desc: String) { + // self.vars.insert( + // name, + // Variable { + // vtype: VariableType::Keyword, + // desc, + // state, + // params: Variables { + // vars: HashMap::new(), + // }, + // rname: generate_varname(), + // }, + // ); + // } pub fn new_func(&mut self, name: String, state: LexerState, desc: String) { self.vars.insert( @@ -156,6 +156,11 @@ impl Variables { pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> { self.vars.get_mut(&name) } + pub fn expand(&mut self, vars: Variables) { + for (x, y) in vars.vars { + self.vars.insert(x, y); + } + } } pub fn generate_varname() -> String {