CcCompilers · Lesson 4 of 7

Names, Scopes & Type Checking

The parser accepts 'undefined_thing + 3' happily — it's grammatically fine. Semantic analysis is where the compiler asks: does this name exist? Do these types fit? It's the stage that catches your actual bugs.

Name resolution walks the tree carrying a symbol table — a stack of scopes mapping names to their declarations. Enter a function or block: push a scope. Leave: pop it. A name lookup searches innermost outward, which is exactly why an inner 'x' shadows an outer one, and why 'undefined variable' errors can name the function but not variables from elsewhere.

Text
let x = 10
fn f(y):           scope stack while checking f's body:
    let z = y + x     [ globals: x, f ]
    return z          [ f's params: y ]
                      [ f's body: z ]
z = 5              <- ERROR: 'z' not in any live scope —
                      f's scopes were popped at its end.

Type checking then asks, for every operation, whether the operand types allow it — using declared types (C, Rust) or inferred ones (compilers can deduce that x = 3 makes x an int, and flow that through everything x touches; that's how TypeScript knows so much with so few annotations). Static checking happens here, at compile time; dynamic languages defer the same checks to runtime, one operation at a time.

Text
"hello" + 3

C:           compile error — char* + int is pointer math
             you didn't mean
Rust:        compile error — no impl of Add<i32> for &str
TypeScript:  allowed -> "hello3" (+ is overloaded, checked)
Python:      RUNTIME TypeError — same check, later
JavaScript:  "hello3" — coerces silently, no check ever

Same question — 'do these types fit this operation?' —
five different policies on when/whether to ask it.
◆ Note
This stage powers your editor: 'go to definition' reads the symbol table, autocomplete lists what's in scope with fitting types, and red squiggles are the semantic checker running continuously. A language server (LSP) is a compiler front end kept alive, re-checking as you type.