/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package frontend.Ivannosys; import API.BuildParams; import API.Functions; import API.Imports; import API.Interfaces; import API.Types; import API.Utils; import API.Variables; import ast.AbstractSyntaxTree; import ast.Node; import common.Instruction; import common.Log; import compiler.IvannosysCompiler; import grammar.IvannosysGrammarBaseListener; import grammar.IvannosysGrammarParser; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Stack; import java.util.logging.Level; import java.util.logging.Logger; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.TerminalNode; /** * * @author Eugenio */ public class IvannosysListener extends IvannosysGrammarBaseListener { protected int uniq = 0; protected int InsideType; protected boolean insideSwitch = false; // protected String packageName; protected Log errors; protected AbstractSyntaxTree ast; protected IvannosysCompiler compiler; protected Stack scopeStack = new Stack<>(); protected Stack scopeFile = new Stack<>(); protected LinkedList ReadId = new LinkedList<>(); protected HashMap packages = new HashMap<>(); protected LinkedList TypePath; // protected final ArrayList paths; // protected boolean returnReferece; // protected int paramPosition; // protected int defAtribuicaoIndex; // protected int returnPosition; protected LinkedList packageNames = new LinkedList<>(); public IvannosysListener(IvannosysCompiler comp) throws Exception { ast = AbstractSyntaxTree.getAbstractSyntaxTree(); compiler = comp; errors = new Log(); this.ReadId.push(true); } public Log Error() { return errors; } @Override public void enterBuild_stmt(IvannosysGrammarParser.Build_stmtContext ctx) { String tag = ctx.ID().getText(); ArrayList values = new ArrayList<>(); String value; for (IvannosysGrammarParser.BuildvalueContext id : ctx.buildvalue()) { value = id.getText().trim(); if (value.contains("`")) { value = value.replace("`", ""); } values.add(value); } BuildParams.Set(tag, values); // ast.getCompileParams().addList(tag, values); super.enterBuild_stmt(ctx); //To change body of generated methods, choose Tools | Templates. } //INIT @Override public void enterInit(IvannosysGrammarParser.InitContext ctx) { packageNames.push(ctx.ID().getText()); String scope = packageNames.peek(); setEscopo(scope); Node root = ast.getRoot(); ast.Current(root); ast.setNode(new Node(packageNames.peek()).Set("class", "package")); scopeFile.push(scope + "::" + ctx.ID().getText()); astBaseSet(ctx); List imps = ctx.imports(); if (imps.size() > 0) { Node imports = astSetCurrentNode("imports", ctx); imports.Set("class", "imports"); String alias, path, defaultname; String[] parts; for (IvannosysGrammarParser.ImportsContext imp : imps) { for (IvannosysGrammarParser.Import_partContext impPart : imp.import_part()) { path = impPart.T_STRING().getText().replaceAll("\"", ""); parts = path.split("/"); defaultname = parts[parts.length - 1]; if (impPart.ID() != null) { alias = impPart.ID().getText().replaceAll("\"", ""); } else { alias = defaultname; } packages.put(alias, path); imports.addFilho(new Node(alias) .Set("path", path) .Set("default", defaultname)); } } astReturnLevel(); } super.enterInit(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitInit(IvannosysGrammarParser.InitContext ctx) { // if (ctx.R_INIT_LIBRARY() != null) { // astReturnLevel(); // } astReturnLevel(); ast.Back(); scopeStack.pop(); scopeFile.pop(); // Extracao de contantes, variaveis, funcoes e metodos // if (packageNames.peek().equals("main")) { // // } packageNames.pop(); // InitConstantes(ctx); super.exitInit(ctx); //To change body of generated methods, choose Tools | Templates. } /** * * * */ @Override public void enterNewstmt(IvannosysGrammarParser.NewstmtContext ctx) { astSetCurrentNode("new", ctx); astSetAtributo("class", "new"); super.enterNewstmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitNewstmt(IvannosysGrammarParser.NewstmtContext ctx) { String size = "1"; if (ctx.T_INTEIRO() != null) { size = ctx.T_INTEIRO().getText(); } astAddChildren(size); astReturnLevel(); super.exitNewstmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFallthroughStmt(IvannosysGrammarParser.FallthroughStmtContext ctx) { astSetCurrentNode("fallthrough", ctx).Set("class", "fallthrough.stmt"); super.enterFallthroughStmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFallthroughStmt(IvannosysGrammarParser.FallthroughStmtContext ctx) { astReturnLevel(); super.exitFallthroughStmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDelete(IvannosysGrammarParser.DeleteContext ctx) { astSetCurrentNode("delete", ctx); astSetAtributo("class", "delete"); super.enterDelete(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDelete(IvannosysGrammarParser.DeleteContext ctx) { astReturnLevel(); super.exitDelete(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDec_var_part(IvannosysGrammarParser.Dec_var_partContext ctx) { astSetCurrentNode("dec.var", ctx); astSetAtributo("class", "dec.var"); super.enterDec_var_part(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDec_var_part(IvannosysGrammarParser.Dec_var_partContext ctx) { try { DeclVar(ctx, astCurrent()); astReturnLevel(); super.exitDec_var_part(ctx); //To change body of generated methods, choose Tools | Templates. } catch (Exception ex) { Logger.getLogger(IvannosysListener.class.getName()).log(Level.SEVERE, null, ex); } } protected void DeclVar(ParserRuleContext ctx, Node node) throws Exception { int i = 0; String varname, t, value; Node variable, exprs = node.find("exprs"), type = node.find("type"); ArrayList> valuesGroup = new ArrayList<>(); ArrayList types = new ArrayList<>(), values; ArrayList ids = node.find("ids").childrens(); ArrayList> indexes = new ArrayList<>(); if (type != null) { // System.out.println("DeclVar:" + type); // Quando declarado normal t = type.Get("type"); for (int k = 0; k < ids.size(); k++) { types.add(t); indexes.add(type.childrens()); values = new ArrayList<>(); if (exprs != null) { Node e = exprs.childrens().get(k); // for (Node e : exprs.childrens()) { switch (e.Class()) { // case "selector": // break; default: value = e.Get("value"); switch (t) { case "bool": value = value.equals("true") ? "1" : "0"; } values.add(value); // System.out.println("Ey:" + e); } // } } valuesGroup.add(values); } } else { // Quando declarado encurtado //Todo fazer os tipos inferidos; for (Node e : exprs.childrens()) { values = new ArrayList<>(); switch (e.Class()) { case "call": // System.out.println("Call:" + e.getText()); try { Node def = Functions.Get(e.getText()); for (Node rtype : def.find("dec.return").childrens()) { types.add(rtype.Get("type")); indexes.add(new ArrayList()); } } catch (Exception ex) { errors.AddError(new Instruction() .Set("class", "Call") .Set("msg", ex.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } break; case "literal": // System.out.println("Lit:" + e); if (e.eq("subclass", "array")) { ArrayList indc = new ArrayList<>(); indexes.add(indc); indc.add(new Node("" + e.find("exprs").childrens().size())); types.add(e.find("exprs").childrens().get(0).Get("type")); } break; case "expr": // System.out.println("Exp:" + e); types.add(e.Get("type")); indexes.add(new ArrayList()); break; default: // System.out.println("E:" + e); types.add(e.Get("type")); indexes.add(e.childrens()); break; } valuesGroup.add(values); } } // System.out.println("types:" + types); for (Node var : node.find("ids").childrens()) { varname = scopeStack.peek() + "." + var.getText(); // nmm // System.out.println("DecVariavel:" + varname); t = types.get(i); var.Set("type", t) .Set("value", varname) .Set("fullname", varname) .Set("name", var.getText()) .Set("class", "ID") .Set("array", "" + (indexes.get(i).size() > 0)) .Set("array_size", "" + ArraySize(indexes.get(i))) .Copy("pointer", type); variable = new Node(varname) .Set("global", "" + (scopeStack.peek().split("\\.").length == 1)) .Set("fullname", varname) .Set("name", var.getText()) .Set("class", "selector") .Set("subclass", "operand"); variable.Copy("type,value,pointer,array,array_size", var); variable.addList("default.values", valuesGroup.get(i)); astBaseSet(ctx, variable); if (exprs != null) { // expr = exprs.childrens.Get(i++); // variable.addFilho(expr); } variable.childrens = indexes.get(i); // System.out.println("DeclVAR:" + varname + "|" + variable); try { Variables.Add(varname, variable); } catch (Exception e) { errors.AddError(new Instruction() .Set("class", "Decl.Var") .Set("msg", e.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } i++; } } protected String ArraySize(ArrayList indexes) throws Exception { int result = 1, v; for (Node index : indexes) { if (index.isNumber("value")) { v = index.GetInt("value"); } else { v = 1; } result *= v; } return "" + result; } @Override public void enterExpression_list(IvannosysGrammarParser.Expression_listContext ctx) { astSetCurrentNode("exprs", ctx); astSetAtributo("class", "exprs"); super.enterExpression_list(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitExpression_list(IvannosysGrammarParser.Expression_listContext ctx) { astReturnLevel(); super.exitExpression_list(ctx); //To change body of generated methods, choose Tools | Templates. } //DECLARACAO DE CONSTANTES ------------------------------------------------- @Override public void enterDec_const_part(IvannosysGrammarParser.Dec_const_partContext ctx) { astSetCurrentNode("const", ctx); astSetAtributo("class", "dec.const"); astBaseSet(ctx); Node label = new Node(ctx.ID().getText()); label.Set("class", "ID"); astAddChildren(label); super.enterDec_const_part(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDec_const_part(IvannosysGrammarParser.Dec_const_partContext ctx) { // String id = ctx.ID().getText(); astBaseSet(ctx); Node node = astCurrent() .Set("constant", "true"); ArrayList childrens = node.childrens(); String id = childrens.get(0).getText(); Node value = childrens.get(1); String varID = scopeStack.peek() + "." + id; //nmm // System.out.println("DECCONST:" + varID); Node var = new Node(varID) .Set("fullname", varID) .Set("name", id) .Set("default.value", value.getText()) .Set("constant", "true") .Set("pointer", "false") .Set("array", "false") .Copy("file,scope,line,col,type", value); try { Variables.Add(varID, var); } catch (Exception e) { errors.AddError( (Instruction) new Instruction() .Set("class", "Import") .Set("msg", e.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } astReturnLevel(); super.exitDec_const_part(ctx); //To change body of generated methods, choose Tools | Templates. } public String getTypeOfPrimitive(IvannosysGrammarParser.Primitive_valueContext ctx) { if (ctx.T_BOOL_FALSE() != null || ctx.T_BOOL_TRUE() != null) { return "bool"; } else if (ctx.T_CHAR() != null) { return "char"; } else if (ctx.T_INTEIRO() != null) { return "int32"; } return "undefined"; } @Override public void enterPrimitive_value(IvannosysGrammarParser.Primitive_valueContext ctx) { if (!this.ReadId.peek()) { return; } String classe = "value", type = getTypeOfPrimitive(ctx), subclasse = ""; if (!Types.Primitive(type)) { errors.AddError((Instruction) new Instruction() .Set("class", "Import") .Set("msg", "Primitive type undefined.") .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); return; } // if (ctx.T_BOOL_FALSE() != null || ctx.T_BOOL_TRUE() != null) { // type = "bool"; // subclasse = "boolean"; // } else if (ctx.T_CHAR() != null) { // type = "char"; // subclasse = "char"; // } else if (ctx.T_INTEIRO() != null) { // type = "int32"; // subclasse = "integer"; // } else { // return; // } astSetCurrentNode(ctx.getText(), ctx); astSetAtributo("type", type); astSetAtributo("class", classe); astSetAtributo("subclass", classe); astBaseSet(ctx); super.enterPrimitive_value(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitPrimitive_value(IvannosysGrammarParser.Primitive_valueContext ctx) { if (!this.ReadId.peek()) { return; } astReturnLevel(); super.exitPrimitive_value(ctx); //To change body of generated methods, choose Tools | Templates. } // Definicao de tipos @Override public void enterType(IvannosysGrammarParser.TypeContext ctx) { // if (this.InsideType == 0) { //// System.out.println("???? Type:" + typename + ":" + this.InsideType); //// System.out.println("Type:" + ctx.getText()); // this.TypePath = new LinkedList<>(); astSetCurrentNode("type", ctx); astBaseSet(ctx); astSetAtributo("class", "type"); // } // // if (ctx.R_OP_AST() != null) { // astSetAtributo("pointer", "*"); // // } else if (ctx.ltype != "" && ctx.ltype != null && !ctx.ltype.equals("null")) { // // String base = ctx.ltype; // Node imports = ast.getPackage(packageNames.peek()).find("imports"); // if (imports != null) { // Node impt = imports.find(ctx.ltype); // if (impt != null) { // base = impt.Get("default"); // } // } //// System.out.println("Ctx ltype " + base); // this.TypePath.addFirst(base); // } else if (ctx.expression_seletor() != null) { // //// System.out.println("Ctx seletor " + ctx.expression_seletor().ID().getText()); // this.TypePath.addFirst(ctx.expression_seletor().ID().getText()); // // } else if (ctx.type() != null) { //// System.out.println("Ctx type " + ctx.type().getText()); // this.TypePath.addFirst(ctx.type().getText()); // } else if (ctx.ID() != null) { //// System.out.println("Ctx id " + ctx.ID().getText()); // this.TypePath.addFirst(ctx.ID().getText()); // } // // this.InsideType++; super.enterType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitType(IvannosysGrammarParser.TypeContext ctx) { String typename = ctx.ltype; // Adiciona o pacote local se não for um tipo primitivo e não possui um pacote if (!Types.Primitive(typename)) { String pack = packageNames.peek(); // Se não tem formato "pacote.tipo" if (typename.indexOf(".") < 0 && !pack.equals("main")) { // local type typename = packageNames.peek() + "." + typename; // System.out.println("ExitTypeL:" + typename + "::" + pack); } else { // imported type // Carrega pacote se não for o pacote local String[] parts = typename.split("\\."); // System.out.println("ExitType:" + typename + "::" + pack); if (!parts[0].equals(pack)) { try { Imports.Load(parts[0]); } catch (Exception ex) { Logger.getLogger(IvannosysListener.class.getName()).log(Level.SEVERE, null, ex); return; } Node imports = ast.getPackage(pack).find("imports"); if (imports != null) { Node impt = imports.find(ctx.ltype); if (impt != null) { typename = impt.Get("default") + "." + ctx.ltype; } } } } } // System.out.println("Out of type :" + ctx.ltype + ":" + ctx.getText()); // System.out.println("TYPE:" + typename); Node type = astCurrent().Set("type", typename); ArrayList indexes = new ArrayList<>(); for (Node x : type.childrens()) { if (x.eq("class", "index")) { indexes.add(x); } } type.childrens = indexes; astReturnLevel(); // } super.exitType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterIndexedType(IvannosysGrammarParser.IndexedTypeContext ctx) { if (ctx.index() != null) { String val = ctx.index().expression().getText(); if (!Utils.IsNumber(val)) { Node ref = Variables.Get(scopeStack.peek() + "." + val); //nmmd if (ref != null && ref.eq("constant", "true")) { // System.out.println("INDEXEDTYPE" + constante); val = ref.Get("default.value"); } } astAddChildren(val) .Set("class", "index"); } super.enterIndexedType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterTypename(IvannosysGrammarParser.TypenameContext ctx) { if (ctx.R_OP_AST() != null) { astSetAtributo("pointer", "*"); // System.out.println("ENTERTYPENAME = " + ctx.ltype); } super.enterTypename(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitTypename(IvannosysGrammarParser.TypenameContext ctx) { super.exitTypename(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDef_type(IvannosysGrammarParser.Def_typeContext ctx) { astSetCurrentNode(ctx.ID().getText(), ctx); astSetAtributo("class", "dec.type"); astBaseSet(ctx); super.enterDef_type(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_type(IvannosysGrammarParser.Def_typeContext ctx) { Node defType = astCurrent(); try { Types.Add(packageNames.peek() + "." + defType.getText(), defType); } catch (Exception e) { errors.AddError((Instruction) new Instruction() .Set("class", "Import") .Set("msg", e.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } astReturnLevel(); super.exitDef_type(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterArguments(IvannosysGrammarParser.ArgumentsContext ctx) { // Chamda de funcao astSetCurrentNode("arguments", ctx); if (ctx.expression_list() != null) { // Declaracao } else if (ctx.expression_list_typed().size() > 0) { } // astSetCurrentNode("args", ctx); super.enterArguments(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitArguments(IvannosysGrammarParser.ArgumentsContext ctx) { astReturnLevel(); super.exitArguments(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterExpression_list_typed(IvannosysGrammarParser.Expression_list_typedContext ctx) { astSetCurrentNode("argument", ctx).Set("class", "argument"); super.enterExpression_list_typed(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitExpression_list_typed(IvannosysGrammarParser.Expression_list_typedContext ctx) { Node argument = astCurrent(); if (argument != null && argument.find("ids") != null) { try { // System.out.println("Argument:" + argument); DeclVar(ctx, argument); } catch (Exception ex) { Logger.getLogger(IvannosysListener.class.getName()).log(Level.SEVERE, null, ex); } } astReturnLevel(); super.exitExpression_list_typed(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterId_list(IvannosysGrammarParser.Id_listContext ctx) { astSetCurrentNode("ids", ctx); for (TerminalNode id : ctx.ID()) { astAddChildren(id.getText()); } super.enterId_list(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitId_list(IvannosysGrammarParser.Id_listContext ctx) { astReturnLevel(); super.exitId_list(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterStructType(IvannosysGrammarParser.StructTypeContext ctx) { super.enterStructType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitStructType(IvannosysGrammarParser.StructTypeContext ctx) { Node decl = astCurrent(), type; ArrayList attribs = new ArrayList<>(); ArrayList decls = decl.childrens(); // System.out.println("StructType:" + decl); for (Node ids : decl.findAll("ids", "value")) { type = decls.get(decls.indexOf(ids) + 1); for (Node id : ids.childrens()) { astBaseSet(ctx, id); id.Set("class", "attr"); id.addFilho(type); attribs.add(id); } } decl.childrens = attribs; super.exitStructType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterComposite(IvannosysGrammarParser.CompositeContext ctx) { // astSetCurrentNode("composite", ctx); super.enterComposite(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitComposite(IvannosysGrammarParser.CompositeContext ctx) { // astReturnLevel(); super.exitComposite(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterArrayType(IvannosysGrammarParser.ArrayTypeContext ctx) { astCurrent() .Set("class", "literal") .Set("value", "literal") .Set("subclass", "array"); super.enterArrayType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitArrayType(IvannosysGrammarParser.ArrayTypeContext ctx) { super.exitArrayType(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFieldDecl(IvannosysGrammarParser.FieldDeclContext ctx) { super.enterFieldDecl(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFieldDecl(IvannosysGrammarParser.FieldDeclContext ctx) { // if (ctx.id_list() != null) { // for (TerminalNode x : ctx.id_list().ID()) { //// astSetCurrentNode(x.getText(), ctx); //// astSetAtributo("class", "attr"); //// astReturnLevel(); // } // } else if (ctx.anon_field() != null) { //// ctx.anon_field().typename().getText() // } // Node decl = astCurrent(), type; // ArrayList attribs = new ArrayList<>(); // ArrayList decls = decl.childrens(); // // for (Node ids : decl.findAll("ids", "value")) { // type = decls.Get(decls.indexOf(ids) + 1); // for (Node id : ids.childrens()) { // System.out.println("Add attr:" + id + type); // astBaseSet(ctx, id); // id.Set("class", "attr"); // id.addFilho(type); // attribs.Add(id); // } // } // decl.childrens = attribs; super.exitFieldDecl(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterIndex(IvannosysGrammarParser.IndexContext ctx) { super.enterIndex(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitIndex(IvannosysGrammarParser.IndexContext ctx) { super.exitIndex(ctx); //To change body of generated methods, choose Tools | Templates. } // Definicao de um bloco de instrucoes @Override public void enterDef_block(IvannosysGrammarParser.Def_blockContext ctx) { astSetCurrentNode("stmts", ctx); astSetAtributo("class", "stmts"); astBaseSet(ctx); super.enterDef_block(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_block(IvannosysGrammarParser.Def_blockContext ctx) { astReturnLevel(); super.exitDef_block(ctx); //To change body of generated methods, choose Tools | Templates. } // Definicao do retorno de uma funcao @Override public void enterReturn_stmt(IvannosysGrammarParser.Return_stmtContext ctx) { astSetCurrentNode("return", ctx); astSetAtributo("class", "return"); astBaseSet(ctx); super.enterReturn_stmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitReturn_stmt(IvannosysGrammarParser.Return_stmtContext ctx) { astReturnLevel(); super.exitReturn_stmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterInc_dec(IvannosysGrammarParser.Inc_decContext ctx) { astSetCurrentNode("incdec.stmt", ctx); astSetAtributo("class", "incdec"); astSetCurrentNode(ctx.op.getText(), ctx); astSetAtributo("class", "operator"); astReturnLevel(); super.enterInc_dec(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitInc_dec(IvannosysGrammarParser.Inc_decContext ctx) { astReturnLevel(); super.exitInc_dec(ctx); //To change body of generated methods, choose Tools | Templates. } //DECLARACAO DE FUNCOES protected String __functionName__(IvannosysGrammarParser.Def_functionContext ctx) { return ((ctx.name != null) ? ctx.name.getText() : ("anonymous." + this.uniq++)); } @Override public void enterDef_function(IvannosysGrammarParser.Def_functionContext ctx) { String id = this.__functionName__(ctx), classe; // setEscopo("func." + id); setEscopo(id); astSetCurrentNode(id, ctx); astBaseSet(ctx); if (ctx.receive_type() != null) { astSetAtributo("method", "true"); classe = "dec.method"; } else { classe = "dec.func"; } astSetAtributo("class", classe); super.enterDef_function(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_function(IvannosysGrammarParser.Def_functionContext ctx) { Node node = astCurrent(); ArrayList name = null; if (ctx.receive_type() != null) { astSetAtributo("method", "true"); name = new ArrayList(); // name.add(packageNames.peek()); name.add("method"); name.add("(" + node.find("receive.type").find("type").Get("type") + ")"); // type } else { if (name == null) { name = new ArrayList(); name.add(packageNames.peek()); } } // Adiciona o nome da funcao name.add(node.getText()); node.Set("name", node.getText()); try { astBaseSet(ctx, node); Functions.Add(Utils.Join(name, "."), node); } catch (Exception e) { errors.AddError( (Instruction) new Instruction() .Set("class", "Decl.Func") .Set("msg", e.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } scopeStack.pop(); astReturnLevel(); super.exitDef_function(ctx); //To change body of generated methods, choose Tools | Templates. } /** * Não possui valor padrão. corresponde a variavel da qual é chamado um * metodo * * @param ctx */ @Override public void enterReceive_type(IvannosysGrammarParser.Receive_typeContext ctx) { astSetCurrentNode("receive.type", ctx); astAddChildren(ctx.ID().getText()).Set("class", "ID"); super.enterReceive_type(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitReceive_type(IvannosysGrammarParser.Receive_typeContext ctx) { ArrayList parts = astCurrent().childrens(); String varname = parts.get(0).getText(); String fullname = scopeStack.peek() + "." + varname; //nmmd // System.out.println("Received"); // astBaseSet(ctx); parts.get(0).Set("value", fullname); Node var = new Node(fullname) .Set("fullname", fullname) .Set("name", varname) .Set("pointer", parts.get(1).Get("pointer")) .Set("type", parts.get(1).Get("type")); // System.out.println("POINTER[" + fullname + "]:" + parts.Get(1).Get("pointer")); try { Variables.Add(fullname, var); } catch (Exception e) { errors.AddError( (Instruction) new Instruction() .Set("class", "Import") .Set("msg", e.getMessage()) .Set("line", ctx.getStart().getLine()) .Set("col", ctx.getStart().getCharPositionInLine())); } astReturnLevel(); super.exitReceive_type(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterReturn_dec(IvannosysGrammarParser.Return_decContext ctx) { astSetCurrentNode("dec.return", ctx); super.enterReturn_dec(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitReturn_dec(IvannosysGrammarParser.Return_decContext ctx) { astReturnLevel(); super.exitReturn_dec(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDef_interface(IvannosysGrammarParser.Def_interfaceContext ctx) { astSetCurrentNode(ctx.ID().getText(), ctx); astSetAtributo("class", "dec.interface"); astSetAtributo("package", ""); super.enterDef_interface(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_interface(IvannosysGrammarParser.Def_interfaceContext ctx) { Node node = astCurrent(); Interfaces.Add(packageNames.peek() + "." + node.getText(), node); astReturnLevel(); super.exitDef_interface(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFunc_spec(IvannosysGrammarParser.Func_specContext ctx) { astSetCurrentNode(ctx.ID().getText(), ctx); astSetAtributo("class", "desc.method"); super.enterFunc_spec(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFunc_spec(IvannosysGrammarParser.Func_specContext ctx) { astReturnLevel(); super.exitFunc_spec(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDec_var_short(IvannosysGrammarParser.Dec_var_shortContext ctx) { astSetCurrentNode("dec.var.short", ctx); astSetAtributo("class", "def.assign"); // List ids = ctx.id_list().ID(); // List expr = ctx.expression_list().expression(); // int idsLen = ids.size(), exprLen = expr.size(); // // if (idsLen == exprLen) {// Caso OK //// Node inode; //// for (TerminalNode id : ids) { //// inode = astAddChildren(id.getText()); //// inode.Set("class", "ID"); //// } // // } else if (idsLen < exprLen) {// Menos endereco de atribuicao // // } else {// Mais endereco de atribuicao // // } super.enterDec_var_short(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDec_var_short(IvannosysGrammarParser.Dec_var_shortContext ctx) { try { DeclVar(ctx, astCurrent()); astReturnLevel(); super.exitDec_var_short(ctx); //To change body of generated methods, choose Tools | Templates. } catch (Exception ex) { Logger.getLogger(IvannosysListener.class.getName()).log(Level.SEVERE, null, ex); } } @Override public void enterDef_for(IvannosysGrammarParser.Def_forContext ctx) { String id = "for_" + this.__uniq__(); setEscopo(id); astSetCurrentNode(id, ctx); astSetAtributo("class", "for.stmt"); astBaseSet(ctx); super.enterDef_for(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_for(IvannosysGrammarParser.Def_forContext ctx) { scopeStack.pop(); astReturnLevel(); super.exitDef_for(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterIncrement(IvannosysGrammarParser.IncrementContext ctx) { astSetCurrentNode("increment", ctx); super.enterIncrement(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitIncrement(IvannosysGrammarParser.IncrementContext ctx) { astReturnLevel(); super.exitIncrement(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterInitialization(IvannosysGrammarParser.InitializationContext ctx) { astSetCurrentNode("initialization", ctx); super.enterInitialization(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitInitialization(IvannosysGrammarParser.InitializationContext ctx) { astReturnLevel(); super.exitInitialization(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterTest(IvannosysGrammarParser.TestContext ctx) { astSetCurrentNode("test", ctx).Set("class", "test"); super.enterTest(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitTest(IvannosysGrammarParser.TestContext ctx) { // if (astCurrent().childrens().size() == 0) { // astCurrent().parent.removeFilho(astCurrent()); // } astReturnLevel(); super.exitTest(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFor_clause(IvannosysGrammarParser.For_clauseContext ctx) { // astSetCurrentNode("ctrl", ctx); // astSetAtributo("class", "ctrl"); // astSetAtributo("subclass", "clause"); super.enterFor_clause(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFor_clause(IvannosysGrammarParser.For_clauseContext ctx) { // astReturnLevel(); super.exitFor_clause(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFor_each(IvannosysGrammarParser.For_eachContext ctx) { astSetCurrentNode("range", ctx); astSetAtributo("class", "range"); // this.ReadId.push(false); // astSetAtributo("subclass", "each"); super.enterFor_each(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFor_each(IvannosysGrammarParser.For_eachContext ctx) { // this.ReadId.pop(); Node range = astCurrent(), ids = new Node("ids"); range.Set("type", ctx.R_SHORT_VAR() != null ? "dec" : "assign"); ids.Set("class", "ids"); for (Node n : range.findAll("selector", "class")) { ids.addFilho(n); range.removeFilho(n); } astAddChildren(ids); astReturnLevel(); super.exitFor_each(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterUnary_expr(IvannosysGrammarParser.Unary_exprContext ctx) { // System.out.println("Unary:" + ctx.getText()); if (ctx.op != null) { String subclass, op = ctx.op.getText(); switch (op) { case "&": subclass = "address"; break; case "!": subclass = "negation.bool"; break; case "+": subclass = "add"; break; case "-": subclass = "negation.arith"; break; case "*": subclass = "content"; break; default: return; } astSetCurrentNode("unary", ctx) .Set("class", "unary") .Set("subclass", subclass); astAddChildren(op) .Set("class", "operator"); } super.enterUnary_expr(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitUnary_expr(IvannosysGrammarParser.Unary_exprContext ctx) { if (ctx.op != null) { Node c = astCurrent(); c.Set("type", c.childrens().get(1).Get("type")); astReturnLevel(); } super.exitUnary_expr(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDef_assign_op(IvannosysGrammarParser.Def_assign_opContext ctx) { astSetCurrentNode("def.assign", ctx); astSetAtributo("class", "def.assign"); IvannosysGrammarParser.Assign_modifyContext mod = ctx.assign_modify(); if (mod != null) { astSetAtributo("modify", mod.getText()); } astBaseSet(ctx); // super.enterDef_assign_op(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_assign_op(IvannosysGrammarParser.Def_assign_opContext ctx) { for (Node address : astCurrent().first().childrens()) { address.Set("access", "write"); } astReturnLevel(); // super.exitDef_assign_op(ctx); //To change body of generated methods, choose Tools | Templates. } // //CONTROLE // //IF-ELSE @Override public void enterDef_if(IvannosysGrammarParser.Def_ifContext ctx ) { astSetCurrentNode("if." + this.__uniq__(), ctx); astSetAtributo("class", "if.stmt"); astBaseSet(ctx); super.enterDef_if(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_if(IvannosysGrammarParser.Def_ifContext ctx) { astReturnLevel(); super.exitDef_if(ctx); //To change body of generated methods, choose Tools | Templates. } //IFBLOCK @Override public void enterDef_if_block(IvannosysGrammarParser.Def_if_blockContext ctx) { astSetCurrentNode("if.case.stmt", ctx); astSetAtributo("class", "if.case.stmt"); astBaseSet(ctx); super.enterDef_if_block(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_if_block(IvannosysGrammarParser.Def_if_blockContext ctx) { astReturnLevel(); super.exitDef_if_block(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterRange(IvannosysGrammarParser.RangeContext ctx) { astSetCurrentNode("range.gen", ctx); super.enterRange(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitRange(IvannosysGrammarParser.RangeContext ctx) { astReturnLevel(); super.exitRange(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterPrimary_expr(IvannosysGrammarParser.Primary_exprContext ctx) { String base = "", funcname = "", subclasse = "", classe = "selector", type = "", pointer = "", name = "", classType = "", ctxVar = ""; Node d = new Node(""); astBaseSet(ctx, d); if (ctx.getParent().getClass().getName().equals("grammar.IvannosysGrammarParser$Primary_exprContext")) { // System.out.println("Return Primary_expr:" + ctx.getText()); return; } else if (ctx.arguments() != null) { base = ctx.primary_expr().getText(); classe = "call"; subclasse = "arguments"; // É o acesso de uma funcao do pacote atual if (base.indexOf(".") == -1) { funcname = base; base = packageNames.peek() + "." + base; name = base; } else { String[] parts = base.split("\\."); if (parts.length >= 2 && !packages.containsKey(parts[0])) { // System.out.println("Base:" + +"." + base); // É sempre um metodo ArrayList p = new ArrayList<>(); p.add(scopeStack.peek()); for (int k = 0; k < parts.length - 1; k++) { p.add(parts[k]); } ctxVar = Utils.Join(p, "."); String t = Variables.Type(ctxVar); funcname = parts[parts.length - 1]; name = funcname; // base = packageNames.peek() + ".method.(" + t + ")." + funcname; base = "method.(" + t + ")." + funcname; } else { name = funcname = parts[1]; // É um acesso de uma funcao de um pacote } } } else if (ctx.operand() != null) { base = ctx.operand().getText(); if (ctx.operand().primitive_value() != null) { classType = "value"; type = getTypeOfPrimitive(ctx.operand().primitive_value()); } else { try { base = scopeStack.peek() + "." + base;//NMM type = Variables.TypeOf(base); pointer = Variables.Get(base).Get("pointer"); } catch (Exception ex) { // Logger.getLogger(IvannosysListener.class.getName()).Log(Level.SEVERE, null, ex); } } subclasse = "operand"; } else if (ctx.expression_seletor() != null) { try { base = scopeStack.peek() + "." + ctx.primary_expr().getText() + "." + ctx.expression_seletor().ID().getText(); subclasse = "selector"; type = Variables.TypeOf(base); } catch (Exception ex) { // Logger.getLogger(IvannosysListener.class.getName()).Log(Level.SEVERE, null, ex); } } else if (ctx.index() != null) { try { subclasse = "index"; base = scopeStack.peek() + "." + ctx.id; type = Variables.TypeOf(base); } catch (Exception ex) { // Logger.getLogger(IvannosysListener.class.getName()).Log(Level.SEVERE, null, ex); } } ast.setNode(d.Set("value", base) .Set("class", classe) .Set("subclass", subclasse) .Set("type", type) .Set("name", name) .Set("pointer", pointer) .Set("classType", classType)); if (funcname != "") { d.Set("ctx", ctxVar).Set("funcname", funcname); } this.ReadId.push(false); // System.out.println("PrimaryExpr:" + base + "<>" + ctx.getText()); super.enterPrimary_expr(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitPrimary_expr(IvannosysGrammarParser.Primary_exprContext ctx) { if (ctx.getParent().getClass().getName().equals("grammar.IvannosysGrammarParser$Primary_exprContext")) { return; } else if (ctx.arguments() != null) { // System.out.println("packageName:" + packageName); // Functions.Add(, null); // base = ctx.primary_expr().getText(); // classe = "call"; // subclasse = "arguments"; } this.ReadId.pop(); astReturnLevel(); super.exitPrimary_expr(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterExpression_seletor(IvannosysGrammarParser.Expression_seletorContext ctx) { super.enterExpression_seletor(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitExpression_seletor(IvannosysGrammarParser.Expression_seletorContext ctx) { super.exitExpression_seletor(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterExpression(IvannosysGrammarParser.ExpressionContext ctx) { if (ctx.op != null) { // expr_operation String op = ctx.op.getText(), classe = "", subclasse = "", type = ""; switch (op) { case "||": case "&&": case "==": case "!=": case "<": case "<=": case ">=": case ">": classe = "expr"; subclasse = "bool"; type = "bool"; //Booleana break; case "+": case "-": case "*": case "/": case "%": case "&": case "^": case "|": case "<<": case ">>": classe = "expr"; subclasse = "arith"; type = "int32"; //Aritimeticas } astSetCurrentNode(op, ctx) .Set("type", type) .Set("class", classe) .Set("subclass", subclasse); } else { // expr_unary } super.enterExpression(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitExpression(IvannosysGrammarParser.ExpressionContext ctx) { if (ctx.op != null) { astReturnLevel(); } super.exitExpression(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterOperand(IvannosysGrammarParser.OperandContext ctx) { if (this.ReadId.peek() && ctx.Value != "") { astSetCurrentNode(ctx.Value, ctx); } super.enterOperand(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitOperand(IvannosysGrammarParser.OperandContext ctx) { if (this.ReadId.peek() && ctx.Value != "") { String type; Node operand = astCurrent(); if (ctx.primitive_value() != null) { type = getTypeOfPrimitive(ctx.primitive_value()); } else { Node var = Variables.Get(ctx.ID().getText()); type = var.Get("type"); operand.Copy("pointer", var); } operand.Set("class", "operand").Set("type", type); astReturnLevel(); } super.exitOperand(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterLabel_stmt(IvannosysGrammarParser.Label_stmtContext ctx) { astSetCurrentNode(ctx.ID().getText(), ctx).Set("class", "label.stmt"); super.enterLabel_stmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitLabel_stmt(IvannosysGrammarParser.Label_stmtContext ctx) { astReturnLevel(); super.exitLabel_stmt(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDef_switch(IvannosysGrammarParser.Def_switchContext ctx) { this.insideSwitch = true; astSetCurrentNode("switch." + this.__uniq__(), ctx); astSetAtributo("class", "switch.stmt"); astBaseSet(ctx); super.enterDef_switch(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterFlux_control(IvannosysGrammarParser.Flux_controlContext ctx) { Node ctrlStmt = astSetCurrentNode(ctx.control, ctx) .Set("class", "ctrl.stmt"); if (ctx.ID() != null) { ctrlStmt.Set("label", ctx.ID().getText()); } super.enterFlux_control(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitFlux_control(IvannosysGrammarParser.Flux_controlContext ctx) { astReturnLevel(); super.exitFlux_control(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_switch(IvannosysGrammarParser.Def_switchContext ctx) { astReturnLevel(); this.insideSwitch = false; super.exitDef_switch(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterDef_case(IvannosysGrammarParser.Def_caseContext ctx) { astSetCurrentNode("switch.case", ctx); astSetAtributo("class", "def.case"); astBaseSet(ctx); super.enterDef_case(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitDef_case(IvannosysGrammarParser.Def_caseContext ctx) { // retorno do switch // Node c =astCurrent(); astReturnLevel(); super.exitDef_case(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void enterStatement_list(IvannosysGrammarParser.Statement_listContext ctx) { astSetCurrentNode("stmts", ctx); astSetAtributo("class", "stmts"); super.enterStatement_list(ctx); //To change body of generated methods, choose Tools | Templates. } @Override public void exitStatement_list(IvannosysGrammarParser.Statement_listContext ctx) { astReturnLevel(); super.exitStatement_list(ctx); //To change body of generated methods, choose Tools | Templates. } /*AST FUNCTIONS ----------------------------------------------------------*/ protected void astBaseSet(ParserRuleContext ctx) { astBaseSet(ctx, astCurrent()); } protected void astBaseSet(ParserRuleContext ctx, Node n) { n.Set("file", scopeFile.peek()) .Set("scope", scopeStack.peek()) .Set("line", "" + ctx.getStart().getLine()) .Set("col", "" + ctx.getStart().getCharPositionInLine()); } protected String getNodeType(RuleContext node) { return node.getClass().getSimpleName().replace("Context", ""); } protected void setEscopo(String escopo) { String ant = scopeStack.empty() ? "" : scopeStack.peek() + ".@"; scopeStack.push(ant + escopo); } protected Node astAddChildren(String n) { return astAddChildren(new Node(n)); } protected Node astAddChildren(Node n) { this.ast.addChildren(n); return n; } protected Node astSetCurrentNode(String n, ParserRuleContext ctx) { Node x = new Node(n); astBaseSet(ctx, x); return this.ast.setNode(x); } protected Node astReturnLevel() { return this.ast.setParentToCurrent(); } protected void astSetAtributo(String atrib, String valor) { this.ast.setAtributo(atrib, valor); } AbstractSyntaxTree getAbstractSyntaxTree() { return this.ast; } protected void astConcatAtributo(String atrib, String valor) { String at = this.ast.getAtributo(atrib); this.ast.setAtributo(atrib, at + "," + valor); } protected String astGetAtributo(String atrib) { return this.ast.getAtributo(atrib); } protected Node astCurrent() { return this.ast.getCurrent(); } protected void astSetAtributo(Node parent, String atrib, String valor) { parent.Set(atrib, valor); } protected int __uniq__() { return this.uniq++; } // protected String getTypeOfVar(String base) { // System.out.println("getTypeOfVar:" + base); // Node var = Variables.Get(base); // if (var != null) { // return var.Get("type"); // } else { // return "undefined"; // } // } }