gen/
.clang-format
570 B
.gitignore
30 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
911 B
README
1.8 KiB
ast.c
5.0 KiB
ast.h
15.1 KiB
desugar.c
23.1 KiB
desugar.h
286 B
gen.c
108.5 KiB
gen.h
4.9 KiB
io.c
1.1 KiB
io.h
444 B
limits.h
1.3 KiB
module.c
10.0 KiB
module.h
2.2 KiB
options.c
1.4 KiB
options.h
472 B
parser.c
68.3 KiB
parser.h
942 B
radiance.c
3.7 KiB
ralloc.c
2.0 KiB
ralloc.h
1.1 KiB
resolver.c
109.7 KiB
resolver.h
5.6 KiB
riscv.c
12.0 KiB
riscv.h
12.0 KiB
scanner.c
10.2 KiB
scanner.h
3.2 KiB
strings.c
2.6 KiB
strings.h
407 B
symtab.c
5.7 KiB
symtab.h
4.6 KiB
types.h
1.0 KiB
util.h
1.5 KiB
radiance.c
raw
| 1 | #include <errno.h> |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <string.h> |
| 5 | #include <unistd.h> |
| 6 | |
| 7 | #include "ast.h" |
| 8 | #include "desugar.h" |
| 9 | #include "gen.h" |
| 10 | #include "io.h" |
| 11 | #include "module.h" |
| 12 | #include "options.h" |
| 13 | #include "parser.h" |
| 14 | #include "resolver.h" |
| 15 | #include "scanner.h" |
| 16 | #include "strings.h" |
| 17 | #include "symtab.h" |
| 18 | #include "types.h" |
| 19 | #include "util.h" |
| 20 | |
| 21 | static int compile(struct options *o) { |
| 22 | if (o->ninputs > 1) { |
| 23 | bail("too many inputs (%d)", o->ninputs); |
| 24 | } |
| 25 | if (o->ninputs < 1) { |
| 26 | bail("no input files"); |
| 27 | } |
| 28 | if (!o->output) { |
| 29 | bail("an output file must be specified with `-o`"); |
| 30 | } |
| 31 | |
| 32 | FILE *text = NULL; |
| 33 | FILE *data_ro = NULL; |
| 34 | FILE *data_rw = NULL; |
| 35 | const char *rootpath = o->inputs[0]; |
| 36 | int err = MODULE_OK; |
| 37 | |
| 38 | static module_manager_t mm; |
| 39 | module_manager_init(&mm, rootpath); |
| 40 | |
| 41 | /* Register the root module */ |
| 42 | if (!(mm.root = module_manager_register(&mm, rootpath))) { |
| 43 | bail("error registering root module '%s'", rootpath); |
| 44 | } |
| 45 | |
| 46 | /* Register additional modules specified with -mod. |
| 47 | * |
| 48 | * Module paths are given as full relative paths (e.g. `lib/std/foo.rad`). |
| 49 | * The qualified name is derived by stripping the leading directory |
| 50 | * component (e.g. `std/foo.rad`). */ |
| 51 | for (int i = 0; i < o->nmodules; i++) { |
| 52 | const char *path = o->modules[i]; |
| 53 | const char *qualified = strchr(path, '/'); |
| 54 | qualified = qualified ? qualified + 1 : path; |
| 55 | |
| 56 | if (!module_manager_register_qualified(&mm, path, qualified)) { |
| 57 | bail("error registering module '%s'", path); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /* Parse all modules */ |
| 62 | if (!module_manager_parse(&mm, &err)) { |
| 63 | bail("error parsing modules"); |
| 64 | } |
| 65 | |
| 66 | /* Run desugaring pass on all modules */ |
| 67 | for (usize i = 0; i < mm.nmodules; i++) { |
| 68 | module_t *mod = &mm.modules[i]; |
| 69 | |
| 70 | if (mod->ast) { |
| 71 | static desugar_t d; |
| 72 | |
| 73 | mod->ast = desugar_run(&d, mod, mod->ast); |
| 74 | if (!mod->ast) { |
| 75 | bail("desugaring failed for module %s", mod->name); |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | static resolve_t t; |
| 81 | resolve_init(&t, &mm); |
| 82 | |
| 83 | if (!resolve_run(&t, mm.root)) { |
| 84 | bail("type checking failed"); |
| 85 | } |
| 86 | |
| 87 | /* Initialize code generator */ |
| 88 | static gen_t g; |
| 89 | gen_init(&g, &t.types, &mm, 0); |
| 90 | |
| 91 | if (!(text = fopen(o->output, "w"))) { |
| 92 | bail("failed to open '%s' for writing: %s", o->output, strerror(errno)); |
| 93 | } |
| 94 | |
| 95 | /* Generate code */ |
| 96 | if (gen_emit(&g, mm.root) != 0) { |
| 97 | bail("code generation failed"); |
| 98 | } |
| 99 | |
| 100 | /* Write binary output */ |
| 101 | if (g.data.ro_size > 0) { |
| 102 | char datapath_ro[MAX_PATH_LEN] = { 0 }; |
| 103 | strncpy(datapath_ro, o->output, MAX_PATH_LEN); |
| 104 | strlcat(datapath_ro, ".ro.data", MAX_PATH_LEN); |
| 105 | |
| 106 | if (!(data_ro = fopen(datapath_ro, "w"))) { |
| 107 | bail( |
| 108 | "failed to open '%s' for writing: %s", |
| 109 | datapath_ro, |
| 110 | strerror(errno) |
| 111 | ); |
| 112 | } |
| 113 | } |
| 114 | if (g.data.rw_init_total > 0) { |
| 115 | char datapath[MAX_PATH_LEN] = { 0 }; |
| 116 | strncpy(datapath, o->output, MAX_PATH_LEN); |
| 117 | strlcat(datapath, ".rw.data", MAX_PATH_LEN); |
| 118 | |
| 119 | if (!(data_rw = fopen(datapath, "w"))) { |
| 120 | bail( |
| 121 | "failed to open '%s' for writing: %s", datapath, strerror(errno) |
| 122 | ); |
| 123 | } |
| 124 | } |
| 125 | gen_dump_bin(&g, text, data_ro, data_rw); |
| 126 | |
| 127 | if (data_ro) |
| 128 | fclose(data_ro); |
| 129 | if (data_rw) |
| 130 | fclose(data_rw); |
| 131 | if (text) |
| 132 | fclose(text); |
| 133 | |
| 134 | return 0; |
| 135 | } |
| 136 | |
| 137 | int main(int argc, char *argv[]) { |
| 138 | strings_init(); |
| 139 | |
| 140 | struct options o = options(argc, argv); |
| 141 | options_parse(&o); |
| 142 | |
| 143 | if (compile(&o) != 0) { |
| 144 | bail("compilation failed"); |
| 145 | } |
| 146 | return 0; |
| 147 | } |