Skip to content

Commit a9d1b48

Browse files
authored
Merge branch 'main' into feature/71-spacing-pending-rules
2 parents db2cb5d + f71c842 commit a9d1b48

File tree

4 files changed

+68
-45
lines changed

4 files changed

+68
-45
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
# Change Log
66

77
## 0.9.13
8+
- Corrected the name of "explicit\_param\_decls" provisional. Note that it still
9+
has no semantic effect.
10+
- The parameter declaration patterns ":=" and ": \<type\> = \<val\>" are now
11+
correctly parsed.
812

913
## 0.9.12
1014
- Added 'simics\_util\_vect' as a known provisional (with no DLS semantics)

src/analysis/parsing/structure.rs

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -329,30 +329,22 @@ fn parse_method(modifier: Option<LeafToken>,
329329

330330
#[derive(Debug, Clone, PartialEq)]
331331
pub enum ParamDef {
332-
// Either default or =
332+
// default | = <expr>
333333
Set(LeafToken, Expression),
334334
Auto(LeafToken),
335-
Typed(LeafToken, CTypeDecl),
336-
Empty,
337335
}
338336

339337
impl TreeElement for ParamDef {
340338
fn range(&self) -> ZeroRange {
341339
match self {
342340
Self::Set(kw, expr) => Range::combine(kw.range(), expr.range()),
343341
Self::Auto(tok) => tok.range(),
344-
Self::Typed(colon, typedecl) =>
345-
Range::combine(colon.range(), typedecl.range()),
346-
Self::Empty => ZeroRange::invalid(),
347342
}
348343
}
349344
fn subs(&self) -> TreeElements<'_> {
350345
match self {
351346
Self::Set(kw, expr) => create_subs!(kw, expr),
352347
Self::Auto(tok) => create_subs!(tok),
353-
Self::Typed(colon, typedecl) =>
354-
create_subs!(colon, typedecl),
355-
Self::Empty => vec![],
356348
}
357349
}
358350
}
@@ -361,7 +353,9 @@ impl TreeElement for ParamDef {
361353
pub struct ParameterContent {
362354
pub param: LeafToken,
363355
pub name: LeafToken,
364-
pub def: ParamDef,
356+
pub colon: Option<LeafToken>,
357+
pub typing: Option<CTypeDecl>,
358+
pub def: Option<ParamDef>,
365359
pub semi: LeafToken,
366360
}
367361

@@ -374,6 +368,8 @@ impl TreeElement for ParameterContent {
374368
fn subs(&self) -> TreeElements<'_> {
375369
create_subs!(&self.param,
376370
&self.name,
371+
&self.colon,
372+
&self.typing,
377373
&self.def,
378374
&self.semi)
379375
}
@@ -385,23 +381,44 @@ impl Parse<DMLObjectContent> for ParameterContent {
385381
let param = inner.expect_next_kind(stream, TokenKind::Param);
386382
let name = inner.expect_next_filter(
387383
stream, objident_filter, "parameter name");
388-
let def = match inner.peek_kind(stream) {
389-
Some(TokenKind::Assign) | Some(TokenKind::Default) => {
390-
let assign = inner.next_leaf(stream);
391-
let value = Expression::parse(&inner, stream, file_info);
392-
ParamDef::Set(assign, value)
393-
},
394-
Some(TokenKind::Auto) => ParamDef::Auto(inner.next_leaf(stream)),
395-
Some(TokenKind::Colon) => {
396-
let colon = inner.next_leaf(stream);
397-
let typed = CTypeDecl::parse(&inner, stream, file_info);
398-
ParamDef::Typed(colon, typed)
399-
},
400-
_ => ParamDef::Empty,
384+
let colon = if inner.peek_kind(stream) == Some(TokenKind::Colon) {
385+
Some(inner.next_leaf(stream))
386+
} else {
387+
None
388+
};
389+
fn parse_assign(context: &mut ParseContext,
390+
stream: &mut FileParser<'_>,
391+
file_info: &FileInfo) -> Option<ParamDef> {
392+
match context.peek_kind(stream) {
393+
Some(TokenKind::Assign) | Some(TokenKind::Default) => {
394+
let assign = context.next_leaf(stream);
395+
let value = Expression::parse(context, stream, file_info);
396+
Some(ParamDef::Set(assign, value))
397+
},
398+
Some(TokenKind::Auto) =>
399+
Some(ParamDef::Auto(context.next_leaf(stream))),
400+
_ => None
401+
}
402+
}
403+
404+
let (typing, def) = match inner.peek_kind(stream) {
405+
Some(TokenKind::Assign | TokenKind::Default | TokenKind::Auto) =>
406+
(None, parse_assign(&mut inner, stream, file_info)),
407+
_ if colon.is_some() =>
408+
(Some(CTypeDecl::parse(&inner, stream, file_info)),
409+
if matches!(inner.peek_kind(stream),
410+
Some(TokenKind::Assign
411+
| TokenKind::Default
412+
| TokenKind::Auto)) {
413+
parse_assign(&mut inner, stream, file_info)
414+
} else {
415+
None
416+
}),
417+
_ => (None, None),
401418
};
402419
let semi = outer.expect_next_kind(stream, TokenKind::SemiColon);
403420
DMLObjectContent::Parameter(ParameterContent {
404-
param, name, def, semi
421+
param, name, colon, typing, def, semi
405422
}).into()
406423
}
407424
}
@@ -719,7 +736,7 @@ fn check_dmlobject_kind(obj: &DMLObjectContent, _file: &TextFile) ->
719736
trace!("Checking kind restriction on {:?}", obj);
720737
match obj {
721738
DMLObjectContent::Parameter(paramcontent) => {
722-
if let ParamDef::Typed(_, _) = &paramcontent.def {
739+
if paramcontent.typing.is_some() {
723740
return vec![LocalDMLError {
724741
range: obj.range(),
725742
description: "Typed parameter declaration only \

src/analysis/provisionals.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::analysis::FileSpec;
1414
#[strum(serialize_all = "snake_case")]
1515
pub enum Provisional {
1616
// TODO: implement the neccessary checks for explicit params
17-
ExplicitParamDecl,
17+
ExplicitParamDecls,
1818
SimicsUtilVect,
1919
}
2020

@@ -69,7 +69,7 @@ mod test {
6969
#[test]
7070
fn test_provisionals_parsing() {
7171
for (s, p) in [
72-
("explicit_param_decl", Provisional::ExplicitParamDecl),
72+
("explicit_param_decls", Provisional::ExplicitParamDecls),
7373
("simics_util_vect", Provisional::SimicsUtilVect),
7474
] {
7575
assert_eq!(Provisional::from_str(s), Ok(p));

src/analysis/structure/objects.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,24 +1132,26 @@ impl ToStructure<structure::ParameterContent> for Parameter {
11321132
fn to_structure<'a>(content: &structure::ParameterContent,
11331133
report: &mut Vec<LocalDMLError>,
11341134
file: FileSpec<'a>) -> Option<Parameter> {
1135-
let (is_default, value, typed) = match &content.def {
1136-
structure::ParamDef::Set(assigntok, expr) => {
1137-
(assigntok.get_token()
1138-
.map_or(false, |rt|rt.kind == TokenKind::Default),
1139-
ExpressionKind::to_expression(expr, report, file).map(
1140-
|e|ParamValue::Set(e)),
1141-
None)
1142-
},
1143-
structure::ParamDef::Auto(tok) =>
1144-
(false,
1145-
Some(ParamValue::Auto(ZeroSpan::from_range(tok.range(),
1146-
file.path))),
1147-
None),
1148-
structure::ParamDef::Typed(_, ty) =>
1149-
(false, None, to_type(ty, report, file)),
1150-
structure::ParamDef::Empty =>
1151-
(false, None, None),
1152-
};
1135+
// TODO: track whether this was a defining-declaration without type
1136+
// ("param foo := 1;") for purposes of checking when the provisional
1137+
// is activated
1138+
// TODO: We could consider warning here if ":=" syntax is used without
1139+
// provisional active?
1140+
let typed = content.typing.as_ref()
1141+
.and_then(|t|to_type(t, report, file));
1142+
let (is_default, value) = content.def.as_ref()
1143+
.map_or((false, None), |d| match d {
1144+
structure::ParamDef::Set(assigntok, expr) => {
1145+
(assigntok.get_token()
1146+
.map_or(false, |rt|rt.kind == TokenKind::Default),
1147+
ExpressionKind::to_expression(expr, report, file).map(
1148+
|e|ParamValue::Set(e)))
1149+
},
1150+
structure::ParamDef::Auto(tok) =>
1151+
(false,
1152+
Some(ParamValue::Auto(ZeroSpan::from_range(tok.range(),
1153+
file.path)))),
1154+
});
11531155
let object = DMLObjectCommon {
11541156
name: DMLString::from_token(&content.name, file)?,
11551157
span: ZeroSpan::from_range(content.range(), file.path),

0 commit comments

Comments
 (0)