Skip to content

Commit

Permalink
{amod} Be more specific about arg types to catch things during parsing (
Browse files Browse the repository at this point in the history
#383)

Setting up for printing by buffer slot
  • Loading branch information
asmaloney authored Aug 17, 2023
1 parent c3cf935 commit 38629f7
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 131 deletions.
107 changes: 54 additions & 53 deletions amod/amod.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"reflect"
"slices"
"strconv"
"strings"

"github.com/alecthomas/participle/v2"
Expand Down Expand Up @@ -559,7 +558,7 @@ func addProductions(model *actr.Model, log *issueLog, productions *productionSec
actrConstraint := actr.Constraint{
LHS: &expr.LHS,
Comparison: comparison,
RHS: convertArg(expr.RHS),
RHS: convertWhenArg(expr.RHS),
}

// Add the constraint on the pattern var
Expand Down Expand Up @@ -662,30 +661,6 @@ func findModuleStateMatch(prod *actr.Production, bufferName string) *actr.Match
return nil
}

func argToKeyValue(key string, a *arg) *keyvalue.KeyValue {
value := keyvalue.Value{}

switch {
case a.Nil != nil:
nilStr := "nil"
value.Str = &nilStr
case a.Var != nil:
value.Str = a.Var
case a.ID != nil:
value.Str = a.ID
case a.Str != nil:
value.Str = a.Str
case a.Number != nil:
num, _ := strconv.ParseFloat(*a.Number, 64)
value.Number = &num
}

return &keyvalue.KeyValue{
Key: key,
Value: value,
}
}

func fieldToKeyValue(f *field) *keyvalue.KeyValue {
value := f.Value

Expand Down Expand Up @@ -794,52 +769,57 @@ func createSetStatement(model *actr.Model, log *issueLog, set *setStatement, pro
return nil, err
}

buffer := model.LookupBuffer(set.BufferName)
bufferName := set.BufferRef.BufferName
buffer := model.LookupBuffer(bufferName)

s := actr.Statement{Set: &actr.SetStatement{
Buffer: buffer,
}}
createNewStatement := true
setStatement := production.LookupSetStatementByBuffer(set.BufferName)
setStatement := production.LookupSetStatementByBuffer(bufferName)
if setStatement != nil {
// If we found one, use its set statement
createNewStatement = false
s.Set = setStatement
}

if set.Slot != nil {
if set.BufferRef.SlotName != nil {
bufferName := buffer.Name()

// find slot index in chunk
match := production.LookupMatchByBuffer(bufferName)

s.Set.Chunk = match.Pattern.Chunk

slotName := *set.Slot
slotName := *set.BufferRef.SlotName
index := match.Pattern.Chunk.SlotIndex(slotName)
value := &actr.Value{}

switch {
case set.Value.Arg != nil:
valueArg := set.Value.Arg
switch {
case valueArg.Var != nil:
varName := strings.TrimPrefix(*valueArg.Var, "?")
value.Var = &varName

case valueArg.Number != nil:
value.Number = valueArg.Number

case valueArg.Str != nil:
value.Str = valueArg.Str
}

case set.Value.Nil != nil:
value.Nil = set.Value.Nil

case set.Value.Var != nil:
varName := strings.TrimPrefix(*set.Value.Var, "?")
value.Var = &varName

case set.Value.ID != nil:
value.ID = set.Value.ID

case set.Value.Number != nil:
value.Number = set.Value.Number

case set.Value.Str != nil:
value.Str = set.Value.Str

}

newSlot := &actr.SetSlot{
Name: *set.Slot,
Name: slotName,
SlotIndex: index,
Value: value,
}
Expand Down Expand Up @@ -876,7 +856,7 @@ func createRecallStatement(model *actr.Model, log *issueLog, recall *recallState

if recall.With != nil {
for _, param := range *recall.With.Expressions {
value := convertArg(param.Value)
value := convertWithArg(param.Value)
requestParameters[param.Param] = value.String()
}
}
Expand Down Expand Up @@ -915,7 +895,7 @@ func createPrintStatement(model *actr.Model, log *issueLog, print *printStatemen

p := actr.PrintStatement{}
if print.Args != nil {
p.Values = convertArgs(print.Args)
p.Values = convertPrintArgs(print.Args)
}

s := actr.Statement{Print: &p}
Expand All @@ -931,15 +911,9 @@ func convertArg(v *arg) (actrValue *actr.Value) {
actrValue = &actr.Value{}

switch {
case v.Nil != nil:
actrValue.Nil = v.Nil

case v.Var != nil:
actrValue.Var = v.Var

case v.ID != nil:
actrValue.ID = v.ID

case v.Str != nil:
actrValue.Str = v.Str

Expand All @@ -950,13 +924,40 @@ func convertArg(v *arg) (actrValue *actr.Value) {
return
}

func convertArgs(args []*arg) *[]*actr.Value {
func convertWhenArg(w *whenArg) *actr.Value {
if w.Nil != nil {
return &actr.Value{Nil: w.Nil}
}

return convertArg(w.Arg)
}

func convertWithArg(w *withArg) *actr.Value {
if w.Nil != nil {
return &actr.Value{Nil: w.Nil}
} else if w.ID != nil {
return &actr.Value{ID: w.ID}
}

return convertArg(w.Arg)
}

func convertPrintArg(p *printArg) *actr.Value {
if p.Arg == nil {
return nil
}

return convertArg(p.Arg)
}

func convertPrintArgs(args []*printArg) *[]*actr.Value {
actrValues := []*actr.Value{}

for _, v := range args {
newValue := convertArg(v)

actrValues = append(actrValues, newValue)
newValue := convertPrintArg(v)
if newValue != nil {
actrValues = append(actrValues, newValue)
}
}

return &actrValues
Expand Down
79 changes: 74 additions & 5 deletions amod/amod_productions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,28 @@ func Example_productionWhenClauseCompareNil() {
// Output:
}

func Example_productionWhenClauseCompareID() {
generateToStdout(`
~~ model ~~
name: Test
~~ config ~~
chunks { [foo: thing] }
~~ init ~~
~~ productions ~~
start {
match {
goal [foo: ?blat] when ( ?blat == bar )
}
do {
print ?blat
stop
}
}`)

// Output:
// ERROR: unexpected token "bar" (expected WhenArg ")") (line 10, col 37)
}

func Example_productionWhenClauseNegatedAndConstrained() {
generateToStdout(`
~~ model ~~
Expand Down Expand Up @@ -398,8 +420,7 @@ func Example_productionSetStatementNonBuffer() {
}`)

// Output:
// ERROR: buffer 'foo' not found (line 10, col 11)
// ERROR: match buffer 'foo' not found in production 'start' (line 10, col 11)
// ERROR: buffer "foo" not found in model (line 10, col 11)
}

func Example_productionSetStatementNonBuffer2() {
Expand Down Expand Up @@ -801,7 +822,38 @@ func Example_productionPrintStatement3() {
// Output:
}

func Example_productionPrintStatementInvalidID() {
func Example_productionPrintStatementBuffer() {
generateToStdout(`
~~ model ~~
name: Test
~~ config ~~
~~ init ~~
~~ productions ~~
start {
match { buffer_state retrieval empty }
do { print goal }
}`)

// Output:
}

func Example_productionPrintStatementBufferSlot() {
generateToStdout(`
~~ model ~~
name: Test
~~ config ~~
chunks { [foo: thing1 thing2] }
~~ init ~~
~~ productions ~~
start {
match { goal [foo: * *] }
do { print goal.thing1 }
}`)

// Output:
}

func Example_productionPrintStatementInvalidBuffer() {
generateToStdout(`
~~ model ~~
name: Test
Expand All @@ -814,7 +866,24 @@ func Example_productionPrintStatementInvalidID() {
}`)

// Output:
// ERROR: cannot use ID 'fooID' in print statement (line 9, col 13)
// ERROR: buffer "fooID" not found in model (line 9, col 13)
}

func Example_productionPrintStatementInvalidBufferSlot() {
generateToStdout(`
~~ model ~~
name: Test
~~ config ~~
chunks { [foo: thing1 thing2] }
~~ init ~~
~~ productions ~~
start {
match { goal [foo: * *] }
do { print goal.blat }
}`)

// Output:
// ERROR: slot 'blat' does not exist in chunk type 'foo' for match buffer 'goal' in production 'start' (line 10, col 18)
}

func Example_productionPrintStatementInvalidNil() {
Expand All @@ -830,7 +899,7 @@ func Example_productionPrintStatementInvalidNil() {
}`)

// Output:
// ERROR: cannot use nil in print statement (line 9, col 13)
// ERROR: unexpected token "nil" (expected "}") (line 9, col 13)
}

func Example_productionPrintStatementInvalidVar() {
Expand Down
Loading

0 comments on commit 38629f7

Please sign in to comment.