From 7d0a2d461a9e58cb8947daefed78eec87fa4010a Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Mon, 4 Apr 2022 19:38:58 +0200 Subject: [PATCH] Parses arglist, fixes several potential infinite loops --- src/parsing/parser/mod.rs | 53 ++++++++++++++++++++++---- src/parsing/parser/parsed_statement.rs | 3 ++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/parsing/parser/mod.rs b/src/parsing/parser/mod.rs index 20e35e1..bbe93c3 100644 --- a/src/parsing/parser/mod.rs +++ b/src/parsing/parser/mod.rs @@ -22,8 +22,6 @@ use crate::prim_type::PrimitiveType; use crate::span::Span; use enumflags2::BitFlags; use parsed_statement::ParsedStatement; -use std::fs::read; -use std::os::linux::raw::stat; struct ParseReader<'a> { tokens: &'a Vec, @@ -593,7 +591,9 @@ fn parse_paramlist( let mut params = Vec::new(); loop { if reader.peek().token_type == TokenType::CloseBracket { - reader.next(); + break; + } + if reader.peek().token_type == TokenType::EndOfFile { break; } let param_type = parse_type(reader, log); @@ -608,7 +608,7 @@ fn parse_paramlist( } params.push((param_type.unwrap(), type_mod, identifier, default)); } - + reader.consume(TokenType::CloseBracket, log); Some(Box::new(ParsedStatement::ParamList { parameters: params })) } @@ -645,6 +645,9 @@ fn parse_statblock( if reader.peek().token_type == TokenType::CloseCurlyBracket { break; } + if reader.peek().token_type == TokenType::EndOfFile { + break; + } let var = parse_var(reader, log); if let Some(..) = var { children.push(var.unwrap()); @@ -763,12 +766,17 @@ fn parse_switch( if reader.peek().token_type == TokenType::CloseCurlyBracket { break; } + if reader.peek().token_type == TokenType::EndOfFile { + break; + } + let case = parse_case(reader, log); if case.is_none() { break; } vec.push(case.unwrap()); } + reader.consume(TokenType::CloseCurlyBracket, log); Some(Box::new(ParsedStatement::Switch { expression: assign.unwrap(), cases: vec, @@ -874,6 +882,9 @@ fn parse_for( if reader.peek().token_type == TokenType::CloseBracket { break; } + if reader.peek().token_type == TokenType::EndOfFile { + break; + } let assign = parse_assign(reader, log); if assign.is_some() { increment_expressions.push(assign.unwrap()); @@ -883,6 +894,7 @@ fn parse_for( } reader.next(); } + reader.consume(TokenType::CloseBracket, log); Some(Box::new(ParsedStatement::ForStatement { initializer: initializer.unwrap(), bounds: bounds.unwrap(), @@ -1367,11 +1379,38 @@ fn parse_funccall( } fn parse_arglist( - _outer_reader: &mut ParseReader, - _log: &mut dyn FnMut(Message, Span), + reader: &mut ParseReader, + log: &mut dyn FnMut(Message, Span), ) -> Option> { // arglist ::= '(' [identifier ':'] assign {',' [identifier ':'] assign} ')'; - unimplemented!(); + if reader.peek().token_type != TokenType::OpenBracket { + return None; + } + reader.next(); + let mut args = Vec::new(); + loop { + if reader.peek().token_type == TokenType::CloseBracket + || reader.peek().token_type == TokenType::EndOfFile + { + break; + } + let mut inner_reader = reader.create_inner(); + let identifier = parse_identifier(&mut inner_reader, log, true); + if inner_reader.peek().token_type == TokenType::Colon { + // identifier: ... + inner_reader.next(); + reader.set_from_inner(&inner_reader); + } + let mut expression = parse_assign(reader, log); + if expression.is_none() { + // FIXME: logging + expression = Some(Box::new(ParsedStatement::Invalid {})); + } + args.push((identifier, expression.unwrap())); + } + reader.consume(TokenType::CloseBracket, log); + + Some(Box::new(ParsedStatement::ArgList { args })) } fn parse_exprpreop( diff --git a/src/parsing/parser/parsed_statement.rs b/src/parsing/parser/parsed_statement.rs index ed76ae8..5837f68 100644 --- a/src/parsing/parser/parsed_statement.rs +++ b/src/parsing/parser/parsed_statement.rs @@ -195,4 +195,7 @@ pub enum ParsedStatement { func_attr: BitFlags, source: String, }, + ArgList { + args: Vec<(Option, Box)>, + }, }