better module system
This commit is contained in:
+12
-10
@@ -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"));
|
||||
}
|
||||
|
||||
+3
-2
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
+15
-4
@@ -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 => {}
|
||||
|
||||
+35
-14
@@ -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<Problem>,
|
||||
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,
|
||||
|
||||
+19
-14
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user