LARA

// This is how to manage memory if it is infinite :)
class Heap(size : Int) {
  private var mem = new Array[Int](size)   // OS would provide this memory
  private var nextAvailable : Int = 0 // where to allocate next
  def malloc(blockSize : Int) : Int = {
    val res = nextAvailable
    nextAvailable = nextAvailable + blockSize
    initMem(res, nextAvailable) // optional
    res
  }
 
  def initMem(from : Int, to : Int) = {
    var i = from
    while (i < to) { 
      mem(i) = 0;
      i = i + 1;
    }
  }
 
  // Do nothing in free
  def free(ptr : Int, size : Int) = { }
 
  val nullPtr = 0
 
  // x.f
  def load(x : Int, f : Int) = 
    mem(x + f)
 
  // x.f = y
  def store(x : Int, f : Int, y : Int) = {
    mem(x + f) = y
  }
 
  override def toString() : String = {
    var res = ""
    var i : Int = 0
    while (i <= nextAvailable) {
      res += (i + "->" + mem(i) + "  ")
      i = i + 1
    }
    res
  }
}
 
// source code example
object TestSourceCode {
  class Node {
    var next : Node = null
    var data : Int = 0
  }
  def main(args : Array[String]) = {
    var x : Node = new Node()
    var y : Node = new Node()
    x.next = y
    x.data = 42
    var z : Node = x.next
    z.data = 9
  }
}
 
// object code for the above example
object TestObjectCode {
  val typeTagOffset  = 0 // implicit, first, field
  val nextOffset     = 1 // second field
  val dataOffset     = 2 // third field
  val nodeSize = 3 // three fields total
 
  val nodeTypeTag = 555 // index of type 'Node'
 
  def main(args : Array[String]) = {
    var h : Heap = new Heap(64)
    var x : Int = h.malloc(nodeSize)
    h.store(x, typeTagOffset, nodeTypeTag)
 
    var y : Int = h.malloc(nodeSize)
    h.store(y, typeTagOffset, nodeTypeTag)
 
    h.store(x, nextOffset, y)
    h.store(x, dataOffset, 42)
    var z : Int = h.load(x, nextOffset)
    h.store(z, dataOffset, 9)
 
    println(h)
  }
}