NEW
  AUTO 3,1
*--------------------------------------
* Input : ZPLineBufPtr, Y,A = T/Q, X = SC
*	 CS : Reset Buffer
*	 CC : Reuse Buffer
* Output : Y,A = VarID
*--------------------------------------
SYM.New			>STYA ZPPtr2			T/Q
				stx ZPPtr3				SC

				bit bPass2
				bmi SYM.New.Pass2
*--------------------------------------
SYM.New.Pass1	jsr SYM.BufInitYAXC		set buf according C

				jsr SYM.Get
				bcs .1

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #SYM.Q.FUNC
				beq .90
				
				ldy #SYM.Addr+1
				lda (ZPSymBufPtr),y
				bne .90
				
				jmp F.Def

.1				>PUSHB.G CC.hSyms
				>PUSHW ZPLineBufPtr
				jsr SCOPE.Push
				>SYSCALL SListNewKey
				bcs SYM.New.9

				>STYA.G CC.SymID		Y,A = KeyID

				jsr CC.SkipX			X = KeyLen

				.DO _DBG_SYM=1
			jsr SYM.DEBUGN
				.FIN

				bra SYM.New.2
				
.90				lda #E.REDEF
				sec

SYM.New.9		rts
*--------------------------------------
SYM.New.Pass2	jsr SYM.Get
				bcs	SYM.New.9
*--------------------------------------
SYM.New.2		jsr CC.GetCharNB
				bcs .98

				cmp #';'
				bne .1

				lda ZPPtr3
				cmp #SYM.SC.TYPEDEF
				bne SYM.SetAddr

				clc
				rts

.1				cmp #'('
				bne SYM.NewV

				jsr SYM.GetSymSizeOfInAX
				jsr SYM.SetSizeOf

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				ora #SYM.Q.FUNC
				sta (ZPSymBufPtr),y

				jsr SYM.Store			Store this f() with no prototype...
				bcs .99

				jsr F.Decl
				rts

.98				lda #E.CSYN
				sec
.99				rts
*--------------------------------------
SYM.NewV		cmp #'['
				bne SYM.SetAddr

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #%11001111
				sta (ZPSymBufPtr),y

				ldy #SYM.DefSize
				lda #SYM.Def
				sta (ZPSymBufPtr),y

				ldy #SYM.Q

.1				lda (ZPSymBufPtr),y
				clc
				adc #SYM.Q.ARRAY
				sta (ZPSymBufPtr),y

				jsr CORE.GetNCharNB	Skip [
				bcs .98

				cmp #']'
				bne .2

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #SYM.Q.PPPOINTER
				beq .98					[] only allowed for *

				jsr SYM.Add0000			set as [0] (deref)
				bcs .99

				bra .3

.2				jsr EXP.IntConst
				bcs .98

				jsr SYM.AddWord
				bcs .99

				jsr CC.GetCharNB
				bcs .98

				cmp #']'
				bne .98

.3				jsr CORE.GetNCharNB	Skip ]
				bcs SYM.SetAddr

				cmp #'['
				bne SYM.SetAddr

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #SYM.Q.AAARRAY
				cmp #SYM.Q.AAARRAY
				bne .1					already [][][] ?

.98				lda #E.CSYN
				sec
.99				rts
*--------------------------------------
SYM.SetAddr		ldy #SYM.SizeOf
				lda (ZPSymBufPtr),y
				iny
				ora (ZPSymBufPtr),y
				bne .1

				jsr SYM.GetSymSizeOfInAX
				jsr SYM.SetSizeOf

.1				ldy #SYM.SC
				lda (ZPSymBufPtr),y
				beq SYM.SetAddrG		SYM.SC.STATIC

				cmp #SYM.SC.AUTO
				beq SYM.SetAddrL

.9				lda #E.TMISMATCH
				sec
				rts
