Corrected parsing bool literal by setting lexer priority
This commit is contained in:
parent
81b677b9fe
commit
8835751449
24
.vscode/launch.json
vendored
24
.vscode/launch.json
vendored
@ -51,6 +51,30 @@
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Bool Test",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tests/bool_tests",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -7,6 +7,8 @@ SET (ANTLR_INCLUDE_DIR /usr/local/include/antlr4-runtime/)
|
||||
SET (ANTLR_GENERATED_DIR "${CMAKE_BINARY_DIR}/antlr4/generated")
|
||||
SET (GRAMMAR_FILE "${CMAKE_SOURCE_DIR}/Hoo.g4")
|
||||
SET (LLVM_LIBRARY_DIRS "/usr/lib/llvm-19/lib")
|
||||
set(CMAKE_INSTALL_RPATH "/usr/local/lib")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
LINK_DIRECTORIES(${LLVM_LIBRARY_DIRS})
|
||||
FIND_PACKAGE(LLVM REQUIRED CONFIG)
|
||||
ADD_DEFINITIONS(${LLVM_DEFINITIONS})
|
||||
@ -26,3 +28,4 @@ ADD_SUBDIRECTORY(tests)
|
||||
ENABLE_TESTING()
|
||||
ADD_TEST(NAME integer_tests COMMAND integer_tests)
|
||||
ADD_TEST(NAME double_tests COMMAND double_tests)
|
||||
ADD_TEST(NAME bool_tests COMMAND bool_tests)
|
||||
12
HooLexer.g4
12
HooLexer.g4
@ -1,16 +1,10 @@
|
||||
lexer grammar HooLexer;
|
||||
|
||||
IDENTIFIER: Letter LetterOrDigit*;
|
||||
|
||||
fragment DIGIT: [0-9];
|
||||
BOOL_LITERAL: 'true' | 'false';
|
||||
|
||||
INTEGER_LITERAL: '0' | ('+' | '-')? [1-9] [0-9]*;
|
||||
|
||||
DOUBLE_LITERAL: ('+' | '-')? Digits+ '.' Digits+ (
|
||||
[eE] [+-]? Digits+
|
||||
)?;
|
||||
|
||||
BOOL_LITERAL: 'true' | 'false';
|
||||
DOUBLE_LITERAL: ('+' | '-')? Digits+ '.' Digits+;
|
||||
|
||||
CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\'';
|
||||
|
||||
@ -24,6 +18,8 @@ WS: [ \t\r\n\u000C]+ -> channel(HIDDEN);
|
||||
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
|
||||
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
|
||||
|
||||
IDENTIFIER: Letter LetterOrDigit*;
|
||||
|
||||
fragment EscapeSequence:
|
||||
'\\' 'u005c'? [btnfr"'\\]
|
||||
| '\\' 'u005c'? ([0-3]? [0-7])? [0-7]
|
||||
|
||||
@ -14,6 +14,11 @@ Visitor::Visitor(const std::string &moduleName) : _moduleName(moduleName),
|
||||
|
||||
std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
auto text = ctx->getText();
|
||||
std::cout << "Literal: " << text << std::endl;
|
||||
#endif
|
||||
|
||||
auto value = ctx->INTEGER_LITERAL();
|
||||
if (value)
|
||||
{
|
||||
@ -22,7 +27,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
||||
llvm::Type *decimalType = llvm::Type::getInt64Ty(*_context);
|
||||
llvm::Constant *decimalConstant = llvm::ConstantInt::getSigned(decimalType, decimalValue);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#ifndef NDEBUG
|
||||
auto constantValue = llvm::dyn_cast<llvm::ConstantInt>(decimalConstant)->getValue().getSExtValue();
|
||||
assert(constantValue == decimalValue);
|
||||
#endif
|
||||
|
||||
@ -7,3 +7,7 @@ TARGET_INCLUDE_DIRECTORIES(integer_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
ADD_EXECUTABLE(double_tests double_tests.cpp)
|
||||
TARGET_LINK_LIBRARIES(double_tests GTest::GTest GTest::Main hoocore antlr4-runtime LLVMCore LLVMSupport)
|
||||
TARGET_INCLUDE_DIRECTORIES(double_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
|
||||
|
||||
ADD_EXECUTABLE(bool_tests bool_tests.cpp)
|
||||
TARGET_LINK_LIBRARIES(bool_tests GTest::GTest GTest::Main hoocore antlr4-runtime LLVMCore LLVMSupport)
|
||||
TARGET_INCLUDE_DIRECTORIES(bool_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src)
|
||||
71
tests/bool_tests.cpp
Normal file
71
tests/bool_tests.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "Compiler.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Utility function to test boolean literal compilation
|
||||
void testBoolLiteral(const std::string &input, bool expectedValue)
|
||||
{
|
||||
auto compiler = std::make_unique<Compiler>(input, "main");
|
||||
auto result = compiler->compile();
|
||||
auto boolNode = std::any_cast<Node>(result);
|
||||
|
||||
// Validate node type and data type
|
||||
ASSERT_EQ(boolNode.getNodeType(), NODE_LITERAL);
|
||||
ASSERT_EQ(boolNode.getDataType(), DATATYPE_BOOL);
|
||||
|
||||
// Validate LLVM value
|
||||
auto value = boolNode.getValue();
|
||||
ASSERT_NE(value, nullptr);
|
||||
|
||||
auto value_constant = llvm::dyn_cast<llvm::ConstantInt>(value);
|
||||
ASSERT_NE(value_constant, nullptr);
|
||||
|
||||
// Check the boolean value (1 for true, 0 for false)
|
||||
ASSERT_EQ(value_constant->getValue().getLimitedValue(), static_cast<uint64_t>(expectedValue));
|
||||
}
|
||||
|
||||
// Test fixture for boolean tests
|
||||
class BoolTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
// Setup code if needed
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
// Cleanup code if needed
|
||||
}
|
||||
};
|
||||
|
||||
// Test cases
|
||||
TEST_F(BoolTest, LiteralTrue)
|
||||
{
|
||||
testBoolLiteral("true;", true);
|
||||
}
|
||||
|
||||
TEST_F(BoolTest, LiteralFalse)
|
||||
{
|
||||
testBoolLiteral("false;", false);
|
||||
}
|
||||
|
||||
// Negative test cases
|
||||
TEST_F(BoolTest, InvalidLiteral)
|
||||
{
|
||||
auto compiler = std::make_unique<Compiler>("notbool;", "main");
|
||||
ASSERT_THROW(compiler->compile(), std::invalid_argument);
|
||||
}
|
||||
|
||||
TEST_F(BoolTest, MissingSemicolon)
|
||||
{
|
||||
auto compiler = std::make_unique<Compiler>("true", "main");
|
||||
ASSERT_THROW(compiler->compile(), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_F(BoolTest, MixedCaseLiteral)
|
||||
{
|
||||
auto compiler = std::make_unique<Compiler>("True;", "main");
|
||||
ASSERT_THROW(compiler->compile(), std::invalid_argument); // Expect strict case-sensitivity
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user