Projects, Revision and Certification Assessment

This module turns the course into practice: projects to build at each level, a revision map, an exam with explained answers and the rubric used to judge a capstone.

Learning Objectives

Choose and complete projects at four levels; revise the course; pass the final assessment; evaluate a capstone with the rubric.

Plain-Language Explanation

This module turns the course into practice: projects to build at each level, a revision map, an exam with explained answers and the rubric used to judge a capstone.

Precise Technical Explanation

Tokenizer for arithmetic expressions AST explorer for arithmetic expressions

Interactive REPL for a calculator language Runtime vocabulary flashcards

Tree-walk interpreter for variables, arithmetic, conditionals, loops and functions Stack-based bytecode VM Runtime environment visualizer Scope and closure explorer Bytecode compiler for a small language

Bytecode verifier with stack-depth analysis VM debugger with breakpoints and instruction stepping

Runtime heap visualizer using synthetic data Differential test harness comparing interpreter and VM results

JIT optimization simulation using synthetic type feedback WASM module inspector Add closures and upvalues to the VM

Implement a register-based VM and compare it with a stack VM

Implement a simple mark-sweep collector in a sandboxed teaching runtime

Add profiling-guided bytecode specialization Design a safe plugin execution environment

Analyze cold-start versus warmed-up execution using reproducible benchmarks

Short checks after each lesson (every module's quiz) Code reading and predict-the-output questions (below)

Token/AST interpretation exercises (Modules 3–5) Bytecode tracing tasks (Modules 8–11)

Runtime design decisions (Modules 2, 15, 22, 24) Debugging challenges (Modules 13, 23)

Module-level tests (each module's exercises) Final exam with a balanced difficulty distribution (the quiz below: beginner, intermediate, advanced and expert questions)

Capstone rubric: correctness, semantic clarity, tests, diagnostics, safety, performance methodology, documentation and portability awareness Capstone rubric Insufficient (0) both back ends pass all golden and differential tests most tests pass frequent wrong results semantics documented; errors defined implicit host semantics lexer, parser, scope, closure, recursion, error and verifier tests; fuzzing some unit tests positioned lexical, syntax, compile, verification and runtime errors with traces messages without positions crashes or raw host errors verification, budgets, depth and size limits, minimal host API warm-up, repeats, medians, versions stated none or invented numbers grammar, instruction set, limitations, build/run steps versioned bytecode; implementation specifics labelled assumes one platform

Why It Matters in Real Systems

Projects and assessment consolidate the mental model you will use whenever a runtime surprises you.

Key Terms

See the Glossary at the end of the course.

Syntax or Instruction Format

No dedicated source syntax; this is a review module.

Complete Example

Predict the output before reading it (MiniLang, both back ends):

let x = "global";
fun show() { print(x); }
fun run() { let x = "local"; show(); }
run();
fun counter() { let n = 0; fun inc() { n = n + 1; return n; } return inc; }
let c1 = counter(); let c2 = counter();
c1(); c1();
print(c1() + c2());
print(1 + 2 * 3 - 4 / 2);
print(!nil == !false);
global
4
5
true

Line-by-Line Explanation

show prints global: lexical scope — show sees the environment where it was defined, not run's local x.

c1 has been called three times (3) and c2 once (1): 4.

!nil is true, !false is true, so == gives true.

Common Misconceptions

Revisit each module's list; the most common: "interpreted means not compiled", "bytecode is portable across versions", "GC closes files", "verification proves termination".

Performance Considerations

Module 2's fair-comparison rules and Module 25's profile-first method.

Portability and Version Caveats

Every production listing in the course is labelled with its runtime and version.

Real-World Use Cases

Language and runtime engineering, performance engineering, security review of plugin systems, tooling (linters, debuggers, profilers).

Best Practices

Build, measure, test differentially, document — and keep specifications and implementations apart in your head.

Exercises

E1 · Beginner. Write the tokens for print(-x);.

Answer: PRINT LEFT_PAREN MINUS IDENTIFIER(x) RIGHT_PAREN SEMICOLON EOF.

E2 · Intermediate. Trace the stack for CONSTANT 0; CONSTANT 1; LESS; NOT; PRINT with constants 3 and 2.

Answer: [3] → [3, 2] → [false] (3 < 2) → [true] → [] (prints true) — this is how >= compiles.

E3 · Advanced challenge. A Node.js service is fast in benchmarks but slow for the first requests after each deploy. Explain and propose fixes.

Answer: Cold start: modules load, code runs in Ignition, then baseline/optimising JITs compile hot paths (warm-up). Fixes: warm up before taking traffic (synthetic requests), reduce start-up work (lazy imports), use V8 code caches/snapshots, keep instances alive longer, or move critical paths to precompiled Wasm.

Quiz

? Beginner: what does a lexer produce?
+ Tokens with kinds and positions :: Module 3.
- An AST :: That is the parser.
- Bytecode :: That is the compiler.
- Machine code :: Much later, if at all.

? Beginner: which MiniLang values are falsy?
+ nil and false :: 0 and "" are truthy.
- 0 and "" :: Truthy in MiniLang.
- Every number :: Numbers are truthy.
- Only nil :: false is also falsy.

? Intermediate: what does DEFINE_GLOBAL 0 do in MiniLang?
+ Pops the top value and binds it to names[0]. :: The documented convention.
- Pushes names[0]. :: That is GET_GLOBAL.
- Defines a constant. :: Constants are in the pool.
- Jumps to offset 0. :: No.

? Intermediate: why does the bytecode verifier reject a jump into the middle of an instruction?
+ The VM would decode operand bytes as opcodes. :: Jump targets must be instruction boundaries.
- Jumps are not allowed. :: They are.
- It slows the VM down. :: Correctness, not speed.
- The constant pool would overflow. :: Unrelated.

? Advanced: what happened when V8's optimised `add` received strings?
+ A guard failed and V8 deoptimised it back to the interpreter ("not a Smi"). :: Real run in Module 16.
- The program crashed. :: Deoptimisation preser
…

Summary and Key Takeaways

Projects at four levels, a predict-the-output review, a balanced final quiz and a rubric close the course. Review any module whose quiz questions you missed, then build a capstone that meets every requirement.

Further Reading

Revisit each module's Further Reading; *Crafting Interpreters* and the *Garbage Collection Handbook* are the best next books.