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();
|
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::string ReturnStatement::formatted() {
|
||||||
std::stringstream out{ "" };
|
std::stringstream out{ "" };
|
||||||
out << "return ";
|
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;
|
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 {
|
class TopLevelStatement : public Node {
|
||||||
public:
|
public:
|
||||||
TopLevelStatement(token::Metadata meta) : Node{ meta } {}
|
TopLevelStatement(token::Metadata meta) : Node{ meta } {}
|
||||||
|
|||||||
@ -557,6 +557,15 @@ namespace AST {
|
|||||||
builder.builder->SetInsertPoint(after_block);
|
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) {
|
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
std::shared_ptr<types::Type> ret_ty_ptr{ this->m_return_ty };
|
std::shared_ptr<types::Type> ret_ty_ptr{ this->m_return_ty };
|
||||||
|
|||||||
@ -93,4 +93,11 @@ namespace AST {
|
|||||||
(*this->m_else)->codegen_alloca(allocator);
|
(*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) {
|
void Function::typecheck_preprocess(typecheck::Scope& scope) {
|
||||||
this->m_return_ty = refresh_type(scope, this->m_return_ty);
|
this->m_return_ty = refresh_type(scope, this->m_return_ty);
|
||||||
for (auto& param : this->m_params) {
|
for (auto& param : this->m_params) {
|
||||||
|
|||||||
6
test.c
6
test.c
@ -51,9 +51,9 @@ int main() {
|
|||||||
twod_array[0][0] = 50;
|
twod_array[0][0] = 50;
|
||||||
printf("2d array: %d!\n", twod_array[0][0]);
|
printf("2d array: %d!\n", twod_array[0][0]);
|
||||||
|
|
||||||
int counter = 0;
|
for (int counter = 0; counter < 10; counter++) {
|
||||||
int a = -500;
|
printf("counter: %d\n", counter);
|
||||||
printf("a: %d\n", a);
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user