better variable manager
This commit is contained in:
+6
-5
@@ -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");
|
||||
}
|
||||
|
||||
+48
-12
@@ -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<String> {
|
||||
let mut vstr: Vec<String> = 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<Token> {
|
||||
let mut code = code;
|
||||
code += " ";
|
||||
let mut tokens: Vec<Token> = 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<T
|
||||
let mut t: u32 = 0;
|
||||
let mut ignore = false;
|
||||
state.column += 1;
|
||||
if root.inject.inject
|
||||
&& root.inject.state.line == state.line
|
||||
&& root.inject.state.column == state.column
|
||||
{
|
||||
token_value += "list_vx";
|
||||
}
|
||||
if stoken.1 > 0 {
|
||||
match c {
|
||||
'(' => {
|
||||
@@ -184,9 +214,14 @@ pub fn parse(
|
||||
) -> Vec<Ast> {
|
||||
let mut ast: Vec<Ast> = 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);
|
||||
|
||||
+33
-7
@@ -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<ProblemCap>,
|
||||
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 {
|
||||
|
||||
+186
-2
@@ -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<String, Variable>,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
-191
@@ -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<String, Variable>,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user