Skip to content

Commit

Permalink
Support an important part of Verbatim.
Browse files Browse the repository at this point in the history
  • Loading branch information
corywalker committed Jul 14, 2017
1 parent 63221bc commit 8906ef5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
14 changes: 14 additions & 0 deletions expreduce/builtin_pattern.go
Expand Up @@ -577,5 +577,19 @@ func GetPatternDefinitions() (defs []Definition) {
&SameTest{"True", "MatchQ[x^x, (x^x)^Optional[exp_]]"},
},
})
defs = append(defs, Definition{
Name: "Verbatim",
Usage: "`Verbatim[expr]` matches `expr` exactly, even if it has patterns.",
// Not fully supported. Don't document
OmitDocumentation: true,
Tests: []TestInstruction{
&SameTest{"{{a,b},{b,c},{c,d}}", "ReplaceList[a+b+c+d,Verbatim[Plus][___,x_,y_,___]->{x,y}]"},
&SameTest{"{}", "ReplaceList[a+b+c+d,Verbatim[Times][___,x_,y_,___]->{x,y}]"},
&SameTest{"{}", "ReplaceList[a+b*c+d,Verbatim[Times][___,x_,y_,___]->{x,y}]"},
&SameTest{"{{a,b},{b,c},{c,d}}", "ReplaceList[foo[a,b,c,d],Verbatim[foo][___,x_,y_,___]->{x,y}]"},
&SameTest{"{{a,b},{b,c},{c,d}}", "ReplaceList[(a+b)[a,b,c,d],Verbatim[a+b][___,x_,y_,___]->{x,y}]"},
&SameTest{"{}", "ReplaceList[(a+b)[a,b,c,d],Verbatim[a+_][___,x_,y_,___]->{x,y}]"},
},
})
return
}
16 changes: 16 additions & 0 deletions expreduce/ex_expression.go
Expand Up @@ -40,6 +40,22 @@ func headExAssertion(ex Ex, head Ex, cl *CASLogger) (*Expression, bool) {
return NewEmptyExpression(), false
}

func OperatorAssertion(ex Ex, opHead string) (*Expression, *Expression, bool) {
expr, isExpr := ex.(*Expression)
if isExpr {
headExpr, headIsExpr := expr.Parts[0].(*Expression)
if headIsExpr {
sym, isSym := headExpr.Parts[0].(*Symbol)
if isSym {
if sym.Name == opHead {
return expr, headExpr, true
}
}
}
}
return NewEmptyExpression(), NewEmptyExpression(), false
}

func tryReturnValue(e Ex) (Ex, bool) {
asReturn, isReturn := HeadAssertion(e, "Return")
if !isReturn {
Expand Down
17 changes: 16 additions & 1 deletion expreduce/matchq.go
Expand Up @@ -116,6 +116,19 @@ func NewMatchIter(a Ex, b Ex, pm *PDManager, es *EvalState) (matchIter, bool) {
aExpression, aIsExpression := a.(*Expression)
bExpression, bIsExpression := b.(*Expression)

// Special case for the operator form of Verbatim
forceOrdered := false
verbatimOp, opExpr, isVerbatimOp := OperatorAssertion(b, "Verbatim")
if aIsExpression && isVerbatimOp {
if len(opExpr.Parts) == 2 {
if IsSameQ(aExpression.Parts[0], opExpr.Parts[1], &es.CASLogger) {
b = NewExpression(append([]Ex{opExpr.Parts[1]}, verbatimOp.Parts[1:]...))
bExpression, bIsExpression = b.(*Expression)
forceOrdered = true
}
}
}

// This initial value is just a randomly chosen placeholder
// TODO, convert headStr to symbol type, have Ex implement getHead() Symbol
headStr := "Unknown"
Expand Down Expand Up @@ -211,7 +224,9 @@ func NewMatchIter(a Ex, b Ex, pm *PDManager, es *EvalState) (matchIter, bool) {
}
}

nomi, ok := NewSequenceMatchIter(aExpression.Parts[startI:], bExpression.Parts[startI:], attrs.Orderless, attrs.Flat, sequenceHead, pm, es)
isOrderless := attrs.Orderless && !forceOrdered
isFlat := attrs.Flat && !forceOrdered
nomi, ok := NewSequenceMatchIter(aExpression.Parts[startI:], bExpression.Parts[startI:], isOrderless, isFlat, sequenceHead, pm, es)
if !ok {
return &dummyMatchIter{false, pm, true}, true
}
Expand Down

0 comments on commit 8906ef5

Please sign in to comment.