better state system

This commit is contained in:
2024-07-03 12:07:05 +02:00
parent 3cb1ab90fd
commit 9b755b1821
4 changed files with 61 additions and 45 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ 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() {x int x}".to_string(), 0, &mut vars); let out = trsp.transpile("struct Test {}".to_string(), 0, &mut vars);
for p in trsp.problems { for p in trsp.problems {
match p { match p {
ProblemCap::Error(problem) => { ProblemCap::Error(problem) => {
+49 -29
View File
@@ -10,33 +10,34 @@ use crate::{
#[allow(dead_code)] #[allow(dead_code)]
pub enum Token { pub enum Token {
Number(String, State), Number(String, State),
Keyword(String, State), DKeyword(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 { pub fn extract_values(token: Token) -> (String, State) {
match token { match token {
Token::Number(_, state) => state, Token::Number(x, state) => (x, state),
Token::Identifier(_, state) => state, Token::Identifier(x, state) => (x, state),
Token::Curly(_, state) => state, Token::Curly(x, state) => (x, state),
Token::Round(_, state) => state, Token::Round(x, state) => (x, state),
Token::Keyword(_, state) => state, Token::DKeyword(x, state) => (x, state),
} }
} }
pub enum Ast { pub enum Ast {
Variable(String, String), Variable(String, String),
Function(String, String, String, String), Function(String, String, String, String),
Struct(String, String),
} }
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 => match v.as_str() { 2 => match v.as_str() {
"enum" | "struct" | "namespace" => Token::Keyword(v, state), "enum" | "struct" | "namespace" => Token::DKeyword(v, state),
_ => Token::Identifier(v, state), _ => Token::Identifier(v, state),
}, },
3 => Token::Round(v, state), 3 => Token::Round(v, state),
@@ -45,7 +46,7 @@ pub fn get_token(v: String, t: u32, state: State) -> Token {
} }
} }
pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> { pub fn tokenize(code: String, state: &mut State, 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();
@@ -56,8 +57,9 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
if let Some(c) = code.chars().next() { if let Some(c) = code.chars().next() {
code.remove(0); code.remove(0);
let mut tval = c; let mut tval = c;
let mut t: u32 = token_type; let mut t: u32 = 0;
root.state.column += 1; let mut ignore = false;
state.column += 1;
if stoken.1 > 0 { if stoken.1 > 0 {
match c { match c {
'(' => { '(' => {
@@ -120,11 +122,13 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
'a'..='z' | 'A'..='Z' => { 'a'..='z' | 'A'..='Z' => {
t = 2; t = 2;
} }
'\t' | ' ' => tval = '\n', '\t' | ' ' => {
ignore = true;
}
'\n' | '\r' => { '\n' | '\r' => {
tval = '\n'; ignore = true;
root.state.line += 1; state.line += 1;
root.state.column = 0; state.column = 0;
} }
'(' => { '(' => {
stoken.0 = 1; stoken.0 = 1;
@@ -142,11 +146,12 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
root.problems.push(ProblemCap::Error(Problem { root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!("Invalid character '{}'", x,), problem_msg: format!("Invalid character '{}'", x,),
problem_type: ProblemType::SyntaxError, problem_type: ProblemType::SyntaxError,
state: root.state.clone(), state: state.clone(),
})); }));
ignore = true;
} }
} }
if (t != token_type || tval == '\n') && token_type != 0 { if token_type != t && token_type != 0 {
tokens.push(get_token( tokens.push(get_token(
token_value.clone(), token_value.clone(),
token_type, token_type,
@@ -155,27 +160,30 @@ pub fn tokenize(code: String, root: &mut Transpiler) -> Vec<Token> {
token_type = 0; token_type = 0;
token_value = String::new(); token_value = String::new();
} }
if tval != '\n' { if token_type != t {
token_state = root.state.clone(); token_state = state.clone();
token_type = t; token_type = t;
token_value += tval.to_string().as_str().trim(); token_value += tval.to_string().as_str();
} else if !ignore {
token_value += tval.to_string().as_str();
} }
} }
} }
} }
if token_type != 0 { if token_type != 0 {
tokens.push(get_token( tokens.push(get_token(token_value.clone(), token_type, state.clone()));
token_value.clone(),
token_type,
root.state.clone(),
));
} }
tokens tokens
} }
pub fn parse(code: String, vars: &mut Variables, root: &mut Transpiler) -> Vec<Ast> { pub fn parse(
code: String,
vars: &mut Variables,
state: &mut State,
root: &mut Transpiler,
) -> Vec<Ast> {
let mut ast: Vec<Ast> = Vec::new(); let mut ast: Vec<Ast> = Vec::new();
let mut tokens = tokenize(code, root); let mut tokens = tokenize(code, state, root);
let mut pcon: Vec<(u32, u32)> = Vec::new(); let mut pcon: Vec<(u32, u32)> = Vec::new();
while tokens.len() > 0 { while tokens.len() > 0 {
let mut drain: usize = 1; let mut drain: usize = 1;
@@ -201,12 +209,24 @@ pub fn parse(code: String, vars: &mut Variables, root: &mut Transpiler) -> Vec<A
)); ));
drain += 1; drain += 1;
} }
[Token::DKeyword(keyword, _), Token::Identifier(name, state), Token::Curly(curly, _), ..] =>
{
match keyword.as_str() {
"struct" => ast.push(Ast::Struct(
vars.new_struct(name.clone(), state.clone(), String::from("")),
curly.clone(),
)),
_ => {}
}
drain += 2;
}
x => { x => {
if !pcon.contains(&(root.state.line, root.state.column)) { let estate = extract_values(x[0].clone()).1;
if !pcon.contains(&(estate.line, estate.column)) {
root.problems.push(ProblemCap::Error(Problem { root.problems.push(ProblemCap::Error(Problem {
problem_msg: format!("Invalid placement"), problem_msg: format!("Invalid placement"),
problem_type: ProblemType::SyntaxError, problem_type: ProblemType::SyntaxError,
state: extract_state(x[0].clone()), state: estate,
})); }));
pcon.push((root.state.line, root.state.column)); pcon.push((root.state.line, root.state.column));
} }
+11 -1
View File
@@ -34,7 +34,7 @@ impl Default for Transpiler {
impl Transpiler { impl Transpiler {
pub fn transpile(&mut self, code: String, indent: usize, 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, &mut self.state.clone(), self);
let mut res = String::new(); let mut res = String::new();
if indent > 0 { if indent > 0 {
res += " ".repeat(indent * 2).as_str(); res += " ".repeat(indent * 2).as_str();
@@ -56,6 +56,16 @@ impl Transpiler {
) )
.as_str(); .as_str();
} }
Ast::Struct(name, curly) => {
res += format!(
"struct {} {}\n{}{}\n",
name,
"{",
self.transpile(curly, indent + 1, &mut vars.clone()),
"}"
)
.as_str()
}
} }
} }
if indent > 0 { if indent > 0 {
-14
View File
@@ -147,20 +147,6 @@ impl Variables {
); );
rname rname
} }
pub fn add(&mut self, vtype: VariableType, name: String, state: State, desc: String) {
self.vars.insert(
name,
Variable {
vtype,
desc,
state,
params: Variables {
vars: HashMap::new(),
},
rname: generate_varname(),
},
);
}
pub fn get_var(&mut self, name: String, root: &mut Transpiler, state: State) -> 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();