github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/cgo/const_test.go (about)

     1  package cgo
     2  
     3  import (
     4  	"bytes"
     5  	"go/format"
     6  	"go/token"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  func TestParseConst(t *testing.T) {
    12  	// Test converting a C constant to a Go constant.
    13  	for _, tc := range []struct {
    14  		C  string
    15  		Go string
    16  	}{
    17  		{`5`, `5`},
    18  		{`(5)`, `(5)`},
    19  		{`(((5)))`, `(5)`},
    20  		{`)`, `error: 1:1: unexpected token )`},
    21  		{`5)`, `error: 1:2: unexpected token ), expected end of expression`},
    22  		{"  \t)", `error: 1:4: unexpected token )`},
    23  		{`5.8f`, `5.8`},
    24  		{`foo`, `C.foo`},
    25  		{``, `error: 1:1: empty constant`}, // empty constants not allowed in Go
    26  		{`"foo"`, `"foo"`},
    27  		{`"a\\n"`, `"a\\n"`},
    28  		{`"a\n"`, `"a\n"`},
    29  		{`"a\""`, `"a\""`},
    30  		{`'a'`, `'a'`},
    31  		{`0b10`, `0b10`},
    32  		{`0x1234_5678`, `0x1234_5678`},
    33  		{`5 5`, `error: 1:3: unexpected token INT, expected end of expression`}, // test for a bugfix
    34  		// Binary operators.
    35  		{`5+5`, `5 + 5`},
    36  		{`5-5`, `5 - 5`},
    37  		{`5*5`, `5 * 5`},
    38  		{`5/5`, `5 / 5`},
    39  		{`5%5`, `5 % 5`},
    40  		{`5&5`, `5 & 5`},
    41  		{`5|5`, `5 | 5`},
    42  		{`5^5`, `5 ^ 5`},
    43  		{`5||5`, `error: 1:2: unexpected token ||, expected end of expression`}, // logical binops aren't supported yet
    44  		{`(5/5)`, `(5 / 5)`},
    45  		{`1 - 2`, `1 - 2`},
    46  		{`1 - 2 + 3`, `1 - 2 + 3`},
    47  		{`1 - 2 * 3`, `1 - 2*3`},
    48  		{`(1 - 2) * 3`, `(1 - 2) * 3`},
    49  		{`1 * 2 - 3`, `1*2 - 3`},
    50  		{`1 * (2 - 3)`, `1 * (2 - 3)`},
    51  		// Unary operators.
    52  		{`-5`, `-5`},
    53  		{`-5-2`, `-5 - 2`},
    54  		{`5 - - 2`, `5 - -2`},
    55  	} {
    56  		fset := token.NewFileSet()
    57  		startPos := fset.AddFile("", -1, 1000).Pos(0)
    58  		expr, err := parseConst(startPos, fset, tc.C)
    59  		s := "<invalid>"
    60  		if err != nil {
    61  			if !strings.HasPrefix(tc.Go, "error: ") {
    62  				t.Errorf("expected value %#v for C constant %#v but got error %#v", tc.Go, tc.C, err.Error())
    63  				continue
    64  			}
    65  			s = "error: " + err.Error()
    66  		} else if expr != nil {
    67  			// Serialize the Go constant to a string, for more readable test
    68  			// cases.
    69  			buf := &bytes.Buffer{}
    70  			err := format.Node(buf, fset, expr)
    71  			if err != nil {
    72  				t.Errorf("could not format expr from C constant %#v: %v", tc.C, err)
    73  				continue
    74  			}
    75  			s = buf.String()
    76  		}
    77  		if s != tc.Go {
    78  			t.Errorf("C constant %#v was parsed to %#v while expecting %#v", tc.C, s, tc.Go)
    79  		}
    80  	}
    81  }