*--------------------------------------
SYM.SetAddrG	ldy #SYM.Addr

				lda ZPCCData
				sta (ZPSymBufPtr),y

				iny

				lda ZPCCData+1
				sta (ZPSymBufPtr),y

				ldy #SYM.SizeOf
				lda (ZPSymBufPtr),y
				clc
				adc ZPCCData
				sta ZPCCData

				iny
				lda (ZPSymBufPtr),y
				adc ZPCCData+1
				sta ZPCCData+1

				clc
				rts
*--------------------------------------
SYM.SetAddrL	ldy #SYM.SizeOf+1

				lda (ZPSymBufPtr),y
				bne .9

				dey						#SYM.SizeOf

				lda (ZPSymBufPtr),y
				clc
				ldy ScopePtr
				iny
				iny
				adc (ScopeStk),y
				bcs .9

				sta (ScopeStk),y

				ldy #SYM.Addr
				sta (ZPSymBufPtr),y

				ldy #SYM.SizeOf
				lda (ZPSymBufPtr),y

				clc
				ldy ScopePtr
				iny
				iny
				iny
				adc (ScopeStk),y
				sta (ScopeStk),y

				clc
				rts

.9				lda #E.BUF
				sec
				rts
*--------------------------------------
SYM.BufInitYAXC	pha
				tya
				sta (ZPSymBufPtr)		#SYM.T

				pla
				ldy #SYM.Q
				sta (ZPSymBufPtr),y

				txa
				iny						#SYM.SC
				sta (ZPSymBufPtr),y

				bcc .8					DONT reset buffer

				lda #0

.1				iny
				sta (ZPSymBufPtr),y
				cpy #SYM-1
				bcc .1

				ldy #SYM.DefSize
				lda #SYM.Def
				sta (ZPSymBufPtr),y

.8				rts
*--------------------------------------
SYM.PushAddr	ldy #SYM.SC
				lda (ZPSymBufPtr),y
				beq .1					SYM.SC.STATIC
* LOCAL
				>LDYA L.PCC.PushLAddrH
				jsr CODE.EmitPCC
				bcs .9

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

				>LDYA L.PCC.PushLAddrL
				jmp CODE.EmitPCC

* GLOBAL

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

				dey
				lda (ZPSymBufPtr),y

				jsr CODE.LDAXI
				bcs .9

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

				>LDYA L.PCC.PushIAddr
				jmp CODE.EmitPCC

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

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

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

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

				dey
				lda (ZPSymBufPtr),y

				jsr CODE.LDAXI
				bcs .9

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

				>LDYA L.PCC.GetIAddr1
				jmp CODE.EmitPCC

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

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

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

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

				dey
				lda (ZPSymBufPtr),y

				jsr CODE.LDAXI
				bcs .9

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

				>LDYA L.PCC.GetIAddr2
				jmp CODE.EmitPCC

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

.9				rts
*--------------------------------------
SYM.Get			>PUSHB.G CC.hSyms
				>PUSHW ZPLineBufPtr
				jsr SCOPE.Push
				>SYSCALL SListLookup
				bcs .9

				>STYA.G CC.SymID		Y,A = KeyID

				jsr CC.SkipX			X = KeyLen

				>PUSHB.G CC.hSyms
				>PUSHW.G CC.SymID
				>PUSHW ZPSymBufPtr
				>PUSHWI 65535			all
				>PUSHWZ					From Start
				>SYSCALL SListGetData
				.DO _DBG_SYM=1
			bcs	.9
			jsr SYM.DEBUGG
				.FIN
.9				rts				
*--------------------------------------
SYM.NewKey		>PUSHA
				>PUSHW ZPLineBufPtr
				>PUSHWI 0				ScopeID
				>SYSCALL SListNewKey
				rts						Y,A = KeyID, X = KeyLen
