error codes and compiler
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.10.4"
|
regex = "1.10.4"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
clap = { version = "4.0", features = ["derive"] }
|
clap = "3.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = "1.0.203"
|
serde = "1.0.203"
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
use std::{fs, path::Path, process::Command};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
transpiler::{State, Transpiler},
|
||||||
|
utils::{Problem, ProblemCap, ProblemType, Variables},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 {
|
||||||
|
let mut ecode: u8 = 0;
|
||||||
|
let mut trsp = Transpiler {
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let mut vars = Variables::new();
|
||||||
|
if let Ok(file_contents) = fs::read_to_string(input_file) {
|
||||||
|
let mut output_code = trsp.transpile(file_contents, 0, &mut vars);
|
||||||
|
if is_main {
|
||||||
|
output_code += "fn main() {";
|
||||||
|
output_code += vars
|
||||||
|
.get_var(
|
||||||
|
"main".to_string(),
|
||||||
|
&mut trsp,
|
||||||
|
State {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.as_str();
|
||||||
|
output_code += "();}";
|
||||||
|
}
|
||||||
|
if let Ok(_) = fs::write(Path::new("build").join(output_file), output_code) {}
|
||||||
|
} else {
|
||||||
|
trsp.problems.push(ProblemCap::Error(Problem {
|
||||||
|
problem_msg: "File not found".to_string(),
|
||||||
|
problem_type: ProblemType::FileNotFound,
|
||||||
|
state: State {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
for p in trsp.problems {
|
||||||
|
match p {
|
||||||
|
ProblemCap::Error(problem) => {
|
||||||
|
ecode = 1;
|
||||||
|
if problem.state.file == None {
|
||||||
|
println!(
|
||||||
|
"\x1b[31;1m{:?}\x1b[0;1m: {}",
|
||||||
|
problem.problem_type, problem.problem_msg,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"\x1b[31;1mError\x1b[0;1m: {}\x1b[0m\n{}:{}: {:?}",
|
||||||
|
problem.problem_msg,
|
||||||
|
problem.state.line,
|
||||||
|
problem.state.column,
|
||||||
|
problem.problem_type,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ecode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compile_rust(exe_file: String) {
|
||||||
|
Command::new("rustc")
|
||||||
|
.arg(Path::new("build").join("main.rs"))
|
||||||
|
.arg("-o")
|
||||||
|
.arg(exe_file)
|
||||||
|
.output()
|
||||||
|
.expect("Error compiling rust: ");
|
||||||
|
}
|
||||||
+28
-17
@@ -1,25 +1,36 @@
|
|||||||
use utils::{ProblemCap, Variables};
|
use std::{fs, process};
|
||||||
|
|
||||||
|
mod compiler;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod transpiler;
|
mod transpiler;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
use clap::{App, Arg};
|
||||||
|
use compiler::{compile_rust, transpile};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut vars = Variables::new();
|
let matches = App::new("Wyst")
|
||||||
let mut trsp = transpiler::Transpiler::default();
|
.version("0.51")
|
||||||
let out = trsp.transpile("rust{let mut x;}".to_string(), 0, &mut vars);
|
.author("Leo dev")
|
||||||
for p in trsp.problems {
|
.about("The wyst compiler")
|
||||||
match p {
|
.arg(
|
||||||
ProblemCap::Error(problem) => {
|
Arg::with_name("file")
|
||||||
println!(
|
.required(true)
|
||||||
"\x1b[31;1mError\x1b[0;1m: {}\x1b[0m\n{}:{}: {:?}",
|
.help("Sets the input file to use"),
|
||||||
problem.problem_msg,
|
|
||||||
problem.state.line,
|
|
||||||
problem.state.column,
|
|
||||||
problem.problem_type,
|
|
||||||
)
|
)
|
||||||
}
|
.arg(
|
||||||
}
|
Arg::with_name("output")
|
||||||
}
|
.short('o')
|
||||||
println!("{out}\n\n\n");
|
.long("output")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("Specifies the output executable file name"),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let file = matches.value_of("file").unwrap().to_string();
|
||||||
|
let output = matches.value_of("output").unwrap_or("out").to_string();
|
||||||
|
if let Ok(_) = fs::create_dir("build") {}
|
||||||
|
let ecode = transpile(file, "main.rs".to_string(), true);
|
||||||
|
compile_rust(output);
|
||||||
|
fs::remove_dir_all("build").expect("Error removing build");
|
||||||
|
process::exit(ecode as i32);
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-11
@@ -18,15 +18,15 @@ pub enum Token {
|
|||||||
// Square(String),
|
// Square(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_values(token: Token) -> (String, State) {
|
pub fn extract_values(token: Token) -> (u8, String, State) {
|
||||||
match token {
|
match token {
|
||||||
Token::Number(x, state) => (x, state),
|
Token::Number(x, state) => (0, x, state),
|
||||||
Token::Identifier(x, state) => (x, state),
|
Token::Identifier(x, state) => (1, x, state),
|
||||||
Token::Curly(x, state) => (x, state),
|
Token::Curly(x, state) => (2, x, state),
|
||||||
Token::Round(x, state) => (x, state),
|
Token::Round(x, state) => (3, x, state),
|
||||||
Token::DKeyword(x, state) => (x, state),
|
Token::DKeyword(x, state) => (4, x, state),
|
||||||
Token::SKeyword(x, state) => (x, state),
|
Token::SKeyword(x, state) => (5, x, state),
|
||||||
Token::Keyword(x, state) => (x, state),
|
Token::Keyword(x, state) => (6, x, state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,11 @@ pub fn tokenize(code: String, state: &mut State, root: &mut Transpiler) -> Vec<T
|
|||||||
let mut token_value: String = String::new();
|
let mut token_value: String = String::new();
|
||||||
let mut token_type: u32 = 0;
|
let mut token_type: u32 = 0;
|
||||||
let mut stoken: (u8, u8) = (0, 0);
|
let mut stoken: (u8, u8) = (0, 0);
|
||||||
let mut token_state = State { line: 0, column: 0 };
|
let mut token_state = State {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
};
|
||||||
while !code.is_empty() {
|
while !code.is_empty() {
|
||||||
if let Some(c) = code.chars().next() {
|
if let Some(c) = code.chars().next() {
|
||||||
code.remove(0);
|
code.remove(0);
|
||||||
@@ -224,8 +228,8 @@ pub fn parse(
|
|||||||
while tokens.len() > 0 {
|
while tokens.len() > 0 {
|
||||||
let mut drain: usize = 1;
|
let mut drain: usize = 1;
|
||||||
let vals = extract_values(tokens[0].clone());
|
let vals = extract_values(tokens[0].clone());
|
||||||
if vals.0.contains("list_vx") {
|
if vals.1.contains("list_vx") {
|
||||||
ast.push(Ast::Single(Token::Identifier(vals.0, vals.1)));
|
ast.push(Ast::Single(Token::Identifier(vals.1, vals.2)));
|
||||||
tokens.drain(0..1);
|
tokens.drain(0..1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-4
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
parser::{self, extract_ast, Ast},
|
parser::{self, extract_ast, extract_values, Ast},
|
||||||
utils::{ProblemCap, VariableType, Variables},
|
utils::{ProblemCap, VariableType, Variables},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub struct State {
|
pub struct State {
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
pub column: u32,
|
pub column: u32,
|
||||||
|
pub file: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@@ -27,7 +28,11 @@ impl Default for Inject {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Inject {
|
Inject {
|
||||||
inject: false,
|
inject: false,
|
||||||
state: State { line: 0, column: 0 },
|
state: State {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +43,11 @@ impl Default for Transpiler {
|
|||||||
matched_vars: Variables::new(),
|
matched_vars: Variables::new(),
|
||||||
inject: Inject::default(),
|
inject: Inject::default(),
|
||||||
problems: Vec::new(),
|
problems: Vec::new(),
|
||||||
state: State { line: 1, column: 0 },
|
state: State {
|
||||||
|
line: 1,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +105,13 @@ impl Transpiler {
|
|||||||
res += rs.as_str();
|
res += rs.as_str();
|
||||||
res += "}";
|
res += "}";
|
||||||
}
|
}
|
||||||
Ast::Single(_) => {}
|
Ast::Single(x) => {
|
||||||
|
let vals = extract_values(x);
|
||||||
|
if vals.0 == 1 {
|
||||||
|
println!("{:?}", vals);
|
||||||
|
res += vars.get_var(vals.1, self, vals.2).as_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if indent > 0 {
|
if indent > 0 {
|
||||||
|
|||||||
+25
-3
@@ -19,7 +19,6 @@ pub enum ProblemCap {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Problem {
|
pub struct Problem {
|
||||||
//pub code: u32,
|
|
||||||
pub problem_type: ProblemType,
|
pub problem_type: ProblemType,
|
||||||
pub problem_msg: String,
|
pub problem_msg: String,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
@@ -57,7 +56,11 @@ impl Variables {
|
|||||||
Variable {
|
Variable {
|
||||||
vtype: VariableType::Keyword,
|
vtype: VariableType::Keyword,
|
||||||
desc: "".to_string(),
|
desc: "".to_string(),
|
||||||
state: State { line: 0, column: 0 },
|
state: State {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
file: None,
|
||||||
|
},
|
||||||
params: Variables {
|
params: Variables {
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
},
|
},
|
||||||
@@ -182,7 +185,26 @@ impl Variables {
|
|||||||
self.vars.iter_mut()
|
self.vars.iter_mut()
|
||||||
}
|
}
|
||||||
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)
|
if !name.contains("::") {
|
||||||
|
return self.vars.get_mut(&name);
|
||||||
|
}
|
||||||
|
if let Some((x, _)) = name.split_once("::") {
|
||||||
|
println!("{x}");
|
||||||
|
if let Some(v) = self.vars.get_mut(x) {
|
||||||
|
println!("{:?}", v);
|
||||||
|
let mut var = v;
|
||||||
|
for a in name.split("::") {
|
||||||
|
if let Some(b) = var.params.vars.get_mut(a) {
|
||||||
|
var = b;
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(var);
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
pub fn expand(&mut self, vars: Variables) {
|
pub fn expand(&mut self, vars: Variables) {
|
||||||
for (x, y) in vars.vars {
|
for (x, y) in vars.vars {
|
||||||
|
|||||||
Reference in New Issue
Block a user