Function calls

This commit is contained in:
alari 2018-09-08 19:20:15 +02:00
parent f4d186dfa9
commit 36b6a683bb
4 changed files with 41 additions and 19 deletions

View File

@ -9,7 +9,7 @@ sealed trait Expr[T] {
def toVyper: String def toVyper: String
} }
sealed trait InlineExpr[T <: types.Type] extends Expr[T] { sealed trait InlineExpr[T] extends Expr[T] with Expr.ToInlineVyper {
def toReturn: Free[Expr, T] = Free liftF Expr.Return[T](this) def toReturn: Free[Expr, T] = Free liftF Expr.Return[T](this)
def :=:(name: Symbol): Free[Expr, Expr.Ref[T]] = def :=:(name: Symbol): Free[Expr, Expr.Ref[T]] =
@ -17,27 +17,33 @@ sealed trait InlineExpr[T <: types.Type] extends Expr[T] {
} }
object Expr { object Expr {
case class Ref[T <: types.Type](name: String, boxedValue: T) extends InlineExpr[T] { sealed trait ToInlineVyper {
override def toVyper: String = name def toInlineVyper: String
} }
case class Infix[L <: types.Type, R <: types.Type, T <: types.Type]( case class Ref[T](name: String, boxedValue: T) extends InlineExpr[T] {
override def toVyper: String = name
override def toInlineVyper: String = toVyper
}
case class Infix[L, R, T](
op: String, op: String,
left: InlineExpr[L], left: InlineExpr[L],
right: InlineExpr[R], right: InlineExpr[R],
boxedValue: T boxedValue: T
) extends InlineExpr[T] { ) extends InlineExpr[T] {
override def toVyper: String = left.toVyper + s" $op " + right.toVyper override def toVyper: String = left.toVyper + s" $op " + right.toVyper
override def toInlineVyper: String = toVyper
} }
case class Assign[T <: Type](ref: Ref[T], value: InlineExpr[T]) extends Expr[Ref[T]] { case class Assign[T](ref: Ref[T], value: InlineExpr[T]) extends Expr[Ref[T]] {
override def boxedValue: Ref[T] = ref override def boxedValue: Ref[T] = ref
override def toVyper: String = override def toVyper: String =
s"${ref.toVyper} = ${value.toVyper}" s"${ref.toVyper} = ${value.toVyper}"
} }
case class Return[T <: types.Type](ret: InlineExpr[T]) extends Expr[T] { case class Return[T](ret: InlineExpr[T]) extends Expr[T] {
override def boxedValue: T = ret.boxedValue override def boxedValue: T = ret.boxedValue
override def toVyper: String = override def toVyper: String =

View File

@ -4,7 +4,7 @@ import fluence.hackethberlin.types.{DataVyper, ProductType}
import shapeless._ import shapeless._
import cats.free.Free import cats.free.Free
class FuncDef[Args <: HList, Ret <: types.Type]( class FuncDef[Args <: HList, Ret <: types.Type, Params <: HList](
name: String, name: String,
argsDef: ProductType[Args], argsDef: ProductType[Args],
ret: Ret, ret: Ret,
@ -20,25 +20,32 @@ class FuncDef[Args <: HList, Ret <: types.Type](
.filter(_ != types.Void) .filter(_ != types.Void)
.fold("")(" -> " + _.toVyper)}:\n$bodyVyper\n" .fold("")(" -> " + _.toVyper)}:\n$bodyVyper\n"
def @:(decorator: Decorator): FuncDef[Args, Ret] = def @:(decorator: Decorator): FuncDef[Args, Ret, Params] =
new FuncDef[Args, Ret](name, argsDef, ret, body, decorators + decorator) new FuncDef[Args, Ret, Params](name, argsDef, ret, body, decorators + decorator)
//def apply[Params <: HList](params: Params)(implicit a: LUBConstraint s: ops.hlist.Mapped[Args, InlineExpr]): InlineExpr[Ret] = ??? def apply(params: Params)(implicit toList: ops.hlist.ToList[Params, Expr.ToInlineVyper]): InlineExpr[Ret] =
Expr.Ref(toList.apply(params).map(_.toInlineVyper).mkString(s"$name(", ", ", ")"), ret)
} }
object FuncDef { object FuncDef {
def apply[Args <: HList: DataVyper, Ret <: types.Type]( def apply[Args <: HList: DataVyper, Ret <: types.Type, _Values <: HList](
name: String, name: String,
argsDef: Args, argsDef: Args,
ret: Ret ret: Ret
)(body: ProductType[Args] Free[Expr, Ret]): FuncDef[Args, Ret] = )(body: ProductType[Args] Free[Expr, Ret])(
implicit values: ops.record.Values.Aux[Args, _Values],
mapped: ops.hlist.Mapped[_Values, InlineExpr]
): FuncDef[Args, Ret, mapped.Out] =
new FuncDef(name, ProductType(argsDef), ret, body) new FuncDef(name, ProductType(argsDef), ret, body)
def apply[Args <: HList: DataVyper]( def apply[Args <: HList: DataVyper, _Values <: HList](
name: String, name: String,
argsDef: Args argsDef: Args
)(body: ProductType[Args] Free[Expr, Unit]): FuncDef[Args, types.Void] = )(
body: ProductType[Args] Free[Expr, Unit],
mapped: ops.hlist.Mapped[_Values, InlineExpr]
)(implicit values: ops.record.Values.Aux[Args, _Values]): FuncDef[Args, types.Void, mapped.Out] =
new FuncDef(name, ProductType(argsDef), types.Void, args body(args).map(_ types.Void)) new FuncDef(name, ProductType(argsDef), types.Void, args body(args).map(_ types.Void))
} }

View File

@ -1,13 +1,13 @@
package fluence.hackethberlin.types package fluence.hackethberlin.types
import cats.free.Free import cats.free.Free
import fluence.hackethberlin.{Expr, FuncDef} import fluence.hackethberlin.{Expr, FuncDef, InlineExpr}
import shapeless.{HList, Witness} import shapeless._
import shapeless.ops.record.Selector import shapeless.ops.record.Selector
class ProductType[D <: HList](dataDef: D, dv: DataVyper[D]) extends Type { class ProductType[D <: HList](dataDef: D, dv: DataVyper[D]) extends Type {
def ref[T <: Symbol, V <: Type](k: Witness.Aux[T])(implicit selector: Selector.Aux[D, T, V]): Expr.Ref[V] = def ref[T <: Symbol, V <: Type](k: Witness.Aux[T])(implicit selector: Selector.Aux[D, T, V]): InlineExpr[V] =
Expr.Ref[V](k.value.name, selector(dataDef)) Expr.Ref[V](k.value.name, selector(dataDef))
// type in type definition somewhere // type in type definition somewhere
@ -22,8 +22,13 @@ class ProductType[D <: HList](dataDef: D, dv: DataVyper[D]) extends Type {
def toArgsVyper: String = def toArgsVyper: String =
dv.toVyperDefinitions(dataDef).mkString(", ") dv.toVyperDefinitions(dataDef).mkString(", ")
def funcDef[Ret <: Type](name: String, ret: Ret)(body: ProductType[D] Free[Expr, Ret]): FuncDef[D, Ret] = def funcDef[Ret <: Type, _Values <: HList](name: String, ret: Ret)(
new FuncDef[D, Ret](name, this, ret, body) body: ProductType[D] Free[Expr, Ret]
)(
implicit values: ops.record.Values.Aux[D, _Values],
mapped: ops.hlist.Mapped[_Values, InlineExpr]
): FuncDef[D, Ret, mapped.Out] =
new FuncDef[D, Ret, mapped.Out](name, this, ret, body)
} }

View File

@ -59,4 +59,8 @@ object MakeVyperApp extends App {
).toVyper ).toVyper
) )
println(
func(recordStruct.ref('record_address) :: HNil).toVyper
)
} }