From 0bf4b2a74ddcb04de5a7509b6c586b0925a0326c Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 17 Dec 2024 12:09:50 +0530 Subject: [PATCH 1/9] Add unit parsing Signed-off-by: innocentzero --- src/parser.rs | 3 +++ src/typechecker.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index d990281..6b44aac 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -73,6 +73,9 @@ pub enum AstNode { // Empty values Null, + // Unit / Null + Unit, + // Operators Equal, NotEqual, diff --git a/src/typechecker.rs b/src/typechecker.rs index 27dd9f9..d44ef23 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -201,6 +201,9 @@ impl<'a> Typechecker<'a> { AstNode::String => { self.set_node_type_id(node_id, STRING_TYPE); } + AstNode::Unit => { + self.set_node_type_id(node_id, NOTHING_TYPE); + } AstNode::Params(ref params) => { for param in params { self.typecheck_node(*param); From 2a87b72b2d0253c7d4f10aa25aa3b7b2c3611f7c Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 17 Dec 2024 12:12:08 +0530 Subject: [PATCH 2/9] Add while loop flag structure Signed-off-by: innocentzero --- src/parser.rs | 21 ++++++++++++++++++--- src/resolver.rs | 5 ++++- src/typechecker.rs | 26 +++++++++++++++----------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 6b44aac..5565a0b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -109,8 +109,9 @@ pub enum AstNode { is_mutable: bool, }, While { - condition: NodeId, - block: NodeId, + cond_block: Option<(NodeId, NodeId)>, + short_flag: Option, + long_flag: Option, }, For { variable: NodeId, @@ -1149,11 +1150,25 @@ impl Parser { let span_start = self.position(); self.keyword(b"while"); + if self.is_operator() { + // TODO: flag parsing + self.error("WIP: Flags on while are not supported yet"); + self.next(); + } + let condition = self.expression(); let block = self.block(BlockContext::Curlies); let span_end = self.get_span_end(block); - self.create_node(AstNode::While { condition, block }, span_start, span_end) + self.create_node( + AstNode::While { + cond_block: Some((condition, block)), + short_flag: None, + long_flag: None, + }, + span_start, + span_end, + ) } pub fn for_statement(&mut self) -> NodeId { diff --git a/src/resolver.rs b/src/resolver.rs index 4d32b38..093cb1b 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -256,7 +256,10 @@ impl<'a> Resolver<'a> { self.resolve_node(initializer); self.define_variable(variable_name, is_mutable) } - AstNode::While { condition, block } => { + AstNode::While { + cond_block: Some((condition, block)), + .. + } => { self.resolve_node(condition); self.resolve_node(block); } diff --git a/src/typechecker.rs b/src/typechecker.rs index d44ef23..4542d24 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -383,20 +383,24 @@ impl<'a> Typechecker<'a> { self.set_node_type_id(node_id, NONE_TYPE); } } - AstNode::While { condition, block } => { - self.typecheck_node(block); - if self.type_id_of(block) != NONE_TYPE { - self.error("Blocks in looping constructs cannot return values", block); - } + AstNode::While { cond_block, .. } => { + if let Some((condition, block)) = cond_block { + self.typecheck_node(block); + if self.type_id_of(block) != NONE_TYPE { + self.error("Blocks in looping constructs cannot return values", block); + } - self.typecheck_node(condition); + self.typecheck_node(condition); - // the condition should always evaluate to a boolean - if self.type_of(condition) != Type::Bool { - self.error("The condition for while loop is not a boolean", condition); - self.set_node_type_id(node_id, ERROR_TYPE); + // the condition should always evaluate to a boolean + if self.type_of(condition) != Type::Bool { + self.error("The condition for while loop is not a boolean", condition); + self.set_node_type_id(node_id, ERROR_TYPE); + } else { + self.set_node_type_id(node_id, self.type_id_of(block)); + } } else { - self.set_node_type_id(node_id, self.type_id_of(block)); + self.set_node_type_id(node_id, NONE_TYPE); } } AstNode::Match { From 74d6126857ed089e9a2836d571875cd0a2e36207 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 17 Dec 2024 12:12:54 +0530 Subject: [PATCH 3/9] Add alias support to the compiler Signed-off-by: innocentzero --- src/parser.rs | 25 +++++++++++++++++++++++++ src/resolver.rs | 6 ++++++ src/typechecker.rs | 24 ++++++++++++++++++++++++ tests/alias.nu | 3 +++ 4 files changed, 58 insertions(+) create mode 100644 tests/alias.nu diff --git a/src/parser.rs b/src/parser.rs index 5565a0b..9f1fd66 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -141,6 +141,10 @@ pub enum AstNode { params: Option, block: NodeId, }, + Alias { + new_name: NodeId, + old_name: NodeId, + }, /// Long flag ('--' + one or more letters) FlagLong, @@ -1116,6 +1120,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(); @@ -1241,6 +1247,25 @@ 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 = if self.is_string() { + self.string() + } else { + self.name() + }; + self.equals(); + let old_name = if self.is_string() { + self.string() + } else { + 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 { let (token, span) = self.tokens.peek(); diff --git a/src/resolver.rs b/src/resolver.rs index 093cb1b..3fa52a3 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -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] { diff --git a/src/typechecker.rs b/src/typechecker.rs index 4542d24..e3b5e4e 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -351,6 +351,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, @@ -616,6 +619,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` diff --git a/tests/alias.nu b/tests/alias.nu new file mode 100644 index 0000000..639d233 --- /dev/null +++ b/tests/alias.nu @@ -0,0 +1,3 @@ +alias "fancy alias" = foo + +fancy alias From 85833d76c743a45a80e8f06b40b5981271faeab8 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 17 Dec 2024 12:13:26 +0530 Subject: [PATCH 4/9] fix match parsing Signed-off-by: innocentzero --- src/parser.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 9f1fd66..250784a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -779,6 +779,10 @@ impl Parser { let pattern_result = self.simple_expression(BarewordContext::String); + if self.is_comma() { + self.next(); + } + match_arms.push((pattern, pattern_result)); } else if self.is_newline() { self.tokens.advance(); From e837125761d979be122a69daf525365115b56495 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 17 Dec 2024 12:18:45 +0530 Subject: [PATCH 5/9] run tests Signed-off-by: innocentzero --- ...nu_parser__test__node_output@alias.nu.snap | 36 ++++---- ...est__node_output@binary_ops_spaces.nu.snap | 1 + ..._parser__test__node_output@closure.nu.snap | 1 + ...parser__test__node_output@closure2.nu.snap | 1 + ...r__test__node_output@invalid_range.nu.snap | 1 + ...__test__node_output@invalid_record.nu.snap | 1 + ...nu_parser__test__node_output@match.nu.snap | 84 +++++++++++-------- ..._nu_parser__test__node_output@mut_.nu.snap | 1 + ...nu_parser__test__node_output@while.nu.snap | 2 +- 9 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/snapshots/new_nu_parser__test__node_output@alias.nu.snap b/src/snapshots/new_nu_parser__test__node_output@alias.nu.snap index 79badab..02149e2 100644 --- a/src/snapshots/new_nu_parser__test__node_output@alias.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@alias.nu.snap @@ -5,21 +5,21 @@ input_file: tests/alias.nu snapshot_kind: text --- ==== COMPILER ==== -0: Name (4 to 7) "foo" -1: Name (9 to 10) "a" -2: Param { name: NodeId(1), ty: None } (9 to 10) -3: Params([NodeId(2)]) (8 to 11) -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 +0: String (6 to 19) ""fancy alias"" +1: Name (22 to 25) "foo" +2: Alias { new_name: NodeId(0), old_name: NodeId(1) } (0 to 25) +3: Name (27 to 32) "fancy" +4: Name (33 to 38) "alias" +5: Call { parts: [NodeId(3), NodeId(4)] } (33 to 38) +6: Block(BlockId(0)) (0 to 39) +==== SCOPE ==== +0: Frame Scope, node_id: NodeId(6) + decls: [ fancy alias: NodeId(0) ] +==== TYPES ==== +0: unknown +1: unknown +2: () +3: unknown +4: string +5: stream +6: stream diff --git a/src/snapshots/new_nu_parser__test__node_output@binary_ops_spaces.nu.snap b/src/snapshots/new_nu_parser__test__node_output@binary_ops_spaces.nu.snap index 29f0028..bfe066d 100644 --- a/src/snapshots/new_nu_parser__test__node_output@binary_ops_spaces.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@binary_ops_spaces.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/binary_ops_spaces.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Int (0 to 1) "1" diff --git a/src/snapshots/new_nu_parser__test__node_output@closure.nu.snap b/src/snapshots/new_nu_parser__test__node_output@closure.nu.snap index 4ef7169..00ef4a6 100644 --- a/src/snapshots/new_nu_parser__test__node_output@closure.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@closure.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/closure.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Name (3 to 4) "a" diff --git a/src/snapshots/new_nu_parser__test__node_output@closure2.nu.snap b/src/snapshots/new_nu_parser__test__node_output@closure2.nu.snap index a841564..f192ad4 100644 --- a/src/snapshots/new_nu_parser__test__node_output@closure2.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@closure2.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/closure2.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Variable (4 to 6) "$a" diff --git a/src/snapshots/new_nu_parser__test__node_output@invalid_range.nu.snap b/src/snapshots/new_nu_parser__test__node_output@invalid_range.nu.snap index 2a4dccb..c5d3a4c 100644 --- a/src/snapshots/new_nu_parser__test__node_output@invalid_range.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@invalid_range.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/invalid_range.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Int (0 to 1) "1" diff --git a/src/snapshots/new_nu_parser__test__node_output@invalid_record.nu.snap b/src/snapshots/new_nu_parser__test__node_output@invalid_record.nu.snap index a439045..f8b4411 100644 --- a/src/snapshots/new_nu_parser__test__node_output@invalid_record.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@invalid_record.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/invalid_record.nu +snapshot_kind: text --- ==== COMPILER ==== 0: String (2 to 3) "a" diff --git a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap index 296fd4a..e4eff75 100644 --- a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap @@ -12,38 +12,52 @@ snapshot_kind: text 4: Variable (27 to 29) "$x" 5: Int (34 to 35) "1" 6: String (39 to 44) ""one"" -7: Garbage (44 to 45) -8: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(7), is_mutable: false } (11 to 45) -9: Int (48 to 49) "2" -10: Garbage (50 to 52) -11: Variable (63 to 64) "w" -12: Int (67 to 68) "3" -13: Let { variable_name: NodeId(11), ty: None, initializer: NodeId(12), is_mutable: false } (59 to 68) -14: Int (73 to 74) "2" -15: Plus (75 to 76) -16: Variable (77 to 79) "$w" -17: BinaryOp { lhs: NodeId(14), op: NodeId(15), rhs: NodeId(16) } (73 to 79) -18: Block(BlockId(0)) (59 to 82) -19: Closure { params: None, block: NodeId(18) } (53 to 83) -20: Garbage (83 to 84) -21: Int (87 to 88) "3" -22: Garbage (89 to 91) -23: Null (92 to 96) -24: Garbage (96 to 97) -25: Name (100 to 101) "_" -26: Garbage (102 to 104) -27: Garbage (106 to 107) -28: Garbage (107 to 108) -29: Call { parts: [NodeId(25), NodeId(26), NodeId(27)] } (102 to 108) -30: Garbage (109 to 110) -31: Block(BlockId(1)) (0 to 111) -==== COMPILER ERRORS ==== -Error (NodeId 7): expected match arm in match -Error (NodeId 10): incomplete expression -Error (NodeId 20): incomplete expression -Error (NodeId 22): incomplete expression -Error (NodeId 24): incomplete expression -Error (NodeId 26): incomplete expression -Error (NodeId 27): incomplete expression -Error (NodeId 28): expected: right paren ')' -Error (NodeId 30): incomplete expression +7: Int (48 to 49) "2" +8: Variable (63 to 64) "w" +9: Int (67 to 68) "3" +10: Let { variable_name: NodeId(8), ty: None, initializer: NodeId(9), is_mutable: false } (59 to 68) +11: Int (73 to 74) "2" +12: Plus (75 to 76) +13: Variable (77 to 79) "$w" +14: BinaryOp { lhs: NodeId(11), op: NodeId(12), rhs: NodeId(13) } (73 to 79) +15: Block(BlockId(0)) (59 to 82) +16: Closure { params: None, block: NodeId(15) } (53 to 83) +17: Int (87 to 88) "3" +18: Null (92 to 96) +19: String (100 to 101) "_" +20: Unit (105 to 107) +21: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) +22: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(21), is_mutable: false } (11 to 110) +23: Block(BlockId(1)) (0 to 111) +==== SCOPE ==== +0: Frame Scope, node_id: NodeId(23) + variables: [ foo: NodeId(3), x: NodeId(0) ] +1: Frame Scope, node_id: NodeId(15) + variables: [ w: NodeId(8) ] +==== TYPES ==== +0: int +1: int +2: () +3: oneof +4: int +5: int +6: string +7: int +8: int +9: int +10: () +11: int +12: forbidden +13: int +14: int +15: int +16: closure +17: int +18: nothing +19: string +20: nothing +21: oneof +22: () +23: () +==== TYPE ERRORS ==== +Error (NodeId 19): The types do not match diff --git a/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap b/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap index 1c9b477..3573c8c 100644 --- a/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/mut_.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Variable (4 to 5) "x" diff --git a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap index 520476d..b3ad510 100644 --- a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap @@ -17,7 +17,7 @@ snapshot_kind: text 9: Int (32 to 33) "1" 10: BinaryOp { lhs: NodeId(7), op: NodeId(8), rhs: NodeId(9) } (26 to 33) 11: Block(BlockId(0)) (22 to 35) -12: While { condition: NodeId(6), block: NodeId(11) } (10 to 35) +12: While { cond_block: Some((NodeId(6), NodeId(11))), short_flag: None, long_flag: None } (10 to 35) 13: Block(BlockId(1)) (0 to 36) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(13) From e9c8fde3833542caa0e97fd829403fbd1db73a60 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Tue, 24 Dec 2024 04:32:10 +0530 Subject: [PATCH 6/9] Remove Unit and parse empty subexpression Signed-off-by: innocentzero --- src/parser.rs | 13 +++++++------ .../new_nu_parser__test__node_output@match.nu.snap | 7 ++++--- src/typechecker.rs | 3 --- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 250784a..6528ab6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -73,9 +73,6 @@ pub enum AstNode { // Empty values Null, - // Unit / Null - Unit, - // Operators Equal, NotEqual, @@ -381,7 +378,11 @@ impl Parser { Token::LCurly => self.record_or_closure(), Token::LParen => { self.tokens.advance(); - let output = self.expression(); + let output = if self.tokens.peek().0 == Token::RParen { + self.error("use null instead of ()") + } else { + self.expression() + }; self.rparen(); output } @@ -780,7 +781,7 @@ impl Parser { let pattern_result = self.simple_expression(BarewordContext::String); if self.is_comma() { - self.next(); + self.tokens.advance(); } match_arms.push((pattern, pattern_result)); @@ -1163,7 +1164,7 @@ impl Parser { if self.is_operator() { // TODO: flag parsing self.error("WIP: Flags on while are not supported yet"); - self.next(); + self.tokens.advance(); } let condition = self.expression(); diff --git a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap index e4eff75..f76aac6 100644 --- a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap @@ -25,15 +25,16 @@ snapshot_kind: text 17: Int (87 to 88) "3" 18: Null (92 to 96) 19: String (100 to 101) "_" -20: Unit (105 to 107) +20: Block(BlockId(1)) (105 to 107) 21: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) 22: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(21), is_mutable: false } (11 to 110) -23: Block(BlockId(1)) (0 to 111) +23: Block(BlockId(2)) (0 to 111) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(23) variables: [ foo: NodeId(3), x: NodeId(0) ] 1: Frame Scope, node_id: NodeId(15) variables: [ w: NodeId(8) ] +2: Frame Scope, node_id: NodeId(20) (empty) ==== TYPES ==== 0: int 1: int @@ -55,7 +56,7 @@ snapshot_kind: text 17: int 18: nothing 19: string -20: nothing +20: () 21: oneof 22: () 23: () diff --git a/src/typechecker.rs b/src/typechecker.rs index e3b5e4e..76dc682 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -201,9 +201,6 @@ impl<'a> Typechecker<'a> { AstNode::String => { self.set_node_type_id(node_id, STRING_TYPE); } - AstNode::Unit => { - self.set_node_type_id(node_id, NOTHING_TYPE); - } AstNode::Params(ref params) => { for param in params { self.typecheck_node(*param); From 359978203e2bb03a4844f486eb497fcedfb28d4e Mon Sep 17 00:00:00 2001 From: innocentzero Date: Sun, 29 Dec 2024 02:48:14 +0530 Subject: [PATCH 7/9] Add error for () Signed-off-by: innocentzero --- ...nu_parser__test__node_output@match.nu.snap | 45 ++++--------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap index f76aac6..8cc7753 100644 --- a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap @@ -25,40 +25,11 @@ snapshot_kind: text 17: Int (87 to 88) "3" 18: Null (92 to 96) 19: String (100 to 101) "_" -20: Block(BlockId(1)) (105 to 107) -21: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) -22: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(21), is_mutable: false } (11 to 110) -23: Block(BlockId(2)) (0 to 111) -==== SCOPE ==== -0: Frame Scope, node_id: NodeId(23) - variables: [ foo: NodeId(3), x: NodeId(0) ] -1: Frame Scope, node_id: NodeId(15) - variables: [ w: NodeId(8) ] -2: Frame Scope, node_id: NodeId(20) (empty) -==== TYPES ==== -0: int -1: int -2: () -3: oneof -4: int -5: int -6: string -7: int -8: int -9: int -10: () -11: int -12: forbidden -13: int -14: int -15: int -16: closure -17: int -18: nothing -19: string -20: () -21: oneof -22: () -23: () -==== TYPE ERRORS ==== -Error (NodeId 19): The types do not match +20: Garbage (106 to 107) +21: Garbage (107 to 108) +22: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) +23: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(22), is_mutable: false } (11 to 110) +24: Block(BlockId(1)) (0 to 111) +==== COMPILER ERRORS ==== +Error (NodeId 20): use null instead of () +Error (NodeId 21): expected: right paren ')' From c8219cb166a076cdb4af761f334cbde5a186a048 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Sun, 29 Dec 2024 02:40:22 +0530 Subject: [PATCH 8/9] Remove flags from While node Signed-off-by: innocentzero --- src/parser.rs | 15 +++-------- src/resolver.rs | 5 +--- ...nu_parser__test__node_output@while.nu.snap | 2 +- src/typechecker.rs | 26 ++++++++----------- 4 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 6528ab6..5dff510 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -106,9 +106,8 @@ pub enum AstNode { is_mutable: bool, }, While { - cond_block: Option<(NodeId, NodeId)>, - short_flag: Option, - long_flag: Option, + condition: NodeId, + block: NodeId, }, For { variable: NodeId, @@ -1171,15 +1170,7 @@ impl Parser { let block = self.block(BlockContext::Curlies); let span_end = self.get_span_end(block); - self.create_node( - AstNode::While { - cond_block: Some((condition, block)), - short_flag: None, - long_flag: None, - }, - span_start, - span_end, - ) + self.create_node(AstNode::While { condition, block }, span_start, span_end) } pub fn for_statement(&mut self) -> NodeId { diff --git a/src/resolver.rs b/src/resolver.rs index 3fa52a3..537d786 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -262,10 +262,7 @@ impl<'a> Resolver<'a> { self.resolve_node(initializer); self.define_variable(variable_name, is_mutable) } - AstNode::While { - cond_block: Some((condition, block)), - .. - } => { + AstNode::While { condition, block } => { self.resolve_node(condition); self.resolve_node(block); } diff --git a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap index b3ad510..520476d 100644 --- a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap @@ -17,7 +17,7 @@ snapshot_kind: text 9: Int (32 to 33) "1" 10: BinaryOp { lhs: NodeId(7), op: NodeId(8), rhs: NodeId(9) } (26 to 33) 11: Block(BlockId(0)) (22 to 35) -12: While { cond_block: Some((NodeId(6), NodeId(11))), short_flag: None, long_flag: None } (10 to 35) +12: While { condition: NodeId(6), block: NodeId(11) } (10 to 35) 13: Block(BlockId(1)) (0 to 36) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(13) diff --git a/src/typechecker.rs b/src/typechecker.rs index 76dc682..ce978b6 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -383,24 +383,20 @@ impl<'a> Typechecker<'a> { self.set_node_type_id(node_id, NONE_TYPE); } } - AstNode::While { cond_block, .. } => { - if let Some((condition, block)) = cond_block { - self.typecheck_node(block); - if self.type_id_of(block) != NONE_TYPE { - self.error("Blocks in looping constructs cannot return values", block); - } + AstNode::While { condition, block } => { + self.typecheck_node(block); + if self.type_id_of(block) != NONE_TYPE { + self.error("Blocks in looping constructs cannot return values", block); + } - self.typecheck_node(condition); + self.typecheck_node(condition); - // the condition should always evaluate to a boolean - if self.type_of(condition) != Type::Bool { - self.error("The condition for while loop is not a boolean", condition); - self.set_node_type_id(node_id, ERROR_TYPE); - } else { - self.set_node_type_id(node_id, self.type_id_of(block)); - } + // the condition should always evaluate to a boolean + if self.type_of(condition) != Type::Bool { + self.error("The condition for while loop is not a boolean", condition); + self.set_node_type_id(node_id, ERROR_TYPE); } else { - self.set_node_type_id(node_id, NONE_TYPE); + self.set_node_type_id(node_id, self.type_id_of(block)); } } AstNode::Match { From 7f0ddff3f1d6cc3de7fddde011c142b1eecfe292 Mon Sep 17 00:00:00 2001 From: innocentzero Date: Fri, 3 Jan 2025 16:39:24 +0530 Subject: [PATCH 9/9] Fix error message and span Signed-off-by: innocentzero --- src/parser.rs | 10 +++++----- .../new_nu_parser__test__node_output@match.nu.snap | 8 +++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 5dff510..950648c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -377,13 +377,13 @@ impl Parser { Token::LCurly => self.record_or_closure(), Token::LParen => { self.tokens.advance(); - let output = if self.tokens.peek().0 == Token::RParen { + if self.tokens.peek_token() == Token::RParen { self.error("use null instead of ()") } else { - self.expression() - }; - self.rparen(); - output + let output = self.expression(); + self.rparen(); + output + } } Token::LSquare => self.list_or_table(), Token::Int => self.advance_node(AstNode::Int, span), diff --git a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap index 8cc7753..05cb6ac 100644 --- a/src/snapshots/new_nu_parser__test__node_output@match.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@match.nu.snap @@ -26,10 +26,8 @@ snapshot_kind: text 18: Null (92 to 96) 19: String (100 to 101) "_" 20: Garbage (106 to 107) -21: Garbage (107 to 108) -22: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) -23: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(22), is_mutable: false } (11 to 110) -24: Block(BlockId(1)) (0 to 111) +21: Match { target: NodeId(4), match_arms: [(NodeId(5), NodeId(6)), (NodeId(7), NodeId(16)), (NodeId(17), NodeId(18)), (NodeId(19), NodeId(20))] } (21 to 110) +22: Let { variable_name: NodeId(3), ty: None, initializer: NodeId(21), is_mutable: false } (11 to 110) +23: Block(BlockId(1)) (0 to 111) ==== COMPILER ERRORS ==== Error (NodeId 20): use null instead of () -Error (NodeId 21): expected: right paren ')'