8 // Index represents an indexing operation into another data structure
15 func (n *Index) Accept(v Visitor) Node {
16 n.Target = n.Target.Accept(v)
17 n.Key = n.Key.Accept(v)
21 func (n *Index) Pos() Pos {
25 func (n *Index) String() string {
26 return fmt.Sprintf("Index(%s, %s)", n.Target, n.Key)
29 func (n *Index) Type(s Scope) (Type, error) {
30 variableAccess, ok := n.Target.(*VariableAccess)
32 return TypeInvalid, fmt.Errorf("target is not a variable")
35 variable, ok := s.LookupVar(variableAccess.Name)
37 return TypeInvalid, fmt.Errorf("unknown variable accessed: %s", variableAccess.Name)
40 switch variable.Type {
42 return n.typeList(variable, variableAccess.Name)
44 return n.typeMap(variable, variableAccess.Name)
46 return TypeInvalid, fmt.Errorf("invalid index operation into non-indexable type: %s", variable.Type)
50 func (n *Index) typeList(variable Variable, variableName string) (Type, error) {
51 // We assume type checking has already determined that this is a list
52 list := variable.Value.([]Variable)
54 return VariableListElementTypesAreHomogenous(variableName, list)
57 func (n *Index) typeMap(variable Variable, variableName string) (Type, error) {
58 // We assume type checking has already determined that this is a map
59 vmap := variable.Value.(map[string]Variable)
61 return VariableMapValueTypesAreHomogenous(variableName, vmap)
64 func reportTypes(typesFound map[Type]struct{}) string {
65 stringTypes := make([]string, len(typesFound))
67 for k, _ := range typesFound {
68 stringTypes[0] = k.String()
71 return strings.Join(stringTypes, ", ")
74 func (n *Index) GoString() string {
75 return fmt.Sprintf("*%#v", *n)