NEW
  AUTO 3,1
*--------------------------------------
* Input:
*   ZPLineBufPtr, Y,A = Expected type/qual
* Output:
*   CS, A = EC
*   CC, Y,A = type/qual
*--------------------------------------
EXP.Eval00		lda #0
				tay

EXP.Eval		ldx ZPPtr1				local : returned T/Q
				phx
				ldx ZPPtr1+1
				phx

				ldx ZPPtr2				local : expected T/Q
				phx
				ldx ZPPtr2+1
				phx

				ldx ZPPtr3				local : BOP
				phx
				ldx ZPPtr3+1			local : PREOP
				phx

				>STYA ZPPtr2

				stz ZPPtr1
				stz ZPPtr1+1

				lda #$ff				no previous OP
				sta ZPPtr3+1			no PREOPS
				pha
*--------------------------------------
.10				jsr CC.GetCharNB
				bcs .19

				cmp #'('
				bne .20

				jsr CORE.GetNCharNB	skip (
				bcs .19

				>LDYA L.CC.TYPEQUAL
				jsr CC.LookupID
				bcs .12

				jsr EXP.Cast
				bcs .19

				bra .20
*--------------------------------------
.12				>LDYA ZPPtr2			expected T/Q
				jsr EXP.Eval
				bcs .19

				>STYA ZPPtr2			update T/Q

				jsr CC.GetCharNB
				bcs .19

				cmp #')'
				bne .19

				jsr CORE.GetNCharNB	skip )
				bcc .31

.19				jmp EXP.Eval.ESYN
*--------------------------------------
.20				>LDYA L.CC.PREOPS
				jsr CC.LookupOP
				stx ZPPtr3+1

				jsr CC.GetCharNB
				bcs .29

				jsr CC.IsLetter			define, f() or Var ?
				bcs .22

				jsr CC.GetDefine
				bcc .10

				jsr SYM.Lookup
				bcs .22

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.FUNC
				bne .21

				jsr EXP.GetVar			Check T/Q & Get value on stack
				bcs .29

				jsr SYM.LookupFree

				bra .30
*--------------------------------------
.21				>LDYA ZPPtr2			get expected T/Q

				jsr F.CallRetV
				bcs .29

				>STYA ZPPtr2			store real T/Q

				jsr SYM.LookupFree

				bra .30
*--------------------------------------
.22				jsr CC.IsDigit10		number ?
				bcs .24

				ldy ZPPtr2				T
				bne .23

				ldy #SYM.T.SINT
				sty ZPPtr2
				stz ZPPtr2+1			Q

.23				jsr EXP.GetNum
				bcs .29

				bra .30
*--------------------------------------
.24				cmp #'''
				bne .25

				jsr EXP.GetChar
				bcs .29

				bra .30

.25				cmp #'"'				String literal
				bne EXP.Eval.ESYN

				jsr EXP.AddConstCharP
.29				bcs EXP.Eval.Err
*--------------------------------------
.30				jsr CC.GetCharNB
				bcs EXP.Eval.ESYN

.31				jsr CC.IsEndArg			, ; ) ? :
				bcc EXP.Eval.End

				jsr CC.IsOPChar
				bcs EXP.Eval.ESYN

				>LDYA L.CC.BOPS			we are at V1 op1 V2 op2...
				jsr CC.LookupOP
				bcs EXP.Eval.ESYN

				stx ZPPtr3				save OP(n)

.33				plx						get OP(n-1)
				bmi .38					$ff....

				cpx ZPPtr3
				bcc .38					OP(n) has precedence, on stack : V1,V2

				>LDYA ZPPtr2			OP(n-1) has precedence...
				jsr EXP.BOPS			compute V(n-1) <OP(n-1)> V(n)
				bcc .33

				bcs EXP.Eval.Err

.38				phx						push back OP(n-1)

				lda ZPPtr3				get OP(n)
				pha						push OP(n) on stack

				jmp .10					go check for next token
