Parse if-statements
This commit is contained in:
parent
f59b5db29b
commit
97745ffbb0
@ -28,6 +28,15 @@ namespace AST {
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string IfStatement::formatted() {
|
||||||
|
std::stringstream out{ "if " };
|
||||||
|
out << this->m_condition->formatted();
|
||||||
|
out << "\n then " << this->m_then->formatted();
|
||||||
|
if (this->m_else.has_value())
|
||||||
|
out << "\n else " << (*this->m_else)->formatted();
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string ReturnStatement::formatted() {
|
std::string ReturnStatement::formatted() {
|
||||||
std::stringstream out{ "" };
|
std::stringstream out{ "" };
|
||||||
out << "return ";
|
out << "return ";
|
||||||
|
|||||||
18
src/ast.h
18
src/ast.h
@ -96,6 +96,24 @@ namespace AST {
|
|||||||
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IfStatement : public Statement {
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Expression> m_condition;
|
||||||
|
std::unique_ptr<Statement> m_then;
|
||||||
|
std::optional<std::unique_ptr<Statement>> m_else;
|
||||||
|
public:
|
||||||
|
IfStatement(std::unique_ptr<Expression> condition,
|
||||||
|
std::unique_ptr<Statement> then_statement,
|
||||||
|
std::optional<std::unique_ptr<Statement>> else_statement)
|
||||||
|
: m_condition{ std::move(condition) }
|
||||||
|
, m_then{ std::move(then_statement) }
|
||||||
|
, m_else{ std::move(else_statement) } {
|
||||||
|
}
|
||||||
|
virtual ~IfStatement() override = default;
|
||||||
|
virtual std::string formatted() override;
|
||||||
|
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
||||||
|
};
|
||||||
|
|
||||||
class TopLevelStatement : public Node {
|
class TopLevelStatement : public Node {
|
||||||
public:
|
public:
|
||||||
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
|
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
|
||||||
|
|||||||
@ -110,6 +110,14 @@ namespace AST {
|
|||||||
scope.values[this->m_name] = codegen::StackValue{ ptr, std::move(this->m_type) };
|
scope.values[this->m_name] = codegen::StackValue{ ptr, std::move(this->m_type) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IfStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
|
if (!builder.block)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
codegen::Scope inner_scope{ scope };
|
codegen::Scope inner_scope{ scope };
|
||||||
|
|
||||||
|
|||||||
@ -148,6 +148,28 @@ namespace parsing {
|
|||||||
auto ret = new AST::ReturnStatement{ std::move(expression) };
|
auto ret = new AST::ReturnStatement{ std::move(expression) };
|
||||||
return new std::unique_ptr<AST::Statement>{ ret };
|
return new std::unique_ptr<AST::Statement>{ ret };
|
||||||
}
|
}
|
||||||
|
else if (inner.peek().type == token::Type::IfKeyword) {
|
||||||
|
inner.next();
|
||||||
|
inner.expect(token::Type::Symbol, "(");
|
||||||
|
auto expression = parse_expression(inner).unwrap();
|
||||||
|
inner.expect(token::Type::Symbol, ")");
|
||||||
|
|
||||||
|
auto then_statement = parse_statement(inner).unwrap();
|
||||||
|
std::optional<std::unique_ptr<AST::Statement>> else_statement{};
|
||||||
|
if (inner.peek().type == token::Type::ElseKeyword) {
|
||||||
|
inner.next();
|
||||||
|
else_statement = parse_statement(inner).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.m_position = inner.m_position;
|
||||||
|
|
||||||
|
auto statement = new AST::IfStatement{
|
||||||
|
std::move(expression),
|
||||||
|
std::move(then_statement),
|
||||||
|
std::move(else_statement)
|
||||||
|
};
|
||||||
|
return new std::unique_ptr<AST::Statement>{ statement };
|
||||||
|
}
|
||||||
else if (auto init = parse_init_statement(inner); init.ok()) {
|
else if (auto init = parse_init_statement(inner); init.ok()) {
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
return new std::unique_ptr<AST::Statement>{ init.unwrap() };
|
return new std::unique_ptr<AST::Statement>{ init.unwrap() };
|
||||||
|
|||||||
@ -26,6 +26,10 @@ namespace token {
|
|||||||
|
|
||||||
case token::Type::ReturnKeyword:
|
case token::Type::ReturnKeyword:
|
||||||
return "Return";
|
return "Return";
|
||||||
|
case token::Type::IfKeyword:
|
||||||
|
return "If";
|
||||||
|
case token::Type::ElseKeyword:
|
||||||
|
return "Else";
|
||||||
|
|
||||||
case token::Type::Whitespace:
|
case token::Type::Whitespace:
|
||||||
return "Whitespace";
|
return "Whitespace";
|
||||||
@ -110,6 +114,12 @@ namespace token {
|
|||||||
if (content == "return") {
|
if (content == "return") {
|
||||||
type = token::Type::ReturnKeyword;
|
type = token::Type::ReturnKeyword;
|
||||||
}
|
}
|
||||||
|
else if (content == "if") {
|
||||||
|
type = token::Type::IfKeyword;
|
||||||
|
}
|
||||||
|
else if (content == "else") {
|
||||||
|
type = token::Type::ElseKeyword;
|
||||||
|
}
|
||||||
tokens.push_back(token::Token{ type, content });
|
tokens.push_back(token::Token{ type, content });
|
||||||
}
|
}
|
||||||
else if (iswhitespace(c)) {
|
else if (iswhitespace(c)) {
|
||||||
|
|||||||
@ -12,6 +12,8 @@ namespace token {
|
|||||||
LiteralInt,
|
LiteralInt,
|
||||||
|
|
||||||
ReturnKeyword,
|
ReturnKeyword,
|
||||||
|
IfKeyword,
|
||||||
|
ElseKeyword,
|
||||||
|
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user