diff options
author | Ayke van Laethem <[email protected]> | 2024-06-06 19:36:23 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2024-06-07 20:40:27 +0200 |
commit | ae6220262acac838dc092f915fd41f3f74aa8391 (patch) | |
tree | 70aade8c04aaee7efcfb85c28c217372600115a9 | |
parent | e731a31eb93c14b82396b5d8756b2e5042092093 (diff) | |
download | tinygo-ae6220262acac838dc092f915fd41f3f74aa8391.tar.gz tinygo-ae6220262acac838dc092f915fd41f3f74aa8391.zip |
cgo: implement shift operations in preprocessor macros
-rw-r--r-- | cgo/const.go | 14 | ||||
-rw-r--r-- | cgo/const_test.go | 4 |
2 files changed, 16 insertions, 2 deletions
diff --git a/cgo/const.go b/cgo/const.go index 6420af4b9..2d0e29e10 100644 --- a/cgo/const.go +++ b/cgo/const.go @@ -17,6 +17,8 @@ var ( token.OR: precedenceOr, token.XOR: precedenceXor, token.AND: precedenceAnd, + token.SHL: precedenceShift, + token.SHR: precedenceShift, token.ADD: precedenceAdd, token.SUB: precedenceAdd, token.MUL: precedenceMul, @@ -25,11 +27,13 @@ var ( } ) +// See: https://en.cppreference.com/w/c/language/operator_precedence const ( precedenceLowest = iota + 1 precedenceOr precedenceXor precedenceAnd + precedenceShift precedenceAdd precedenceMul precedencePrefix @@ -82,7 +86,7 @@ func parseConstExpr(t *tokenizer, precedence int) (ast.Expr, *scanner.Error) { for t.peekToken != token.EOF && precedence < precedences[t.peekToken] { switch t.peekToken { - case token.OR, token.XOR, token.AND, token.ADD, token.SUB, token.MUL, token.QUO, token.REM: + case token.OR, token.XOR, token.AND, token.SHL, token.SHR, token.ADD, token.SUB, token.MUL, token.QUO, token.REM: t.Next() leftExpr, err = parseBinaryExpr(t, leftExpr) } @@ -205,13 +209,19 @@ func (t *tokenizer) Next() { // https://en.cppreference.com/w/cpp/string/byte/isspace t.peekPos++ t.buf = t.buf[1:] - case len(t.buf) >= 2 && (string(t.buf[:2]) == "||" || string(t.buf[:2]) == "&&"): + case len(t.buf) >= 2 && (string(t.buf[:2]) == "||" || string(t.buf[:2]) == "&&" || string(t.buf[:2]) == "<<" || string(t.buf[:2]) == ">>"): // Two-character tokens. switch c { case '&': t.peekToken = token.LAND case '|': t.peekToken = token.LOR + case '<': + t.peekToken = token.SHL + case '>': + t.peekToken = token.SHR + default: + panic("unreachable") } t.peekValue = t.buf[:2] t.buf = t.buf[2:] diff --git a/cgo/const_test.go b/cgo/const_test.go index 305416e84..d150e751f 100644 --- a/cgo/const_test.go +++ b/cgo/const_test.go @@ -40,6 +40,10 @@ func TestParseConst(t *testing.T) { {`5&5`, `5 & 5`}, {`5|5`, `5 | 5`}, {`5^5`, `5 ^ 5`}, + {`5<<5`, `5 << 5`}, + {`5>>5`, `5 >> 5`}, + {`5>>5 + 3`, `5 >> (5 + 3)`}, + {`5>>5 ^ 3`, `5>>5 ^ 3`}, {`5||5`, `error: 1:2: unexpected token ||, expected end of expression`}, // logical binops aren't supported yet {`(5/5)`, `(5 / 5)`}, {`1 - 2`, `1 - 2`}, |