/
ValueGrammar.scala
108 lines (97 loc) · 3.61 KB
/
ValueGrammar.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* Copyright 2009-2016 EPFL, Lausanne */
package leon
package grammars
import leon.purescala.Common.FreshIdentifier
import leon.purescala.Definitions.ValDef
import purescala.Types._
import purescala.Expressions._
/** A grammar of values (ground terms) */
case object ValueGrammar extends SimpleExpressionGrammar {
def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = t match {
case BooleanType =>
List(
terminal(BooleanLiteral(true), Tags.One),
terminal(BooleanLiteral(false), Tags.Zero)
)
case Int32Type =>
List(
terminal(IntLiteral(0), Tags.Zero),
terminal(IntLiteral(1), Tags.One),
terminal(IntLiteral(5), Tags.Constant),
terminal(IntLiteral(-1), Tags.Constant, 3),
terminal(IntLiteral(2), Tags.Constant, 3),
terminal(IntLiteral(3), Tags.Constant, 3),
terminal(IntLiteral(-2), Tags.Constant, 5),
terminal(IntLiteral(4), Tags.Constant, 5),
terminal(IntLiteral(10), Tags.Constant, 5)
)
case IntegerType =>
List(
terminal(InfiniteIntegerLiteral(0), Tags.Zero),
terminal(InfiniteIntegerLiteral(1), Tags.One),
terminal(InfiniteIntegerLiteral(5), Tags.Constant),
terminal(InfiniteIntegerLiteral(-1), Tags.Constant, 3),
terminal(InfiniteIntegerLiteral(2), Tags.Constant, 3),
terminal(InfiniteIntegerLiteral(3), Tags.Constant, 3),
terminal(InfiniteIntegerLiteral(-2), Tags.Constant, 5),
terminal(InfiniteIntegerLiteral(4), Tags.Constant, 5),
terminal(InfiniteIntegerLiteral(10), Tags.Constant, 5)
)
case CharType =>
List(
terminal(CharLiteral('a'), Tags.Constant),
terminal(CharLiteral('b'), Tags.Constant),
terminal(CharLiteral('0'), Tags.Constant)
)
case RealType =>
List(
terminal(FractionalLiteral(0, 1), Tags.Zero),
terminal(FractionalLiteral(1, 1), Tags.One),
terminal(FractionalLiteral(-1, 2), Tags.Constant),
terminal(FractionalLiteral(555, 42), Tags.Constant)
)
case StringType =>
List(
terminal(StringLiteral(""), Tags.Constant),
terminal(StringLiteral("a"), Tags.Constant),
terminal(StringLiteral("foo"), Tags.Constant),
terminal(StringLiteral("bar"), Tags.Constant),
terminal(StringLiteral("b"), Tags.Constant, 3),
terminal(StringLiteral("c"), Tags.Constant, 3),
terminal(StringLiteral("d"), Tags.Constant, 3)
)
case tp: TypeParameter =>
List(
terminal(GenericValue(tp, 0))
)
case TupleType(stps) =>
List(
nonTerminal(stps, Tuple, Tags.Constructor(stps.isEmpty))
)
case cct: CaseClassType =>
List(
nonTerminal(cct.fields.map(_.getType), CaseClass(cct, _), Tags.tagOf(cct))
)
case act: AbstractClassType =>
act.knownCCDescendants.map { cct =>
nonTerminal(cct.fields.map(_.getType), CaseClass(cct, _), Tags.tagOf(cct))
}
case st @ SetType(base) =>
List(
terminal(FiniteSet(Set(), base), Tags.Constant),
nonTerminal(List(base), { elems => FiniteSet(elems.toSet, base) }, Tags.Constructor(isTerminal = false)),
nonTerminal(List(base, base), { elems => FiniteSet(elems.toSet, base) }, Tags.Constructor(isTerminal = false))
)
case UnitType =>
List(
terminal(UnitLiteral(), Tags.Constant)
)
case FunctionType(from, to) =>
val args = from map (tp => ValDef(FreshIdentifier("x", tp, true)))
List(
nonTerminal(Seq(to), { case Seq(e) => Lambda(args, e) })
)
case _ =>
Nil
}
}