| Assignment 5 Solutions
    
     Part of 
      
      the homework for 22C:50, Spring 2003
      
     
      | 
This is a little programming problem; as such, there is no one correct answer, but rather, a family of answers that vary from awful to wonderful. The answer given here is probably somewhere between these extremes, an illustration of a decent answer.
	procedure line;
	var level: integer;
	begin
	     if lex.this = 'IF' then begin
		  nextlex {skip IF so operand can be parsed};
		  if not(operand) then begin
		       { search for matching else or endif }
		       level := 1;
		       repeat
			    skipline;
			    if lex.this = 'IF'
				 then level = level + 1;
			    if lex.this = 'ENDIF'
				 then level = level - 1;
			    if level = 1 AND lex.this = 'ELSE'
				 then level = level - 1;
		       until level = 0;
		  end;
	     end else if lex.this = 'ELSE' then begin
		  level := 1;
		  repeat
		       skipline;
		       if lex.this = 'IF' then level = level + 1;
		       if lex.this = 'ENDIF' then level = level - 1;
		  until level = 0;
	     end else if lex.this = 'ENDIF' then begin
		  /* do nothing */
	     end else begin
		  if lex.next = '='
		       then definition
		       else statement;
	     end;
	     skipline;
	end {line};
After the first recursive call to TWICE means after TWICE calls itself for the first time. It only calls itself as a result of the second call given in Figure 6.9.
TWICE (TWICE (B 4))
This puts the parameter TWICE (B 4) on the stack, and as we process the body of TWICE, we find that the actual parameter has become a line of text; when we execute this line, we put B 4 on the stack. This gives us the following:
                 n k         n k
                 ______________________________________
       <-push-< |1|m|o|B 4|@|1|x|o|TWICE (B 4)|@| ...
                 ----|-----------|---------------------
                 ^   |_^         |_^
      stack top _|
                 \__________/\__________________/
                   recursive       original
                     call            call
           n = the number of parameters.
           k = previous location from which input was being read.
           m = someplace in body of the stored macro text.
           x = value used to indicate text be read from source file.
           @ = end of parameter
Here is a bit of overkill, an answer that actually works under the SMAL assembler on which EAL is based. Spaces have been squeezed out of the listing because SMAL is a bit generous with them:
SMAL32, rev  6/98.             Fri Feb 28 2003 17:20:59
                1     MACRO PICKAPART (first),(rest)
                2       IF LEN("first")>2
                3         LIST +1000  ; turn on listing
                4         B first
                5         LIST -1000  ; turn it back off
                6         PICKAPART (rest):1:1,(rest):2:9999
                7       ENDIF
                8     ENDMAC
                9 
               10     MACRO DIGITS string
               11       PICKAPART (string):1:1,(string):2:9999
               12     ENDMAC
               13
               14     DIGITS 0
+000000: 00    14         B 0
               15     DIGITS 12
+000001: 01    15         B 1
+000002: 02    15         B 2
               16     DIGITS 123
+000003: 01    16         B 1
+000004: 02    16         B 2
+000005: 03    16         B 3
a)(A + X) - Y
(rel + abs) - abs
rel - abs
rel --- it's relocatable
b)(A + X) - B
(rel + abs) - rel
rel - rel
abs --- it's absolute
c)(A - B) + (A - C)
(rel - rel) + (rel - rel)
abs + abs
abs -- it's absolute
d)(A - X) + (B - Y)
(rel - abs) + (rel - abs)
rel + rel
??? -- it's illegal
e)(A - B) + (A - X)
(rel - rel) + (rel - abs)
abs + rel
rel -- it's relocatable
(5 - A)+(B + C)a) Using Figure 7.6 as a model, find the relocatable value of this expression.
(5 - (A' + R)) + ((B'+R) + (C'+R)) = 5 + -A' + -R + B'+ R + C'+ R = 5 + -A' + -R + B'+ R + C'+ R = 5 + -A' + B'+ R + C' = 5 + B' + C' - A' + R
b) Explain why most assemblers will not allow this expression.
Because it contains a term, (B+C) that is twice relocatable, and another term (5-A) that requires negative relocation.
c) Rewrite this expression in an equivalent form which would be accepted by most assemblers.
		= 5 + B' + C' - A' + R
                = 5 + (B' + R) + (C' - A')
                = 5 + (B' + R) + ((C' + R) - (A' + R))
                = 5 + B + (C - A)
                = 5 + B + C - A