; Symbol Table

; Structure of a symbol: (rough draft!!)
;  label:
;	link->next symbol
;	name
;	type {proc, func, var, const}
;	type {int, char, string, real, rational}
;	size
;	value/data...
;
; Keywords will have a separate symbol table, to reduce search time and/or
; to simplify.
;
; For now, the keyword symtab is just a list of strings, with labels to use
; for tokens.

;---------------------------------------------------------------------
SECTION .data

;KEYWORD symbol table
keywords:
.begin		db 'BEGIN',0
.end		db 'END',0
		db 0

;IDENTIFIER symbol table
idents	dd .1		;link -> last symbol added to table

.1	dd .2		;link -> next
	db 'BLAH',0	;name

.2	dd 0		;link -> next  0 = end of list
	db 'ABC',0	;name

h	dd free

;---------------------------------------------------------------------
SECTION .bss
	alignb 4
free	resd 1024
;---------------------------------------------------------------------


SECTION .text

;---------------------------------------------------------------------
; KeywordToken(): int	-- Returns ptr to entry, or 0 if not found
	align 4
KeywordToken:
	push ebx,edx,esi,edi
	mov edx, [value]	;edx= search string
	mov esi, keywords	;esi= symbol table

.0	cmp [esi], byte 0
	if e
	  xor eax,eax		;Not found, return 0
	  jmp short .end
	endif
	mov edi,edx		;edi= start of search string
	mov ebx,esi		;ebx= start of symtab string

.1	lodsb
	scasb
	if ne	  ;Chars differ. Scan to next symbol in table.
.skip	  lodsb
	  or al,al
	  jnz .skip
	  jmp short .0
	endif
	or al,al		;Chars match
	jnz .1			; not 0.... Get next char
	mov eax,ebx		; both 0... Strings match
.end	pop ebx,edx,esi,edi
	ret
;---------------------------------------------------------------------
; IdentToken(): int	-- Returns ptr to entry, or 0 if not found
	align 4
IdentToken:
	push ebx,esi,edi
	mov ebx, idents		;ebx= symbol table

.0	mov ebx,[ebx]		;follow link
	or ebx,ebx		;ebx=0? (end of list)
	if z
	  xor eax,eax		;Not found, return 0
	  jmp short .end
	endif
	lea esi,[ebx+4]		;esi= start of symtab string
	mov edi,[value]		;edi= start of search string

.1	lodsb
	scasb
	jne .0		;Chars differ. Go to next symbol in table.
	or al,al		;Chars match
	jnz .1			; not 0.... Get next char
	mov eax,ebx		; both 0... Strings match
.end	pop ebx,esi,edi
	ret
;---------------------------------------------------------------------
;TBD:
; Factor out Tokenize(symtab) from IdentToken. Also use it for keywords.
; Will need to handle globals/locals. Parameters are locals.

;---------------------------------------------------------------------
AddIdent:
	push esi,edi
	mov edi,[h]		;Insert in list
	mov eax,[idents]
	mov [idents],edi
	stosd
	mov [h],edi

	mov esi,[value]		;Copy string
.1	lodsb
	stosb
	or al,al
	jnz .1
	pop esi,edi
printf "Added ident: %s\n", [value]
	ret

;---------------------------------------------------------------------
;END
