Skip to content

Commit 7dd03cb

Browse files
committed
refactor: start of abstacting away ast nodes into an enum.
1 parent faad477 commit 7dd03cb

File tree

8 files changed

+279
-130
lines changed

8 files changed

+279
-130
lines changed

crates/fuse-ast/src/ast.rs

-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,6 @@ pub enum BinaryOperatorKind {
353353
Modulo(Span),
354354
ShiftLeft(Span),
355355
ShiftRight(Span),
356-
Member(Span),
357356
}
358357

359358
impl GetSpan for BinaryOperatorKind {
@@ -380,7 +379,6 @@ impl GetSpan for BinaryOperatorKind {
380379
Self::Modulo(span) => span,
381380
Self::ShiftLeft(span) => span,
382381
Self::ShiftRight(span) => span,
383-
Self::Member(span) => span,
384382
};
385383
*span
386384
}

crates/fuse-ast/src/ast_node.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use crate::ast::*;
2+
3+
#[derive(Debug, Clone, Copy)]
4+
pub enum AstNode<'a> {
5+
// Primary nodes
6+
Chunk(&'a Chunk),
7+
Block(&'a Block),
8+
9+
// Statement related
10+
EmptyStatement(&'a EmptyStatement),
11+
ImplStatement(&'a ImplStatement),
12+
EnumDeclaration(&'a EnumDeclaration),
13+
StructDeclaration(&'a StructDeclaration),
14+
FunctionDeclaration(&'a Function),
15+
VariableDeclaration(&'a VariableDeclaration),
16+
17+
// expression related
18+
FunctionExpression(&'a Function),
19+
ArrayExpression(&'a ArrayExpression),
20+
ParenthesizedExpression(&'a ParenthesizedExpression),
21+
ConstructionExpression(&'a ConstructionExpression),
22+
StructConstructionExpression(&'a StructConstructionExpression),
23+
If(&'a If),
24+
Else(&'a Else),
25+
26+
// function inner nodes
27+
FunctionSignature(&'a FunctionSignature),
28+
FunctionParameters(&'a FunctionParameters),
29+
FunctionParameter(&'a FunctionParameter),
30+
FunctionBody(&'a FunctionBody),
31+
32+
EnumVariant(&'a EnumVariant),
33+
34+
StructField(&'a StructField),
35+
36+
VisibilityModifier(&'a VisibilityModifier),
37+
38+
// literals
39+
NumberLiteral(&'a NumberLiteral),
40+
StringLiteral(&'a StringLiteral),
41+
BooleanLiteral(&'a BooleanLiteral),
42+
43+
Identifier(&'a Identifier),
44+
45+
UnaryOperator(&'a UnaryOperator),
46+
BinaryOperator(&'a BinaryOperator),
47+
}

crates/fuse-ast/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
mod ast_factory;
2+
mod ast_node;
23
mod get_span;
34
mod precedence;
45

56
pub mod ast;
67

78
pub use ast::*;
89
pub use ast_factory::*;
10+
pub use ast_node::*;
911
pub use get_span::*;
1012
pub use precedence::*;

crates/fuse-parser/src/parsers/operators.rs

-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ impl<'a> Parser<'a> {
8181
Percent => Modulo
8282
LShift => ShiftLeft
8383
RShift => ShiftRight
84-
Dot => Member
8584
}
8685
}
8786

crates/fuse-semantic/src/lib.rs

+68-64
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::collections::HashMap;
22

33
use fuse_ast::{
4-
Atom, BinaryOperator, BinaryOperatorKind, BindingPatternKind, CallExpression, Chunk,
5-
Expression, Function, Identifier, VariableDeclaration,
4+
Atom, BindingPatternKind, Chunk, Function, Identifier, MemberExpression, MemberExpressionLHS,
5+
MemberExpressionRHS, VariableDeclaration,
66
};
77
use fuse_common::ReferenceType;
88
use fuse_visitor::{
9-
walk_binary_operator_mut, walk_call_expression_mut, walk_function_mut,
10-
walk_variable_declaration_mut, ScopeVisitor, VisitorMut,
9+
walk_function_mut, walk_member_expression_mut, walk_variable_declaration_mut, ScopeVisitor,
10+
VisitorMut,
1111
};
1212

1313
#[derive(Debug, PartialEq, Clone, Copy)]
@@ -31,9 +31,9 @@ impl PartialEq<ReferenceType> for ScopeId {
3131
}
3232
}
3333

34-
struct IdentifierMap(HashMap<Atom, ReferenceType>);
34+
struct IdentDeclMap(HashMap<Atom, ReferenceType>);
3535

36-
impl IdentifierMap {
36+
impl IdentDeclMap {
3737
fn new() -> Self {
3838
Self(HashMap::new())
3939
}
@@ -54,30 +54,31 @@ enum ReferenceKind {
5454

5555
struct ScopeTree {
5656
current: ScopeId,
57-
identifier_maps: Vec<IdentifierMap>,
57+
ident_decl_maps: Vec<IdentDeclMap>,
5858
/// Maps between `ReferenceId` and `ReferenceKind`
5959
reference_kinds: Vec<ReferenceKind>,
6060
parent_ids: Vec<ScopeId>,
6161
}
6262

63+
/// Tree operations for `ScopeTree`
6364
impl ScopeTree {
6465
fn root_scope() -> Self {
6566
Self {
6667
current: ScopeId(0),
6768
parent_ids: vec![ScopeId(0)],
68-
identifier_maps: vec![IdentifierMap::new()],
69+
ident_decl_maps: vec![IdentDeclMap::new()],
6970
reference_kinds: Vec::new(),
7071
}
7172
}
7273

7374
fn push_stack(&mut self) -> ScopeId {
74-
self.identifier_maps.push(IdentifierMap::new());
75+
self.ident_decl_maps.push(IdentDeclMap::new());
7576
self.parent_ids.push(self.current);
7677

7778
// length of all arrays should be same.
78-
debug_assert!(self.identifier_maps.len() == self.parent_ids.len());
79+
debug_assert!(self.ident_decl_maps.len() == self.parent_ids.len());
7980

80-
self.current = ScopeId(self.identifier_maps.len() - 1);
81+
self.current = ScopeId(self.ident_decl_maps.len() - 1);
8182
self.current
8283
}
8384

@@ -90,13 +91,32 @@ impl ScopeTree {
9091
self.current = self.parent();
9192
}
9293

94+
fn parent(&self) -> ScopeId {
95+
assert_ne!(
96+
self.current, 0,
97+
"Attempt to access the root scope's parent."
98+
);
99+
self.parent_ids[self.current.as_index()]
100+
}
101+
102+
fn parent_of(&self, children_id: ScopeId) -> ScopeId {
103+
assert_ne!(
104+
self.current, 0,
105+
"Attempt to access the root scope's parent."
106+
);
107+
self.parent_ids[children_id.as_index()]
108+
}
109+
}
110+
111+
/// Identifier operations for `ScopeTree`
112+
impl ScopeTree {
93113
/// Get an identifier reference from current scope or its parents.
94114
/// This function is implemented using loops instead of recursion.
95-
fn identifier_reference(&mut self, atom: &Atom) -> Option<ReferenceType> {
115+
fn scope_identifier_reference(&mut self, atom: &Atom) -> Option<ReferenceType> {
96116
let mut scope_id = self.current;
97117
let mut reference;
98118
loop {
99-
reference = self.identifier_maps[scope_id.as_index()].get(atom);
119+
reference = self.ident_decl_maps[scope_id.as_index()].get(atom);
100120

101121
if reference.is_some() || scope_id.is_root() {
102122
break;
@@ -109,29 +129,20 @@ impl ScopeTree {
109129

110130
/// Set a `ReferenceType` for the given identifier's `Atom` in the current scope.
111131
/// Would return the last `ReferenceType` if we are shadowing it.
112-
fn set_identifier_reference(
132+
fn set_scope_identifier_reference(
113133
&mut self,
114134
atom: Atom,
115135
ref_id: ReferenceType,
116-
ref_kind: ReferenceKind,
117136
) -> Option<ReferenceType> {
118-
self.identifier_maps[self.current.as_index()].insert(atom, ref_id)
119-
}
120-
121-
fn parent(&self) -> ScopeId {
122-
assert_ne!(
123-
self.current, 0,
124-
"Attempt to access the root scope's parent."
125-
);
126-
self.parent_ids[self.current.as_index()]
137+
self.ident_decl_maps[self.current.as_index()].insert(atom, ref_id)
127138
}
128139

129-
fn parent_of(&self, children_id: ScopeId) -> ScopeId {
130-
assert_ne!(
131-
self.current, 0,
132-
"Attempt to access the root scope's parent."
133-
);
134-
self.parent_ids[children_id.as_index()]
140+
fn member_identifier_reference(
141+
&mut self,
142+
atom: Atom,
143+
ref_id: ReferenceType,
144+
) -> Option<ReferenceType> {
145+
self.ident_decl_maps[self.current.as_index()].insert(atom, ref_id)
135146
}
136147
}
137148

@@ -159,23 +170,29 @@ impl<'ast> Semantic<'ast> {
159170

160171
fn declare_identifier(&mut self, ident: &Identifier) {
161172
self.last_reference += 1;
162-
self.scope.set_identifier_reference(
163-
ident.name.clone(),
164-
self.last_reference,
165-
ReferenceKind::Scope,
166-
);
173+
self.scope
174+
.set_scope_identifier_reference(ident.name.clone(), self.last_reference);
167175
ident.reference.set(Some(self.last_reference))
168176
}
169177

170178
fn reference_scope_identifier(&mut self, ident: &Identifier) {
171-
let reference = self.scope.identifier_reference(&ident.name);
179+
let reference = self.scope.scope_identifier_reference(&ident.name);
172180
ident.reference.set(reference)
173181
}
174182

175-
fn reference_member_identifier(&mut self, ident: &Identifier, sup: Option<&Identifier>) {
176-
let reference = self.scope.identifier_reference(&ident.name);
183+
fn resolve_member_identifier(&mut self, ident: &Identifier, sup: Option<&Identifier>) {
184+
let Some(sup) = sup else {
185+
return self.declare_member_identifier(ident, None);
186+
};
187+
let reference = self.scope.scope_identifier_reference(&ident.name);
188+
ident.reference.set(reference);
189+
// todo!()
190+
}
191+
192+
fn declare_member_identifier(&mut self, ident: &Identifier, sup: Option<&Identifier>) {
193+
let reference = self.scope.scope_identifier_reference(&ident.name);
177194
ident.reference.set(reference);
178-
todo!()
195+
// todo!()
179196
}
180197
}
181198

@@ -205,33 +222,20 @@ impl<'ast> VisitorMut<'ast> for Semantic<'ast> {
205222
walk_function_mut(self, decl)
206223
}
207224

208-
fn visit_binary_operator_mut(&mut self, op: &'ast mut BinaryOperator) {
209-
match &op.kind {
210-
BinaryOperatorKind::Member(_) => {
211-
println!("{:?}", op);
212-
let rhs = match &op.rhs {
213-
Expression::Identifier(rhs) => rhs,
214-
Expression::BinaryOperator(op) => match &**op {
215-
BinaryOperator {
216-
kind: BinaryOperatorKind::Member(..),
217-
lhs: Expression::Identifier(lhs),
218-
..
219-
} => lhs,
220-
BinaryOperator {
221-
kind: BinaryOperatorKind::Member(..),
222-
lhs: Expression::ParenthesizedExpression(expr),
223-
..
224-
} => todo!(),
225-
_ => {
226-
todo!()
227-
}
228-
},
229-
_ => panic!("Right hand side of a member(.) operator should be an identifier"),
230-
};
225+
fn visit_member_expression_mut(&mut self, member: &'ast mut MemberExpression) {
226+
let lhs = member.lhs.as_ref();
227+
let rhs = member.rhs.as_ref();
228+
let sup = match lhs {
229+
MemberExpressionLHS::Identifier(ident) => {
230+
self.reference_scope_identifier(ident);
231+
Some(ident)
231232
}
232-
_ => {}
233+
_ => None,
234+
};
235+
if let MemberExpressionRHS::Identifier(ident) = rhs {
236+
self.resolve_member_identifier(ident, sup)
233237
}
234-
walk_binary_operator_mut(self, op)
238+
walk_member_expression_mut(self, member)
235239
}
236240
}
237241

crates/fuse-visitor/src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
mod node_visitor;
12
mod scope_visitor;
23
mod visitor;
34
mod visitor_mut;
45

6+
pub use node_visitor::*;
57
pub use scope_visitor::*;
68
pub use visitor::*;
79
pub use visitor_mut::*;
@@ -26,9 +28,9 @@ macro_rules! visit_list {
2628

2729
#[macro_export]
2830
macro_rules! visit_scope {
29-
($visitor:ident => $block:block) => {
31+
($visitor:ident => $block:expr) => {
3032
$visitor.enter_scope();
31-
$block
33+
$block;
3234
$visitor.leave_scope();
3335
};
3436
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use fuse_ast::AstNode;
2+
3+
pub trait NodeVisitor {
4+
fn enter_node(&mut self, node: AstNode) {}
5+
fn leave_node(&mut self, node: AstNode) {}
6+
}

0 commit comments

Comments
 (0)