Add bolt::TextFile and add testing infrasturcture

This commit is contained in:
Sam Vervaeck 2022-08-22 15:33:46 +02:00
parent 311f1d228b
commit a4a2b4cca5
4 changed files with 167 additions and 18 deletions

View file

@ -7,36 +7,72 @@ set(CMAKE_CXX_STANDARD 17)
add_subdirectory(deps/zen EXCLUDE_FROM_ALL)
add_executable(
bolt
set(ICU_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build/icu/install")
set(ICU_INCLUDE_DIRS "${ICU_DIR}/include")
set(ICU_LIBRARY_DIRS "${ICU_DIR}/lib")
add_library(
BoltCore
src/Text.cc
src/CST.cc
src/Diagnostics.cc
src/Scanner.cc
src/Parser.cc
src/Checker.cc
src/main.cc
)
target_link_directories(
BoltCore
PUBLIC
${ICU_LIBRARY_DIRS}
)
target_compile_options(
bolt
BoltCore
PUBLIC
-fstandalone-debug
)
target_include_directories(
bolt
BoltCore
PUBLIC
include
${ICU_LIBRARY_DIRS}
)
target_link_libraries(
BoltCore
PUBLIC
zen
icuuc
)
add_executable(
bolt
src/main.cc
)
target_link_libraries(
bolt
PUBLIC
zen
BoltCore
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/include/bolt/CST.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/CST.cc"
COMMAND scripts/gennodes.py --name=CST ./bolt-cst-spec.txt -Iinclude/ --include-root=bolt --source-root=src/ --namespace=bolt
DEPENDS scripts/gennodes.py
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/bolt-cst-spec.txt"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
if (BOLT_ENABLE_TESTS)
add_subdirectory(deps/googletest EXCLUDE_FROM_ALL)
add_executable(
alltests
src/TestText.cc
)
target_link_libraries(
alltests
PUBLIC
BoltCore
gtest
gtest_main
)
endif()
#add_custom_command(
# OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/include/bolt/CST.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/CST.cc"
# COMMAND scripts/gennodes.py --name=CST ./bolt-cst-spec.txt -Iinclude/ --include-root=bolt --source-root=src/ --namespace=bolt
# DEPENDS scripts/gennodes.py
# MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/bolt-cst-spec.txt"
# WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
#)

View file

@ -1,11 +1,13 @@
#ifndef BOLT_TEXT_HPP
#define BOLT_TEXT_HPP
#include "ByteString.hpp"
#pragma once
#include <stddef.h>
#include <vector>
#include <string>
#include "bolt/ByteString.hpp"
namespace bolt {
class TextLoc {
@ -34,10 +36,25 @@ namespace bolt {
};
class TextFile {
ByteString Path;
ByteString Text;
std::vector<size_t> LineOffsets;
public:
ByteString getText();
TextFile(ByteString Path, ByteString Text);
size_t getLine(size_t Offset);
size_t getColumn(size_t Offset);
size_t getStartOffset(size_t Line);
ByteString getPath() const;
ByteString getText() const;
};
}
#endif // of #ifndef BOLT_TEXT_HPP

47
src/TestText.cc Normal file
View file

@ -0,0 +1,47 @@
#include "gtest/gtest.h"
#include "bolt/Text.hpp"
using namespace bolt;
TEST(TextFileTest, ReportsCorrectLine) {
TextFile T1 { "foo.txt", "bar\nbaz\nbax\n" };
ASSERT_EQ(T1.getLine(0), 1);
ASSERT_EQ(T1.getLine(1), 1);
ASSERT_EQ(T1.getLine(2), 1);
ASSERT_EQ(T1.getLine(3), 1);
ASSERT_EQ(T1.getLine(4), 2);
ASSERT_EQ(T1.getLine(5), 2);
ASSERT_EQ(T1.getLine(6), 2);
ASSERT_EQ(T1.getLine(7), 2);
ASSERT_EQ(T1.getLine(8), 3);
ASSERT_EQ(T1.getLine(9), 3);
ASSERT_EQ(T1.getLine(10), 3);
ASSERT_EQ(T1.getLine(11), 3);
}
TEST(TextFileTest, ReportsCorrectStartOffset) {
TextFile T1 { "foo.txt", "bar\nbaz\nbax\n" };
ASSERT_EQ(T1.getStartOffset(1), 0);
ASSERT_EQ(T1.getStartOffset(2), 4);
ASSERT_EQ(T1.getStartOffset(3), 8);
ASSERT_EQ(T1.getStartOffset(4), 12);
ASSERT_EQ(T1.getStartOffset(5), 12);
}
TEST(TextFileTest, ReportsCorrectColumn) {
TextFile T1 { "foo.txt", "bar\nbaz\nbax\n" };
ASSERT_EQ(T1.getColumn(0), 1);
ASSERT_EQ(T1.getColumn(1), 2);
ASSERT_EQ(T1.getColumn(2), 3);
ASSERT_EQ(T1.getColumn(3), 4);
ASSERT_EQ(T1.getColumn(4), 1);
ASSERT_EQ(T1.getColumn(5), 2);
ASSERT_EQ(T1.getColumn(6), 3);
ASSERT_EQ(T1.getColumn(7), 4);
ASSERT_EQ(T1.getColumn(8), 1);
ASSERT_EQ(T1.getColumn(9), 2);
ASSERT_EQ(T1.getColumn(10), 3);
ASSERT_EQ(T1.getColumn(11), 4);
}

49
src/Text.cc Normal file
View file

@ -0,0 +1,49 @@
#include "zen/config.hpp"
#include "bolt/Text.hpp"
#include "bolt/ByteString.hpp"
namespace bolt {
TextFile::TextFile(ByteString Path, ByteString Text):
Path(Path), Text(Text) {
LineOffsets.push_back(0);
for (size_t I = 0; I < Text.size(); I++) {
auto Chr = Text[I];
if (Chr == '\n') {
LineOffsets.push_back(I+1);
}
}
LineOffsets.push_back(Text.size());
}
size_t TextFile::getStartOffset(size_t Line) {
return LineOffsets[Line-1];
}
size_t TextFile::getLine(size_t Offset) {
ZEN_ASSERT(Offset < Text.size());
for (size_t I = 0; I < LineOffsets.size(); ++I) {
if (LineOffsets[I] > Offset) {
return I;
}
}
ZEN_UNREACHABLE
}
size_t TextFile::getColumn(size_t Offset) {
auto Line = getLine(Offset);
auto StartOffset = getStartOffset(Line);
return Offset - StartOffset + 1 ;
}
ByteString TextFile::getPath() const {
return Path;
}
ByteString TextFile::getText() const {
return Text;
}
}