Skip to content

Instantly share code, notes, and snippets.

@SethTisue
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SethTisue/9993133 to your computer and use it in GitHub Desktop.
Save SethTisue/9993133 to your computer and use it in GitHub Desktop.
NetLogo: proposal for splitting primitive classes into front-end and back-end parts

Old

combined front/back end

package org.nlogo.prim

class _breedvariable(name: String) extends nvm.Reporter {
  def syntax = core.Syntax.reporterSyntax(...)
  def toString = s"${super.toString}:$name"
  def report(context: nvm.Context): AnyRef =
    context.agent.getBreedVariable(name)
}

New

front end

package org.nlogo.core
package prim

class _breedvariable(name: String) extends Reporter {  // that's core.Reporter
  def syntax = Syntax.reporterSyntax(...)
  def toString = s"${super.toString}:$name"
}

back end (option 1)

package org.nlogo.prim

class _breedvariable(bv: core.prim._breedvariable) extends nvm.Reporter {
  def report(context: nvm.Context): AnyRef =
    context.agent.getBreedVariable(bv.name)
}

back end (option 2)

package org.nlogo.prim

object _breedvariable {
  def apply(bv: core.prim._breedvariable) =
    new _breedvariable(bv.name)
}
class _breedvariable(name: String) extends nvm.Reporter {
  def report(context: nvm.Context): AnyRef =
    context.agent.getBreedVariable(bv.name)
}  

Notes

Until we reach Assembler, we'd have only the ASTs, containing instances of core.Command (inside ast.Statement) and core.Reporter (inside ast.ReporterApp).

Assembler would discard the ASTs and replace them with instances of nvm.Command and nvm.Reporter.

The mapping from the front end classes in core.prim to the back end classes in prim would be via reflection, I suppose. There could also be a big static map that did it, but we'd either have to hand-maintain it, or generate it. Generating it is just as ugly as reflection, and hand-maintenance sucks, so I'd lean towards reflection. It wouldn't be any worse than the old system, which does reflection on the class names stored in tokens.txt.

Tangent: take args in constructor too?

since we're holding off until Assembler to instantiate the prim classes, we could do this:

package org.nlogo.prim

class _plus(arg0: nvm.Reporter, arg1: nvm.Reporter) {
  def report(context: nvm.Context) =
    arg0.reportDoubleValue + arg1.reportDoubleValue
}

which is a lot cleaner than the current grubby args/arg0/arg1/... stuff.

We might want to add def args = Seq(arg0, Arg1) = ... just so we can do things like print out the assembled code. Though I suppose reflection could accomplish the same thing.

Background

I had been planning on redoing the front end of the compiler so that AST nodes didn't have Instruction objects (Commands and Reporters) attached to them anymore, but instead just a Syntax object and a string with the canonical name of the prim.

I ran into two fundamental difficulties:

  • It's a radical change that was going to involve tearing up lots of code. It was going to be difficult to accomplish before April 30.
  • We have too many primitives that can't easily be shoehorned into a (String, Syntax) representation
  • Other information we need to attach includes:
  • breed names
  • lvalues (a variable number or name)
  • Not clear how to attach this stuff except by piling it into the string, or by resorting to a Seq[Any] type hack
  • Representing primitives with String instead of classes would cost us a lot of compile-type safety.
  • If push comes to shove, maintaining module boundaries is more important than maximizing compile-time safety, but must we sacrifice one or the other?

Side note: for a while I also considered attaching the extra information as additional AST nodes, as we already do with the _reference-Referenceable-TypeReference stuff for the diffuse, downhill, uphill family of primitives, but it's too big a change, and I'm thinking it's actually a bad idea even if were feasible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment