Add for-loop AST
This commit is contained in:
parent
ba21718f71
commit
8d826326fa
11
src/ast.cpp
11
src/ast.cpp
@ -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 ";
|
||||
|
||||
27
src/ast.h
27
src/ast.h
@ -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 } {}
|
||||
|
||||
@ -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 };
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user