Intermediate Representation (IR)

In a Compiler, an intermediate representation (IR) is a data structure that represents the program being compiled.

The following diagram summarizes the overall structure of a compiler (Lacs compiler):

Implementation that Brian gave me because I didn’t know how to implement closures

def generateCode(procedureScope: ProcedureScope): Unit = {
  val symbolTable = typedProcedures.symbolTables(procedureScope)
  val opMap = Map(("PLUS", plus), ("STAR", times), ("PCT", remainder), ("MINUS", minus), ("SLASH", divide))
  val cmpMap: Map[String, Label=>Code] = Map(("NE", neCmp), ("LT", ltCmp), ("GT", gtCmp), ("LE", leCmp), ("GE", geCmp), ("EQ", eqCmp))
  /** Generates the `Code` that implements `tree`.
	*
	* This method will be called from the outside only on `tree`s rooted at nodes of kind "expras".
	* However, if it calls itself recursively on other kinds of nodes, it needs to be able to handle
	* those node kinds as well.
	*/
  def recur(tree: Tree): Code = {
	val p = tree.production
	val c = tree.children
	if(p == "factor ID"){
	  symbolTable(c(0).lhs.lexeme) match {
		case Left(v) => read(Reg.result, v.variable)
		case Right(p) => Closure(p.procedure)
	  }
	} else if(p == "factor NUM"){
	  block(LIS(Reg.result), Word(encodeUnsigned(c(0).lhs.lexeme.toInt)))
	} else if(p == "factor LPAREN expr RPAREN"){
	  recur(c(1))
	} else if(p == "factor factor LPAREN argsopt RPAREN"){
	  val argExprs = collect(c(2), "expr")
	  val args = argExprs.map(expr => recur(expr))
	  val params = argExprs.map(expr => new Variable("param", isPointer=typedProcedures.typeMap(expr).isInstanceOf[FunctionType]))
	  recur(c(0)) match {
		case Closure(p) => return Call(p, args)
		case _ => return CallClosure(recur(c(0)), args, params)
	  }
	} else if (p == "term term STAR factor" || p == "term term SLASH factor" || p == "term term PCT factor" || p == "expr expr PLUS term" || p == "expr expr MINUS term") {
	  binOp(recur(c(0)), opMap(c(1).lhs.kind), recur(c(2)))
	} else if (p == "expr IF LPAREN test RPAREN LBRACE expras RBRACE ELSE LBRACE expras RBRACE"){
	  ifStmt(recur(c(2).children(0)), cmpMap(c(2).children(1).lhs.kind), recur(c(2).children(2)), recur(c(5)), recur(c(9)))
	} else if(p == "expras expra SEMI expras"){
	  block(recur(c(0)), recur(c(2)))
	} else if (p == "expras expra" || p == "expra expr" || p == "expr term" || p == "term factor"){
	  recur(c(0))
	} else if(p == "expra ID BECOMES expr") {
	  block(recur(c(2)), write(symbolTable(c(0).lhs.lexeme).left.get.variable, Reg.result) )
	} else {
	  sys.error("no matching production")
	}
  }