better state system
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user