better error checking
This commit is contained in:
+6
-2
@@ -7,6 +7,10 @@ mod variable;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut vars = Variables::new();
|
let mut vars = Variables::new();
|
||||||
let out = transpiler::Transpiler::default().transpile(r#"int x"#.to_string(), 0, &mut vars);
|
let mut trsp = transpiler::Transpiler::default();
|
||||||
println!("{out}");
|
let out = trsp.transpile("int 12 x".to_string(), 0, &mut vars);
|
||||||
|
for p in trsp.problems {
|
||||||
|
println!("{:?}: {}", p.problem_type, p.problem_msg)
|
||||||
|
}
|
||||||
|
println!("{out}\n\n\n{:?}", vars);
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-19
@@ -1,9 +1,15 @@
|
|||||||
use crate::{transpiler::State, variable::Variables};
|
use std::usize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
transpiler::{State, Transpiler},
|
||||||
|
utils::{Problem, ProblemType},
|
||||||
|
variable::Variables,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Number(String),
|
Number(String, State),
|
||||||
Identifier(String),
|
Identifier(String, State),
|
||||||
// Curly(String),
|
// Curly(String),
|
||||||
// Round(String),
|
// Round(String),
|
||||||
// Square(String),
|
// Square(String),
|
||||||
@@ -12,24 +18,26 @@ pub enum Ast {
|
|||||||
Variable(String, String),
|
Variable(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_token(v: String, t: u32) -> Token {
|
pub fn get_token(v: String, t: u32, state: State) -> Token {
|
||||||
match t {
|
match t {
|
||||||
1 => Token::Number(v),
|
1 => Token::Number(v, state),
|
||||||
2 => Token::Identifier(v),
|
2 => Token::Identifier(v, state),
|
||||||
_ => Token::Number(String::from("")),
|
_ => Token::Number(String::from(""), state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tokenize(code: String) -> Vec<Token> {
|
pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
|
||||||
let mut code = code;
|
let mut code = code;
|
||||||
let mut tokens: Vec<Token> = Vec::new();
|
let mut tokens: Vec<Token> = Vec::new();
|
||||||
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 state = State { line: }
|
||||||
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);
|
||||||
let mut tval: char = c;
|
let mut tval: char = c;
|
||||||
let mut t: u32 = 0;
|
let mut t: u32 = 0;
|
||||||
|
root.state.column += 1;
|
||||||
match c {
|
match c {
|
||||||
'0'..='9' => {
|
'0'..='9' => {
|
||||||
if token_type == 2 {
|
if token_type == 2 {
|
||||||
@@ -42,37 +50,70 @@ pub fn tokenize(code: String) -> Vec<Token> {
|
|||||||
t = 2;
|
t = 2;
|
||||||
}
|
}
|
||||||
'\t' | ' ' => tval = ' ',
|
'\t' | ' ' => tval = ' ',
|
||||||
_ => {}
|
'\n' | '\r' => {
|
||||||
|
tval = '\n';
|
||||||
|
root.state.line += 1;
|
||||||
|
root.state.column = 0;
|
||||||
|
}
|
||||||
|
x => {
|
||||||
|
root.problems.push(Problem {
|
||||||
|
problem_msg: format!(
|
||||||
|
"Invalid character '{}' at {}:{}, LexingError",
|
||||||
|
x, root.state.line, root.state.column
|
||||||
|
),
|
||||||
|
problem_type: ProblemType::SyntaxError,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if t != token_type && token_type != 0 || tval == ' ' {
|
if t != token_type && token_type != 0 || tval == ' ' {
|
||||||
tokens.push(get_token(token_value.clone(), token_type));
|
tokens.push(get_token(
|
||||||
|
token_value.clone(),
|
||||||
|
token_type,
|
||||||
|
root.state.clone(),
|
||||||
|
));
|
||||||
token_type = 0;
|
token_type = 0;
|
||||||
token_value = String::new();
|
token_value = String::new();
|
||||||
}
|
}
|
||||||
if tval != ' ' {
|
if tval != ' ' && tval != '\n' {
|
||||||
token_type = t;
|
token_type = t;
|
||||||
token_value += tval.to_string().as_str();
|
token_value += tval.to_string().as_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if token_type != 0 {
|
if token_type != 0 {
|
||||||
tokens.push(get_token(token_value.clone(), token_type));
|
tokens.push(get_token(
|
||||||
|
token_value.clone(),
|
||||||
|
token_type,
|
||||||
|
root.state.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
tokens
|
tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(code: String, vars: &mut Variables) -> Vec<Ast> {
|
pub fn parse(code: String, vars: &mut Variables, root: &mut Transpiler) -> Vec<Ast> {
|
||||||
let mut ast: Vec<Ast> = Vec::new();
|
let mut ast: Vec<Ast> = Vec::new();
|
||||||
let mut tokens = tokenize(code);
|
let mut tokens = tokenize(code, root);
|
||||||
|
let mut pcon: Vec<(u32, u32)> = Vec::new();
|
||||||
while tokens.len() > 0 {
|
while tokens.len() > 0 {
|
||||||
let mut drain: usize = 0;
|
let mut drain: usize = 1;
|
||||||
match tokens.as_slice() {
|
match tokens.as_slice() {
|
||||||
[Token::Identifier(var_type), Token::Identifier(var_name), ..] => {
|
[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(), var_name.clone()));
|
||||||
drain += 2;
|
drain += 1;
|
||||||
// vars.new_var(var_name, State {}, desc)
|
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
|
||||||
|
),
|
||||||
|
problem_type: ProblemType::SyntaxError,
|
||||||
|
});
|
||||||
|
pcon.push((root.state.line, root.state.column));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
tokens.drain(0..drain);
|
tokens.drain(0..drain);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,7 @@ pub struct Transpiler {
|
|||||||
pub peek: String,
|
pub peek: String,
|
||||||
// pub libmgr: LibManager,
|
// pub libmgr: LibManager,
|
||||||
pub problems: Vec<Problem>,
|
pub problems: Vec<Problem>,
|
||||||
|
pub state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Transpiler {
|
impl Default for Transpiler {
|
||||||
@@ -26,13 +27,14 @@ impl Default for Transpiler {
|
|||||||
peek: String::new(),
|
peek: String::new(),
|
||||||
// libmgr: LibManager::new(".".to_string()),
|
// libmgr: LibManager::new(".".to_string()),
|
||||||
problems: Vec::new(),
|
problems: Vec::new(),
|
||||||
|
state: State { line: 1, column: 0 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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: u32, vars: &mut Variables) -> String {
|
||||||
let ast = parser::parse(code, vars);
|
let ast = parser::parse(code, vars, self);
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
for a in ast {
|
for a in ast {
|
||||||
match a {
|
match a {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ pub enum ProblemType {
|
|||||||
VariableNotFound,
|
VariableNotFound,
|
||||||
FileNotFound,
|
FileNotFound,
|
||||||
HeaderSyntaxError,
|
HeaderSyntaxError,
|
||||||
|
SyntaxError,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
|||||||
Reference in New Issue
Block a user