Files
doslang-mirror/fec/src/resolve.h
T
coolguy 4624c6d0ec std: 표준 라이브러리가 컴파일러 옆에서 해석되고 호출된다
std 는 예약된 이름이고 프로그램이 아니라 컴파일러와 함께 있으므로 자기 루트를
갖는다 (--std=). 본문 없는 선언은 링커가 찾을 것 -- 런타임이나 C 라이브러리 --
이므로 IR 에 extern 으로 나간다.

런타임에 write/alloc/free/exit 를 넣었다. 이것이 표준 라이브러리가 스스로
말할 수 없는 전부이고 나머지는 Ferro 로 쓴다.

@trap @unreachable @size_of @align_of @line 을 내린다.

링크 이름에서 점과 괄호를 걸렀다. 유닛 경로에는 점이 있고 제네릭 인스턴스에는
괄호가 있는데 어셈블러가 받지 않는다.
2026-08-17 06:12:44 +09:00

64 lines
2.6 KiB
C

#ifndef FE_RESOLVE_H
#define FE_RESOLVE_H
#include "ast.h"
#include "diag.h"
/* Unit-level resolution: identity, import bindings, and the unit graph.
This runs between parsing and semantic checking. It answers questions that
need more than one file -- what a unit is called, what it imports, and
whether those imports exist and terminate -- so that check.c can keep
looking at one function at a time. */
/* SPEC 8.1: each segment is ASCII lowercase, starts with a letter, continues
with letters, digits or '_', and is at most eight characters. The limit is
what makes a unit path map to a FAT/DOS 8.3 source path unambiguously. */
#define FE_UNIT_SEGMENT_MAX 8
#define FE_UNIT_PATH_MAX 128
#define FE_BUILD_UNIT_MAX 64
typedef struct FeUnit {
char name[FE_UNIT_PATH_MAX]; /* canonical dotted path */
char path[260]; /* source file it was read from */
FeAst ast;
char *source; /* owned; freed with the build */
unsigned long size;
int loaded;
int checked;
} FeUnit;
typedef struct FeBuild {
FeUnit units[FE_BUILD_UNIT_MAX];
unsigned count;
char root[260]; /* import root: where unit paths start */
/* Where `std.*` is looked for. The standard library is not under the
program's root -- it ships with the compiler. */
char std_root[260];
FeDiags *diags;
} FeBuild;
/* Validate the `unit` declaration against SPEC 8.1, and against the file it was
read from: the path must match the dotted name, so `game.world.map` has to
come from `game/world/map.fe`. `source_path` may be null to skip that half.
Returns non-zero when the unit is well formed. */
int fe_resolve_unit_identity(FeAst *ast, FeDiags *diags, const char *source_path);
/* Load `entry` and everything it imports, transitively.
The import root is derived from the entry file: a unit named `a.b` read from
`<root>/a/b.fe` fixes `<root>`, so a sibling `import c.d;` is looked for at
`<root>/c/d.fe`. Reports missing imports, import cycles, and binding
conflicts. Returns non-zero when the whole graph loaded cleanly. */
int fe_build_load(FeBuild *build, const char *entry, FeDiags *diags,
const char *std_root);
void fe_build_destroy(FeBuild *build);
/* The unit a binding refers to inside `unit`, or null.
The binding is the last segment of the import path unless `as` renamed it. */
FeUnit *fe_build_binding(FeBuild *build, FeUnit *unit, const char *binding);
/* The local name an import introduces: its alias, or the last path segment. */
const char *fe_import_binding(const FeNode *import);
#endif