;..............................................................................;
;
;        EVAL - Evaluate word expression to A
;
;        eval expression
;
;   The first operand in an expression may or may not be present. If it is
; present then the accumulator will be loaded with its value before expression
; evaluation begins.
;
; Sample expressions:
;
;   eval 'Var1.+Var2.-Var3.+#10'
;   eval '.*Var3./Var4.%Var5'
;
; Note:
;
;   Eleven operations are supported +,-,*,/,% (mod), ^ (and), | (or), x (eor), < (asl),
; > (lsr), i (inc), and d (dec). Each of these must be preceded by a '.' and no spaces
; can be present in the expression. The expression should be quoted. Also note that
; both immediate and variable word values may be operands.
;
;..............................................................................;
               MACRO
&lab           eval     &exp
&lab
               lclc     &operand
               lcla     &opstart
			   lclc		&newexp
			   
			IF (&substr(&exp,1,1) = '''') or (&substr(&exp,1,1) = '"') THEN
&newexp			setc &substr(&exp,2,&len(&exp)-2)
			ELSE
&newexp 		setc &exp
			ENDIF
			
&operand       setc     &substr(&newexp,1,1)

		IF	&operand='.' GOTO .no1op
&opstart       seta		&pos('.',&newexp)
		IF	&opstart>0 GOTO .doexp
               lda      &newexp
               mexit
.doexp
&operand       setc	&substr(&newexp,1,&opstart-1)
&newexp           setc	&substr(&newexp,&opstart,&len(&newexp)-&opstart+1)
               lda      &operand
.no1op
               eval2    &newexp
               mexit
               MEND
;
; Eval2 is the heart of the eval macro
;
               MACRO
&lab           eval2    &exp
&lab	; 
		IF	(&nbr(&syslist)=0) GOTO .done
               lclc     &op
               lclc     &operand
               lclc     &rest
               lcla     &restbegin
			   lclc		&newexp
&newexp		setc	&exp
.start
&op            setc	&substr(&newexp,2,1)
&rest          setc	&substr(&newexp,3,&len(&newexp)-2)
&restbegin     seta		&pos('.',&rest)
		IF	&restbegin>0 GOTO .ok
&restbegin     seta     &len(&rest)+1
.ok
&operand       setc		&substr(&rest,1,&restbegin-1)
		IF	&op='+' GOTO .doadd
		IF	&op='-' GOTO .dosub
		IF	&op='*' GOTO .domul
		IF	&op='/' GOTO .dodiv
		IF	&op='%' GOTO .domod
		IF	&op='^' GOTO .doand
		IF	&op='|' GOTO .door
		IF	&op='x' GOTO .doxor
		IF	&op='<' GOTO .doasl
		IF	&op='>' GOTO .dolsr
		IF	&op='i' GOTO .doinc
		IF	&op='d' GOTO .dodec
.done
               mexit
.doadd
               clc
               adc      &operand
		GOTO .dorest

.dosub
               sec
               sbc      &operand
		GOTO .dorest

.domul
               pha
               pha
               pha
               lda      &operand
               pha
				_Multiply
				pla
               plx
		GOTO .dorest

.dodiv
               pha
               pha
               pha
               lda      &operand
               pha
				_SDivide
				pla
               plx
		GOTO .dorest

.domod
               pha
               pha
               pha
               lda      &operand
               pha
				_SDivide
				plx
               pla
		GOTO .dorest


.doand
				and &operand
		GOTO .dorest


.door
				ora &operand
		GOTO .dorest


.doxor
				eor &operand
		GOTO .dorest


.doasl
				asl a
		GOTO .dorest


.dolsr
				lsr a
		GOTO .dorest


.doinc
				inc a
		GOTO .dorest

.dodec
				dec a
		GOTO .dorest


.dorest
&restbegin     seta	&pos('.',&rest)
		IF	&restbegin>0 GOTO .next
               mexit
.next
&newexp           setc		&substr(&rest,&restbegin,&len(&rest)-&restbegin+1)
		GOTO .start

               mexit
               MEND
