Files
avo/operand/make_const.go
Michael McLoughlin 0d789c8353 operand: fix integer float data (#393)
Issue #387 pointed out that integer float data is printed incorrectly, such
that it is not parsed correctly by the Go assembler. Specifically, integer
values need the decimal point, otherwise they will be treated as integers. For
example, 1 must be represented as `$(1.)` or `$(1.0)` to be parsed correctly.

This PR fixes that problem and adds a regression test.  The root of the
problem was that the formatting verb `%#v` does not have the right behavior
for integers. We fix it by deferring to custom `String()` function for the
float operand types.

Fixes #387
Closes #388
2023-06-11 16:12:59 -07:00

75 lines
1.8 KiB
Go

//go:build ignore
package main
import (
"bytes"
"flag"
"fmt"
"go/format"
"io"
"log"
"os"
"path/filepath"
"runtime"
"strconv"
)
var output = flag.String("output", "", "path to output file (default stdout)")
func PrintConstType(w io.Writer, name, typ, format string, size int, doc string) {
r := typ[0]
fmt.Fprintf(w, "// %s\n", doc)
fmt.Fprintf(w, "type %s %s\n", name, typ)
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "func (%c %s) Asm() string { return fmt.Sprintf(\"$%s\", %c) }\n", r, name, format, r)
fmt.Fprintf(w, "func (%c %s) Bytes() int { return %d }\n", r, name, size)
fmt.Fprintf(w, "func (%c %s) constant() {}\n", r, name)
fmt.Fprintf(w, "\n")
}
func PrintConstTypes(w io.Writer) {
_, self, _, _ := runtime.Caller(0)
fmt.Fprintf(w, "// Code generated by %s. DO NOT EDIT.\n\n", filepath.Base(self))
fmt.Fprintf(w, "package operand\n\n")
fmt.Fprintf(w, "import \"fmt\"\n\n")
for n := 1; n <= 8; n *= 2 {
bits := n * 8
bs := strconv.Itoa(bits)
if n >= 4 {
// Use string format verb to direct to our custom implementation.
PrintConstType(w, "F"+bs, "float"+bs, "(%s)", n, fmt.Sprintf("F%d is a %d-bit floating point constant.", bits, bits))
}
PrintConstType(w, "I"+bs, "int"+bs, "%+d", n, fmt.Sprintf("I%d is a %d-bit signed integer constant.", bits, bits))
PrintConstType(w, "U"+bs, "uint"+bs, "%#0"+strconv.Itoa(2*n)+"x", n, fmt.Sprintf("U%d is a %d-bit unsigned integer constant.", bits, bits))
}
}
func main() {
flag.Parse()
w := os.Stdout
if *output != "" {
f, err := os.Create(*output)
if err != nil {
log.Fatal(err)
}
defer f.Close()
w = f
}
buf := bytes.NewBuffer(nil)
PrintConstTypes(buf)
src, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
_, err = w.Write(src)
if err != nil {
log.Fatal(err)
}
}