Skip to content
Snippets Groups Projects
Commit e6edbfbe authored by Lior Spach's avatar Lior Spach
Browse files

2/3

parent 1449166d
No related branches found
No related tags found
No related merge requests found
package other
import scala.annotation.tailrec
object Tudo {
import collection.mutable.ListBuffer
val MEPA = ListBuffer[String]()
object rotulos {
private var num = 0
def -- = num-=1
def geraRotulo = {
num += 1
"R"+ (if (num<10) "00"+num else if (num<100) "0"+num else num)
}
}
def insereIntVars(vars: List[String], nivelLexico: Int) = {
val orgSize = vars.size
var desloc = 0
if (orgSize == vars.distinct.size) {
TabelaSimb insere vars.map { id =>
val v = Var(id, desloc, nivelLexico); desloc += 1; v
}
MEPA += "AMEM " + orgSize
} else {
println("Erro: declaração de variáveis: identificadores já declarados: "+vars.diff(vars.distinct).mkString(" "))
}
}
def chamaId(id: String, nvLexAtual:Int):Unit = {
TabelaSimb.getById(id) match {
case Some(it) => it match {
case v:Var =>
if (MyParser.eh_param) {
val isByRef = MyParser.procStack.top match {
case p:Procedimento => p.paramInfo(MyParser.paramCounter.get).byRef
case f:Funcao => f.paramInfo(MyParser.paramCounter.get).byRef
}
if (isByRef)
aplica("CREN "+v.nvLex+","+v.desloc)
else
aplica("CRVL "+v.nvLex+","+v.desloc)
} else
aplica("CRVL "+v.nvLex+","+v.desloc)
case p:Param =>
if (MyParser.eh_param) {
val isByRef = MyParser.procStack.top match {
case p:Procedimento => p.paramInfo(MyParser.paramCounter.get).byRef
case f:Funcao => f.paramInfo(MyParser.paramCounter.get).byRef
}
if (isByRef)
if (p.byRef) aplica("CRVL "+p.nvLex+","+p.desloc) else aplica("CREN "+p.nvLex+","+p.desloc)
else
if (p.byRef) aplica("CRVI "+p.nvLex+","+p.desloc) else aplica("CRVL "+p.nvLex+","+p.desloc)
} else
if (p.byRef) aplica("CRVI "+p.nvLex+","+p.desloc) else aplica("CRVL "+p.nvLex+","+p.desloc)
case p:Procedimento => aplica("CHPR "+p.rotEntrada+","+nvLexAtual)
case f:Funcao => aplica("CHPR "+f.rotEntrada+","+nvLexAtual)
case other =>
println("Erro(1): Identificador Inválido: "+ id)
sys.exit(1)
}
case None =>
if(id!="read" && id!="write") {
println("Erro(2): Identificador Inválido: "+ id);
sys.exit(1)
} else id match {
case "read" => aplica("LEIT")
case "write" => aplica("IMPR")
}
}
}
object proc {
val RotStack = collection.mutable.Stack[String]()
//DRY!
def entraProcFun(nivelLexico: Int) = {
val rotulo = rotulos.geraRotulo //rotuloEntrada
val rotuloBegin = rotulos.geraRotulo
RotStack.push(rotuloBegin) //Begin
if (nivelLexico>1) {
val rotDesvio = TabelaSimb.getLastProc(nivelLexico-1) match {
case p:Procedimento => p.rotEntrada
case f:Funcao => f.rotEntrada
case o => println("====> "+o)
}
}
aplica(rotulo+": ENPR "+nivelLexico)
rotulo
}
def entraProc(id:String, params:Option[ List[(Option[String],List[String])] ], nivelLexico:Int): Unit = {
val rotulo = entraProcFun(nivelLexico)
params match {
case Some( lstParams ) if ! lstParams.isEmpty =>
val ps = retornaParamsLst(lstParams, nivelLexico)
TabelaSimb.insere( Procedimento(id, ps, nivelLexico, rotulo) )
ps.foreach { TabelaSimb.insere }
case None =>
TabelaSimb.insere( Procedimento(id, List.empty, nivelLexico, rotulo) )
}
}
def entraFunc(id:String, params:Option[ List[(Option[String],List[String])] ], nivelLexico:Int):Unit = {
val rotulo = entraProcFun(nivelLexico)
params match {
case Some( lstParams ) if ! lstParams.isEmpty =>
val ps = retornaParamsLst(lstParams, nivelLexico)
val desloc = -4-ps.size
TabelaSimb.insere( Funcao(id,ps,desloc,nivelLexico,rotulo) )
ps.foreach { TabelaSimb.insere }
case None =>
TabelaSimb.insere( Funcao(id, null, -4, nivelLexico,rotulo) )
}
}
def retornaParamsLst(params:List[(Option[String],List[String])], nivelLexico:Int):List[Param] = {
var desloc = -3 - params.map(_._2.size).sum
params.flatMap {
case (varOpt, idlst) =>
idlst map { id =>
val p = Param(id,desloc,varOpt.isDefined,nivelLexico)
desloc +=1
p
}
}
}
@tailrec def contaVariaveis(nvLex:Int, count:Int = 0):Int = TabelaSimb.hasNext match {
case true => TabelaSimb.top match {
case v:Var => TabelaSimb.drop; contaVariaveis(nvLex,count+1)
case p:Procedimento => if (p.nvLex>nvLex) {TabelaSimb.drop; contaVariaveis(nvLex,count)} else count
case f:Funcao => if (f.nvLex>nvLex) {TabelaSimb.drop; contaVariaveis(nvLex,count)} else count
case r:Label =>
if (! r.used) {println("Warning: rótulo nunca usado: "+ r.id)}
TabelaSimb.drop
contaVariaveis(nvLex,count)
case _ => count
}
case false => count
}
def saiProcFunc(nivelLexico:Int) {
val numVariaveis = contaVariaveis(nivelLexico)
if (numVariaveis>0)
aplica("DMEM "+numVariaveis)
val table = TabelaSimb.getTable
TabelaSimb.setTable(
table.dropWhile {
case p:Procedimento => if (p.nvLex>nivelLexico) true else false
case f:Funcao => if (f.nvLex>nivelLexico) true else false
case r:Label =>
if (r.used) { //Se rótulo nunca usado
println("Warning: rótulo nunca usado: "+ r.id)
//sys.exit(1)
}
true
case _ => true
}
)
TabelaSimb.top match {
case p:Procedimento => aplica("RTPR "+ p.nvLex +","+p.paramInfo.size)
case f:Funcao => aplica("RTPR "+ f.nvLex+","+f.paramInfo.size )
case e => println(e); println("Nao eh instancia proc nem func-> ERRO"); sys.exit(2)
}
}
}
//ROTULOS
def insereRotulos(lstRot: List[String], nivelLexico: Int) = {
lstRot.foreach {
id => TabelaSimb insere ( Label(id,rotulos.geraRotulo,nivelLexico) )
}
}
def entraRotulo(rotuloLogico:String,nvLex:Int) {
val rot = TabelaSimb.getById(rotuloLogico)
rot match {
case Some(e) => e match {
case r:Label =>
if (r.put) {
println("Erro: Rotulo "+r.id+" posto mais de uma vez!")
sys.exit(1)
} else {
r.put = true
//r.used = true goto should do that
aplica(r.rotulo+": ENRT "+nvLex+","+TabelaSimb.numVarsLocais(nvLex))
}
case _ => println("Erro: Rótulo "+rotuloLogico+" não declarado!"); sys.exit(1)
}
case None => println("Erro: Rótulo "+rotuloLogico+" não declarado!"); sys.exit(1)
}
}
def iniciaPrograma {
aplica("INPP")
}
def encerraPrograma = {
val countVars = proc.contaVariaveis(0)
if (countVars>0) { aplica("DMEM "+countVars) }
aplica("PARA")
}
def atribuicao(id: String) = {
val e = TabelaSimb.getById(id)
e match {
case Some(e) => e match {
case f:Funcao => aplica("ARMZ "+f.nvLex+","+f.desloc)
case v:Var => aplica("ARMZ "+v.nvLex+","+v.desloc)
case p:Param =>
if (p.byRef) aplica("ARMI "+p.nvLex+","+p.desloc) else aplica("ARMZ "+p.nvLex+","+p.desloc)
case other => println("Atribuição a "+id+" é inválida!"); sys.exit(1)
}
case None => println("identificador inválido: "+id); sys.exit(1)
}
}
def literal(num: Int) = {
aplica("CRCT "+num)
}
def aplica(cmdMEPA: String) {
MEPA += cmdMEPA
}
def gotoRotulo(rot: String, nivelLexico: Int) {
val r = TabelaSimb.getById(rot)
r match {
case Some(s) => s match {
case r:Label =>
r.used = true
aplica("DSVR "+r.rotulo+","+r.nvLex+","+nivelLexico)
case _ => println("goto para rótulo não declarado! (goto "+rot+")"); sys.exit(1)
}
case None => println("goto para rótulo não declarado! (goto "+rot+")"); sys.exit(1)
}
}
def reservadas = List("program", "label", "var", "procedure", "function","begin","end",
"if", "then", "else", "while", "do", "or", "and","div","not")
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment