diff --git a/src/main/scala/other/Parser.scala b/src/main/scala/other/Parser.scala index d20ee857a731f5af0ca51c0be7fa70a21620ef32..3862e261626a1f17c62c2132e703722ac3a2eac9 100644 --- a/src/main/scala/other/Parser.scala +++ b/src/main/scala/other/Parser.scala @@ -90,7 +90,30 @@ class Arith extends JavaTokenParsers { condicional | comando_composto | chamaId | expr_simples def atribuicao = (ident ^^ {e => eh_atrib = true; e}) <~ ":=" ~ expr_simples ^^ - { case id => eh_atrib = false; fazTudo.atribuicao(id) } + { + case id => + eh_atrib = false + verificaTipoAtrib(id) + fazTudo.atribuicao(id) } + + + def verificaTipoAtrib (idAtrib:String) { + val e = TabelaSimb.getById(idAtrib).get + val tipoExpr = stackbooltipo.pop() + val tipoAtrib = e match { + case v:Var => v.tipo + case p:Param => p.tipo + case f:Funcao => f.tipo + case _ => println("Encontrei um procedimento em uma atribuição?"); "integer" + } + //assert tipos + if (tipoExpr!="integer" && tipoAtrib!="integer") { + if (tipoExpr != tipoAtrib) { + println("Erro de tipo: Atribuição recebendo tipo diferente. (["+tipoAtrib+"] := ["+tipoExpr+"])") + sys.exit(1) + } + } //Otherwise ok! + } def desvio = "goto".iso ~> """\d+""".r ^^ { rot => fazTudo.gotoRotulo(rot,nivelLexico) } @@ -133,17 +156,7 @@ class Arith extends JavaTokenParsers { //EXPRESSOES BOOLEANAS def boolexpr:Parser[Unit] = ( - //"(" ~> boolexpr_simples ~> rep( ("and"|"or") <~ boolexpr_simples ) <~ ")" | - (boolexpr_simples ^^ {e => - val a = stackbooltipo.pop() - val b = if (stackbooltipo.isEmpty) a else stackbooltipo.pop - if (a != b) { - println("Erro de tipo: comparação entre dois tipos diferentes"); - sys.exit(1) - } - e - } ) ~> - rep ( ("and"|"or") <~ boolexpr ) + boolexpr_simples ~> rep ( ("and"|"or") <~ boolexpr ) ) ^^ { lst => lst.reverse.foreach { case "and" => fazTudo.aplica("CONJ") case "or" => fazTudo.aplica("DISJ")} @@ -154,14 +167,28 @@ class Arith extends JavaTokenParsers { expr_simples ~> relacao <~ expr_simples | "(" ~ expr_simples ~> relacao <~ expr_simples ~ ")" ) ^^ - { - case "=" => fazTudo.aplica("CMIG") - case "<>" => fazTudo.aplica("CMDG") - case "<=" => fazTudo.aplica("CMEG") - case ">=" => fazTudo.aplica("CMAG") - case "<" => fazTudo.aplica("CMME") - case ">" => fazTudo.aplica("CMMA") - case _ => sys.exit(1) + { e => + if (stackbooltipo.size < 2) + println("stackbooltipo size less than 2") + + val distinct = stackbooltipo.distinct + if (distinct.size==1 || (distinct.size==2 && distinct.contains("integer")) ) + { + //fine + } + else { + println("Erro de tipo: dois lados da expressão booleana com tipos diferentes") + sys.exit(1) + } + e match { + case "=" => fazTudo.aplica("CMIG") + case "<>" => fazTudo.aplica("CMDG") + case "<=" => fazTudo.aplica("CMEG") + case ">=" => fazTudo.aplica("CMAG") + case "<" => fazTudo.aplica("CMME") + case ">" => fazTudo.aplica("CMMA") + case _ => sys.exit(1) + } } def relacao = "<="|">="|"="|"<>"|"<"|">" @@ -198,14 +225,22 @@ class Arith extends JavaTokenParsers { def expr_simples:Parser[Object] = termo ~ rep( ("+"|"-") ~ termo ) ^^ { e => - if (stacktipo.distinct.size > 1) + //TIPO + val distinct = stacktipo.distinct + if ( distinct.size == 1 || ( distinct.size == 2 && distinct.contains("integer") ) ) { - println("Erro de tipo detectado!") - sys.exit(1) - } else { - stackbooltipo.push(stacktipo.top) + if (distinct.size==2) + //Less priority for integer + if (stacktipo.top != "integer") stackbooltipo.push( stacktipo.pop() ) + else { stacktipo.pop(); stackbooltipo.push( stacktipo.pop() ) } + else + stackbooltipo.push( stacktipo.top ) stacktipo.clear() + } else { + println("Erro de tipo detectado! Expresão com tipos diferentes") + sys.exit(1) } + //END e match { case t ~ lst if ! lst.isEmpty => lst.reverse.foreach { @@ -258,6 +293,7 @@ class Arith extends JavaTokenParsers { TabelaSimb.getById(id) match { case Some(p) if p.isInstanceOf[Param] => stacktipo.push(p.asInstanceOf[Param].tipo) case Some(v) if v.isInstanceOf[Var]=> stacktipo.push(v.asInstanceOf[Var].tipo) + case Some(f) if f.isInstanceOf[Funcao]=> stacktipo.push(f.asInstanceOf[Funcao].tipo) case _ => } if (ehProcFun(id)) { @@ -324,7 +360,7 @@ class Arith extends JavaTokenParsers { (ident ^^ { id => entraId(id); id }) <~ opt("(" ~ lista_expr ~ ")") ^^ { id => saiId(id); id } - def numero = wholeNumber ^^ { case x => fazTudo.literal(x.toInt) } + def numero = wholeNumber ^^ { case x => stacktipo.push("integer");fazTudo.literal(x.toInt) } } } diff --git a/src/main/scala/other/TabelaSimb.scala b/src/main/scala/other/TabelaSimb.scala index db2341e77df692d1ba63261df44f043df2f8ac0b..8946515289c9176954ee230aeb62a421a0a31cbc 100644 --- a/src/main/scala/other/TabelaSimb.scala +++ b/src/main/scala/other/TabelaSimb.scala @@ -3,7 +3,7 @@ import scala.annotation.tailrec class Entrada(val id:String) case class Funcao (override val id:String, paramInfo:List[Param], desloc:Int, - nvLex:Int, rotEntrada:String) extends Entrada(id) + nvLex:Int, rotEntrada:String, tipo:String = "integer") extends Entrada(id) case class Procedimento(override val id:String, paramInfo:List[Param], nvLex:Int, rotEntrada:String) extends Entrada(id) case class Param(override val id:String, desloc: Int, byRef:Boolean, nvLex:Int, tipo:String = "integer") extends Entrada(id)