Skip to content

Commit

Permalink
Integrated scala to macros, local abstract machine execution and serv…
Browse files Browse the repository at this point in the history
…ice calls
  • Loading branch information
basilkohler committed Mar 20, 2014
1 parent c76173d commit d75d603
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 32 deletions.
56 changes: 49 additions & 7 deletions nfn/lambda-to-macros/src/main/scala/LambdaToMacros.scala
@@ -1,11 +1,13 @@
import com.typesafe.scalalogging.slf4j.Logging
import lambdacalculus.machine.{ConstValue, ValuePrettyPrinter, Value, CallExecutor}
import lambdacalculus.{ExecutionOrder, LambdaCalculus}
import language.experimental.macros

import LambdaMacros._
import scala.collection.immutable
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.Try
import scala.util.{Failure, Success, Try}


case class WordCountService() extends NFNService {
Expand Down Expand Up @@ -89,12 +91,43 @@ case class NFNMapReduce(values: NFNNameList, map: NFNService, reduce: NFNService

case class NFNNameList(names: List[NFNName])

object ScalaToNFN extends App with Logging {
case class LocalNFNCallExecutor() extends CallExecutor {
override def executeCall(call: String): Value = {
NFNService.parseAndFindFromName(call).flatMap({ serv => serv.exec}) match {
case Success(NFNIntValue(n)) => ConstValue(n)
case Success(res @ _) => throw new Exception(s"LocalNFNCallExecutor: Result of executeCall is not implemented for: $res")
case Failure(e) => throw new Exception(e)
}
}
}

case class ScalaToLocalMachine() extends NFNSender with Logging {
val lc = LambdaCalculus(ExecutionOrder.CallByValue, maybeExecutor = Some(LocalNFNCallExecutor()))

override def nfnSend(lambda: String): String = {
lc.substituteParseCompileExecute(lambda) match {
case Success(List(v: Value)) => ValuePrettyPrinter(v)
case Success(List(values @ _*)) => {
logger.warn("More than one execution result")
values.mkString("[", " | ", "]")
}
case Success(Nil) => throw new Exception("ScalaToLocalMachine: For some reason there was a successful execution without an result")
case Failure(e) => throw new Exception(e)
}

}
}

trait NFNSender {
def apply(lambda:String): String = nfnSend(lambda)
def nfnSend(lambda: String): String
}

case class ScalaToNFN() extends NFNSender with Logging {
val socket = UDPClient()
val ccnIf = new CCNLiteInterface()

def nfnSend(lambda: String): String = {
override def nfnSend(lambda: String): String = {

val interest = Interest(lambda)

Expand Down Expand Up @@ -125,18 +158,27 @@ object ScalaToNFN extends App with Logging {
}
}

}

object ScalaToNFN extends App with Logging {

// val nfnSend = ScalaToNFN()
val nfnSend = ScalaToLocalMachine()
println("Running ScalaToNFN...")

val res = nfnSend(lambda{
val res = nfnSend(
"call 3 SumService/Int/Int/rInt 11 1"
// lambda{
// val x = 41
// x + 1
// val dollar = 100
// NFNServiceLibrary.convertDollarToChf(100)
// def fun(x: Int): Int = x + 1
// fun(2)
val dollar = 100
dollar + 1
})
// val dollar = 100
// dollar + 1
// }
)
println(s"Result: $res")


Expand Down
50 changes: 31 additions & 19 deletions nfn/lambda-to-macros/src/main/scala/Main.scala
Expand Up @@ -5,6 +5,7 @@ import LambdaMacros._

import scala.reflect.runtime.{universe => ru}
import scala.util.matching.Regex
import scala.util.matching.Regex.Match
import scala.util.{Failure, Success, Try}


Expand All @@ -15,12 +16,17 @@ import ExecutionContext.Implicits.global
object NFNServiceLibrary {

private var services:Map[String, NFNService] = Map()
add(SumService())

def add(serv: NFNService) = services += serv.toNFNName.toString -> serv
def add(serv: NFNService) = services += serv.toNFNName.name -> serv

def find(servName: String):Option[NFNService] = {
println(s"Looking for: '$servName' in '$services'")
services.get(servName)
}

def find(servName: String):NFNService = services(servName)

def find(servName: NFNName):NFNService = find(servName.name)
def find(servName: NFNName):Option[NFNService] = find(servName.name)

def convertDollarToChf(dollar: Int): Int = ???
// val serv = DollarToChf()
Expand Down Expand Up @@ -114,23 +120,29 @@ trait NFNService {

object NFNService {
def parseAndFindFromName(name: String): Try[CallableNFNService] = {
var pattern = new Regex("^call (\\d)+ ((/[\\w]+)+)*$")
pattern.findAllMatchIn(name).toList match {
case List(matchh) =>
matchh.groupNames match {
case Seq(countString, funString, argStrings@_*) => {
val count = countString.toInt - 1
assert(count == argStrings.size, s"matched name $name is not a valid service call, because arg count is not equal nto number of args (currently nfn counts the function name itself as an arg)")
assert(count > 0, s"matched name $name is not a valid service call, because count cannot be 0 or smaller (currently nfn counts the function name itself as an arg)")
val fun = argStrings.head
val serv = NFNServiceLibrary.find(fun)

Try(serv.parse(name, argStrings))
}
case _ => throw new Exception(s"matched name $name is not a valid service call, because arg count is not equal nto number of args (currently nfn counts the function name itself as an arg)")

println(s"Name: $name")
// val pattern = new Regex("""^call (\d)+ ([\S]+) ([\S]+) ([\S]+)$""")
val pattern = new Regex("""^call (\d)+ (.*)$""")

name match {
case pattern(countString, funArgs) => {
val l = funArgs.split(" ").toList
val (fun, args) = (l.head, l.tail)

println(s"fun: $fun")
println(s"args: $args")

val count = countString.toInt - 1
assert(count == args.size, s"matched name $name is not a valid service call, because arg count (${count + 1}) is not equal to number of args (${args.size}) (currently nfn counts the function name itself as an arg)")
assert(count > 0, s"matched name $name is not a valid service call, because count cannot be 0 or smaller (currently nfn counts the function name itself as an arg)")
//
val serv = NFNServiceLibrary.find(fun).getOrElse(throw new Exception(s"parseAndFindFromName: Service $fun not found in service library"))

Try(serv.parse(fun, args))
}
case Nil => throw new Exception(s"No name could be parsed from: $name")
case _ => throw new Exception(s"For some reason more than valid possible name was parsed from $name")
// case Nil => throw new Exception(s"No name could be parsed from: $name")
case unvalidServ @ _ => throw new Exception(s"matched name $name (parsed to: $unvalidServ) is not a valid service call, because arg count is not equal nto number of args (currently nfn counts the function name itself as an arg)")
}
}
}
Expand Down
Expand Up @@ -66,20 +66,23 @@ object LambdaCalculus extends App {
lc.substituteParseCompileExecute(l)
}

case class LambdaCalculus(execOrder: ExecutionOrder.ExecutionOrder, debug: Boolean = false, storeIntermediateSteps: Boolean = false) extends Logging {
case class LambdaCalculus(execOrder: ExecutionOrder.ExecutionOrder,
debug: Boolean = false,
storeIntermediateSteps: Boolean = false,
maybeExecutor: Option[CallExecutor] = None) extends Logging {

val parser = new LambdaParser()
val compiler = compilerForExecOrder(debug, execOrder)
val machine = machineForExecOrder(storeIntermediateSteps, execOrder)
val machine = machineForExecOrder(storeIntermediateSteps, execOrder, maybeExecutor)


private def compilerForExecOrder(debug: Boolean, execOrder: ExecutionOrder): Compiler = execOrder match {
case ExecutionOrder.CallByName => CBNCompiler(debug)
case ExecutionOrder.CallByValue => CBVCompiler(debug)
}
private def machineForExecOrder(storeIntermediateSteps: Boolean, execOrder: ExecutionOrder): Machine = execOrder match {
private def machineForExecOrder(storeIntermediateSteps: Boolean, execOrder: ExecutionOrder, maybeExecutor: Option[CallExecutor]): Machine = execOrder match {
case ExecutionOrder.CallByName => CBNMachine(storeIntermediateSteps)
case ExecutionOrder.CallByValue => CBVMachine(storeIntermediateSteps)
case ExecutionOrder.CallByValue => CBVMachine(storeIntermediateSteps, maybeExecutor)
}

def substituteParse(code: String): Try[Expr] = {
Expand Down
Expand Up @@ -215,7 +215,7 @@ case class CBVMachine(override val storeIntermediateSteps:Boolean = false, maybe
case arg @ _ => throw new MachineException(s"CBVMachine: transformation from value $arg to a string is not implemented")
}

val r: Value = executeCall(s"call ${nArgs + 1} ${argsStrings.mkString(" ")}")
val r: Value = executeCall(s"call ${nArgs + 1} $name ${argsStrings.mkString(" ")}")

nextStack = r :: s
nextEnv = e
Expand Down
Expand Up @@ -33,7 +33,7 @@ object ValuePrettyPrinter {
case VariableValue(n, _) => s"$n"
}
case v: Value => v match {
case ConstValue(n, maybeVarName) => s"$n(${maybeVarName.getOrElse("-")}})"
case ConstValue(n, maybeVarName) => s"$n(${maybeVarName.getOrElse("-")})"
case CodeValue(c, maybeVarName) => s"CodeVal(${c.mkString(",")}, ${maybeVarName.getOrElse("-")}))"
}
case _ => throw new NotImplementedError(s"ValuePrettyPrinter has no conversion for value $value")
Expand Down

0 comments on commit d75d603

Please sign in to comment.