diff --git a/src/main/scala/other/Tudo.scala b/src/main/scala/other/Tudo.scala index 77e804dc1e87ef00fd7f4d3f2429ab5731ca2c7c..4e733d888b81fc63a2efcd7766e5b1c84a60f235 100644 --- a/src/main/scala/other/Tudo.scala +++ b/src/main/scala/other/Tudo.scala @@ -11,7 +11,13 @@ object Tudo { def -- = num-=1 def geraRotulo = { num += 1 - "R"+ (if (num<10) "00"+num else if (num<100) "0"+num else num) + "R"+ ( + num match { + case dig if num<10 => "0"+dig + case dezena if num<100 => ""+dezena + case bigger if num>=100 => "" + bigger + } + ) } } @@ -22,56 +28,69 @@ object Tudo { TabelaSimb insere vars.map { id => val v = Var(id, desloc, nivelLexico); desloc += 1; v } - MEPA += "AMEM " + orgSize + aplica("AMEM " + orgSize) } else { - println("Erro: declaração de variáveis: identificadores já declarados: "+vars.diff(vars.distinct).mkString(" ")) + println("Erro: declaração de variáveis:") + println(" identificadores já declarados para parametros ou var: "+vars.diff(vars.distinct).mkString(" ")) + sys.exit(1) } } - def chamaId(id: String, nvLexAtual:Int):Unit = { + def geraMepaDoId(id: String, nvLexAtual:Int): Unit = + try + geraMepaDoId_code(id,nvLexAtual) + catch { + case e:IndexOutOfBoundsException => + val id = MyParser.procStack.pop.id + println("Erro: Número de parametros"+ + " incorretos na chamada da função/procedimento "+id) + sys.exit(1) + } + def isAtArgByRef() = { + MyParser.procStack.top match { + case p:Procedimento => p.paramInfo(MyParser.paramCounterStack.top).byRef + case f:Funcao => f.paramInfo(MyParser.paramCounterStack.top).byRef + case o => false //write and read will get here + } + } + + private def geraMepaDoId_code(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 - } + val isByRef = isAtArgByRef() if (isByRef) - aplica("CREN "+v.nvLex+","+v.desloc) + aplica("CREN "+v.nvLex+", "+v.desloc) else - aplica("CRVL "+v.nvLex+","+v.desloc) + aplica("CRVL "+v.nvLex+", "+v.desloc) } else - aplica("CRVL "+v.nvLex+","+v.desloc) + 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 - } + val isByRef = isAtArgByRef() if (isByRef) - if (p.byRef) aplica("CRVL "+p.nvLex+","+p.desloc) else aplica("CREN "+p.nvLex+","+p.desloc) + 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) + 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) + 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 p:Procedimento => aplica("CHPR "+p.rotEntrada+","+nvLexAtual) + case f:Funcao => aplica("CHPR "+f.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") - } } } @@ -104,7 +123,13 @@ object Tudo { case Some( lstParams ) if ! lstParams.isEmpty => val ps = retornaParamsLst(lstParams, nivelLexico) TabelaSimb.insere( Procedimento(id, ps, nivelLexico, rotulo) ) - ps.foreach { TabelaSimb.insere } + ps.foreach { param => + if (TabelaSimb.temParamOuVarComMesmoId(param.id)) { + println("Erro: Parâmetros com mesmo nome no procedimento "+id+": "+ param.id) + sys.exit(1) + } + TabelaSimb.insere(param) + } case None => TabelaSimb.insere( Procedimento(id, List.empty, nivelLexico, rotulo) ) } @@ -118,9 +143,15 @@ object Tudo { val ps = retornaParamsLst(lstParams, nivelLexico) val desloc = -4-ps.size TabelaSimb.insere( Funcao(id,ps,desloc,nivelLexico,rotulo) ) - ps.foreach { TabelaSimb.insere } + ps.foreach { param => + if (TabelaSimb.temParamOuVarComMesmoId(param.id)) { + println("Erro: Parâmetros com mesmo nome na função "+id+": "+ param.id) + sys.exit(1) + } + TabelaSimb.insere(param) + } case None => - TabelaSimb.insere( Funcao(id, null, -4, nivelLexico,rotulo) ) + TabelaSimb.insere( Funcao(id, List.empty, -4, nivelLexico, rotulo) ) } } @@ -172,8 +203,8 @@ object Tudo { ) TabelaSimb.top match { - case p:Procedimento => aplica("RTPR "+ p.nvLex +","+p.paramInfo.size) - case f:Funcao => aplica("RTPR "+ f.nvLex+","+f.paramInfo.size ) + 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) } } @@ -197,7 +228,7 @@ object Tudo { } else { r.put = true //r.used = true goto should do that - aplica(r.rotulo+": ENRT "+nvLex+","+TabelaSimb.numVarsLocais(nvLex)) + aplica(r.rotulo+": ENRT "+nvLex+", "+TabelaSimb.numVarsLocais(nvLex)) } case _ => println("Erro: Rótulo "+rotuloLogico+" não declarado!"); sys.exit(1) } @@ -219,10 +250,10 @@ object Tudo { 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 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) + 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) @@ -233,17 +264,21 @@ object Tudo { aplica("CRCT "+num) } - def aplica(cmdMEPA: String) { - MEPA += cmdMEPA - } + def aplica(cmdMEPA: String) : Unit = + MEPA += (if ( ! cmdMEPA.contains(":") ) " " else "") + cmdMEPA + def paplica(cmdMEPA: String) = { + println(cmdMEPA) + aplica(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) + 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)