From efaca55138bfb613996bdd737d3a9cdde4b2e527 Mon Sep 17 00:00:00 2001 From: afonya2 Date: Sat, 24 May 2025 16:09:48 +0200 Subject: [PATCH] added for, continue --- src/lexer.rs | 4 ++-- src/main.rs | 14 +++++++++++++ src/parser.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 00f6281..5979a42 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -28,7 +28,7 @@ fn is_number(char: &str) -> bool { return chars.contains(&char); } fn is_operator(char: &str) -> bool { - let chars = vec!["+","-","*","/","^","%","|","&","!"]; + let chars = vec!["+","-","*","/","^","%","|","&","!","<",">"]; return chars.contains(&char); } fn is_mul_operator(char: &str, next_char: &str) -> bool { @@ -100,7 +100,7 @@ fn generate_combinations(words: Vec<&str>) -> Vec { return result; } fn read_identifier(splitted: &Vec<&str>, pos: &mut usize, out: &mut Vec) { - let keywords = vec!["kraf","piszolj","ha nem geny akkor geny","ha nem geny","nem piszv","kopva","gethelj","ha geny","jukadban","lőcsve","nem reti","csecs","megint","reti","piszv","amíg geny","nincs hám"]; + let keywords = vec!["kraf","piszolj","ha nem geny akkor geny","ha nem geny","nem piszv","kopva","gethelj","ha geny","jukadban","lőcsve","nem reti","csecs","megint","reti","piszv","amíg geny","nincs hám","szard le"]; let mut raw_keywords: Vec = vec![]; for keyword in &keywords { let spi: Vec<&str> = keyword.split(" ").collect(); diff --git a/src/main.rs b/src/main.rs index 1703445..9dc6ffd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,6 +65,20 @@ fn log_ast_part(part: &ASTPart, prefix: String) { } }, ASTPart::Break(brk) => println!("{}{}: Break", prefix, brk.pos), + ASTPart::For(fr) => { + println!("{}{}: For:", prefix, fr.pos); + println!("{} Init:", prefix); + log_ast_part(&fr.init, format!("{} ", prefix)); + println!("{} Condition:", prefix); + log_ast_part(&fr.condition, format!("{} ", prefix)); + println!("{} Update:", prefix); + log_ast_part(&fr.update, format!("{} ", prefix)); + println!("{} Body:", prefix); + for part in &fr.body { + log_ast_part(part, format!("{} ", prefix)); + } + }, + ASTPart::Continue(cnt) => println!("{}{}: Continue", prefix, cnt.pos), ASTPart::NOOP => println!("{}NOOP", prefix) } } diff --git a/src/parser.rs b/src/parser.rs index 052563f..5cb76e4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -17,6 +17,8 @@ pub enum ASTPart { If(AstIf), While(AstWhile), Break(AstBreak), + For(AstFor), + Continue(AstContinue), NOOP } #[derive(Debug, Clone, PartialEq)] @@ -90,6 +92,18 @@ pub struct AstWhile { pub struct AstBreak { pub pos: usize } +#[derive(Debug, Clone, PartialEq)] +pub struct AstFor { + pub init: Box, + pub condition: Box, + pub update: Box, + pub body: Vec, + pub pos: usize +} +#[derive(Debug, Clone, PartialEq)] +pub struct AstContinue { + pub pos: usize +} fn is_end(input: &Token, end: &Vec) -> bool { for token in end { @@ -257,7 +271,7 @@ fn read_function(input: &Vec, pos: &mut usize, with_args: bool) -> ASTPar let parse_ends: Vec = vec![ Token { typ: TokenType::SEPARATOR, value: String::from("}"), pos: 0 } ]; - let body = parse_internal(input, op_ends, parse_ends, pos); + let body = parse_internal(input, &op_ends, &parse_ends, pos); if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "}" { panic!("Unexpected end of function at {}", input[*pos].pos); } @@ -403,6 +417,44 @@ fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, par return ASTPart::While(AstWhile { condition: Box::new(condition), body: real_body, pos: token.pos }); } else if token.value == "kraf" { return ASTPart::Break(AstBreak { pos: token.pos }); + } else if token.value == "kopva" { + if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" { + panic!("Expected ( at {}", token.pos); + } + *pos += 1; + let ends = vec![ + Token { typ: TokenType::SEPARATOR, value: String::from(")"), pos: 0 }, + Token { typ: TokenType::OPEND, value: String::from(";"), pos: 0 } + ]; + let init = parse_internal(input, &ends, &ends, pos); + if init.len() != 1 { + panic!("Only one expression is expected for init at {}", token.pos); + } + if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" { + panic!("Unexpected end of init at {}", token.pos); + } + *pos += 1; + let condition = read_exp(pos, input, &ends, &ends); + if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" { + panic!("Unexpected end of condition at {}", token.pos); + } + *pos += 1; + let update = parse_internal(input, &ends, &ends, pos); + if update.len() != 1 { + panic!("Only one expression is expected for update at {}", token.pos); + } + if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { + panic!("Unexpected end of update at {}", token.pos); + } + *pos += 1; + let body = read_function(input, pos, false); + let real_body = match body { + ASTPart::Function(func) => func.body, + _ => panic!("Expected function body at {}", token.pos) + }; + return ASTPart::For(AstFor { init: Box::new(init[0].clone()), condition: Box::new(condition), update: Box::new(update[0].clone()), body: real_body, pos: token.pos }); + } else if token.value == "szard le" { + return ASTPart::Continue(AstContinue { pos: token.pos }); } else { panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos); } @@ -422,7 +474,7 @@ fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, par } } -fn parse_internal(input: &Vec, op_ends: Vec, parse_ends: Vec, pos: &mut usize) -> Vec { +fn parse_internal(input: &Vec, op_ends: &Vec, parse_ends: &Vec, pos: &mut usize) -> Vec { let mut out: Vec = vec![]; while *pos < input.len() { let op = next_operation(pos, &input, &op_ends, &parse_ends); @@ -447,6 +499,6 @@ pub fn parse(input: Vec) -> Vec { let parse_ends: Vec = vec![ Token { typ: TokenType::OPEND, value: String::from("EOF"), pos: 0 } ]; - let out = parse_internal(&input, op_ends, parse_ends, &mut 0); + let out = parse_internal(&input, &op_ends, &parse_ends, &mut 0); return out; } \ No newline at end of file