public IHolderCil Visit(CaseExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var value = new LocalCil($"_value{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(value); var expr0 = Visit(parserRule.expresion, cilTree, contextCil); //is void var TypeValue = new LocalCil($"_TypeValue{cilTree.LocalCils.Count}"); var not_is_void = new LocalCil($"not_is_void{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(TypeValue); cilTree.LocalCils.Add(not_is_void); cilTree.ThreeDirInses.Add(new TypeOf(TypeValue, expr0)); cilTree.ThreeDirInses.Add(new NotEqualCil(not_is_void, TypeValue, CilAst.GetTypeCilByName("void"))); //lanzamos el error Visit_Runtime_Error_whit_Cond(not_is_void, cilTree, $"\"({parserRule.Start.Line},{parserRule.Start.Column + 1}) - Rutime Error: A case on void\""); //ejecucion del case var closestAncestor = new LocalCil($"_closestAncestor{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(closestAncestor); //Inicializo el valor de numberType en 0 y closestAncestor con object var isNotConform = new LocalCil($"_isNotConform{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(isNotConform); var branches = parserRule._branches.Concat(new List <BranchContext>() { parserRule.firstBranch }).OrderBy(t => - (CilAst.GetTypeCilByName(t.typeText).IndexOfPrecedence)).ToArray(); //El tipo de la primera rama var End = cilTree.CreateLabel("End_"); for (int i = 0; i < branches.Length; i++) { var branch = branches[i]; var nextLabel = cilTree.CreateLabel("Case_"); //tipo de la rama var typeBranch = CilAst.GetTypeCilByName(branch.typeText, typeCil); cilTree.ThreeDirInses.Add(new IsNotConformCil(isNotConform, TypeValue, typeBranch)); cilTree.ThreeDirInses.Add(new IfGoto(isNotConform, nextLabel)); var valueBranch = new LocalCil(branch.idText);//preguntarle as zahuis cilTree.LocalCils.Add(valueBranch); cilTree.ThreeDirInses.Add(new AssigCil(valueBranch, expr0)); var newContextCil = contextCil.CreateAChild(); newContextCil.Define(branch.idText); var valueExpr = Visit(branch.expression, cilTree, newContextCil); cilTree.ThreeDirInses.Add(new AssigCil(value, valueExpr)); cilTree.ThreeDirInses.Add(new GotoCil(End)); cilTree.ThreeDirInses.Add(new Label(nextLabel)); } Visit_Runtime_Error(cilTree, $"\"linea {parserRule.Start.Line} y columna {parserRule.Start.Column + 1} Execution of a case statement without a matching branch\""); cilTree.ThreeDirInses.Add(new Label(End)); return(value); }
public virtual IFunctionCil Visit(MethodContext parserRule) { IFunctionCil function; var contextCil = new ContextCil(); //El unico metodo que no pertenece a una clase es entry if (parserRule.Parent == null) { function = CilAst.GetFunctionCilsByName($"{parserRule.idText}"); } else { // El nombre metodo en el tipo tiene siempre esta estructura (Type_CoolName) function = CilAst.GetFunctionCilsByName($"{(parserRule.Parent as ClassContext).type.Text}_{parserRule.idText}"); // Como toda fucion pertenece a una clase se le agrega self como una parametro var self = new ArgCil("self"); function.ArgCils.Add(self); contextCil.Define("self"); foreach (var formal in parserRule._formals) { Visit(formal, function, contextCil); } } var result = Visit(parserRule.exprBody, function, contextCil); function.ThreeDirInses.Add(new ReturnCil(result)); return(function); }
public virtual void Visit(ProgramContext parserRule) { Visit(basicTypes.entry); foreach (var _class in parserRule._classes) { typeCil = CilAst.GetTypeCilByName(_class.type.Text); typeC = GlobalContext.GetType(_class.type.Text); Visit(_class); } }
public IHolderCil Visit(IsvoidExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var value = new LocalCil($"_value{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(value); var valueExpr = Visit(parserRule.expresion, cilTree, contextCil); var TypeValue = new LocalCil($"_TypeValue{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(TypeValue); cilTree.ThreeDirInses.Add(new TypeOf(TypeValue, valueExpr)); cilTree.ThreeDirInses.Add(new EqualCil(value, TypeValue, CilAst.GetTypeCilByName("void"))); return(CreateABasicTypeWhitVal(cilTree, CilAst.Bool, value)); }
public void Visit(MethodContext parserRule, ITypeCil cilTree) { if (cilTree == null) { CilAst.CreateFunctionCil(null, parserRule.idText); } else { //Creo la funcion e cil y la se anade al CilAst var function = CilAst.CreateFunctionCil(type.type.Text, parserRule.idText); //Le hago referencia al tipo correspondiente //La al anadirla ya hay una funcion definida con el mismo nombre se le cambia el nombre de la funcionCil por el nuevo cilTree.AddFunc(new FunctionTypeCil(type.type.Text, parserRule.idText, function)); } }
public IHolderCil Visit(NewTypeExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var value = new LocalCil($"_value{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(value); if (parserRule.type.Text == "SELF_TYPE") { var varType = new LocalCil($"_Type{cilTree.ThreeDirInses.Count}"); cilTree.LocalCils.Add(varType); cilTree.ThreeDirInses.Add(new TypeOf(varType, new ValuelCil("self"))); cilTree.ThreeDirInses.Add(new VCallCil(value, varType, new ValuelCil("Init"))); } else { var varType = CilAst.GetTypeCilByName(parserRule.type.Text, typeCil); cilTree.ThreeDirInses.Add(new CallCil(value, varType.Init.Function)); } return(value); }
public void Visit(ProgramContext parserRule) { Visit(basicTypes.entry, null); foreach (var _class in parserRule._classes) { var typeCil = new TypeCil(_class.type.Text, CilAst); typeCil.inherit = CilAst.GetTypeCilByName(_class.father?.type.Text); if (typeCil.inherit != null) { typeCil.IndexOfPrecedence = 1 + typeCil.inherit.IndexOfPrecedence; } CilAst.TypeCils.Add(typeCil); } foreach (var _class in parserRule._classes) { var typeCil = CilAst.GetTypeCilByName(_class.type.Text); Visit(_class, typeCil); } }
public IHolderCil Visit(IFunctionCil cilTree) { switch (cilTree.Name) { case "String_lenght": var value = new LocalCil("value"); cilTree.LocalCils.Add(value); cilTree.ThreeDirInses.Add(new LenghtCil(value, GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String")))); return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("Int"), value)); case "String_concat": value = new LocalCil("value"); cilTree.LocalCils.Add(value); cilTree.ThreeDirInses.Add(new ConcatCil(value, GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String")), GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("String")))); return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), value)); case "String_substr": value = new LocalCil("value"); cilTree.LocalCils.Add(value); var self = GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String")); //tomamos los valores de los argumentos var param1 = GetValue(cilTree.ArgCils.ElementAt(1), cilTree, CilAst.Int); var param2 = GetValue(cilTree.ArgCils.ElementAt(2), cilTree, CilAst.Int); cilTree.ThreeDirInses.Add(new SubStringCil(value, self, param1, param2)); return(CreateABasicTypeWhitVal(cilTree, CilAst.String, value)); case "Object_abort": cilTree.ThreeDirInses.Add(new Halt()); return(null); case "Object_type_name": var x_type_name = new LocalCil("x"); cilTree.LocalCils.Add(x_type_name); cilTree.ThreeDirInses.Add(new Type_Name(x_type_name, cilTree.self)); return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), x_type_name)); case "Object_copy": var x_Object_copy = new LocalCil("x"); cilTree.LocalCils.Add(x_Object_copy); cilTree.ThreeDirInses.Add(new Copy(x_Object_copy, cilTree.self)); return(x_Object_copy); case "IO_out_string": cilTree.ThreeDirInses.Add(new Out_strCil(GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("String")))); return(cilTree.self); case "IO_out_int": cilTree.ThreeDirInses.Add(new Out_intCil(GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("Int")))); return(cilTree.self); case "IO_in_string": var x_in_string = new LocalCil("x"); cilTree.LocalCils.Add(x_in_string); cilTree.ThreeDirInses.Add(new In_strCil(x_in_string)); return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), x_in_string)); case "IO_in_int": var x_in_int = new LocalCil("x"); cilTree.LocalCils.Add(x_in_int); cilTree.ThreeDirInses.Add(new In_intCil(x_in_int)); return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("Int"), x_in_int)); default: return(null); } }
public void Visit() { IFunctionCil init = typeCil.Init.Function; var value = new LocalCil("self"); init.LocalCils.Add(value); var typeCilNew = CilAst.GetTypeCilByName(typeCil.Name, typeCil); init.ThreeDirInses.Add(new Allocate(value, typeCilNew)); var typeCool = GlobalContext.GetType(typeCil.Name); var contextCil = new ContextCil(); contextCil.Define("self"); foreach (var typeTemp in typeCool.Hierachty) { foreach (var attributeTemp in typeTemp.Attributes) { //Inicializamos los atributos if (attributeTemp.initializacion != null) { var valueAttribute = Visit(attributeTemp.initializacion, init, contextCil); //No siempre los tipos de Cil estan para eso eso habria que hacer 2 pasadas al AST init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), valueAttribute)); } else { if (typeTemp == GlobalContext.Int || typeTemp == GlobalContext.Bool) { init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), new ValuelCil("0"))); } else if (typeTemp == GlobalContext.String) { var valueS = new LocalCil($"_value{init.LocalCils.Count}"); init.LocalCils.Add(valueS); var stringCool = ""; var varDataString = new VarCil($"s{CilAst.dataStringCils.Count}"); CilAst.dataStringCils.Add(new DataStringCil(varDataString, new StringCil(stringCool))); init.ThreeDirInses.Add(new LoadCil(valueS, varDataString)); init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), valueS)); } else if (attributeTemp.Type == GlobalContext.String) { init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.String))); } else if (attributeTemp.Type == GlobalContext.Int) { init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.Int))); } else if (attributeTemp.Type == GlobalContext.Bool) { init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.Bool))); } else { init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), Visit_void(init))); } } } } init.ThreeDirInses.Add(new ReturnCil(value)); }
public virtual IHolderCil Visit(DispatchContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var Params = new List <IHolderCil>(); var expr0 = Visit(parserRule.expresion, cilTree, contextCil); foreach (var expr in parserRule._expresions) { //genera el codigo de cada parametro que le paso a los metodos var param = Visit(expr, cilTree, contextCil); Params.Add(param); } //Averiguo el tipo dinamico de self es decir( el de la clase que esta usando la funcion en ese momento) var varType = new LocalCil($"_Type{cilTree.ThreeDirInses.Count}"); cilTree.LocalCils.Add(varType); cilTree.ThreeDirInses.Add(new TypeOf(varType, expr0)); //Verifico si el tipo del objeto que le voy hacer el dispatch es void if (parserRule.id.Text == "substr") { VisitString(parserRule, cilTree, new List <IHolderCil>() { expr0 }.Concat(Params).ToList()); } if (cilTree.Name != "entry") { var isVoid = new LocalCil($"_isVoid{cilTree.ThreeDirInses.Count}"); cilTree.LocalCils.Add(isVoid); cilTree.ThreeDirInses.Add(new NotEqualCil(isVoid, varType, CilAst.GetTypeCilByName("void"))); Visit_Runtime_Error_whit_Cond(isVoid, cilTree, $"\"({parserRule.id.Line},{parserRule.id.Column+1}) - Rutime Error: A dispatch on void\""); cilTree.ThreeDirInses.Add(new ArgExprCil(expr0)); } //cada parametro los anado al metodo puede que tenga sentido pasarlos al revez foreach (var param in Params) { cilTree.ThreeDirInses.Add(new ArgExprCil(param)); } ////nueva variable donde se almacena el valor que retorna el metodo var value = new LocalCil($"_value{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(value); if (parserRule.type == null) { //Se resuleve el tipo de la expr0 a partir de su tipo estatico calculado por el checkeo semantico var typeExpr0 = CilAst.GetTypeCilByName(parserRule.expresion.computedType.Name, typeCil); ////resuelve el metodo en cil de ese tipo estatico var functionCil = typeExpr0.GetFunctionCilsByCoolName(parserRule.id.Text); //como ningun tipo puede redefinir a string entonces llamo directamente al metodo if (parserRule.expresion.computedType == GlobalContext.String) { cilTree.ThreeDirInses.Add(new CallCil(value, functionCil.Function)); } else { cilTree.ThreeDirInses.Add(new VCallCil(value, varType, functionCil)); } } else { //Se resuelve el tipo de la type var typeT = CilAst.GetTypeCilByName(parserRule.type.Text, typeCil); var functionCil = typeT.GetFunctionCilsByCoolName(parserRule.id.Text).Function; cilTree.ThreeDirInses.Add(new CallCil(value, functionCil)); } return(value); }
public GenerateToCilTypes(CheckSemanticVisitor visitor) { basicTypes = visitor.basicTypes; GlobalContext = visitor.globalContext; CilAst = new CilAst(); }