*--------------------------------------
SYM.Add0000		>LDYAI 0
*--------------------------------------
SYM.AddWord		phy
				pha

				ldy #SYM.DefSize
				lda (ZPSymBufPtr),y

				clc
				adc #2
				bcs .9

				sta (ZPSymBufPtr),y
				tay

				dey

				pla						A
				sta (ZPSymBufPtr),y

				dey

				pla						Y
				pha
				sta (ZPSymBufPtr),y
				iny
				lda (ZPSymBufPtr),y		get back A
				ply						get back Y

*				clc
				rts

.9				pla
				pla
				lda #E.BUF
				sec
				rts
*--------------------------------------
SYM.AddName		jsr CC.GetCharNB
				bcs .98

				jsr CC.IsLetter
				bcs .98

				jsr CC.GetIDLen
				tax
				jsr SYM.AddByte
				bcs .99

				ldy #0

.1				lda (ZPLineBufPtr),y
				phy
				jsr SYM.AddByte
				ply
				bcs .99

				iny
				dex
				bne .1

				tya
				jsr CC.SkipA

				clc
				rts

.98				lda #E.CSYN
				sec
.99				rts
*--------------------------------------
SYM.AddByte		pha

				ldy #SYM.DefSize
				lda (ZPSymBufPtr),y

				inc
				beq .9

				sta (ZPSymBufPtr),y
				dec
				tay
				pla
				sta (ZPSymBufPtr),y

				clc
				rts

.9				pla
				lda #E.BUF
				sec
				rts
*--------------------------------------
SYM.Update		sec
				.HS 90					BCC
*--------------------------------------
SYM.Store		clc
				bit bPass2
				bmi .8

				php
				.DO _DBG_SYM=1
				bcc .10

			jsr SYM.DEBUGU

				bra .11

.10
			jsr SYM.DEBUGS

.11				.FIN
				>PUSHB.G CC.hSyms
				>PUSHW.G CC.SymID
				>PUSHW ZPSymBufPtr
				>PUSHBI 0

				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #SYM.Q.FUNC
				bne .1

				ldy #SYM.DefSize
				lda (ZPSymBufPtr),y
				bra .2

.1				lda #SYM.F.MAX

.2				>PUSHA

				plp
				bcs .3

				>SYSCALL SListAddData
				rts

.3				>SYSCALL SListSetData
				rts

.8				bcc .9

				>PUSHB.G CC.hSyms
				>PUSHW.G CC.SymID
				>PUSHW ZPSymBufPtr
				>PUSHWI 65535			all
				>PUSHWZ					From Start
				>SYSCALL SListGetData

				.DO _DBG_SYM=1
			bcs	.9
			jsr SYM.DEBUGG
				.FIN
.9				rts
*--------------------------------------
SYM.Lookup		>LDA.G CC.LookupIdx

				cmp #CC.LookupIdx+LOOKUP.MAX
				beq .99

				>PUSHB.G CC.hSyms	...for SListGetData

				lda ScopePtr

.1				pha
				>PUSHB.G CC.hSyms
				>PUSHW ZPLineBufPtr
				pla
				pha
				jsr SCOPE.PushA
				>SYSCALL SListLookup
				bcc .8

				pla
				beq .9

*				sec
				sbc #SCOPE
				bra .1

.99				lda #E.OOH
*				sec
				rts

.9				inc pStack				discard CC.hSyms

				lda #E.NOKEY
				sec
				rts

.8				>PUSHA					KeyID.HI
				tya
				>PUSHA					KeyID.LO

				pla						discard ScopePtr

				jsr CC.SkipX

				>PUSHWZ					allocate
				>PUSHWI 65535			all
				>PUSHWZ					From Start
				>SYSCALL SListGetData

				>STYA.G CC.LookupSymSize

				>INC.G CC.LookupIdx
				tay

				txa
				sta (pdata),y

				>SYSCALL GetMemPtr
				>STYA ZPLookupSymPtr

*				clc
				rts
