From e5edc6b2ba0ee8a48270a178114a2b6032006de3 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Fri, 11 Feb 2022 13:00:41 +0100 Subject: [PATCH] Fix UB non top-level functions --- src/parser.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 19b3221..6170408 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -20,6 +20,8 @@ pub enum ParseErr { UseOfUndeclaredFun(String), #[error("Redeclation of function \"{0}\"")] RedeclarationFun(String), + #[error("Function not declared at top level \"{0}\"")] + FunctionOnNonTopLevel(String), } type ResPE = Result; @@ -44,6 +46,7 @@ struct Parser> { string_store: StringStore, var_stack: Vec, fun_stack: Vec, + nesting_level: usize, } impl> Parser { @@ -58,6 +61,7 @@ impl> Parser { string_store, var_stack, fun_stack, + nesting_level: 0, } } @@ -76,6 +80,7 @@ impl> Parser { /// Parse tokens into an abstract syntax tree. This will continuously parse statements until /// encountering end-of-file or a block end '}' . fn parse_scoped_block_fp_offset(&mut self, framepoint_offset: usize) -> ResPE { + self.nesting_level += 1; let framepointer = self.var_stack.len() - framepoint_offset; let mut prog = Vec::new(); @@ -100,6 +105,7 @@ impl> Parser { } self.var_stack.truncate(framepointer); + self.nesting_level -= 1; Ok(prog) } @@ -149,12 +155,17 @@ impl> Parser { T![if] => Statement::If(self.parse_if()?), T![fun] => { + self.next(); let fun_name = match self.next() { T![ident(fun_name)] => fun_name, tok => return Err(ParseErr::UnexpectedToken(tok, "".to_string())), }; + + if self.nesting_level > 1 { + return Err(ParseErr::FunctionOnNonTopLevel(fun_name)); + } let fun_name = self.string_store.intern_or_lookup(&fun_name);