*--------------------------------------
EXP.Eval.End	plx						any OP on stack ?
				bmi EXP.Eval.Exit

				>LDYA ZPPtr2			Var Type

				jsr EXP.BOPS
				bcc EXP.Eval.End

				bra EXP.Eval.Err
*--------------------------------------
EXP.Eval.ESYN	lda #E.ESYN

EXP.Eval.Err	plx
				bpl EXP.Eval.Err

				sec
				bra EXP.Eval.ExitErr
*--------------------------------------
EXP.Eval.Exit	lda ZPPtr1+1
				ldy ZPPtr1
				bne .1

				>LDYA ZPPtr2			Type/Qual

.1				and #$FC				ignore SYM.Q.FUNC+SYM.Q.FASTCALL
				clc

EXP.Eval.ExitErr
				plx
				stx ZPPtr3+1
				plx
				stx ZPPtr3

				plx
				stx ZPPtr2+1
				plx
				stx ZPPtr2

				plx
				stx ZPPtr1+1
				plx
				stx ZPPtr1

				rts
*--------------------------------------
EXP.Cast		jsr TYPE.GetTQInYA
				bcs .99

				>STYA ZPPtr1

				jsr CC.GetCharNB
				bcs .9

				cmp #')'
				bne .9

				jsr CORE.GetNCharNB	skip )

				clc
				rts

.9				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
* Y,A = Type/Qual, X = OP
*--------------------------------------
EXP.BOPS		bit #SYM.Q.PPPOINTER
				beq .10

				ldy #SYM.T.UINT
				bra .3

.10				cpy #SYM.T.UINT
				bcs .3

				cpy #SYM.T.UCHAR
				beq .1

				cpy #SYM.T.SCHAR
				beq .2

				lda #E.TMISMATCH
				sec
				rts

.1				>LDYA L.PCC.bBOPS,x
				jmp CODE.EmitPCC

.2				>LDYA L.PCC.bBOPS,x
				jmp CODE.EmitPCC

.3				txa
				clc
				adc CC.Type2FPU-SYM.T.UINT,y
				tax
				jsr CODE.FPUCALL

				clc
				rts
*--------------------------------------
EXP.GetIntegral	jsr CC.GetCharNB
				cmp #'''
				bne .1

				jsr CC.GetNextCharEsc
				bcs .9

				tay

				jsr CC.GetNextChar
				bcs .9

				cmp #'''
				bne .9

				jsr CORE.GetNCharNB		skip '

				lda #0					Y,A = integral

				clc
				rts

.1				jsr CC.IsDigit10
				bcc EXP.IntConst

.9				lda #E.CSYN
*				sec
				rts
*--------------------------------------
EXP.IntConst	>PUSHW ZPLineBufPtr
				>PUSHWI ZPLineBufPtr
				>PUSHBI 10
				>SYSCALL StrToUL

				>PULLA
				tay

				>PULLA

				inc pStack
				inc pStack				Y,A = integral

				rts
*--------------------------------------
EXP.GetNum		cpy #SYM.T.FLOAT
				bcc .1

				beq .11

.90				lda #E.TMISMATCH
*				sec
				rts

.11				>PUSHW ZPLineBufPtr
				>PUSHWI ZPLineBufPtr
				>SYSCALL StrToF
*				bcs .99

				ldy #4

.10				lda (pStack),y
				jsr CODE.PUSHI
				dey
				bpl .10

				>POP 5
				clc
				rts
*--------------------------------------
.1				>PUSHW ZPLineBufPtr
				>PUSHWI ZPLineBufPtr
				>PUSHBI 10

				lda CC.TYPESIGN-1,y
				bmi .2

				>SYSCALL StrToUL
				bra .3

.2				>SYSCALL StrToL

.3				bcs .99

				ldy #1					anticipate 2 bytes if *
				lda ZPPtr2+1
				and #SYM.Q.PPPOINTER
				bne .5

				ldx ZPPtr2
				lda CC.TYPESIZE-1,x

				dec
				tay

.5				lda (pStack),y
				jsr CODE.PUSHI
				dey
				bpl .5

				>POP 4
