change syntax of array declaration: move brackets from after name to after type

This commit is contained in:
Moritz Hölting 2025-08-13 12:58:35 +02:00
parent 3271ca514c
commit d9ae985282
4 changed files with 93 additions and 82 deletions

View File

@ -99,7 +99,7 @@ FunctionParameterList:
```ebnf ```ebnf
ArrayVariableDeclaration: ArrayVariableDeclaration:
('int' | 'bool') identifier '[' integer ']' VariableDeclarationAssignment? ('int' | 'bool') '[' integer ']' identifier VariableDeclarationAssignment?
``` ```
## ComptimeValueDeclaration ## ComptimeValueDeclaration

View File

@ -493,7 +493,7 @@ impl SingleVariableDeclaration {
/// ///
/// ```ebnf /// ```ebnf
/// ArrayVariableDeclaration: /// ArrayVariableDeclaration:
/// ('int' | 'bool') identifier '[' integer ']' VariableDeclarationAssignment? /// ('int' | 'bool') '[' integer ']' identifier VariableDeclarationAssignment?
/// ``` /// ```
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)]
@ -501,9 +501,6 @@ pub struct ArrayVariableDeclaration {
/// The type of the variable. /// The type of the variable.
#[get = "pub"] #[get = "pub"]
variable_type: Keyword, variable_type: Keyword,
/// The identifier of the variable.
#[get = "pub"]
identifier: Identifier,
/// The opening bracket of the array. /// The opening bracket of the array.
#[get = "pub"] #[get = "pub"]
open_bracket: Punctuation, open_bracket: Punctuation,
@ -513,6 +510,9 @@ pub struct ArrayVariableDeclaration {
/// The closing bracket of the array. /// The closing bracket of the array.
#[get = "pub"] #[get = "pub"]
close_bracket: Punctuation, close_bracket: Punctuation,
/// The identifier of the variable.
#[get = "pub"]
identifier: Identifier,
/// The optional assignment of the variable. /// The optional assignment of the variable.
#[get = "pub"] #[get = "pub"]
assignment: Option<VariableDeclarationAssignment>, assignment: Option<VariableDeclarationAssignment>,
@ -1053,11 +1053,7 @@ impl Parser<'_> {
None None
}; };
// read identifier let index = match self.stop_at_significant() {
self.stop_at_significant();
let identifier = self.parse_identifier(handler)?;
match self.stop_at_significant() {
Reading::IntoDelimited(punc) Reading::IntoDelimited(punc)
if punc.punctuation == '[' if punc.punctuation == '['
&& matches!(variable_type.keyword, KeywordKind::Int | KeywordKind::Bool) => && matches!(variable_type.keyword, KeywordKind::Int | KeywordKind::Bool) =>
@ -1094,84 +1090,69 @@ impl Parser<'_> {
let close_bracket = tree.close; let close_bracket = tree.close;
let inner = tree.tree?; let inner = tree.tree?;
match inner { Some((open_bracket, inner, close_bracket))
IndexingType::IntegerSize(size) => {
let assignment = self
.try_parse(|p| {
// read equals sign
let equals = p.parse_punctuation('=', true, &VoidHandler)?;
// read expression
let expression = p.parse_expression(&VoidHandler)?;
Ok(VariableDeclarationAssignment { equals, expression })
})
.ok();
Ok(VariableDeclaration::Array(ArrayVariableDeclaration {
variable_type,
identifier,
open_bracket,
size,
close_bracket,
assignment,
annotations: VecDeque::new(),
}))
}
IndexingType::None => match variable_type.keyword {
KeywordKind::Int => {
Ok(VariableDeclaration::Score(ScoreVariableDeclaration {
int_keyword: variable_type,
criteria: criteria_selection,
identifier,
open_bracket,
close_bracket,
assignment: None,
annotations: VecDeque::new(),
}))
}
KeywordKind::Bool => Ok(VariableDeclaration::Tag(TagVariableDeclaration {
bool_keyword: variable_type,
identifier,
open_bracket,
close_bracket,
target_assignment: None,
annotations: VecDeque::new(),
})),
_ => unreachable!(),
},
}
} }
// SingleVariableDeclaration with Assignment _ => None,
Reading::Atomic(Token::Punctuation(punc)) if punc.punctuation == '=' => { };
self.forward();
let equals = punc;
let expression = self.parse_expression(handler)?;
let assignment = VariableDeclarationAssignment { equals, expression };
if variable_type.keyword == KeywordKind::Val { // read identifier
Ok(VariableDeclaration::ComptimeValue( self.stop_at_significant();
ComptimeValueDeclaration { let identifier = self.parse_identifier(handler)?;
val_keyword: variable_type,
identifier, // TODO: allow assignment when map and array literals have been implemented
assignment: Some(assignment), let assignment = if index.is_none() {
annotations: VecDeque::new(), self.try_parse(|p| {
}, // read equals sign
)) let equals = p.parse_punctuation('=', true, &VoidHandler)?;
} else {
Ok(VariableDeclaration::Single(SingleVariableDeclaration { // read expression
variable_type, let expression = p.parse_expression(&VoidHandler)?;
Ok(VariableDeclarationAssignment { equals, expression })
})
.ok()
} else {
None
};
match index {
Some((open_bracket, IndexingType::IntegerSize(size), close_bracket)) => {
Ok(VariableDeclaration::Array(ArrayVariableDeclaration {
variable_type,
identifier,
open_bracket,
size,
close_bracket,
assignment,
annotations: VecDeque::new(),
}))
}
Some((open_bracket, IndexingType::None, close_bracket)) => {
match variable_type.keyword {
KeywordKind::Int => Ok(VariableDeclaration::Score(ScoreVariableDeclaration {
int_keyword: variable_type,
criteria: criteria_selection,
identifier, identifier,
assignment: Some(assignment), open_bracket,
close_bracket,
assignment: None,
annotations: VecDeque::new(), annotations: VecDeque::new(),
})) })),
KeywordKind::Bool => Ok(VariableDeclaration::Tag(TagVariableDeclaration {
bool_keyword: variable_type,
identifier,
open_bracket,
close_bracket,
target_assignment: None,
annotations: VecDeque::new(),
})),
_ => unreachable!(),
} }
} }
// SingleVariableDeclaration without Assignment None => Ok(VariableDeclaration::Single(SingleVariableDeclaration {
_ => Ok(VariableDeclaration::Single(SingleVariableDeclaration {
variable_type, variable_type,
identifier, identifier,
assignment: None, assignment,
annotations: VecDeque::new(), annotations: VecDeque::new(),
})), })),
} }

