In case anyone is interested, I came up with this simple code to generate 
the call graph:
import org.nlogo.headless.HeadlessWorkspace
import org.nlogo.nvm._

case class GraphEdge(from : String, to: String, isolate : Boolean) {
override def toString = s"$from -> $to"
def toCSV = s"$from,$to,$isolate"
}

object GraphEdge {
def apply(from: String, to: String) : GraphEdge = {
val isolate = to match {
case "" => true
case _ => false
}
apply(from, to, isolate)
}

}

 object GenerateCallGraph {
  def extractCallGraph(procedures : Procedure.ProceduresMap) : 
Set[GraphEdge] = {
val procNames = procedures.keySet
println("printing the procNames")
procNames foreach println
println("*******printing the calls")
val edges = procedures.map{case(parent,child) => {
println(s"working procedure: $parent")
val (gcall,gargs) = child.code.partition(_.toString.contains("_call"))
val topEdges = gcall.map(c => GraphEdge(from=parent,to=c.displayName))
// greports : Array[Array[org.nlogo.nvm.Reporter]] 
val greports = gargs.map(_.args).filter(a => 
a.exists(_.toString.contains("_callreport")))
val argEdges = greports.map(r => {
val edge = GraphEdge(from=parent, to=r(0).displayName)
println(s"making edge in proc: $parent => $edge")
edge
})
argEdges match {
case e if e.isEmpty => topEdges.toList
case _ => topEdges.toList ::: argEdges.toList
}
}}  
val edgeSet = edges.toList.flatten.toSet
edgeSet foreach println
edgeSet

  }

def run(modelFileName : String, callGraphOutFileName : String) : Unit = {
val workspace = HeadlessWorkspace.newInstance
workspace.open(modelFileName)
val procs = workspace.procedures 
val callGraph = extractCallGraph(procs)
val output = callGraph.map(_.toCSV).toList
Utils.writeFile(callGraphOutFileName, output)
workspace.dispose()
}


} 

On Thursday, June 11, 2020 at 11:41:03 AM UTC-4, Steve Upton wrote:
>
> Shoot, has it been that long??
>
> Your answers, and references, are enough to get me going. I'll parse the 
> Commands since I don't see where to get the FrontEndResults - maybe they 
> have been discarded. Or maybe someone else will pipe in.
>
> thanx again
> steve
>
> On Thursday, June 11, 2020 at 11:20:30 AM UTC-4, Seth Tisue wrote:
>>
>> It's now been more than five years since I worked on NetLogo; there's a 
>> limit to how much I still remember.
>>
>> In particular, I don't remember whether it's possible to get back to the 
>> ASTs after the entire compiler has run, or whether they have already been 
>> discarded and it's too late.
>>
>> I found some prior discussions in this area in the NetLogo room on Gitter:
>>
>> * https://gitter.im/NetLogo/NetLogo?at=5be1a45dda57ff676c9d4305  — "you 
>> want `FrontEndResults` and not `CompilerResults`. "FrontEndResults contains 
>> ProcedureDefinition objects, these have the ASTs inside them. see 
>> AstNode.scala"
>> * https://gitter.im/NetLogo/NetLogo?at=5bba30ccc7bf7c3662cda279
>>
>> But anyway, although my first thought was to walk the ASTs, on second 
>> thought it might be easier and just as effective for your use case to walk 
>> the fully compiled model (the `Array[Command]` inside each procedure) and 
>> look for the `_call` and `_callreport` nodes there. Any `_call`s will be in 
>> the `Array[Command]` directly, but to find the `_callreport`s you'll need 
>> recursively walk the `args` tree under each `Command`.
>>
>> Seth
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"netlogo-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netlogo-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netlogo-devel/af675a50-601e-4a20-8d54-4deb5338c211o%40googlegroups.com.

Reply via email to