*--------------------------------------
* "_B"reak
* "_C"ontinue
* "_D"efault
* "_E"lse
* "_F"rame Size
* "_J"umpTable
* "_L"oop
* "_R"eturn value
* "_S"statement
* e"_X"it
*--------------------------------------
SYM.NewLabelA	bit bPass2
				bpl .10

				clc
.98				rts

.10				>STA.G CC.Label+1

				>PUSHB.G CC.hSyms
				>PUSHEA.G CC.Label
				jsr SCOPE.Push
				>SYSCALL SListNewKey
				bcs .98

				>STYA.G CC.LabelID

				ldy #CC.LabelBuf+SYM.DefSize
				lda #SYM.Def
				sta (pData),y

				>LDA.G CC.Label+1
				cmp #'F'
				bne .1

				jsr SYM.NewLabelF
				bra .7

.1				cmp #'R'
				bne .6

				jsr SYM.NewLabelR
				bra .7

.6				lda #SYM.T.VOID
				>STA.G CC.LabelBuf
				lda #SYM.Q.POINTER
				iny
				sta (pData),y

				iny
				lda #SYM.SC.STATIC
				sta (pData),y

				ldy #CC.LabelBuf+SYM.Addr
				lda ZPCCCode
				sta (pData),y
				iny
				lda ZPCCCode+1
				sta (pData),y

.7				.DO _DBG_SYM=1
			jsr SYM.DEBUGNL
				.FIN

				>PUSHB.G CC.hSyms
				>PUSHW.G CC.LabelID
				>PUSHEA.G CC.LabelBuf
				>PUSHBI 0

				lda #SYM.Def
				>PUSHA
				>SYSCALL SListAddData

				.DO _DBG_SYM=1
			bcs .99
			jsr SYM.DEBUGSL
				.FIN
.99				rts
*--------------------------------------
SYM.NewLabelF	lda #SYM.T.UCHAR
				>STA.G CC.LabelBuf
				lda #0
				iny
				sta (pData),y

				iny
				lda #SYM.SC.AUTO
				sta (pData),y

				ldy ScopePtr
				iny
				iny
				iny
				lda (ScopeStk),y		#SCOPE.FrameSize

				ldy #CC.LabelBuf+SYM.Addr
				sta (pData),y
				rts
*--------------------------------------
SYM.NewLabelR	ldy #SYM.Q
				lda (ZPSymBufPtr),y
				and #$F8				strip off SYM.Q.FUNC...
				pha

				lda (ZPSymBufPtr)
				>STA.G CC.LabelBuf
				pla
				iny
				sta (pData),y

				iny
				lda #SYM.SC.AUTO
				sta (pData),y
				rts
*--------------------------------------
* _R : Y,A = T/Q
* others : X,Y = SYM.Addr
*--------------------------------------
SYM.LookupLabelA
				cmp #'R'
				beq .1

				bit bPass2
				bmi .1

				ldx #0
				ldy #0
				clc
				rts

.1				>STA.G CC.Label+1		A = "B"reak, "C"ontinue...

				>PUSHB.G CC.hSyms	...for SListGetData

				lda ScopePtr

.2				pha
				>PUSHB.G CC.hSyms
				>PUSHEA.G CC.Label
				pla
				pha
				jsr SCOPE.PushA
				>SYSCALL SListLookup
				bcc .3

				pla
				beq .9

*				sec
				sbc #SCOPE
				bra .2

.9				inc pStack				discard CC.hSyms

				lda #E.NOKEY
				sec
				rts

.3				plx

				>PUSHA					KeyID.HI
				tya
				>PUSHA					KeyID.LO

				>PUSHWZ					allocate
				>PUSHWI 65535			all
				>PUSHWZ					From Start
				>SYSCALL SListGetData
				bcs .99

				phx

				txa
				>SYSCALL GetMemPtr
				>STYA ZPLookupPtr

				plx

				>LDA.G CC.Label+1
				cmp #'R'
				beq .4

				ldy #SYM.Addr

				lda (ZPLookupPtr),y

				pha

				iny
				lda (ZPLookupPtr),y
				pha

				txa
				>SYSCALL FreeMem

				ply
				plx

