diff options
Diffstat (limited to 'ptx_parser/src/lib.rs')
-rw-r--r-- | ptx_parser/src/lib.rs | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/ptx_parser/src/lib.rs b/ptx_parser/src/lib.rs index b81d826..ed2cf2a 100644 --- a/ptx_parser/src/lib.rs +++ b/ptx_parser/src/lib.rs @@ -3,6 +3,7 @@ use logos::Logos; use ptx_parser_macros::derive_parser; use rustc_hash::FxHashMap; use std::fmt::Debug; +use std::iter; use std::num::{NonZeroU8, ParseFloatError, ParseIntError}; use winnow::ascii::dec_uint; use winnow::combinator::*; @@ -397,14 +398,13 @@ fn directive<'a, 'input>( fn module_variable<'a, 'input>( stream: &mut PtxParser<'a, 'input>, ) -> PResult<(ast::LinkingDirective, ast::Variable<&'input str>)> { - ( - linking_directives, - global_space - .flat_map(multi_variable) - // TODO: support multi var in globals - .map(|multi_var| multi_var.var), - ) - .parse_next(stream) + let linking = linking_directives.parse_next(stream)?; + let var = global_space + .flat_map(|space| multi_variable(linking.contains(LinkingDirective::EXTERN), space)) + // TODO: support multi var in globals + .map(|multi_var| multi_var.var) + .parse_next(stream)?; + Ok((linking, var)) } fn file<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> { @@ -621,7 +621,7 @@ fn statement<'a, 'input>( debug_directive.map(|_| None), terminated( method_space - .flat_map(multi_variable) + .flat_map(|space| multi_variable(false, space)) .map(|var| Some(Statement::Variable(var))), Token::Semicolon, ), @@ -678,6 +678,7 @@ fn variable_declaration<'a, 'input>( } fn multi_variable<'a, 'input: 'a>( + extern_: bool, state_space: StateSpace, ) -> impl Parser<PtxParser<'a, 'input>, MultiVariable<&'input str>, ContextError> { move |stream: &mut PtxParser<'a, 'input>| { @@ -714,7 +715,7 @@ fn multi_variable<'a, 'input: 'a>( _ => None, }; if let Some(ref dims) = array_dimensions { - if dims[0] == 0 { + if !extern_ && dims[0] == 0 { return Err(ErrMode::from_error_kind(stream, ErrorKind::Verify)); } } @@ -746,13 +747,16 @@ fn array_initializer<'a, 'input: 'a>( delimited( Token::LBrace, separated( - array_dimensions[0] as usize..=array_dimensions[0] as usize, + 0..=array_dimensions[0] as usize, single_value_append(&mut result, type_), Token::Comma, ), Token::RBrace, ) .parse_next(stream)?; + // pad with zeros + let result_size = type_.size_of() as usize * array_dimensions[0] as usize; + result.extend(iter::repeat(0u8).take(result_size - result.len())); Ok(result) } } @@ -1079,11 +1083,11 @@ impl<Ident> ast::ParsedOperand<Ident> { fn vector_operand<'a, 'input>( stream: &mut PtxParser<'a, 'input>, ) -> PResult<Vec<&'input str>> { - let (_, r1, _, r2) = - (Token::LBracket, ident, Token::Comma, ident).parse_next(stream)?; + let (_, r1, _, r2) = (Token::LBrace, ident, Token::Comma, ident).parse_next(stream)?; + // TODO: parse .v8 literals dispatch! {any; - Token::LBracket => empty.map(|_| vec![r1, r2]), - Token::Comma => (ident, Token::Comma, ident, Token::LBracket).map(|(r3, _, r4, _)| vec![r1, r2, r3, r4]), + Token::RBrace => empty.map(|_| vec![r1, r2]), + Token::Comma => (ident, Token::Comma, ident, Token::RBrace).map(|(r3, _, r4, _)| vec![r1, r2, r3, r4]), _ => fail } .parse_next(stream) |