added operatiom parsing

This commit is contained in:
afonya2 2025-05-17 19:39:51 +02:00
parent 2851612e39
commit 3f8d1df4cb
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 80 additions and 15 deletions

View file

@ -1,6 +1,6 @@
use crate::lexer::{Token, TokenType}; use crate::lexer::{Token, TokenType};
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum ASTPart { pub enum ASTPart {
String(AstString), String(AstString),
Number(AstNumber), Number(AstNumber),
@ -10,35 +10,35 @@ pub enum ASTPart {
Call(AstCall), Call(AstCall),
NOOP NOOP
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct AstString { pub struct AstString {
pub value: String, pub value: String,
pub pos: usize pub pos: usize
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct AstNumber { pub struct AstNumber {
pub value: i64, pub value: i64,
pub pos: usize pub pos: usize
} }
#[derive(Debug)] #[derive(Debug, Clone)]
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)] #[derive(Debug, Clone)]
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)] #[derive(Debug, Clone)]
pub struct AstVarRead { pub struct AstVarRead {
pub variable: String, pub variable: String,
pub pos: usize pub pos: usize
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct AstCall { pub struct AstCall {
pub function: Box<ASTPart>, pub function: Box<ASTPart>,
pub args: Vec<ASTPart>, pub args: Vec<ASTPart>,
@ -57,7 +57,7 @@ fn is_end(input: &Token, end: &Vec<Token>) -> bool {
fn read_call(variable: ASTPart, pos: &mut usize, input: &Vec<Token>) -> ASTPart { fn read_call(variable: ASTPart, pos: &mut usize, input: &Vec<Token>) -> ASTPart {
let mut args: Vec<ASTPart> = vec![]; let mut args: Vec<ASTPart> = vec![];
*pos += 1; *pos += 1;
let start_pos = *pos; let start_pos = input[*pos-1].pos;
while pos < &mut input.len() { while pos < &mut input.len() {
let token = &input[*pos]; let token = &input[*pos];
if token.typ == TokenType::SEPARATOR && token.value == "," { if token.typ == TokenType::SEPARATOR && token.value == "," {
@ -78,11 +78,76 @@ fn read_call(variable: ASTPart, pos: &mut usize, input: &Vec<Token>) -> ASTPart
return ASTPart::Call(AstCall { function: Box::new(variable), args: args, pos: start_pos }); return ASTPart::Call(AstCall { function: Box::new(variable), args: args, pos: start_pos });
} }
fn shunt(input: Vec<ASTPart>) -> ASTPart { fn operator_precedence(op: &str) -> i64 {
for part in input { match op {
"|" | "&" => 1,
"+" | "-" => 2,
"*" | "/" | "%" => 3,
"^" => 4,
_ => 0
} }
return ASTPart::NOOP; }
fn shunt(input: Vec<ASTPart>) -> ASTPart {
let mut output: Vec<ASTPart> = vec![];
let mut stack: Vec<ASTPart> = vec![];
for part in input {
match &part {
ASTPart::String(_) => {
output.push(part);
},
ASTPart::Number(_) => {
output.push(part);
},
ASTPart::Call(_) => {
stack.push(part);
},
ASTPart::VarRead(_) => {
output.push(part);
},
ASTPart::Operation(op) => {
while stack.len() > 0 {
let top = &stack[stack.len()-1];
match top {
ASTPart::Operation(top_op) => {
if operator_precedence(&top_op.operator) >= operator_precedence(&op.operator) {
output.push(stack.pop().unwrap());
} else {
break;
}
},
_ => break
}
}
stack.push(part);
},
_ => {}
}
}
while stack.len() > 0 {
output.push(stack.pop().unwrap());
}
for i in 0..output.len() {
match &output[i] {
ASTPart::Operation(op) => {
if i < 2 {
panic!("Unexpected operation at {}", op.pos);
}
let left = &output[i-2];
let right = &output[i-1];
output[i] = ASTPart::Operation(AstOperation {
operator: op.operator.clone(),
left: Box::new(left.clone()),
right: Box::new(right.clone()),
pos: op.pos
});
output.remove(i-2);
output.remove(i-2);
},
_ => {}
}
}
return output[0].clone();
} }
fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart { fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {
let mut expressions: Vec<ASTPart> = vec![]; let mut expressions: Vec<ASTPart> = vec![];
@ -120,9 +185,8 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
} }
} }
println!("{:?}", expressions);
let shunted = shunt(expressions); let shunted = shunt(expressions);
return ASTPart::NOOP; return shunted;
} }
fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart { fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {

View file

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