Browse Source

cgo: implement shift operations in preprocessor macros

pull/4288/head
Ayke van Laethem 5 months ago
committed by Ron Evans
parent
commit
ae6220262a
  1. 14
      cgo/const.go
  2. 4
      cgo/const_test.go

14
cgo/const.go

@ -17,6 +17,8 @@ var (
token.OR: precedenceOr, token.OR: precedenceOr,
token.XOR: precedenceXor, token.XOR: precedenceXor,
token.AND: precedenceAnd, token.AND: precedenceAnd,
token.SHL: precedenceShift,
token.SHR: precedenceShift,
token.ADD: precedenceAdd, token.ADD: precedenceAdd,
token.SUB: precedenceAdd, token.SUB: precedenceAdd,
token.MUL: precedenceMul, token.MUL: precedenceMul,
@ -25,11 +27,13 @@ var (
} }
) )
// See: https://en.cppreference.com/w/c/language/operator_precedence
const ( const (
precedenceLowest = iota + 1 precedenceLowest = iota + 1
precedenceOr precedenceOr
precedenceXor precedenceXor
precedenceAnd precedenceAnd
precedenceShift
precedenceAdd precedenceAdd
precedenceMul precedenceMul
precedencePrefix precedencePrefix
@ -82,7 +86,7 @@ func parseConstExpr(t *tokenizer, precedence int) (ast.Expr, *scanner.Error) {
for t.peekToken != token.EOF && precedence < precedences[t.peekToken] { for t.peekToken != token.EOF && precedence < precedences[t.peekToken] {
switch 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() t.Next()
leftExpr, err = parseBinaryExpr(t, leftExpr) leftExpr, err = parseBinaryExpr(t, leftExpr)
} }
@ -205,13 +209,19 @@ func (t *tokenizer) Next() {
// https://en.cppreference.com/w/cpp/string/byte/isspace // https://en.cppreference.com/w/cpp/string/byte/isspace
t.peekPos++ t.peekPos++
t.buf = t.buf[1:] 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. // Two-character tokens.
switch c { switch c {
case '&': case '&':
t.peekToken = token.LAND t.peekToken = token.LAND
case '|': case '|':
t.peekToken = token.LOR t.peekToken = token.LOR
case '<':
t.peekToken = token.SHL
case '>':
t.peekToken = token.SHR
default:
panic("unreachable")
} }
t.peekValue = t.buf[:2] t.peekValue = t.buf[:2]
t.buf = t.buf[2:] t.buf = t.buf[2:]

4
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`, `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`, `error: 1:2: unexpected token ||, expected end of expression`}, // logical binops aren't supported yet
{`(5/5)`, `(5 / 5)`}, {`(5/5)`, `(5 / 5)`},
{`1 - 2`, `1 - 2`}, {`1 - 2`, `1 - 2`},

Loading…
Cancel
Save