1+ package org .combinators
2+
3+ import com .github .javaparser .ast .expr .DoubleLiteralExpr
4+ import org .combinators .ep .domain .abstractions .TypeRep
5+ import org .combinators .ep .generator .Command .Generator
6+ import org .combinators .ep .generator .NameProvider
7+ import org .combinators .ep .generator .paradigm .{AnyParadigm , ObjectOriented }
8+ import org .combinators .ep .generator .paradigm .ffi .{Arithmetic , Assertions , Booleans , Equality , RealArithmetic }
9+
10+ // Expression Tree
11+ sealed abstract class Condition (val label : String )
12+
13+ final case class True () extends Condition (label = " true" )
14+ final case class False () extends Condition (label = " false" )
15+
16+ final case class LT (left: Formula , right: Formula ) extends Condition (label = " lt" )
17+ final case class LE (left: Formula , right: Formula ) extends Condition (label = " le" )
18+
19+ final case class Not (inner: Condition ) extends Condition (label = " not" )
20+ final case class And (left: Condition , right: Condition ) extends Condition (label = " and" )
21+ final case class Or (left: Condition , right: Condition ) extends Condition (label = " or" )
22+
23+ // Operations
24+ abstract class Formula (val label : String )
25+ case class ConstantFormula (value: Double , actualType: TypeRep ) extends Formula (label= " const" )
26+ case class VariableFormula (name: String , actualType: TypeRep ) extends Formula (label= " var" )
27+ final case class Pi () extends Formula (label = " pi" )
28+ final case class Euler () extends Formula (label = " euler" )
29+
30+ case class DoubleToInt (inner: Formula ) extends Formula (" cast" )
31+
32+ case class Sqrt (inner: Formula ) extends Formula (label = " sqrt" )
33+ case class Sin (inner: Formula ) extends Formula (label = " sin" )
34+ case class Cos (inner: Formula ) extends Formula (label = " cos" )
35+ case class Floor (inner: Formula ) extends Formula (label = " floor" )
36+ case class Abs (inner: Formula ) extends Formula (label = " abs" )
37+
38+ case class Add (left: Formula , right: Formula ) extends Formula (" add" )
39+ case class Sub (left: Formula , right: Formula ) extends Formula (" sub" )
40+ case class Mult (left: Formula , right: Formula ) extends Formula (" mult" )
41+ case class Div (left: Formula , right: Formula ) extends Formula (" div" )
42+ case class Mod (leftt: Formula , right: Formula ) extends Formula (" mod" )
43+ case class Pow (left: Formula , right: Formula ) extends Formula (" pow" )
44+ case class Log (left: Formula , right: Formula ) extends Formula (" log" )
45+
46+ case class UnaryFunctionCall (name: String , inner: Formula ) extends Formula (label= " function" )
47+ case class BinaryFunctionCall (name: String , left: Formula , right: Formula ) extends Formula (label= " function" )
48+
49+ class Structure (val conditions : Seq [(Condition , Formula )], val default : Formula ) {
50+
51+ }
52+
53+ trait Expansion {
54+ val paradigm : AnyParadigm
55+ val names : NameProvider [paradigm.syntax.Name ]
56+
57+ val ffiArithmetic : Arithmetic .WithBase [paradigm.MethodBodyContext , paradigm.type , Int ]
58+ val ffiRealArithmetic : RealArithmetic .WithBase [paradigm.MethodBodyContext , paradigm.type , Double ]
59+ val ffiBooleans : Booleans .WithBase [paradigm.MethodBodyContext , paradigm.type ]
60+ val ffiAssertions : Assertions .WithBase [paradigm.MethodBodyContext , paradigm.type ]
61+ val ffiEquality : Equality .WithBase [paradigm.MethodBodyContext , paradigm.type ]
62+
63+ // must be provided
64+ def find_method_recursive (name: paradigm.syntax.Name ) : Generator [paradigm.MethodBodyContext , paradigm.syntax.Expression ]
65+ def cast_double_to_int (inner: paradigm.syntax.Expression ) : Generator [paradigm.MethodBodyContext , paradigm.syntax.Expression ]
66+
67+
68+ def expand (f: Formula ): Generator [paradigm.MethodBodyContext , paradigm.syntax.Expression ] = {
69+ import paradigm .methodBodyCapabilities ._
70+
71+ f match {
72+
73+ case DoubleToInt (inner) =>
74+ for {
75+ in <- expand(inner)
76+ res <- cast_double_to_int(in)
77+ } yield res
78+
79+ case ConstantFormula (value, TypeRep .Int ) =>
80+ for {
81+ value <- paradigm.methodBodyCapabilities.reify(TypeRep .Int , value.intValue())
82+ } yield value
83+
84+ case ConstantFormula (value, TypeRep .Double ) =>
85+ for {
86+ value <- paradigm.methodBodyCapabilities.reify(TypeRep .Double , value)
87+ } yield value
88+
89+ // this works for Java. NOT for Scala
90+ case VariableFormula (name, typeRep) =>
91+ for {
92+ args <- getArguments()
93+
94+ specific = args.filter(triple => triple._1.toString.equals(name)).head
95+ } yield specific._3
96+
97+ case Pi () =>
98+ for {
99+ value <- paradigm.methodBodyCapabilities.reify(TypeRep .Double , math.Pi )
100+ } yield value
101+
102+ case Euler () =>
103+ for {
104+ value <- paradigm.methodBodyCapabilities.reify(TypeRep .Double , math.E )
105+ } yield value
106+
107+ case Sqrt (inner) =>
108+ for {
109+ in <- expand(inner)
110+ value <- ffiRealArithmetic.realArithmeticCapabilities.sqrt(in)
111+ } yield value
112+
113+ case Sin (inner) =>
114+ for {
115+ in <- expand(inner)
116+ value <- ffiRealArithmetic.realArithmeticCapabilities.sin(in)
117+ } yield value
118+
119+ case Cos (inner) =>
120+ for {
121+ in <- expand(inner)
122+ value <- ffiRealArithmetic.realArithmeticCapabilities.cos(in)
123+ } yield value
124+
125+ case Floor (inner) =>
126+ for {
127+ in <- expand(inner)
128+ value <- ffiRealArithmetic.realArithmeticCapabilities.floor(in)
129+ } yield value
130+
131+ case Abs (inner) =>
132+ for {
133+ in <- expand(inner)
134+ value <- ffiRealArithmetic.realArithmeticCapabilities.abs(in)
135+ } yield value
136+
137+ case Add (left, right) =>
138+ for {
139+ leftF <- expand(left)
140+ rightF <- expand(right)
141+ value <- ffiArithmetic.arithmeticCapabilities.add(leftF, rightF)
142+ } yield value
143+
144+ case Sub (left, right) =>
145+ for {
146+ leftF <- expand(left)
147+ rightF <- expand(right)
148+ value <- ffiArithmetic.arithmeticCapabilities.sub(leftF, rightF)
149+ } yield value
150+
151+ case Mult (left, right) =>
152+ for {
153+ leftF <- expand(left)
154+ rightF <- expand(right)
155+ value <- ffiArithmetic.arithmeticCapabilities.mult(leftF, rightF)
156+ } yield value
157+
158+ case Div (left, right) =>
159+ for {
160+ leftF <- expand(left)
161+ rightF <- expand(right)
162+ value <- ffiArithmetic.arithmeticCapabilities.div(leftF, rightF)
163+ } yield value
164+
165+ case Mod (left, right) =>
166+ for {
167+ leftF <- expand(left)
168+ rightF <- expand(right)
169+ value <- ffiArithmetic.arithmeticCapabilities.mod(leftF, rightF)
170+ } yield value
171+
172+ case Pow (left, right) =>
173+ for {
174+ leftF <- expand(left)
175+ rightF <- expand(right)
176+ value <- ffiRealArithmetic.realArithmeticCapabilities.pow(leftF, rightF)
177+ } yield value
178+
179+ case Log (left, right) =>
180+ for {
181+ leftF <- expand(left)
182+ rightF <- expand(right)
183+ value <- ffiRealArithmetic.realArithmeticCapabilities.log(leftF, rightF)
184+ } yield value
185+
186+ case UnaryFunctionCall (name, inner) =>
187+ for {
188+ func <- find_method_recursive(names.mangle(name))
189+ in <- expand(inner)
190+ fres <- apply(func, Seq (in))
191+ } yield fres
192+
193+ case BinaryFunctionCall (name, left, right) =>
194+ for {
195+ func <- find_method_recursive(names.mangle(name))
196+ leftF <- expand(left)
197+ rightF <- expand(right)
198+ fres <- apply(func, Seq (leftF, rightF))
199+ } yield fres
200+ }
201+ }
202+
203+ def expand (cond: Condition ): Generator [paradigm.MethodBodyContext , paradigm.syntax.Expression ] = {
204+ import paradigm .projectCapabilities ._
205+
206+ cond match {
207+ case True () =>
208+ for {
209+ res <- ffiBooleans.booleanCapabilities.trueExp
210+ } yield res
211+
212+ case False () =>
213+ for {
214+ res <- ffiBooleans.booleanCapabilities.falseExp
215+ } yield res
216+
217+ case Not (inner) =>
218+ for {
219+ in <- expand(inner)
220+ res <- ffiBooleans.booleanCapabilities.not(in)
221+ } yield res
222+
223+ case And (left, right) =>
224+ for {
225+ leftExp <- expand(left)
226+ rightExp <- expand(right)
227+ res <- ffiBooleans.booleanCapabilities.and(Seq (leftExp, rightExp))
228+ } yield res
229+
230+ case Or (left, right) =>
231+ for {
232+ leftExp <- expand(left)
233+ rightExp <- expand(right)
234+ res <- ffiBooleans.booleanCapabilities.or(Seq (leftExp, rightExp))
235+ } yield res
236+
237+ case LT (left, right) =>
238+ for {
239+ leftExp <- expand(left)
240+ rightExp <- expand(right)
241+ res <- ffiArithmetic.arithmeticCapabilities.lt(leftExp, rightExp)
242+ } yield res
243+
244+ case LE (left, right) =>
245+ for {
246+ leftExp <- expand(left)
247+ rightExp <- expand(right)
248+ res <- ffiArithmetic.arithmeticCapabilities.le(leftExp, rightExp)
249+ } yield res
250+
251+ case _ => ???
252+ }
253+ }
254+
255+
256+ }
0 commit comments