*				clc
.99				rts
*--------------------------------------
EXP.GetChar		ldy ZPPtr2+1
				bne .9

				lda ZPPtr2
				cmp #SYM.T.UCHAR
				beq .1

				cmp #SYM.T.SCHAR
				bne .9

.1				jsr CC.GetNextCharEsc
				bcs .9

				jsr CODE.PUSHI
				bcs .99

				jsr CC.GetNextChar
				bcs .9

				cmp #'''
				bne .9

				jsr CORE.GetNCharNB	skip '

				clc
				rts

.9				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
EXP.AddConstCharP
				lda ZPCCConst
				ldx ZPCCConst+1

				jsr CODE.LDAXI
				bcs .99

				>LDYA L.PCC.PushIAddr
				jsr CODE.EmitPCC
				bcs .99

				jsr CODE.DSSelect
				bcs .99

.1				jsr CC.GetNextCharEsc
				bcs .9

				bvs .2					ESCaped

				cmp #C.CR
				beq .9

				cmp #'"'
				beq .3

.2				jsr CODE.EmitData
				bcs .99

				bra .1

.3				jsr CORE.GetNCharNBNL		Skip "
				bcs .8

				cmp #'\'
				beq .3

				cmp #'"'
				beq .1

.8				lda #0
				jsr CODE.EmitData
				bcs .99

				jmp CODE.CSSelect

.9				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
* ZPPtr2 = expected T/Q
* ZPPtr3+1 = PREOPS
*--------------------------------------
EXP.GetVar		stz ExpState

				jsr EXP.POSTOPS		var++, var[0]... ?
				bcs .99

				ldx ZPPtr3+1			preop &, * ...
				jsr EXP.PREOPS
				bcs .99

				lda ExpState
				bmi .8					VonStack

				asl

				bmi .7					AinPTR

				asl
				bmi .6					AonStack

				jsr EXP.GetAddr2
				bcs .99

				bra .7

.6				>LDYA L.PCC.PopAddr2
				jsr CODE.EmitPCC
				bcs .99

.7				jsr EXP.PushValue
				bcs .99

.8				jmp SYM.LookupCheckTQ

.99				rts
*--------------------------------------
* POSTOPS
*--------------------------------------
EXP.POSTOPS		>LDYA L.CC.POSTOPS
				jsr CC.LookupOP
				bcs .8

				jmp (J.CC.POSTOPS,x)

.8				clc
				rts
*--------------------------------------
EXP.postinc		lda ExpState
				bit #ExpState.AinPTR
				bne .1

				jsr EXP.GetAddr2
				bcs .99

				lda #ExpState.AinPTR
				tsb ExpState

.1				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.AAARRAY+SYM.Q.PPPOINTER
				bne .8

				lda (ZPLookupSymPtr)	#SYM.T
				cmp #SYM.T.FLOAT
				bcs .98

				tay

				lda CC.TYPESIZE-1,y
				lsr
				bcc .2

				>LDYA L.PCC.Inc1
				jmp CODE.EmitPCC

.2				lsr
				bcc .4

				>LDYA L.PCC.Inc2
				jmp CODE.EmitPCC

.4				>LDYA L.PCC.Inc4
				jmp CODE.EmitPCC


.8

.98				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
EXP.postdec		lda ExpState
				bit #ExpState.AinPTR
				bne .1

				jsr EXP.GetAddr2
				bcs .99

				lda #ExpState.AinPTR
				tsb ExpState

.1				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.AAARRAY+SYM.Q.PPPOINTER
				bne .8

				lda (ZPLookupSymPtr)	#SYM.T
				cmp #SYM.T.FLOAT
				bcs .98

				tay

				lda CC.TYPESIZE-1,y
				lsr
				bcc .2

				>LDYA L.PCC.Dec1
				jmp CODE.EmitPCC

.2				lsr
				bcc .4

				>LDYA L.PCC.Dec2
				jmp CODE.EmitPCC

.4				>LDYA L.PCC.Dec4
				jmp CODE.EmitPCC


