aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-09-18 15:39:22 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-09-18 15:39:22 -0400
commit7f5af625e5045055173fb776fc5aaa5453704f61 (patch)
treed69a512eef5f5a04f039bc0f9d9a210db5d200bd
parent2d78f11400d61f89845678b40e7b0682f14bba7f (diff)
Support `use`ing .c files and .S files (assembly)
-rw-r--r--ast.h2
-rw-r--r--compile.c11
-rw-r--r--parse.c13
-rw-r--r--tomo.c4
-rw-r--r--typecheck.c2
5 files changed, 24 insertions, 8 deletions
diff --git a/ast.h b/ast.h
index 69bdc994..2301100e 100644
--- a/ast.h
+++ b/ast.h
@@ -312,7 +312,7 @@ struct ast_s {
} DocTest;
struct {
const char *path;
- enum { USE_LOCAL, USE_MODULE, USE_SHARED_OBJECT, USE_HEADER } what;
+ enum { USE_LOCAL, USE_MODULE, USE_SHARED_OBJECT, USE_HEADER, USE_C_CODE, USE_ASM } what;
} Use;
struct {
CORD code;
diff --git a/compile.c b/compile.c
index f836cee0..1e2c3693 100644
--- a/compile.c
+++ b/compile.c
@@ -1371,6 +1371,8 @@ CORD compile_statement(env_t *env, ast_t *ast)
if (use->what == USE_LOCAL) {
CORD name = file_base_name(Match(ast, Use)->path);
env->code->variable_initializers = CORD_all(env->code->variable_initializers, name, "$$initialize();\n");
+ } else if (use->what == USE_C_CODE) {
+ return CORD_all("#include \"", use->path, "\"\n");
} else if (use->what == USE_MODULE) {
const char *libname = Text$as_c_string(
Text$replace(Text$from_str(use->path), Pattern("{1+ !alphanumeric}"), Text("_"), Pattern(""), false));
@@ -3735,6 +3737,10 @@ CORD compile_file(env_t *env, ast_t *ast)
} else if (stmt->ast->tag == InlineCCode) {
CORD code = compile_statement(env, stmt->ast);
env->code->staticdefs = CORD_all(env->code->staticdefs, code, "\n");
+ } else if (stmt->ast->tag == Use) {
+ CORD code = compile_statement(env, stmt->ast);
+ if (code)
+ env->code->staticdefs = CORD_all(env->code->staticdefs, code);
} else {
CORD code = compile_statement(env, stmt->ast);
assert(!code);
@@ -3795,7 +3801,10 @@ CORD compile_statement_header(env_t *env, ast_t *ast)
case USE_LOCAL:
return CORD_all("#include \"", use->path, ".h\"\n");
case USE_HEADER:
- return CORD_all("#include ", use->path, "\n");
+ if (use->path[0] == '<')
+ return CORD_all("#include ", use->path, "\n");
+ else
+ return CORD_all("#include \"", use->path, "\"\n");
default:
return CORD_EMPTY;
}
diff --git a/parse.c b/parse.c
index b387eb5d..b3f9a0c3 100644
--- a/parse.c
+++ b/parse.c
@@ -2356,14 +2356,19 @@ PARSER(parse_use) {
pos += name_len;
while (match(&pos, ";")) continue;
int what;
- if (name[0] == '<' || name[0] == '"')
+ if (name[0] == '<' || ends_with(name, ".h")) {
what = USE_HEADER;
- else if (starts_with(name, "./") || starts_with(name, "/") || starts_with(name, "../") || starts_with(name, "~/"))
+ } else if (ends_with(name, ".c")) {
+ what = USE_C_CODE;
+ } else if (ends_with(name, ".S") || ends_with(name, ".s")) {
+ what = USE_ASM;
+ } else if (starts_with(name, "./") || starts_with(name, "/") || starts_with(name, "../") || starts_with(name, "~/")) {
what = USE_LOCAL;
- else if (ends_with(name, ".so"))
+ } else if (ends_with(name, ".so")) {
what = USE_SHARED_OBJECT;
- else
+ } else {
what = USE_MODULE;
+ }
return NewAST(ctx->file, start, pos, Use, .path=name, .what=what);
}
diff --git a/tomo.c b/tomo.c
index 104f2760..9340abe9 100644
--- a/tomo.c
+++ b/tomo.c
@@ -431,6 +431,10 @@ void build_file_dependency_graph(const char *filename, Table_t *to_compile, Tabl
Table$str_set(to_link, lib, lib);
break;
}
+ case USE_ASM: {
+ Table$str_set(to_link, use->path, use->path);
+ break;
+ }
default: case USE_HEADER: break;
}
}
diff --git a/typecheck.c b/typecheck.c
index 8f1e5e81..29743e63 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -191,8 +191,6 @@ static env_t *load_module(env_t *env, ast_t *module_ast)
globfree(&tm_files);
return module_env;
}
- case USE_SHARED_OBJECT: return NULL;
- case USE_HEADER: return NULL;
default: return NULL;
}
}