;; =======================================
;; Author : Matthew W. Coan
;; Date   : 2/23/2000
;;
;; A test program to test the interpreter.
;; =======================================

;; ==============
;; Global Memory:
;; ==============
.GLOBAL_DATA 3 9
INT 0 zero
INT 1 one
CHAR 10 returnChar

;; ================================
;; Procedure/Function declarations.
;; ================================
.PROCS 5
myPrint
myRead
testPointer
factorial
main

;; ==========================
;; A function to print an int 
;; followed by a \n
;; ==========================
.PROC myPrint
.DATA 0 0
.CODE 4
	CALL printInt
	CPUSH returnChar
	CALL printChar
	RET

;; ==========================
;; A function to read and int 
;; from a prompt.
;; ==========================
.PROC myRead
.DATA 0 0
.CODE 2
	CALL readInt
	RET

;; ===========================
;; A pointer testing function.
;; ===========================
;; void testPointer() {
;;    int data;
;;    int * pointer;
;;    int temp;
;;    pointer = &data;
;;    temp = myRead();
;;    *pointer = temp;
;;    myPrint(data);
;;    myPrint(*pointer);
;; }
;; ===========================
.PROC testPointer 
.DATA 3 12 
INT 0 data
INT 0 pointer
INT 0 temp
.CODE 11
	ADDR_OF data
	POP pointer
	CALL myRead
	POP temp
	PUSH pointer
	L_VAL temp
	PUSH data
	CALL myPrint
	R_VAL pointer
	CALL myPrint
	RET

;; ==================================
;; Factorial function
;; ==================================
;; int factorial(int n) {
;;    if(n == 0)
;;       return 1;
;;    else
;;       return n * factorial(n - 1);
;; }
;; ==================================
.PROC factorial
.DATA 2 8
INT 0 arg1
INT 0 temp
.CODE 15
    POP arg1
    PUSH zero
	PUSH arg1
	EQ
	POP temp
	BZ beg
	PUSH one
	BR end
beg	PUSH arg1
	PUSH one
	SUB
	CALL factorial
	PUSH arg1
	MUL
end	RET

;; ===============================
;; Main entry pont:
;; ===============================
;; void main() {
;;    int i = readInt();
;;    myPrint(factorial(i));
;;    while(i >= 0) { 
;;       myPrint(i);
;;       i--;
;;    }
;; }
;; ===============================
.PROC main
.DATA 2 8
INT 0	i
INT 0	temp
.CODE 20
		CALL testPointer
		CALL myRead
		POP i
		PUSH i
		CALL factorial
		POP temp
		PUSH temp
		CALL myPrint
top		PUSH i
		PUSH zero
		GTEQ
		POP temp
		BZ bottom
		PUSH i
		CALL myPrint
		PUSH i
		DEC	
		POP i
		BR top
bottom	RET 
