aboutsummaryrefslogtreecommitdiffhomepage
path: root/cgo
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-06-06 19:36:23 +0200
committerRon Evans <[email protected]>2024-06-07 20:40:27 +0200
commitae6220262acac838dc092f915fd41f3f74aa8391 (patch)
tree70aade8c04aaee7efcfb85c28c217372600115a9 /cgo
parente731a31eb93c14b82396b5d8756b2e5042092093 (diff)
downloadtinygo-ae6220262acac838dc092f915fd41f3f74aa8391.tar.gz
tinygo-ae6220262acac838dc092f915fd41f3f74aa8391.zip
cgo: implement shift operations in preprocessor macros
Diffstat (limited to 'cgo')
-rw-r--r--cgo/const.go14
-rw-r--r--cgo/const_test.go4
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`},