.8

.98				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
EXP.Idx			ldy #SYM.Q
				lda (ZPLookupSymPtr),y

				bit #SYM.Q.AAARRAY
				bne EXP.array

				and #SYM.Q.PPPOINTER
				cmp #SYM.Q.POINTER
				bne .98

				lda (ZPLookupSymPtr),y
				eor #SYM.Q.POINTER+SYM.Q.ARRAY
				sta (ZPLookupSymPtr),y		convert from *type to type[]

				jsr EXP.GetAddr2
				bcs .99

				>LDYA L.PCC.PushDeref2
				jsr CODE.EmitPCC
				bcs .99

				jsr EXP.array.getIdx	...int16 on stack...
				bcs .99

				jsr EXP.GetSymSizeOfInAX
				cmp #1
				bne .1

				cpx #0
				beq .2					sizeof=1, no MUL required

.1				jsr CODE.PUSHAXI		...sizeof on stack...
				bcs .99

				ldx #FPU.wMUL
				jsr CODE.FPUCALL		...sizeof*int16...
				bcs .99

.2				ldx #FPU.wAdd
				jsr CODE.FPUCALL		...add to base address
				bcs .99

				jsr CC.GetCharNB
				bcs .97

				cmp #']'
				bne .97

				jsr CORE.GetNCharNB	skip ']'

				lda #ExpState.AonStack
				sta ExpState

				clc
				rts

.97				lda #E.ESYN
				sec
				rts

.98				lda #E.TMISMATCH
				sec
.99				rts
*--------------------------------------
EXP.array		ldy #SYM.Def
				lda (ZPLookupSymPtr),y
				iny
				ora (ZPLookupSymPtr),y
				beq .1
*			jsr CODE.DEBUG
				jsr EXP.PushAddr		array[int]...
				bcc .2

				rts

.1				jsr EXP.GetAddr2		array[]...it is a *
				bcs .9

				>LDYA L.PCC.PushDeref2
				jsr CODE.EmitPCC
				bcs .9

.2				jsr EXP.array.getIdx	...int16 on stack...
				bcs .9

				jsr EXP.GetSymSizeOfInAX
				jsr CODE.PUSHAXI		...sizeof on stack...
				bcs .9

				ldx #FPU.wMUL
				jsr CODE.FPUCALL		...sizeof*int16...
				bcs .9

				ldx #FPU.wAdd
				jsr CODE.FPUCALL		...add to base address
				bcs .9

.3				jsr CORE.GetNCharNB	skip ']'
				bcs .98

				cmp #'['
				bne .8

				jsr CORE.GetNCharNB	skip '['
				bcs .98

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.AAARRAY
.39				beq .99

				jsr EXP.array.getIdx	...int16 on stack...
				bcs .9

				ldy #SYM.Def+3
				lda (ZPLookupSymPtr),y
				tax
				dey
				lda (ZPLookupSymPtr),y
				jsr CODE.PUSHAXI		[][SIZE] on stack

				ldx #FPU.wMUL
				jsr CODE.FPUCALL		[][SIZE] * int16 on stack

				jsr EXP.GetSymSizeOfInAX
				jsr CODE.PUSHAXI		...sizeof on stack...
				bcs .9

				ldx #FPU.wMUL
				jsr CODE.FPUCALL		...sizeof*int16...

				ldx #FPU.wAdd
				jsr CODE.FPUCALL		...add to base address
				bcs .9

				jsr CORE.GetNCharNB	skip ']'
				bcs .98


* TODO : [][][]

.8				lda #ExpState.AonStack
				sta ExpState

				clc
				rts

.98				lda #E.ESYN
				sec
				rts

.99				lda #E.TMISMATCH
				sec
.9				rts
*--------------------------------------
EXP.array.getIdx
				ldy #SYM.T.SINT
				lda #0

				jsr EXP.Eval
				bcs .9

				jsr CC.GetCharNB
				bcs .98

				cmp #']'
				bne .98

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				sec
				sbc #SYM.Q.ARRAY
				sta (ZPLookupSymPtr),y

				clc
				rts

