Skip to content

Commit 8c6aa9d

Browse files
authored
feat: simple traits (#6)
2 parents ccecf86 + bd09b81 commit 8c6aa9d

43 files changed

Lines changed: 2195 additions & 319 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cspell.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": "0.2",
33
"language": "en-GB",
44
"useGitignore": true,
5-
"ignorePaths": [".cspell.json"],
5+
"ignorePaths": [".cspell.json", "*.snap"],
66
"words": [
77
"color",
88

src/ir/ast.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::BTreeMap;
2+
13
use crate::prelude::*;
24

35
pub use self::{block::*, expression::*, function::*, statement::*};
@@ -7,6 +9,7 @@ create_id!(ExpressionId);
79
create_id!(FunctionId);
810
create_id!(StatementId);
911
create_id!(AstTypeId);
12+
create_id!(TraitId);
1013

1114
#[derive(Clone, Debug)]
1215
pub struct Ast {
@@ -17,6 +20,12 @@ pub struct Ast {
1720
pub expressions: IndexedVec<ExpressionId, Expression>,
1821

1922
pub types: IndexedVec<AstTypeId, AstType>,
23+
24+
/// Top-level function declarations.
25+
pub item_functions: Vec<FunctionId>,
26+
27+
pub traits: IndexedVec<TraitId, Trait>,
28+
pub trait_implementations: Vec<TraitImplementation>,
2029
}
2130

2231
impl Ast {
@@ -27,6 +36,9 @@ impl Ast {
2736
statements: IndexedVec::new(),
2837
expressions: IndexedVec::new(),
2938
types: IndexedVec::new(),
39+
item_functions: Vec::new(),
40+
traits: IndexedVec::new(),
41+
trait_implementations: Vec::new(),
3042
}
3143
}
3244
}
@@ -71,9 +83,19 @@ impl Index<AstTypeId> for Ast {
7183
}
7284
}
7385

86+
impl Index<TraitId> for Ast {
87+
type Output = Trait;
88+
89+
fn index(&self, index: TraitId) -> &Self::Output {
90+
&self.traits[index]
91+
}
92+
}
93+
7494
/// Type representation used within the [`Ast`].
7595
#[derive(Clone, Debug)]
7696
pub enum AstType {
97+
/// Built-in alias for the type where this type representation is used.
98+
SelfType,
7799
/// A type referenced by a single interned name (eg. `i8`, `bool`).
78100
Named(StringId),
79101
/// A tuple type (`(i8, bool, u8)`).
@@ -84,10 +106,15 @@ mod function {
84106
use super::*;
85107

86108
#[derive(Clone, Debug)]
87-
pub struct FunctionDeclaration {
109+
pub struct FunctionSignature {
88110
pub name: StringId,
89111
pub parameters: Vec<FunctionParameter>,
90112
pub return_ty: Option<AstTypeId>,
113+
}
114+
115+
#[derive(Clone, Debug)]
116+
pub struct FunctionDeclaration {
117+
pub signature: FunctionSignature,
91118
pub body: BlockId,
92119
}
93120

@@ -167,6 +194,7 @@ mod expression {
167194
Variable(Variable),
168195
Tuple(Tuple),
169196
Field(Field),
197+
QualifiedPath(QualifiedPath),
170198
}
171199

172200
#[derive(Clone, Debug)]
@@ -235,6 +263,13 @@ mod expression {
235263
Unnamed(usize),
236264
}
237265

266+
#[derive(Clone, Debug)]
267+
pub struct QualifiedPath {
268+
pub ty: AstTypeId,
269+
pub name: StringId,
270+
pub item: StringId,
271+
}
272+
238273
enum_conversion! {
239274
[Expression]
240275
Assign: Assign,
@@ -248,5 +283,21 @@ mod expression {
248283
Variable: Variable,
249284
Tuple: Tuple,
250285
Field: Field,
286+
QualifiedPath: QualifiedPath,
251287
}
252288
}
289+
290+
#[derive(Clone, Debug)]
291+
pub struct Trait {
292+
/// Original name of the trait.
293+
pub name: StringId,
294+
/// Methods defined within the trait.
295+
pub methods: BTreeMap<StringId, FunctionSignature>,
296+
}
297+
298+
#[derive(Clone, Debug)]
299+
pub struct TraitImplementation {
300+
pub trait_name: StringId,
301+
pub target_ty: AstTypeId,
302+
pub methods: BTreeMap<StringId, FunctionId>,
303+
}

src/ir/cst.rs

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,83 @@ impl Program {
2222

2323
pub fn add_function_declaration(&mut self, function_declaration: FunctionDeclaration) {
2424
self.items
25-
.push(Item::FunctionDeclaration(function_declaration))
25+
.push(Item::FunctionDeclaration(function_declaration));
26+
}
27+
28+
pub fn add_trait_declaration(&mut self, trait_declaration: TraitDeclaration) {
29+
self.items.push(Item::TraitDeclaration(trait_declaration));
30+
}
31+
32+
pub fn add_trait_implementation(&mut self, trait_implementation: TraitImplementation) {
33+
self.items
34+
.push(Item::TraitImplementation(trait_implementation));
2635
}
2736
}
2837

2938
/// A node which may appear at the top-level of a program.
3039
#[derive(Clone, Debug)]
3140
pub enum Item {
41+
TraitDeclaration(TraitDeclaration),
42+
TraitImplementation(TraitImplementation),
3243
FunctionDeclaration(FunctionDeclaration),
3344
}
3445

46+
/// Trait declaration.
47+
///
48+
/// ```
49+
/// trait MyTrait {
50+
/// fn a() -> bool;
51+
/// fn b(n: i32);
52+
/// }
53+
/// ```
54+
#[derive(Clone, Debug)]
55+
pub struct TraitDeclaration {
56+
#[expect(dead_code, reason = "token field")]
57+
pub tok_trait: tok::Trait,
58+
pub name: tok::Ident,
59+
#[expect(dead_code, reason = "token field")]
60+
pub tok_l_brace: tok::LBrace,
61+
pub methods: Vec<(FunctionSignature, tok::SemiColon)>,
62+
#[expect(dead_code, reason = "token field")]
63+
pub tok_r_brace: tok::RBrace,
64+
}
65+
66+
/// Trait implementation.
67+
///
68+
/// ```
69+
/// impl MyTrait for SomeType {
70+
/// fn a() -> bool {
71+
/// true
72+
/// }
73+
///
74+
/// fn b(n: 123) { }
75+
/// }
76+
/// ```
77+
#[derive(Clone, Debug)]
78+
pub struct TraitImplementation {
79+
#[expect(dead_code, reason = "token field")]
80+
pub tok_impl: tok::Impl,
81+
pub name: tok::Ident,
82+
#[expect(dead_code, reason = "named fields will be implemented with struct")]
83+
pub tok_for: tok::For,
84+
pub ty: CstType,
85+
#[expect(dead_code, reason = "token field")]
86+
pub tok_l_brace: tok::LBrace,
87+
pub methods: Vec<FunctionDeclaration>,
88+
#[expect(dead_code, reason = "token field")]
89+
pub tok_r_brace: tok::RBrace,
90+
}
91+
3592
mod function {
3693
use super::*;
3794

38-
/// Function declaration.
95+
/// Function signature.
3996
///
4097
/// ```
41-
/// fn some_function(parameter_a: usize, parameter_b: bool) -> f64 {
42-
/// // Statements...
43-
/// }
98+
/// fn some_function(parameter_a: usize, parameter_b: bool) -> f64
4499
/// ```
45100
#[derive(Clone, Debug)]
46-
pub struct FunctionDeclaration {
101+
pub struct FunctionSignature {
47102
#[expect(dead_code, reason = "token field")]
48103
pub tok_fn: tok::Fn,
49104
/// Name of the function.
@@ -56,6 +111,20 @@ mod function {
56111
pub tok_r_parenthesis: tok::RParenthesis,
57112
/// Optional return type for the function.
58113
pub return_ty: Option<FunctionReturnType>,
114+
}
115+
116+
/// Function declaration.
117+
///
118+
/// ```
119+
/// fn some_function(parameter_a: usize, parameter_b: bool) -> f64 {
120+
/// // Statements...
121+
/// }
122+
/// ```
123+
#[derive(Clone, Debug)]
124+
pub struct FunctionDeclaration {
125+
/// Signature of the function.
126+
pub signature: FunctionSignature,
127+
/// Implementation of the function.
59128
pub body: Block,
60129
}
61130

@@ -212,6 +281,7 @@ mod expression {
212281
Variable(Variable),
213282
Tuple(Tuple<Expression>),
214283
Field(Field),
284+
QualifiedPath(QualifiedPath),
215285
}
216286

217287
/// Assignment.
@@ -425,6 +495,29 @@ mod expression {
425495
Named(tok::Ident),
426496
}
427497

498+
/// Qualified path.
499+
///
500+
/// ```
501+
/// <Ty as Trait>::item
502+
/// ```
503+
#[derive(Clone, Debug)]
504+
pub struct QualifiedPath {
505+
#[expect(dead_code, reason = "named fields will be implemented with struct")]
506+
pub tok_l_angle: tok::LAngle,
507+
/// Self qualifier.
508+
pub ty: CstType,
509+
#[expect(dead_code, reason = "named fields will be implemented with struct")]
510+
pub tok_as: tok::As,
511+
/// Qualification.
512+
pub name: tok::Ident,
513+
#[expect(dead_code, reason = "named fields will be implemented with struct")]
514+
pub tok_r_angle: tok::RAngle,
515+
#[expect(dead_code, reason = "named fields will be implemented with struct")]
516+
pub tok_colon_colon: tok::ColonColon,
517+
/// Path item.
518+
pub item: tok::Ident,
519+
}
520+
428521
enum_conversion! {
429522
[Expression]
430523
Assign: Assign,
@@ -439,6 +532,7 @@ mod expression {
439532
Variable: Variable,
440533
Tuple: Tuple<Expression>,
441534
Field: Field,
535+
QualifiedPath: QualifiedPath,
442536
}
443537
}
444538

0 commit comments

Comments
 (0)