added operatiom parsing
This commit is contained in:
parent
2851612e39
commit
3f8d1df4cb
2 changed files with 80 additions and 15 deletions
|
@ -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 {
|
||||||
|
|
3
test.as
3
test.as
|
@ -1,2 +1,3 @@
|
||||||
gethelj a = 1
|
gethelj a = 1
|
||||||
gethelj b = a + 2
|
gethelj b = a + (2+2)
|
||||||
|
gethelj c = ugass(a,b)
|
Loading…
Add table
Add a link
Reference in a new issue