Skip to content

Commit

Permalink
bootstrap upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 15, 2025
1 parent 0dc8f43 commit 1c75b18
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 10 deletions.
8 changes: 5 additions & 3 deletions bootstrap_compiler/build_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -873,18 +873,20 @@ static void build_match_statament(struct State *st, const AstMatchStatement *mat

CfBlock *done = add_block(st);
for (int i = 0; i < match_stmt->ncases; i++) {
const LocalVariable *case_obj_enum = build_expression(st, &match_stmt->cases[i].case_obj);
for (AstExpression *caseobj = match_stmt->cases[i].case_objs; caseobj < &match_stmt->cases[i].case_objs[match_stmt->cases[i].n_case_objs]; caseobj++) {
const LocalVariable *case_obj_enum = build_expression(st, caseobj);
LocalVariable *case_obj_int = add_local_var(st, intType);
add_unary_op(st, match_stmt->cases[i].case_obj.location, CF_ENUM_TO_INT32, case_obj_enum, case_obj_int);
add_unary_op(st, caseobj->location, CF_ENUM_TO_INT32, case_obj_enum, case_obj_int);

const LocalVariable *cond = build_binop(st, AST_EXPR_EQ, match_stmt->cases[i].case_obj.location, match_obj_int, case_obj_int, boolType);
const LocalVariable *cond = build_binop(st, AST_EXPR_EQ, caseobj->location, match_obj_int, case_obj_int, boolType);
CfBlock *then = add_block(st);
CfBlock *otherwise = add_block(st);

add_jump(st, cond, then, otherwise, then);
build_body(st, &match_stmt->cases[i].body);
add_jump(st, NULL, done, done, otherwise);
}
}

build_body(st, &match_stmt->case_underscore);
add_jump(st, NULL, done, done, done);
Expand Down
5 changes: 4 additions & 1 deletion bootstrap_compiler/free.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ void free_ast_statement(const AstStatement *stmt)
case AST_STMT_MATCH:
free_expression(&stmt->data.match.match_obj);
for (int i = 0; i < stmt->data.match.ncases; i++) {
free_expression(&stmt->data.match.cases[i].case_obj);
for (AstExpression *caseobj = stmt->data.match.cases[i].case_objs; caseobj < &stmt->data.match.cases[i].case_objs[stmt->data.match.cases[i].n_case_objs]; caseobj++) {
free_expression(caseobj);
}
free(stmt->data.match.cases[i].case_objs);
free_ast_body(&stmt->data.match.cases[i].body);
}
free(stmt->data.match.cases);
Expand Down
3 changes: 2 additions & 1 deletion bootstrap_compiler/jou_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ struct AstForLoop {
AstBody body;
};
struct AstCase {
AstExpression case_obj;
AstExpression *case_objs;
int n_case_objs;
AstBody body;
};
struct AstMatchStatement {
Expand Down
13 changes: 12 additions & 1 deletion bootstrap_compiler/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,20 @@ static AstMatchStatement parse_match_statement(ParserState *ps)
ps->tokens++;
result.case_underscore = parse_body(ps);
} else {
List(AstExpression) case_objs = {0};
while(1){
Append(&case_objs, parse_expression(ps));
if (is_operator(ps->tokens, "|"))
ps->tokens++;
else if (is_operator(ps->tokens, ":"))
break;
else
fail_with_parse_error(ps->tokens, "'|' or ':'");
}
result.cases = realloc(result.cases, sizeof result.cases[0] * (result.ncases + 1));
result.cases[result.ncases++] = (AstCase){
.case_obj = parse_expression(ps),
.case_objs = case_objs.ptr,
.n_case_objs = case_objs.len,
.body = parse_body(ps),
};
}
Expand Down
10 changes: 6 additions & 4 deletions bootstrap_compiler/typecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -1292,10 +1292,12 @@ static void typecheck_match_statement(FileTypes *ft, AstMatchStatement *match_st
assert(mtype->kind == TYPE_ENUM);

for (int i = 0; i < match_stmt->ncases; i++) {
typecheck_expression_with_implicit_cast(
ft, &match_stmt->cases[i].case_obj, mtype,
"case value of type FROM cannot be matched against TO"
);
for (int k = 0; k < match_stmt->cases[i].n_case_objs; k++) {
typecheck_expression_with_implicit_cast(
ft, &match_stmt->cases[i].case_objs[k], mtype,
"case value of type FROM cannot be matched against TO"
);
}
typecheck_body(ft, &match_stmt->cases[i].body);
}
typecheck_body(ft, &match_stmt->case_underscore);
Expand Down

0 comments on commit 1c75b18

Please sign in to comment.