Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}