;---------------------------------------------------------------------
; Scanner (with full names)

SECTION .text

;---------------------------------------------------------------------
; Skipwhite()	-- Skip over whitespace
	align 4
Skipwhite:
	begin
	  mov eax,[look]
	  call iswhite
	while nz
	  call Getchar
	wend
	ret

;---------------------------------------------------------------------
; Skipcomma()	-- Skip over an _optional_ comma
	align 4
Skipcomma:
	call Skipwhite
	cmp [look], byte ','
	if e
	  call Getchar
	  call Skipwhite
	endif
	ret

;---------------------------------------------------------------------
; Match(c)	-- Error out if (look <> c)
	align 4
_Match:
;	call Skipwhite
	cmp eax,[look]
	if ne
	  printf "Error: '%c' (ascii %d) expected.\n", eax, eax
	  jmp halt
	endif
	call Getchar
	ret

%macro Match 1
	mov eax,%1
	call _Match
%endmacro

;---------------------------------------------------------------------
; Getname()	-- Parse an identifier, return w/ [value]= string ptr
	align 4
Getname:
	call Skipwhite
	push edi
	mov edi, strbuf
	mov eax, [look]
	call isalpha
	if z
	  printf "Error: Name expected.\n"
	  jmp halt
	endif
	begin
	  mov eax, [look]
	  call isalnum
	while nz
	  mov eax, [look]
	  call toupper
	  stosb
	  call Getchar
	wend
	mov [edi], byte 0

	mov [value], dword strbuf
	mov [type], dword 2		;type=string (Name)
	pop edi
	ret

;---------------------------------------------------------------------
; Getnum(): int		-- Parse a number
	align 4
Getnum:
	call Skipwhite
	push edx
	mov eax,[look]
	call isdigit
	jnz .1
	  printf "Error: Number expected.\n"
	  jmp halt
.1	xor edx,edx
.while
	  mov eax,[look]
	  call isdigit
	jz .wend
	  mov eax,[look]
	  sub al,'0'
	  imul edx,10
	  add edx,eax
	  call Getchar
	jmp short .while
.wend
	mov [value],edx
	mov [type],dword 0		;type=int (Number)
	pop edx
	ret

;---------------------------------------------------------------------
; Next()   (formerly Scan)	-- Get next token
;	LEXICAL SCANNER (only needed when we don't know whether to expect
;			a number, identifier or operator)
Next:
	call Skipwhite
	mov eax,[look]
	call isalpha
	if nz
	  call Getname
	else
	  mov eax,[look]
	  call isdigit
	  if nz
	    call Getnum
	  else
	    mov eax,[look]
	    mov [value],eax
	    mov [type],dword 1		;type=char (Operator or fuckup)
	    call Getchar
	  endif
	endif
	ret


SECTION .bss

strbuf	resb	256
