From c982c9a8010c008f2a1aa6921745b4fb6abeeb13 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Fri, 16 Jan 2026 22:22:50 +0800 Subject: [PATCH] def: support --env and --wrapped --- src/lexer.rs | 2 + src/parser.rs | 32 ++++++++++++ src/resolver.rs | 2 + ...nu_parser__test__node_output@calls.nu.snap | 2 +- ...r__test__node_output@calls_invalid.nu.snap | 4 +- ...w_nu_parser__test__node_output@def.nu.snap | 4 +- ..._test__node_output@def_return_type.nu.snap | 6 +-- ...__test__node_output@def_with_flags.nu.snap | 50 +++++++++++++++++++ ...r__test__node_output@infer_complex.nu.snap | 6 +-- ...__test__node_output@infer_generics.nu.snap | 4 +- ...rser__test__node_output@infer_plus.nu.snap | 4 +- ...r__test__node_output@invalid_types.nu.snap | 6 +-- tests/def_with_flags.nu | 3 ++ 13 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 src/snapshots/new_nu_parser__test__node_output@def_with_flags.nu.snap create mode 100644 tests/def_with_flags.nu diff --git a/src/lexer.rs b/src/lexer.rs index b626d2a..508334a 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -375,6 +375,8 @@ pub enum Token { DashEquals, #[token("-")] Dash, + #[token("--")] + DashDash, #[token("**")] AsteriskAsterisk, #[token("*=")] diff --git a/src/parser.rs b/src/parser.rs index 7936492..79aa5a9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -183,6 +183,8 @@ pub enum AstNode { params: NodeId, in_out_types: Option, block: NodeId, + env: bool, + wrapped: bool, }, Params(Vec), Param { @@ -1177,6 +1179,34 @@ impl Parser { let span_start = self.position(); self.keyword(b"def"); + let mut has_env_flag = false; + let mut has_wrapped_flag = false; + + // maybe `--env` or `--wrapped` + while let (Token::DashDash, _) = self.tokens.peek() { + self.tokens.advance(); + match self.tokens.peek() { + // let's make sure that the word is `env` or `wrapped` + (Token::Bareword, span) => { + let flag_name = self.compiler.get_span_contents_manual(span.start, span.end); + if flag_name == b"env" { + if has_env_flag { + return self.error("duplicated --env flag"); + } + has_env_flag = true; + } else if flag_name == b"wrapped" { + if has_wrapped_flag { + return self.error("duplicated --wrapped flag"); + } + has_wrapped_flag = true + } else { + return self.error("expect --env or --wrapped"); + } + self.tokens.advance(); + } + _ => return self.error("incomplete flag name"), + } + } let name = match self.tokens.peek() { (Token::Bareword, span) => self.advance_node(AstNode::Name, span), @@ -1209,6 +1239,8 @@ impl Parser { params, in_out_types, block, + env: has_env_flag, + wrapped: has_wrapped_flag, }, span_start, span_end, diff --git a/src/resolver.rs b/src/resolver.rs index 1048cf2..5c281fb 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -266,6 +266,8 @@ impl<'a> Resolver<'a> { params, in_out_types, block, + env: _, + wrapped: _, } => { // define the command before the block to enable recursive calls self.define_decl(name, node_id); diff --git a/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap b/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap index 60d535f..83b8078 100644 --- a/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap @@ -31,7 +31,7 @@ input_file: tests/calls.nu 24: Variable (80 to 82) "$c" 25: List([NodeId(22), NodeId(23), NodeId(24)]) (70 to 82) 26: Block(BlockId(0)) (68 to 85) -27: Def { name: NodeId(8), type_params: None, params: NodeId(21), in_out_types: None, block: NodeId(26) } (24 to 85) +27: Def { name: NodeId(8), type_params: None, params: NodeId(21), in_out_types: None, block: NodeId(26), env: false, wrapped: false } (24 to 85) 28: Name (86 to 94) "existing" 29: Name (95 to 98) "foo" 30: String (100 to 104) ""ba"" diff --git a/src/snapshots/new_nu_parser__test__node_output@calls_invalid.nu.snap b/src/snapshots/new_nu_parser__test__node_output@calls_invalid.nu.snap index 8bca912..b6e2bd7 100644 --- a/src/snapshots/new_nu_parser__test__node_output@calls_invalid.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@calls_invalid.nu.snap @@ -11,7 +11,7 @@ input_file: tests/calls_invalid.nu 4: Param { name: NodeId(1), ty: Some(NodeId(3)) } (10 to 16) 5: Params([NodeId(4)]) (8 to 18) 6: Block(BlockId(0)) (19 to 21) -7: Def { name: NodeId(0), type_params: None, params: NodeId(5), in_out_types: None, block: NodeId(6) } (0 to 21) +7: Def { name: NodeId(0), type_params: None, params: NodeId(5), in_out_types: None, block: NodeId(6), env: false, wrapped: false } (0 to 21) 8: Name (22 to 25) "foo" 9: Int (26 to 27) "1" 10: Int (28 to 29) "2" @@ -49,4 +49,4 @@ Error (NodeId 13): Expected int, got string register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 7): node Def { name: NodeId(0), type_params: None, params: NodeId(5), in_out_types: None, block: NodeId(6) } not suported yet +Error (NodeId 7): node Def { name: NodeId(0), type_params: None, params: NodeId(5), in_out_types: None, block: NodeId(6), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@def.nu.snap b/src/snapshots/new_nu_parser__test__node_output@def.nu.snap index 0baa77c..3416eb2 100644 --- a/src/snapshots/new_nu_parser__test__node_output@def.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@def.nu.snap @@ -39,7 +39,7 @@ input_file: tests/def.nu 32: Variable (77 to 79) "$z" 33: List([NodeId(29), NodeId(30), NodeId(31), NodeId(32)]) (64 to 80) 34: Block(BlockId(0)) (62 to 83) -35: Def { name: NodeId(0), type_params: None, params: NodeId(28), in_out_types: None, block: NodeId(34) } (0 to 83) +35: Def { name: NodeId(0), type_params: None, params: NodeId(28), in_out_types: None, block: NodeId(34), env: false, wrapped: false } (0 to 83) 36: Block(BlockId(1)) (0 to 83) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(36) @@ -88,4 +88,4 @@ input_file: tests/def.nu register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 35): node Def { name: NodeId(0), type_params: None, params: NodeId(28), in_out_types: None, block: NodeId(34) } not suported yet +Error (NodeId 35): node Def { name: NodeId(0), type_params: None, params: NodeId(28), in_out_types: None, block: NodeId(34), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@def_return_type.nu.snap b/src/snapshots/new_nu_parser__test__node_output@def_return_type.nu.snap index 76247ec..9885986 100644 --- a/src/snapshots/new_nu_parser__test__node_output@def_return_type.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@def_return_type.nu.snap @@ -17,7 +17,7 @@ input_file: tests/def_return_type.nu 10: InOutTypes([NodeId(9)]) (14 to 35) 11: List([]) (37 to 38) 12: Block(BlockId(0)) (35 to 41) -13: Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: Some(NodeId(10)), block: NodeId(12) } (0 to 41) +13: Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: Some(NodeId(10)), block: NodeId(12), env: false, wrapped: false } (0 to 41) 14: Name (46 to 49) "bar" 15: Params([]) (50 to 53) 16: Name (58 to 64) "string" @@ -39,7 +39,7 @@ input_file: tests/def_return_type.nu 32: InOutTypes([NodeId(23), NodeId(31)]) (56 to 101) 33: List([]) (103 to 104) 34: Block(BlockId(1)) (101 to 107) -35: Def { name: NodeId(14), type_params: None, params: NodeId(15), in_out_types: Some(NodeId(32)), block: NodeId(34) } (42 to 107) +35: Def { name: NodeId(14), type_params: None, params: NodeId(15), in_out_types: Some(NodeId(32)), block: NodeId(34), env: false, wrapped: false } (42 to 107) 36: Block(BlockId(2)) (0 to 108) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(36) @@ -88,4 +88,4 @@ input_file: tests/def_return_type.nu register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 13): node Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: Some(NodeId(10)), block: NodeId(12) } not suported yet +Error (NodeId 13): node Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: Some(NodeId(10)), block: NodeId(12), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@def_with_flags.nu.snap b/src/snapshots/new_nu_parser__test__node_output@def_with_flags.nu.snap new file mode 100644 index 0000000..fe7af17 --- /dev/null +++ b/src/snapshots/new_nu_parser__test__node_output@def_with_flags.nu.snap @@ -0,0 +1,50 @@ +--- +source: src/test.rs +expression: evaluate_example(path) +input_file: tests/def_with_flags.nu +--- +==== COMPILER ==== +0: Name (10 to 13) "foo" +1: Params([]) (14 to 17) +2: String (20 to 25) ""foo"" +3: Block(BlockId(0)) (18 to 27) +4: Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: None, block: NodeId(3), env: true, wrapped: false } (0 to 27) +5: Name (42 to 46) "foo2" +6: Params([]) (47 to 50) +7: String (53 to 59) ""foo2"" +8: Block(BlockId(1)) (51 to 61) +9: Def { name: NodeId(5), type_params: None, params: NodeId(6), in_out_types: None, block: NodeId(8), env: false, wrapped: true } (28 to 61) +10: Name (82 to 86) "foo3" +11: Params([]) (87 to 90) +12: String (93 to 99) ""foo3"" +13: Block(BlockId(2)) (91 to 101) +14: Def { name: NodeId(10), type_params: None, params: NodeId(11), in_out_types: None, block: NodeId(13), env: true, wrapped: true } (62 to 101) +15: Block(BlockId(3)) (0 to 102) +==== SCOPE ==== +0: Frame Scope, node_id: NodeId(15) + decls: [ foo2: NodeId(5), foo3: NodeId(10), foo: NodeId(0) ] +1: Frame Scope, node_id: NodeId(3) (empty) +2: Frame Scope, node_id: NodeId(8) (empty) +3: Frame Scope, node_id: NodeId(13) (empty) +==== TYPES ==== +0: unknown +1: forbidden +2: string +3: string +4: () +5: unknown +6: forbidden +7: string +8: string +9: () +10: unknown +11: forbidden +12: string +13: string +14: () +15: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Def { name: NodeId(0), type_params: None, params: NodeId(1), in_out_types: None, block: NodeId(3), env: true, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@infer_complex.nu.snap b/src/snapshots/new_nu_parser__test__node_output@infer_complex.nu.snap index b91bb9c..6b874d4 100644 --- a/src/snapshots/new_nu_parser__test__node_output@infer_complex.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@infer_complex.nu.snap @@ -52,7 +52,7 @@ input_file: tests/infer_complex.nu 45: InOutTypes([NodeId(44)]) (63 to 93) 46: Variable (97 to 99) "$x" 47: Block(BlockId(0)) (93 to 101) -48: Def { name: NodeId(0), type_params: Some(NodeId(3)), params: NodeId(30), in_out_types: Some(NodeId(45)), block: NodeId(47) } (0 to 101) +48: Def { name: NodeId(0), type_params: Some(NodeId(3)), params: NodeId(30), in_out_types: Some(NodeId(45)), block: NodeId(47), env: false, wrapped: false } (0 to 101) 49: Name (106 to 116) "mysterious" 50: Name (117 to 118) "T" 51: Params([NodeId(50)]) (116 to 119) @@ -68,7 +68,7 @@ input_file: tests/infer_complex.nu 61: InOutType(NodeId(58), NodeId(60)) (133 to 146) 62: InOutTypes([NodeId(61)]) (133 to 146) 63: Block(BlockId(1)) (146 to 148) -64: Def { name: NodeId(49), type_params: Some(NodeId(51)), params: NodeId(56), in_out_types: Some(NodeId(62)), block: NodeId(63) } (102 to 148) +64: Def { name: NodeId(49), type_params: Some(NodeId(51)), params: NodeId(56), in_out_types: Some(NodeId(62)), block: NodeId(63), env: false, wrapped: false } (102 to 148) 65: Variable (154 to 155) "m" 66: Name (158 to 168) "mysterious" 67: Int (169 to 170) "0" @@ -203,4 +203,4 @@ input_file: tests/infer_complex.nu register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 48): node Def { name: NodeId(0), type_params: Some(NodeId(3)), params: NodeId(30), in_out_types: Some(NodeId(45)), block: NodeId(47) } not suported yet +Error (NodeId 48): node Def { name: NodeId(0), type_params: Some(NodeId(3)), params: NodeId(30), in_out_types: Some(NodeId(45)), block: NodeId(47), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@infer_generics.nu.snap b/src/snapshots/new_nu_parser__test__node_output@infer_generics.nu.snap index 3a202d4..4d262bb 100644 --- a/src/snapshots/new_nu_parser__test__node_output@infer_generics.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@infer_generics.nu.snap @@ -29,7 +29,7 @@ input_file: tests/infer_generics.nu 22: Variable (60 to 62) "$z" 23: List([NodeId(22)]) (59 to 62) 24: Block(BlockId(0)) (39 to 65) -25: Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(16)), block: NodeId(24) } (0 to 65) +25: Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(16)), block: NodeId(24), env: false, wrapped: false } (0 to 65) 26: Name (67 to 68) "f" 27: Int (69 to 70) "1" 28: Call { parts: [NodeId(26), NodeId(27)] } (69 to 70) @@ -75,4 +75,4 @@ input_file: tests/infer_generics.nu register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 25): node Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(16)), block: NodeId(24) } not suported yet +Error (NodeId 25): node Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(16)), block: NodeId(24), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@infer_plus.nu.snap b/src/snapshots/new_nu_parser__test__node_output@infer_plus.nu.snap index ff021e2..e8cdfea 100644 --- a/src/snapshots/new_nu_parser__test__node_output@infer_plus.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@infer_plus.nu.snap @@ -19,7 +19,7 @@ input_file: tests/infer_plus.nu 12: InOutType(NodeId(9), NodeId(11)) (31 to 44) 13: InOutTypes([NodeId(12)]) (31 to 44) 14: Block(BlockId(0)) (44 to 46) -15: Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(13)), block: NodeId(14) } (0 to 46) +15: Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(13)), block: NodeId(14), env: false, wrapped: false } (0 to 46) 16: Variable (52 to 53) "m" 17: Name (56 to 66) "mysterious" 18: Int (67 to 68) "0" @@ -78,4 +78,4 @@ Error (NodeId 27): Expected string, got int register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 15): node Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(13)), block: NodeId(14) } not suported yet +Error (NodeId 15): node Def { name: NodeId(0), type_params: Some(NodeId(2)), params: NodeId(7), in_out_types: Some(NodeId(13)), block: NodeId(14), env: false, wrapped: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap b/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap index 2791175..1dc23bf 100644 --- a/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap @@ -17,7 +17,7 @@ input_file: tests/invalid_types.nu 10: Params([NodeId(9)]) (8 to 30) 11: Variable (33 to 35) "$x" 12: Block(BlockId(0)) (31 to 37) -13: Def { name: NodeId(0), type_params: None, params: NodeId(10), in_out_types: None, block: NodeId(12) } (0 to 37) +13: Def { name: NodeId(0), type_params: None, params: NodeId(10), in_out_types: None, block: NodeId(12), env: false, wrapped: false } (0 to 37) 14: Name (42 to 45) "bar" 15: Name (47 to 48) "y" 16: Name (50 to 54) "list" @@ -27,7 +27,7 @@ input_file: tests/invalid_types.nu 20: Params([NodeId(19)]) (46 to 57) 21: Variable (60 to 62) "$y" 22: Block(BlockId(1)) (58 to 64) -23: Def { name: NodeId(14), type_params: None, params: NodeId(20), in_out_types: None, block: NodeId(22) } (38 to 64) +23: Def { name: NodeId(14), type_params: None, params: NodeId(20), in_out_types: None, block: NodeId(22), env: false, wrapped: false } (38 to 64) 24: Block(BlockId(2)) (0 to 65) ==== SCOPE ==== 0: Frame Scope, node_id: NodeId(24) @@ -69,4 +69,4 @@ Error (NodeId 17): list must have one type argument register_count: 0 file_count: 0 ==== IR ERRORS ==== -Error (NodeId 13): node Def { name: NodeId(0), type_params: None, params: NodeId(10), in_out_types: None, block: NodeId(12) } not suported yet +Error (NodeId 13): node Def { name: NodeId(0), type_params: None, params: NodeId(10), in_out_types: None, block: NodeId(12), env: false, wrapped: false } not suported yet diff --git a/tests/def_with_flags.nu b/tests/def_with_flags.nu new file mode 100644 index 0000000..50649ec --- /dev/null +++ b/tests/def_with_flags.nu @@ -0,0 +1,3 @@ +def --env foo [ ] { "foo" } +def --wrapped foo2 [ ] { "foo2" } +def --env --wrapped foo3 [ ] { "foo3" }