diff --git a/src/ast.cpp b/src/ast.cpp index cd3f1f8..bdfa083 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -139,9 +139,15 @@ namespace AST { std::string ForStatement::formatted() { std::stringstream out{ "" }; - out << "(" << this->m_init->formatted(); - out << ";" << this->m_cond->formatted(); - out << ";" << this->m_after->formatted(); + out << "("; + if (this->m_init) + 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 << "\n then " << this->m_loop->formatted(); diff --git a/src/ast.h b/src/ast.h index 9f7dd4f..5639d1f 100644 --- a/src/ast.h +++ b/src/ast.h @@ -429,9 +429,9 @@ namespace AST { class ForStatement : public Statement { private: - std::unique_ptr m_init; - std::unique_ptr m_cond; - std::unique_ptr m_after; + std::optional> m_init; + std::optional> m_cond; + std::optional> m_after; std::unique_ptr m_loop; public: ForStatement(token::Metadata meta, diff --git a/src/stack_allocator.cpp b/src/stack_allocator.cpp index b7e6805..7f8f1ef 100644 --- a/src/stack_allocator.cpp +++ b/src/stack_allocator.cpp @@ -95,9 +95,12 @@ namespace AST { } 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); + if (this->m_init) + (*this->m_init)->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); } } \ No newline at end of file diff --git a/src/typechecker.cpp b/src/typechecker.cpp index 81b94f2..cd2cf49 100644 --- a/src/typechecker.cpp +++ b/src/typechecker.cpp @@ -632,9 +632,12 @@ 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); + if (this->m_init) + (*this->m_init)->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); } @@ -642,13 +645,19 @@ namespace AST { auto bool_ty = std::shared_ptr{ 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; + if (this->m_init) + (*this->m_init)->typecheck(state, scope); - auto check_res = check_type(state, cond_ty, bool_ty); - this->m_cond = handle_res(std::move(this->m_cond), check_res, state); + 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); + 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); }