Skip to content

Commit

Permalink
Adding support to Const in Statements in Parser (#6245)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomer-StarkWare authored Aug 21, 2024
1 parent 66ef465 commit fb3d11c
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 1 deletion.
6 changes: 6 additions & 0 deletions crates/cairo-lang-parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1983,6 +1983,12 @@ impl<'a> Parser<'a> {
let semicolon = self.parse_token::<TerminalSemicolon>();
Ok(StatementBreak::new_green(self.db, attributes, break_kw, expr, semicolon).into())
}
SyntaxKind::TerminalConst => Ok(StatementItem::new_green(
self.db,
self.expect_item_const(attributes, VisibilityDefault::new_green(self.db).into())
.into(),
)
.into()),
_ => match self.try_parse_expr() {
Ok(expr) => {
let optional_semicolon = if self.peek().kind == SyntaxKind::TerminalSemicolon {
Expand Down
143 changes: 143 additions & 0 deletions crates/cairo-lang-parser/src/parser_test_data/partial_trees/constant
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,146 @@ ItemConstant
│ ├── size (kind: OptionFixedSizeArraySizeEmpty) []
│ └── rbrack (kind: TokenRBrack): ']'
└── semicolon (kind: TokenSemicolon): ';'

//! > ==========================================================================

//! > Const Statements

//! > test_runner_name
test_partial_parser_tree(expect_diagnostics: false)

//! > cairo_code
struct A {
member: felt252,
}

fn foo() {
const X: felt252 = 3;
const Y: A = A { member: 3 };
}

//! > top_level_kind
ItemConstant

//! > ignored_kinds

//! > expected_diagnostics

//! > expected_tree
└── Top level kind: ItemConstant
├── attributes (kind: AttributeList) []
├── visibility (kind: VisibilityDefault) []
├── const_kw (kind: TokenConst): 'const'
├── name (kind: TokenIdentifier): 'X'
├── type_clause (kind: TypeClause)
│ ├── colon (kind: TokenColon): ':'
│ └── ty (kind: ExprPath)
│ └── item #0 (kind: PathSegmentSimple)
│ └── ident (kind: TokenIdentifier): 'felt252'
├── eq (kind: TokenEq): '='
├── value (kind: TokenLiteralNumber): '3'
└── semicolon (kind: TokenSemicolon): ';'
└── Top level kind: ItemConstant
├── attributes (kind: AttributeList) []
├── visibility (kind: VisibilityDefault) []
├── const_kw (kind: TokenConst): 'const'
├── name (kind: TokenIdentifier): 'Y'
├── type_clause (kind: TypeClause)
│ ├── colon (kind: TokenColon): ':'
│ └── ty (kind: ExprPath)
│ └── item #0 (kind: PathSegmentSimple)
│ └── ident (kind: TokenIdentifier): 'A'
├── eq (kind: TokenEq): '='
├── value (kind: ExprStructCtorCall)
│ ├── path (kind: ExprPath)
│ │ └── item #0 (kind: PathSegmentSimple)
│ │ └── ident (kind: TokenIdentifier): 'A'
│ └── arguments (kind: StructArgListBraced)
│ ├── lbrace (kind: TokenLBrace): '{'
│ ├── arguments (kind: StructArgList)
│ │ └── item #0 (kind: StructArgSingle)
│ │ ├── identifier (kind: TokenIdentifier): 'member'
│ │ └── arg_expr (kind: StructArgExpr)
│ │ ├── colon (kind: TokenColon): ':'
│ │ └── expr (kind: TokenLiteralNumber): '3'
│ └── rbrace (kind: TokenRBrace): '}'
└── semicolon (kind: TokenSemicolon): ';'

//! > ==========================================================================

//! > Const Statements Missing Type

//! > test_runner_name
test_partial_parser_tree(expect_diagnostics: true)

//! > cairo_code
fn foo() {
const X = 3;
}

//! > top_level_kind
ItemConstant

//! > ignored_kinds

//! > expected_diagnostics
error: Unexpected token, expected ':' followed by a type.
--> dummy_file.cairo:2:12
const X = 3;
^

//! > expected_tree
└── Top level kind: ItemConstant
├── attributes (kind: AttributeList) []
├── visibility (kind: VisibilityDefault) []
├── const_kw (kind: TokenConst): 'const'
├── name (kind: TokenIdentifier): 'X'
├── type_clause (kind: TypeClause)
│ ├── colon: Missing
│ └── ty: Missing []
├── eq (kind: TokenEq): '='
├── value (kind: TokenLiteralNumber): '3'
└── semicolon (kind: TokenSemicolon): ';'

//! > ==========================================================================

//! > Const Statements with attribute

//! > test_runner_name
test_partial_parser_tree(expect_diagnostics: false)

//! > cairo_code
fn foo() {
#[flat]
const X: felt252 = 3;
}

//! > top_level_kind
ItemConstant

//! > ignored_kinds

//! > expected_diagnostics

//! > expected_tree
└── Top level kind: ItemConstant
├── attributes (kind: AttributeList)
│ └── child #0 (kind: Attribute)
│ ├── hash (kind: TokenHash): '#'
│ ├── lbrack (kind: TokenLBrack): '['
│ ├── attr (kind: ExprPath)
│ │ └── item #0 (kind: PathSegmentSimple)
│ │ └── ident (kind: TokenIdentifier): 'flat'
│ ├── arguments (kind: OptionArgListParenthesizedEmpty) []
│ └── rbrack (kind: TokenRBrack): ']'
├── visibility (kind: VisibilityDefault) []
├── const_kw (kind: TokenConst): 'const'
├── name (kind: TokenIdentifier): 'X'
├── type_clause (kind: TypeClause)
│ ├── colon (kind: TokenColon): ':'
│ └── ty (kind: ExprPath)
│ └── item #0 (kind: PathSegmentSimple)
│ └── ident (kind: TokenIdentifier): 'felt252'
├── eq (kind: TokenEq): '='
├── value (kind: TokenLiteralNumber): '3'
└── semicolon (kind: TokenSemicolon): ';'
1 change: 1 addition & 0 deletions crates/cairo-lang-semantic/src/expr/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3401,6 +3401,7 @@ pub fn compute_statement_semantic(
stable_ptr: syntax.stable_ptr(),
})
}
ast::Statement::Item(_) => todo!(),
ast::Statement::Missing(_) => todo!(),
};
ctx.resolver.data.feature_config.restore(feature_restore);
Expand Down
6 changes: 5 additions & 1 deletion crates/cairo-lang-syntax-codegen/src/cairo_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ pub fn get_spec() -> Vec<Node> {
.node("Continue")
.node("Return")
.node("Break")
.node("Item")
)
.add_list("StatementList", "Statement")
.add_struct(StructBuilder::new("StatementMissing"))
Expand Down Expand Up @@ -399,6 +400,9 @@ pub fn get_spec() -> Vec<Node> {
.node("expr_clause", "OptionExprClause")
.node("semicolon", "TerminalSemicolon")
)
.add_struct(StructBuilder::new("StatementItem")
.node("item", "ModuleItem")
)
// --- Functions ---
.add_struct(StructBuilder::new("Param")
.node("modifiers", "ModifierList")
Expand Down Expand Up @@ -497,7 +501,7 @@ pub fn get_spec() -> Vec<Node> {
.add_enum(EnumBuilder::new("MaybeModuleBody")
.node_with_explicit_kind("Some", "ModuleBody")
.node_with_explicit_kind("None", "TerminalSemicolon")
)
)
.add_struct(StructBuilder::new("ModuleBody")
.node("lbrace", "TerminalLBrace")
.node("items", "ModuleItemList")
Expand Down
97 changes: 97 additions & 0 deletions crates/cairo-lang-syntax/src/node/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8958,6 +8958,7 @@ pub enum Statement {
Continue(StatementContinue),
Return(StatementReturn),
Break(StatementBreak),
Item(StatementItem),
Missing(StatementMissing),
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
Expand Down Expand Up @@ -9001,6 +9002,11 @@ impl From<StatementBreakPtr> for StatementPtr {
Self(value.0)
}
}
impl From<StatementItemPtr> for StatementPtr {
fn from(value: StatementItemPtr) -> Self {
Self(value.0)
}
}
impl From<StatementMissingPtr> for StatementPtr {
fn from(value: StatementMissingPtr) -> Self {
Self(value.0)
Expand Down Expand Up @@ -9031,6 +9037,11 @@ impl From<StatementBreakGreen> for StatementGreen {
Self(value.0)
}
}
impl From<StatementItemGreen> for StatementGreen {
fn from(value: StatementItemGreen) -> Self {
Self(value.0)
}
}
impl From<StatementMissingGreen> for StatementGreen {
fn from(value: StatementMissingGreen) -> Self {
Self(value.0)
Expand Down Expand Up @@ -9059,6 +9070,7 @@ impl TypedSyntaxNode for Statement {
SyntaxKind::StatementBreak => {
Statement::Break(StatementBreak::from_syntax_node(db, node))
}
SyntaxKind::StatementItem => Statement::Item(StatementItem::from_syntax_node(db, node)),
SyntaxKind::StatementMissing => {
Statement::Missing(StatementMissing::from_syntax_node(db, node))
}
Expand All @@ -9072,6 +9084,7 @@ impl TypedSyntaxNode for Statement {
Statement::Continue(x) => x.as_syntax_node(),
Statement::Return(x) => x.as_syntax_node(),
Statement::Break(x) => x.as_syntax_node(),
Statement::Item(x) => x.as_syntax_node(),
Statement::Missing(x) => x.as_syntax_node(),
}
}
Expand All @@ -9093,6 +9106,7 @@ impl Statement {
SyntaxKind::StatementContinue => true,
SyntaxKind::StatementReturn => true,
SyntaxKind::StatementBreak => true,
SyntaxKind::StatementItem => true,
SyntaxKind::StatementMissing => true,
_ => false,
}
Expand Down Expand Up @@ -10202,6 +10216,89 @@ impl From<&StatementBreak> for SyntaxStablePtrId {
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct StatementItem {
node: SyntaxNode,
children: Arc<[SyntaxNode]>,
}
impl StatementItem {
pub const INDEX_ITEM: usize = 0;
pub fn new_green(db: &dyn SyntaxGroup, item: ModuleItemGreen) -> StatementItemGreen {
let children: Vec<GreenId> = vec![item.0];
let width = children.iter().copied().map(|id| id.lookup_intern(db).width()).sum();
StatementItemGreen(
Arc::new(GreenNode {
kind: SyntaxKind::StatementItem,
details: GreenNodeDetails::Node { children, width },
})
.intern(db),
)
}
}
impl StatementItem {
pub fn item(&self, db: &dyn SyntaxGroup) -> ModuleItem {
ModuleItem::from_syntax_node(db, self.children[0].clone())
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct StatementItemPtr(pub SyntaxStablePtrId);
impl StatementItemPtr {}
impl TypedStablePtr for StatementItemPtr {
type SyntaxNode = StatementItem;
fn untyped(&self) -> SyntaxStablePtrId {
self.0
}
fn lookup(&self, db: &dyn SyntaxGroup) -> StatementItem {
StatementItem::from_syntax_node(db, self.0.lookup(db))
}
}
impl From<StatementItemPtr> for SyntaxStablePtrId {
fn from(ptr: StatementItemPtr) -> Self {
ptr.untyped()
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct StatementItemGreen(pub GreenId);
impl TypedSyntaxNode for StatementItem {
const OPTIONAL_KIND: Option<SyntaxKind> = Some(SyntaxKind::StatementItem);
type StablePtr = StatementItemPtr;
type Green = StatementItemGreen;
fn missing(db: &dyn SyntaxGroup) -> Self::Green {
StatementItemGreen(
Arc::new(GreenNode {
kind: SyntaxKind::StatementItem,
details: GreenNodeDetails::Node {
children: vec![ModuleItem::missing(db).0],
width: TextWidth::default(),
},
})
.intern(db),
)
}
fn from_syntax_node(db: &dyn SyntaxGroup, node: SyntaxNode) -> Self {
let kind = node.kind(db);
assert_eq!(
kind,
SyntaxKind::StatementItem,
"Unexpected SyntaxKind {:?}. Expected {:?}.",
kind,
SyntaxKind::StatementItem
);
let children = db.get_children(node.clone());
Self { node, children }
}
fn as_syntax_node(&self) -> SyntaxNode {
self.node.clone()
}
fn stable_ptr(&self) -> Self::StablePtr {
StatementItemPtr(self.node.0.stable_ptr)
}
}
impl From<&StatementItem> for SyntaxStablePtrId {
fn from(node: &StatementItem) -> Self {
node.stable_ptr().untyped()
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Param {
node: SyntaxNode,
children: Arc<[SyntaxNode]>,
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-lang-syntax/src/node/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ impl QueryAttrs for Statement {
Statement::Return(statement) => statement.attributes_elements(db),
Statement::Let(statement) => statement.attributes_elements(db),
Statement::Expr(statement) => statement.attributes_elements(db),
Statement::Item(statement) => statement.item(db).attributes_elements(db),
Statement::Missing(_) => vec![],
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/cairo-lang-syntax/src/node/key_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ pub fn get_key_fields(kind: SyntaxKind, children: &[GreenId]) -> Vec<GreenId> {
SyntaxKind::StatementBreak => {
vec![]
}
SyntaxKind::StatementItem => {
vec![]
}
SyntaxKind::Param => {
vec![/* name */ children[1]]
}
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-lang-syntax/src/node/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub enum SyntaxKind {
OptionExprClauseEmpty,
StatementReturn,
StatementBreak,
StatementItem,
Param,
ModifierList,
ParamList,
Expand Down

0 comments on commit fb3d11c

Please sign in to comment.