Skip to content

Commit 94621bc

Browse files
committed
git
1 parent 39ef6b0 commit 94621bc

25 files changed

+869
-71
lines changed

CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,21 @@ endif()
3434
find_package(ICU REQUIRED COMPONENTS i18n uc data)
3535
find_package(Microsoft.GSL CONFIG REQUIRED)
3636
find_package(LibGit2 CONFIG REQUIRED)
37+
find_package(OpenSSL REQUIRED)
3738

3839
add_library(hk_objects OBJECT
3940
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/expression_node.hpp"
41+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/import_declaration_node.cpp"
4042
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/import_declaration_node.hpp"
4143
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/module_declaration_node.hpp"
4244
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/module_node.hpp"
4345
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/node.hpp"
4446
"${CMAKE_CURRENT_SOURCE_DIR}/src/ast/nodes.hpp"
4547
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/error_code.hpp"
48+
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/error_item.hpp"
4649
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/error_list.hpp"
47-
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/error.hpp"
50+
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/errors.hpp"
51+
"${CMAKE_CURRENT_SOURCE_DIR}/src/error/make_error.hpp"
4852
"${CMAKE_CURRENT_SOURCE_DIR}/src/parser/consume.hpp"
4953
"${CMAKE_CURRENT_SOURCE_DIR}/src/parser/parse_fqname.cpp"
5054
"${CMAKE_CURRENT_SOURCE_DIR}/src/parser/parse_import_declaration.cpp"
@@ -70,6 +74,8 @@ add_library(hk_objects OBJECT
7074
"${CMAKE_CURRENT_SOURCE_DIR}/src/tokenizer/tokenizer.cpp"
7175
"${CMAKE_CURRENT_SOURCE_DIR}/src/tokenizer/tokenizer.hpp"
7276
"${CMAKE_CURRENT_SOURCE_DIR}/src/tokenizer/token_parsers.hpp"
77+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/base32.cpp"
78+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/base32.hpp"
7379
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/char_category.cpp"
7480
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/char_category.hpp"
7581
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/command_line.cpp"
@@ -85,12 +91,16 @@ add_library(hk_objects OBJECT
8591
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/file.hpp"
8692
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/fixed_fifo.hpp"
8793
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/fqname.hpp"
94+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/git.cpp"
95+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/git.hpp"
8896
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/module.cpp"
8997
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/module.hpp"
9098
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/path.cpp"
9199
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/path.hpp"
92100
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/semantic_version.cpp"
93101
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/semantic_version.hpp"
102+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/sha.cpp"
103+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/sha.hpp"
94104
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/strings.cpp"
95105
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/strings.hpp"
96106
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/unicode.cpp"
@@ -131,12 +141,14 @@ target_link_libraries(hkc PRIVATE ICU::i18n)
131141
target_link_libraries(hkc PRIVATE ICU::uc)
132142
target_link_libraries(hkc PRIVATE ICU::data)
133143
target_link_libraries(hkc PRIVATE libgit2::libgit2package)
134-
144+
target_link_libraries(hkc PRIVATE OpenSSL::SSL)
145+
target_link_libraries(hkc PRIVATE OpenSSL::Crypto)
135146

136147
if(BUILD_TESTING)
137148
add_executable(hktests)
138149
target_sources(hktests PRIVATE
139150
$<TARGET_OBJECTS:hk_objects>
151+
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/git_tests.cpp"
140152
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/unit_test.cpp"
141153
"${CMAKE_CURRENT_SOURCE_DIR}/src/utility/unit_test.hpp"
142154
"${CMAKE_CURRENT_SOURCE_DIR}/src/prologue/prologue_scan_tests.cpp"
@@ -151,6 +163,8 @@ if(BUILD_TESTING)
151163
target_link_libraries(hktests PRIVATE ICU::uc)
152164
target_link_libraries(hktests PRIVATE ICU::data)
153165
target_link_libraries(hktests PRIVATE libgit2::libgit2package)
166+
target_link_libraries(hktests PRIVATE OpenSSL::SSL)
167+
target_link_libraries(hktests PRIVATE OpenSSL::Crypto)
154168
target_link_libraries(hktests PRIVATE hikotest)
155169
target_include_directories(hktests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
156170

launch.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "lldb"
6+
}
7+
]
8+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
#include "import_declaration_node.hpp"
3+
#include "utility/sha.hpp"
4+
#include "utility/base32.hpp"
5+
#include <format>
6+
7+
namespace hk::ast {
8+
9+
[[nodiscard]] std::string import_declaration_node::path_hash() const
10+
{
11+
auto const full_path = [this] {
12+
switch (kind) {
13+
case kind_type::git:
14+
return std::format("{}:{}", path, branch);
15+
case kind_type::zip:
16+
return path;
17+
case kind_type::mod:
18+
return static_cast<std::string>(name);
19+
case kind_type::lib:
20+
return path;
21+
}
22+
std::unreachable();
23+
}();
24+
25+
auto const hash = sha256(full_path);
26+
return base32_encode(hash);
27+
}
28+
29+
[[nodiscard]] std::string import_declaration_node::path_stem() const
30+
{
31+
if (kind == kind_type::mod) {
32+
return static_cast<std::string>(name);
33+
}
34+
35+
auto first = path.rfind('/');
36+
if (first == std::string::npos) {
37+
first = path.rfind('\\');
38+
}
39+
if (first == std::string::npos) {
40+
first = 0;
41+
} else {
42+
++first;
43+
}
44+
45+
auto last = path.rfind('.');
46+
if (last == std::string::npos or last <= first) {
47+
last = path.size();
48+
}
49+
50+
return path.substr(first, last - first);
51+
}
52+
53+
[[nodiscard]] std::string import_declaration_node::directory_name() const
54+
{
55+
return std::format("{}-{}", path_stem(), path_hash().substr(0, 10));
56+
}
57+
58+
59+
}

src/ast/import_declaration_node.hpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,57 @@ class import_declaration_node : public node {
1111
public:
1212
using node::node;
1313

14+
enum class kind_type {
15+
/** Import a module.
16+
*/
17+
mod,
18+
19+
/** Import a git repository.
20+
*/
21+
git,
22+
23+
/** Import a zip-file repository.
24+
*/
25+
zip,
26+
27+
/** Import a FFI/system library.
28+
*/
29+
lib
30+
};
31+
32+
/** The kind of import
33+
*/
34+
kind_type kind = kind_type::mod;
35+
1436
/** The fully qualified name of the imported module.
1537
*/
16-
fqname name;
38+
fqname name = {};
39+
40+
/** The name to import the module to.
41+
*/
42+
std::string as = {};
43+
44+
/** Path to the repository or library.
45+
*/
46+
std::string path = {};
47+
48+
/** Git brach/tag/sha to checkout.
49+
*/
50+
std::string branch = {};
51+
52+
53+
/** Create the dependency directory-name.
54+
*
55+
* This is based around the following parts:
56+
* - The filename (excluding extension)
57+
* - A dash `-`
58+
* - A hash of the full path and branch.
59+
*/
60+
[[nodiscard]] std::string directory_name() const;
61+
62+
private:
63+
[[nodiscard]] std::string path_hash() const;
64+
[[nodiscard]] std::string path_stem() const;
1765

1866
};
1967

src/error/error_code.hpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,4 @@ struct error_code {
6161
}
6262
};
6363

64-
inline std::set<error_code> all_unique_error_codes = {};
65-
66-
template<fixed_string Fmt>
67-
struct unique_error_code_helper {
68-
error_code code;
69-
70-
unique_error_code_helper() {
71-
code = error_code{Fmt};
72-
auto const [_, inserted] = all_unique_error_codes.insert(code);
73-
74-
assert(inserted);
75-
}
76-
};
77-
78-
template<fixed_string Fmt>
79-
inline unique_error_code_helper<Fmt> unique_error_code = {};
80-
8164
}
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace hk {
1111

12-
class cause {
12+
class error_cause {
1313
public:
1414

1515
private:
@@ -18,16 +18,16 @@ class cause {
1818
std::string _message;
1919
};
2020

21-
class error {
21+
class error_item {
2222
public:
23-
constexpr error() noexcept = default;
24-
error(error const&) = default;
25-
error(error&&) = default;
26-
error& operator=(error const&) = default;
27-
error& operator=(error&&) = default;
23+
constexpr error_item() noexcept = default;
24+
error_item(error_item const&) = default;
25+
error_item(error_item&&) = default;
26+
error_item& operator=(error_item const&) = default;
27+
error_item& operator=(error_item&&) = default;
2828

2929
template<typename... Args>
30-
error(file_location first, file_location last, error_code code, std::format_string<Args...> fmt, Args&&... args)
30+
error_item(file_location first, file_location last, error_code code, std::format_string<Args...> fmt, Args&&... args)
3131
: _first(first), _last(last), _code(code), _message(std::format(std::move(fmt), std::forward<Args>(args)...))
3232
{
3333
assert(_code.has_value());
@@ -56,7 +56,7 @@ class error {
5656
file_location _last = {};
5757
error_code _code = {};
5858
std::string _message = {};
59-
std::vector<cause> _causes = {};
59+
std::vector<error_cause> _causes = {};
6060
};
6161

6262
}

src/error/error_list.hpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
#pragma once
33

4-
#include "error.hpp"
4+
#include "error_item.hpp"
55
#include "error_code.hpp"
66
#include "utility/file_location.hpp"
77
#include "utility/fixed_string.hpp"
@@ -10,9 +10,9 @@
1010

1111
namespace hk {
1212

13-
class error_list : public std::vector<error> {
13+
class error_list : public std::vector<error_item> {
1414
public:
15-
using element_type = error;
15+
using element_type = error_item;
1616

1717
/** Add an error to the list.
1818
*
@@ -23,15 +23,12 @@ class error_list : public std::vector<error> {
2323
* @param args The arguments to format the error message.
2424
* @return A unexpected error containing the error code.
2525
*/
26-
template<fixed_string Fmt, typename... Args>
26+
template<typename ErrorType, typename... Args>
2727
std::unexpected<error_code> add(file_location first, file_location last, Args&&... args)
2828
{
29-
auto const code = unique_error_code<Fmt>.code;
30-
assert(code.has_value());
31-
32-
auto e = error{first, last, code, Fmt, std::forward<Args>(args)...};
29+
auto e = error_item{first, last, ErrorType::code, ErrorType::fmt, std::forward<Args>(args)...};
3330
this->push_back(std::move(e));
34-
return std::unexpected{code};
31+
return std::unexpected{ErrorType::code};
3532
}
3633

3734
private:

src/error/errors.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
#pragma once
3+
4+
#include "make_error.hpp"
5+
6+
namespace hk::error {
7+
8+
#define E(name, fmt) struct name : public make_error<fmt> {}
9+
10+
E(missing_module_declaration_name, "E0001: Module declaration requires fqname.");
11+
E(missing_module_application_declaration_exe, "E0002: Module application declaration requires an executable name.");
12+
E(missing_module_library_declaration_bin, "E0003: Module library declaration requires a binary name.");
13+
E(missing_module_package_declaration_version, "E0004: Module package declaration requires a version number.");
14+
E(unimplemented_module_declaration_if, "E0005: module-if expression is not implemented.");
15+
E(missing_module_declaration_semicolon, "E0006: Expecting ';' at end of module declaration.");
16+
E(missing_import_git_declaration_url, "E0007: Expecting a URL string literal after 'git' keyword in a import-declaration.");
17+
E(missing_import_git_declaration_branch, "E0008: Expecting a branch string literal after 'git' keyword in a import-declaration.");
18+
E(missing_import_zip_declaration_path, "E0009: Expect a path string literal after 'zip' keyword in a import-declaration.");
19+
E(missing_import_lib_declaration_path, "E0010: Expect a path string literal after 'lib' keyword in a import-declaration.");
20+
E(missing_import_mod_declaration_as_name, "E0011: Expected a name after 'as' keyword in a import-declaration.");
21+
E(missing_import_mod_declaration_name, "E0012: Expected fully qualified name after 'import' keyword in a import-declaration.");
22+
E(missing_import_declaration_semicolon, "E0013: Expected ';' after a import-declaration.");
23+
E(missing_fqname_identifier_after_dot, "E0014: Expected identifier after '.' in fully qualified name.");
24+
25+
26+
#undef E
27+
28+
}

src/error/make_error.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
#pragma once
3+
4+
#include "utility/fixed_string.hpp"
5+
#include "error_code.hpp"
6+
7+
namespace hk {
8+
9+
template<fixed_string Fmt>
10+
struct make_error {
11+
constexpr static decltype(Fmt) fmt = Fmt;
12+
constexpr static error_code code = error_code{fmt};
13+
};
14+
15+
16+
}

src/parser/parse_fqname.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
#include "parsers.hpp"
33
#include "utility/fqname.hpp"
4+
#include "error/errors.hpp"
45

56
namespace hk {
67

@@ -16,13 +17,13 @@ namespace hk {
1617
++it;
1718

1819
while (true) {
19-
if (*it != '.') {
20+
if (*it != ".") {
2021
return r;
2122
}
2223

2324
++it;
2425
if (*it != token::identifier) {
25-
return e.add<"E0004: Expected identifier after '.' in fully qualified name.">(first, it->last);
26+
return e.add<error::missing_fqname_identifier_after_dot>(first, it->last);
2627
}
2728

2829
r += it->text;

0 commit comments

Comments
 (0)