@@ -27,15 +27,36 @@ fn is_whitespace(char c) -> bool {
27
27
ret c == ' ' || c == '\t' || c == '\r' || c == '\n' ;
28
28
}
29
29
30
+ fn consume_any_whitespace ( stdio_reader rdr, char c) -> char {
31
+ auto c1 = c;
32
+ while ( is_whitespace ( c1) ) {
33
+ c1 = rdr. getc ( ) as char ;
34
+ }
35
+ be consume_any_line_comment ( rdr, c1) ;
36
+ }
37
+
38
+ fn consume_any_line_comment ( stdio_reader rdr, char c) -> char {
39
+ auto c1 = c;
40
+ if ( c1 == '/' ) {
41
+ auto c2 = rdr. getc ( ) as char ;
42
+ if ( c2 == '/' ) {
43
+ while ( c1 != '\n' ) {
44
+ c1 = rdr. getc ( ) as char ;
45
+ }
46
+ // Restart whitespace munch.
47
+ be consume_any_whitespace ( rdr, c1) ;
48
+ }
49
+ }
50
+ ret c;
51
+ }
52
+
30
53
fn next_token ( stdio_reader rdr) -> token . token {
31
54
auto eof = ( -1 ) as char ;
32
55
auto c = rdr. getc ( ) as char ;
33
56
auto accum_str = "" ;
34
57
auto accum_int = 0 ;
35
58
36
- while ( is_whitespace ( c) && c != eof) {
37
- c = rdr. getc ( ) as char ;
38
- }
59
+ c = consume_any_whitespace ( rdr, c) ;
39
60
40
61
if ( c == eof) { ret token. EOF ( ) ; }
41
62
@@ -61,8 +82,19 @@ fn next_token(stdio_reader rdr) -> token.token {
61
82
}
62
83
}
63
84
64
- // One-byte structural symbols.
85
+
86
+ fn op_or_opeq ( stdio_reader rdr, char c2,
87
+ token . op op) -> token . token {
88
+ if ( c2 == '=' ) {
89
+ ret token. OPEQ ( op) ;
90
+ } else {
91
+ rdr. ungetc ( c2 as int ) ;
92
+ ret token. OP ( op) ;
93
+ }
94
+ }
95
+
65
96
alt ( c) {
97
+ // One-byte tokens.
66
98
case ( ';' ) { ret token. SEMI ( ) ; }
67
99
case ( ',' ) { ret token. COMMA ( ) ; }
68
100
case ( '.' ) { ret token. DOT ( ) ; }
@@ -74,6 +106,8 @@ fn next_token(stdio_reader rdr) -> token.token {
74
106
case ( ']' ) { ret token. RBRACKET ( ) ; }
75
107
case ( '@' ) { ret token. AT ( ) ; }
76
108
case ( '#' ) { ret token. POUND ( ) ; }
109
+
110
+ // Multi-byte tokens.
77
111
case ( '=' ) {
78
112
auto c2 = rdr. getc ( ) as char ;
79
113
if ( c2 == '=' ) {
@@ -83,6 +117,49 @@ fn next_token(stdio_reader rdr) -> token.token {
83
117
ret token. OP ( token. EQ ( ) ) ;
84
118
}
85
119
}
120
+
121
+ case ( '-' ) {
122
+ auto c2 = rdr. getc ( ) as char ;
123
+ if ( c2 == '>' ) {
124
+ ret token. RARROW ( ) ;
125
+ } else {
126
+ ret op_or_opeq ( rdr, c2, token. MINUS ( ) ) ;
127
+ }
128
+ }
129
+
130
+ case ( '&' ) {
131
+ auto c2 = rdr. getc ( ) as char ;
132
+ if ( c2 == '&' ) {
133
+ ret token. OP ( token. ANDAND ( ) ) ;
134
+ } else {
135
+ ret op_or_opeq ( rdr, c2, token. AND ( ) ) ;
136
+ }
137
+ }
138
+
139
+ case ( '+' ) {
140
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. PLUS ( ) ) ;
141
+ }
142
+
143
+ case ( '*' ) {
144
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. STAR ( ) ) ;
145
+ }
146
+
147
+ case ( '/' ) {
148
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. STAR ( ) ) ;
149
+ }
150
+
151
+ case ( '!' ) {
152
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. NOT ( ) ) ;
153
+ }
154
+
155
+ case ( '^' ) {
156
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. CARET ( ) ) ;
157
+ }
158
+
159
+ case ( '%' ) {
160
+ ret op_or_opeq ( rdr, rdr. getc ( ) as char , token. PERCENT ( ) ) ;
161
+ }
162
+
86
163
}
87
164
88
165
log "lexer stopping at " ;
0 commit comments