// File: /workspace/github_cpp_makefile_star2_O3/AndrewAlbert[P]Compiler-Theory/SourceCode/scanner.cpp
// Function: Scanner::ScanOneToken(_IO_FILE*, token_type*)
int Scanner::ScanOneToken(FILE *fPtr, token_type *token){
	char ch, nextch;
	string str = "";
	do{
		ch = getc(fPtr);
		if(debug && (ch == '\n') ) cout << endl;		
	} while(isSpace(ch));
	
	//handle comments or divisor token
	if(ch == '/'){
		str += ch;
		nextch = getc(fPtr);
		if (nextch == '/'){
			while(nextch != '\n'){
				str += nextch;
				nextch = getc(fPtr);
			}
			token->ascii = str;
			line_number++;
			return T_COMMENT;
		}
		else if (nextch == '*'){
			str += nextch;
			int i = 1;
			while (i > 0){
				nextch = getc(fPtr);
				str += nextch;
				if (nextch == '*'){
					nextch = getc(fPtr);
					str += nextch;
					if(nextch == '/') i -= 1;
				}
				else if (nextch == '/'){
					nextch = getc(fPtr);
					str += nextch;
					if(nextch == '*') i += 1;
				}
				else if (nextch == '\n') line_number++;
			}
			token->ascii = str;
			return T_COMMENT;
		}
		else{
			ungetc(nextch, fPtr);
			token->ascii = str;
			return T_DIVIDE;
		}
	}
	//handle integer and float tokens
	else if(isNum(ch)){
		str += ch;
		nextch = getc(fPtr);
		while(isNum(nextch)){
			str += nextch;
			nextch = getc(fPtr);
		}
		if (nextch == '.'){
			str+= nextch;
			nextch = getc(fPtr);
			while(isNum(nextch)){
				str += nextch;
				nextch = getc(fPtr);
			}
			token->val.doubleValue = stod(str);
			token->ascii = str;
			ungetc(nextch, fPtr);
			return TYPE_FLOAT;
		}
		else {
			token->val.intValue = stoi(str);
			token->ascii = str;
			ungetc(nextch, fPtr);
			return TYPE_INTEGER;
		}
	}
	//handle string tokens
	else if (isString(ch)){
		str += ch;
		nextch = getc(fPtr);
		int i = 0;
		while(!isString(nextch)){
			token->val.stringValue[i++] = nextch;
			str += nextch;
			nextch = getc(fPtr);
		}
		str += nextch;
		token->ascii = str;
		return TYPE_STRING;
	}
	//handle char tokens
	else if (isChar(ch)){
		str += ch;
		nextch = getc(fPtr);
		int i = 0;
		while(!isChar(nextch)){
			token->val.stringValue[i++] = nextch;
			str += nextch;
			nextch = getc(fPtr);
		}
		str += nextch;
		token->ascii = str;
		return TYPE_CHAR;
	}
	//handle identifier tokens
	else if (isLetter(ch)){
		int i = 0;
		token->val.stringValue[i++] = toupper(nextch);
		str += toupper(ch);
		nextch = getc(fPtr);
		while(isLetter(nextch) || isNum(nextch) || nextch == '_')
		{
			token->val.stringValue[i++] = toupper(nextch);
			str += toupper(nextch);
			nextch = getc(fPtr);
		}
		ungetc(nextch, fPtr);
		token->ascii = str;
		
		map<string,int>::iterator it;
		it = reserved_table.find(str);
		if (it != reserved_table.end()) return reserved_table.find(str)->second;
		else return TYPE_IDENTIFIER;
	}
	else if (isSingleToken(ch)){
		str += ch;
		token->ascii = str;
		switch(ch){
			case '.': return T_PERIOD;
			case ';': return T_SEMICOLON;
			case '(': return T_LPAREN;
			case ')': return T_RPAREN;
			case '/': return T_DIVIDE;
			case '*': return T_MULTIPLY;
			case '+': return T_ADD;
			case '-': return T_SUBTRACT;
			case ',': return T_COMMA;
			case '[': return T_LBRACKET;
			case ']': return T_RBRACKET;
			case ':':
				ch = getc(fPtr);
				if (ch == '='){
					str += ch;
					token->ascii = str;
					return T_ASSIGNMENT;
				}
				else{
					ungetc(ch, fPtr);
					token->ascii = str;
					return T_UNKNOWN;
				}
			case '>': case '<': case '=':
				ch = getc(fPtr);
				if (ch == '='){
					str+=ch;
					token->ascii = str;
					return T_LOGICAL;
				}
				else{
					ungetc(ch, fPtr);
					if (str == "=") return T_UNKNOWN;
					else return T_LOGICAL;
				}
			case '!':
				ch = getc(fPtr);
				if (ch == '='){
					str += ch;
					token->ascii = str;
					return T_LOGICAL;
				}
				else{
					ungetc(ch,fPtr);
					return T_UNKNOWN;
				}
			case '&': case '|':
				return T_BITWISE;			
			default: return T_UNKNOWN;
		}
	}
	else if (ch == EOF) return T_EOF;
	else{
		str += ch;
		token->ascii = str;
		return T_UNKNOWN;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbp
movq %rsi, %r14
movq %rdi, %r15
leaq 0x20(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x176a8(%rip), %rdx     # 0x1a95d
leaq 0x10(%rsp), %rdi
movq %rdx, %rsi
callq 0x3c42
movq 0x1ed0f(%rip), %r13     # 0x21fd8
movq %r14, %rdi
callq 0x20b0
movl %eax, %r12d
movl %eax, %ebx
shll $0x18, %ebx
cmpl $0xa000000, %ebx        # imm = 0xA000000
jne 0x3313
cmpb $0x0, 0x138(%r15)
je 0x3313
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq %r13, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
cmpb $0xa, %r12b
jne 0x331c
incl (%r15)
cmpb $0x20, %r12b
jg 0x3328
cmpb $-0x1, %r12b
jne 0x32c9
cmpl $0x2f000000, %ebx       # imm = 0x2F000000
movq %rbp, 0x8(%rsp)
jne 0x33a7
movsbl %r12b, %esi
leaq 0x10(%rsp), %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
movl %eax, %edi
shll $0x18, %edi
cmpl $0x2a000000, %edi       # imm = 0x2A000000
je 0x3528
cmpl $0x2f000000, %edi       # imm = 0x2F000000
jne 0x35cf
cmpb $0xa, %al
movq 0x8(%rsp), %rbx
je 0x338d
leaq 0x10(%rsp), %r12
movsbl %al, %esi
movq %r12, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
cmpb $0xa, %al
jne 0x3376
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
incl (%r15)
movl $0x15c, %ebp            # imm = 0x15C
jmp 0x379d
leal -0x30(%r12), %eax
cmpb $0x9, %al
ja 0x34a4
movsbl %r12b, %esi
leaq 0x10(%rsp), %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
cmpb $0x9, %al
ja 0x33f9
leaq 0x10(%rsp), %r12
movsbl %r15b, %esi
movq %r12, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
cmpb $0xa, %al
jb 0x33da
movl %r15d, %eax
shll $0x18, %eax
cmpl $0x2e000000, %eax       # imm = 0x2E000000
jne 0x35f3
movsbl %r15b, %esi
leaq 0x10(%rsp), %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
cmpb $0x9, %al
ja 0x344f
leaq 0x10(%rsp), %r12
movsbl %r15b, %esi
movq %r12, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
cmpb $0xa, %al
jb 0x3430
movq 0x10(%rsp), %r13
callq 0x2050
movq %rax, %r12
movl (%rax), %ebx
movl $0x0, (%rax)
leaq 0x30(%rsp), %rbp
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2170
cmpq %r13, (%rbp)
je 0x3a4b
movl (%r12), %eax
testl %eax, %eax
movq 0x8(%rsp), %rdi
je 0x3779
cmpl $0x22, %eax
jne 0x377d
leaq 0x15ca6(%rip), %rdi     # 0x19145
callq 0x22b0
cmpb $0x27, %r12b
je 0x3670
movzbl %r12b, %eax
cmpl $0x22, %eax
jne 0x36dd
leaq 0x10(%rsp), %rdi
movl $0x22, %esi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
cmpb $0x22, %al
movq 0x8(%rsp), %rcx
je 0x3500
leaq 0x28(%rcx), %rbx
leaq 0x10(%rsp), %r15
movb %al, (%rbx)
movsbl %al, %esi
movq %r15, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
incq %rbx
cmpb $0x22, %al
jne 0x34e4
leaq 0x10(%rsp), %rdi
movl $0x22, %esi
callq 0x21b0
movl $0x10d, %ebp            # imm = 0x10D
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movsbl %al, %esi
leaq 0x10(%rsp), %rdi
callq 0x21b0
movl $0x1, %ebx
leaq 0x10(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x21b0
cmpb $0xa, %bpl
je 0x35af
movzbl %bpl, %eax
cmpl $0x2f, %eax
je 0x358c
cmpl $0x2a, %eax
jne 0x35b2
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x21b0
xorl %eax, %eax
cmpb $0x2f, %bpl
sete %al
subl %eax, %ebx
jmp 0x35b2
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x21b0
xorl %eax, %eax
cmpb $0x2a, %bpl
sete %al
addl %eax, %ebx
jmp 0x35b2
incl (%r15)
testl %ebx, %ebx
jg 0x353f
movl $0x15c, %ebp            # imm = 0x15C
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
sarl $0x18, %edi
movq %r14, %rsi
callq 0x2070
movl $0x130, %ebp            # imm = 0x130
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movq 0x10(%rsp), %r13
callq 0x2050
movq %rax, %r12
movl (%rax), %ebx
movl $0x0, (%rax)
leaq 0x30(%rsp), %rbp
movq %r13, %rdi
movq %rbp, %rsi
movl $0xa, %edx
callq 0x2290
cmpq %r13, (%rbp)
je 0x3a33
movslq %eax, %rcx
cmpq %rax, %rcx
movq 0x8(%rsp), %rdi
jne 0x3a3f
movl (%r12), %ecx
cmpl $0x22, %ecx
je 0x3a3f
testl %ecx, %ecx
jne 0x364d
movl %ebx, (%r12)
movl %eax, 0x28(%rdi)
leaq 0x10(%rsp), %rsi
callq 0x2120
movsbl %r15b, %edi
movq %r14, %rsi
callq 0x2070
movl $0x10a, %ebp            # imm = 0x10A
jmp 0x379d
leaq 0x10(%rsp), %rdi
movl $0x27, %esi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
cmpb $0x27, %al
movq 0x8(%rsp), %rcx
je 0x36b5
leaq 0x28(%rcx), %rbx
leaq 0x10(%rsp), %r15
movb %al, (%rbx)
movsbl %al, %esi
movq %r15, %rdi
callq 0x21b0
movq %r14, %rdi
callq 0x20b0
incq %rbx
cmpb $0x27, %al
jne 0x3699
leaq 0x10(%rsp), %rdi
movl $0x27, %esi
callq 0x21b0
movl $0x10e, %ebp            # imm = 0x10E
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movl %ebx, %r13d
sarl $0x18, %r13d
movl %r12d, %eax
andb $-0x21, %al
addb $-0x41, %al
cmpb $0x19, %al
ja 0x37ca
xorl %edi, %edi
callq 0x2360
movb %al, 0x28(%rbp)
movl %r13d, %edi
callq 0x2360
movsbl %al, %esi
leaq 0x10(%rsp), %rdi
callq 0x21b0
leaq 0x29(%rbp), %rbx
leaq 0x10(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
movl %eax, %r13d
andb $-0x21, %al
addb $-0x41, %al
cmpb $0x19, %al
ja 0x3734
shll $0x18, %r13d
jmp 0x3753
leal -0x30(%r13), %eax
cmpb $0xa, %al
setae %al
shll $0x18, %r13d
cmpl $0x5f000000, %r13d      # imm = 0x5F000000
setne %cl
testb %al, %cl
jne 0x386a
sarl $0x18, %r13d
movl %r13d, %edi
callq 0x2360
movb %al, (%rbx)
movl %r13d, %edi
callq 0x2360
movsbl %al, %esi
movq %r12, %rdi
callq 0x21b0
incq %rbx
jmp 0x371b
movl %ebx, (%r12)
movsd %xmm0, 0x28(%rdi)
leaq 0x10(%rsp), %rsi
callq 0x2120
movsbl %r15b, %edi
movq %r14, %rsi
callq 0x2070
movl $0x10b, %ebp            # imm = 0x10B
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x37b9
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2200
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movsbl %r12b, %r15d
movl %r15d, %esi
callq 0x31b2
testb %al, %al
je 0x38bb
leaq 0x10(%rsp), %rdi
movl %r15d, %esi
callq 0x21b0
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
cmpl $0x5a, %r13d
jg 0x38fc
addl $-0x21, %r13d
cmpl $0x1d, %r13d
ja 0x3a17
leaq 0x157eb(%rip), %rax     # 0x19004
movslq (%rax,%r13,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
je 0x3976
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2070
leaq 0x15868(%rip), %rsi     # 0x190b4
leaq 0x10(%rsp), %rdi
callq 0x20a0
testl %eax, %eax
movl $0x15e, %eax            # imm = 0x15E
movl $0x139, %ebp            # imm = 0x139
cmovel %eax, %ebp
jmp 0x379d
sarl $0x18, %r13d
movl %r13d, %edi
movq %r14, %rsi
callq 0x2070
leaq 0x10(%rsp), %rsi
movq %rbp, %rdi
callq 0x2120
leaq 0x140(%r15), %rbx
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3ffc
addq $0x148, %r15            # imm = 0x148
cmpq %r15, %rax
je 0x38f2
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3ffc
movl 0x40(%rax), %ebp
jmp 0x379d
movl $0x15d, %ebp            # imm = 0x15D
cmpl $0xff000000, %ebx       # imm = 0xFF000000
je 0x379d
leaq 0x10(%rsp), %rdi
movl %r15d, %esi
callq 0x21b0
movl $0x15e, %ebp            # imm = 0x15E
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movl $0x11c, %ebp            # imm = 0x11C
jmp 0x379d
cmpl $0x5b, %r13d
je 0x3a00
cmpl $0x5d, %r13d
je 0x39f6
cmpl $0x7c, %r13d
jne 0x3a17
movl $0x13b, %ebp            # imm = 0x13B
jmp 0x379d
movl $0x130, %ebp            # imm = 0x130
jmp 0x379d
movl $0x12c, %ebp            # imm = 0x12C
jmp 0x379d
movl $0x12b, %ebp            # imm = 0x12B
jmp 0x379d
movl $0x134, %ebp            # imm = 0x134
jmp 0x379d
movl $0x133, %ebp            # imm = 0x133
jmp 0x379d
movl $0x132, %ebp            # imm = 0x132
jmp 0x379d
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
jne 0x3a0a
leaq 0x10(%rsp), %rdi
movl $0x3d, %esi
callq 0x21b0
movl $0x139, %ebp            # imm = 0x139
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movl $0x12d, %ebp            # imm = 0x12D
jmp 0x379d
movl $0x131, %ebp            # imm = 0x131
jmp 0x379d
movl $0x12e, %ebp            # imm = 0x12E
jmp 0x379d
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
jne 0x3a21
leaq 0x10(%rsp), %rdi
movl $0x3d, %esi
callq 0x21b0
movl $0x13a, %ebp            # imm = 0x13A
leaq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0x2120
jmp 0x379d
movl $0x136, %ebp            # imm = 0x136
jmp 0x379d
movl $0x135, %ebp            # imm = 0x135
jmp 0x379d
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2070
movl $0x15e, %ebp            # imm = 0x15E
jmp 0x379d
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2070
jmp 0x38d9
leaq 0x15710(%rip), %rdi     # 0x1914a
callq 0x2130
leaq 0x15704(%rip), %rdi     # 0x1914a
callq 0x22b0
leaq 0x156f3(%rip), %rdi     # 0x19145
callq 0x2130
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a65
movq %rax, %r14
cmpl $0x0, (%r12)
jne 0x3a88
movl %ebx, (%r12)
jmp 0x3a88
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
jmp 0x3a85
movq %rax, %r14
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x3aa4
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2200
movq %r14, %rdi
callq 0x2330