# Compiler Week 3 :::danger [Course link](http://cc.ee.ntu.edu.tw/~farn/courses/Compiler/2021.spring/index.htm) ::: :::success Instead of the manual method described below, there is a productivity extension for controlling video playback rate with keyboard shortcuts: [Video Speed Controller](https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk) ::: :::info To set the YouTube video playback rate to some particular number, e.g., $\pi$, execute the following command in the browser's console; use `Command + Option + J` or `Control + Shift + J` to access Chrome's console. ```javascript document.querySelector('video').playbackRate = Math.PI ``` What this actually does is setting the playback rate of the first `<video>` tag on the page to $\pi$, which happens to be the main video on any YouTube page. ::: :::warning Many links in this page refer to [text fragments](https://web.dev/text-fragments/#text-fragments) which are known to work on Chrome 80 and above. **I** can't say about other browsers. ::: ## Q&A ### Classify the following as front-end or back-end components - **Target code optimizer**: back-end - **Parser**: front-end - **Scanner**: front-end - **IR code generator**: front/middle-end - **Type checker**: front-end ### Classify 1-3 as (a) or (b) (a) a common back-end compiling system (b) a retargetable compiler 1. **HP PA-RISC compiler/optimizer**: (a) 2. **Intel C++ Compiler Classic (ICC)**: (a) for C/C++ (b) for x86/x64 - According to the [developer's guide](https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top.html#top:~:text=Intel%C2%AE%20C%2B%2B%20Compiler%20Classic%20(icc)), ICC actually stands for Intel C++ Compiler Classic. - x86 refers to IA-32 whereas x64 refers to IA-64 3. **GNU Compiler Collection (GCC)**: (b) - Nowadays, [GCC stands for GNU Compiler Collection]((https://gcc.gnu.org/)); historically, at version 1.0, [GCC actually stood for GNU C Compiler](https://en.wikipedia.org/wiki/GNU_Compiler_Collection#cite_ref-loc_4-1:~:text=GCC%201.0%20was%20named%20the%20GNU%20C%20Compiler). - Even in the stricter sense, referring exclusively to the C compiler, GCC is still (b). ### How to create the first C compiler on the Itanium machine? - [ ] Write a C compiler in C, compile it on Itanium machines using GCC. - This line of reasoning is incoherent. If the first C compiler for Itanium is being developed, GCC wouldn't be able to target Itanium. - [x] Write a C compiler in Itanium machine code. - One doesn't attempt this feat unless one is [Jeff Dean](https://www.reddit.com/r/todayilearned/comments/11qqrz/til_that_googles_most_badass_engineer_jeff_dean/c6ow1ff?utm_source=share&utm_medium=web2x&context=3). - [x] Develop a cross-compiler on x86 and use it to compile itself into Itanium instructions. - A cross compiler is a compiler that can generate instructions for some CPU architecture different from the one it is running on. E.g., GCC running on an Intel machine can compile sources as ARM binaries. A cross compiler targeting Itanium can compile its source code on x86 to produce its Itanium counterpart which can then be executed on Itanium as a native compiler. - [This](https://hackmd.io/@mcnlab538/rk0rWidQP) illustrates the process. - [ ] Leave it to Intel/Microsoft, i.e., evil empire. - **Why not?** Why is the professor against this. ### How to create the first C compiler on the new Itanium if no cross-compiler is available? Incremental ==bootstrapping==. 1. Craft a simple assembler, C1, in Itanium machine code, i.e., directly editing a binary file from scratch. 2. Craft a more complex assembler, C2, in Itanium assembly with C1. 3. Craft a simple C compiler, C3, with C2. 4. Craft a more complex C compiler, C4, with C3. 5. Continue step 4 for several iterations until a good enough C compiler, C0, is finally produced. Then, C0 is what we seek for. ### Evaluate `1u > -1` in C/C++ Comparing `unsigned int` with `int` is defined behavior in C/C++: `int` is coerced to `unsigned int` for comparison. Since -1 has all bits being 1 in 2's complement, `1u > -1` evaluates to ==`false`== in most cases. In fact, C++20 mandates that [all values be represented in 2's complement](https://en.cppreference.com/w/cpp/language/types#Range_of_values:~:text=as%20of%20C%2B%2B20%2C%20it%20is%20the%20only%20representation%20allowed%20by%20the%20standard). Here are more C\++ specific details. - `1u` and `-1` are [integer literals](https://en.cppreference.com/w/cpp/language/integer_literal) that are of type `unsigned int` and `int`, respectively. - Coercion of mismatched operand types of an [arithmetic (comparison) operator](https://en.cppreference.com/w/cpp/language/operator_comparison#Arithmetic_comparison_operators:~:text=If%20the%20operands%20has%20arithmetic%20or,The%20values%20are%20compared%20after%20conversions%3A) is called [usual arithmetic conversion](https://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions:~:text=as-,usual%20arithmetic%20conversions). In this case, usual arithmetic conversion is due to [the unsigned operand's *conversion rank* being equal to the *conversion rank* of the signed operand, thus, requiring the signed operand to be converted to the unsigned operand's type](https://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions:~:text=Otherwise%2C%20if%20the%20unsigned%20operand's%20conversion,converted%20to%20the%20unsigned%20operand's%20type.) where [the *conversion rank* of any unsigned type is equal to the rank of the corresponding signed type](https://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions:~:text=The%20rank%20of%20any%20unsigned%20type%20is%20equal%20to%20the%20rank%20of%20the%20corresponding%20signed%20type.). - For best practices, consult the [*Arithmetic*](https://web.dev/text-fragments/#text-fragments) section (consists of only 8 points; **highly recommended**) of C++ Core Guidelines. Honorable mentions: - ES.100: Don’t mix signed and unsigned arithmetic. - ES.101: Use unsigned types for bit manipulation. - ES.102: Use signed types for arithmetic. - ES.106: Don’t try to avoid negative values by using `unsigned`. - In fact, the C++ standard library devoted a whole class -- [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset) -- to bit manipulation. - For safer integral comparisons, C++20 provides [`std::cmp_{equal,not_equal,less,greater,less_equal,greater_equal}`](https://en.cppreference.com/w/cpp/utility/intcmp). - C++20 also provides safer [math constants](https://en.cppreference.com/w/cpp/symbol_index/numbers) belonging to the namespace `std::numbers`. ### Which of the following are in the language defined by the AC syntax? - [x] `f b i a a = 0 b = a + 3.2 p b` ```graphviz digraph { nodesep=0 node [fontname=Arial,shape=none] 1 [label="Dcls"] 2 [label="Dcl"] 3 [label="floatdcl\nf"] 4 [label="id\nb"] 5 [label="Dcls"] 6 [label="Dcl"] 7 [label="intdcl\ni"] 8 [label="id\na"] 9 [label="Dcls"] 10 [label="λ",shape=circle] 11 [label="Stmts"] 12 [label="Stmt"] 13 [label="id\na"] 14 [label="assign\n="] 15 [label="Val"] 16 [label="inum\n0"] 17 [label="Expr"] 18 [label="λ",shape=circle] 19 [label="Stmts"] 20 [label="Stmt"] 21 [label="id\nb"] 22 [label="assign\n="] 23 [label="Val"] 24 [label="id\na"] 25 [label="Expr"] 26 [label="plus\n+"] 27 [label="Val"] 28 [label="fnum\n3.2"] 29 [label="Expr"] 30 [label="λ",shape=circle] 31 [label="Stmts"] 32 [label="Stmt"] 33 [label="print\np"] 34 [label="id\nb"] 35 [label="Stmts"] 36 [label="λ",shape=circle] Prog [shape=oval] "$" [shape=circle] Prog -> {1 11 "$"} 1 -> {2 5} 2 -> {3 4} 5 -> {6 9} 6 -> {7 8} 9 -> 10 11 -> {12 19} 12 -> {13 14 15 17} 15 -> 16 17 -> 18 19 -> {20 31} 20 -> {21 22 23 25} 23 -> 24 25 -> {26 27 29} 27 -> 28 29 -> 30 31 -> {32 35} 32 -> {33 34} 35 -> 36 {rank=same; 10 18 30 36 "$" 27} {rank=same; 3 4 7 8 13 14 16 21 22 24 26 28 33 34} } ``` - [ ] `p`++`15`++ An `id` must follow `print`. ```graphviz digraph { nodesep=0 node [fontname=Arial,shape=none] Prog [shape=oval] 1 [label="Dcls"] 2 [label="λ",shape=circle] 3 [label="Stmts"] 5 [label="Stmt"] 6 [label="Stmts"] 4 [label="λ",shape=circle] 7 [label="print\np"] 8 [label="inum\n15"] "$" [shape=circle] Prog -> {1 3 "$"} 1 -> 2 3 -> {5 6} 5 -> 7 5 -> 8 [label="expects id", style=dashed, color=red, fontcolor=red] 6 -> 4 {rank=same; 2 4 "$" 5} } ``` - [x] An empty file ```graphviz digraph { nodesep=0 node [fontname=Arial,shape=none] Prog [shape=oval] 1 [label="Dcls"] 2 [label="λ",shape=circle] 3 [label="Stmts"] 4 [label="λ",shape=circle] "$" [shape=circle] Prog -> {1 3 "$"} 1 -> 2 3 -> 4 {rank=same; 2 4 "$"} } ``` - [ ] `f b a = 1.0`++`i c`++`c = 0 p a` Note that `a = 1.0` is not a syntax error but a semantics error. ```graphviz digraph { nodesep=0 node [fontname=Arial,shape=none] 1 [label="Dcls"] 2 [label="Dcl"] 3 [label="floatdcl\nf"] 4 [label="id\nb"] 11 [label="Stmts"] 12 [label="Stmt"] 13 [label="id\na"] 14 [label="assign\n="] 15 [label="Val"] 16 [label="fnum\n1.0"] 17 [label="Expr"] 18 [label="λ",shape=circle] 19 [label="Dcls"] 20 [label="Dcl"] 21 [label="intdcl\ni"] 22 [label="id\nc"] 23 [label="id\nc"] 24 [label="assign\n="] 25 [label="inum\n0"] 26 [label="Val"] 27 [label="Stmt"] 28 [label="Expr"] 29 [label="λ",shape=circle] 30 [label="Stmts"] 30 -> {27 31} 27 -> {23 24 26 28} 26 -> 25 28 -> 29 31 [label="Stmts"] 32 [label="Stmt"] 33 [label="print\np"] 34 [label="id\na"] 35 [label="Stmts"] 36 [label="λ",shape=circle] Prog [shape=oval] "$" [shape=circle] Prog -> {1 11 "$"} 1 -> 2 2 -> {3 4} 11 -> 12 11 -> 19 [label="expects Stmts", style=dashed, color=red, fontcolor=red] 12 -> {13 14 15 17} 15 -> 16 17 -> 18 19 -> 20 19 -> 30 [label="expects Dcls", style=dashed, color=red, fontcolor=red] 20 -> {21 22} 31 -> {32 35} 32 -> {33 34} 35 -> 36 {rank=same; 17 20} {rank=same; 18 36 "$" 29 26} {rank=same; 3 4 13 14 16 21 22 33 34 23 24 25} } ``` - [ ] `f b i a a = 0 b =`++`-`++`a - 3.2 p b` ```graphviz digraph { nodesep=0 node [fontname=Arial,shape=none] 1 [label="Dcls"] 2 [label="Dcl"] 3 [label="floatdcl\nf"] 4 [label="id\nb"] 5 [label="Dcls"] 6 [label="Dcl"] 7 [label="intdcl\ni"] 8 [label="id\na"] 9 [label="Dcls"] 10 [label="λ",shape=circle] 11 [label="Stmts"] 12 [label="Stmt"] 13 [label="id\na"] 14 [label="assign\n="] 15 [label="Val"] 16 [label="inum\n0"] 17 [label="Expr"] 18 [label="λ",shape=circle] 19 [label="Stmts"] 20 [label="Stmt"] 21 [label="id\nb"] 22 [label="assign\n="] 23 [label="?"] 37 [label="minus\n-"] 24 [label="id\na"] 25 [label="Expr"] 26 [label="minus\n-"] 27 [label="Val"] 28 [label="fnum\n3.2"] 29 [label="Expr"] 30 [label="λ",shape=circle] 31 [label="Stmts"] 32 [label="Stmt"] 33 [label="print\np"] 34 [label="id\nb"] 35 [label="Stmts"] 36 [label="λ",shape=circle] Prog [shape=oval] "$" [shape=circle] Prog -> {1 11 "$"} 1 -> {2 5} 2 -> {3 4} 5 -> {6 9} 6 -> {7 8} 9 -> 10 11 -> {12 19} 12 -> {13 14 15 17} 15 -> 16 17 -> 18 19 -> {20 31} 20 -> {21 22} 20 -> 23 [label="expects Val", style=dashed, color=red, fontcolor=red] 20 -> 25 23 -> {37 24} 25 -> {26 27 29} 27 -> 28 29 -> 30 31 -> {32 35} 32 -> {33 34} 35 -> 36 {rank=same; 10 18 30 36 "$" 27} {rank=same; 3 4 7 8 13 14 16 21 22 37 24 26 28 33 34} } ``` ### What is the associativity of `op` given the grammar `expr -> expr op primary`? How can the grammar be re-defined so as to invert the associativity of `op`? - Left associative. - `expr -> primary op expr` ### Identify expressions with *constant folding* potential - [ ] `3 + 5 * b` - [ ] ++`a + 5`++`- 4` Left association doesn't make way for folding `5 - 4`. - [x] `a +`==`2 * 5`==`+ c` - [x] ==`2 + 5`==`+ c`