Parses arglist, fixes several potential infinite loops

This commit is contained in:
Deukhoofd 2022-04-04 19:38:58 +02:00
parent f004c19133
commit 7d0a2d461a
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
2 changed files with 49 additions and 7 deletions

View File

@ -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<LexToken>,
@ -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<Box<ParsedStatement>> {
// 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(

View File

@ -195,4 +195,7 @@ pub enum ParsedStatement {
func_attr: BitFlags<FuncAttr>,
source: String,
},
ArgList {
args: Vec<(Option<String>, Box<ParsedStatement>)>,
},
}