Make for-loop parts optional

This commit is contained in:
Sofia 2026-04-28 01:18:26 +03:00
parent 8d826326fa
commit 2d004cc5d8
4 changed files with 35 additions and 17 deletions

View File

@ -139,9 +139,15 @@ namespace AST {
std::string ForStatement::formatted() { std::string ForStatement::formatted() {
std::stringstream out{ "" }; std::stringstream out{ "" };
out << "(" << this->m_init->formatted(); out << "(";
out << ";" << this->m_cond->formatted(); if (this->m_init)
out << ";" << this->m_after->formatted(); out << (*this->m_init)->formatted();
out << ";";
if (this->m_cond)
out << (*this->m_cond)->formatted();
out << ";";
if (this->m_after)
out << (*this->m_after)->formatted();
out << ")"; out << ")";
out << "\n then " << this->m_loop->formatted(); out << "\n then " << this->m_loop->formatted();

View File

@ -429,9 +429,9 @@ namespace AST {
class ForStatement : public Statement { class ForStatement : public Statement {
private: private:
std::unique_ptr<Statement> m_init; std::optional<std::unique_ptr<Statement>> m_init;
std::unique_ptr<Expression> m_cond; std::optional<std::unique_ptr<Expression>> m_cond;
std::unique_ptr<Expression> m_after; std::optional<std::unique_ptr<Expression>> m_after;
std::unique_ptr<Statement> m_loop; std::unique_ptr<Statement> m_loop;
public: public:
ForStatement(token::Metadata meta, ForStatement(token::Metadata meta,

View File

@ -95,9 +95,12 @@ namespace AST {
} }
void ForStatement::codegen_alloca(codegen::StackAllocator& allocator) { void ForStatement::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_init->codegen_alloca(allocator); if (this->m_init)
this->m_cond->codegen_alloca(allocator); (*this->m_init)->codegen_alloca(allocator);
this->m_after->codegen_alloca(allocator); if (this->m_cond)
(*this->m_cond)->codegen_alloca(allocator);
if (this->m_after)
(*this->m_after)->codegen_alloca(allocator);
this->m_loop->codegen_alloca(allocator); this->m_loop->codegen_alloca(allocator);
} }
} }

View File

@ -632,9 +632,12 @@ namespace AST {
} }
void ForStatement::typecheck_preprocess(typecheck::Scope& scope) { void ForStatement::typecheck_preprocess(typecheck::Scope& scope) {
this->m_init->typecheck_preprocess(scope); if (this->m_init)
this->m_cond->typecheck_preprocess(scope); (*this->m_init)->typecheck_preprocess(scope);
this->m_after->typecheck_preprocess(scope); if (this->m_cond)
(*this->m_cond)->typecheck_preprocess(scope);
if (this->m_after)
(*this->m_after)->typecheck_preprocess(scope);
this->m_loop->typecheck_preprocess(scope); this->m_loop->typecheck_preprocess(scope);
} }
@ -642,13 +645,19 @@ namespace AST {
auto bool_ty = std::shared_ptr<types::Type>{ auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
this->m_init->typecheck(state, scope); if (this->m_init)
auto cond_ty = this->m_cond->typecheck(state, scope, bool_ty).type; (*this->m_init)->typecheck(state, scope);
if (this->m_cond) {
auto cond_ty = (*this->m_cond)->typecheck(state, scope, bool_ty).type;
auto check_res = check_type(state, cond_ty, bool_ty); 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_cond = handle_res(std::move(*this->m_cond), check_res, state);
}
if (this->m_after)
(*this->m_after)->typecheck(state, scope, {});
this->m_after->typecheck(state, scope, {});
this->m_loop->typecheck(state, scope); this->m_loop->typecheck(state, scope);
} }