stmt.c (4426B)
1 #include "../parser.h" 2 #include "../utils.h" 3 4 #include <stdio.h> 5 #include <string.h> 6 #include <stdbool.h> 7 #include <assert.h> 8 9 Node* 10 parse_if(Parser* par) 11 { 12 expect(par, TOKEN_IF); 13 expect(par, TOKEN_LPAREN); // @later remove necessity for parens 14 Node* cond = parse_expression(par); 15 expect(par, TOKEN_RPAREN); 16 17 Node* then_body = parse_statement(par); 18 19 Node* else_body = NULL; 20 if (match(par, TOKEN_ELSE)) else_body = parse_statement(par); 21 22 Node* node = (Node*)calloc(1, sizeof(Node)); 23 if (node == NULL) panic("parse_if: could not alloc"); 24 node->type = NODE_IF; 25 node->scope = NULL; 26 node->data.if_statement.cond = cond; 27 node->data.if_statement.then_body = then_body; 28 node->data.if_statement.else_body = else_body; 29 return node; 30 } 31 32 Node* 33 parse_while(Parser* par) 34 { 35 expect(par, TOKEN_WHILE); 36 expect(par, TOKEN_LPAREN); 37 Node* cond = parse_expression(par); 38 expect(par, TOKEN_RPAREN); 39 40 Node* body = parse_statement(par); 41 42 Node* node = (Node*)calloc(1, sizeof(Node)); 43 if (node == NULL) panic("parse_while: could not alloc"); 44 node->type = NODE_WHILE; 45 node->scope = NULL; 46 node->data.while_statement.cond = cond; 47 node->data.while_statement.body = body; 48 return node; 49 } 50 51 Node* 52 parse_for(Parser* par) 53 { 54 expect(par, TOKEN_FOR); 55 expect(par, TOKEN_LPAREN); 56 57 // init can be empty, a decl, or a expr statement 58 Node* init = NULL; // int i = 0 ... conditional expression stment 59 if (!check(par, TOKEN_SEMICOLON)) { 60 Token tok2 = peek2(par); 61 if (tok2.type == TOKEN_IDENT) { 62 init = parse_declaration_statement(par); 63 } else { 64 init = parse_expression_statement(par); 65 } 66 } else 67 expect(par, TOKEN_SEMICOLON); 68 69 Node* cond = NULL; // i < len ... optional expression 70 if (!check(par, TOKEN_SEMICOLON)) cond = parse_expression(par); 71 expect(par, TOKEN_SEMICOLON); 72 73 Node* inc = NULL; // i++ ... optional expression 74 if (!check(par, TOKEN_RPAREN)) { inc = parse_expression(par); } 75 expect(par, TOKEN_RPAREN); 76 77 Node* body = parse_statement(par); 78 79 Node* node = (Node*)calloc(1, sizeof(Node)); 80 node->type = NODE_FOR; 81 node->scope = NULL; 82 node->data.for_statement.init = init; 83 node->data.for_statement.cond = cond; 84 node->data.for_statement.increment = inc; 85 if (node == NULL) panic("parse_for: could not alloc"); 86 87 node->data.for_statement.body = body; 88 return node; 89 } 90 91 Node* 92 parse_assignment(Parser* par) 93 { 94 Token ident = expect(par, TOKEN_IDENT); 95 Span name = { .start = ident.start, .end = ident.end }; 96 97 expect(par, TOKEN_EQUAL); 98 Node* expr = parse_expression(par); 99 100 Node* assign = (Node*)calloc(1, sizeof(Node)); 101 if (assign == NULL) panic("parse_assignment: could not alloc"); 102 assign->type = NODE_VAR_ASSIGN; 103 assign->scope = NULL; 104 assign->data.var_assign.lhs = (Node*)calloc(1, sizeof(Node)); 105 if (assign->data.var_assign.lhs == NULL) panic("parse_for: lhs: could not alloc"); 106 /* 107 identifier 108 x = 5; 109 110 member field access 111 obj.field = 5; 112 obj->field = 5; 113 114 array or pointer indexing 115 arr[0] = 5; 116 *(p + 1) = 5; 117 118 dereference 119 *p = 5; 120 */ 121 assign->data.var_assign.lhs->type = NODE_IDENT; // TODO handle other cases 122 assign->data.var_assign.lhs->scope = NULL; 123 assign->data.var_assign.lhs->data.ident.name = name; 124 assign->data.var_assign.rhs = expr; 125 return assign; 126 } 127 128 Node* 129 parse_break(Parser* par) 130 { 131 expect(par, TOKEN_BREAK); 132 expect(par, TOKEN_SEMICOLON); 133 134 Node* node = (Node*)calloc(1, sizeof(Node)); 135 if (node == NULL) panic("parse_break: could not alloc"); 136 node->type = NODE_BREAK; 137 node->scope = NULL; 138 return node; 139 } 140 141 Node* 142 parse_continue_statement(Parser* par) 143 { 144 expect(par, TOKEN_CONTINUE); // consume 'continue' 145 146 Node* node = (Node*)calloc(1, sizeof(Node)); 147 if (node == NULL) panic("parse_continue_statemenet: could not alloc"); 148 node->type = NODE_CONTINUE; 149 node->scope = NULL; 150 151 TokenType next_type = peek(par).type; 152 153 if (next_type != TOKEN_SEMICOLON) 154 node->data.cont.expr = parse_expression(par); 155 else 156 node->data.cont.expr = NULL; 157 158 expect(par, TOKEN_SEMICOLON); 159 return node; 160 } 161 162 Node* 163 parse_return_statement(Parser* par) 164 { 165 expect(par, TOKEN_RETURN); // consume 'return' 166 Node* ret = (Node*)calloc(1, sizeof(Node)); 167 if (ret == NULL) panic("parse_return_statemenet: could not alloc"); 168 ret->type = NODE_RETURN; 169 ret->scope = NULL; 170 171 TokenType next_type = peek(par).type; 172 173 if (next_type != TOKEN_SEMICOLON) 174 ret->data.ret.expr = parse_expression(par); 175 else 176 ret->data.ret.expr = NULL; 177 178 expect(par, TOKEN_SEMICOLON); 179 return ret; 180 }