-
Notifications
You must be signed in to change notification settings - Fork 0
/
Input.cpp
123 lines (105 loc) · 2.34 KB
/
Input.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Parse.h"
TokenType next_token_type = INVALID;
int32_t token_number_value = 0;
FILE* input_source = stdin;
static const uint32_t buff_size = 4096;
static char buff[buff_size];
static uint32_t cursor = 0;
static const uint32_t token_max_size = 128;
static char token[token_max_size];
void set_input(const char* file_name) {
FILE* p = fopen(file_name, "r");
if (!p) {
fprintf(stderr, "sorry, I coulnd't open the file %s for reading\n", file_name);
return;
}
input_source = p;
cursor = 0;
buff[0] = 0;
}
void skip_line(void) {
cursor = 0;
buff[0] = 0;
}
static bool IS_NUMBER(char c) {
return c >= '0' && c <='9';
}
static bool IS_LETTER(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
static bool IS_SPACE(char c) {
return c == ' ' || c == '\t' || c == '\n';
}
static bool token_has_been_peeked = false;
void read_next_token(void) {
if (token_has_been_peeked) {
token_has_been_peeked = false;
return;
}
uint32_t k = 0;
do {
if (buff[cursor] == 0) {
cursor = 0;
const char* res = fgets(buff, buff_size, input_source);
if (res == 0) {
*token = 0;
next_token_type = END;
return;
}
}
bool is_quoted_string = false;
while (buff[cursor] != 0) {
if (IS_SPACE(buff[cursor]) && !is_quoted_string) {
cursor += 1;
break;
}
if (buff[cursor] == '\"') { // a " character is next
is_quoted_string = !is_quoted_string;
cursor += 1;
} else if (buff[cursor] == '\\') { // a \ character is next
switch(buff[cursor+1]) {
case 'n':
token[k] = '\n'; k += 1;
break;
case 't':
token[k] = '\t'; k += 1;
break;
case '\\':
token[k] = '\\'; k += 1;
break;
default:
break;
}
cursor += 2;
} else {
token[k] = buff[cursor];
k += 1;
cursor += 1;
}
}
token[k] = 0;
} while (k == 0);
while (buff[cursor] != 0 && IS_SPACE(buff[cursor])) {
cursor += 1;
}
/* now, set the various parsing flags */
if (IS_NUMBER(token[0])) {
next_token_type = NUMBER;
token_number_value = atoi(token);
} else if (! IS_LETTER(token[0])) {
next_token_type = SYMBOL;
} else {
next_token_type = NAME;
}
}
const char* next_token(void) {
return token;
}
const char* peek_next_token(void) {
read_next_token();
token_has_been_peeked = true;
return next_token();
}