From 26a7970e60145eb3f45f69f5a34cef9f14f0558b Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 13:57:25 -0700 Subject: [PATCH 1/9] feat: use cppfront directly as a parser --- .gitmodules | 3 + build.cmd | 22 +++++- build.cpp2 | 10 +++ build.sh | 10 +-- cppfront | 1 + src/main.cpp2 | 163 ++++++++++++++++++++-------------------- src/parser_wrapper.cppm | 121 +++++++++++++++++++++++++++++ 7 files changed, 240 insertions(+), 90 deletions(-) create mode 100644 .gitmodules create mode 160000 cppfront create mode 100644 src/parser_wrapper.cppm diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9f615c0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cppfront"] + path = cppfront + url = https://github.com/hsutter/cppfront.git diff --git a/build.cmd b/build.cmd index c4339e4..f9bde4e 100644 --- a/build.cmd +++ b/build.cmd @@ -4,7 +4,7 @@ setlocal enabledelayedexpansion set root_dir=%~dp0 set tools_dir=%~dp0.cache\tools\ set cppfront=%tools_dir%\cppfront.exe -set cppfront_include_dir=%~dp0.cache\repos\cppfront\include +set cppfront_include_dir=%~dp0cppfront\source set cpp2b_dist=%~dp0dist\debug\cpp2b set modules_dir=%~dp0.cache\modules @@ -140,8 +140,23 @@ if %ERRORLEVEL% neq 0 ( exit %ERRORLEVEL% ) +echo INFO: compiling parser_wrapper module... +pushd %modules_dir% +cl /nologo ^ + /std:c++latest /W4 /MDd /EHsc ^ + -I"%cppfront_include_dir%" ^ + /reference "%modules_dir%\std.ifc" ^ + /reference "%modules_dir%\std.compat.ifc" ^ + /c /interface /TP "%root_dir%src\parser_wrapper.cppm" > NUL +popd + +if %ERRORLEVEL% neq 0 ( + echo ERROR: failed to compile parser_wrapper module + exit %ERRORLEVEL% +) + if not exist %cppfront% ( - pushd .cache\repos\cppfront\source + pushd cppfront\source echo INFO: compiling cppfront... cl /nologo /std:c++latest /EHsc cppfront.cpp xcopy cppfront.exe %tools_dir% /Y /Q @@ -155,7 +170,7 @@ if %ERRORLEVEL% neq 0 ( if not exist "%root_dir%.cache/cpp2/source/src" ( mkdir "%root_dir%.cache/cpp2/source/src" ) -%cppfront% src/main.cpp2 -pure -import-std -l -format-colon-errors -o "%root_dir%.cache/cpp2/source/src/main.cpp" +%cppfront% src/main.cpp2 -import-std -l -format-colon-errors -o "%root_dir%.cache/cpp2/source/src/main.cpp" if %ERRORLEVEL% neq 0 exit %ERRORLEVEL% @@ -167,6 +182,7 @@ cl /nologo "%root_dir%.cache/cpp2/source/src/main.cpp" ^ /reference "%modules_dir%\dylib.ifc" "%modules_dir%\dylib.obj" ^ /reference "%modules_dir%\nlohmann.json.ifc" "%modules_dir%\nlohmann.json.obj" ^ /reference "%modules_dir%\cpp2b.ifc" "%modules_dir%\cpp2b.obj" ^ + /reference "%modules_dir%\parser_wrapper.ifc" "%modules_dir%\parser_wrapper.obj" ^ /std:c++latest /W4 /MDd /EHsc ^ /DEBUG:FULL /Zi /FC ^ -I"%cppfront_include_dir%" ^ diff --git a/build.cpp2 b/build.cpp2 index f02c758..4e68a17 100644 --- a/build.cpp2 +++ b/build.cpp2 @@ -1,7 +1,17 @@ import cpp2b.build; +cppfront_url: std::string_view == "hsutter/cppfront"; +cppfront_version: std::string_view == "v0.8.1"; + +build_info: namespace = { + hello :== "yo"; +} + build: (inout b: cpp2b::build) -> void = { _ = b.cpp1_module().source_path("src/dylib.cppm"); _ = b.cpp1_module().source_path("src/nlohmann.json.cppm"); + _ = b.cpp1_module() + .source_path("src/parser_wrapper.cppm") + .include_directory("cppfront/source"); b.binary_name("src/main", "cpp2b"); } diff --git a/build.sh b/build.sh index a70f80f..4215875 100755 --- a/build.sh +++ b/build.sh @@ -83,17 +83,17 @@ function ensure_gh_repo_subdir() { fi } -ensure_gh_repo "hsutter/cppfront" "v0.8.1" -ensure_gh_repo_subdir "hsutter/cppfront" "source" -ensure_gh_repo_subdir "hsutter/cppfront" "include" +# ensure_gh_repo "hsutter/cppfront" "v0.8.1" +# ensure_gh_repo_subdir "hsutter/cppfront" "source" +# ensure_gh_repo_subdir "hsutter/cppfront" "include" -CPPFRONT_INCLUDE_DIR=$ROOT_DIR/.cache/repos/hsutter/cppfront/include +CPPFRONT_INCLUDE_DIR=$ROOT_DIR/cppfront/source LLVM_ROOT=/usr/lib/llvm-$COMPILER_MAJOR_VERSION if ! [ -x $CPPFRONT ]; then log_info "compiling cppfront..." - cd $ROOT_DIR/.cache/repos/hsutter/cppfront/source + cd $ROOT_DIR/cppfront/source $CPP2B_COMPILER \ -std=c++23 \ -stdlib=libc++ \ diff --git a/cppfront b/cppfront new file mode 160000 index 0000000..ec1f98a --- /dev/null +++ b/cppfront @@ -0,0 +1 @@ +Subproject commit ec1f98abd3752459e372f0228041e233f0fd6c7e diff --git a/src/main.cpp2 b/src/main.cpp2 index 0f8b718..3d32859 100644 --- a/src/main.cpp2 +++ b/src/main.cpp2 @@ -2,6 +2,7 @@ import std.compat; import cpp2b; import dylib; import nlohmann.json; +import parser_wrapper; fs: namespace == std::filesystem; json: type == nlohmann::json; @@ -95,15 +96,31 @@ expect: (move opt: std::optional, message) -> T = { return opt*; } -GitHubRepo: type = { - private repo_: fs::path; +GitRepo: type = { + private repo_name: fs::path = (); + private clone_url: std::string = (); - operator=: (out this, repo, branch) = { - repo_ = repo; + operator=: (out this, repo: std::string_view, branch: std::string_view) = { + if repo.find("://") != std::string_view::npos { + clone_url = std::string(repo); + // Simple folder name extraction from URL + last_slash := repo.find_last_of('/'); + if last_slash != std::string_view::npos { + repo_name = std::string(repo.substr(last_slash + 1)); + if repo_name.string().ends_with(".git") { + repo_name = repo_name.string().substr(0, repo_name.string().size() - 4); + } + } else { + repo_name = std::string(repo); + } + } else { + clone_url = "https://github.com/(repo)$"; + repo_name = std::string(repo); + } if !fs::exists(path() / ".git") { ensure_dir(path()); - git_("clone --depth=1 --branch=(branch)$ --filter=blob:none --sparse https://github.com/(repo_.generic_string())$ ."); + git_("clone --depth=1 --branch=(branch)$ --filter=blob:none --sparse (clone_url)$ ."); } } @@ -116,7 +133,7 @@ GitHubRepo: type = { } path: (this) -> fs::path = { - return fs::current_path() / ".cache" / "cpp2" / "repos" / repo_; + return fs::current_path() / ".cache" / "cpp2" / "repos" / repo_name; } add: (this, subpath: std::string) = { @@ -898,14 +915,21 @@ cpp2b_detail_build: (copy _impl: *cpp2b_detail_build_impl) -> void = { } cl_build_build_script_cmd: (info: cpp2b_source_build_info, bin_outpath: fs::path) -> std::string = { - cppfront_include_dir := fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); + cppfront_include_dir: fs::path = fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); + if fs::exists("cppfront/source") { + cppfront_include_dir = fs::absolute("cppfront/source"); + } else if fs::exists("cppfront/include") { + cppfront_include_dir = fs::absolute("cppfront/include"); + } + transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); cmd_str: std::string = "cl /nologo /std:c++latest /W4 /MDd /EHsc /LDd /DLL"; for info.imports do (imp: std::string) { imp_bmi := d / ("(imp)$.ifc"); imp_obj := d / ("(imp)$.obj"); - cmd_str += " /reference \"(imp_bmi.string())$\" \"(imp_obj.string())$\""; + cmd_str += " /reference \"(imp_bmi.string())$\""; + cmd_str += " \"(imp_obj.string())$\""; } cmd_str += " \"(transpiled_src .string())$\""; cmd_str += " -I\"(cppfront_include_dir.string())$\""; @@ -919,7 +943,12 @@ cl_build_build_script_cmd: (info: cpp2b_source_build_info, bin_outpath: fs::path unix_build_build_script_cmd: (compiler_cmd: std::string, info: cpp2b_source_build_info, bin_outpath: fs::path) -> std::string = { sys_inc_dir := get_llvm_root() / "include" / "c++" / "v1"; sys_lib_dir := get_llvm_root() / "lib"; - cppfront_include_dir := fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); + cppfront_include_dir: fs::path = fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); + if fs::exists("cppfront/source") { + cppfront_include_dir = fs::absolute("cppfront/source"); + } else if fs::exists("cppfront/include") { + cppfront_include_dir = fs::absolute("cppfront/include"); + } transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); cmd_str: std::string = std::format("{} -stdlib=libc++ -shared", compiler_cmd); @@ -1079,7 +1108,23 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c build_cpp2_dir := fs::current_path(); stuff = (); - (repo := GitHubRepo("hsutter/cppfront", "v0.8.1")) { + cppfront_url: std::string = "hsutter/cppfront"; + cppfront_version: std::string = "v0.8.1"; + + if fs::exists("build.cpp2") { + build_info_variant := cpp2b_parse_source("build.cpp2"); + if build_info_variant.is_build() { + build_info := build_info_variant.build(); + if build_info.constants.contains("cppfront_url") { + cppfront_url = build_info.constants.at("cppfront_url"); + } + if build_info.constants.contains("cppfront_version") { + cppfront_version = build_info.constants.at("cppfront_version"); + } + } + } + + (repo := GitRepo(cppfront_url, cppfront_version)) { repo.add("source"); repo.add("include"); exit_code = ensure_cppfront(repo.path()); @@ -1106,7 +1151,8 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c if p.extension() == ".cpp2" { rel_path := fs::relative(p, fs::current_path()); for rel_path do(rel_path_comp) { - if rel_path_comp.string().starts_with(".") { + comp := rel_path_comp.string(); + if comp.starts_with(".") || comp == "cppfront" || comp == "dist" { continue src_loop; } } @@ -1593,6 +1639,7 @@ cpp2b_source_binary_info: @struct type = { cpp2b_source_build_info: @struct type = { src: fs::path = (); imports: std::vector = (); + constants: std::map = (); } cpp2b_source_unknown_info: @struct type = { @@ -1683,91 +1730,43 @@ cpp2b_parse_cpp1_module_statements: (copy stream: std::ifstream) -> (module_name } cpp2b_parse_source: (source_file: fs::path) -> cpp2b_source_info = { - stream: std::ifstream = source_file; - statement: std::string = ""; - imports: std::vector = (); - - // without this cppfront thinks stream is never used - assert(stream); + info := parser_wrapper::parse_source(source_file.string()); - result: cpp2b_source_info = (); - result.set_unknown(cpp2b_source_unknown_info(source_file)); - - while std::getline(stream, statement, ';') { - trimmed_statement := statement.ltrim(); - kw_import: std::string_view = "import"; - - if trimmed_statement.starts_with(kw_import) { - import_name := trimmed_statement.lstrip(kw_import.size()).ltrim().rtrim(); - if !contains_any_whitespace(import_name) { - imports.emplace_back(import_name); - } - } + if std::ranges::find(info.imports, "std") == info.imports.end() { + info.imports.emplace_back("std"); } - if std::ranges::find(imports, "std") == imports.end() { - imports.emplace_back("std"); + if std::ranges::find(info.imports, "std.compat") == info.imports.end() { + info.imports.emplace_back("std.compat"); } - if std::ranges::find(imports, "std.compat") == imports.end() { - imports.emplace_back("std.compat"); - } + result: cpp2b_source_info = (); + result.set_unknown(cpp2b_source_unknown_info(source_file)); - if source_file.filename() == "build.cpp2" { + if info.kind == parser_wrapper::source_kind::build { build_info: cpp2b_source_build_info = (); build_info.src = source_file; - build_info.imports = imports; + build_info.imports = info.imports; + build_info.constants = info.constants; result.set_build(build_info); return result; } - stream.clear(); - stream.seekg(0); - - while std::getline(stream, statement, ';') { - trimmed_statement := statement.ltrim(); - kw_export: std::string_view = "export"; - kw_module: std::string_view = "module"; - - if trimmed_statement.starts_with(kw_export) { - trimmed_statement = trimmed_statement.lstrip(kw_export.size()).ltrim(); - if !trimmed_statement.starts_with(kw_module) { break; } - - module_name := trimmed_statement.lstrip(kw_module.size()).ltrim(); - partition_start := module_name.find(':'); - if partition_start != std::string::npos { - module_name = module_name.substr(0, partition_start).rtrim(); - } else { - module_name = module_name.rtrim(); - } - - mod_info: cpp2b_source_module_info = (); - - mod_info.name = std::string(module_name); - mod_info.imports = imports; - mod_info.exported = true; - - result.set_mod(mod_info); - return result; - } + if info.kind == parser_wrapper::source_kind::module { + mod_info: cpp2b_source_module_info = (); + mod_info.name = info.module_name; + mod_info.imports = info.imports; + mod_info.exported = info.exported; + result.set_mod(mod_info); + return result; } - stream.clear(); - stream.seekg(0); - - line: std::string = (); - while std::getline(stream, line) { - trimmed_line := line.ltrim(); - if trimmed_line.starts_with("main") { - after_main := trimmed_line.substr(4).ltrim(); - if after_main.empty() || after_main[0] == ':' { - bin_info: cpp2b_source_binary_info = (); - bin_info.src = source_file; - bin_info.imports = imports; - result.set_bin(bin_info); - return result; - } - } + if info.kind == parser_wrapper::source_kind::binary { + bin_info: cpp2b_source_binary_info = (); + bin_info.src = source_file; + bin_info.imports = info.imports; + result.set_bin(bin_info); + return result; } return result; diff --git a/src/parser_wrapper.cppm b/src/parser_wrapper.cppm new file mode 100644 index 0000000..c43c7d8 --- /dev/null +++ b/src/parser_wrapper.cppm @@ -0,0 +1,121 @@ +module; +#include "parse.h" +export module parser_wrapper; + +import std; + +export namespace parser_wrapper { + +enum class source_kind { unknown, module, binary, build }; + +struct source_info { + source_kind kind = source_kind::unknown; + std::string module_name; + std::vector imports; + std::map constants; + bool exported = false; +}; + +source_info parse_source(const std::string& filename) { + auto result = source_info{}; + auto errors = std::vector{}; + auto source = cpp2::source{errors}; + + if(!source.load(filename)) { + return result; + } + + // Extract imports from source lines + for(auto const& line : source.get_lines()) { + if(line.cat == cpp2::source_line::category::import) { + std::string text = line.text; + // Basic extraction: import ; + size_t import_pos = text.find("import"); + if(import_pos != std::string::npos) { + std::string import_name; + size_t k = import_pos + 6; + while(k < text.size() && std::isspace(text[k])) { + k++; + } + while(k < text.size() && !std::isspace(text[k]) && text[k] != ';') { + import_name += text[k]; + k++; + } + if(!import_name.empty()) { + result.imports.emplace_back(import_name); + } + } + } + } + + cpp2::tokens tokens(errors); + tokens.lex(source.get_lines()); + + std::vector all_tokens; + for(auto const& [line, line_tokens] : tokens.get_map()) { + for(auto const& t : line_tokens) { + all_tokens.push_back(t); + } + } + + std::filesystem::path p(filename); + if(p.filename() == "build.cpp2") { + result.kind = source_kind::build; + // Extract constants + for(size_t j = 0; j < all_tokens.size(); ++j) { + // identifier == string_literal ; + if(j + 3 < all_tokens.size() && + all_tokens[j].type() == cpp2::lexeme::Identifier && + all_tokens[j + 1].type() == cpp2::lexeme::EqualComparison && + all_tokens[j + 2].type() == cpp2::lexeme::StringLiteral && + all_tokens[j + 3].type() == cpp2::lexeme::Semicolon) { + auto name = all_tokens[j].as_string_view(); + auto value_raw = all_tokens[j + 2].as_string_view(); + if(value_raw.size() >= 2) { + auto value = std::string(value_raw.substr(1, value_raw.size() - 2)); + result.constants[std::string(name)] = value; + } + j += 3; + } + // identifier : type == string_literal ; + else if(j + 5 < all_tokens.size() && + all_tokens[j].type() == cpp2::lexeme::Identifier && + all_tokens[j + 1].type() == cpp2::lexeme::Colon && + all_tokens[j + 3].type() == cpp2::lexeme::EqualComparison && + all_tokens[j + 4].type() == cpp2::lexeme::StringLiteral && + all_tokens[j + 5].type() == cpp2::lexeme::Semicolon) { + auto name = all_tokens[j].as_string_view(); + auto value_raw = all_tokens[j + 4].as_string_view(); + if(value_raw.size() >= 2) { + auto value = std::string(value_raw.substr(1, value_raw.size() - 2)); + result.constants[std::string(name)] = value; + } + j += 5; + } + } + } else { + // Module detection + for(size_t k = 0; k + 2 < all_tokens.size(); ++k) { + if(all_tokens[k].as_string_view() == "export" && + all_tokens[k + 1].as_string_view() == "module" && + all_tokens[k + 2].type() == cpp2::lexeme::Identifier) { + result.kind = source_kind::module; + result.module_name = std::string(all_tokens[k + 2].as_string_view()); + result.exported = true; + return result; + } + } + + // Binary detection + for(auto const& t : all_tokens) { + if(t.type() == cpp2::lexeme::Identifier && t.as_string_view() == "main") { + result.kind = source_kind::binary; + return result; + } + } + } + + return result; +} + +} // namespace parser_wrapper From c037b558ed9d585692d80a6151e9ab7b199524f0 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 14:17:42 -0700 Subject: [PATCH 2/9] fix: better version detection --- build.cpp2 | 8 +--- src/main.cpp2 | 99 +++++++++++++++++++++++++++-------------- src/parser_wrapper.cppm | 26 ++++++++--- 3 files changed, 88 insertions(+), 45 deletions(-) diff --git a/build.cpp2 b/build.cpp2 index 4e68a17..20d0af5 100644 --- a/build.cpp2 +++ b/build.cpp2 @@ -1,11 +1,7 @@ import cpp2b.build; -cppfront_url: std::string_view == "hsutter/cppfront"; -cppfront_version: std::string_view == "v0.8.1"; - -build_info: namespace = { - hello :== "yo"; -} +cppfront_url :== "hsutter/cppfront"; +cppfront_version :== "v0.8.1"; build: (inout b: cpp2b::build) -> void = { _ = b.cpp1_module().source_path("src/dylib.cppm"); diff --git a/src/main.cpp2 b/src/main.cpp2 index 3d32859..3b0d372 100644 --- a/src/main.cpp2 +++ b/src/main.cpp2 @@ -99,11 +99,12 @@ expect: (move opt: std::optional, message) -> T = { GitRepo: type = { private repo_name: fs::path = (); private clone_url: std::string = (); + private branch: std::string = (); - operator=: (out this, repo: std::string_view, branch: std::string_view) = { + operator=: (out this, repo: std::string_view, repo_branch: std::string_view) = { + branch = std::string(repo_branch); if repo.find("://") != std::string_view::npos { clone_url = std::string(repo); - // Simple folder name extraction from URL last_slash := repo.find_last_of('/'); if last_slash != std::string_view::npos { repo_name = std::string(repo.substr(last_slash + 1)); @@ -117,10 +118,15 @@ GitRepo: type = { clone_url = "https://github.com/(repo)$"; repo_name = std::string(repo); } + } + fetch: (this) = { if !fs::exists(path() / ".git") { ensure_dir(path()); git_("clone --depth=1 --branch=(branch)$ --filter=blob:none --sparse (clone_url)$ ."); + } else { + git_("fetch origin (branch)$ --depth=1"); + git_("checkout FETCH_HEAD"); } } @@ -699,8 +705,7 @@ build_binary_result: @struct type = { duration: std::chrono::milliseconds = (); } -cl_build_binary_cmd: (info: cpp2b_source_binary_info, bin_outpath: fs::path) -> std::string = { - cppfront_include_dir := fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); +cl_build_binary_cmd: (info: cpp2b_source_binary_info, bin_outpath: fs::path, cppfront_include_dir: fs::path) -> std::string = { transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); @@ -721,10 +726,9 @@ cl_build_binary_cmd: (info: cpp2b_source_binary_info, bin_outpath: fs::path) -> return cmd_str; } -unix_build_binary_cmd: (compiler_cmd: std::string, info: cpp2b_source_binary_info, bin_outpath: fs::path) -> std::string = { +unix_build_binary_cmd: (compiler_cmd: std::string, info: cpp2b_source_binary_info, bin_outpath: fs::path, cppfront_include_dir: fs::path) -> std::string = { sys_inc_dir := get_llvm_root() / "include" / "c++" / "v1"; sys_lib_dir := get_llvm_root() / "lib"; - cppfront_include_dir := fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); cmd_str: std::string = std::format("{} -stdlib=libc++ -fPIC", compiler_cmd); @@ -743,7 +747,7 @@ unix_build_binary_cmd: (compiler_cmd: std::string, info: cpp2b_source_binary_inf } -build_binary: (info: cpp2b_source_binary_info) -> build_binary_result = { +build_binary: (info: cpp2b_source_binary_info, cppfront_include_dir: fs::path) -> build_binary_result = { compiler :== cpp2b::compiler(); bin_basename: fs::path = info.name(); if bin_basename.extension().empty() { @@ -758,9 +762,9 @@ build_binary: (info: cpp2b_source_binary_info) -> build_binary_result = { d := fs::absolute(modules_dir()); cmd_str: std::string = ""; - if compiler == cpp2b::compiler_type::msvc { cmd_str = cl_build_binary_cmd(info, bin_outpath); } - else if compiler == cpp2b::compiler_type::clang { cmd_str = unix_build_binary_cmd("clang-19", info, bin_outpath); } - else if compiler == cpp2b::compiler_type::gcc { cmd_str = unix_build_binary_cmd("gcc", info, bin_outpath); } + if compiler == cpp2b::compiler_type::msvc { cmd_str = cl_build_binary_cmd(info, bin_outpath, cppfront_include_dir); } + else if compiler == cpp2b::compiler_type::clang { cmd_str = unix_build_binary_cmd("clang-19", info, bin_outpath, cppfront_include_dir); } + else if compiler == cpp2b::compiler_type::gcc { cmd_str = unix_build_binary_cmd("gcc", info, bin_outpath, cppfront_include_dir); } else { log_error("Unsupported compiler"); std::exit(1); } cmd_str += " (cmd_log_output(fs::absolute(log_path)))$"; @@ -914,14 +918,7 @@ cpp2b_detail_build: (copy _impl: *cpp2b_detail_build_impl) -> void = { // empty. this is just so we can decltype the signature } -cl_build_build_script_cmd: (info: cpp2b_source_build_info, bin_outpath: fs::path) -> std::string = { - cppfront_include_dir: fs::path = fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); - if fs::exists("cppfront/source") { - cppfront_include_dir = fs::absolute("cppfront/source"); - } else if fs::exists("cppfront/include") { - cppfront_include_dir = fs::absolute("cppfront/include"); - } - +cl_build_build_script_cmd: (info: cpp2b_source_build_info, bin_outpath: fs::path, cppfront_include_dir: fs::path) -> std::string = { transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); cmd_str: std::string = "cl /nologo /std:c++latest /W4 /MDd /EHsc /LDd /DLL"; @@ -940,15 +937,9 @@ cl_build_build_script_cmd: (info: cpp2b_source_build_info, bin_outpath: fs::path } -unix_build_build_script_cmd: (compiler_cmd: std::string, info: cpp2b_source_build_info, bin_outpath: fs::path) -> std::string = { +unix_build_build_script_cmd: (compiler_cmd: std::string, info: cpp2b_source_build_info, bin_outpath: fs::path, cppfront_include_dir: fs::path) -> std::string = { sys_inc_dir := get_llvm_root() / "include" / "c++" / "v1"; sys_lib_dir := get_llvm_root() / "lib"; - cppfront_include_dir: fs::path = fs::absolute(".cache/cpp2/repos/hsutter/cppfront/include"); - if fs::exists("cppfront/source") { - cppfront_include_dir = fs::absolute("cppfront/source"); - } else if fs::exists("cppfront/include") { - cppfront_include_dir = fs::absolute("cppfront/include"); - } transpiled_src := fs::absolute(".cache/cpp2/source") / fs::path(info.src).replace_extension(".cpp"); d := fs::absolute(modules_dir()); cmd_str: std::string = std::format("{} -stdlib=libc++ -shared", compiler_cmd); @@ -967,7 +958,7 @@ unix_build_build_script_cmd: (compiler_cmd: std::string, info: cpp2b_source_buil } -build_build_script: (info: cpp2b_source_build_info) -> build_binary_result = { +build_build_script: (info: cpp2b_source_build_info, cppfront_include_dir: fs::path) -> build_binary_result = { compiler :== cpp2b::compiler(); bin_outpath := fs::absolute(".cache/cpp2/bin") / fs::path(info.src).replace_extension(shared_library_extension()); log_path := fs::absolute(".cache/cpp2/log/compile") / fs::path(info.src).replace_extension(".log"); @@ -976,9 +967,9 @@ build_build_script: (info: cpp2b_source_build_info) -> build_binary_result = { d := fs::absolute(modules_dir()); cmd_str: std::string = ""; - if compiler == cpp2b::compiler_type::msvc { cmd_str = cl_build_build_script_cmd(info, bin_outpath); } - else if compiler == cpp2b::compiler_type::clang { cmd_str = unix_build_build_script_cmd("clang-19", info, bin_outpath); } - else if compiler == cpp2b::compiler_type::gcc { cmd_str = unix_build_build_script_cmd("gcc", info, bin_outpath); } + if compiler == cpp2b::compiler_type::msvc { cmd_str = cl_build_build_script_cmd(info, bin_outpath, cppfront_include_dir); } + else if compiler == cpp2b::compiler_type::clang { cmd_str = unix_build_build_script_cmd("clang-19", info, bin_outpath, cppfront_include_dir); } + else if compiler == cpp2b::compiler_type::gcc { cmd_str = unix_build_build_script_cmd("gcc", info, bin_outpath, cppfront_include_dir); } else { log_error("Unsupported compiler"); std::exit(1); } cmd_str += " (cmd_log_output(fs::relative(log_path)))$"; @@ -1011,6 +1002,7 @@ full_build_info: @struct type = { mods: std::vector = (); build_scripts: std::vector = (); unknowns: std::vector = (); + cppfront_include_dir: fs::path = (); bin_results: std::vector = (); @@ -1124,11 +1116,52 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c } } + cppfront_info_path: fs::path = ".cache/cpp2/tools/cppfront.info"; + cppfront_bin: fs::path = ".cache/cpp2/tools/cppfront(executable_extension())$"; + needs_recompile: bool = false; + if fs::exists(cppfront_info_path) && fs::exists(cppfront_bin) { + info_stream: std::ifstream = cppfront_info_path; + stored_url: std::string = (); + stored_version: std::string = (); + std::getline(info_stream, stored_url); + std::getline(info_stream, stored_version); + if stored_url != cppfront_url { + log_info("cppfront_url changed: {} -> {}", stored_url, cppfront_url); + needs_recompile = true; + } + if stored_version != cppfront_version { + log_info("cppfront_version changed: {} -> {}", stored_version, cppfront_version); + needs_recompile = true; + } + } else { + needs_recompile = true; + } + + if needs_recompile { + if fs::exists(cppfront_bin) { + fs::remove(cppfront_bin); + } + } + (repo := GitRepo(cppfront_url, cppfront_version)) { - repo.add("source"); - repo.add("include"); + if needs_recompile || !fs::exists(repo.path() / ".git") { + repo.fetch(); + repo.add("source"); + repo.add("include"); + } + exit_code = ensure_cppfront(repo.path()); if exit_code != 0 { return; } + + if needs_recompile { + info_out: std::ofstream = (cppfront_info_path, std::ios::binary); + info_out << cppfront_url << "\n" << cppfront_version << "\n"; + } + + stuff.cppfront_include_dir = repo.path() / "source"; + if !fs::exists(stuff.cppfront_include_dir) { + stuff.cppfront_include_dir = repo.path() / "include"; + } } ensure_std_modules(); @@ -1229,7 +1262,7 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c build_script_futures.emplace_back( std::ref(build_script), - std::async(std::launch::async, build_build_script, build_script) + std::async(std::launch::async, build_build_script, build_script, stuff.cppfront_include_dir) ); } @@ -1376,7 +1409,7 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c bin_futures.emplace_back( std::ref(bin), - std::async(std::launch::async, build_binary, bin) + std::async(std::launch::async, build_binary, bin, stuff.cppfront_include_dir) ); } diff --git a/src/parser_wrapper.cppm b/src/parser_wrapper.cppm index c43c7d8..f759411 100644 --- a/src/parser_wrapper.cppm +++ b/src/parser_wrapper.cppm @@ -77,13 +77,27 @@ source_info parse_source(const std::string& filename) { } j += 3; } + // identifier :== string_literal ; + else if (j + 3 < all_tokens.size() && + all_tokens[j].type() == cpp2::lexeme::Identifier && + all_tokens[j+1].type() == cpp2::lexeme::Colon && + all_tokens[j+2].type() == cpp2::lexeme::EqualComparison && + all_tokens[j+3].type() == cpp2::lexeme::StringLiteral) { + auto name = all_tokens[j].as_string_view(); + auto value_raw = all_tokens[j+3].as_string_view(); + if (value_raw.size() >= 2) { + auto value = std::string(value_raw.substr(1, value_raw.size() - 2)); + result.constants[std::string(name)] = value; + } + j += 3; + } // identifier : type == string_literal ; - else if(j + 5 < all_tokens.size() && - all_tokens[j].type() == cpp2::lexeme::Identifier && - all_tokens[j + 1].type() == cpp2::lexeme::Colon && - all_tokens[j + 3].type() == cpp2::lexeme::EqualComparison && - all_tokens[j + 4].type() == cpp2::lexeme::StringLiteral && - all_tokens[j + 5].type() == cpp2::lexeme::Semicolon) { + else if (j + 5 < all_tokens.size() && + all_tokens[j].type() == cpp2::lexeme::Identifier && + all_tokens[j+1].type() == cpp2::lexeme::Colon && + all_tokens[j+3].type() == cpp2::lexeme::EqualComparison && + all_tokens[j+4].type() == cpp2::lexeme::StringLiteral && + all_tokens[j+5].type() == cpp2::lexeme::Semicolon) { auto name = all_tokens[j].as_string_view(); auto value_raw = all_tokens[j + 4].as_string_view(); if(value_raw.size() >= 2) { From ed29f223898c43c6d4662553023dc459452883c8 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 14:19:52 -0700 Subject: [PATCH 3/9] fix: fetch submodules --- .github/workflows/main.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index bef6d66..04439a6 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -18,6 +18,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: crate-ci/typos@cfe759ac8dd421e203cc293a373396fbc6fe0d4b # v1.22.7 build-script-windows: @@ -25,6 +27,8 @@ jobs: runs-on: windows-2025-vs2026 steps: - uses: actions/checkout@v4 + with: + submodules: recursive - run: .\build.cmd - uses: actions/upload-artifact@v4 with: @@ -39,6 +43,8 @@ jobs: runs-on: windows-2025-vs2026 steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: actions/download-artifact@v4 with: name: cpp2b-windows-x86_64 @@ -56,6 +62,8 @@ jobs: - run: rm ./llvm.sh - run: sudo apt-get install libc++-19-dev ninja-build libclang-19-dev -y - uses: actions/checkout@v4 + with: + submodules: recursive - run: ./build.sh - uses: actions/upload-artifact@v4 with: @@ -75,6 +83,8 @@ jobs: - run: rm ./llvm.sh - run: sudo apt-get install libc++-19-dev ninja-build libclang-19-dev -y - uses: actions/checkout@v4 + with: + submodules: recursive - uses: actions/download-artifact@v4 with: name: cpp2b-linux-x86_64 From 25b8daab8247a73fc669ce93e0a4f21a9e9179eb Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 14:27:20 -0700 Subject: [PATCH 4/9] fix: add parser_wrapper to build.sh --- build.cmd | 2 +- build.sh | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/build.cmd b/build.cmd index f9bde4e..2c9709e 100644 --- a/build.cmd +++ b/build.cmd @@ -170,7 +170,7 @@ if %ERRORLEVEL% neq 0 ( if not exist "%root_dir%.cache/cpp2/source/src" ( mkdir "%root_dir%.cache/cpp2/source/src" ) -%cppfront% src/main.cpp2 -import-std -l -format-colon-errors -o "%root_dir%.cache/cpp2/source/src/main.cpp" +%cppfront% src/main.cpp2 -pure -import-std -l -format-colon-errors -o "%root_dir%.cache/cpp2/source/src/main.cpp" if %ERRORLEVEL% neq 0 exit %ERRORLEVEL% diff --git a/build.sh b/build.sh index 4215875..3b76c46 100755 --- a/build.sh +++ b/build.sh @@ -176,6 +176,20 @@ if ! [ -f $MODULES_DIR/nlohmann.json.pcm ]; then cd $ROOT_DIR fi +if ! [ -f $MODULES_DIR/parser_wrapper.pcm ]; then + log_info "compiling parser_wrapper module..." + + $CPP2B_COMPILER \ + -stdlib=libc++ \ + -std=c++23 \ + -fexperimental-library \ + -isystem $LLVM_ROOT/include/c++/v1 \ + -fprebuilt-module-path=$MODULES_DIR \ + -I"$CPPFRONT_INCLUDE_DIR" \ + "$ROOT_DIR/src/parser_wrapper.cppm" \ + --precompile -o $MODULES_DIR/parser_wrapper.pcm +fi + log_info "compiling cpp2b module..." if [ -f "$ROOT_DIR/.cache/cpp2/source/_build/cpp2b.cppm" ]; then rm "$ROOT_DIR/.cache/cpp2/source/_build/cpp2b.cppm" @@ -199,10 +213,16 @@ log_info "compiling..." $CPP2B_COMPILER \ -g \ -stdlib=libc++ \ + -fmodule-file=cpp2b="$MODULES_DIR/cpp2b.pcm" \ + -fmodule-file=dylib="$MODULES_DIR/dylib.pcm" \ + -fmodule-file=std.compat="$MODULES_DIR/std.compat.pcm" \ + -fmodule-file=nlohmann.json="$MODULES_DIR/nlohmann.json.pcm" \ + -fmodule-file=parser_wrapper="$MODULES_DIR/parser_wrapper.pcm" \ "$MODULES_DIR/cpp2b.pcm" \ "$MODULES_DIR/dylib.pcm" \ "$MODULES_DIR/std.compat.pcm" \ "$MODULES_DIR/nlohmann.json.pcm" \ + "$MODULES_DIR/parser_wrapper.pcm" \ "$ROOT_DIR/.cache/cpp2/source/src/main.cpp" \ -std=c++23 \ -fexperimental-library \ From a5b46f6cb717a8ff74b67f5acc9bbcaffcebca62 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 14:28:42 -0700 Subject: [PATCH 5/9] chore: ignore typos in cppfront --- typos.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/typos.toml b/typos.toml index cec9439..c179e70 100644 --- a/typos.toml +++ b/typos.toml @@ -1,6 +1,7 @@ [files] extend-exclude = [ "src/nlohmann.json.cppm", + "cppfront", ] [default] From 5ccd2b6ffbaa795a8fe50dd7ce469d90b128d03c Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 15:16:39 -0700 Subject: [PATCH 6/9] chore: more assertions --- src/main.cpp2 | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main.cpp2 b/src/main.cpp2 index 3b0d372..f03ef4f 100644 --- a/src/main.cpp2 +++ b/src/main.cpp2 @@ -1103,17 +1103,16 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c cppfront_url: std::string = "hsutter/cppfront"; cppfront_version: std::string = "v0.8.1"; - if fs::exists("build.cpp2") { - build_info_variant := cpp2b_parse_source("build.cpp2"); - if build_info_variant.is_build() { - build_info := build_info_variant.build(); - if build_info.constants.contains("cppfront_url") { - cppfront_url = build_info.constants.at("cppfront_url"); - } - if build_info.constants.contains("cppfront_version") { - cppfront_version = build_info.constants.at("cppfront_version"); - } - } + expect_file("build.cpp2"); + build_info_variant := cpp2b_parse_source("build.cpp2"); + assert(build_info_variant.is_build()); + + build_info := build_info_variant.build(); + if build_info.constants.contains("cppfront_url") { + cppfront_url = build_info.constants.at("cppfront_url"); + } + if build_info.constants.contains("cppfront_version") { + cppfront_version = build_info.constants.at("cppfront_version"); } cppfront_info_path: fs::path = ".cache/cpp2/tools/cppfront.info"; From cb8a636d1596dd869a6a419b24e61bfd6e47050b Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 15:17:34 -0700 Subject: [PATCH 7/9] chore: remove some unused build functions --- build.sh | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/build.sh b/build.sh index 3b76c46..827af77 100755 --- a/build.sh +++ b/build.sh @@ -60,33 +60,6 @@ fi log_info "using compiler '$CPP2B_COMPILER' version '$COMPILER_VERSION'" -function ensure_gh_repo() { - local repo=$1 - local branch=$2 - local repo_path=$ROOT_DIR/.cache/repos/$repo - if ! [ -d $repo_path ]; then - mkdir -p $repo_path - git clone --quiet --depth=1 --branch=$branch --filter=blob:none --sparse https://github.com/$repo $repo_path - fi -} - -function ensure_gh_repo_subdir() { - local repo=$1 - local repo_path=$ROOT_DIR/.cache/repos/$repo - local repo_subdir=$2 - local repo_subdir_path=$repo_path/$repo_subdir - if ! [ -d $repo_subdir_path ]; then - cd $repo_path - log_info "checking out repo $repo/$reposubdir" - git sparse-checkout add $repo_subdir - cd $ROOT_DIR - fi -} - -# ensure_gh_repo "hsutter/cppfront" "v0.8.1" -# ensure_gh_repo_subdir "hsutter/cppfront" "source" -# ensure_gh_repo_subdir "hsutter/cppfront" "include" - CPPFRONT_INCLUDE_DIR=$ROOT_DIR/cppfront/source LLVM_ROOT=/usr/lib/llvm-$COMPILER_MAJOR_VERSION From a6e9482678db35926135cd4c3adca3cc61e57ec5 Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 15:40:40 -0700 Subject: [PATCH 8/9] feat: simplified cppfront version selection --- build.cpp2 | 3 +-- src/main.cpp2 | 60 ++++++++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/build.cpp2 b/build.cpp2 index 20d0af5..69edbba 100644 --- a/build.cpp2 +++ b/build.cpp2 @@ -1,7 +1,6 @@ import cpp2b.build; -cppfront_url :== "hsutter/cppfront"; -cppfront_version :== "v0.8.1"; +cppfront :== "v0.8.1"; build: (inout b: cpp2b::build) -> void = { _ = b.cpp1_module().source_path("src/dylib.cppm"); diff --git a/src/main.cpp2 b/src/main.cpp2 index f03ef4f..405c642 100644 --- a/src/main.cpp2 +++ b/src/main.cpp2 @@ -103,20 +103,20 @@ GitRepo: type = { operator=: (out this, repo: std::string_view, repo_branch: std::string_view) = { branch = std::string(repo_branch); - if repo.find("://") != std::string_view::npos { - clone_url = std::string(repo); - last_slash := repo.find_last_of('/'); - if last_slash != std::string_view::npos { - repo_name = std::string(repo.substr(last_slash + 1)); - if repo_name.string().ends_with(".git") { - repo_name = repo_name.string().substr(0, repo_name.string().size() - 4); - } - } else { - repo_name = std::string(repo); - } + clone_url = std::string(repo); + + m: git_clone_url_matcher = (); + result := m.regex.match(clone_url); + + if result.matched { + host := result.group(1); + owner := result.group(2); + name := result.group(3); + repo_name = fs::path(host) / owner / name; } else { - clone_url = "https://github.com/(repo)$"; - repo_name = std::string(repo); + log_error("invalid git clone url: {}", clone_url); + log_error("expected format: [proto://]host/owner/repo[.git]"); + std::exit(1); } } @@ -894,10 +894,16 @@ cpp2b_detail_git_clone: ( m: git_clone_url_matcher = (); result := m.regex.match(repo_impl*.clone_url); - - repo_impl*.clone_host = result.group(1); - repo_impl*.clone_owner_dirname = result.group(2); - repo_impl*.clone_repo_dirname = result.group(3); + + if result.matched { + repo_impl*.clone_host = result.group(1); + repo_impl*.clone_owner_dirname = result.group(2); + repo_impl*.clone_repo_dirname = result.group(3); + } else { + log_error("invalid git clone url: {}", repo_impl*.clone_url); + log_error("expected format: [proto://]host/owner/repo[.git]"); + std::exit(1); + } impl*.git_repos.emplace_back(repo_impl); @@ -1100,8 +1106,8 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c build_cpp2_dir := fs::current_path(); stuff = (); - cppfront_url: std::string = "hsutter/cppfront"; - cppfront_version: std::string = "v0.8.1"; + cppfront_url: std::string = "https://github.com/hsutter/cppfront.git"; + cppfront: std::string = "v0.8.1"; expect_file("build.cpp2"); build_info_variant := cpp2b_parse_source("build.cpp2"); @@ -1111,8 +1117,8 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c if build_info.constants.contains("cppfront_url") { cppfront_url = build_info.constants.at("cppfront_url"); } - if build_info.constants.contains("cppfront_version") { - cppfront_version = build_info.constants.at("cppfront_version"); + if build_info.constants.contains("cppfront") { + cppfront = build_info.constants.at("cppfront"); } cppfront_info_path: fs::path = ".cache/cpp2/tools/cppfront.info"; @@ -1121,15 +1127,15 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c if fs::exists(cppfront_info_path) && fs::exists(cppfront_bin) { info_stream: std::ifstream = cppfront_info_path; stored_url: std::string = (); - stored_version: std::string = (); + stored_cppfront: std::string = (); std::getline(info_stream, stored_url); - std::getline(info_stream, stored_version); + std::getline(info_stream, stored_cppfront); if stored_url != cppfront_url { log_info("cppfront_url changed: {} -> {}", stored_url, cppfront_url); needs_recompile = true; } - if stored_version != cppfront_version { - log_info("cppfront_version changed: {} -> {}", stored_version, cppfront_version); + if stored_cppfront != cppfront { + log_info("cppfront changed: {} -> {}", stored_cppfront, cppfront); needs_recompile = true; } } else { @@ -1142,7 +1148,7 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c } } - (repo := GitRepo(cppfront_url, cppfront_version)) { + (repo := GitRepo(cppfront_url, cppfront)) { if needs_recompile || !fs::exists(repo.path() / ".git") { repo.fetch(); repo.add("source"); @@ -1154,7 +1160,7 @@ do_build: (targets: std::vector) -> (stuff: full_build_info, exit_c if needs_recompile { info_out: std::ofstream = (cppfront_info_path, std::ios::binary); - info_out << cppfront_url << "\n" << cppfront_version << "\n"; + info_out << cppfront_url << "\n" << cppfront << "\n"; } stuff.cppfront_include_dir = repo.path() / "source"; From 35cb5869d892107401423311b94a688db79ef1bd Mon Sep 17 00:00:00 2001 From: Ezekiel Warren Date: Fri, 8 May 2026 15:47:40 -0700 Subject: [PATCH 9/9] chore: rename cpp2b build info parser --- build.cmd | 8 ++++---- build.cpp2 | 2 +- build.sh | 12 ++++++------ ...ser_wrapper.cppm => cpp2b_build_info_parser.cppm} | 6 +++--- src/main.cpp2 | 10 +++++----- 5 files changed, 19 insertions(+), 19 deletions(-) rename src/{parser_wrapper.cppm => cpp2b_build_info_parser.cppm} (97%) diff --git a/build.cmd b/build.cmd index 2c9709e..39965a2 100644 --- a/build.cmd +++ b/build.cmd @@ -140,18 +140,18 @@ if %ERRORLEVEL% neq 0 ( exit %ERRORLEVEL% ) -echo INFO: compiling parser_wrapper module... +echo INFO: compiling cpp2b_build_info_parser module... pushd %modules_dir% cl /nologo ^ /std:c++latest /W4 /MDd /EHsc ^ -I"%cppfront_include_dir%" ^ /reference "%modules_dir%\std.ifc" ^ /reference "%modules_dir%\std.compat.ifc" ^ - /c /interface /TP "%root_dir%src\parser_wrapper.cppm" > NUL + /c /interface /TP "%root_dir%src\cpp2b_build_info_parser.cppm" > NUL popd if %ERRORLEVEL% neq 0 ( - echo ERROR: failed to compile parser_wrapper module + echo ERROR: failed to compile cpp2b_build_info_parser module exit %ERRORLEVEL% ) @@ -182,7 +182,7 @@ cl /nologo "%root_dir%.cache/cpp2/source/src/main.cpp" ^ /reference "%modules_dir%\dylib.ifc" "%modules_dir%\dylib.obj" ^ /reference "%modules_dir%\nlohmann.json.ifc" "%modules_dir%\nlohmann.json.obj" ^ /reference "%modules_dir%\cpp2b.ifc" "%modules_dir%\cpp2b.obj" ^ - /reference "%modules_dir%\parser_wrapper.ifc" "%modules_dir%\parser_wrapper.obj" ^ + /reference "%modules_dir%\cpp2b_build_info_parser.ifc" "%modules_dir%\cpp2b_build_info_parser.obj" ^ /std:c++latest /W4 /MDd /EHsc ^ /DEBUG:FULL /Zi /FC ^ -I"%cppfront_include_dir%" ^ diff --git a/build.cpp2 b/build.cpp2 index 69edbba..d2baad7 100644 --- a/build.cpp2 +++ b/build.cpp2 @@ -6,7 +6,7 @@ build: (inout b: cpp2b::build) -> void = { _ = b.cpp1_module().source_path("src/dylib.cppm"); _ = b.cpp1_module().source_path("src/nlohmann.json.cppm"); _ = b.cpp1_module() - .source_path("src/parser_wrapper.cppm") + .source_path("src/cpp2b_build_info_parser.cppm") .include_directory("cppfront/source"); b.binary_name("src/main", "cpp2b"); } diff --git a/build.sh b/build.sh index 827af77..2fd9b20 100755 --- a/build.sh +++ b/build.sh @@ -149,8 +149,8 @@ if ! [ -f $MODULES_DIR/nlohmann.json.pcm ]; then cd $ROOT_DIR fi -if ! [ -f $MODULES_DIR/parser_wrapper.pcm ]; then - log_info "compiling parser_wrapper module..." +if ! [ -f $MODULES_DIR/cpp2b_build_info_parser.pcm ]; then + log_info "compiling cpp2b_build_info_parser module..." $CPP2B_COMPILER \ -stdlib=libc++ \ @@ -159,8 +159,8 @@ if ! [ -f $MODULES_DIR/parser_wrapper.pcm ]; then -isystem $LLVM_ROOT/include/c++/v1 \ -fprebuilt-module-path=$MODULES_DIR \ -I"$CPPFRONT_INCLUDE_DIR" \ - "$ROOT_DIR/src/parser_wrapper.cppm" \ - --precompile -o $MODULES_DIR/parser_wrapper.pcm + "$ROOT_DIR/src/cpp2b_build_info_parser.cppm" \ + --precompile -o $MODULES_DIR/cpp2b_build_info_parser.pcm fi log_info "compiling cpp2b module..." @@ -190,12 +190,12 @@ $CPP2B_COMPILER \ -fmodule-file=dylib="$MODULES_DIR/dylib.pcm" \ -fmodule-file=std.compat="$MODULES_DIR/std.compat.pcm" \ -fmodule-file=nlohmann.json="$MODULES_DIR/nlohmann.json.pcm" \ - -fmodule-file=parser_wrapper="$MODULES_DIR/parser_wrapper.pcm" \ + -fmodule-file=cpp2b_build_info_parser="$MODULES_DIR/cpp2b_build_info_parser.pcm" \ "$MODULES_DIR/cpp2b.pcm" \ "$MODULES_DIR/dylib.pcm" \ "$MODULES_DIR/std.compat.pcm" \ "$MODULES_DIR/nlohmann.json.pcm" \ - "$MODULES_DIR/parser_wrapper.pcm" \ + "$MODULES_DIR/cpp2b_build_info_parser.pcm" \ "$ROOT_DIR/.cache/cpp2/source/src/main.cpp" \ -std=c++23 \ -fexperimental-library \ diff --git a/src/parser_wrapper.cppm b/src/cpp2b_build_info_parser.cppm similarity index 97% rename from src/parser_wrapper.cppm rename to src/cpp2b_build_info_parser.cppm index f759411..f793d9c 100644 --- a/src/parser_wrapper.cppm +++ b/src/cpp2b_build_info_parser.cppm @@ -1,10 +1,10 @@ module; #include "parse.h" -export module parser_wrapper; +export module cpp2b_build_info_parser; import std; -export namespace parser_wrapper { +export namespace cpp2b_build_info_parser { enum class source_kind { unknown, module, binary, build }; @@ -132,4 +132,4 @@ source_info parse_source(const std::string& filename) { return result; } -} // namespace parser_wrapper +} // namespace cpp2b_build_info_parser diff --git a/src/main.cpp2 b/src/main.cpp2 index 405c642..3abdfeb 100644 --- a/src/main.cpp2 +++ b/src/main.cpp2 @@ -2,7 +2,7 @@ import std.compat; import cpp2b; import dylib; import nlohmann.json; -import parser_wrapper; +import cpp2b_build_info_parser; fs: namespace == std::filesystem; json: type == nlohmann::json; @@ -1768,7 +1768,7 @@ cpp2b_parse_cpp1_module_statements: (copy stream: std::ifstream) -> (module_name } cpp2b_parse_source: (source_file: fs::path) -> cpp2b_source_info = { - info := parser_wrapper::parse_source(source_file.string()); + info := cpp2b_build_info_parser::parse_source(source_file.string()); if std::ranges::find(info.imports, "std") == info.imports.end() { info.imports.emplace_back("std"); @@ -1781,7 +1781,7 @@ cpp2b_parse_source: (source_file: fs::path) -> cpp2b_source_info = { result: cpp2b_source_info = (); result.set_unknown(cpp2b_source_unknown_info(source_file)); - if info.kind == parser_wrapper::source_kind::build { + if info.kind == cpp2b_build_info_parser::source_kind::build { build_info: cpp2b_source_build_info = (); build_info.src = source_file; build_info.imports = info.imports; @@ -1790,7 +1790,7 @@ cpp2b_parse_source: (source_file: fs::path) -> cpp2b_source_info = { return result; } - if info.kind == parser_wrapper::source_kind::module { + if info.kind == cpp2b_build_info_parser::source_kind::module { mod_info: cpp2b_source_module_info = (); mod_info.name = info.module_name; mod_info.imports = info.imports; @@ -1799,7 +1799,7 @@ cpp2b_parse_source: (source_file: fs::path) -> cpp2b_source_info = { return result; } - if info.kind == parser_wrapper::source_kind::binary { + if info.kind == cpp2b_build_info_parser::source_kind::binary { bin_info: cpp2b_source_binary_info = (); bin_info.src = source_file; bin_info.imports = info.imports;