Source file src/simd/archsimd/_gen/specdoc/type.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package specdoc
     6  
     7  import (
     8  	"fmt"
     9  	"go/ast"
    10  	"go/token"
    11  	"strconv"
    12  
    13  	"simd/archsimd/_gen/specgen"
    14  	"simd/archsimd/_gen/specgen/specexpr"
    15  )
    16  
    17  // fieldListArgs translates an AST field list into a slice of specgen.Arg.
    18  func fieldListArgs(fl *ast.FieldList) ([]specgen.Arg, error) {
    19  	if fl == nil {
    20  		return nil, nil
    21  	}
    22  	var args []specgen.Arg
    23  	for _, f := range fl.List {
    24  		typ, err := parseTypeExpr(f.Type)
    25  		if err != nil {
    26  			return nil, err
    27  		}
    28  		if len(f.Names) == 0 {
    29  			args = append(args, specgen.Arg{Name: "", Type: typ})
    30  			continue
    31  		}
    32  		for _, n := range f.Names {
    33  			args = append(args, specgen.Arg{Name: n.Name, Type: typ})
    34  		}
    35  	}
    36  	return args, nil
    37  }
    38  
    39  // parseTypeExpr translates an AST type expression into a specexpr.Type.
    40  func parseTypeExpr(expr ast.Expr) (specexpr.Type, error) {
    41  	switch t := expr.(type) {
    42  	case *ast.Ident:
    43  		return specexpr.ParseTypeName(t.Name)
    44  
    45  	case *ast.StarExpr:
    46  		elem, err := parseTypeExpr(t.X)
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  		return specexpr.Pointer{Elem: elem}, nil
    51  
    52  	case *ast.ArrayType:
    53  		elem, err := parseTypeExpr(t.Elt)
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  		if t.Len == nil {
    58  			return specexpr.Slice{Elem: elem}, nil
    59  		}
    60  		lit, ok := t.Len.(*ast.BasicLit)
    61  		if !ok || lit.Kind != token.INT {
    62  			return nil, fmt.Errorf("array bound is not an integer literal: %T", t.Len)
    63  		}
    64  		n, err := strconv.Atoi(lit.Value)
    65  		if err != nil || n < 0 {
    66  			return nil, fmt.Errorf("invalid array bound %q: %w", lit.Value, err)
    67  		}
    68  		return specexpr.Array{Elem: elem, Len: specexpr.Int(n)}, nil
    69  
    70  	case *ast.ParenExpr:
    71  		return parseTypeExpr(t.X)
    72  
    73  	default:
    74  		return nil, fmt.Errorf("unexpected type expression: %T", expr)
    75  	}
    76  }
    77  

View as plain text