diff --git a/compiler/include/compiler/ast/node.hpp b/compiler/include/compiler/ast/node.hpp index 0e87bc73..b837e6b8 100644 --- a/compiler/include/compiler/ast/node.hpp +++ b/compiler/include/compiler/ast/node.hpp @@ -9,6 +9,7 @@ #include "compiler/utils/source_ref.hpp" #include "compiler/ast/node_type.hpp" +#include "compiler/ast/types.hpp" #include "compiler/ast/variables_table.hpp" namespace ast { @@ -26,6 +27,7 @@ struct Node { * value type : node type * long int : IntegerLiteralValue * double : FloatingPointLiteralValue + * bool : BooleanLiteralValue * std::string : StringLiteralValue, FunctionName, VariableName * TypeId : TypeName * BinaryOperation : BinaryOperation @@ -34,7 +36,7 @@ struct Node { * nothing : other types */ NodeType type; - std::variant value; + std::variant value; const long int &intNum() const { return std::get(value); @@ -42,6 +44,9 @@ struct Node { const double &fpNum() const { return std::get(value); } + const bool &boolean() const { + return std::get(value); + } const std::string &str() const { return std::get(value); } diff --git a/compiler/include/compiler/ast/node_type.hpp b/compiler/include/compiler/ast/node_type.hpp index 953e0bd9..465a5072 100644 --- a/compiler/include/compiler/ast/node_type.hpp +++ b/compiler/include/compiler/ast/node_type.hpp @@ -39,6 +39,7 @@ enum class UnaryOperation { enum class NodeType { BinaryOperation, + BooleanLiteralValue, BranchRoot, ElifStatement, ElseStatement, diff --git a/compiler/lib/ast/node.cpp b/compiler/lib/ast/node.cpp index 6a8c4e0f..4d6dde06 100644 --- a/compiler/lib/ast/node.cpp +++ b/compiler/lib/ast/node.cpp @@ -3,6 +3,8 @@ #include #include +#include "node_type.hpp" + using namespace ast; namespace { @@ -103,6 +105,9 @@ void Node::dump(std::ostream &stream, int depth) const { case NodeType::BinaryOperation: stream << "BinaryOperation: " << binaryOperationToString(binOp()) << "\n"; break; + case NodeType::BooleanLiteralValue: + stream << "BooleanLiteralValue: " << (boolean() ? "True" : "False") << "\n"; + break; case NodeType::BranchRoot: stream << "BranchRoot"; if (std::holds_alternative(value)) { diff --git a/compiler/lib/frontend/parser/parser.cpp b/compiler/lib/frontend/parser/parser.cpp index 4a968b6e..28ee8926 100644 --- a/compiler/lib/frontend/parser/parser.cpp +++ b/compiler/lib/frontend/parser/parser.cpp @@ -4,6 +4,10 @@ #include #include +#include "compiler/ast/node.hpp" +#include "compiler/ast/node_type.hpp" + +#include "lexer/token_types.hpp" #include "parser/parser_context.hpp" #include "parser/parser_error.hpp" #include "parser/type_registry.hpp" @@ -88,7 +92,8 @@ OperationType getOperationType(const ast::Node &node) { ExpressionTokenType getExpressionTokenType(const Token &token) { if (token.type == TokenType::Identifier || token.type == TokenType::IntegerLiteral || - token.type == TokenType::FloatingPointLiteral || token.type == TokenType::StringLiteral) + token.type == TokenType::FloatingPointLiteral || token.type == TokenType::StringLiteral || + token.is(Keyword::True) || token.is(Keyword::False)) return ExpressionTokenType::Operand; if (token.is(Operator::LeftBrace)) return ExpressionTokenType::OpeningBrace; @@ -163,6 +168,9 @@ size_t getOperationPriority(const Token &token) { case BinaryOperation::Greater: case BinaryOperation::GreaterEqual: return 30; + case BinaryOperation::Equal: + case BinaryOperation::NotEqual: + return 35; case BinaryOperation::And: return 40; case BinaryOperation::Or: @@ -222,6 +230,13 @@ void buildExpressionSubtree(std::stack postfixForm, ast::Node::Pt ast::Node::Ptr node = ParserContext::unshiftChildNode(currNode, ast::NodeType::StringLiteralValue, token.ref); node->value = token.literal(); + } else if (token.is(Keyword::False) || token.is(Keyword::True)) { + ast::Node::Ptr node = + ParserContext::unshiftChildNode(currNode, ast::NodeType::BooleanLiteralValue, token.ref); + if (token.is(Keyword::True)) + node->value = true; + else if (token.is(Keyword::False)) + node->value = false; } } } else { diff --git a/compiler/tests/.clang-tidy b/compiler/tests/.clang-tidy new file mode 100644 index 00000000..e2eac699 --- /dev/null +++ b/compiler/tests/.clang-tidy @@ -0,0 +1 @@ +Checks: -*,cppcoreguidelines-avoid-goto diff --git a/compiler/tests/frontend/parser.cpp b/compiler/tests/frontend/parser.cpp index 6771234b..425ec64c 100644 --- a/compiler/tests/frontend/parser.cpp +++ b/compiler/tests/frontend/parser.cpp @@ -460,3 +460,34 @@ TEST(Parser, can_parse_complex_nested_function_call) { " VariableName: z\n"; ASSERT_EQ(tree_str, tree.dump()); } + +TEST(Parser, can_parse_bool) { + StringVec source = { + "def main() -> None:", + " x: bool = True", + " x = (3 == 4) and False", + }; + TokenList tokens = Lexer::process(source); + + SyntaxTree tree = Parser::process(tokens); + std::string expected = "ProgramRoot\n" + " FunctionDefinition\n" + " FunctionName: main\n" + " FunctionArguments\n" + " FunctionReturnType: NoneType\n" + " BranchRoot\n" + " VariableDeclaration\n" + " TypeName: BoolType\n" + " VariableName: x\n" + " Expression\n" + " BooleanLiteralValue: True\n" + " Expression\n" + " BinaryOperation: Assign\n" + " VariableName: x\n" + " BinaryOperation: And\n" + " BinaryOperation: Equal\n" + " IntegerLiteralValue: 3\n" + " IntegerLiteralValue: 4\n" + " BooleanLiteralValue: False\n"; + ASSERT_EQ(expected, tree.dump()); +}