.98				lda #E.ESYN
				sec
.9				rts
*--------------------------------------
EXP.SU			lda (ZPLookupSymPtr)
				cmp #SYM.T.SU
				bne .97

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.PPPOINTER
				bne .97

				jsr CC.GetCharNB
				bcs .98

				jsr CC.IsLetter
				bcs .98

				jsr EXP.SU.GetF
				bcs .98

				jsr CC.SkipX

				lda (ZPLookupSymPtr),y	SU.F.T
				sta (ZPLookupSymPtr)	SYM.T

				iny
				lda (ZPLookupSymPtr),y	SU.F.Q
				phy
				ldy #SYM.Q
				sta (ZPLookupSymPtr),y
				ply

				iny
				lda (ZPLookupSymPtr),y	SU.F.O
				phy
				ldy #SYM.Addr
				clc
				adc (ZPLookupSymPtr),y
				sta (ZPLookupSymPtr),y

				ply
				iny
				lda (ZPLookupSymPtr),y	SU.F.O+1
				ldy #SYM.Addr+1
				adc (ZPLookupSymPtr),y
				sta (ZPLookupSymPtr),y

				clc
				rts

.97				lda #E.TMISMATCH
				sec
				rts

.98				lda #E.ESYN
				sec
.99				rts
*--------------------------------------
EXP.pSU			lda #E.ESYN
				sec
				rts
*--------------------------------------
EXP.SU.GetF		jsr CC.GetIDLen
				tya
				tax

				ldy #SYM.Def

.1				lda (ZPLookupSymPtr),y
				beq .98

				phy						SU.F.T
				tya
				clc
				adc #SU.F.Name
				tay

				txa
				cmp (ZPLookupSymPtr),y
				bne .7

				phy						SU.F.Name
				phx						SU.F.NameLen

				tya
				clc
				adc ZPLookupSymPtr
				sta ZPLookupPtr

				lda #0
				adc ZPLookupSymPtr+1
				sta ZPLookupPtr+1

				ldy #0

.2				lda (ZPLineBufPtr),y
				iny
				cmp (ZPLookupPtr),y
				bne .6

				dex
				bne .2

				plx						NameLen
				pla						SU.F.Name

				ply						SU.F.T

				clc
				rts

.6				plx
				ply

.7				pla
				sec
				adc (ZPLookupSymPtr),y
				adc #SU.F.Name
				tay
				bra .1


.98				lda #E.NOKEY
				sec
.99				rts
*--------------------------------------
* PREOPS
*--------------------------------------
EXP.PREOPS		bmi .8

				jmp (J.CC.PREOPS,x)

.8				clc
				rts
*--------------------------------------
EXP.Ref			ldy #SYM.Q
				lda (ZPLookupSymPtr),y

				clc
				adc #SYM.Q.POINTER
				bcs .9					more than ***

*				and #%11001111
				sta (ZPLookupSymPtr),y

				bit ExpState
				bvs .8

				jsr EXP.PushAddr
				bcs .99

.8				lda #ExpState.VonStack
				sta ExpState

*				clc						Addr on stack
				rts

.9				lda #E.TMISMATCH
*				sec
.99				rts
*--------------------------------------
EXP.Deref		ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				bit #SYM.Q.PPPOINTER
				beq .9

				sec
				sbc #SYM.Q.POINTER
				sta (ZPLookupSymPtr),y

				jsr EXP.GetAddr2
				bcs .99

				>LDYA L.PCC.Deref2
				jsr CODE.EmitPCC
				bcs .99

				lda #ExpState.AinPTR
				sta ExpState

*				clc
				rts

.9				lda #E.TMISMATCH
				sec
.99				rts
*--------------------------------------
EXP.Abs

				clc

.99				rts
*--------------------------------------
EXP.negate

				clc

.99				rts
*--------------------------------------
EXP.lnot

				clc

.99				rts
*--------------------------------------
EXP.bnot

				clc

.99				rts
*--------------------------------------
EXP.preinc

				clc