*				clc

				rts
				
.4 				ldy #SYM.T				return T/Q
								
				lda (ZPLookupPtr),y

				pha

				iny						#SYM.Q
				lda (ZPLookupPtr),y
				pha

				txa
				>SYSCALL FreeMem

				pla
				ply

*				clc


.99				rts
*--------------------------------------
SYM.LookupFree	>LDA.G CC.LookupIdx
				cmp #CC.LookupIdx
				beq .9

				tay
				lda (pdata),y
				>SYSCALL FreeMem
				bcs .99

				>DEC.G CC.LookupIdx
				cmp #CC.LookupIdx
				beq .8

				tay
				lda (pdata),y
				>SYSCALL GetMemPtr
				>STYA ZPLookupSymPtr

.8				clc
				rts

.9				lda #E.INVH
*				sec

.99				rts
*--------------------------------------
* ZPPtr2 = expected T/Q
* ZPLookupSymPtr
*--------------------------------------
SYM.LookupCheckTQ
				lda ZPPtr2				target T
				bne .1

				lda (ZPLookupSymPtr)	SYM.T
				sta ZPPtr2				T

				ldy #SYM.Q
				lda (ZPLookupSymPtr),y
				and #$F8				ignore VOLATILE|FUNC|FASTCALL
				sta ZPPtr2+1			Q

				clc
				rts

.1				cmp #SYM.T.VOID
				beq .2

				lda (ZPLookupSymPtr)	SYM.T
				cmp #SYM.T.VOID
				beq .2

				cmp ZPPtr2				T
				bne .9

.2				lda ZPPtr2+1			Q

				ldy #SYM.Q
				eor (ZPLookupSymPtr),y
				and #$F8				ignore VOLATILE|FUNC|FASTCALL
				beq .8

				and #SYM.Q.AAARRAY		is mismatch about array ?
				beq .9					no...

				lda ZPPtr2+1			Q
				and #SYM.Q.AAARRAY
				bne .9

.8				clc
				rts

.9				lda #E.TMISMATCH
				sec
.99				rts
*--------------------------------------
* on RT stack : Addr,value
*--------------------------------------
SYM.PopValue	jsr SYM.GetYASizeOfInAX
				tax
				dex
				bne .1

				>LDYA L.PCC.PopValue1
				jmp CODE.EmitPCC

.1				cpx #1
				bne .2

				>LDYA L.PCC.PopValue2
				jmp CODE.EmitPCC

.2				jsr CODE.LDXI
				bcs .9

				>LDYA L.PCC.PopValueX
				jmp CODE.EmitPCC

.9				rts
*--------------------------------------
* out : Y,A = T/Q
*--------------------------------------
SYM.GetTQInYA	ldy #SYM.Q
				lda (ZPSymBufPtr),y
				pha
				lda (ZPSymBufPtr)
				tay
				pla
				rts
*--------------------------------------
* out : A,X = size
*--------------------------------------
SYM.GetSymSizeOfInAX
				ldy #SYM.Q
				lda (ZPSymBufPtr),y
				pha
				lda (ZPSymBufPtr)		SYM.T
				tay
				pla

SYM.GetYASizeOfInAX

				bit #SYM.Q.PPPOINTER
				beq .1

				lda #2					pointer
				ldx #0

				sec						+1 for hMem Storage
				rts

.1				bit #SYM.Q.AAARRAY
				bne .2

				lda CC.TYPESIZE-1,y
				ldx #0

				clc
				rts

.2				ldx CC.TYPESIZE-1,y

				ldy #SYM.Def
				lda (ZPSymBufPtr),y
				>PUSHA
				iny
				lda (ZPSymBufPtr),y
				>PUSHA

				ldy #1

.3				dex
				beq .5

