better errors and defs
This commit is contained in:
+13
-2
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user