# Assignment 3 solution

1. Write an EAL program that demonstrates the different forms of expressions supported by the EAL assembler distributed as MP0. To do this, you'll need to read the expression parser in parser.c.
```     1             |; demo of types of expressions (<operand>)
2             |
3             |IDENT = 1     ; an identifier for demo purposes
4             |
5             |; forms of terms, note that <operand> ::= <term>
6 0000: 0001  |      W IDENT            ; <term> ::= <identifier>
7 0002: 0063  |      W 99               ; <term> ::= <number>
8 0004: 0004  |      W .                ; <term> ::= .
9             |
10             |; forms of expressions, note that <term> ::= IDENT
11 0006: 0001  |      W IDENT            ; <operand> ::= <term>
12 0008: 0002  |      W IDENT + IDENT    ; <operand> ::= <term> { + <term> }
13 000A: 0003  |      W IDENT + IDENT + IDENT
14 000C: 0004  |      W IDENT + IDENT + IDENT + IDENT
15             |
16             |; permissible operators
17 000E: 0002  |      W IDENT + IDENT   ; ::= <term> { (+|-|&||) <term> }
18 0010: 0000  |      W IDENT - IDENT
19 0012: 0001  |      W 99 & IDENT      ; note, 99 and 1 is 1
20 0014: 0063  |      W 99 | IDENT      ; note, 99 or 1 is 99
21             |
22             |; parentheses (not in the BNF, but in parse_operand)!
23 0016: 0001  |      W (IDENT)
24 0018: 0002  |      W IDENT + (IDENT)
25 001A: 0002  |      W (IDENT) + IDENT
26 001C: 0002  |      W (IDENT + IDENT)
27             |
28             |; some illustrations of operator precidence and parens
29 001E: 0005  |      W    1 + 2 - 3 & 4 | 5    ; = 5
30 0020: 0005  |      W (((1 + 2)- 3)& 4)| 5    ; = 5
31 0022: 0002  |      W    1 +(2 -(3 &(4 | 5))) ; = 2
32 0024: 0002  |      W   (1 + 2)-(3 &(4 | 5))  ; = 2
33 0026: 0000  |      W  ((1 + 2)- 3)&(4 | 5)   ; = 0
34             |
35             |; contexts for expressions
36 0028: 02    |      B IDENT + 1
37 0029: 0003  |      W IDENT + 2
38             |IDENT = IDENT + 3
```

2. Do problem 4 at the end of Chapter 2 of the notes. This asks for support for multiple labels on a line.

a) Modified EBNF grammar from Figure 2.9

We need to change only one rule of this grammar, from
<statement> ::= [ <identifier> : ] [ ( B | W ) <operand> ]
to
<statement> ::= { <identifier> : } [ ( B | W ) <operand> ]

b) Modified parser from Figure 2.16

Again, the change required is very small; we replace an if statement with a while loop:

```          /* parse optional label */
while (!strcmp(lex.next,":")) {
lex_scan(); /* skip over identifier */
lex_scan(); /* skip over colon */
}
```
c) Modified parser with graceful error handling:
```          /* parse optional label */
while (!strcmp(lex.next,":")) {
if (!is_identifier(lex.this)) {
error("label must be identifier");
}
lex_scan(); /* skip over identifier or error */
lex_scan(); /* skip over colon */
}
```

Here is an alternate solution that will force malformed labels to be reported as "unexpected opcode" errors.

```          /* parse optional label */
while (is_identifier(lex.this)
&&     !strcmp(lex.next,":")      ) {
lex_scan(); /* skip over identifier */
lex_scan(); /* skip over colon */
}
```
3. Do problem 5 at the end of Chapter 2 of the notes.

There are two fairly obvious ways to do this, one using arithmetic, and the other using logic and bit manipulation. Both of these work identically in Java, C and C++. The solutions given here work for unsigned integers. If negative values are to be held, there is more work required in both cases.

```	first_byte = value / 256
second_byte = value % 256

first_byte = value >> 8
second_byte = value & 255
```