schema: ludicc --emit-schema / ludic schema, --check --diagnostics=json, and editor attributes
--emit-schema FILE writes the compiler's resolved view once the program type-checks: every
record (fields, types, defaults as written, docs, places, attributes), every registry with its
entries in their final order after the open-registry merge (key, constant, index, file:line:col
of the entry and of each field value, and which file contributed which keys), every const, and
the zero-argument functions a fn value can name. Deterministic, schema_version 1; the runtime is
left out. `ludic schema [file] [-o FILE]` wraps it.
--check --diagnostics=json prints every error as one JSON array on stdout: the checker's and the
module rules' all, a parse or lowering error as the last. Tokens and nodes now carry a column.
Fields take several @attributes; @Ref(Registry), @OneOf(PREFIX_), @Range(lo, hi), @Unit("..."),
@Asset("..."), @Color on a field and @AppendOnly / @ByKey on a registry change nothing but go into
the schema, and @Ref naming no registry is an error (every one reported). Fixtures:
examples/lang/attributes.ludic, examples/rejected/ref_unknown.ludic, cases in ludic-dev test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f8d811aa97
commit
42deb76c28
27 changed files with 1220 additions and 23 deletions
|
|
@ -55,6 +55,10 @@ function ensure_slash(d: pointer) -> pointer {
|
|||
}
|
||||
|
||||
function die(msg: pointer) -> void {
|
||||
if g_diag_json {
|
||||
diag_add("", 0, 0, "error", msg)
|
||||
diag_exit(1)
|
||||
}
|
||||
file_write(file_stderr(), msg, len(msg))
|
||||
exit(1)
|
||||
}
|
||||
|
|
@ -154,6 +158,9 @@ entry {
|
|||
else if a == "--save-temps" { save = true }
|
||||
else if a == "--run" { run = true }
|
||||
else if a == "--check" { g_check_only = true }
|
||||
else if a == "--diagnostics=json" { g_diag_json = true } # every error, as JSON on stdout (diag.ludic)
|
||||
else if a == "--diagnostics=text" { g_diag_json = false }
|
||||
else if a == "--emit-schema" { ai += 1; if ai < arg_count() { g_schema_out = arg(ai) } } # emit_schema.ludic
|
||||
else if a == "--globals" { g_allow_globals = true }
|
||||
else if a == "--migrate-state" { # 0.S2: write the plan ludic migrate state applies
|
||||
ai += 1
|
||||
|
|
@ -194,6 +201,7 @@ entry {
|
|||
let src = read_file(path)
|
||||
if (src == null) { die("ludicc: cannot open input\n") }
|
||||
|
||||
fm_put(g_fm_src, path, src) # the schema reads docs and spans from it
|
||||
cur_dir = dir_of(path)
|
||||
g_src_name = base_name(path) # for panic/expect file:line messages
|
||||
g_parse_file = path # for the compiler's own file:line diagnostics
|
||||
|
|
@ -238,13 +246,21 @@ entry {
|
|||
file_close(sink)
|
||||
}
|
||||
if g_migrate { mg_finish() }
|
||||
# --emit-schema FILE: the declarations, the registries and their entries as the checker resolved
|
||||
# them (emit_schema.ludic); on its own it stops there, with -o or --check the build goes on
|
||||
if g_schema_out != null {
|
||||
if not schema_write(g_schema_out) { die(`ludicc: cannot write {g_schema_out}\n`) }
|
||||
if not g_check_only and not has_target and not emit_ir { diag_exit(0) }
|
||||
}
|
||||
# --check: every check a build makes - the emitter refuses things too (a bind to a function that is
|
||||
# gone, an unknown name) - and nothing written
|
||||
if g_check_only {
|
||||
emit_program()
|
||||
exit(0)
|
||||
if g_dg_errors > 0 { diag_exit(1) }
|
||||
diag_exit(0)
|
||||
}
|
||||
emit_program()
|
||||
if g_dg_errors > 0 { diag_exit(1) } # errors a pass went on from (diag.ludic)
|
||||
deps_flush() # LUDIC_DEPS=<file>: the module graph (ludic deps)
|
||||
|
||||
# --emit-llvm, or no binary target: emit IR and stop (stdout when out is null).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue