Skip to content

Commit

Permalink
Merge pull request #44 from BastianBlokland/feature/char-type
Browse files Browse the repository at this point in the history
Character type
  • Loading branch information
BastianBlokland committed Jan 8, 2020
2 parents 1e3b64d + 25b2afe commit 4e99f49
Show file tree
Hide file tree
Showing 49 changed files with 732 additions and 56 deletions.
2 changes: 2 additions & 0 deletions apps/progdiag/get_expr_color.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class GetExprColor final : public prog::expr::NodeVisitor {
m_fg = rang::fg::cyan;
}

auto visit(const prog::expr::LitCharNode & /*unused*/) -> void override { m_fg = rang::fg::cyan; }

private:
rang::fg m_fg{};
};
Expand Down
3 changes: 3 additions & 0 deletions include/backend/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Builder final {
auto addOrInt() -> void;
auto addXorInt() -> void;
auto addLengthString() -> void;
auto addIndexString() -> void;

auto addCheckEqInt() -> void;
auto addCheckEqFloat() -> void;
Expand All @@ -65,6 +66,8 @@ class Builder final {
auto addConvIntString() -> void;
auto addConvFloatString() -> void;
auto addConvBoolString() -> void;
auto addConvCharString() -> void;
auto addConvIntChar() -> void;

auto addMakeStruct(uint8_t fieldCount) -> void;
auto addLoadStructField(uint8_t fieldIndex) -> void;
Expand Down
8 changes: 8 additions & 0 deletions include/lex/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ namespace lex {

[[nodiscard]] auto errLitStrInvalidEscape(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto erLitCharEmpty(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto errLitCharTooBig(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto errLitCharUnterminated(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto errLitCharInvalidEscape(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto errIdentifierIllegalCharacter(input::Span span = input::Span{0}) -> Token;

[[nodiscard]] auto errIdentifierIllegalSequence(input::Span span = input::Span{0}) -> Token;
Expand Down
2 changes: 2 additions & 0 deletions include/lex/lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class LexerImpl {
auto nextLitIntHex() -> Token;
auto nextLitIntBinary() -> Token;
auto nextLitIntOctal() -> Token;

auto nextLitStr() -> Token;
auto nextLitChar() -> Token;
auto nextWordToken(char startingChar) -> Token;
auto nextLineComment() -> Token;

Expand Down
2 changes: 2 additions & 0 deletions include/lex/token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ auto litBoolToken(bool val, input::Span span = input::Span{0}) -> Token;

auto litStrToken(std::string val, input::Span span = input::Span{0}) -> Token;

auto litCharToken(uint8_t val, input::Span span = input::Span{0}) -> Token;

auto keywordToken(Keyword keyword, input::Span span = input::Span{0}) -> Token;

auto identiferToken(std::string id, input::Span span = input::Span{0}) -> Token;
Expand Down
1 change: 1 addition & 0 deletions include/lex/token_kind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum class TokenKind {
LitFloat,
LitBool,
LitString,
LitChar,
Keyword,
Identifier,
LineComment,
Expand Down
32 changes: 32 additions & 0 deletions include/lex/token_payload_lit_char.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once
#include "lex/token_payload.hpp"

namespace lex {

class LitCharTokenPayload final : public TokenPayload {
public:
LitCharTokenPayload() = delete;
explicit LitCharTokenPayload(const uint8_t val) : m_val{val} {}

auto operator==(const TokenPayload& rhs) const noexcept -> bool override {
const auto castedRhs = dynamic_cast<const LitCharTokenPayload*>(&rhs);
return castedRhs != nullptr && m_val == castedRhs->m_val;
}

auto operator!=(const TokenPayload& rhs) const noexcept -> bool override {
return !LitCharTokenPayload::operator==(rhs);
}

[[nodiscard]] auto clone() -> std::unique_ptr<TokenPayload> override {
return std::make_unique<LitCharTokenPayload>(*this);
}

[[nodiscard]] auto getValue() const noexcept { return m_val; }

private:
const uint8_t m_val;

auto print(std::ostream& out) const -> std::ostream& override;
};

} // namespace lex
35 changes: 35 additions & 0 deletions include/prog/expr/node_lit_char.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once
#include "prog/expr/node.hpp"
#include "prog/program.hpp"

namespace prog::expr {

class LitCharNode final : public Node {
friend auto litCharNode(const Program& program, uint8_t val) -> NodePtr;

public:
LitCharNode() = delete;

auto operator==(const Node& rhs) const noexcept -> bool override;
auto operator!=(const Node& rhs) const noexcept -> bool override;

[[nodiscard]] auto operator[](unsigned int i) const -> const Node& override;
[[nodiscard]] auto getChildCount() const -> unsigned int override;
[[nodiscard]] auto getType() const noexcept -> sym::TypeId override;
[[nodiscard]] auto toString() const -> std::string override;

[[nodiscard]] auto getVal() const noexcept -> uint8_t;

auto accept(NodeVisitor* visitor) const -> void override;

private:
sym::TypeId m_type;
uint8_t m_val;

LitCharNode(sym::TypeId type, uint8_t val);
};

// Factories.
auto litCharNode(const Program& program, uint8_t val) -> NodePtr;

} // namespace prog::expr
2 changes: 2 additions & 0 deletions include/prog/expr/node_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class LitFloatNode;
class LitFuncNode;
class LitIntNode;
class LitStringNode;
class LitCharNode;

class NodeVisitor {
public:
Expand All @@ -37,6 +38,7 @@ class NodeVisitor {
virtual auto visit(const LitFuncNode& n) -> void = 0;
virtual auto visit(const LitIntNode& n) -> void = 0;
virtual auto visit(const LitStringNode& n) -> void = 0;
virtual auto visit(const LitCharNode& n) -> void = 0;
};

} // namespace prog::expr
1 change: 1 addition & 0 deletions include/prog/expr/nodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "prog/expr/node_field.hpp"
#include "prog/expr/node_group.hpp"
#include "prog/expr/node_lit_bool.hpp"
#include "prog/expr/node_lit_char.hpp"
#include "prog/expr/node_lit_float.hpp"
#include "prog/expr/node_lit_func.hpp"
#include "prog/expr/node_lit_int.hpp"
Expand Down
2 changes: 2 additions & 0 deletions include/prog/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Program final {
[[nodiscard]] auto getFloat() const noexcept -> sym::TypeId;
[[nodiscard]] auto getBool() const noexcept -> sym::TypeId;
[[nodiscard]] auto getString() const noexcept -> sym::TypeId;
[[nodiscard]] auto getChar() const noexcept -> sym::TypeId;

[[nodiscard]] auto lookupType(const std::string& name) const -> std::optional<sym::TypeId>;
[[nodiscard]] auto
Expand Down Expand Up @@ -125,6 +126,7 @@ class Program final {
sym::TypeId m_float;
sym::TypeId m_bool;
sym::TypeId m_string;
sym::TypeId m_char;
};

} // namespace prog
3 changes: 3 additions & 0 deletions include/prog/sym/func_kind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ enum class FuncKind {

AddString,
LengthString,
IndexString,
CheckEqString,
CheckNEqString,

Expand All @@ -50,6 +51,8 @@ enum class FuncKind {
ConvIntString,
ConvFloatString,
ConvBoolString,
ConvCharString,
ConvIntChar,

DefInt,
DefFloat,
Expand Down
1 change: 1 addition & 0 deletions include/prog/sym/type_kind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum class TypeKind {
Float,
Bool,
String,
Char,
UserStruct,
UserUnion,
UserDelegate,
Expand Down
3 changes: 3 additions & 0 deletions include/vm/opcode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum class OpCode : uint8_t {
OrInt = 66,
XorInt = 67,
LengthString = 68,
IndexString = 69,

CheckEqInt = 80,
CheckEqFloat = 81,
Expand All @@ -53,6 +54,8 @@ enum class OpCode : uint8_t {
ConvFloatInt = 92,
ConvIntString = 93,
ConvFloatString = 94,
ConvCharString = 95,
ConvIntChar = 96,

MakeStruct = 100,
LoadStructField = 101,
Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_library(lex STATIC
lex/token.cpp
lex/token_cat.cpp
lex/token_kind.cpp
lex/token_payload_lit_char.cpp
lex/token_payload_lit_string.cpp
lex/keyword.cpp
lex/utilities.cpp)
Expand Down Expand Up @@ -80,6 +81,7 @@ add_library(prog STATIC
prog/expr/node_lit_func.cpp
prog/expr/node_lit_int.cpp
prog/expr/node_lit_string.cpp
prog/expr/node_lit_char.cpp
prog/expr/node_switch.cpp
prog/expr/node_union_check.cpp
prog/expr/node_union_get.cpp
Expand Down Expand Up @@ -195,6 +197,7 @@ add_library(vm STATIC
vm/internal/call_stack.cpp
vm/internal/const_stack.cpp
vm/internal/exec_scope.cpp
vm/internal/string_utilities.cpp
vm/io/memory_interface.cpp
vm/io/terminal_interface.cpp
vm/assembly.cpp
Expand Down
6 changes: 6 additions & 0 deletions src/backend/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ auto Builder::addXorInt() -> void { writeOpCode(vm::OpCode::XorInt); }

auto Builder::addLengthString() -> void { writeOpCode(vm::OpCode::LengthString); }

auto Builder::addIndexString() -> void { writeOpCode(vm::OpCode::IndexString); }

auto Builder::addCheckEqInt() -> void { writeOpCode(vm::OpCode::CheckEqInt); }

auto Builder::addCheckEqFloat() -> void { writeOpCode(vm::OpCode::CheckEqFloat); }
Expand Down Expand Up @@ -144,6 +146,10 @@ auto Builder::addConvBoolString() -> void {
label(endLabel);
}

auto Builder::addConvCharString() -> void { writeOpCode(vm::OpCode::ConvCharString); }

auto Builder::addConvIntChar() -> void { writeOpCode(vm::OpCode::ConvIntChar); }

auto Builder::addMakeStruct(uint8_t fieldCount) -> void {
writeOpCode(vm::OpCode::MakeStruct);
writeUInt8(fieldCount);
Expand Down
3 changes: 3 additions & 0 deletions src/backend/dasm/disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ auto disassembleInstructions(const vm::Assembly& assembly) -> std::vector<Instru
case vm::OpCode::OrInt:
case vm::OpCode::XorInt:
case vm::OpCode::LengthString:
case vm::OpCode::IndexString:
case vm::OpCode::CheckEqInt:
case vm::OpCode::CheckEqFloat:
case vm::OpCode::CheckEqString:
Expand All @@ -62,6 +63,8 @@ auto disassembleInstructions(const vm::Assembly& assembly) -> std::vector<Instru
case vm::OpCode::ConvFloatInt:
case vm::OpCode::ConvIntString:
case vm::OpCode::ConvFloatString:
case vm::OpCode::ConvCharString:
case vm::OpCode::ConvIntChar:
case vm::OpCode::PrintString:
case vm::OpCode::CallDyn:
case vm::OpCode::CallDynTail:
Expand Down
13 changes: 13 additions & 0 deletions src/backend/internal/gen_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ auto GenExpr::visit(const prog::expr::CallExprNode& n) -> void {
case prog::sym::FuncKind::LengthString:
m_builder->addLengthString();
break;
case prog::sym::FuncKind::IndexString:
m_builder->addIndexString();
break;
case prog::sym::FuncKind::CheckEqString:
m_builder->addCheckEqString();
break;
Expand All @@ -218,6 +221,12 @@ auto GenExpr::visit(const prog::expr::CallExprNode& n) -> void {
case prog::sym::FuncKind::ConvBoolString:
m_builder->addConvBoolString();
break;
case prog::sym::FuncKind::ConvCharString:
m_builder->addConvCharString();
break;
case prog::sym::FuncKind::ConvIntChar:
m_builder->addConvIntChar();
break;

case prog::sym::FuncKind::DefInt:
m_builder->addLoadLitInt(0);
Expand Down Expand Up @@ -404,6 +413,10 @@ auto GenExpr::visit(const prog::expr::LitStringNode& n) -> void {
m_builder->addLoadLitString(n.getVal());
}

auto GenExpr::visit(const prog::expr::LitCharNode& n) -> void {
m_builder->addLoadLitInt(n.getVal());
}

auto GenExpr::genSubExpr(const prog::expr::Node& n, bool tail) -> void {
auto genExpr = GenExpr{m_program, m_builder, tail};
n.accept(&genExpr);
Expand Down
1 change: 1 addition & 0 deletions src/backend/internal/gen_expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class GenExpr final : public prog::expr::NodeVisitor {
auto visit(const prog::expr::LitFuncNode& n) -> void override;
auto visit(const prog::expr::LitIntNode& n) -> void override;
auto visit(const prog::expr::LitStringNode& n) -> void override;
auto visit(const prog::expr::LitCharNode& n) -> void override;

private:
const prog::Program& m_program;
Expand Down
1 change: 1 addition & 0 deletions src/backend/internal/gen_type_eq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ static auto genTypeEquality(Builder* builder, const prog::sym::TypeDecl& typeDec
switch (typeDecl.getKind()) {
case prog::sym::TypeKind::Bool:
case prog::sym::TypeKind::Int:
case prog::sym::TypeKind::Char:
builder->addCheckEqInt();
break;
case prog::sym::TypeKind::Float:
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/internal/check_union_exhaustiveness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,6 @@ auto CheckUnionExhaustiveness::visit(const prog::expr::LitIntNode & /*unused*/)

auto CheckUnionExhaustiveness::visit(const prog::expr::LitStringNode & /*unused*/) -> void {}

auto CheckUnionExhaustiveness::visit(const prog::expr::LitCharNode & /*unused*/) -> void {}

} // namespace frontend::internal
1 change: 1 addition & 0 deletions src/frontend/internal/check_union_exhaustiveness.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class CheckUnionExhaustiveness final : public prog::expr::NodeVisitor {
auto visit(const prog::expr::LitFuncNode& n) -> void override;
auto visit(const prog::expr::LitIntNode& n) -> void override;
auto visit(const prog::expr::LitStringNode& n) -> void override;
auto visit(const prog::expr::LitCharNode& n) -> void override;

private:
const Context& m_context;
Expand Down
5 changes: 5 additions & 0 deletions src/frontend/internal/get_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "internal/get_identifier.hpp"
#include "internal/utilities.hpp"
#include "lex/token_payload_lit_bool.hpp"
#include "lex/token_payload_lit_char.hpp"
#include "lex/token_payload_lit_float.hpp"
#include "lex/token_payload_lit_int.hpp"
#include "lex/token_payload_lit_string.hpp"
Expand Down Expand Up @@ -419,6 +420,10 @@ auto GetExpr::visit(const parse::LitExprNode& n) -> void {
m_expr = prog::expr::litStringNode(
*m_context->getProg(), n.getVal().getPayload<lex::LitStringTokenPayload>()->getValue());
return;
case lex::TokenKind::LitChar:
m_expr = prog::expr::litCharNode(
*m_context->getProg(), n.getVal().getPayload<lex::LitCharTokenPayload>()->getValue());
return;
default:
std::stringstream oss;
oss << n.getVal().getKind();
Expand Down
15 changes: 7 additions & 8 deletions src/frontend/internal/typeinfer_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,22 +227,21 @@ auto TypeInferExpr::visit(const parse::IsExprNode& n) -> void {

auto TypeInferExpr::visit(const parse::LitExprNode& n) -> void {
switch (n.getVal().getKind()) {
case lex::TokenKind::LitInt: {
case lex::TokenKind::LitInt:
m_type = m_context->getProg()->getInt();
break;
}
case lex::TokenKind::LitFloat: {
case lex::TokenKind::LitFloat:
m_type = m_context->getProg()->getFloat();
break;
}
case lex::TokenKind::LitBool: {
case lex::TokenKind::LitBool:
m_type = m_context->getProg()->getBool();
break;
}
case lex::TokenKind::LitString: {
case lex::TokenKind::LitString:
m_type = m_context->getProg()->getString();
break;
}
case lex::TokenKind::LitChar:
m_type = m_context->getProg()->getChar();
break;
default:
break;
}
Expand Down
Loading

0 comments on commit 4e99f49

Please sign in to comment.