.4				lda (pStack),y
				clc
				adc (pStack),y
				sta (pStack),y

				lda (pStack)
				adc (pStack)
				sta (pStack)
				dex
				bne .4

.5				>PULLA
				tax
				>PULLA

				clc
				rts
*--------------------------------------
* in/out : A,X = size
*--------------------------------------
SYM.SetSizeOf	ldy #SYM.SizeOf
				sta (ZPSymBufPtr),y

				pha

				iny
				txa
				sta (ZPSymBufPtr),y

				pla
				rts
*--------------------------------------
SYM.SetAddrCCode
				lda ZPCCCode
				ldy #SYM.Addr
				sta (ZPSymBufPtr),y

				lda ZPCCCode+1
				iny
				sta (ZPSymBufPtr),y

				rts
*--------------------------------------
			.DO _DBG_SYM=1
SYM.DEBUGN	>PUSHW L.MSG.DEBUG.SYMN
			>PUSHW.G CC.SymID
			jsr SCOPE.Push
			lda (ZPSymBufPtr)
			>PUSHA
			ldy #1
			lda (ZPSymBufPtr),y
			>PUSHA
			iny
			lda (ZPSymBufPtr),y
			>PUSHA
			>PUSHBI 7
			>SYSCALL Printf
			rts

SYM.DEBUGU	>PUSHW L.MSG.DEBUG.SYMU
			>PUSHW.G CC.SymID
			lda (ZPSymBufPtr)
			>PUSHA
			ldy #1
			lda (ZPSymBufPtr),y
			>PUSHA
			iny
			lda (ZPSymBufPtr),y
			>PUSHA

			ldy #SYM.Addr+1
			lda (ZPSymBufPtr),y
			>PUSHA
			dey
			lda (ZPSymBufPtr),y
			>PUSHA

			>PUSHBI 7
			>SYSCALL Printf
			rts

SYM.DEBUGS	>PUSHW L.MSG.DEBUG.SYMS
			>PUSHW.G CC.SymID
			lda (ZPSymBufPtr)
			>PUSHA
			ldy #1
			lda (ZPSymBufPtr),y
			>PUSHA
			iny
			lda (ZPSymBufPtr),y
			>PUSHA

			ldy #SYM.Addr+1
			lda (ZPSymBufPtr),y
			>PUSHA
			dey
			lda (ZPSymBufPtr),y
			>PUSHA

			>PUSHBI 7
			>SYSCALL Printf
		>DEBUG
			rts

SYM.DEBUGG	>PUSHW L.MSG.DEBUG.SYMG
			>PUSHW.G CC.SymID
			lda (ZPSymBufPtr)
			>PUSHA
			ldy #1
			lda (ZPSymBufPtr),y
			>PUSHA
			iny
			lda (ZPSymBufPtr),y
			>PUSHA
			>PUSHBI 5
			>SYSCALL Printf
			rts

SYM.DEBUGNL	>PUSHW L.MSG.DEBUG.SYMNL
			>PUSHEA.G CC.Label
			>PUSHW.G CC.LabelID
			jsr SCOPE.Push
			ldy #CC.LabelBuf
			lda (pData),y
			>PUSHA
			iny
			lda (pData),y
			>PUSHA
			iny
			lda (pData),y
			>PUSHA
			>PUSHBI 9
			>SYSCALL Printf
*		>DEBUG
			rts

SYM.DEBUGSL	>PUSHW L.MSG.DEBUG.SYMSL
			>PUSHW.G CC.LabelID
			ldy #CC.LabelBuf
			lda (pData),y
			>PUSHA
			iny
			lda (pData),y
			>PUSHA
			iny
			lda (pData),y
			>PUSHA
			>PUSHBI 5
			>SYSCALL Printf
			rts
			.FIN
*--------------------------------------
MAN
SAVE usr/src/bin/cc.s.sym
LOAD usr/src/bin/cc.s
ASM
