Master the fundamental concepts of semantic analysis through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksC promotes int to float in mixed arithmetic; Java widens primitives automatically. Clang applies standard conversion rules before checking assignment compatibility. Coercion rules are where subtle bugs hide: silent truncation, sign extension, and unexpected overflow.
Integer promotion: char and short widen to int. Usual arithmetic conversions: if one operand is float, the other promotes. Assignment may narrow with a warning or error depending on the language.
cLoading…
Production compilers embed this step inside a longer pipeline. GCC flows through cpp, cc1, assembly, and ld; Clang uses the driver, Sema, LLVM IR passes, and a target backend. LLVM bitcode, JVM bytecode, and WASM are other familiar IRs at the same layer. The exercise isolates one pass so you can test it alone before chaining it to the next stage.
You will implement type coercion rules for mixed-type arithmetic and assignments. This exercise asks you to promote operand types per language rules and report errors when implicit conversion is not permitted.
C silently converts operands before arithmetic. Make those conversions visible: type-check each expression with C's usual arithmetic conversions and print it back with every implicit conversion written out as an explicit cast.
One statement per line (blank lines ignored). Every variable is declared before use.
| Line | Meaning |
|---|---|
TYPE NAME; | declaration, prints nothing |
TYPE NAME = EXPR; | declaration with initializer |
NAME = EXPR; | assignment |
EXPR | a bare expression (no ;) |
TYPE is one of char int long float double. Expressions use variables, literals, + - * /, < and parentheses, with the usual precedence (* / over + - over <, all left-associative).
Literals follow C: 42 is int, 2.5 is double, 2.5f is float, and a character literal like 'a' is int.
Rank: char < int < long < float < double.
char operand of any operator is first converted to int.< compares in the common type but its result is int.warning: narrowing TYPE to TYPE.A conversion is written as (TYPE)operand. Binary operations print fully parenthesized, so a converted operation looks like (double)(i + j).
| Line | Printed as |
|---|---|
| expression | CONVERTED : TYPE |
| assignment | NAME = CONVERTED; |
| declaration with initializer | TYPE NAME = CONVERTED; |
A narrowing warning goes on its own line right after, indented two spaces. Finish with warnings=N.
Input:
cLoading…
Output:
cLoading…
common_type() function implementing the rank rule, and a coerce(node, type) that wraps a node in a cast only when its type differs.Hidden tests cover long vs float, float literals, character literals, comparisons, and narrowing to char in declarations.