View File

@ -398,6 +398,11 @@ pub enum IllegalIndexingReason {
/// The length indexed object. /// The length indexed object.
length: usize, length: usize,
}, },
/// The index provided is invalid
InvalidIndex {
/// The invalid index
index: Span,
},
} }
impl Display for IllegalIndexingReason { impl Display for IllegalIndexingReason {
@ -421,6 +426,9 @@ impl Display for IllegalIndexingReason {
"The index {index} is out of bounds for the expression with length {length}." "The index {index} is out of bounds for the expression with length {length}."
) )
} }
Self::InvalidIndex { index } => {
write!(f, "The index {index} is invalid.", index = index.str())
}
} }
} }
} }

View File

@ -1225,7 +1225,18 @@ impl Transpiler {
.parent() .parent()
.comptime_member_access(member_access, scope, handler) .comptime_member_access(member_access, scope, handler)
.map_or_else( .map_or_else(
|_| todo!("implement non-comptime member access"), |_| {
// TODO: implement non-comptime access
let err = TranspileError::IllegalIndexing(IllegalIndexing {
expression: member_access.member().span(),
reason: IllegalIndexingReason::InvalidIndex {
index: member_access.member().span(),
},
});
handler.receive(err.clone());
Err(err)
},
|value| self.store_comptime_value(&value, target, member_access, handler), |value| self.store_comptime_value(&value, target, member_access, handler),
), ),
Primary::Lua(lua) => Primary::Lua(lua) =>
@ -1794,7 +1805,18 @@ impl Transpiler {
.parent() .parent()
.comptime_member_access(member_access, scope, handler) .comptime_member_access(member_access, scope, handler)
.map_or_else( .map_or_else(
|_| todo!("implement non-comptime member access"), |_| {
// TODO: implement non-comptime access
let err = TranspileError::IllegalIndexing(IllegalIndexing {
expression: member_access.member().span(),
reason: IllegalIndexingReason::InvalidIndex {
index: member_access.member().span(),
},
});
handler.receive(err.clone());
Err(err)
},
|value| match value { |value| match value {
ComptimeValue::Boolean(b) => { ComptimeValue::Boolean(b) => {
Ok((Vec::new(), ExtendedCondition::Comptime(b))) Ok((Vec::new(), ExtendedCondition::Comptime(b)))