added parenthesis

This commit is contained in:
afonya2 2025-05-17 19:52:46 +02:00
parent 3f8d1df4cb
commit 28c440539d
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 46 additions and 16 deletions

View file

@ -1,6 +1,8 @@
use core::panic;
use crate::lexer::{Token, TokenType}; use crate::lexer::{Token, TokenType};
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub enum ASTPart { pub enum ASTPart {
String(AstString), String(AstString),
Number(AstNumber), Number(AstNumber),
@ -10,35 +12,35 @@ pub enum ASTPart {
Call(AstCall), Call(AstCall),
NOOP NOOP
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstString { pub struct AstString {
pub value: String, pub value: String,
pub pos: usize pub pos: usize
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstNumber { pub struct AstNumber {
pub value: i64, pub value: i64,
pub pos: usize pub pos: usize
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstAssigment { pub struct AstAssigment {
pub variable: String, pub variable: String,
pub value: Box<ASTPart>, pub value: Box<ASTPart>,
pub pos: usize pub pos: usize
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstOperation { pub struct AstOperation {
pub operator: String, pub operator: String,
pub left: Box<ASTPart>, pub left: Box<ASTPart>,
pub right: Box<ASTPart>, pub right: Box<ASTPart>,
pub pos: usize pub pos: usize
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstVarRead { pub struct AstVarRead {
pub variable: String, pub variable: String,
pub pos: usize pub pos: usize
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct AstCall { pub struct AstCall {
pub function: Box<ASTPart>, pub function: Box<ASTPart>,
pub args: Vec<ASTPart>, pub args: Vec<ASTPart>,
@ -106,6 +108,10 @@ fn shunt(input: Vec<ASTPart>) -> ASTPart {
output.push(part); output.push(part);
}, },
ASTPart::Operation(op) => { ASTPart::Operation(op) => {
if *op.left != ASTPart::NOOP && *op.right != ASTPart::NOOP {
output.push(part);
break;
}
while stack.len() > 0 { while stack.len() > 0 {
let top = &stack[stack.len()-1]; let top = &stack[stack.len()-1];
match top { match top {
@ -127,24 +133,32 @@ fn shunt(input: Vec<ASTPart>) -> ASTPart {
while stack.len() > 0 { while stack.len() > 0 {
output.push(stack.pop().unwrap()); output.push(stack.pop().unwrap());
} }
for i in 0..output.len() { let mut i = 0;
while i < output.len() {
match &output[i] { match &output[i] {
ASTPart::Operation(op) => { ASTPart::Operation(op) => {
if *op.left != ASTPart::NOOP && *op.right != ASTPart::NOOP {
i += 1;
continue;
}
if i < 2 { if i < 2 {
panic!("Unexpected operation at {}", op.pos); panic!("Unexpected operation at {}", op.pos);
} }
let left = &output[i-2]; let left = output[i-2].clone();
let right = &output[i-1]; let right = output[i-1].clone();
output[i] = ASTPart::Operation(AstOperation { output[i] = ASTPart::Operation(AstOperation {
operator: op.operator.clone(), operator: op.operator.clone(),
left: Box::new(left.clone()), left: Box::new(left),
right: Box::new(right.clone()), right: Box::new(right),
pos: op.pos pos: op.pos,
}); });
output.remove(i-2); output.remove(i-2);
output.remove(i-2); output.remove(i-2);
}, i -= 1;
_ => {} }
_ => {
i += 1;
}
} }
} }
return output[0].clone(); return output[0].clone();
@ -181,6 +195,22 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
} }
} else if token.typ == TokenType::OPERATOR { } else if token.typ == TokenType::OPERATOR {
expressions.push(ASTPart::Operation(AstOperation { operator: token.value.clone(), left: Box::new(ASTPart::NOOP), right: Box::new(ASTPart::NOOP), pos: token.pos })); expressions.push(ASTPart::Operation(AstOperation { operator: token.value.clone(), left: Box::new(ASTPart::NOOP), right: Box::new(ASTPart::NOOP), pos: token.pos }));
} else if token.typ == TokenType::SEPARATOR {
//We check for () and then send the into read_exp again, so we recursively parse the expression
if token.value == "(" {
let ends: Vec<Token> = vec![
Token { typ: TokenType::SEPARATOR, value: String::from(")"), pos: 0 }
];
let exp = read_exp(pos, input, &ends, &ends);
if input[*pos].typ == TokenType::SEPARATOR && input[*pos].value == ")" {
*pos += 1;
} else {
panic!("Unclosed parenthesis at {}", token.pos);
}
expressions.push(exp);
} else {
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
}
} else { } else {
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
} }

View file

@ -1,3 +1,3 @@
gethelj a = 1 gethelj a = 1
gethelj b = a + (2+2) gethelj b = a + 2
gethelj c = ugass(a,b) gethelj c = ugass(a,b)