// allocPrepare checks if the provided types are all allocable, and insert // implicit type casts if needed. Only literay expression list needs alloc // prepare. func allocPrepare( b *builder, toks []*lex8.Token, lst *tast.ExprList, ) *tast.ExprList { ret := tast.NewExprList() for i, tok := range toks { e := lst.Exprs[i] t := e.Type() if types.IsNil(t) { b.Errorf(tok.Pos, "cannot infer type from nil for %q", tok.Lit) return nil } if v, ok := types.NumConst(t); ok { e = constCastInt(b, tok.Pos, v, e) if e == nil { return nil } } if !types.IsAllocable(t) { b.Errorf(tok.Pos, "cannot allocate for %s", t) return nil } ret.Append(e) } return ret }
func buildVarDecl(b *builder, d *ast.VarDecl) *tast.Define { ids := d.Idents.Idents if d.Eq != nil { right := b.buildExpr(d.Exprs) if right == nil { return nil } if d.Type == nil { ret := define(b, ids, right, d.Eq) if ret == nil { return nil } return ret } tdest := b.buildType(d.Type) if tdest == nil { return nil } if !types.IsAllocable(tdest) { pos := ast.ExprPos(d.Type) b.Errorf(pos, "%s is not allocatable", tdest) return nil } // assignable check ts := right.R().TypeList() for _, t := range ts { if !types.CanAssign(tdest, t) { b.Errorf(d.Eq.Pos, "cannot assign %s to %s", t, tdest) return nil } } // cast literal expression lists // after the casting, all types should be matching to tdest if exprList, ok := tast.MakeExprList(right); ok { exprList = varDeclPrepare(b, ids, exprList, tdest) if exprList == nil { return nil } right = exprList } syms := declareVars(b, ids, tdest, false) if syms == nil { return nil } return &tast.Define{syms, right} } if d.Type == nil { panic("type missing") } t := b.buildType(d.Type) if t == nil { return nil } syms := declareVars(b, ids, t, false) if syms == nil { return nil } return &tast.Define{syms, nil} }