Skip to content

Commit fdb4f25

Browse files
committed
Add flag framework for while
Signed-off-by: innocentzero <md-isfarul-haque@proton.me>
1 parent a21f060 commit fdb4f25

File tree

5 files changed

+47
-36
lines changed

5 files changed

+47
-36
lines changed

src/parser.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ pub enum AstNode {
105105
is_mutable: bool,
106106
},
107107
While {
108-
condition: NodeId,
109-
block: NodeId,
108+
cond_block: Option<(NodeId, NodeId)>,
109+
short_flag: Option<NodeId>,
110+
long_flag: Option<NodeId>,
110111
},
111112
For {
112113
variable: NodeId,
@@ -1332,11 +1333,24 @@ impl Parser {
13321333
let span_start = self.position();
13331334
self.keyword(b"while");
13341335

1336+
if self.is_operator() {
1337+
// TODO: flag parsing
1338+
self.next();
1339+
}
1340+
13351341
let condition = self.expression();
13361342
let block = self.block(BlockContext::Curlies);
13371343
let span_end = self.get_span_end(block);
13381344

1339-
self.create_node(AstNode::While { condition, block }, span_start, span_end)
1345+
self.create_node(
1346+
AstNode::While {
1347+
cond_block: Some((condition, block)),
1348+
short_flag: None,
1349+
long_flag: None,
1350+
},
1351+
span_start,
1352+
span_end,
1353+
)
13401354
}
13411355

13421356
pub fn for_statement(&mut self) -> NodeId {

src/resolver.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,10 @@ impl<'a> Resolver<'a> {
262262
self.resolve_node(initializer);
263263
self.define_variable(variable_name, is_mutable)
264264
}
265-
AstNode::While { condition, block } => {
265+
AstNode::While {
266+
cond_block: Some((condition, block)),
267+
..
268+
} => {
266269
self.resolve_node(condition);
267270
self.resolve_node(block);
268271
}

src/snapshots/new_nu_parser__test__node_output@while.nu.snap

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,12 @@ snapshot_kind: text
1717
9: Int (32 to 33) "1"
1818
10: BinaryOp { lhs: NodeId(7), op: NodeId(8), rhs: NodeId(9) } (26 to 33)
1919
11: Block(BlockId(0)) (22 to 35)
20-
12: While { condition: NodeId(6), block: NodeId(11) } (10 to 35)
21-
13: Block(BlockId(1)) (0 to 36)
22-
==== SCOPE ====
23-
0: Frame Scope, node_id: NodeId(13)
24-
variables: [ x: NodeId(0) ]
25-
1: Frame Scope, node_id: NodeId(11) (empty)
26-
==== TYPES ====
27-
0: int
28-
1: int
29-
2: none
30-
3: int
31-
4: forbidden
32-
5: int
33-
6: bool
34-
7: int
35-
8: forbidden
36-
9: int
37-
10: none
38-
11: none
39-
12: none
40-
13: none
20+
12: While { cond_block: Some((NodeId(6), NodeId(11))), short_flag: None, long_flag: None } (10 to 35)
21+
13: Name (44 to 45) "h"
22+
14: Call { parts: [NodeId(13)] } (45 to 45)
23+
15: Garbage (45 to 46)
24+
16: Block(BlockId(1)) (45 to 46)
25+
17: While { cond_block: Some((NodeId(14), NodeId(16))), short_flag: None, long_flag: None } (37 to 46)
26+
18: Block(BlockId(2)) (0 to 46)
27+
==== COMPILER ERRORS ====
28+
Error (NodeId 15): expected: left bracket '{'

src/typechecker.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -386,20 +386,24 @@ impl<'a> Typechecker<'a> {
386386
self.set_node_type_id(node_id, NONE_TYPE);
387387
}
388388
}
389-
AstNode::While { condition, block } => {
390-
self.typecheck_node(block);
391-
if self.type_id_of(block) != NONE_TYPE {
392-
self.error("Blocks in looping constructs cannot return values", block);
393-
}
389+
AstNode::While { cond_block, .. } => {
390+
if let Some((condition, block)) = cond_block {
391+
self.typecheck_node(condition);
394392

395-
self.typecheck_node(condition);
393+
self.typecheck_node(block);
394+
if self.type_id_of(block) != NONE_TYPE {
395+
self.error("Blocks in looping constructs cannot return values", block);
396+
}
396397

397-
// the condition should always evaluate to a boolean
398-
if self.type_of(condition) != Type::Bool {
399-
self.error("The condition for while loop is not a boolean", condition);
400-
self.set_node_type_id(node_id, ERROR_TYPE);
398+
// the condition should always evaluate to a boolean
399+
if self.type_of(condition) != Type::Bool {
400+
self.error("The condition for while loop is not a boolean", condition);
401+
self.set_node_type_id(node_id, ERROR_TYPE);
402+
} else {
403+
self.set_node_type_id(node_id, self.type_id_of(block));
404+
}
401405
} else {
402-
self.set_node_type_id(node_id, self.type_id_of(block));
406+
self.set_node_type_id(node_id, NONE_TYPE);
403407
}
404408
}
405409
AstNode::Match {

tests/while.nu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ mut x = 0
22
while 1 < 2 {
33
$x += 1
44
}
5+
6+
while -h

0 commit comments

Comments
 (0)