Skip to content

Commit

Permalink
improve impl grammar [4] (#155)
Browse files Browse the repository at this point in the history
* Reorder project and add book

* refactor lower type

* Add initial grammar for impl blocks

* optimize grammar

* Add TypeName to AST, allowing type names to have a full path and generics

* remove unused

* remove comment

* improve impl grammar

* clippy
  • Loading branch information
edg-l authored Jan 14, 2025
1 parent d786c3b commit 5c34874
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/ast/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ pub struct MatchVariant {
pub enum PathSegment {
FieldAccess(Ident, Span),
ArrayIndex(ValueExpr, Span),
MethodCall(FnCallOp, Span),
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down
5 changes: 5 additions & 0 deletions src/ast/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ pub enum TypeDescriptor {
size: u64,
span: Span,
},
// Used in impl blocks.
SelfType {
is_ref: bool,
is_mut: bool,
},
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
Expand Down
16 changes: 16 additions & 0 deletions src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern {
"import" => Token::KeywordImport,
"extern" => Token::KeywordExtern,
"as" => Token::KeywordAs,
"self" => Token::KeywordSelf,

// literals
"identifier" => Token::Identifier(<String>),
Expand Down Expand Up @@ -145,6 +146,10 @@ Ident: ast::common::Ident = {
<lo:@L> <name:"identifier"> <hi:@R> => ast::common::Ident {
name,
span: ast::common::Span::new(lo, hi),
},
<lo:@L> <name:"self"> <hi:@R> => ast::common::Ident {
name: name.to_string(),
span: ast::common::Span::new(lo, hi),
}
}

Expand Down Expand Up @@ -311,6 +316,16 @@ Param: ast::functions::Param = {
<name:Ident> ":" <param_type:TypeDescriptor> => ast::functions::Param {
name,
r#type: param_type
},
<lo:@L> <is_ref:"&"?> <is_mut:"mut"?> "self" <hi:@R> => ast::functions::Param {
name: ast::common::Ident {
name: "self".to_string(),
span: Span::new(lo, hi),
},
r#type: ast::types::TypeDescriptor::SelfType {
is_ref: is_ref.is_some(),
is_mut: is_mut.is_some(),
},
}
}

Expand Down Expand Up @@ -572,6 +587,7 @@ PathOp: ast::expressions::PathOp = {

PathSegment: ast::expressions::PathSegment = {
<lo:@L> "." <e:Ident> <hi:@R> => ast::expressions::PathSegment::FieldAccess(e, Span::new(lo, hi)),
<lo:@L> "." <e:FnCallOp> <hi:@R> => ast::expressions::PathSegment::MethodCall(e, Span::new(lo, hi)),
<lo:@L> "[" <e:ValueExpr> "]" <hi:@R> => ast::expressions::PathSegment::ArrayIndex(e, Span::new(lo, hi)),
}

Expand Down
5 changes: 5 additions & 0 deletions src/ir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1739,6 +1739,7 @@ pub fn lower_path(
ty = *element_type;
}
}
PathSegment::MethodCall(_fn_call_op, _span) => todo!(),
}
}

Expand Down Expand Up @@ -1825,5 +1826,9 @@ pub fn lower_type(
}),
),
),
TypeDescriptor::SelfType {
is_ref: _,
is_mut: _,
} => todo!(),
})
}
56 changes: 56 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,62 @@ mod ModuleName {
let source = r##"mod MyMod {
#[intrinsic = "simdsomething"]
pub extern fn myintrinsic();
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
parser.parse(lexer).unwrap();
}

#[test]
fn parse_impl() {
let source = r##"mod MyMod {
struct A {
a: i32,
b: i32,
}
impl A {
pub fn hello(&self, other: i32) -> i32 {
return self.a * other;
}
}
pub fn main() -> i32 {
let x: A = A {
a: 2,
b: 3,
};
return x.hello(4);
}
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
parser.parse(lexer).unwrap();
}

#[test]
fn parse_impl_mut() {
let source = r##"mod MyMod {
struct A {
a: i32,
b: i32,
}
impl A {
pub fn hello(&mut self, other: i32) -> i32 {
return self.a * other;
}
}
pub fn main() -> i32 {
let x: A = A {
a: 2,
b: 3,
};
return x.hello(4);
}
}"##;
let lexer = Lexer::new(source);
let parser = grammar::ProgramParser::new();
Expand Down
2 changes: 2 additions & 0 deletions src/parser/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub enum Token {
KeywordExtern,
#[token("as")]
KeywordAs,
#[token("self")]
KeywordSelf,

// Modern way of allowing identifiers, read: https://unicode.org/reports/tr31/
#[regex(r"[\p{XID_Start}_]\p{XID_Continue}*", |lex| lex.slice().to_string())]
Expand Down

0 comments on commit 5c34874

Please sign in to comment.