1717 token .OR : precedenceOr ,
1818 token .XOR : precedenceXor ,
1919 token .AND : precedenceAnd ,
20+ token .SHL : precedenceShift ,
21+ token .SHR : precedenceShift ,
2022 token .ADD : precedenceAdd ,
2123 token .SUB : precedenceAdd ,
2224 token .MUL : precedenceMul ,
@@ -25,11 +27,13 @@ var (
2527 }
2628)
2729
30+ // See: https://en.cppreference.com/w/c/language/operator_precedence
2831const (
2932 precedenceLowest = iota + 1
3033 precedenceOr
3134 precedenceXor
3235 precedenceAnd
36+ precedenceShift
3337 precedenceAdd
3438 precedenceMul
3539 precedencePrefix
@@ -82,7 +86,7 @@ func parseConstExpr(t *tokenizer, precedence int) (ast.Expr, *scanner.Error) {
8286
8387 for t .peekToken != token .EOF && precedence < precedences [t .peekToken ] {
8488 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 :
8690 t .Next ()
8791 leftExpr , err = parseBinaryExpr (t , leftExpr )
8892 }
@@ -205,13 +209,19 @@ func (t *tokenizer) Next() {
205209 // https://en.cppreference.com/w/cpp/string/byte/isspace
206210 t .peekPos ++
207211 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 ]) == ">>" ):
209213 // Two-character tokens.
210214 switch c {
211215 case '&' :
212216 t .peekToken = token .LAND
213217 case '|' :
214218 t .peekToken = token .LOR
219+ case '<' :
220+ t .peekToken = token .SHL
221+ case '>' :
222+ t .peekToken = token .SHR
223+ default :
224+ panic ("unreachable" )
215225 }
216226 t .peekValue = t .buf [:2 ]
217227 t .buf = t .buf [2 :]
0 commit comments