.99				rts
*--------------------------------------
EXP.predec

				clc

.99				rts
*--------------------------------------
EXP.PushAddr	ldy #SYM.SC
				lda (ZPLookupSymPtr),y
				beq .1					SYM.SC.STATIC
* LOCAL

				>LDYA L.PCC.PushLAddrH
				jsr CODE.EmitPCC
				bcs .9

				ldy #SYM.Addr
				lda (ZPLookupSymPtr),y
				eor #$FF
				inc
				jsr CODE.LDAI
				bcs .9

				>LDYA L.PCC.PushLAddrL
				jmp CODE.EmitPCC

* GLOBAL

.1				ldy #SYM.Addr+1
				lda (ZPLookupSymPtr),y
				tax

				dey
				lda (ZPLookupSymPtr),y

				jsr CODE.LDAXI
				bcs .9

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.CONST
				beq .2

				>LDYA L.PCC.PushIAddr
				jmp CODE.EmitPCC

.2				>LDYA L.PCC.PushUAddr
				jmp CODE.EmitPCC

.9				rts
*--------------------------------------
EXP.GetAddr1	ldy #SYM.SC
				lda (ZPLookupSymPtr),y
				beq .1					SYM.SC.STATIC
* LOCAL
				ldy #SYM.Addr
				lda (ZPLookupSymPtr),y
				eor #$FF
				inc
				jsr CODE.LDAI
				bcs .9

				>LDYA L.PCC.GetLAddr1
				jmp CODE.EmitPCC
* GLOBAL

.1				ldy #SYM.Addr+1
				lda (ZPLookupSymPtr),y
				tax

				dey
				lda (ZPLookupSymPtr),y

				jsr CODE.LDAXI
				bcs .9

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.CONST
				beq .2

				>LDYA L.PCC.GetIAddr1
				jmp CODE.EmitPCC

.2				>LDYA L.PCC.GetUAddr1
				jmp CODE.EmitPCC

.9				rts
*--------------------------------------
EXP.GetAddr2	ldy #SYM.SC
				lda (ZPLookupSymPtr),y
				beq .1					SYM.SC.STATIC
* LOCAL
				ldy #SYM.Addr
				lda (ZPLookupSymPtr),y
				eor #$FF
				inc
				jsr CODE.LDAI
				bcs .9

				>LDYA L.PCC.GetLAddr2
				jmp CODE.EmitPCC
* GLOBAL

.1				ldy #SYM.Addr+1
				lda (ZPLookupSymPtr),y
				tax

				dey
				lda (ZPLookupSymPtr),y

				jsr CODE.LDAXI
				bcs .9

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #SYM.Q.CONST
				beq .2

				>LDYA L.PCC.GetIAddr2
				jmp CODE.EmitPCC

.2				>LDYA L.PCC.GetUAddr2
				jmp CODE.EmitPCC

.9				rts
*--------------------------------------
EXP.PushValue	jsr EXP.GetSymSizeOfInAX
				tay
				dey
				bne .1

				>LDYA L.PCC.PushValue1
				jmp CODE.EmitPCC

.1				cpy #1
				bne .2

				>LDYA L.PCC.PushValue2
				jmp CODE.EmitPCC

.2				jsr CODE.LDYI
				bcs .99

				>LDYA L.PCC.PushValueY
				jmp CODE.EmitPCC

.99				rts
*--------------------------------------
* out : A,X = size
*--------------------------------------
EXP.GetSymSizeOfInAX
				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				pha
				lda (ZPLookupSymPtr)	SYM.T
				tay
				pla

EXP.GetYASizeOfInAX

				bit #SYM.Q.PPPOINTER+SYM.Q.AAARRAY
				bne .1

				lda CC.TYPESIZE-1,y
				ldx #0

				clc
				rts

.1				lda #2					pointer
				ldx #0

				sec						+1 for hMem Storage
				rts
*--------------------------------------
MAN
SAVE usr/src/bin/cc.s.exp
LOAD usr/src/bin/cc.s
ASM
