ex06 Task 1: Mutation for Recursion

plo1234
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 116
Registriert: 14. Nov 2009 18:51

ex06 Task 1: Mutation for Recursion

Beitrag von plo1234 »

Hi,
to get recursion using mutation, I introduced a LetRec expression, which binds the name of the recursive function to a box. The box contains the functions body. For that I also had to change the evaluation of App-expressions.

Code: Alles auswählen

    case WithRec(boundId, namedExpr, boundBody) =>
      // create a new box and in the body set the box's value to the recursive function that refers to the box
      val (_, s1) = interp(With(boundId, NewBox(0), SetBox(boundId, namedExpr)), env, store)
      val newLoc = nextLocation - 1
      interp(boundBody, env + (boundId -> newLoc), s1)

    ....

    case App(funExpr, argExpr) => {
      var (funV, funStore) = interp(funExpr, env, store)
      val (argV, argStore) = interp(argExpr, env, funStore)
      funV match {
        case Closure(fParam, fBody, fEnv) => {
          val newLoc = nextLocation
          interp(fBody, fEnv + (fParam -> newLoc), argStore + (newLoc -> argV))
        }
        case Box(loc) => {
          funV = store(loc)
          funV match {
            case Closure(fParam, fBody, fEnv) => {
              val newLoc = nextLocation
              interp(fBody, fEnv + (fParam -> newLoc), argStore + (newLoc -> argV))
            }
            case _ => sys.error("can only apply functions, but got: " + funV)
          }
        }
        case _ => sys.error("can only apply functions, but got: " + funV)
      }
    }

The App-part seems quite hacky to me. Is there a better way?

plo1234

the whole code could be found here: http://pastebin.com/kprWK4g8

r1chard
Erstie
Erstie
Beiträge: 19
Registriert: 26. Mai 2011 17:23

Re: ex06 Task 1: Mutation for Recursion

Beitrag von r1chard »

You don't even have to change the App part

The trick is to create the location and insert it into the enviroment of the closure before inserting the closure into the store:

Code: Alles auswählen

    case LetRec(boundId, namedExpr, boundBody) =>
      // create the location
      val newLoc = nextLocation
      // insert the location into the environment
      val recEnv = env + (boundId -> newLoc)
      // use the enviroment to create the closure
      val (boundV, boundStore) = interp(namedExpr,  recEnv, store)
      // insert the closure into the store (The enviroment of the closure contains the recursive location in the store)
      val recStore = boundStore + (newLoc -> boundV)

      interp(boundBody, recEnv, recStore)

plo1234
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 116
Registriert: 14. Nov 2009 18:51

Re: ex06 Task 1: Mutation for Recursion

Beitrag von plo1234 »

Oh, yes. That seems much simpler ;)
Thanks!

Antworten

Zurück zu „Archiv“