// ident type checks an identifier. func (c *checker) ident(x *operand, e *ast.Ident, silent bool) { x.mode = invalid x.expr = e _, obj := c.scope.LookupParent(Ord, e.Name, scan.NoPos) if obj == nil { _, obj = c.scope.LookupParent(Fwd, e.Name, scan.NoPos) } if obj == nil { if !silent { c.errorf(e.Span().Start, "undeclared name: %s", e.Name) } return } c.recordUse(e, obj) typ := obj.Type() switch obj := obj.(type) { case *Const: if typ == Typ[Invalid] { return } x.val = obj.val x.mode = constant_ case *Var: if typ == Typ[Invalid] { return } array, isArray := typ.(*Array) if isArray { typ = NewPointer(array.Elem(), array) } x.mode = variable case *Fwrd: if typ == Typ[Invalid] { return } x.mode = variable case *Func: if typ == Typ[Invalid] { return } x.mode = value default: panic(fmt.Sprintf("unknown ident type: %T", obj)) } x.typ = typ }
// variable looks up a variable given its identifier. func (c *compiler) variable(d *ast.Ident, m map[*ast.Ident]types.Object) (*types.Var, bool) { pos := d.Span().Start obj, found := m[d] if !found { c.errorf(pos, "no type information for %s", d.Name) return nil, false } v, ok := obj.(*types.Var) if !ok { c.errorf(pos, "not a valid variable") } switch v.Type() { case types.Typ[types.Short], types.Typ[types.Long], types.Typ[types.Float], types.Typ[types.Double], types.Typ[types.Bool], types.Typ[types.Complex]: c.errorf(pos, "unsupported type %s for variable", v.Type()) } return v, true }