better module system

This commit is contained in:
2024-06-20 16:10:10 +02:00
parent ea7222255a
commit 1edc714213
6 changed files with 86 additions and 45 deletions
+2 -1
View File
@@ -2,5 +2,6 @@
"rust-analyzer.linkedProjects": [ "rust-analyzer.linkedProjects": [
"./Cargo.toml" "./Cargo.toml"
], ],
"rust-analyzer.showUnlinkedFileNotification": false "rust-analyzer.showUnlinkedFileNotification": false,
"cSpell.enabled": false
} }
+12 -10
View File
@@ -1,7 +1,7 @@
use std::fs; use std::fs;
use std::io::{Error, ErrorKind};
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::io::{Error, ErrorKind};
pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Error> { pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Error> {
// Determine the file extension based on the provided file_name // 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(()) 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") let output = Command::new("rustc")
.arg(rust_file) .arg("main.rs".to_string())
.arg("-o") .arg("-o")
.arg(output_exe) .arg(output_exe)
.output()?; .output()?;
// Check if compilation was successful // 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); eprintln!("Compilation failed with error code: {}", code);
} }
if !output.stdout.is_empty() { 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() { if !output.stderr.is_empty() {
eprintln!("Compiler errors:\n{}", String::from_utf8_lossy(&output.stderr)); eprintln!(
} "Compiler errors:\n{}",
// Compilation failed, delete the temporary Rust file String::from_utf8_lossy(&output.stderr)
if let Err(err) = fs::remove_file(rust_file) { );
eprintln!("Failed to delete temporary Rust file: {}", err);
} }
return Err(Error::new(ErrorKind::Other, "Compilation failed")); return Err(Error::new(ErrorKind::Other, "Compilation failed"));
} }
+3 -2
View File
@@ -33,7 +33,8 @@ pub fn get_completion(input: String, line: usize, column: usize) -> Variables {
peek: rand_id.clone(), peek: rand_id.clone(),
..Default::default() ..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 transpiler.matched_vars
} }
@@ -109,4 +110,4 @@ pub struct Problem {
pub code: u32, pub code: u32,
pub problem_type: ProblemType, pub problem_type: ProblemType,
pub problem_msg: String, pub problem_msg: String,
} }
+15 -4
View File
@@ -1,4 +1,5 @@
mod compile; mod compile;
mod file_writer;
mod lexer; mod lexer;
mod lsp; mod lsp;
mod lspcom; mod lspcom;
@@ -38,17 +39,23 @@ fn main() {
} }
fs::create_dir("build").expect("error making build"); fs::create_dir("build").expect("error making build");
let mut trsp = Transpiler::default(); 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 { for problem in trsp.problems {
println!("{}", problem.problem_msg) println!("{}", problem.problem_msg)
} }
trsp.writer.write();
match args.rust { match args.rust {
Some(ref rust_file_name) => { Some(ref rust_file_name) => {
// Write transpiled code to Rust file // Write transpiled code to Rust file
compile::write_to_rust_file( compile::write_to_rust_file(
&transpiled_code, &transpiled_code,
("build/".to_string() + rust_file_name).as_str(), ("build/".to_string() + "main.rs").as_str(),
) )
.expect("Error writing to Rust file"); .expect("Error writing to Rust file");
println!("Transpiled code written to {}", rust_file_name); println!("Transpiled code written to {}", rust_file_name);
@@ -63,10 +70,14 @@ fn main() {
match args.compile { match args.compile {
Some(ref exe_name) => { 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"); .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"); .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"); fs::remove_dir_all("build").expect("err rm build");
} }
None => {} None => {}
+35 -14
View File
@@ -1,11 +1,12 @@
use crate::{ use crate::{
file_writer::FileWriter,
lexer::{lex, LexerState, TokenType}, lexer::{lex, LexerState, TokenType},
lspcom::Problem, lspcom::Problem,
parser::{is_decl, Ast, AstType, Parser}, parser::{is_decl, Ast, AstType, Parser},
variable::{VariableType, Variables}, variable::{VariableType, Variables},
}; };
use std::fs; use std::{fs, path::Path};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Transpiler { pub struct Transpiler {
@@ -18,11 +19,13 @@ pub struct Transpiler {
pub peek: String, pub peek: String,
pub matched_vars: Variables, pub matched_vars: Variables,
pub problems: Vec<Problem>, pub problems: Vec<Problem>,
pub writer: FileWriter,
} }
impl Default for Transpiler { impl Default for Transpiler {
fn default() -> Transpiler { fn default() -> Transpiler {
Transpiler { let transpiler = Transpiler {
writer: FileWriter::new(".".to_string()),
state: LexerState { line: 1, column: 0 }, state: LexerState { line: 1, column: 0 },
auto_mut: true, auto_mut: true,
auto_macro: true, auto_macro: true,
@@ -32,12 +35,13 @@ impl Default for Transpiler {
peek: String::new(), peek: String::new(),
matched_vars: Variables::new(), matched_vars: Variables::new(),
problems: Vec::new(), problems: Vec::new(),
} };
transpiler
} }
} }
impl 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(); let mut result = String::new();
if indent == 0 { if indent == 0 {
// result += "type int = i32;\n"; // result += "type int = i32;\n";
@@ -54,7 +58,9 @@ impl Transpiler {
tokens: vec![], tokens: vec![],
}; };
let f_ast = full_ast.parse(); 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 { for ast in f_ast {
let mut ast = ast; let mut ast = ast;
if ast.ast_type == AstType::Other if ast.ast_type == AstType::Other
@@ -119,7 +125,11 @@ impl Transpiler {
ast.tokens[1].value, ast.tokens[1].value,
round, round,
ast.tokens[0].value, 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(); .as_str();
} else if ast.ast_type == AstType::VoidFunctionDeceleration { } else if ast.ast_type == AstType::VoidFunctionDeceleration {
@@ -132,7 +142,11 @@ impl Transpiler {
"fn {}({}) {}", "fn {}({}) {}",
ast.tokens[1].value, ast.tokens[1].value,
round, 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(); .as_str();
} else if ast.ast_type == AstType::StructDeceleration { } else if ast.ast_type == AstType::StructDeceleration {
@@ -246,7 +260,14 @@ impl Transpiler {
) )
.as_str(); .as_str();
} else if ast.ast_type == AstType::Include { } 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 += "mod ";
result += modname.as_str(); result += modname.as_str();
result += ";\n"; result += ";\n";
@@ -255,7 +276,7 @@ impl Transpiler {
result += "::*;\n"; result += "::*;\n";
self.modnum += 1; self.modnum += 1;
} else if ast.ast_type == AstType::IncludeLocal { } 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 += "mod ";
result += modname.as_str(); result += modname.as_str();
result += ";\n"; result += ";\n";
@@ -274,7 +295,7 @@ impl Transpiler {
self.transpile( self.transpile(
ast.tokens[2].value.clone(), ast.tokens[2].value.clone(),
indent + 1, indent + 1,
variables.clone() &mut variables.clone()
), ),
) )
.as_str(); .as_str();
@@ -285,7 +306,7 @@ impl Transpiler {
self.transpile( self.transpile(
ast.tokens[1].value.clone(), ast.tokens[1].value.clone(),
indent + 1, indent + 1,
variables.clone() &mut variables.clone()
), ),
) )
.as_str(); .as_str();
@@ -294,7 +315,7 @@ impl Transpiler {
"mod {} {}{}{}", "mod {} {}{}{}",
&ast.tokens[0].value.clone(), &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(); .as_str();
@@ -303,7 +324,7 @@ impl Transpiler {
"impl {} {}{}{}", "impl {} {}{}{}",
&ast.tokens[0].value.clone(), &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(); .as_str();
@@ -368,7 +389,7 @@ impl Transpiler {
self.clone().modnum self.clone().modnum
); );
let file_content = fs::read_to_string(s.to_string() + modfile).expect("Error reading file"); 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( fs::write(
("build/".to_string() + modname.as_str()) + ".rs", ("build/".to_string() + modname.as_str()) + ".rs",
transpiled_code, transpiled_code,
+19 -14
View File
@@ -93,20 +93,20 @@ impl Variables {
); );
} }
pub fn new_keyword(&mut self, name: String, state: LexerState, desc: String) { // pub fn new_keyword(&mut self, name: String, state: LexerState, desc: String) {
self.vars.insert( // self.vars.insert(
name, // name,
Variable { // Variable {
vtype: VariableType::Keyword, // vtype: VariableType::Keyword,
desc, // desc,
state, // state,
params: Variables { // params: Variables {
vars: HashMap::new(), // vars: HashMap::new(),
}, // },
rname: generate_varname(), // rname: generate_varname(),
}, // },
); // );
} // }
pub fn new_func(&mut self, name: String, state: LexerState, desc: String) { pub fn new_func(&mut self, name: String, state: LexerState, desc: String) {
self.vars.insert( self.vars.insert(
@@ -156,6 +156,11 @@ impl Variables {
pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> { pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> {
self.vars.get_mut(&name) 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 { pub fn generate_varname() -> String {