public static List <string> LoadFromRegister(IVarCil x, IFunctionCil function, string src) { List <string> result = new List <string>(); if (function.LocalCils.Contains(x)) //si y es una variable local { var index = function.localsDict[x.Name]; result.Add($"sw ${src}, {index}($sp)"); } else if (function.ArgCils.Contains(x)) { //si y es un parametro //var index = function.ArgCils.ToList().FindIndex(i => i.Name.Equals(x.Name)); //result.Add($"move $a{index}, ${src}"); var index = function.argsDict[x.Name]; result.Add($"sw ${src}, {index}($sp)"); } return(result); }
public IHolderCil Visit(AssignExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var valueExpr = Visit(parserRule.expresion, cilTree, contextCil); if (!contextCil.variables.ContainsKey(parserRule.id.Text)) { var value = new LocalCil($"_value{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(value); cilTree.ThreeDirInses.Add(new SetAttrCil(cilTree.self, typeCil.GetAttributeCilsByCoolName(parserRule.id.Text), valueExpr)); cilTree.ThreeDirInses.Add(new GetAttrCil(value, cilTree.self, typeCil.GetAttributeCilsByCoolName(parserRule.id.Text))); return(value); } else { var value = contextCil.variables[parserRule.id.Text]; cilTree.ThreeDirInses.Add(new AssigCil(value, valueExpr)); return(value); } }
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 IHolderCil Visit(BoolExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var value = CreateABasicType(cilTree, CilAst.Bool); switch ([email protected]) { case "true": SetValue(value, new HolderCil("1"), cilTree, CilAst.Bool); break; case "false": SetValue(value, new HolderCil("0"), cilTree, CilAst.Bool); break; default: break; } return(value); }
public MIPS Visitor(NotEqualCil instance, IFunctionCil function, GenerateToCil cil) { var lines = new List <string>(Utils.AcomodarVariables(instance.Y, function)); if (instance.Z is TypeCil) { lines.Add("lw $t1, ($t1)"); lines.Add($"la $t2, type_{instance.Z.Name}_name"); } else { lines.AddRange(Utils.SaveToRegister(instance.Z, function, "t2")); } lines.Add("sne $t0, $t1, $t2"); lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0")); return(new MIPS() { Functions = lines }); }
public MIPS Visitor(GetAttrCil instance, IFunctionCil function, GenerateToCil cil) { var attr = instance.Z as AttributeCil; var typeName = attr.Name.Substring(0, attr.Name.Length - attr.CilName.Length - 1); var type = cil.CilAst.TypeCils.First(x => x.Name == typeName); var indexOf = type.Attributes.ToList().IndexOf(attr); var lines = new List <string>(Utils.SaveToRegister((IVarCil)instance.Y, function, "t0")) { $"addi $t0, $t0, {(indexOf+2)*4}", $"lw $t0, ($t0)" }; lines.AddRange(Utils.LoadFromRegister(instance.X, function, "t0")); return(new MIPS() { Functions = lines }); }
public MIPS Visitor(VCallCil instance, IFunctionCil function, GenerateToCil cil) { CountArgs = 0; if (instance.Y is TypeCil) { var label = ((FunctionTypeCil)instance.Z).Function.Name; var lines = new List <string>() { $"jal {label}" }; lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0")); return(new MIPS() { Functions = lines }); } else { var type = cil.CilAst.TypeCils.First(x => x.Functions.Contains(instance.Z)); var element = type.Functions.Single(x => x.Name == instance.Z.Name); var index = type.Functions.ToList().IndexOf(element); var lines = new List <string>(Utils.SaveToRegister(instance.Y, function, "t0")) { $"lw $t0, ($t0)", //cargo la direccion del puntero (que es donde esta la direccion del nombre) $"add $t0,$t0,-8", //en -4 esta la cantidad de metodos $"lw $t1, ($t0)", //cargo la cantidad de metodos $"mul $t1,$t1,-4", //desplazamiento hasta el primer metodo $"add $t0, $t0, $t1", //la direccion del primer metodo $"add $t0,$t0,{index*4}", //aumentar desplazamiento del metodo buscado $"lw $t0,($t0)", //carga la direccion del metodo $"jalr $t0" }; lines.AddRange(Utils.LoadFromRegister(instance.X, function, "v0")); return(new MIPS() { Functions = lines }); } }
public IHolderCil Visit(WhileExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var whileElse = cilTree.CreateLabel("while"); //Voy para esa etiqueta para evaluar la cod del while cilTree.ThreeDirInses.Add(new GotoCil(whileElse)); var loop = cilTree.CreateLabel("loop"); //Esta etiqueta indica evalua el cuerpo de while cilTree.ThreeDirInses.Add(new Label(loop)); Visit(parserRule.loopExpr, cilTree, contextCil); //Pongo la etiqueta de while cilTree.ThreeDirInses.Add(new Label(whileElse)); var condValue = Visit(parserRule.whileExpr, cilTree, contextCil); condValue = GetValue(condValue, cilTree, CilAst.Bool); cilTree.ThreeDirInses.Add(new IfGoto(condValue, loop)); //retorno el valor var value = Visit_void(cilTree); return(value); }
public IHolderCil Visit(ArithContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { var valueNum = new LocalCil($"_valueNum{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(valueNum); var valueLeft = Visit(parserRule.left, cilTree, contextCil); var valueRight = Visit(parserRule.right, cilTree, contextCil); var valLeft = GetValue(valueLeft, cilTree, CilAst.Int); var valRigth = GetValue(valueRight, cilTree, CilAst.Int); switch (parserRule.op.Text) { case "/": var isZero = new LocalCil($"_isZero{cilTree.LocalCils.Count}"); cilTree.LocalCils.Add(isZero); cilTree.ThreeDirInses.Add(new NotEqualCil(isZero, valRigth, new HolderCil("0"))); Visit_Runtime_Error_whit_Cond(isZero, cilTree, $"\"({parserRule.Start.Line},{parserRule.Start.Column+1}) - Rutime Error: Division by zero\""); cilTree.ThreeDirInses.Add(new DivCil(valueNum, valLeft, valRigth)); break; case "*": cilTree.ThreeDirInses.Add(new MultCil(valueNum, valLeft, valRigth)); break; case "+": cilTree.ThreeDirInses.Add(new SumCil(valueNum, valLeft, valRigth)); break; case "-": cilTree.ThreeDirInses.Add(new RestCil(valueNum, valLeft, valRigth)); break; default: break; } return(CreateABasicTypeWhitVal(cilTree, CilAst.Int, valueNum)); }
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)); }
private MIPS Selector(IThreeDirIns x, IFunctionCil function, GenerateToCil cil) { #region Operations if (x is SumCil) { return(Visitor(x as SumCil, function, cil)); } else if (x is RestCil) { return(Visitor(x as RestCil, function, cil)); } else if (x is MultCil) { return(Visitor(x as MultCil, function, cil)); } else if (x is DivCil) { return(Visitor(x as DivCil, function, cil)); } else if (x is EqualCil) { return(Visitor(x as EqualCil, function, cil)); } else if (x is EqualStringCil) { return(Visitor(x as EqualStringCil, function, cil)); } else if (x is NotEqualCil) { return(Visitor(x as NotEqualCil, function, cil)); } else if (x is MinorCil) { return(Visitor(x as MinorCil, function, cil)); } else if (x is Minor_EqualCil) { return(Visitor(x as Minor_EqualCil, function, cil)); } else if (x is NegCil) { return(Visitor(x as NegCil, function, cil)); } #endregion #region AssigCil else if (x is AssigCil) { return(Visitor(x as AssigCil, function, cil)); } #endregion #region Attribute else if (x is GetAttrCil) { return(Visitor(x as GetAttrCil, function, cil)); } else if (x is SetAttrCil) { return(Visitor(x as SetAttrCil, function, cil)); } #endregion #region MemoryManage else if (x is Allocate) { return(Visitor(x as Allocate, function, cil)); } else if (x is TypeOf) { return(Visitor(x as TypeOf, function, cil)); } #endregion #region Call_function else if (x is CallCil) { return(Visitor(x as CallCil, function, cil)); } else if (x is VCallCil) { return(Visitor(x as VCallCil, function, cil)); } else if (x is ArgExprCil) { return(Visitor(x as ArgExprCil, function, cil)); } #endregion #region Jump else if (x is Label) { return(Visitor(x as Label, function, cil)); } else if (x is IfGoto) { return(Visitor(x as IfGoto, function, cil)); } else if (x is GotoCil) { return(Visitor(x as GotoCil, function, cil)); } #endregion #region Return else if (x is ReturnCil) { return(Visitor(x as ReturnCil, function, cil)); } #endregion #region String_funcions else if (x is LoadCil) { return(Visitor(x as LoadCil, function, cil)); } else if (x is LenghtCil) { return(Visitor(x as LenghtCil, function, cil)); } else if (x is ConcatCil) { return(Visitor(x as ConcatCil, function, cil)); } else if (x is SubStringCil) { return(Visitor(x as SubStringCil, function, cil)); } else if (x is StrCil) { return(Visitor(x as StrCil, function, cil)); } #endregion #region IO else if (x is In_strCil) { return(Visitor(x as In_strCil, function, cil)); } else if (x is In_intCil) { return(Visitor(x as In_intCil, function, cil)); } else if (x is Out_strCil) { return(Visitor(x as Out_strCil, function, cil)); } else if (x is Out_intCil) { return(Visitor(x as Out_intCil, function, cil)); } #endregion #region IsConform else if (x is IsNotConformCil) { return(Visitor(x as IsNotConformCil, function, cil)); } #endregion #region Object else if (x is Halt) { return(Visitor(x as Halt, function, cil)); } else if (x is Copy) { return(Visitor(x as Copy, function, cil)); } else if (x is Type_Name) { return(Visitor(x as Type_Name, function, cil)); } #endregion else { return(null); } }
public MIPS Visitor(StrCil instance, IFunctionCil function, GenerateToCil cil) { return(null); }
public CallCil(IVarCil x, IFunctionCil f) : base(x, f) { }
public FunctionTypeCil(string TypeName, string CilName, IFunctionCil function) : base(TypeName, CilName) { Function = function; }
public IVarCil CreateABasicTypeWhitVal(IFunctionCil cilTree, ITypeCil typeCil, IHolderCil value) { return(SetValue(CreateABasicType(cilTree, typeCil), value, cilTree, typeCil)); }
public IVarCil SetValue(IVarCil obj, IHolderCil value, IFunctionCil cilTree, ITypeCil typeCil) { cilTree.ThreeDirInses.Add(new SetAttrCil(obj, typeCil.GetAttributeCilsByCoolName("x"), value)); return(obj); }
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 IHolderCil Visit(LetExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { return(Visit(parserRule.let, cilTree, contextCil)); }
public IHolderCil Visit(InParenthesisExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { return(Visit(parserRule.expresion, cilTree, contextCil)); }
public IHolderCil Visit(IntegerExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { return(CreateABasicTypeWhitVal(cilTree, CilAst.Int, new HolderCil(parserRule.integer.Text))); }
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 IHolderCil Visit(ExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil) { switch (parserRule) { case SelfDispatchContext rule: return(Visit(rule, cilTree, contextCil)); case DispatchContext rule: return(Visit(rule, cilTree, contextCil)); case CondExprContext rule: return(Visit(rule, cilTree, contextCil)); case WhileExprContext rule: return(Visit(rule, cilTree, contextCil)); case BlockExprContext rule: return(Visit(rule, cilTree, contextCil)); case LetExprContext rule: return(Visit(rule, cilTree, contextCil)); case CaseExprContext rule: return(Visit(rule, cilTree, contextCil)); case NewTypeExprContext rule: return(Visit(rule, cilTree, contextCil)); case AssignExprContext rule: return(Visit(rule, cilTree, contextCil)); case NotExprContext rule: return(Visit(rule, cilTree, contextCil)); case CompaExprContext rule: return(Visit(rule, cilTree, contextCil)); case ArithContext rule: return(Visit(rule, cilTree, contextCil)); case IsvoidExprContext rule: return(Visit(rule, cilTree, contextCil)); case NegExprContext rule: return(Visit(rule, cilTree, contextCil)); case InParenthesisExprContext rule: return(Visit(rule, cilTree, contextCil)); case IdExprContext rule: return(Visit(rule, cilTree, contextCil)); case IntegerExprContext rule: return(Visit(rule, cilTree, contextCil)); case StringExprContext rule: return(Visit(rule, cilTree, contextCil)); case BoolExprContext rule: return(Visit(rule, cilTree, contextCil)); default: return(Visit(cilTree)); } }