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;
mod parser;
@@ -8,9 +9,19 @@ mod variable;
fn main() {
let mut vars = Variables::new();
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 {
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);
}
+39 -22
View File
@@ -2,18 +2,31 @@ use std::usize;
use crate::{
transpiler::{State, Transpiler},
utils::{Problem, ProblemType},
utils::{Problem, ProblemCap, ProblemType},
variable::Variables,
};
#[derive(Clone, Debug)]
#[allow(dead_code)]
pub enum Token {
Number(String, State),
Keyword(String, State),
Identifier(String, State),
Curly(String, State),
Round(String, State),
// 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 {
Variable(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 {
match t {
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),
4 => Token::Curly(v, state),
_ => Token::Number(String::from(""), state),
@@ -123,13 +139,11 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
t = 4;
}
x => {
root.problems.push(Problem {
problem_msg: format!(
"Invalid character '{}' at {}:{}, LexingError",
x, root.state.line, root.state.column
),
root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!("Invalid character '{}'", x,),
problem_type: ProblemType::SyntaxError,
});
state: root.state.clone(),
}));
}
}
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 {
let mut drain: usize = 1;
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(
var_type.clone(),
var_name.clone(),
if var_type == "void" {
"()".to_string()
} else {
var_type.clone()
},
vars.new_func(var_name.clone(), state0.clone(), "".to_string()),
round.clone(),
curly.clone(),
));
drain += 1;
vars.new_func(var_name.clone(), state1.clone(), "".to_string());
drain += 3;
}
[Token::Identifier(var_type, state0), Token::Identifier(var_name, state1), ..] => {
ast.push(Ast::Variable(var_type.clone(), var_name.clone()));
[Token::Identifier(var_type, _state0), Token::Identifier(var_name, state1), ..] => {
ast.push(Ast::Variable(
var_type.clone(),
vars.new_var(var_name.clone(), state1.clone(), "".to_string()),
));
drain += 1;
vars.new_var(var_name.clone(), state1.clone(), "".to_string());
}
x => {
if !pcon.contains(&(root.state.line, root.state.column)) {
root.problems.push(Problem {
problem_msg: format!(
"Invalid placement '{:?}' at {}:{}, ParserError",
x, root.state.line, root.state.column
),
root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!("Invalid placement"),
problem_type: ProblemType::SyntaxError,
});
state: extract_state(x[0].clone()),
}));
pcon.push((root.state.line, root.state.column));
}
}
+17 -5
View File
@@ -1,6 +1,6 @@
use crate::{
parser::{self, Ast},
utils::Problem,
utils::ProblemCap,
variable::Variables,
};
use serde::{Deserialize, Serialize};
@@ -16,7 +16,7 @@ pub struct Transpiler {
pub matched_vars: Variables,
pub peek: String,
// pub libmgr: LibManager,
pub problems: Vec<Problem>,
pub problems: Vec<ProblemCap>,
pub state: State,
}
@@ -33,9 +33,12 @@ impl Default for 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 mut res = String::new();
if indent > 0 {
res += " ".repeat(indent * 2).as_str();
}
for a in ast {
match a {
Ast::Variable(var_type, var_name) => {
@@ -43,13 +46,22 @@ impl Transpiler {
}
Ast::Function(var_type, var_name, round, curly) => {
res += format!(
"fn {}({}) -> {} {}{}{}",
var_name, round, var_type, "{", curly, "}"
"fn {}({}) -> {} {}\n{}{}\n",
var_name,
round,
var_type,
"{",
self.transpile(curly, indent + 1, &mut vars.clone()),
"}"
)
.as_str();
}
}
}
if indent > 0 {
res += "\n";
res += " ".repeat((indent - 1) * 2).as_str();
}
res
}
}
+8
View File
@@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::transpiler::State;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProblemType {
VariableNotFound,
@@ -8,9 +10,15 @@ pub enum ProblemType {
SyntaxError,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProblemCap {
Error(Problem),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Problem {
//pub code: u32,
pub problem_type: ProblemType,
pub problem_msg: String,
pub state: State,
}
+25 -14
View File
@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::{
transpiler::{State, Transpiler},
utils::{Problem, ProblemType},
utils::{Problem, ProblemCap, ProblemType},
};
#[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(
name,
Variable {
@@ -59,12 +60,14 @@ impl Variables {
params: Variables {
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(
name,
Variable {
@@ -74,12 +77,14 @@ impl Variables {
params: Variables {
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(
name,
Variable {
@@ -89,11 +94,13 @@ impl Variables {
params: Variables {
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(
name,
Variable {
@@ -103,9 +110,10 @@ impl Variables {
params: Variables {
vars: HashMap::new(),
},
rname: generate_varname(),
rname: rname.clone(),
},
);
rname
}
// 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(
name,
Variable {
@@ -133,9 +142,10 @@ impl Variables {
params: Variables {
vars: HashMap::new(),
},
rname: generate_varname(),
rname: rname.clone(),
},
);
rname
}
pub fn add(&mut self, vtype: VariableType, name: String, state: State, desc: String) {
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()) {
return x.rname.clone();
} else {
root.problems.push(Problem {
root.problems.push(ProblemCap::Error(Problem {
problem_type: ProblemType::VariableNotFound,
problem_msg: format!("Variable '{}' doesn't exist", &name),
});
state: state,
}));
return name;
}
}