// File: /workspace/github_cpp_makefile_star2_O2/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, 0x28(%rsp)
movq %rsi, %r14
movq %rdi, %r15
leaq 0xf98f(%rip), %rsi      # 0x1293d
leaq 0x8(%rsp), %rdi
leaq 0x37(%rsp), %rdx
callq 0x36b8
movq 0x1800c(%rip), %r12     # 0x1afd0
movq %r14, %rdi
callq 0x20b0
movl %eax, %r13d
movl %eax, %ebx
shll $0x18, %ebx
cmpl $0xa000000, %ebx        # imm = 0xA000000
jne 0x2fee
cmpb $0x0, 0x138(%r15)
je 0x2fee
movq %r12, %rdi
callq 0x2100
cmpb $0xa, %r13b
jne 0x2ff7
incl (%r15)
cmpb $0x20, %r13b
jg 0x3003
cmpb $-0x1, %r13b
jne 0x2fc4
movsbl %r13b, %r12d
cmpl $0x2f000000, %ebx       # imm = 0x2F000000
jne 0x3068
leaq 0x8(%rsp), %rdi
movl %r12d, %esi
callq 0x2190
movq 0x28(%rsp), %rbx
movq %r14, %rdi
callq 0x20b0
movl %eax, %edi
shll $0x18, %edi
cmpl $0x2a000000, %edi       # imm = 0x2A000000
je 0x314a
cmpl $0x2f000000, %edi       # imm = 0x2F000000
jne 0x31df
leaq 0x8(%rsp), %r12
cmpb $0xa, %al
je 0x3201
movsbl %al, %esi
movq %r12, %rdi
callq 0x2190
movq %r14, %rdi
callq 0x20b0
jmp 0x304b
leal -0x30(%r13), %eax
cmpb $0x9, %al
ja 0x30a8
leaq 0x8(%rsp), %rdi
movl %r12d, %esi
callq 0x2190
movq 0x28(%rsp), %rbx
leaq 0x8(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
movsbl %r15b, %esi
cmpb $0x9, %al
ja 0x3105
movq %r12, %rdi
callq 0x2190
jmp 0x3087
cmpb $0x27, %r13b
je 0x329d
movzbl %r13b, %eax
cmpl $0x22, %eax
jne 0x32e3
leaq 0x8(%rsp), %rdi
pushq $0x22
popq %rsi
callq 0x2190
movq 0x28(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
leaq 0x28(%r12), %rbx
leaq 0x8(%rsp), %r15
cmpb $0x22, %al
je 0x3384
movb %al, (%rbx)
movsbl %al, %esi
movq %r15, %rdi
callq 0x2190
movq %r14, %rdi
callq 0x20b0
incq %rbx
jmp 0x30e3
movl %r15d, %eax
shll $0x18, %eax
cmpl $0x2e000000, %eax       # imm = 0x2E000000
jne 0x3234
leaq 0x8(%rsp), %rdi
callq 0x2190
leaq 0x8(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
movl %eax, %r15d
leal -0x30(%r15), %eax
cmpb $0x9, %al
ja 0x3269
movsbl %r15b, %esi
movq %r12, %rdi
callq 0x2190
jmp 0x3125
movsbl %al, %esi
leaq 0x8(%rsp), %rdi
callq 0x2190
pushq $0x1
popq %r13
leaq 0x8(%rsp), %r12
testl %r13d, %r13d
jle 0x321b
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x2190
cmpb $0xa, %bpl
je 0x31b6
movzbl %bpl, %eax
cmpl $0x2f, %eax
je 0x31bb
cmpl $0x2a, %eax
jne 0x3160
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x2190
xorl %eax, %eax
cmpb $0x2f, %bpl
sete %al
negl %eax
jmp 0x31da
incl (%r15)
jmp 0x3160
movq %r14, %rdi
callq 0x20b0
movl %eax, %ebp
movsbl %bpl, %esi
movq %r12, %rdi
callq 0x2190
xorl %eax, %eax
cmpb $0x2a, %bpl
sete %al
addl %eax, %r13d
jmp 0x3160
sarl $0x18, %edi
movq %r14, %rsi
callq 0x2060
movl $0x130, %ebp            # imm = 0x130
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
jmp 0x34e2
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
incl (%r15)
movl $0x15c, %ebp            # imm = 0x15C
jmp 0x34e2
movl $0x15c, %ebp            # imm = 0x15C
leaq 0x8(%rsp), %rsi
movq 0x28(%rsp), %rdi
callq 0x2120
jmp 0x34e2
leaq 0x8(%rsp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x373b
movl %eax, 0x28(%rbx)
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
movsbl %r15b, %edi
movq %r14, %rsi
callq 0x2060
movl $0x10a, %ebp            # imm = 0x10A
jmp 0x34e2
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0x3722
movsd %xmm0, 0x28(%rbx)
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
movsbl %r15b, %edi
movq %r14, %rsi
callq 0x2060
movl $0x10b, %ebp            # imm = 0x10B
jmp 0x34e2
leaq 0x8(%rsp), %rdi
pushq $0x27
popq %rsi
callq 0x2190
movq 0x28(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
leaq 0x28(%r12), %rbx
leaq 0x8(%rsp), %r15
cmpb $0x27, %al
je 0x33a8
movb %al, (%rbx)
movsbl %al, %esi
movq %r15, %rdi
callq 0x2190
movq %r14, %rdi
callq 0x20b0
incq %rbx
jmp 0x32c1
movl %ebx, %ebp
sarl $0x18, %ebp
andb $-0x21, %r13b
addb $-0x41, %r13b
cmpb $0x19, %r13b
ja 0x33cc
xorl %edi, %edi
callq 0x2340
movq 0x28(%rsp), %rbx
movb %al, 0x28(%rbx)
movl %ebp, %edi
callq 0x2340
movsbl %al, %esi
leaq 0x8(%rsp), %rdi
callq 0x2190
addq $0x29, %rbx
leaq 0x8(%rsp), %r12
movq %r14, %rdi
callq 0x20b0
movl %eax, %r13d
andb $-0x21, %al
addb $-0x41, %al
cmpb $0x19, %al
ja 0x333f
shll $0x18, %r13d
jmp 0x335e
leal -0x30(%r13), %eax
cmpb $0xa, %al
setae %al
shll $0x18, %r13d
cmpl $0x5f000000, %r13d      # imm = 0x5F000000
setne %cl
testb %al, %cl
jne 0x345f
sarl $0x18, %r13d
movl %r13d, %edi
callq 0x2340
movb %al, (%rbx)
movl %r13d, %edi
callq 0x2340
movsbl %al, %esi
movq %r12, %rdi
callq 0x2190
incq %rbx
jmp 0x3326
leaq 0x8(%rsp), %rdi
pushq $0x22
popq %rsi
callq 0x2190
movl $0x10d, %ebp            # imm = 0x10D
leaq 0x8(%rsp), %rsi
movq %r12, %rdi
callq 0x2120
jmp 0x34e2
leaq 0x8(%rsp), %rdi
pushq $0x27
popq %rsi
callq 0x2190
movl $0x10e, %ebp            # imm = 0x10E
leaq 0x8(%rsp), %rsi
movq %r12, %rdi
callq 0x2120
jmp 0x34e2
movl %r12d, %esi
callq 0x2ee0
testb %al, %al
movq 0x28(%rsp), %r15
je 0x34af
leaq 0x8(%rsp), %rdi
movl %r12d, %esi
callq 0x2190
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2120
leal -0x21(%rbp), %eax
cmpl $0x1d, %eax
ja 0x34fd
leaq 0xdbf6(%rip), %rcx      # 0x11004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
je 0x355f
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2060
leaq 0xdc73(%rip), %rsi      # 0x110b4
leaq 0x8(%rsp), %rdi
callq 0x3757
testb %al, %al
movl $0x15e, %eax            # imm = 0x15E
movl $0x139, %ebp            # imm = 0x139
cmovnel %eax, %ebp
jmp 0x34e2
sarl $0x18, %r13d
movl %r13d, %edi
movq %r14, %rsi
callq 0x2060
leaq 0x8(%rsp), %rsi
movq 0x28(%rsp), %rdi
callq 0x2120
leaq 0x140(%r15), %rbx
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x3d8c
addq $0x148, %r15            # imm = 0x148
cmpq %r15, %rax
je 0x34dd
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x3d8c
movl 0x40(%rax), %ebp
jmp 0x34e2
movl $0x15d, %ebp            # imm = 0x15D
cmpl $0xff000000, %ebx       # imm = 0xFF000000
je 0x34e2
leaq 0x8(%rsp), %rdi
movl %r12d, %esi
callq 0x2190
movl $0x15e, %ebp            # imm = 0x15E
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2120
jmp 0x34e2
movl $0x11c, %ebp            # imm = 0x11C
leaq 0x8(%rsp), %rdi
callq 0x20f0
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x5b, %ebp
je 0x35e1
cmpl $0x5d, %ebp
je 0x35d7
cmpl $0x7c, %ebp
jne 0x35f8
movl $0x13b, %ebp            # imm = 0x13B
jmp 0x34e2
movl $0x12c, %ebp            # imm = 0x12C
jmp 0x34e2
movl $0x12e, %ebp            # imm = 0x12E
jmp 0x34e2
movl $0x131, %ebp            # imm = 0x131
jmp 0x34e2
movl $0x12b, %ebp            # imm = 0x12B
jmp 0x34e2
movl $0x12d, %ebp            # imm = 0x12D
jmp 0x34e2
movl $0x132, %ebp            # imm = 0x132
jmp 0x34e2
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
jne 0x35eb
leaq 0x8(%rsp), %rdi
pushq $0x3d
popq %rsi
callq 0x2190
movl $0x139, %ebp            # imm = 0x139
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2120
jmp 0x34e2
movl $0x134, %ebp            # imm = 0x134
jmp 0x34e2
movl $0x133, %ebp            # imm = 0x133
jmp 0x34e2
movl $0x130, %ebp            # imm = 0x130
jmp 0x34e2
movq %r14, %rdi
callq 0x20b0
shll $0x18, %eax
cmpl $0x3d000000, %eax       # imm = 0x3D000000
jne 0x3602
leaq 0x8(%rsp), %rdi
pushq $0x3d
popq %rsi
callq 0x2190
movl $0x13a, %ebp            # imm = 0x13A
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2120
jmp 0x34e2
movl $0x136, %ebp            # imm = 0x136
jmp 0x34e2
movl $0x135, %ebp            # imm = 0x135
jmp 0x34e2
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2060
movl $0x15e, %ebp            # imm = 0x15E
jmp 0x34e2
sarl $0x18, %eax
movl %eax, %edi
movq %r14, %rsi
callq 0x2060
jmp 0x34c9
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
jmp 0x3632
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x2310