Skip to content

Commit 6cd9155

Browse files
committed
Add attribute designator
1 parent 314d03f commit 6cd9155

File tree

7 files changed

+53
-45
lines changed

7 files changed

+53
-45
lines changed

vhdl_lang/src/ast.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,18 @@ pub enum Operator {
9090
pub struct AttributeName {
9191
pub name: WithPos<Name>,
9292
pub signature: Option<WithPos<Signature>>,
93-
pub attr: Ident,
93+
pub attr: WithPos<AttributeDesignator>,
9494
pub expr: Option<Box<WithPos<Expression>>>,
9595
}
9696

97+
#[derive(PartialEq, Debug, Clone, Eq)]
98+
pub enum AttributeDesignator {
99+
Subtype,
100+
Range,
101+
ReverseRange,
102+
Ident(Symbol),
103+
}
104+
97105
/// LRM 8.7 External names
98106
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
99107
pub enum ExternalObjectClass {

vhdl_lang/src/ast/display.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ impl Display for AttributeName {
9595
}
9696
}
9797

98+
impl Display for AttributeDesignator {
99+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
100+
match self {
101+
AttributeDesignator::Ident(sym) => write!(f, "{}", sym),
102+
AttributeDesignator::Range => write!(f, "range"),
103+
AttributeDesignator::ReverseRange => write!(f, "reverse_range"),
104+
AttributeDesignator::Subtype => write!(f, "subtype"),
105+
}
106+
}
107+
}
108+
98109
impl Display for ExternalObjectClass {
99110
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
100111
match self {

vhdl_lang/src/syntax/expression.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::subtype_indication::parse_subtype_constraint;
1010
use super::tokens::{Kind, Kind::*, Token, TokenStream};
1111
use crate::ast;
1212
use crate::ast::*;
13-
use crate::data::{Diagnostic, Symbol, WithPos};
13+
use crate::data::{Diagnostic, WithPos};
1414

1515
fn name_to_expression(name: WithPos<Name>) -> WithPos<Expression> {
1616
WithPos {
@@ -281,12 +281,14 @@ fn parse_allocator(stream: &mut TokenStream) -> ParseResult<WithPos<Allocator>>
281281
}
282282
}
283283

284-
fn name_to_type_mark(name: WithPos<Name>, subtype_sym: &Symbol) -> ParseResult<WithPos<TypeMark>> {
284+
fn name_to_type_mark(name: WithPos<Name>) -> ParseResult<WithPos<TypeMark>> {
285285
let pos = name.pos.clone();
286286
let type_mark = name
287287
.try_map_into(|name| match name {
288288
Name::Attribute(attr) => {
289-
if attr.signature.is_none() && attr.expr.is_none() && attr.attr.item == *subtype_sym
289+
if attr.signature.is_none()
290+
&& attr.expr.is_none()
291+
&& attr.attr.item == AttributeDesignator::Subtype
290292
{
291293
Some(TypeMark {
292294
name: attr.name.try_map_into(name_to_selected_name)?,
@@ -370,7 +372,7 @@ fn parse_primary_initial_token(
370372
let pos = name.pos.combine(&expr);
371373
Ok(WithPos {
372374
item: Expression::Qualified(Box::new(QualifiedExpression {
373-
type_mark: name_to_type_mark(name, stream.subtype_sym())?,
375+
type_mark: name_to_type_mark(name)?,
374376
expr,
375377
})),
376378
pos,

vhdl_lang/src/syntax/names.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ mod tests {
670670
let attr = WithPos {
671671
item: Name::Attribute(Box::new(AttributeName {
672672
name: prefix,
673-
attr: code.s1("foo").ident(),
673+
attr: code.s1("foo").ident().map_into(AttributeDesignator::Ident),
674674
signature: None,
675675
expr: None,
676676
})),
@@ -690,7 +690,7 @@ mod tests {
690690
item: Name::Attribute(Box::new(AttributeName {
691691
name: prefix,
692692
attr: WithPos {
693-
item: code.symbol("range"),
693+
item: AttributeDesignator::Range,
694694
pos: code.s1("range").pos(),
695695
},
696696
signature: None,
@@ -712,7 +712,7 @@ mod tests {
712712
item: Name::Attribute(Box::new(AttributeName {
713713
name: prefix,
714714
attr: WithPos {
715-
item: code.symbol("subtype"),
715+
item: AttributeDesignator::Subtype,
716716
pos: code.s1("subtype").pos(),
717717
},
718718
signature: None,
@@ -766,7 +766,7 @@ mod tests {
766766
let attr = WithPos {
767767
item: Name::Attribute(Box::new(AttributeName {
768768
name: prefix,
769-
attr: code.s1("foo").ident(),
769+
attr: code.s1("foo").ident().map_into(AttributeDesignator::Ident),
770770
signature: None,
771771
expr: Some(Box::new(code.s1("expr+1").expr())),
772772
})),
@@ -785,7 +785,7 @@ mod tests {
785785
let attr = WithPos {
786786
item: Name::Attribute(Box::new(AttributeName {
787787
name: prefix,
788-
attr: code.s1("foo").ident(),
788+
attr: code.s1("foo").ident().map_into(AttributeDesignator::Ident),
789789
signature: Some(code.s1("[return natural]").signature()),
790790
expr: Some(Box::new(code.s1("expr+1").expr())),
791791
})),

vhdl_lang/src/syntax/range.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ fn parse_name_or_range(stream: &mut TokenStream) -> ParseResult<NameOrRange> {
5252
} = expr
5353
{
5454
if let Name::Attribute(ref attribute_name) = *name.as_ref() {
55-
if &attribute_name.attr.item == stream.range_sym()
56-
|| &attribute_name.attr.item == stream.reverse_range_sym()
57-
{
55+
if matches!(
56+
attribute_name.attr.item,
57+
AttributeDesignator::Range | AttributeDesignator::ReverseRange
58+
) {
5859
// @TODO avoid clone
5960
let range = ast::Range::Attribute(attribute_name.clone());
6061
return Ok(NameOrRange::Range(WithPos::from(range, pos)));

vhdl_lang/src/syntax/tokens/tokenizer.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,8 +1353,6 @@ pub struct Tokenizer<'a> {
13531353
source: &'a Source,
13541354
reader: ContentReader<'a>,
13551355
final_comments: Option<Vec<Comment>>,
1356-
range_sym: Symbol,
1357-
subtype_sym: Symbol,
13581356
reverse_range_sym: Symbol,
13591357
}
13601358

@@ -1364,8 +1362,6 @@ impl<'a> Tokenizer<'a> {
13641362
source: &'a Source,
13651363
reader: ContentReader<'a>,
13661364
) -> Tokenizer<'a> {
1367-
let subtype_sym = symbols.symtab().insert(&Latin1String::new(b"subtype"));
1368-
let range_sym = symbols.symtab().insert(&Latin1String::new(b"range"));
13691365
let reverse_range_sym = symbols
13701366
.symtab()
13711367
.insert(&Latin1String::new(b"reverse_range"));
@@ -1377,8 +1373,6 @@ impl<'a> Tokenizer<'a> {
13771373
source,
13781374
reader,
13791375
final_comments: None,
1380-
subtype_sym,
1381-
range_sym,
13821376
reverse_range_sym,
13831377
}
13841378
}
@@ -1405,14 +1399,6 @@ impl<'a> Tokenizer<'a> {
14051399
self.reader.set_state(self.state.start);
14061400
}
14071401

1408-
pub fn subtype_sym(&self) -> &Symbol {
1409-
&self.subtype_sym
1410-
}
1411-
1412-
pub fn range_sym(&self) -> &Symbol {
1413-
&self.range_sym
1414-
}
1415-
14161402
pub fn reverse_range_sym(&self) -> &Symbol {
14171403
&self.reverse_range_sym
14181404
}

vhdl_lang/src/syntax/tokens/tokenstream.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
use super::tokenizer::Kind::*;
88
use super::tokenizer::*;
9-
use crate::ast::Ident;
10-
use crate::data::{DiagnosticHandler, DiagnosticResult, Symbol};
9+
use crate::ast::{AttributeDesignator, Ident};
10+
use crate::data::{DiagnosticHandler, DiagnosticResult, Symbol, WithPos};
1111

1212
pub struct TokenStream<'a> {
1313
tokenizer: Tokenizer<'a>,
@@ -18,14 +18,6 @@ impl<'a> TokenStream<'a> {
1818
TokenStream { tokenizer }
1919
}
2020

21-
pub fn subtype_sym(&self) -> &Symbol {
22-
self.tokenizer.subtype_sym()
23-
}
24-
25-
pub fn range_sym(&self) -> &Symbol {
26-
self.tokenizer.range_sym()
27-
}
28-
2921
pub fn reverse_range_sym(&self) -> &Symbol {
3022
self.tokenizer.reverse_range_sym()
3123
}
@@ -140,16 +132,24 @@ impl<'a> TokenStream<'a> {
140132

141133
/// Expect identifier or subtype/range keywords
142134
/// foo'subtype or foo'range
143-
pub fn expect_attribute_designator(&mut self) -> DiagnosticResult<Ident> {
135+
pub fn expect_attribute_designator(
136+
&mut self,
137+
) -> DiagnosticResult<WithPos<AttributeDesignator>> {
144138
let token = self.expect()?;
145-
match_token_kind!(
139+
let des = try_token_kind!(
146140
token,
147-
Identifier => token.expect_ident(),
148-
Subtype => Ok(Ident {item: self.tokenizer.subtype_sym().clone(),
149-
pos: token.pos}),
150-
Range => Ok(Ident {item: self.range_sym().clone(),
151-
pos: token.pos})
152-
)
141+
Identifier => {
142+
let ident = token.expect_ident()?;
143+
if &ident.item == self.reverse_range_sym() {
144+
ident.map_into(|_| AttributeDesignator::ReverseRange)
145+
} else {
146+
ident.map_into(AttributeDesignator::Ident)
147+
}
148+
},
149+
Subtype => WithPos::new(AttributeDesignator::Subtype, token.pos),
150+
Range => WithPos::new(AttributeDesignator::Range, token.pos)
151+
);
152+
Ok(des)
153153
}
154154
}
155155

0 commit comments

Comments
 (0)