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 crate::span::Span;
use enumflags2::BitFlags; use enumflags2::BitFlags;
use parsed_statement::ParsedStatement; use parsed_statement::ParsedStatement;
use std::fs::read;
use std::os::linux::raw::stat;
struct ParseReader<'a> { struct ParseReader<'a> {
tokens: &'a Vec<LexToken>, tokens: &'a Vec<LexToken>,
@ -593,7 +591,9 @@ fn parse_paramlist(
let mut params = Vec::new(); let mut params = Vec::new();
loop { loop {
if reader.peek().token_type == TokenType::CloseBracket { if reader.peek().token_type == TokenType::CloseBracket {
reader.next(); break;
}
if reader.peek().token_type == TokenType::EndOfFile {
break; break;
} }
let param_type = parse_type(reader, log); let param_type = parse_type(reader, log);
@ -608,7 +608,7 @@ fn parse_paramlist(
} }
params.push((param_type.unwrap(), type_mod, identifier, default)); params.push((param_type.unwrap(), type_mod, identifier, default));
} }
reader.consume(TokenType::CloseBracket, log);
Some(Box::new(ParsedStatement::ParamList { parameters: params })) Some(Box::new(ParsedStatement::ParamList { parameters: params }))
} }
@ -645,6 +645,9 @@ fn parse_statblock(
if reader.peek().token_type == TokenType::CloseCurlyBracket { if reader.peek().token_type == TokenType::CloseCurlyBracket {
break; break;
} }
if reader.peek().token_type == TokenType::EndOfFile {
break;
}
let var = parse_var(reader, log); let var = parse_var(reader, log);
if let Some(..) = var { if let Some(..) = var {
children.push(var.unwrap()); children.push(var.unwrap());
@ -763,12 +766,17 @@ fn parse_switch(
if reader.peek().token_type == TokenType::CloseCurlyBracket { if reader.peek().token_type == TokenType::CloseCurlyBracket {
break; break;
} }
if reader.peek().token_type == TokenType::EndOfFile {
break;
}
let case = parse_case(reader, log); let case = parse_case(reader, log);
if case.is_none() { if case.is_none() {
break; break;
} }
vec.push(case.unwrap()); vec.push(case.unwrap());
} }
reader.consume(TokenType::CloseCurlyBracket, log);
Some(Box::new(ParsedStatement::Switch { Some(Box::new(ParsedStatement::Switch {
expression: assign.unwrap(), expression: assign.unwrap(),
cases: vec, cases: vec,
@ -874,6 +882,9 @@ fn parse_for(
if reader.peek().token_type == TokenType::CloseBracket { if reader.peek().token_type == TokenType::CloseBracket {
break; break;
} }
if reader.peek().token_type == TokenType::EndOfFile {
break;
}
let assign = parse_assign(reader, log); let assign = parse_assign(reader, log);
if assign.is_some() { if assign.is_some() {
increment_expressions.push(assign.unwrap()); increment_expressions.push(assign.unwrap());
@ -883,6 +894,7 @@ fn parse_for(
} }
reader.next(); reader.next();
} }
reader.consume(TokenType::CloseBracket, log);
Some(Box::new(ParsedStatement::ForStatement { Some(Box::new(ParsedStatement::ForStatement {
initializer: initializer.unwrap(), initializer: initializer.unwrap(),
bounds: bounds.unwrap(), bounds: bounds.unwrap(),
@ -1367,11 +1379,38 @@ fn parse_funccall(
} }
fn parse_arglist( fn parse_arglist(
_outer_reader: &mut ParseReader, reader: &mut ParseReader,
_log: &mut dyn FnMut(Message, Span), log: &mut dyn FnMut(Message, Span),
) -> Option<Box<ParsedStatement>> { ) -> Option<Box<ParsedStatement>> {
// arglist ::= '(' [identifier ':'] assign {',' [identifier ':'] assign} ')'; // 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( fn parse_exprpreop(

View File

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