stage2 迁移nob 修复nob的问题 继续修复类型导入问题
This commit is contained in:
1 parent
70085355db
commit
9ecb92cb03
5 files changed
+251
-278
No files matched your search
+228
@@ -0,0 +1,228 @@
|
||||
#ifndef __NOB_DATA_H__
|
||||
#define __NOB_DATA_H__
|
||||
|
||||
/* clang-format off */
|
||||
#define VM_SRCS "stage0/spl_mcode.c", "stage0/spl_syscall.c", "stage0/spl_vm.c",
|
||||
static const char *spl_cli_srcs[] = {"stage0/spl_cli.c", VM_SRCS};
|
||||
static const char *vm_test_srcs[] = {"stage0/test_spl_vm.c", VM_SRCS};
|
||||
static const char *splc0_srcs[] = {
|
||||
"stage1/splc0.c",
|
||||
"stage1/spl_diag.c",
|
||||
"stage1/spl_tok.c",
|
||||
"stage1/spl_lexer.c",
|
||||
"stage1/spl_ast.c",
|
||||
"stage1/spl_parser.c",
|
||||
"stage1/spl_dumptree.c",
|
||||
"stage1/spl_type.c",
|
||||
"stage1/spl_fold.c",
|
||||
"stage1/spl_lang_type.c",
|
||||
"stage1/spl_attr.c",
|
||||
"stage1/spl_scope.c",
|
||||
"stage1/spl_sema.c",
|
||||
"stage1/spl_intrin.c",
|
||||
"stage1/spl_ir.c",
|
||||
"stage1/spl_ast2ir.c",
|
||||
"stage1/spl_layout.c",
|
||||
"stage1/spl_ir2vm.c",
|
||||
"stage1/ir_opt.c",
|
||||
"stage1/vm_opt.c",
|
||||
"stage0/spl_mcode.c",
|
||||
};
|
||||
|
||||
static const char *splc1_crt_deps[] ={
|
||||
"stage2/sys/spl_rt.h",
|
||||
"stage2/sys/spl_vm_embed.h",
|
||||
// TODO
|
||||
};
|
||||
|
||||
static const char* splc1_deps[] = {
|
||||
"stage2/sys/exit.spl",
|
||||
"stage2/sys/file.spl",
|
||||
"stage2/sys/mem.spl",
|
||||
"stage2/sys/time.spl",
|
||||
"stage2/sys/vm.spl",
|
||||
"stage2/utils/algorithm.spl",
|
||||
"stage2/utils/arena.spl",
|
||||
"stage2/utils/ascii.spl",
|
||||
"stage2/utils/byte_buffer.spl",
|
||||
"stage2/utils/byte_view.spl",
|
||||
"stage2/utils/error.spl",
|
||||
"stage2/utils/fmt.spl",
|
||||
"stage2/utils/hash.spl",
|
||||
"stage2/utils/io.spl",
|
||||
"stage2/utils/json.spl",
|
||||
"stage2/utils/log.spl",
|
||||
"stage2/utils/lsp_frame.spl",
|
||||
"stage2/utils/map.spl",
|
||||
"stage2/utils/memory.spl",
|
||||
"stage2/utils/mp.spl",
|
||||
"stage2/utils/path.spl",
|
||||
"stage2/utils/profile.spl",
|
||||
"stage2/utils/set.spl",
|
||||
"stage2/utils/source.spl",
|
||||
"stage2/utils/str.spl",
|
||||
"stage2/utils/utf8.spl",
|
||||
"stage2/utils/value.spl",
|
||||
"stage2/utils/vec.spl",
|
||||
"stage2/ast.spl",
|
||||
"stage2/ast2ir.spl",
|
||||
"stage2/attr.spl",
|
||||
"stage2/def.spl",
|
||||
"stage2/diag.spl",
|
||||
"stage2/eval.spl",
|
||||
"stage2/intrin.spl",
|
||||
"stage2/ir.spl",
|
||||
"stage2/ir2c.spl",
|
||||
"stage2/ir2vm.spl",
|
||||
"stage2/ir_builder.spl",
|
||||
"stage2/lang_type.spl",
|
||||
"stage2/layout.spl",
|
||||
"stage2/lexer.spl",
|
||||
"stage2/mcode.spl",
|
||||
"stage2/parser.spl",
|
||||
"stage2/scope.spl",
|
||||
"stage2/sema.spl",
|
||||
"stage2/splc1.spl",
|
||||
"stage2/token.spl",
|
||||
"stage2/type_table.spl",
|
||||
};
|
||||
|
||||
static const char* splc2_deps[] = {
|
||||
|
||||
};
|
||||
|
||||
static const char *splc2_crt_deps[] = {};
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
typedef struct build {
|
||||
const char *name;
|
||||
enum {
|
||||
BUILD_EXE,
|
||||
BUILD_EXE_WITH_OPTIMIZATION,
|
||||
BUILD_SIR,
|
||||
BUILD_NATIVE,
|
||||
} kind;
|
||||
union {
|
||||
struct {
|
||||
const char **srcs;
|
||||
size_t srcs_count;
|
||||
const char **headers;
|
||||
size_t headers_count;
|
||||
} exe;
|
||||
struct {
|
||||
const char *src;
|
||||
const char *compiler;
|
||||
const char **deps;
|
||||
size_t deps_count;
|
||||
} sir;
|
||||
struct {
|
||||
const char *src;
|
||||
const char *compiler;
|
||||
const char **deps;
|
||||
size_t deps_count;
|
||||
const char **crt_deps;
|
||||
size_t crt_deps_count;
|
||||
} native;
|
||||
};
|
||||
} build_t;
|
||||
|
||||
typedef struct run {
|
||||
const char *name;
|
||||
const char *interpreter;
|
||||
} run_t;
|
||||
|
||||
static build_t targets[] = {
|
||||
{
|
||||
"spl_cli",
|
||||
BUILD_EXE_WITH_OPTIMIZATION,
|
||||
.exe = {.srcs = spl_cli_srcs,
|
||||
.srcs_count = NOB_ARRAY_LEN(spl_cli_srcs),
|
||||
.headers = NULL,
|
||||
.headers_count = 0},
|
||||
},
|
||||
{
|
||||
"spl_cli_g",
|
||||
BUILD_EXE,
|
||||
.exe = {.srcs = spl_cli_srcs,
|
||||
.srcs_count = NOB_ARRAY_LEN(spl_cli_srcs),
|
||||
.headers = NULL,
|
||||
.headers_count = 0},
|
||||
},
|
||||
{
|
||||
"vm_test",
|
||||
BUILD_EXE,
|
||||
.exe = {.srcs = vm_test_srcs,
|
||||
.srcs_count = NOB_ARRAY_LEN(vm_test_srcs),
|
||||
.headers = NULL,
|
||||
.headers_count = 0},
|
||||
},
|
||||
{
|
||||
"splc0",
|
||||
BUILD_EXE,
|
||||
.exe = {.srcs = splc0_srcs,
|
||||
.srcs_count = NOB_ARRAY_LEN(splc0_srcs),
|
||||
.headers = NULL,
|
||||
.headers_count = 0},
|
||||
},
|
||||
{
|
||||
"splc1",
|
||||
BUILD_SIR,
|
||||
.sir = {.src = "stage2/splc1.spl",
|
||||
.compiler = "splc0",
|
||||
.deps = splc1_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc1_deps)},
|
||||
},
|
||||
{
|
||||
"splc1s",
|
||||
BUILD_SIR,
|
||||
.sir = {.src = "stage2/splc1.spl",
|
||||
.compiler = "splc1",
|
||||
.deps = splc1_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc1_deps)},
|
||||
},
|
||||
{
|
||||
"splc1r",
|
||||
BUILD_SIR,
|
||||
.sir = {.src = "stage2/splc1.spl",
|
||||
.compiler = "splc1s",
|
||||
.deps = splc1_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc1_deps)},
|
||||
},
|
||||
{
|
||||
"splc1n",
|
||||
BUILD_NATIVE,
|
||||
.native = {.src = "stage2/splc1.spl",
|
||||
.compiler = "splc1",
|
||||
.deps = splc1_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc1_deps),
|
||||
.crt_deps = splc1_crt_deps,
|
||||
.crt_deps_count = NOB_ARRAY_LEN(splc1_crt_deps)},
|
||||
},
|
||||
{
|
||||
"splc2",
|
||||
BUILD_SIR,
|
||||
.sir = {.src = "stage3/splc2.spl",
|
||||
.compiler = "splc1n",
|
||||
.deps = splc2_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc2_deps)},
|
||||
},
|
||||
{
|
||||
"splc2n",
|
||||
BUILD_NATIVE,
|
||||
.native = {.src = "stage3/splc2.spl",
|
||||
.compiler = "splc1n",
|
||||
.deps = splc2_deps,
|
||||
.deps_count = NOB_ARRAY_LEN(splc2_deps),
|
||||
.crt_deps = splc2_crt_deps,
|
||||
.crt_deps_count = NOB_ARRAY_LEN(splc2_crt_deps)},
|
||||
},
|
||||
};
|
||||
|
||||
static run_t runs[] = {
|
||||
{"spl_cli", NULL}, {"vm_test", NULL}, {"splc0", NULL},
|
||||
{"splc1", "spl_cli"}, {"splc1r", "spl_cli"}, {"splc1s", "spl_cli"},
|
||||
{"splc1n", NULL}, {"splc2", "spl_cli"}, {"splc2n", NULL},
|
||||
};
|
||||
|
||||
#endif /* __NOB_DATA_H__ */
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
#ifndef __NOB_POPEN_H__
|
||||
#define __NOB_POPEN_H__
|
||||
|
||||
#include "nob.h"
|
||||
|
||||
typedef struct {
|
||||
Nob_String_Builder out; // stdout 内容
|
||||
int exit_code; // 实际退出码
|
||||
bool ok; // 是否成功启动
|
||||
} Nob_Cmd_Result;
|
||||
|
||||
typedef struct {
|
||||
const char **items;
|
||||
int capacity;
|
||||
int count;
|
||||
} Nob_Files;
|
||||
|
||||
// 运行命令,捕获 stdout(Windows 下会合并 stderr)和真实退出码。
|
||||
// 返回 true 仅表示命令成功启动并完成,不代表 exit_code == 0。
|
||||
bool nob_cmd_capture_popen(const char *tname, Nob_Cmd_Result *res) {
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
#ifdef _WIN32
|
||||
// ---------- Windows: CreateProcessA + 匿名管道 ----------
|
||||
SECURITY_ATTRIBUTES sa = {0};
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.bInheritHandle = TRUE;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
|
||||
HANDLE hRead = NULL;
|
||||
HANDLE hWrite = NULL;
|
||||
if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
|
||||
nob_log(NOB_ERROR, "CreatePipe failed: %s", nob_win32_error_message(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// 读端不能被继承,否则父进程 ReadFile 永远等不到 EOF
|
||||
if (!SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0)) {
|
||||
nob_log(NOB_ERROR, "SetHandleInformation failed: %s",
|
||||
nob_win32_error_message(GetLastError()));
|
||||
CloseHandle(hRead);
|
||||
CloseHandle(hWrite);
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTUPINFOA si = {0};
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
si.hStdOutput = hWrite;
|
||||
si.hStdError = hWrite; // 把 stderr 也并入 out,需要分离的话另开一条管道
|
||||
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
|
||||
// CreateProcessA 会就地修改 lpCommandLine,必须传可写缓冲
|
||||
char *cmdline = NULL;
|
||||
{
|
||||
size_t n = strlen(tname) + 1;
|
||||
cmdline = (char *)malloc(n);
|
||||
if (!cmdline) {
|
||||
CloseHandle(hRead);
|
||||
CloseHandle(hWrite);
|
||||
nob_log(NOB_ERROR, "malloc failed");
|
||||
return false;
|
||||
}
|
||||
memcpy(cmdline, tname, n);
|
||||
}
|
||||
|
||||
BOOL ok = CreateProcessA(NULL, // lpApplicationName: 让系统从 lpCommandLine 里解析
|
||||
cmdline, // lpCommandLine
|
||||
NULL, // lpProcessAttributes
|
||||
NULL, // lpThreadAttributes
|
||||
TRUE, // bInheritHandles: 必须为 TRUE,才能继承管道写端
|
||||
CREATE_NO_WINDOW, // 不弹黑窗;想弹就传 0
|
||||
NULL, // lpEnvironment
|
||||
NULL, // lpCurrentDirectory
|
||||
&si, &pi);
|
||||
|
||||
free(cmdline);
|
||||
|
||||
// 无论成功与否,父进程都不再需要写端(子进程已持有自己的副本)
|
||||
CloseHandle(hWrite);
|
||||
|
||||
if (!ok) {
|
||||
nob_log(NOB_ERROR, "CreateProcessA failed for \"%s\": %s", tname,
|
||||
nob_win32_error_message(GetLastError()));
|
||||
CloseHandle(hRead);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------- 读取 stdout ----------
|
||||
{
|
||||
char buffer[4096];
|
||||
DWORD n = 0;
|
||||
while (ReadFile(hRead, buffer, sizeof(buffer), &n, NULL) && n > 0) {
|
||||
nob_sb_append_buf(&res->out, buffer, (size_t)n);
|
||||
}
|
||||
}
|
||||
CloseHandle(hRead);
|
||||
|
||||
// ---------- 等待并取真实退出码 ----------
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
DWORD code = 0;
|
||||
if (!GetExitCodeProcess(pi.hProcess, &code)) {
|
||||
nob_log(NOB_ERROR, "GetExitCodeProcess failed: %s",
|
||||
nob_win32_error_message(GetLastError()));
|
||||
code = (DWORD)-1;
|
||||
}
|
||||
res->exit_code = (int)code;
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
#else
|
||||
// ---------- POSIX: popen ----------
|
||||
FILE *fp = popen(tname, "r");
|
||||
if (!fp) {
|
||||
nob_log(NOB_ERROR, "popen failed: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
nob_sb_append_cstr(&res->out, buffer);
|
||||
}
|
||||
|
||||
int status = pclose(fp);
|
||||
if (status == -1) {
|
||||
nob_log(NOB_ERROR, "pclose failed: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (WIFEXITED(status))
|
||||
status = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status))
|
||||
status = 128 + WTERMSIG(status);
|
||||
res->exit_code = status;
|
||||
#endif
|
||||
|
||||
res->ok = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define nob_cmd_result_free(res) nob_sb_free((res).out)
|
||||
|
||||
#endif /* __NOB_POPEN_H__ */
|
||||
Reference in new issue
Block a user