Skip to content

Commit

Permalink
Add Alias Node
Browse files Browse the repository at this point in the history
Define an alias node to parse, resolve and typecheck aliases

Signed-off-by: innocentzero <[email protected]>
  • Loading branch information
InnocentZero committed Dec 8, 2024
1 parent a13e77d commit 7c3ed88
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 11 deletions.
17 changes: 17 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ pub enum AstNode {
params: Option<NodeId>,
block: NodeId,
},
Alias {
new_name: NodeId,
old_name: NodeId,
},

/// Long flag ('--' + one or more letters)
FlagLong,
Expand Down Expand Up @@ -1292,6 +1296,8 @@ impl Parser {
code_body.push(self.continue_statement());
} else if self.is_keyword(b"break") {
code_body.push(self.break_statement());
} else if self.is_keyword(b"alias") {
code_body.push(self.alias_statement());
} else {
let exp_span_start = self.position();
let expression = self.expression_or_assignment();
Expand Down Expand Up @@ -1403,6 +1409,17 @@ impl Parser {
self.create_node(AstNode::Break, span_start, span_end)
}

pub fn alias_statement(&mut self) -> NodeId {
let _span = span!();
let span_start = self.position();
self.keyword(b"alias");
let new_name = self.name();
self.equals();
let old_name = self.name();
let span_end = self.get_span_end(old_name);
self.create_node(AstNode::Alias { new_name, old_name }, span_start, span_end)
}

pub fn is_operator(&mut self) -> bool {
match self.peek() {
Some(Token {
Expand Down
6 changes: 6 additions & 0 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ impl<'a> Resolver<'a> {

self.resolve_block(block, block_id, Some(def_scope));
}
AstNode::Alias {
new_name,
old_name: _,
} => {
self.define_decl(new_name);
}
AstNode::Params(ref params) => {
for param in params {
if let AstNode::Param { name, .. } = self.compiler.ast_nodes[param.0] {
Expand Down
38 changes: 27 additions & 11 deletions src/snapshots/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,30 @@ snapshot_kind: text
4: Variable (14 to 16) "$a"
5: Block(BlockId(0)) (12 to 18)
6: Def { name: NodeId(0), params: NodeId(3), return_ty: None, block: NodeId(5) } (0 to 18)
7: Name (20 to 25) "alias"
8: Name (26 to 29) "bar"
9: Garbage (30 to 31)
10: String (32 to 35) "foo"
11: Call { parts: [NodeId(7), NodeId(8), NodeId(9), NodeId(10)] } (26 to 35)
12: Name (37 to 40) "bar"
13: Int (41 to 42) "1"
14: Call { parts: [NodeId(12), NodeId(13)] } (41 to 42)
15: Block(BlockId(1)) (0 to 43)
==== COMPILER ERRORS ====
Error (NodeId 9): incomplete expression
7: Name (26 to 29) "bar"
8: Name (32 to 35) "foo"
9: Alias { new_name: NodeId(7), old_name: NodeId(8) } (20 to 35)
10: Name (37 to 40) "bar"
11: Int (41 to 42) "1"
12: Call { parts: [NodeId(10), NodeId(11)] } (41 to 42)
13: Block(BlockId(1)) (0 to 43)
==== SCOPE ====
0: Frame Scope, node_id: NodeId(13)
decls: [ bar: NodeId(7), foo: NodeId(0) ]
1: Frame Scope, node_id: NodeId(5)
variables: [ a: NodeId(1) ]
==== TYPES ====
0: unknown
1: unknown
2: any
3: none
4: unknown
5: unknown
6: none
7: unknown
8: unknown
9: none
10: unknown
11: int
12: any
13: any
24 changes: 24 additions & 0 deletions src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ impl<'a> Typechecker<'a> {
return_ty,
block,
} => self.typecheck_def(name, params, return_ty, block, node_id),
AstNode::Alias { new_name, old_name } => {
self.typecheck_alias(new_name, old_name, node_id)
}
AstNode::Call { ref parts } => self.typecheck_call(parts, node_id),
AstNode::For {
variable,
Expand Down Expand Up @@ -606,6 +609,27 @@ impl<'a> Typechecker<'a> {
}];
}

fn typecheck_alias(&mut self, new_name: NodeId, old_name: NodeId, node_id: NodeId) {
self.set_node_type_id(node_id, NONE_TYPE);

// set input/output types for the command
let decl_id_new = self
.compiler
.decl_resolution
.get(&new_name)
.expect("missing declared new name for alias");

let decl_id_old = self.compiler.decl_resolution.get(&old_name);

self.decl_types[decl_id_new.0] = decl_id_old.map_or(
vec![InOutType {
in_type: ANY_TYPE,
out_type: BYTE_STREAM_TYPE,
}],
|decl_id| self.decl_types[decl_id.0].clone(),
);
}

fn typecheck_call(&mut self, parts: &[NodeId], node_id: NodeId) {
let num_name_parts = if let Some(decl_id) = self.compiler.decl_resolution.get(&node_id) {
// TODO: The type should be `oneof<all_possible_output_types>`
Expand Down

0 comments on commit 7c3ed88

Please sign in to comment.