Skip to content

Commit 41d1321

Browse files
if else condition working
1 parent a24f2e1 commit 41d1321

File tree

5 files changed

+83
-43
lines changed

5 files changed

+83
-43
lines changed

mas/interpreter.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -355,23 +355,29 @@ static MASObject* evaluate(ASTNode* node, Interpreter* interp) {
355355
return create_null();
356356
}
357357
case AST_IF: {
358-
MASObject* cond = evaluate(node->data.loop.condition, interp);
359-
if (cond->type != AST_BOOLEAN) {
360-
fprintf(stderr, "If condition must be boolean\n");
361-
exit(1);
362-
}
363-
if (cond->data.boolean) {
364-
mas_object_decref(cond);
365-
// Execute if body
366-
for (int i = 0; i < node->data.loop.body_count; i++) {
367-
MASObject* result = evaluate(node->data.loop.body[i], interp);
368-
mas_object_decref(result);
369-
}
370-
} else {
371-
mas_object_decref(cond);
372-
}
373-
return create_null();
358+
MASObject* cond = evaluate(node->data.if_stmt.condition, interp);
359+
if (cond->type != AST_BOOLEAN) {
360+
fprintf(stderr, "If condition must be boolean\n");
361+
exit(1);
362+
}
363+
364+
if (cond->data.boolean) {
365+
// Execute 'then' branch
366+
for (int i = 0; i < node->data.if_stmt.then_body_count; i++) {
367+
MASObject* result = evaluate(node->data.if_stmt.then_body[i], interp);
368+
mas_object_decref(result);
369+
}
370+
} else if (node->data.if_stmt.else_body) {
371+
// Execute 'else' branch (only if it exists)
372+
for (int i = 0; i < node->data.if_stmt.else_body_count; i++) {
373+
MASObject* result = evaluate(node->data.if_stmt.else_body[i], interp);
374+
mas_object_decref(result);
374375
}
376+
}
377+
378+
mas_object_decref(cond);
379+
return create_null();
380+
}
375381
case AST_EXPRSTMT: {
376382
MASObject* result = evaluate(node->data.expr, interp);
377383
mas_object_decref(result);

mas/mas.exe

512 Bytes
Binary file not shown.

mas/mas.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct ASTNode {
7575
struct { ASTNode* condition; ASTNode** body; int body_count; } loop;
7676
struct { char* target; ASTNode* iterable; ASTNode** body; int body_count; } each;
7777
struct { char* name; char** params; int param_count; ASTNode** body; int body_count; } funcdef;
78+
struct { ASTNode* condition; ASTNode** then_body; int then_body_count; ASTNode** else_body; int else_body_count; } if_stmt;
7879
ASTNode* expr;
7980
} data;
8081
};

mas/parser.c

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ ASTNode* parse_program() {
5656
statements[stmt_count++] = parse_statement();
5757

5858
// After a statement, we must have a newline or EOF.
59-
if (current_token->type != TOK_NEWLINE && current_token->type != TOK_EOF) {
59+
if (current_token->type != TOK_EOF && current_token->type != TOK_EOF) {
6060
consume(TOK_NEWLINE, "Expected newline after statement");
6161
}
6262
}
@@ -169,30 +169,52 @@ ASTNode* parse_statement() {
169169
return each;
170170
}
171171
else if (match(KW_IF)) {
172-
advance(); // consume 'if'
173-
ASTNode* condition = parse_expression();
174-
consume(TOK_COLON, "Expected ':'");
175-
consume(TOK_NEWLINE, "Expected newline after if condition");
176-
177-
int body_count = 0;
178-
ASTNode** body = malloc(sizeof(ASTNode*) * 100);
172+
advance(); // consume 'if'
173+
ASTNode* condition = parse_expression();
174+
consume(TOK_COLON, "Expected ':'");
175+
consume(TOK_NEWLINE, "Expected newline after if condition");
176+
177+
// Parse 'then' body (stop at 'else' or 'end')
178+
int then_body_count = 0;
179+
ASTNode** then_body = malloc(sizeof(ASTNode*) * 100);
180+
while (current_token && current_token->type != TOK_END && current_token->type != KW_ELSE) {
181+
if (current_token->type == TOK_NEWLINE) {
182+
advance();
183+
continue;
184+
}
185+
then_body[then_body_count++] = parse_statement();
186+
}
187+
188+
// Parse optional 'else' block
189+
ASTNode** else_body = NULL;
190+
int else_body_count = 0;
191+
if (match(KW_ELSE)) {
192+
advance(); // consume 'else'
193+
consume(TOK_COLON, "Expected ':' after else");
194+
consume(TOK_NEWLINE, "Expected newline after else");
195+
196+
else_body = malloc(sizeof(ASTNode*) * 100);
179197
while (current_token && current_token->type != TOK_END) {
180198
if (current_token->type == TOK_NEWLINE) {
181199
advance();
182200
continue;
183201
}
184-
body[body_count++] = parse_statement();
202+
else_body[else_body_count++] = parse_statement();
185203
}
186-
consume(TOK_END, "Expected 'end' to close if");
187-
188-
ASTNode* if_stmt = malloc(sizeof(ASTNode));
189-
if_stmt->type = AST_IF;
190-
if_stmt->line = current_token->line;
191-
if_stmt->data.loop.condition = condition;
192-
if_stmt->data.loop.body = body;
193-
if_stmt->data.loop.body_count = body_count;
194-
return if_stmt;
195204
}
205+
206+
consume(TOK_END, "Expected 'end' to close if");
207+
208+
ASTNode* if_node = malloc(sizeof(ASTNode));
209+
if_node->type = AST_IF;
210+
if_node->line = condition->line;
211+
if_node->data.if_stmt.condition = condition;
212+
if_node->data.if_stmt.then_body = then_body;
213+
if_node->data.if_stmt.then_body_count = then_body_count;
214+
if_node->data.if_stmt.else_body = else_body; // NULL if no else
215+
if_node->data.if_stmt.else_body_count = else_body_count;
216+
return if_node;
217+
}
196218
else if (match(KW_GIVE)) {
197219
advance(); // consume 'give'
198220
ASTNode* value = parse_expression();
@@ -599,12 +621,19 @@ void print_ast(ASTNode* node, int indent) {
599621
}
600622
break;
601623
case AST_IF:
602-
printf("IF\n");
603-
print_ast(node->data.loop.condition, indent + 1);
604-
for (int i = 0; i < node->data.loop.body_count; i++) {
605-
print_ast(node->data.loop.body[i], indent + 1);
606-
}
607-
break;
624+
printf("IF\n");
625+
print_ast(node->data.if_stmt.condition, indent + 1);
626+
printf("%*sTHEN:\n", indent * 2, "");
627+
for (int i = 0; i < node->data.if_stmt.then_body_count; i++) {
628+
print_ast(node->data.if_stmt.then_body[i], indent + 1);
629+
}
630+
if (node->data.if_stmt.else_body) {
631+
printf("%*sELSE:\n", indent * 2, "");
632+
for (int i = 0; i < node->data.if_stmt.else_body_count; i++) {
633+
print_ast(node->data.if_stmt.else_body[i], indent + 1);
634+
}
635+
}
636+
break;
608637
case AST_LOOP:
609638
printf("LOOP\n");
610639
print_ast(node->data.loop.condition, indent + 1);

mas/test.mas

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
x = 4 - 5
2-
print "Sum is equal to ", x
3-
print "Sagnik is idiot"
1+
x = 2
2+
if x > 5:
3+
print "hello"
4+
print "hello"
5+
else:
6+
print "world"
7+
end

0 commit comments

Comments
 (0)