Skip to content

Commit dcc76ff

Browse files
committed
Add Alias Node
Define an alias node to parse, resolve and typecheck aliases Signed-off-by: innocentzero <[email protected]>
1 parent 3960f5f commit dcc76ff

File tree

6 files changed

+72
-14
lines changed

6 files changed

+72
-14
lines changed

src/parser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ pub enum AstNode {
136136
params: Option<NodeId>,
137137
block: NodeId,
138138
},
139+
Alias {
140+
new_name: NodeId,
141+
old_name: NodeId,
142+
},
139143

140144
/// Long flag ('--' + one or more letters)
141145
FlagLong,
@@ -1292,6 +1296,8 @@ impl Parser {
12921296
code_body.push(self.continue_statement());
12931297
} else if self.is_keyword(b"break") {
12941298
code_body.push(self.break_statement());
1299+
} else if self.is_keyword(b"alias") {
1300+
code_body.push(self.alias_statement());
12951301
} else {
12961302
let exp_span_start = self.position();
12971303
let expression = self.expression_or_assignment();
@@ -1403,6 +1409,17 @@ impl Parser {
14031409
self.create_node(AstNode::Break, span_start, span_end)
14041410
}
14051411

1412+
pub fn alias_statement(&mut self) -> NodeId {
1413+
let _span = span!();
1414+
let span_start = self.position();
1415+
self.keyword(b"alias");
1416+
let new_name = self.name();
1417+
self.equals();
1418+
let old_name = self.name();
1419+
let span_end = self.get_span_end(old_name);
1420+
self.create_node(AstNode::Alias { new_name, old_name }, span_start, span_end)
1421+
}
1422+
14061423
pub fn is_operator(&mut self) -> bool {
14071424
match self.peek() {
14081425
Some(Token {

src/resolver.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ impl<'a> Resolver<'a> {
238238

239239
self.resolve_block(block, block_id, Some(def_scope));
240240
}
241+
AstNode::Alias {
242+
new_name,
243+
old_name: _,
244+
} => {
245+
self.define_decl(new_name);
246+
}
241247
AstNode::Params(ref params) => {
242248
for param in params {
243249
if let AstNode::Param { name, .. } = self.compiler.ast_nodes[param.0] {

src/snapshots/[email protected]

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,30 @@ snapshot_kind: text
1212
4: Variable (14 to 16) "$a"
1313
5: Block(BlockId(0)) (12 to 18)
1414
6: Def { name: NodeId(0), params: NodeId(3), return_ty: None, block: NodeId(5) } (0 to 18)
15-
7: Name (20 to 25) "alias"
16-
8: Name (26 to 29) "bar"
17-
9: Garbage (30 to 31)
18-
10: String (32 to 35) "foo"
19-
11: Call { parts: [NodeId(7), NodeId(8), NodeId(9), NodeId(10)] } (26 to 35)
20-
12: Name (37 to 40) "bar"
21-
13: Int (41 to 42) "1"
22-
14: Call { parts: [NodeId(12), NodeId(13)] } (41 to 42)
23-
15: Block(BlockId(1)) (0 to 43)
24-
==== COMPILER ERRORS ====
25-
Error (NodeId 9): incomplete expression
15+
7: Name (26 to 29) "bar"
16+
8: Name (32 to 35) "foo"
17+
9: Alias { new_name: NodeId(7), old_name: NodeId(8) } (20 to 35)
18+
10: Name (37 to 40) "bar"
19+
11: Int (41 to 42) "1"
20+
12: Call { parts: [NodeId(10), NodeId(11)] } (41 to 42)
21+
13: Block(BlockId(1)) (0 to 43)
22+
==== SCOPE ====
23+
0: Frame Scope, node_id: NodeId(13)
24+
decls: [ bar: NodeId(7), foo: NodeId(0) ]
25+
1: Frame Scope, node_id: NodeId(5)
26+
variables: [ a: NodeId(1) ]
27+
==== TYPES ====
28+
0: unknown
29+
1: unknown
30+
2: any
31+
3: none
32+
4: unknown
33+
5: unknown
34+
6: none
35+
7: unknown
36+
8: unknown
37+
9: none
38+
10: unknown
39+
11: int
40+
12: any
41+
13: any

src/snapshots/new_nu_parser__test__node_output@for_break_continue.nu.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ snapshot_kind: text
5959
11: bool
6060
12: unknown
6161
13: unknown
62-
14: oneof<none, unknown>
62+
14: oneof<unknown, none>
6363
15: int
6464
16: forbidden
6565
17: int

src/snapshots/[email protected]

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ snapshot_kind: text
3838
0: int
3939
1: int
4040
2: none
41-
3: oneof<string, closure, ()>
41+
3: oneof<string, (), closure>
4242
4: int
4343
5: int
4444
6: string
@@ -56,7 +56,7 @@ snapshot_kind: text
5656
18: ()
5757
19: string
5858
20: ()
59-
21: oneof<string, closure, ()>
59+
21: oneof<string, (), closure>
6060
22: none
6161
23: none
6262
==== TYPE ERRORS ====

src/typechecker.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ impl<'a> Typechecker<'a> {
350350
return_ty,
351351
block,
352352
} => self.typecheck_def(name, params, return_ty, block, node_id),
353+
AstNode::Alias { new_name, old_name } => {
354+
self.typecheck_alias(new_name, old_name, node_id)
355+
}
353356
AstNode::Call { ref parts } => self.typecheck_call(parts, node_id),
354357
AstNode::For {
355358
variable,
@@ -604,6 +607,22 @@ impl<'a> Typechecker<'a> {
604607
}];
605608
}
606609

610+
fn typecheck_alias(&mut self, new_name: NodeId, old_name: NodeId, node_id: NodeId) {
611+
self.set_node_type_id(node_id, NONE_TYPE);
612+
613+
// set input/output types for the command
614+
let decl_id_new = self
615+
.compiler
616+
.decl_resolution
617+
.get(&new_name)
618+
.expect("missing declared new name for alias");
619+
620+
let decl_id_old = self.compiler.decl_resolution.get(&old_name);
621+
622+
self.decl_types[decl_id_new.0] =
623+
decl_id_old.map_or(vec![], |decl_id| self.decl_types[decl_id.0].clone());
624+
}
625+
607626
fn typecheck_call(&mut self, parts: &[NodeId], node_id: NodeId) {
608627
let num_name_parts = if let Some(decl_id) = self.compiler.decl_resolution.get(&node_id) {
609628
// TODO: The type should be `oneof<all_possible_output_types>`

0 commit comments

Comments
 (0)