diff --git a/docs/lectures/03-adder.html b/docs/lectures/03-adder.html index fa7061e..ef7e1c2 100644 --- a/docs/lectures/03-adder.html +++ b/docs/lectures/03-adder.html @@ -676,7 +676,7 @@
At what position on the stack do we store variable c
?
-- []
diff --git a/docs/lectures/04-boa.html b/docs/lectures/04-boa.html
index f0e767e..4d2c162 100644
--- a/docs/lectures/04-boa.html
+++ b/docs/lectures/04-boa.html
@@ -267,17 +267,17 @@ Example: If1
Since 10
is not 0
we evaluate the “then” case to get 22
Example: If2
-if sub(1):
+
-- Since
sub(1)
is 0
we evaluate the “else” case to get -1
+- Since
sub1(1)
is 0
we evaluate the “else” case to get -1
QUIZ: If3
if-else
is also an expression so we can nest them:
What should the following evaluate to?
-let x = if sub(1):
+let x = if sub1(1):
22
else:
sub1(0)
@@ -325,7 +325,7 @@ QUIZ
Which of the following is a valid x86 encoding of
Types & Strategy
Writing the type aliases:
type BareE = Expr ()
@@ -993,8 +996,8 @@ ANF: Making Arguments Immediate
anf
the relevant expressions,
bind them to a fresh variable.
-imm e@(If _ _ _) = immExp e
-imm e@(If _ _ _) = immExp e
+imm e@(If _ _ _) = immExp e
+imm e@(Let _ _ _) = immExp e
immExp :: AnfE -> ([(Id, AnfE)], ImmE)
immExp e = ([(t, e')], t)
diff --git a/docs/lectures/05-cobra.html b/docs/lectures/05-cobra.html
index 537a9ce..962292f 100644
--- a/docs/lectures/05-cobra.html
+++ b/docs/lectures/05-cobra.html
@@ -285,11 +285,11 @@ Option 1: Use Two Words
12
-[0x000000000][0x0000000c]
+[0x000000000][0x00000018]
42
-[0x000000000][0x0000002a]
+[0x000000000][0x00000054]
false
@@ -459,11 +459,11 @@ Types
Number 12
-HexConst 0x0000000c
+HexConst 0x00000018
Number 42
-HexConst 0x0000002a
+HexConst 0x00000054
@@ -625,7 +625,7 @@ Shifted Representation and Mu
n1 * n2
-2*n1 * 2*n2 = 4*(n1 + n2)
+2*n1 * 2*n2 = 4*(n1 * n2)
@@ -777,7 +777,8 @@ 4. Dynamic Checking
or
In fact, lets try to see what happens with our code on the above:
-
+
Oops.
Checking Tags at Run-Time
Later, we will look into adding a static type system that will reject such meaningless programs at compile time. For now, lets see how to extend the compilation to abort execution when the wrong types of operands are found when the code is executing.
diff --git a/lectures/03-adder.md b/lectures/03-adder.md
index adb3ad1..ab88104 100644
--- a/lectures/03-adder.md
+++ b/lectures/03-adder.md
@@ -629,7 +629,7 @@ let x = 1 -- []
, y = add1(x) -- [x |-> 1]
, z = add1(y) -- [y |-> 2, x |-> 1]
in
- add1(z) -- [z |- 3, y |-> 2, x |-> 1]
+ add1(z) -- [z |-> 3, y |-> 2, x |-> 1]
```
### QUIZ
diff --git a/lectures/04-boa.md b/lectures/04-boa.md
index b858674..386389b 100644
--- a/lectures/04-boa.md
+++ b/lectures/04-boa.md
@@ -55,7 +55,7 @@ else:
### Example: `If2`
```haskell
-if sub(1):
+if sub1(1):
22
else:
sub1(0)
@@ -64,7 +64,7 @@ else:
-* Since `sub(1)` _is_ `0` we evaluate the "else" case to get `-1`
+* Since `sub1(1)` _is_ `0` we evaluate the "else" case to get `-1`
### QUIZ: `If3`
@@ -73,7 +73,7 @@ else:
What should the following evaluate to?
```haskell
-let x = if sub(1):
+let x = if sub1(1):
22
else:
sub1(0)
@@ -136,7 +136,7 @@ Which of the following is a valid x86 encoding of
```python
if 10:
22
-else
+else:
33
```
@@ -354,7 +354,7 @@ compile env (If eCond eTrue eFalse i)
, IJe (BranchFalse i) -- if-zero then jump to 'False'-block
]
++ compile env eTrue ++ -- code for `True`-block
- [ IJmp lExit ] -- jump to exit (don't execute `False`-block!)
+ [ IJmp (BranchExit i) ] -- jump to exit (don't execute `False`-block!)
++
ILabel (BranchFalse i) -- start of `False`-block
: compile env eFalse ++ -- code for `False`-block
@@ -773,7 +773,10 @@ Use the above function to **test** our ANF conversion.
```haskell
immArg :: Env -> ImmExpr -> Arg
immArg env (Number n _) = Const n
-immArg env (Id x _) = RegOffset EBP (lookupEnv env x)
+immArg env (Id x _) = RegOffset EBP i
+ where
+ i = fromMaybe err (lookupEnv env x)
+ err = error (printf "Error: Variable '%s' is unbound" x)
compileImm :: Env -> ImmExpr Tag -> [Instruction]
compileImm env v = [IMov (Reg EAX) (immArg env v) ]
@@ -784,7 +787,7 @@ compile env v@(Id _ _) = compileImm env v
compile env (Prim1 op e) = compile env e
++ [ (prim1Asm op (Reg EAX) (Const 1)]
compile env (Prim2 op v1 v2) = [ compileImm env v1
- , prim2asm o (Reg EAX) (immArg env v2)
+ , prim2Asm o (Reg EAX) (immArg env v2)
]
prim2Asm Add2 = IAdd
@@ -1091,8 +1094,8 @@ That is, simply
* bind them to a fresh variable.
```haskell
-imm e@(If _ _ _) = immExp e
-imm e@(If _ _ _) = immExp e
+imm e@(If _ _ _) = immExp e
+imm e@(Let _ _ _) = immExp e
immExp :: AnfE -> ([(Id, AnfE)], ImmE)
immExp e = ([(t, e')], t)
diff --git a/lectures/05-cobra.md b/lectures/05-cobra.md
index 44582b0..8090c95 100644
--- a/lectures/05-cobra.md
+++ b/lectures/05-cobra.md
@@ -57,8 +57,8 @@ First word is `0` means `bool`, is `1` means `number`, `2` means pointer etc.
|---------:|------------------------------:|
| `3`| `[0x000000000][0x00000003]`|
| `5`| `[0x000000000][0x00000005]`|
-| `12`| `[0x000000000][0x0000000c]`|
-| `42`| `[0x000000000][0x0000002a]`|
+| `12`| `[0x000000000][0x00000018]`|
+| `42`| `[0x000000000][0x00000054]`|
| `false`| `[0x000000001][0x00000000]`|
| `true`| `[0x000000001][0x00000001]`|
@@ -157,8 +157,8 @@ So, our examples become:
| `Boolean True`| `HexConst 0x80000001`|
| `Number 3`| `HexConst 0x00000006`|
| `Number 5`| `HexConst 0x0000000a`|
-| `Number 12`| `HexConst 0x0000000c`|
-| `Number 42`| `HexConst 0x0000002a`|
+| `Number 12`| `HexConst 0x00000018`|
+| `Number 42`| `HexConst 0x00000054`|
### Transforms
@@ -353,7 +353,7 @@ Thus, our _source values_ have the following _representations:
| `3`| `6` |
| `5`| `10` |
| `3 * 5 = 15`| `6 * 10 = 60` |
-| `n1 * n2`| `2*n1 * 2*n2 = 4*(n1 + n2)` |
+| `n1 * n2`| `2*n1 * 2*n2 = 4*(n1 * n2)` |
Thus, multiplication ends up accumulating the factor of 2.
* Result is _two times_ the desired one.
@@ -567,6 +567,7 @@ In fact, lets try to see what happens with our code on the above:
```haskell
ghci> exec "2 + true"
+Unknown value: 0x80000005
```
Oops.