diff --git a/actr/chunk.go b/actr/chunk.go index 3a1774ee..e2a012d2 100644 --- a/actr/chunk.go +++ b/actr/chunk.go @@ -23,6 +23,11 @@ func (model Model) LookupChunk(chunkName string) *Chunk { return nil } +// SlotName returns the name of the slot given the index. +func (c Chunk) SlotName(index int) (str string) { + return c.SlotNames[index] +} + func (c Chunk) IsInternal() bool { return c.Name[0] == '_' } diff --git a/actr/production.go b/actr/production.go index 984914bd..c713c9a1 100644 --- a/actr/production.go +++ b/actr/production.go @@ -6,12 +6,21 @@ type Production struct { Name string Description *string // optional description to output as a comment in the generated code + VarIndexMap map[string]VarIndex // track the buffer and slot name each variable refers to + Matches []*Match DoStatements []*Statement AMODLineNumber int // line number in the amod file of the this production } +// VarIndex is used to track which buffer slot a variable refers to +type VarIndex struct { + Var string + Buffer BufferInterface + SlotName string +} + type Match struct { Buffer BufferInterface Pattern *Pattern diff --git a/amod/amod.go b/amod/amod.go index 58230311..62285911 100644 --- a/amod/amod.go +++ b/amod/amod.go @@ -369,6 +369,7 @@ func addProductions(model *actr.Model, log *amodlog.Log, productions *production prod := actr.Production{ Name: production.Name, Description: production.Description, + VarIndexMap: map[string]actr.VarIndex{}, AMODLineNumber: production.Pos.Line, } @@ -384,12 +385,31 @@ func addProductions(model *actr.Model, log *amodlog.Log, productions *production } name := item.Name - - prod.Matches = append(prod.Matches, &actr.Match{ + match := actr.Match{ Buffer: model.LookupBuffer(name), Pattern: pattern, - }) + } + + prod.Matches = append(prod.Matches, &match) + for index, slot := range pattern.Slots { + item := slot.Items[0] + + if item.Var == nil { + continue + } + + // Track the buffer and slot name the variable refers to + varItem := *item.Var + if _, ok := prod.VarIndexMap[varItem]; !ok { + varIndex := actr.VarIndex{ + Var: varItem, + Buffer: match.Buffer, + SlotName: pattern.Chunk.SlotName(index), + } + prod.VarIndexMap[varItem] = varIndex + } + } } if production.Do.Statements != nil { diff --git a/amod/validate.go b/amod/validate.go index a3a0b6b5..a26d1157 100644 --- a/amod/validate.go +++ b/amod/validate.go @@ -177,7 +177,7 @@ func validateSetStatement(set *setStatement, model *actr.Model, log *amodlog.Log for slotIndex, slot := range set.Pattern.Slots { if len(slot.Items) > 1 { - log.Error(set.Pattern.Pos.Line, "cannot set '%s.%v' to compound var in production '%s'", bufferName, chunk.SlotNames[slotIndex], production.Name) + log.Error(set.Pattern.Pos.Line, "cannot set '%s.%v' to compound var in production '%s'", bufferName, chunk.SlotName(slotIndex), production.Name) err = CompileError{} continue @@ -193,8 +193,7 @@ func validateSetStatement(set *setStatement, model *actr.Model, log *amodlog.Log match := production.LookupMatchByVariable(varItem) if match == nil { if varItem == "?" { - - log.Error(set.Pattern.Pos.Line, "cannot set '%s.%v' to anonymous var ('?') in production '%s'", bufferName, chunk.SlotNames[slotIndex], production.Name) + log.Error(set.Pattern.Pos.Line, "cannot set '%s.%v' to anonymous var ('?') in production '%s'", bufferName, chunk.SlotName(slotIndex), production.Name) } else { log.Error(set.Pattern.Pos.Line, "set statement variable '%s' not found in matches for production '%s'", varItem, production.Name) }