Add for-loop AST

This commit is contained in:
Sofia 2026-04-28 01:15:57 +03:00
parent ba21718f71
commit 8d826326fa
6 changed files with 78 additions and 3 deletions

View File

@ -137,6 +137,17 @@ namespace AST {
return out.str();
}
std::string ForStatement::formatted() {
std::stringstream out{ "" };
out << "(" << this->m_init->formatted();
out << ";" << this->m_cond->formatted();
out << ";" << this->m_after->formatted();
out << ")";
out << "\n then " << this->m_loop->formatted();
return out.str();
}
std::string ReturnStatement::formatted() {
std::stringstream out{ "" };
out << "return ";

View File

@ -427,6 +427,33 @@ namespace AST {
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class ForStatement : public Statement {
private:
std::unique_ptr<Statement> m_init;
std::unique_ptr<Expression> m_cond;
std::unique_ptr<Expression> m_after;
std::unique_ptr<Statement> m_loop;
public:
ForStatement(token::Metadata meta,
std::unique_ptr<Statement> init,
std::unique_ptr<Expression> cond,
std::unique_ptr<Expression> after,
std::unique_ptr<Statement> loop,
std::optional<std::unique_ptr<Statement>> else_statement)
: Statement{ meta }
, m_init{ std::move(init) }
, m_cond{ std::move(cond) }
, m_after{ std::move(after) }
, m_loop{ std::move(loop) } {
}
virtual ~ForStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class TopLevelStatement : public Node {
public:
TopLevelStatement(token::Metadata meta) : Node{ meta } {}

View File

@ -557,6 +557,15 @@ namespace AST {
builder.builder->SetInsertPoint(after_block);
}
void ForStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block);
throw CompileError("TODO", this->m_meta);
}
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
std::shared_ptr<types::Type> ret_ty_ptr{ this->m_return_ty };

View File

@ -93,4 +93,11 @@ namespace AST {
(*this->m_else)->codegen_alloca(allocator);
}
}
void ForStatement::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_init->codegen_alloca(allocator);
this->m_cond->codegen_alloca(allocator);
this->m_after->codegen_alloca(allocator);
this->m_loop->codegen_alloca(allocator);
}
}

View File

@ -631,6 +631,27 @@ namespace AST {
}
}
void ForStatement::typecheck_preprocess(typecheck::Scope& scope) {
this->m_init->typecheck_preprocess(scope);
this->m_cond->typecheck_preprocess(scope);
this->m_after->typecheck_preprocess(scope);
this->m_loop->typecheck_preprocess(scope);
}
void ForStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
this->m_init->typecheck(state, scope);
auto cond_ty = this->m_cond->typecheck(state, scope, bool_ty).type;
auto check_res = check_type(state, cond_ty, bool_ty);
this->m_cond = handle_res(std::move(this->m_cond), check_res, state);
this->m_after->typecheck(state, scope, {});
this->m_loop->typecheck(state, scope);
}
void Function::typecheck_preprocess(typecheck::Scope& scope) {
this->m_return_ty = refresh_type(scope, this->m_return_ty);
for (auto& param : this->m_params) {

6
test.c
View File

@ -51,9 +51,9 @@ int main() {
twod_array[0][0] = 50;
printf("2d array: %d!\n", twod_array[0][0]);
int counter = 0;
int a = -500;
printf("a: %d\n", a);
for (int counter = 0; counter < 10; counter++) {
printf("counter: %d\n", counter);
}
return 0;
}