Skip to content

Commit 888ca4b

Browse files
committed
use external symbol names during code gen
1 parent b9423de commit 888ca4b

File tree

12 files changed

+226
-53
lines changed

12 files changed

+226
-53
lines changed

codegen.c

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ char *gen_name_c(char *name) {
6969
if (sym->external_name) {
7070
gen_name = sym->external_name;
7171
} else if (sym->package->external_name) {
72-
gen_name = strf("%s_%s", sym->package->external_name, sym->name);
72+
gen_name = strf("%s%s", sym->package->external_name, sym->name);
7373
} else {
7474
gen_name = sym->name;
7575
}
@@ -106,7 +106,7 @@ char *gen_type_c(Type *type, char *inner) {
106106
case TYPE_STRUCT:
107107
case TYPE_UNION:
108108
case TYPE_ENUM: {
109-
return strf("%s%s%s", type->sym->name, sep, inner);
109+
return strf("%s%s%s", gen_name_c(type->sym->name), sep, inner);
110110
}
111111

112112
case TYPE_PTR: {
@@ -243,21 +243,22 @@ char *gen_expr_c(Expr *expr) {
243243
gen_expr_c(expr->ternary.then_expr),
244244
gen_expr_c(expr->ternary.else_expr));
245245
case EXPR_CALL: {
246-
char *name = gen_expr_c(expr->call.expr);
246+
Expr *call_expr = expr->call.expr;
247+
char *name = gen_expr_c(call_expr);
247248
Expr **args = expr->call.args;
248249
int num_args = expr->call.num_args;
249250
BUF(char *str) = NULL;
250251

251-
if (expr->type->sym->kind == SYM_TYPE) {
252-
// cast
253-
str = strf("(%s)(%s)", name, gen_expr_c(args[0]));
254-
} else {
252+
if (call_expr->type->kind == TYPE_FUNC) {
255253
// function call
256254
da_printf(str, "%s(", name);
257255
for (int i=0; i<num_args; ++i) {
258256
da_printf(str, "%s%s", gen_expr_c(args[i]), i == num_args - 1 ? "" : ", ");
259257
}
260258
da_printf(str, ")");
259+
} else {
260+
// cast
261+
str = strf("(%s)(%s)", name, gen_expr_c(args[0]));
261262
}
262263
return str;
263264
}
@@ -294,8 +295,7 @@ char *gen_typespec_c(Typespec *typespec, char *inner) {
294295

295296
switch (typespec->kind) {
296297
case TYPESPEC_NAME: {
297-
298-
return strf("%s%s%s", typespec->name, sep, inner);
298+
return strf("%s%s%s", gen_name_c(typespec->name), sep, inner);
299299
}
300300

301301
case TYPESPEC_ARRAY: {
@@ -338,7 +338,7 @@ char *gen_typespec_c(Typespec *typespec, char *inner) {
338338
char *gen_decl_func_c(Decl *decl) {
339339
BUF(char *str) = NULL; // @LEAK
340340

341-
da_printf(str, "%s(", decl->name);
341+
da_printf(str, "%s(", gen_name_c(decl->name));
342342

343343
int num_params = decl->func.num_params;
344344
if (num_params == 0) {
@@ -595,10 +595,12 @@ char *gen_sym_decl_c(Sym *sym) {
595595

596596
switch (decl->kind) {
597597
case DECL_CONST:
598-
return strf("#define %s (%s)", decl->name, gen_expr_c(decl->const_decl.expr));
598+
return strf("#define %s (%s)", gen_name_c(decl->name), gen_expr_c(decl->const_decl.expr));
599599
break;
600-
case DECL_TYPEDEF:
601-
return strf("typedef %s;", gen_typespec_c(decl->typedef_decl.typespec, decl->name));
600+
case DECL_TYPEDEF: {
601+
char *decl_name = gen_name_c(decl->name);
602+
return strf("typedef %s;", gen_typespec_c(decl->typedef_decl.typespec, decl_name));
603+
}
602604

603605
case DECL_UNION:
604606
case DECL_STRUCT: {
@@ -609,7 +611,7 @@ char *gen_sym_decl_c(Sym *sym) {
609611
}
610612

611613
BUF(char *str) = NULL; // @LEAK
612-
da_printf(str, "%s %s {", decl->kind == DECL_STRUCT ? "struct" : "union", decl->name);
614+
da_printf(str, "%s %s {", decl->kind == DECL_STRUCT ? "struct" : "union", gen_name_c(decl->name));
613615
++gen_indent;
614616
gen_newline(str);
615617

@@ -629,7 +631,7 @@ char *gen_sym_decl_c(Sym *sym) {
629631
BUF(char *str) = NULL; // @LEAK
630632
da_printf(str, "enum ");
631633
if (!decl->enum_decl.is_anonymous) {
632-
da_printf(str, "%s ", decl->name);
634+
da_printf(str, "%s ", gen_name_c(decl->name));
633635
}
634636
da_printf(str, "{");
635637
++gen_indent;
@@ -652,9 +654,10 @@ char *gen_sym_decl_c(Sym *sym) {
652654
}
653655

654656
case DECL_VAR: {
657+
char *decl_name = gen_name_c(decl->name);
655658
char *str = decl->var.typespec
656-
? gen_typespec_c(decl->var.typespec, decl->name)
657-
: gen_type_c(sym->type, decl->name);
659+
? gen_typespec_c(decl->var.typespec, decl_name)
660+
: gen_type_c(sym->type, decl_name);
658661
return strf("extern %s;", str);
659662
}
660663

@@ -693,9 +696,10 @@ char *gen_sym_def_c(Sym *sym) {
693696
break;
694697

695698
case DECL_VAR: {
699+
char *decl_name = gen_name_c(decl->name);
696700
char *type = decl->var.typespec
697-
? gen_typespec_c(decl->var.typespec, decl->name)
698-
: gen_type_c(sym->type, decl->name);
701+
? gen_typespec_c(decl->var.typespec, decl_name)
702+
: gen_type_c(sym->type, decl_name);
699703

700704
if (decl->var.expr) {
701705
char *init_expr = (decl->var.expr->kind == EXPR_COMPOUND)
@@ -783,15 +787,16 @@ char *gen_forward_decls_c(void) {
783787
if (!decl) continue;
784788
if (is_foreign_decl(decl)) continue;
785789
if (sym->kind == SYM_TYPE) {
790+
char *name = gen_name_c(sym->name);
786791
if (decl->kind == DECL_STRUCT) {
787-
da_printf(str, "typedef struct %s %s;", sym->name, sym->name);
792+
da_printf(str, "typedef struct %s %s;", name, name);
788793
gen_newline(str);
789794
} else if (decl->kind == DECL_UNION) {
790-
da_printf(str, "typedef union %s %s;", sym->name, sym->name);
795+
da_printf(str, "typedef union %s %s;", name, name);
791796
gen_newline(str);
792797
} else if (decl->kind == DECL_ENUM) {
793798
if (!decl->enum_decl.is_anonymous) {
794-
da_printf(str, "typedef enum %s %s;", sym->name, sym->name);
799+
da_printf(str, "typedef enum %s %s;", name, name);
795800
gen_newline(str);
796801
}
797802
}

common.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,13 @@ char *str_replace_char(char *str, char to_replace, char replacement) {
220220
return result;
221221
}
222222

223-
223+
void str_replace_char_in_place(char *str, char to_replace, char replacement) {
224+
for (char *it = str; *it; ++it) {
225+
if (*it == to_replace) {
226+
*it = replacement;
227+
}
228+
}
229+
}
224230

225231
void da_test(void) {
226232
int *buf = NULL;

ion.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,17 @@ Package *import_package(char *package_path) {
165165
free(package);
166166
return NULL;
167167
}
168-
char *external_name = str_replace_char(package_path, '/', '_');
168+
169+
// set external name
170+
char external_name[MAX_PATH];
171+
path_copy(external_name, package_path);
172+
str_replace_char_in_place(external_name, '/', '_');
173+
size_t len = strlen(external_name);
174+
assert(len + 1 < MAX_PATH);
175+
external_name[len] = '_';
176+
external_name[len+1] = 0;
169177
package->external_name = str_intern(external_name);
178+
170179
add_package(package);
171180
parse_package(package);
172181
}

notes.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
TODO:
2-
[ ] add a parameter to foreign directives to allow assigning an external name to
2+
[X] add a parameter to foreign directives to allow assigning an external name to
33
the declaration: @foreign("external_name") ...
4+
[X] codegen should generate the external name for all usages (for example if a
5+
typedef has a foreign external name, that is the name that should be used
6+
any time a variable of that type is declared
47

5-
[ ] move builtin package to an actual package in system_packages
8+
[X] symbol renaming on import
9+
[ ] c codegen should output the original symbol name (although with any
10+
package prefixes to avoid duplicate names)
611

712
[ ] static assert
813

@@ -17,10 +22,6 @@ TODO:
1722
[ ] support increment expression in array index
1823
e.g. deck[card_index++] = Card{num=1, symbol='A', face_down=true, prev=prev};
1924

20-
[ ] symbol renaming on import
21-
[ ] c codegen should output the original symbol name (although with any
22-
package prefixes to avoid duplicate names)
23-
2425
[ ] when importing all symbols from a package, ignore the main symbol. this
2526
should allow programmers to create packages that can be used as an
2627
executable and also as a library
@@ -100,6 +101,7 @@ TODO:
100101

101102

102103
DONE:
104+
[X] move builtin package to an actual package in system_packages
103105
[X] change cast syntax from cast(type, val) to type(val)
104106
[X] change codegen for call exprs that are casts
105107
[X] resolving constants

resolve.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,13 @@ bool is_foreign_decl(Decl *decl) {
286286
return false;
287287
}
288288

289-
289+
Note *get_note_foreign(Decl *decl) {
290+
for (int i=0; i<decl->notes.num_notes; ++i) {
291+
if (decl->notes.notes[i].name == name_foreign)
292+
return &decl->notes.notes[i];
293+
}
294+
return NULL;
295+
}
290296

291297
Sym *resolve_name(char *name);
292298
ResolvedExpr resolve_expr_expected(Expr *expr, Type *expected_type);
@@ -1228,6 +1234,7 @@ ResolvedExpr resolve_expr_call(Expr *expr) {
12281234
semantic_error(expr->pos, "expected one argument to cast, got %d", expr->call.num_args);
12291235
return resolved_null;
12301236
}
1237+
expr->call.expr->type = sym->type;
12311238
ResolvedExpr operand = resolve_expr(expr->call.args[0]);
12321239
if (!cast_operand(&operand, sym->type)) {
12331240
semantic_error(expr->pos, "Invalid type cast from %s to %s",
@@ -1865,14 +1872,26 @@ void complete_sym(Sym *sym) {
18651872
assert(sym->state == SYM_RESOLVED);
18661873
Package *old_package = enter_package(sym->package);
18671874

1868-
if (sym->decl && !is_foreign_decl(sym->decl)) {
1869-
if (sym->kind == SYM_TYPE) {
1870-
complete_type(sym->type);
1871-
} else if (sym->kind == SYM_FUNC) {
1872-
if (!sym->decl->func.is_incomplete) {
1873-
resolve_func_body(sym->decl, sym->type);
1875+
if (sym->decl) {
1876+
// set external name for foreign decls
1877+
Note *foreign_note = get_note_foreign(sym->decl);
1878+
if (foreign_note) {
1879+
if (foreign_note->num_args > 0) {
1880+
sym->external_name = foreign_note->args[0].name;
1881+
} else {
1882+
sym->external_name = sym->decl->name;
1883+
}
1884+
1885+
// complete normal syms
1886+
} else {
1887+
if (sym->kind == SYM_TYPE) {
1888+
complete_type(sym->type);
1889+
} else if (sym->kind == SYM_FUNC) {
1890+
if (!sym->decl->func.is_incomplete) {
1891+
resolve_func_body(sym->decl, sym->type);
1892+
}
1893+
da_push(ordered_syms, sym);
18741894
}
1875-
da_push(ordered_syms, sym);
18761895
}
18771896
}
18781897

0 commit comments

Comments
 (0)