better errors and defs

This commit is contained in:
2024-07-02 15:06:11 +02:00
parent 41c6b99e26
commit 3cb1ab90fd
5 changed files with 102 additions and 43 deletions
+13 -2
View File
@@ -1,3 +1,4 @@
use utils::ProblemCap;
use variable::Variables; use variable::Variables;
mod parser; mod parser;
@@ -8,9 +9,19 @@ mod variable;
fn main() { fn main() {
let mut vars = Variables::new(); let mut vars = Variables::new();
let mut trsp = transpiler::Transpiler::default(); let mut trsp = transpiler::Transpiler::default();
let out = trsp.transpile("void main() {int x}".to_string(), 0, &mut vars); let out = trsp.transpile("void main() {x int x}".to_string(), 0, &mut vars);
for p in trsp.problems { for p in trsp.problems {
println!("{:?}: {}", p.problem_type, p.problem_msg) match p {
ProblemCap::Error(problem) => {
println!(
"\x1b[31;1mError\x1b[0;1m: {}\x1b[0m\n{}:{}: {:?}",
problem.problem_msg,
problem.state.line,
problem.state.column,
problem.problem_type,
)
}
}
} }
println!("{out}\n\n\n{:?}", vars); println!("{out}\n\n\n{:?}", vars);
} }
+39 -22
View File
@@ -2,18 +2,31 @@ use std::usize;
use crate::{ use crate::{
transpiler::{State, Transpiler}, transpiler::{State, Transpiler},
utils::{Problem, ProblemType}, utils::{Problem, ProblemCap, ProblemType},
variable::Variables, variable::Variables,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[allow(dead_code)]
pub enum Token { pub enum Token {
Number(String, State), Number(String, State),
Keyword(String, State),
Identifier(String, State), Identifier(String, State),
Curly(String, State), Curly(String, State),
Round(String, State), Round(String, State),
// Square(String), // Square(String),
} }
pub fn extract_state(token: Token) -> State {
match token {
Token::Number(_, state) => state,
Token::Identifier(_, state) => state,
Token::Curly(_, state) => state,
Token::Round(_, state) => state,
Token::Keyword(_, state) => state,
}
}
pub enum Ast { pub enum Ast {
Variable(String, String), Variable(String, String),
Function(String, String, String, String), Function(String, String, String, String),
@@ -22,7 +35,10 @@ pub enum Ast {
pub fn get_token(v: String, t: u32, state: State) -> Token { pub fn get_token(v: String, t: u32, state: State) -> Token {
match t { match t {
1 => Token::Number(v, state), 1 => Token::Number(v, state),
2 => Token::Identifier(v, state), 2 => match v.as_str() {
"enum" | "struct" | "namespace" => Token::Keyword(v, state),
_ => Token::Identifier(v, state),
},
3 => Token::Round(v, state), 3 => Token::Round(v, state),
4 => Token::Curly(v, state), 4 => Token::Curly(v, state),
_ => Token::Number(String::from(""), state), _ => Token::Number(String::from(""), state),
@@ -123,13 +139,11 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
t = 4; t = 4;
} }
x => { x => {
root.problems.push(Problem { root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!( problem_msg: format!("Invalid character '{}'", x,),
"Invalid character '{}' at {}:{}, LexingError",
x, root.state.line, root.state.column
),
problem_type: ProblemType::SyntaxError, problem_type: ProblemType::SyntaxError,
}); state: root.state.clone(),
}));
} }
} }
if (t != token_type || tval == '\n') && token_type != 0 { if (t != token_type || tval == '\n') && token_type != 0 {
@@ -166,31 +180,34 @@ pub fn parse(code: String, vars: &mut Variables, root: &mut Transpiler) -> Vec<A
while tokens.len() > 0 { while tokens.len() > 0 {
let mut drain: usize = 1; let mut drain: usize = 1;
match tokens.as_slice() { match tokens.as_slice() {
[Token::Identifier(var_type, state0), Token::Identifier(var_name, state1), Token::Round(round, state2), Token::Curly(curly, state3), ..] => [Token::Identifier(var_type, state0), Token::Identifier(var_name, _state1), Token::Round(round, _state2), Token::Curly(curly, _state3), ..] =>
{ {
ast.push(Ast::Function( ast.push(Ast::Function(
var_type.clone(), if var_type == "void" {
var_name.clone(), "()".to_string()
} else {
var_type.clone()
},
vars.new_func(var_name.clone(), state0.clone(), "".to_string()),
round.clone(), round.clone(),
curly.clone(), curly.clone(),
)); ));
drain += 1; drain += 3;
vars.new_func(var_name.clone(), state1.clone(), "".to_string());
} }
[Token::Identifier(var_type, state0), Token::Identifier(var_name, state1), ..] => { [Token::Identifier(var_type, _state0), Token::Identifier(var_name, state1), ..] => {
ast.push(Ast::Variable(var_type.clone(), var_name.clone())); ast.push(Ast::Variable(
var_type.clone(),
vars.new_var(var_name.clone(), state1.clone(), "".to_string()),
));
drain += 1; drain += 1;
vars.new_var(var_name.clone(), state1.clone(), "".to_string());
} }
x => { x => {
if !pcon.contains(&(root.state.line, root.state.column)) { if !pcon.contains(&(root.state.line, root.state.column)) {
root.problems.push(Problem { root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!( problem_msg: format!("Invalid placement"),
"Invalid placement '{:?}' at {}:{}, ParserError",
x, root.state.line, root.state.column
),
problem_type: ProblemType::SyntaxError, problem_type: ProblemType::SyntaxError,
}); state: extract_state(x[0].clone()),
}));
pcon.push((root.state.line, root.state.column)); pcon.push((root.state.line, root.state.column));
} }
} }
+17 -5
View File
@@ -1,6 +1,6 @@
use crate::{ use crate::{
parser::{self, Ast}, parser::{self, Ast},
utils::Problem, utils::ProblemCap,
variable::Variables, variable::Variables,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -16,7 +16,7 @@ pub struct Transpiler {
pub matched_vars: Variables, pub matched_vars: Variables,
pub peek: String, pub peek: String,
// pub libmgr: LibManager, // pub libmgr: LibManager,
pub problems: Vec<Problem>, pub problems: Vec<ProblemCap>,
pub state: State, pub state: State,
} }
@@ -33,9 +33,12 @@ impl Default for Transpiler {
} }
impl Transpiler { impl Transpiler {
pub fn transpile(&mut self, code: String, indent: u32, vars: &mut Variables) -> String { pub fn transpile(&mut self, code: String, indent: usize, vars: &mut Variables) -> String {
let ast = parser::parse(code, vars, self); let ast = parser::parse(code, vars, self);
let mut res = String::new(); let mut res = String::new();
if indent > 0 {
res += " ".repeat(indent * 2).as_str();
}
for a in ast { for a in ast {
match a { match a {
Ast::Variable(var_type, var_name) => { Ast::Variable(var_type, var_name) => {
@@ -43,13 +46,22 @@ impl Transpiler {
} }
Ast::Function(var_type, var_name, round, curly) => { Ast::Function(var_type, var_name, round, curly) => {
res += format!( res += format!(
"fn {}({}) -> {} {}{}{}", "fn {}({}) -> {} {}\n{}{}\n",
var_name, round, var_type, "{", curly, "}" var_name,
round,
var_type,
"{",
self.transpile(curly, indent + 1, &mut vars.clone()),
"}"
) )
.as_str(); .as_str();
} }
} }
} }
if indent > 0 {
res += "\n";
res += " ".repeat((indent - 1) * 2).as_str();
}
res res
} }
} }
+8
View File
@@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::transpiler::State;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProblemType { pub enum ProblemType {
VariableNotFound, VariableNotFound,
@@ -8,9 +10,15 @@ pub enum ProblemType {
SyntaxError, SyntaxError,
} }
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProblemCap {
Error(Problem),
}
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Problem { 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,
pub state: State,
} }
+25 -14
View File
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
transpiler::{State, Transpiler}, transpiler::{State, Transpiler},
utils::{Problem, ProblemType}, utils::{Problem, ProblemCap, ProblemType},
}; };
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
@@ -49,7 +49,8 @@ impl Variables {
)]), )]),
} }
} }
pub fn new_var(&mut self, name: String, state: State, desc: String) { pub fn new_var(&mut self, name: String, state: State, desc: String) -> String {
let rname = generate_varname();
self.vars.insert( self.vars.insert(
name, name,
Variable { Variable {
@@ -59,12 +60,14 @@ impl Variables {
params: Variables { params: Variables {
vars: HashMap::new(), vars: HashMap::new(),
}, },
rname: generate_varname(), rname: rname.clone(),
}, },
); );
rname
} }
pub fn new_namespace(&mut self, name: String, state: State, desc: String) { pub fn new_namespace(&mut self, name: String, state: State, desc: String) -> String {
let rname = generate_varname();
self.vars.insert( self.vars.insert(
name, name,
Variable { Variable {
@@ -74,12 +77,14 @@ impl Variables {
params: Variables { params: Variables {
vars: HashMap::new(), vars: HashMap::new(),
}, },
rname: generate_varname(), rname: rname.clone(),
}, },
); );
rname
} }
pub fn new_struct(&mut self, name: String, state: State, desc: String) { pub fn new_struct(&mut self, name: String, state: State, desc: String) -> String {
let rname = generate_varname();
self.vars.insert( self.vars.insert(
name, name,
Variable { Variable {
@@ -89,11 +94,13 @@ impl Variables {
params: Variables { params: Variables {
vars: HashMap::new(), vars: HashMap::new(),
}, },
rname: generate_varname(), rname: rname.clone(),
}, },
); );
rname
} }
pub fn new_enum(&mut self, name: String, state: State, desc: String) { pub fn new_enum(&mut self, name: String, state: State, desc: String) -> String {
let rname = generate_varname();
self.vars.insert( self.vars.insert(
name, name,
Variable { Variable {
@@ -103,9 +110,10 @@ impl Variables {
params: Variables { params: Variables {
vars: HashMap::new(), vars: HashMap::new(),
}, },
rname: generate_varname(), rname: rname.clone(),
}, },
); );
rname
} }
// pub fn new_keyword(&mut self, name: String, state: State, desc: String) { // pub fn new_keyword(&mut self, name: String, state: State, desc: String) {
@@ -123,7 +131,8 @@ impl Variables {
// ); // );
// } // }
pub fn new_func(&mut self, name: String, state: State, desc: String) { pub fn new_func(&mut self, name: String, state: State, desc: String) -> String {
let rname = generate_varname();
self.vars.insert( self.vars.insert(
name, name,
Variable { Variable {
@@ -133,9 +142,10 @@ impl Variables {
params: Variables { params: Variables {
vars: HashMap::new(), vars: HashMap::new(),
}, },
rname: generate_varname(), rname: rname.clone(),
}, },
); );
rname
} }
pub fn add(&mut self, vtype: VariableType, name: String, state: State, desc: String) { pub fn add(&mut self, vtype: VariableType, name: String, state: State, desc: String) {
self.vars.insert( self.vars.insert(
@@ -151,14 +161,15 @@ impl Variables {
}, },
); );
} }
pub fn get_var(&mut self, name: String, root: &mut Transpiler) -> String { pub fn get_var(&mut self, name: String, root: &mut Transpiler, state: State) -> String {
if let Some(x) = self.get_mut(name.clone()) { if let Some(x) = self.get_mut(name.clone()) {
return x.rname.clone(); return x.rname.clone();
} else { } else {
root.problems.push(Problem { root.problems.push(ProblemCap::Error(Problem {
problem_type: ProblemType::VariableNotFound, problem_type: ProblemType::VariableNotFound,
problem_msg: format!("Variable '{}' doesn't exist", &name), problem_msg: format!("Variable '{}' doesn't exist", &name),
}); state: state,
}));
return name; return name;
} }
} }