diff --git a/src/parsing/parser/mod.rs b/src/parsing/parser/mod.rs index bbe93c3..0deb6e9 100644 --- a/src/parsing/parser/mod.rs +++ b/src/parsing/parser/mod.rs @@ -427,11 +427,83 @@ fn parse_import( } fn parse_enum( - _outer_reader: &mut ParseReader, - _log: &mut dyn FnMut(Message, Span), + reader: &mut ParseReader, + log: &mut dyn FnMut(Message, Span), ) -> Option> { // enum ::= {'shared' | 'external'} 'enum' identifier [ ':' primtype ] (';' | ('{' identifier ['=' expr] {',' identifier ['=' expr]} '}')); - unimplemented!(); + let mut inner_reader = reader.create_inner(); + let mut modifiers: BitFlags = BitFlags::empty(); + loop { + match inner_reader.peek().token_type { + TokenType::SharedKeyword => { + inner_reader.next(); + modifiers |= TypeModifier::Shared; + } + TokenType::ExternalKeyword => { + inner_reader.next(); + modifiers |= TypeModifier::External; + } + TokenType::EnumKeyword => { + break; + } + + _ => { + return None; + } + } + } + inner_reader.consume(TokenType::EnumKeyword, log); + reader.set_from_inner(&inner_reader); + let name = parse_identifier(reader, log, false); + if name.is_none() { + return Some(Box::new(ParsedStatement::Invalid)); + } + let mut base_type = None; + if reader.peek().token_type == TokenType::Colon { + reader.next(); + let prim_type = parse_primtype(reader, log); + if prim_type.is_none() { + // FIXME: make clearer + log( + UnexpectedToken { + found: reader.peek().token_type.clone(), + expected: vec![], + }, + reader.peek().span, + ); + return Some(Box::new(ParsedStatement::Invalid)); + } + base_type = prim_type; + } + + let mut values = Vec::new(); + + if reader.peek().token_type == TokenType::OpenCurlyBracket { + reader.next(); + loop { + if reader.peek().token_type == TokenType::CloseCurlyBracket + || reader.peek().token_type == TokenType::EndOfFile + { + break; + } + let identifier = parse_identifier(reader, log, false); + let mut value = None; + if reader.peek().token_type == TokenType::Equals { + reader.next(); + value = parse_assign(reader, log); + // FIXME: Add error log if value is None + } + values.push((identifier.unwrap(), value)); + } + reader.consume(TokenType::CloseCurlyBracket, log); + } + + Some(Box::new(ParsedStatement::EnumDeclaration { + modifiers: modifiers, + identifier: name.unwrap(), + base_type, + values, + })) } fn parse_class( diff --git a/src/parsing/parser/parsed_statement.rs b/src/parsing/parser/parsed_statement.rs index 5837f68..83e2322 100644 --- a/src/parsing/parser/parsed_statement.rs +++ b/src/parsing/parser/parsed_statement.rs @@ -198,4 +198,10 @@ pub enum ParsedStatement { ArgList { args: Vec<(Option, Box)>, }, + EnumDeclaration { + modifiers: BitFlags, + identifier: String, + base_type: Option>, + values: Vec<(String, Option>)>, + }, }