본문으로 건너뛰기
cccskills
무료GitHub에 공개

Interpreter Internals

Comprehensive guide to Chemical interpretation and comptime evaluation after the MIR migration — the MIR interpreter engine, the comptime driver, the residual AST expression folder, and how to debug `--interpret` and comptime failures.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical스타 31(GitHub 31 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Interpreter Internals

There is no AST statement interpreter any more. compiler/Interpreter/ is gone. Interpretation runs the same MIR the code generators consume, and lowering-time comptime calls run on the same engine. Read lang/docs/mir-interpretation-plan.md first — it records the design, the phases, and the measured state.

What runs where

PathEngineEntry point
--arg-interpret (interpretation job)mir::MIRInterpreterdo_interpretation_job() in compiler/lab/LabBuildCompiler.cpp
comptime func call during loweringmir::MIRInterpreter via mir::MIRComptimeMIRComptime::evaluate / evaluate_block / evaluate_value
symres-time comptime if condition, array length, const initializerAST expression folderValue::evaluated_value + compiler-intrinsic FunctionDeclaration::call overrides

The first two are the real interpreters. The third is a residual, deliberately kept: symres decides which branch/texture even exists before MIR is built, so it must fold an expression — typically a call to a compiler intrinsic, whose body is a C++ call override. See §5.4 of the plan for why this floor exists.

Interpretation job (--arg-interpret)

do_interpretation_job():

  1. Parses, symres's and typechecks every module of the job.
  2. Lowers each module's function bodies and globals into one shared MIR program (ASTProcessor::interpret_module, collect mode).
  3. Finds main(), resolves its mangled name with the same Mangler the lowerer used, and runs it with mir::MIRInterpreter::run.
  4. Emits no object code and links no executable.

interpretation_mode is false during the job on purpose, so comptime if(intrinsics::is_interpretation()) takes the compiled branch and the test suite prints through printf. Interpretation is defined to have the same semantics as the compiled binary — the engine differs, the language does not.

The MIR interpreter (compiler/mir/MIRInterpreter.{h,cpp})

  • AST-free and single-threaded: it reads only MIR tables.
  • prepare() resolves everything the hot loop needs (type facts, field offsets, symbol targets, constant bits, global storage) once, into flat dense side tables indexed by MIR ids.
  • Public API: run(entry, argc, argv, out_result, error), call(name, args, nargs, out_result, error) (scalar result), call_sret(name, args, nargs, out_buf, error) (aggregate result), has_function(name).
  • Unsupported MIR (e.g. coroutine/Async* opcodes, DynamicCall vtables) reports through error rather than executing; see §10 of the plan.

The comptime driver (compiler/mir/MIRComptime.{h,cpp})

Lowering-time comptime func calls are lowered into their own MIR module (with every function they reach, transitively) and executed; the raw result is bridged back to an AST Value* that the lowering keeps folding. It declines anything the engine does not reproduce identically and the caller then falls back to the AST expression folder, so every suite stays green. Covered today: generics, flat-struct (sret) results, no-body intrinsics the lowerer folds, pointer arithmetic/comparison, and comptime-mode intrinsics (is_comptime/is_runtime/is_interpretation).

The residual AST expression folder

Only expressions are folded, never statements:

  • Value::evaluated_value implementations (IntNumValue, BoolValue, StringValue, CastedValue, SizeOfValue, IsValue, AccessChain, VariableIdentifier, StructValue, ArrayValue, …).
  • InterpretScope (ast/base/InterpretScope.h) is just a small value map for parameter binding (FunctionDeclaration::call binds params and folds a body that is a single return <expr>), plus arithmetic folding in InterpretScope::evaluate.
  • PointerValue simulates pointers with behind/ahead bounds for comptime pointer arithmetic.
  • Compiler intrinsics in ast/utils/GlobalFunctions.cpp override FunctionDeclaration::call; this is where intrinsics::* values come from.

Do not add statement execution back here, and do not add a new AST interpreter: a capability belongs in MIR (opcode + engine support), so every backend and the engine keep agreeing.

Test suite entry points

ModeEntry FunctionModuleFile
Interpretmain()interpret_testslang/tests/interpret/src/main.ch
Native compiledmain()mainlang/tests/src/tests.ch
Common (shared)run_common_tests()common_testslang/tests/common/src/main.ch
Native-commonrun_native_common_tests()native_common_testslang/tests/native_common/src/main.ch

Because the interpret suite runs the same MIR, a test that passes compiled and fails interpreted is an engine bug (MIRInterpreter diverging from the emitter), not a language limitation. Write the failure down as such.

Debugging

  1. ./scripts/test.sh --tcc --interpret — the interpretation suite.
  2. ./scripts/test.sh --tcc --interpret -bt — run under GDB with a backtrace.
  3. ./cmake-build-debug/MIRTests — engine smoke tests; extend these when you add an opcode.
  4. [lab] error: MIR interpreter: <message> is the engine declining or trapping; the message names the function and opcode.
  5. Lowering-time comptime failures surface as ordinary diagnostics at the call site (the driver reports why it declined, the AST path reports why it could not fold).
  6. MIRDump (MIRDump.{h,cpp}) prints the MIR a module lowered to — the fastest way to see what the engine will actually execute.

Adding coverage

  1. Pick the right location: lang/tests/src/comptime/ for comptime features, lang/tests/common/src/ for tests shared by both modes, lang/tests/native_common/src/ for pointer arithmetic.
  2. Write the function and test("name", () => { ... }) the assertion.
  3. Register it (run_common_tests() / run_native_common_tests() / main()), or annotate it @test for the compiled runner.
  4. Run both --tcc and --tcc --interpret; they must agree.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Comprehensive guide to the Chemical compiler's annotation system (`@name`, `@name(args)`) — how annotations are lexed, parsed, registered in the `AnnotationController`, stored and queried centrally, consumed by the compiler and CBI plugins, and how to add a new one. Load when working on annotations, `AnnotationController`, compiler plugins that define/read annotations, or node attribute flags such as `@extern`, `@test`, `@make`, `@deprecated`, `@no_mangle`, `@inline`, and `@volatile`.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

The C++ AST node framework of the Chemical compiler — the ASTAny/ASTNode/Value/BaseType hierarchy, node/value/type kind enums and range predicates, the visitor dispatch framework, the arena allocator, TypeBuilder canonicalization, member containers, and cross-reference resolution. Load when adding or modifying AST nodes, writing compiler passes/codegen visitors, debugging kind mismatches or arena/lifetime issues, or extending the compiler API bindings.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

The Chemical compiler benchmark & release analytics system — how the static GitHub Pages dashboard works, the JSON data model (manifest/daily/release records), the bash collection scripts (bench-*.sh), the GitHub Actions workflows (benchmark-daily/release), and the critical pitfalls (hidden upload dirs, worktree submodules, gh-pages-only data). Load when working on the dashboard, benchmark collection, or analytics workflows.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

Comprehensive deep-dive into the Chemical build pipeline — how chemical.mod is converted to build.lab, how build scripts are JIT-compiled via TinyCC, how jobs are created and executed, and how ASTProcessor orchestrates the parallel compilation passes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

Building

무료

All documentation related to building and running Project or Tests

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

Comprehensive guide to the C translation backend (2c) — how Chemical AST is translated to C code, key patterns, gotchas, and optimization strategies.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

chemicallang/chemical312026년 10월 26일 업데이트

chemicallang의 스킬 모두 보기

이 스킬의 문제 신고