17
17
token .OR : precedenceOr ,
18
18
token .XOR : precedenceXor ,
19
19
token .AND : precedenceAnd ,
20
+ token .SHL : precedenceShift ,
21
+ token .SHR : precedenceShift ,
20
22
token .ADD : precedenceAdd ,
21
23
token .SUB : precedenceAdd ,
22
24
token .MUL : precedenceMul ,
@@ -25,11 +27,13 @@ var (
25
27
}
26
28
)
27
29
30
+ // See: https://en.cppreference.com/w/c/language/operator_precedence
28
31
const (
29
32
precedenceLowest = iota + 1
30
33
precedenceOr
31
34
precedenceXor
32
35
precedenceAnd
36
+ precedenceShift
33
37
precedenceAdd
34
38
precedenceMul
35
39
precedencePrefix
@@ -82,7 +86,7 @@ func parseConstExpr(t *tokenizer, precedence int) (ast.Expr, *scanner.Error) {
82
86
83
87
for t .peekToken != token .EOF && precedence < precedences [t .peekToken ] {
84
88
switch t .peekToken {
85
- case token .OR , token .XOR , token .AND , token .ADD , token .SUB , token .MUL , token .QUO , token .REM :
89
+ case token .OR , token .XOR , token .AND , token .SHL , token . SHR , token . ADD , token .SUB , token .MUL , token .QUO , token .REM :
86
90
t .Next ()
87
91
leftExpr , err = parseBinaryExpr (t , leftExpr )
88
92
}
@@ -205,13 +209,19 @@ func (t *tokenizer) Next() {
205
209
// https://en.cppreference.com/w/cpp/string/byte/isspace
206
210
t .peekPos ++
207
211
t .buf = t .buf [1 :]
208
- case len (t .buf ) >= 2 && (string (t .buf [:2 ]) == "||" || string (t .buf [:2 ]) == "&&" ):
212
+ case len (t .buf ) >= 2 && (string (t .buf [:2 ]) == "||" || string (t .buf [:2 ]) == "&&" || string ( t . buf [: 2 ]) == "<<" || string ( t . buf [: 2 ]) == ">>" ):
209
213
// Two-character tokens.
210
214
switch c {
211
215
case '&' :
212
216
t .peekToken = token .LAND
213
217
case '|' :
214
218
t .peekToken = token .LOR
219
+ case '<' :
220
+ t .peekToken = token .SHL
221
+ case '>' :
222
+ t .peekToken = token .SHR
223
+ default :
224
+ panic ("unreachable" )
215
225
}
216
226
t .peekValue = t .buf [:2 ]
217
227
t .buf = t .buf [2 :]
0 commit comments