diff --git a/src/main.rs b/src/main.rs index 8cf7575..0e17b5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,16 @@ -use utils::ProblemCap; -use variable::Variables; +use utils::{ProblemCap, Variables}; mod parser; mod transpiler; mod utils; -mod variable; fn main() { let mut vars = Variables::new(); let mut trsp = transpiler::Transpiler::default(); - let out = trsp.transpile("struct Test {}".to_string(), 0, &mut vars); + trsp.inject.inject = true; + trsp.inject.state.line = 2; + trsp.inject.state.column = 2; + let out = trsp.transpile("int x\nx".to_string(), 0, &mut vars); for p in trsp.problems { match p { ProblemCap::Error(problem) => { @@ -23,5 +24,5 @@ fn main() { } } } - println!("{out}\n\n\n{:?}", vars); + println!("{out}\n\n\n"); } diff --git a/src/parser.rs b/src/parser.rs index e1d2644..d9261fb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2,8 +2,7 @@ use std::usize; use crate::{ transpiler::{State, Transpiler}, - utils::{Problem, ProblemCap, ProblemType}, - variable::Variables, + utils::{Problem, ProblemCap, ProblemType, Variables}, }; #[derive(Clone, Debug)] @@ -27,10 +26,34 @@ pub fn extract_values(token: Token) -> (String, State) { } } +pub fn extract_ast(ast: Ast) -> Vec { + let mut vstr: Vec = Vec::new(); + match ast { + Ast::Struct(a, _) => { + vstr.push(a); + } + Ast::Single(a) => match a { + Token::Identifier(b, _) => vstr.push(b), + _ => {} + }, + Ast::Variable(a, b) => { + vstr.push(a); + vstr.push(b); + } + Ast::Function(a, b, _, _) => { + vstr.push(a); + vstr.push(b); + } + } + vstr +} + +#[derive(Clone, Debug)] pub enum Ast { Variable(String, String), Function(String, String, String, String), Struct(String, String), + Single(Token), } pub fn get_token(v: String, t: u32, state: State) -> Token { @@ -48,6 +71,7 @@ pub fn get_token(v: String, t: u32, state: State) -> Token { pub fn tokenize(code: String, state: &mut State, root: &mut Transpiler) -> Vec { let mut code = code; + code += " "; let mut tokens: Vec = Vec::new(); let mut token_value: String = String::new(); let mut token_type: u32 = 0; @@ -60,6 +84,12 @@ pub fn tokenize(code: String, state: &mut State, root: &mut Transpiler) -> Vec 0 { match c { '(' => { @@ -184,9 +214,14 @@ pub fn parse( ) -> Vec { let mut ast: Vec = Vec::new(); let mut tokens = tokenize(code, state, root); - let mut pcon: Vec<(u32, u32)> = Vec::new(); while tokens.len() > 0 { let mut drain: usize = 1; + let vals = extract_values(tokens[0].clone()); + if vals.0.contains("list_vx") { + ast.push(Ast::Single(Token::Identifier(vals.0, vals.1))); + tokens.drain(0..1); + continue; + } match tokens.as_slice() { [Token::Identifier(var_type, state0), Token::Identifier(var_name, _state1), Token::Round(round, _state2), Token::Curly(curly, _state3), ..] => { @@ -221,15 +256,16 @@ pub fn parse( drain += 2; } x => { - let estate = extract_values(x[0].clone()).1; - if !pcon.contains(&(estate.line, estate.column)) { - root.problems.push(ProblemCap::Error(Problem { - problem_msg: format!("Invalid placement"), - problem_type: ProblemType::SyntaxError, - state: estate, - })); - pcon.push((root.state.line, root.state.column)); - } + ast.push(Ast::Single(x[0].clone())); + //let estate = extract_values(x[0].clone()).1; + //if !pcon.contains(&(estate.line, estate.column)) { + // root.problems.push(ProblemCap::Error(Problem { + // problem_msg: format!("Invalid placement"), + // problem_type: ProblemType::SyntaxError, + // state: estate, + // })); + // pcon.push((root.state.line, root.state.column)); + //} } } tokens.drain(0..drain); diff --git a/src/transpiler.rs b/src/transpiler.rs index bdce0f4..390c0bd 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,7 +1,6 @@ use crate::{ - parser::{self, Ast}, - utils::ProblemCap, - variable::Variables, + parser::{self, extract_ast, Ast}, + utils::{ProblemCap, VariableType, Variables}, }; use serde::{Deserialize, Serialize}; @@ -14,18 +13,30 @@ pub struct State { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Transpiler { pub matched_vars: Variables, - pub peek: String, - // pub libmgr: LibManager, pub problems: Vec, pub state: State, + pub inject: Inject, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Inject { + pub state: State, + pub inject: bool, +} + +impl Default for Inject { + fn default() -> Self { + Inject { + inject: false, + state: State { line: 0, column: 0 }, + } + } } impl Default for Transpiler { fn default() -> Self { Transpiler { matched_vars: Variables::new(), - peek: String::new(), - // libmgr: LibManager::new(".".to_string()), + inject: Inject::default(), problems: Vec::new(), state: State { line: 1, column: 0 }, } @@ -40,6 +51,20 @@ impl Transpiler { res += " ".repeat(indent * 2).as_str(); } for a in ast { + let astval = extract_ast(a.clone()); + if self.inject.inject { + for val in astval { + if val.contains("list_vx") { + for (name, var) in vars.clone().iter_mut() { + if self.inject.state.line > var.state.line + || var.vtype != VariableType::Var + { + self.matched_vars.vars.insert(name.clone(), var.clone()); + } + } + } + } + } match a { Ast::Variable(var_type, var_name) => { res += format!("let mut {}: {}", var_name, var_type).as_str(); @@ -66,6 +91,7 @@ impl Transpiler { ) .as_str() } + Ast::Single(_) => {} } } if indent > 0 { diff --git a/src/utils.rs b/src/utils.rs index d5bed48..28526f6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,8 @@ -use serde::{Deserialize, Serialize}; - use crate::transpiler::State; +use crate::transpiler::Transpiler; +use rand::Rng; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; #[derive(Clone, Debug, Serialize, Deserialize)] pub enum ProblemType { @@ -22,3 +24,185 @@ pub struct Problem { pub problem_msg: String, pub state: State, } + +#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] +pub enum VariableType { + Var, + Func, + Keyword, + Struct, + Namespace, + Enum, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Variable { + pub vtype: VariableType, + pub desc: String, + pub state: State, + pub params: Variables, + pub rname: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Variables { + pub vars: HashMap, +} + +impl Variables { + pub fn new() -> Variables { + Variables { + vars: HashMap::from([( + "void".to_string(), + Variable { + vtype: VariableType::Keyword, + desc: "".to_string(), + state: State { line: 0, column: 0 }, + params: Variables { + vars: HashMap::new(), + }, + rname: "".to_string(), + }, + )]), + } + } + pub fn new_var(&mut self, name: String, state: State, desc: String) -> String { + let rname = generate_varname(); + self.vars.insert( + name, + Variable { + vtype: VariableType::Var, + desc, + state, + params: Variables { + vars: HashMap::new(), + }, + rname: rname.clone(), + }, + ); + rname + } + + pub fn new_namespace(&mut self, name: String, state: State, desc: String) -> String { + let rname = generate_varname(); + self.vars.insert( + name, + Variable { + vtype: VariableType::Namespace, + desc, + state, + params: Variables { + vars: HashMap::new(), + }, + rname: rname.clone(), + }, + ); + rname + } + + pub fn new_struct(&mut self, name: String, state: State, desc: String) -> String { + let rname = generate_varname(); + self.vars.insert( + name, + Variable { + vtype: VariableType::Struct, + desc, + state, + params: Variables { + vars: HashMap::new(), + }, + rname: rname.clone(), + }, + ); + rname + } + pub fn new_enum(&mut self, name: String, state: State, desc: String) -> String { + let rname = generate_varname(); + self.vars.insert( + name, + Variable { + vtype: VariableType::Enum, + desc, + state, + params: Variables { + vars: HashMap::new(), + }, + rname: rname.clone(), + }, + ); + rname + } + + // pub fn new_keyword(&mut self, name: String, state: State, desc: String) { + // self.vars.insert( + // name, + // Variable { + // vtype: VariableType::Keyword, + // desc, + // state, + // params: Variables { + // vars: HashMap::new(), + // }, + // rname: generate_varname(), + // }, + // ); + // } + + pub fn new_func(&mut self, name: String, state: State, desc: String) -> String { + let rname = generate_varname(); + self.vars.insert( + name, + Variable { + vtype: VariableType::Func, + desc, + state, + params: Variables { + vars: HashMap::new(), + }, + rname: rname.clone(), + }, + ); + rname + } + 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(ProblemCap::Error(Problem { + problem_type: ProblemType::VariableNotFound, + problem_msg: format!("Variable '{}' doesn't exist", &name), + state: state, + })); + return name; + } + } + pub fn iter_mut( + &mut self, + ) -> std::collections::hash_map::IterMut<'_, std::string::String, Variable> { + self.vars.iter_mut() + } + pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> { + self.vars.get_mut(&name) + } + pub fn expand(&mut self, vars: Variables) { + for (x, y) in vars.vars { + self.vars.insert(x, y); + } + } +} + +pub fn generate_varname() -> String { + let mut rng = rand::thread_rng(); + let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ + abcdefghijklmnopqrstuvwxyz\ + 0123456789"; + let mut result = String::with_capacity(19); + result.push('_'); + result.push('0'); + result.push('x'); + for _ in 0..14 { + let random_char = charset[rng.gen_range(0..charset.len())] as char; + result.push(random_char); + } + result +} diff --git a/src/variable.rs b/src/variable.rs deleted file mode 100644 index 75c1bfb..0000000 --- a/src/variable.rs +++ /dev/null @@ -1,191 +0,0 @@ -use std::collections::HashMap; - -use rand::Rng; -use serde::{Deserialize, Serialize}; - -use crate::{ - transpiler::{State, Transpiler}, - utils::{Problem, ProblemCap, ProblemType}, -}; - -#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum VariableType { - Var, - Func, - Keyword, - Struct, - Namespace, - Enum, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Variable { - pub vtype: VariableType, - pub desc: String, - pub state: State, - pub params: Variables, - pub rname: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Variables { - pub vars: HashMap, -} - -impl Variables { - pub fn new() -> Variables { - Variables { - vars: HashMap::from([( - "void".to_string(), - Variable { - vtype: VariableType::Keyword, - desc: "".to_string(), - state: State { line: 0, column: 0 }, - params: Variables { - vars: HashMap::new(), - }, - rname: "".to_string(), - }, - )]), - } - } - pub fn new_var(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Var, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - pub fn new_namespace(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Namespace, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - pub fn new_struct(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Struct, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - pub fn new_enum(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Enum, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - // pub fn new_keyword(&mut self, name: String, state: State, desc: String) { - // self.vars.insert( - // name, - // Variable { - // vtype: VariableType::Keyword, - // desc, - // state, - // params: Variables { - // vars: HashMap::new(), - // }, - // rname: generate_varname(), - // }, - // ); - // } - - pub fn new_func(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Func, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - 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(ProblemCap::Error(Problem { - problem_type: ProblemType::VariableNotFound, - problem_msg: format!("Variable '{}' doesn't exist", &name), - state: state, - })); - return name; - } - } - pub fn iter_mut( - &mut self, - ) -> std::collections::hash_map::IterMut<'_, std::string::String, Variable> { - self.vars.iter_mut() - } - pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> { - self.vars.get_mut(&name) - } - pub fn expand(&mut self, vars: Variables) { - for (x, y) in vars.vars { - self.vars.insert(x, y); - } - } -} - -pub fn generate_varname() -> String { - let mut rng = rand::thread_rng(); - let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789"; - let mut result = String::with_capacity(19); - result.push('_'); - result.push('0'); - result.push('x'); - for _ in 0..14 { - let random_char = charset[rng.gen_range(0..charset.len())] as char; - result.push(random_char); - } - result -}