Skip to content

Commit

Permalink
Merge pull request #45 from BastianBlokland/feature/qmarkqmark-operator
Browse files Browse the repository at this point in the history
Add '??' overloadable operator
  • Loading branch information
BastianBlokland committed Jan 8, 2020
2 parents 4e99f49 + adacc52 commit 532a3cf
Show file tree
Hide file tree
Showing 9 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/lex/token_kind.hpp
Expand Up @@ -27,6 +27,7 @@ enum class TokenKind {
OpGtEq,
OpSemi,
OpQMark,
OpQMarkQMark,
OpDot,
OpColonColon,
OpSquareSquare,
Expand Down
1 change: 1 addition & 0 deletions include/prog/operator.hpp
Expand Up @@ -24,6 +24,7 @@ enum class Operator {
ColonColon,
SquareSquare,
ParenParen,
QMarkQMark,
};

auto getFuncName(Operator op) -> std::string;
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/internal/utilities.cpp
Expand Up @@ -91,6 +91,8 @@ auto getOperator(const lex::Token& token) -> std::optional<prog::Operator> {
return prog::Operator::SquareSquare;
case lex::TokenKind::OpParenParen:
return prog::Operator::ParenParen;
case lex::TokenKind::OpQMarkQMark:
return prog::Operator::QMarkQMark;
default:
return std::nullopt;
}
Expand Down Expand Up @@ -138,6 +140,8 @@ auto getText(const prog::Operator& op) -> std::string {
return "[]";
case prog::Operator::ParenParen:
return "()";
case prog::Operator::QMarkQMark:
return "??";
}
return "__unknown";
}
Expand Down
4 changes: 4 additions & 0 deletions src/lex/lexer.cpp
Expand Up @@ -139,6 +139,10 @@ auto LexerImpl::next() -> Token {
case ';':
return basicToken(TokenKind::OpSemi, input::Span{m_inputPos});
case '?':
if (peekChar(0) == '?') {
consumeChar();
return basicToken(TokenKind::OpQMarkQMark, input::Span{m_inputPos - 1, m_inputPos});
}
return basicToken(TokenKind::OpQMark, input::Span{m_inputPos});
case '.':
if (isDigit(peekChar(0))) {
Expand Down
1 change: 1 addition & 0 deletions src/lex/token_cat.cpp
Expand Up @@ -56,6 +56,7 @@ auto lookupCat(const TokenKind kind) -> TokenCat {
case TokenKind::OpGtEq:
case TokenKind::OpSemi:
case TokenKind::OpQMark:
case TokenKind::OpQMarkQMark:
case TokenKind::OpDot:
case TokenKind::OpColonColon:
case TokenKind::OpSquareSquare:
Expand Down
3 changes: 3 additions & 0 deletions src/lex/token_kind.cpp
Expand Up @@ -70,6 +70,9 @@ auto operator<<(std::ostream& out, const TokenKind& rhs) -> std::ostream& {
case TokenKind::OpQMark:
out << "qmark";
break;
case TokenKind::OpQMarkQMark:
out << "qmarkqmark";
break;
case TokenKind::OpDot:
out << "dot";
break;
Expand Down
1 change: 1 addition & 0 deletions src/parse/op_precedence.cpp
Expand Up @@ -19,6 +19,7 @@ auto getRhsOpPrecedence(const lex::Token& token) -> int {
case lex::TokenKind::OpParenParen:
case lex::TokenKind::SepOpenParen:
case lex::TokenKind::SepOpenSquare:
case lex::TokenKind::OpQMarkQMark:
case lex::TokenKind::OpDot:
return callPrecedence;
case lex::TokenKind::OpStar:
Expand Down
2 changes: 2 additions & 0 deletions src/prog/operator.cpp
Expand Up @@ -45,6 +45,8 @@ auto getFuncName(Operator op) -> std::string {
return "__op_squaresquare";
case Operator::ParenParen:
return "__op_parenparen";
case Operator::QMarkQMark:
return "__op_qmarkqmark";
}
throw std::invalid_argument("Unknown operator");
}
Expand Down
1 change: 1 addition & 0 deletions tests/lex/operators_test.cpp
Expand Up @@ -26,6 +26,7 @@ TEST_CASE("Lexing operators", "[lex]") {
CHECK_TOKENS(">=", basicToken(TokenKind::OpGtEq));
CHECK_TOKENS(";", basicToken(TokenKind::OpSemi));
CHECK_TOKENS("?", basicToken(TokenKind::OpQMark));
CHECK_TOKENS("??", basicToken(TokenKind::OpQMarkQMark));
CHECK_TOKENS(".", basicToken(TokenKind::OpDot));
CHECK_TOKENS("::", basicToken(TokenKind::OpColonColon));
CHECK_TOKENS("[]", basicToken(TokenKind::OpSquareSquare));
Expand Down

0 comments on commit 532a3cf

Please sign in to comment.