Skip to content

Commit 43d3aa3

Browse files
author
heineman
committed
Completed Height() implementation (I1, J8, M9) all functional.
Integrated dispatch into OperationAsClass. Issue was in implement() oddly enough.
1 parent 889a155 commit 43d3aa3

File tree

7 files changed

+176
-152
lines changed

7 files changed

+176
-152
lines changed

Diff for: TODO.txt

-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ Add exceptions to newScala
1616

1717
Make CoGen stand alone
1818

19-
M9 & J8 & M2_ABS needs functional implementation of height. Should be straightforward, though I cannot figure
20-
out how to set up the match and patterns!
21-
2219
Note that Java equality in methods uses the .equals() which is a problem with primitive types. Thoughts?
2320

2421
Trees that grow

Diff for: core/src/main/scala/org/combinators/ep/approach/oo/RuntimeDispatch.scala

+12-46
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
165165
addMethod(names.mangle(names.instanceNameOf(op)), makeBody)
166166
}
167167

168-
169168
/**
170169
* Each operation is placed in its own class, with a 'visit' method for each known data type.
171170
*
@@ -199,7 +198,7 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
199198

200199
for {
201200
// this will ultimately invoke makeTypeCaseImplementation for all necessary typecases
202-
_ <- operationClass(names.addPrefix("_", names.mangle(names.instanceNameOf(op))), op, domain, domain.typeCases, domain.baseDataType, domainSpecific)
201+
_ <- operationClass(names.addPrefix("_", names.mangle(names.instanceNameOf(op))), op, domain, domain.flatten.typeCases.distinct, domain.baseDataType, domainSpecific)
203202

204203
returnTpe <- toTargetLanguageType(op.returnType)
205204
_ <- resolveAndAddImport(returnTpe)
@@ -252,6 +251,15 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
252251
addClassToProject( makeClass, names.mangle(names.conceptNameOf(tpe)))
253252
}
254253

254+
def targetExp : Generator[MethodBodyContext, Expression] = {
255+
import paradigm.methodBodyCapabilities._
256+
import ooParadigm.methodBodyCapabilities._
257+
258+
for {
259+
expRef <- getArguments().map(_.head._3)
260+
} yield expRef
261+
}
262+
255263
/** Make a method body for each operation, which dispatches to appropriate method
256264
*
257265
* {{{
@@ -283,9 +291,8 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
283291
_ <- resolveAndAddImport(ptype)
284292
_ <- makeOperationSignature(ptype, op)
285293

286-
result <- dispatchImplementation(tpe, tpeCase, op, model, domainSpecific)
294+
result <- completeImplementationFromParameters(tpe, tpeCase, op, model, domainSpecific, target=targetExp, attributeAccess = attributeDispatchAccess)
287295
} yield result
288-
289296
}
290297

291298
/**
@@ -305,47 +312,6 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
305312
} yield getterCall
306313
}
307314

308-
/**
309-
* Have to do it this way (copied from OperationAsClass) because FOR SOME REASON, if we pass in a model with the request, it always seems to fail
310-
*/
311-
def dispatchImplementation(tpe: DataType, tpeCase: DataTypeCase, op: Operation, domain: GenericModel,
312-
domainSpecific: EvolutionImplementationProvider[this.type]): Generator[MethodBodyContext, Option[Expression]] = {
313-
import paradigm.methodBodyCapabilities._
314-
import ooParadigm.methodBodyCapabilities._
315-
316-
for {
317-
expRef <- getArguments().map(_.head._3)
318-
319-
/** Direct access or use as is provided. */
320-
attributes <- {
321-
for {
322-
attAccessors <- forEach (tpeCase.attributes) { att => attributeDispatchAccess(att, tpeCase, domain, None) }
323-
atts = tpeCase.attributes.zip(attAccessors).toMap
324-
} yield atts
325-
}
326-
327-
// subtly different from all other ones
328-
arguments <- forEach (op.parameters) { param =>
329-
for {
330-
thisRef <- selfReference()
331-
paramField <- getMember(thisRef, names.mangle(param.name))
332-
} yield (param, paramField)
333-
}
334-
335-
result <-
336-
domainSpecific.logic(this)(
337-
ReceivedRequest(
338-
tpe,
339-
tpeCase,
340-
expRef,
341-
attributes,
342-
Request(op, arguments.toMap)
343-
// NOTE: this is the only AIP that does not pass in a model. Doing so fails
344-
)
345-
)
346-
} yield result
347-
}
348-
349315
/**
350316
* The Runtime Dispatch approach is defined as follows
351317
*
@@ -377,7 +343,7 @@ trait RuntimeDispatch extends SharedOO with OperationAsClass {
377343
makeDerived(flat.baseDataType, tpeCase)
378344
}
379345
_ <- forEach (flat.ops) { op =>
380-
addClassToProject(makeOperationImplementation(flat, op, domainSpecific), names.mangle(names.conceptNameOf(op)))
346+
addClassToProject(makeOperationImplementation(gdomain, op, domainSpecific), names.mangle(names.conceptNameOf(op)))
381347
}
382348
} yield ()
383349
}

Diff for: core/src/main/scala/org/combinators/ep/approach/oo/Visitor.scala

-3
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,6 @@ trait Visitor extends SharedOO with OperationAsClass { self =>
135135

136136
// Properly cast all Base arguments to designated baseType (which was used in the method signature)
137137
for {
138-
//thisRef <- selfReference()
139-
args <- getArguments()
140138
expRef <- getArguments().map(_.head._3)
141139
paramField <- getMember(expRef, names.mangle(param.name))
142140
} yield paramField
@@ -147,7 +145,6 @@ trait Visitor extends SharedOO with OperationAsClass { self =>
147145
import ooParadigm.methodBodyCapabilities._
148146

149147
for {
150-
args <- getArguments()
151148
expRef <- getArguments().map(_.head._3)
152149
} yield expRef
153150
}

Diff for: domain/math/src/main/scala/org/combinators/ep/domain/math/eips/M9funct.scala

+44-94
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.combinators.ep.domain.math.eips /*DD:LI:AI*/
33
import org.combinators.ep.domain.abstractions.{DataTypeCase, Operation, TypeRep}
44
import org.combinators.ep.domain.instances.InstanceRep
55
import org.combinators.ep.domain.{abstractions, math}
6-
import org.combinators.ep.generator.Command.Generator
6+
import org.combinators.ep.generator.Command.{Generator, lift}
77
import org.combinators.ep.generator.{ApproachImplementationProvider, EvolutionImplementationProvider}
88
import org.combinators.ep.generator.EvolutionImplementationProvider.monoidInstance
99
import org.combinators.ep.generator.communication.{PotentialRequest, ReceivedRequest, Request, SendRequest}
@@ -15,12 +15,8 @@ object M9funct {
1515
def apply[P <: AnyParadigm, AIP[P <: AnyParadigm] <: ApproachImplementationProvider.WithParadigm[P]]
1616
(paradigm: P)
1717
(m8Provider : EvolutionImplementationProvider[AIP[paradigm.type]])
18-
(functional:Functional.WithBase[paradigm.type],
19-
functionalControl: control.Functional.WithBase[paradigm.MethodBodyContext, paradigm.type],
20-
ffiArithmetic: Arithmetic.WithBase[paradigm.MethodBodyContext, paradigm.type, Double],
21-
ffiRealArithmetic: RealArithmetic.WithBase[paradigm.MethodBodyContext, paradigm.type, Double],
22-
ffiEquals: Equality.WithBase[paradigm.MethodBodyContext, paradigm.type]
23-
):
18+
(functionalControl: control.Functional.WithBase[paradigm.MethodBodyContext, paradigm.type],
19+
ffiArithmetic: Arithmetic.WithBase[paradigm.MethodBodyContext, paradigm.type, Double]):
2420
EvolutionImplementationProvider[AIP[paradigm.type]] = {
2521
val m9Provider = new EvolutionImplementationProvider[AIP[paradigm.type]] {
2622
override val model = math.M9.getModel
@@ -29,7 +25,6 @@ object M9funct {
2925
for {
3026
_ <- m8Provider.initialize(forApproach)
3127
_ <- ffiArithmetic.enable()
32-
_ <- ffiRealArithmetic.enable()
3328
} yield ()
3429
}
3530

@@ -50,89 +45,33 @@ object M9funct {
5045
(forApproach: AIP[paradigm.type])
5146
(onRequest: ReceivedRequest[forApproach.paradigm.syntax.Expression]):
5247
Generator[paradigm.MethodBodyContext, Option[paradigm.syntax.Expression]] = {
53-
import paradigm._
54-
import AnyParadigm.syntax._
55-
import methodBodyCapabilities._
5648
import functionalControl.functionalCapabilities._
57-
58-
// def makeCtorPat(tpe: paradigm.syntax.Type, caseName: paradigm.syntax.Name, attributeNames: Seq[paradigm.syntax.Name]): Generator[functionalControl.PatternContext, paradigm.syntax.Expression] = {
59-
// import functionalControl.patternCapabilities._
60-
// applyConstructorPattern(ConstructorPattern(tpe, caseName), attributeNames.map(patternVariable))
61-
// }
62-
//
63-
64-
if (onRequest.request.op == math.M9.Height && onRequest.tpeCase != math.M0.Lit) {
65-
val allCase = math.M9.getModel.flatten.typeCases
66-
for {
67-
zero <- forApproach.reify(InstanceRep(TypeRep.Int)(0))
68-
one <- forApproach.reify(InstanceRep(TypeRep.Int)(1))
69-
intType <- toTargetLanguageType(TypeRep.Int)
70-
71-
72-
// _ <- forEach(onRequest.attributes.toSeq) { case (att, expr) => {
73-
// for {
74-
// attName <- freshName(forApproach.names.mangle(att.name))
75-
// exprVal <- forApproach.dispatch(
76-
// SendRequest(
77-
// expr,
78-
// math.M4.getModel.baseDataType,
79-
// Request(math.M9.Height, Map.empty)
80-
// )
81-
// )
82-
// declVar <- ffiImper.imperativeCapabilities.declareVar(attName, intType, Some(exprVal))
83-
// ifExpr <- ffiArithmetic.arithmeticCapabilities.lt(maxDecl, declVar)
84-
//
85-
// ifStmt <- ffiImper.imperativeCapabilities.ifThenElse(ifExpr, for {
86-
// assignStmt <- ffiImper.imperativeCapabilities.assignVar(maxDecl, declVar)
87-
// _ <- addBlockDefinitions(Seq(assignStmt))
88-
// } yield (),
89-
// Seq.empty
90-
// )
91-
92-
// insert logic for all types:
93-
// can get all types and find those with just one recursive inner
94-
// attribute; and the height method is defined
95-
96-
//
97-
// def height_rec(exp:Exp)
98-
// exp match {
99-
// case Sub(left, right) => { leftHeight = height(left); rightHeight = height(right) 1 + if (leftHeight > rightHeight) leftHeight rightHeight }
100-
// case Mult(left, right) => { 1 + max(height_rec(left), height_rec(right)) }
101-
// case Lit(value) => { 0 }
102-
// case Add(left, right) => { 1 + max(height_rec(left), height_rec(right)) }
103-
// case Neg(inner) => { 1 + eval(inner) }
104-
// }
105-
//
106-
// def height(exp : mathdomain.Exp): Integer = {
107-
// val leftHeight = height_rec(exp)
108-
// }
109-
//
110-
//
111-
// maxName <- freshName(forApproach.names.mangle("max"))
112-
// maxDecl <- ffiImper.imperativeCapabilities.declareVar(maxName, intType, Some(zero))
113-
//
114-
// _ <- forEach(onRequest.attributes.toSeq) { case (att, expr) => {
115-
// for {
116-
// attName <- freshName(forApproach.names.mangle(att.name))
117-
// exprVal <- forApproach.dispatch(
118-
// SendRequest(
119-
// expr,
120-
// math.M4.getModel.baseDataType,
121-
// Request(math.M9.Height, Map.empty)
122-
// )
123-
// )
124-
// declVar <- ffiImper.imperativeCapabilities.declareVar(attName, intType, Some(exprVal))
125-
// ifExpr <- ffiArithmetic.arithmeticCapabilities.lt(maxDecl, declVar)
126-
//
127-
// ifStmt <- ffiImper.imperativeCapabilities.ifThenElse(ifExpr, for {
128-
// assignStmt <- ffiImper.imperativeCapabilities.assignVar(maxDecl, declVar)
129-
// _ <- addBlockDefinitions(Seq(assignStmt))
130-
// } yield (),
131-
// Seq.empty
132-
// )
133-
//
134-
// _ <- addBlockDefinitions(Seq(ifStmt))
135-
} yield Some(one)
49+
import ffiArithmetic.arithmeticCapabilities._
50+
51+
if (onRequest.request.op == math.M9.Height) {
52+
onRequest.tpeCase match {
53+
54+
// these are all binary cases
55+
case binary@(math.M3.Neg | math.M3.Mult | math.M3.Divd | math.M0.Add | math.M1.Sub | math.systemI.I2.Power | math.M8.Inv) =>
56+
for {
57+
left <- forApproach.dispatch(SendRequest(
58+
onRequest.attributes(binary.attributes.head),
59+
math.M0.getModel.baseDataType,
60+
onRequest.request
61+
))
62+
63+
right <- forApproach.dispatch(SendRequest(
64+
onRequest.attributes(binary.attributes.tail.head),
65+
math.M0.getModel.baseDataType,
66+
onRequest.request
67+
))
68+
69+
ifExpr <- ffiArithmetic.arithmeticCapabilities.lt(left, right)
70+
one <- forApproach.reify(InstanceRep(TypeRep.Int)(1))
71+
72+
result <- ifThenElse(cond = ifExpr, ifBlock = add(one, right), elseIfs = Seq.empty, elseBlock = add(one, left))
73+
} yield Some(result)
74+
}
13675
} else {
13776
m8Provider.genericLogic(forApproach)(onRequest)
13877
}
@@ -142,20 +81,31 @@ object M9funct {
14281
(forApproach: AIP[paradigm.type])
14382
(onRequest: ReceivedRequest[forApproach.paradigm.syntax.Expression]):
14483
Generator[paradigm.MethodBodyContext, Option[paradigm.syntax.Expression]] = {
145-
import paradigm._
146-
import AnyParadigm.syntax._
147-
import methodBodyCapabilities._
84+
import ffiArithmetic.arithmeticCapabilities._
14885

14986
assert(dependencies(PotentialRequest(onRequest.onType, onRequest.tpeCase, onRequest.request.op)).nonEmpty)
15087

15188
onRequest.tpeCase match {
89+
// Height of a Lit is ZERO.
15290
case math.M0.Lit =>
15391
for {
15492
zero <- forApproach.reify(InstanceRep(TypeRep.Int)(0))
15593
} yield Some(zero)
15694

157-
case _ => genericLogic(forApproach)(onRequest)
95+
case neg@math.M3.Neg =>
96+
for {
97+
one <- forApproach.reify(InstanceRep(TypeRep.Int)(1))
15898

99+
inner <- forApproach.dispatch(SendRequest(
100+
onRequest.attributes(neg.attributes.head),
101+
math.M0.getModel.baseDataType,
102+
onRequest.request
103+
))
104+
105+
res <- add(one, inner)
106+
} yield Some(res)
107+
108+
case _ => genericLogic(forApproach)(onRequest)
159109
}
160110
}
161111
}

Diff for: domain/math/src/main/scala/org/combinators/ep/domain/math/eips/systemI/I1funct.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ object I1funct {
8181

8282
// def multByRec: Double => ep.Exp = (multiplier: Double) => {
8383
// if (1 < multiplier) {
84-
// add(self, powByRec(multiplier - 1))
84+
// add(self, multByRec(multiplier - 1))
8585
// } else {
8686
// self
8787
// }

0 commit comments

Comments
 (0)