From 2851612e39ec24d7a58e8bf29f99f394a78eec34 Mon Sep 17 00:00:00 2001 From: afonya2 Date: Thu, 24 Apr 2025 23:29:57 +0200 Subject: [PATCH] begin expression handling --- src/main.rs | 12 ++++- src/parser.rs | 137 ++++++++++++++++++++++++++++++++++++++++++-------- test.as | 2 +- 3 files changed, 128 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9d3215d..9ebdb01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod parser; fn log_ast_part(part: &ASTPart, prefix: String) { match part { ASTPart::Number(number) => println!("{}{}: Number: {}", prefix, number.pos, number.value), + ASTPart::String(str) => println!("{}{}: String: {}", prefix, str.pos, str.value), ASTPart::Assigment(assigment) => { println!("{}{}: Assigment: {}", prefix, assigment.pos, assigment.variable); println!("{} Value:", prefix); @@ -21,7 +22,16 @@ fn log_ast_part(part: &ASTPart, prefix: String) { log_ast_part(&operation.right, format!("{} ", prefix)); }, ASTPart::VarRead(var_read) => println!("{}{}: Variable Read: {}", prefix, var_read.pos, var_read.variable), - _ => {} + ASTPart::Call(call) => { + println!("{}{}: Call:", prefix, call.pos); + println!("{} Function:", prefix); + log_ast_part(&call.function, format!("{} ", prefix)); + println!("{} Args:", prefix); + for arg in &call.args { + log_ast_part(&arg, format!("{} ", prefix)); + } + }, + ASTPart::NOOP => println!("{}NOOP", prefix) } } diff --git a/src/parser.rs b/src/parser.rs index 0332a22..51f3358 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,32 +1,49 @@ use crate::lexer::{Token, TokenType}; +#[derive(Debug)] pub enum ASTPart { + String(AstString), Number(AstNumber), Assigment(AstAssigment), Operation(AstOperation), VarRead(AstVarRead), + Call(AstCall), NOOP } +#[derive(Debug)] +pub struct AstString { + pub value: String, + pub pos: usize +} +#[derive(Debug)] pub struct AstNumber { pub value: i64, pub pos: usize } +#[derive(Debug)] pub struct AstAssigment { pub variable: String, pub value: Box, pub pos: usize } +#[derive(Debug)] pub struct AstOperation { pub operator: String, pub left: Box, pub right: Box, pub pos: usize } +#[derive(Debug)] pub struct AstVarRead { pub variable: String, pub pos: usize } - +#[derive(Debug)] +pub struct AstCall { + pub function: Box, + pub args: Vec, + pub pos: usize +} fn is_end(input: &Token, end: &Vec) -> bool { for token in end { @@ -36,41 +53,119 @@ fn is_end(input: &Token, end: &Vec) -> bool { } return false; } -fn next_operation(pos: &mut usize, input: &Vec, prev: ASTPart, op_ends: &Vec, parse_ends: &Vec) -> ASTPart { + +fn read_call(variable: ASTPart, pos: &mut usize, input: &Vec) -> ASTPart { + let mut args: Vec = vec![]; + *pos += 1; + let start_pos = *pos; + while pos < &mut input.len() { + let token = &input[*pos]; + if token.typ == TokenType::SEPARATOR && token.value == "," { + *pos += 1; + continue; + } + if token.typ == TokenType::SEPARATOR && token.value == String::from(")") { + *pos += 1; + break; + } + let ends: Vec = vec![ + Token { typ: TokenType::SEPARATOR, value: String::from(","), pos: 0 }, + Token { typ: TokenType::SEPARATOR, value: String::from(")"), pos: 0 } + ]; + let arg = read_exp(pos, input, &ends, &ends); + args.push(arg); + } + return ASTPart::Call(AstCall { function: Box::new(variable), args: args, pos: start_pos }); +} + +fn shunt(input: Vec) -> ASTPart { + for part in input { + + } + return ASTPart::NOOP; +} +fn read_exp(pos: &mut usize, input: &Vec, ends: &Vec, parse_ends: &Vec) -> ASTPart { + let mut expressions: Vec = vec![]; + while pos < &mut input.len() { + let token = &input[*pos]; + let mut next_token = &Token { + typ: TokenType::OPEND, + value: String::from("END"), + pos: 0 + }; + if *pos+1 < input.len() { + next_token = &input[*pos+1] + } + if is_end(token, &parse_ends) { + break; + } + *pos += 1; + if is_end(token, ends) { + break; + } + if token.typ == TokenType::STRING { + expressions.push(ASTPart::String(AstString { value: token.value.clone(), pos: token.pos })); + } else if token.typ == TokenType::NUMBER { + expressions.push(ASTPart::Number(AstNumber { value: token.value.parse().unwrap(), pos: token.pos })); + } else if token.typ == TokenType::IDENTIFIER { + if next_token.typ == TokenType::SEPARATOR && next_token.value == "(" { + let var = ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }); + expressions.push(read_call(var, pos, input)); + } else { + expressions.push(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos })); + } + } 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 })); + } else { + panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); + } + } + println!("{:?}", expressions); + let shunted = shunt(expressions); + return ASTPart::NOOP; +} + +fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, parse_ends: &Vec) -> ASTPart { let token = &input[*pos]; if is_end(token, &parse_ends) { - return prev; + return ASTPart::NOOP; } *pos += 1; if is_end(token, &op_ends) { - return prev; + return ASTPart::NOOP; } - if token.typ == TokenType::KEYWORD && token.value == "gethelj" { - let variable = &input[*pos]; - *pos += 1; - if variable.typ != TokenType::IDENTIFIER { - panic!("Unexpected {:?} at {}", variable.typ, variable.pos) - } - let eq = &input[*pos]; - if eq.typ == TokenType::SEPARATOR && eq.value == "=" { + if token.typ == TokenType::KEYWORD { + if token.value == "gethelj" { + let variable = &input[*pos]; *pos += 1; + if variable.typ != TokenType::IDENTIFIER { + panic!("Unexpected {:?} at {}", variable.typ, variable.pos) + } + let eq = &input[*pos]; + if eq.typ == TokenType::SEPARATOR && eq.value == "=" { + *pos += 1; + } + let value = read_exp(pos, input, op_ends, parse_ends); + return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos }); + } else { + panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); } - let value = next_operation(pos, input, ASTPart::NOOP, op_ends, parse_ends); - return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos }); - } else if token.typ == TokenType::NUMBER { - return next_operation(pos, input, ASTPart::Number(AstNumber { value: token.value.parse().unwrap(), pos: token.pos }), op_ends, parse_ends); - } else if token.typ == TokenType::IDENTIFIER { - return next_operation(pos, input, ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }), op_ends, parse_ends); } else { - panic!("Unexpected {:?} at {}", token.typ, token.pos); + panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); } } + fn parse_internal(input: Vec, op_ends: Vec, parse_ends: Vec) -> Vec { let mut out: Vec = vec![]; let mut pos = 0; while pos < input.len() { - let op = next_operation(&mut pos, &input, ASTPart::NOOP, &op_ends, &parse_ends); - out.push(op); + let op = next_operation(&mut pos, &input, &op_ends, &parse_ends); + match op { + ASTPart::NOOP => {}, + _ => { + out.push(op); + } + } if is_end(&input[pos], &parse_ends) { break; } diff --git a/test.as b/test.as index 10d1db2..858b213 100644 --- a/test.as +++ b/test.as @@ -1,2 +1,2 @@ gethelj a = 1 -gethelj b = a \ No newline at end of file +gethelj b = a + 2 \ No newline at end of file