public Word Visit(ReturnNode returnNode) { if (returnNode.Expr == null) { return(new Return()); } var result = returnNode.Expr.Accept(this); PyObj pyObj; if (IsError(result)) { ErrorFactory.CantReturnError(returnNode.Expr, result); return(new Return(MyNull.GetInstance())); } if (IsMemoryBlock(result))//comentar ese if else si se hace la desereferencia en atomic expr. { pyObj = ((MemoryBlock)result).Value; } else { pyObj = (PyObj)result; } //pyObj = (PyObj)result;//Descomentar esta linea si se hace la desereferencia en atomic expr. return(new Return(pyObj)); }
//llena los agumentos con myNull, sirve para llamar y buscar procedures desde c#, hardcoded public static ProcedureSegment EmptyProcedureSegment(string id, int argumentCount) { var arguments = new List <MemoryBlock>(argumentCount); for (int i = 0; i < argumentCount; i++) { arguments.Add(new MemoryBlock(MyNull.GetInstance())); } return(new ProcedureSegment(id, arguments)); }
/// <summary> /// Agrega sin verficar que no contenga la llave. Usarse solo si se verifico que no esten presentes los valores antes /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void UnsafeAdd(string key, PyObj value) { key = key.ToLowerInvariant(); if (value.IsNull()) { Table[key] = new MemoryBlock(MyNull.GetInstance()); } if (value.IsPrimitive()) { Table[key] = new MemoryBlock(MyPrimitiveFactory.CreateCopy((MyPrimitive)value)); } else//Only option left is for value to be customInstance { Table[key] = new MemoryBlock(value); } }
/// <summary> /// Retorna false si no agrego el valor a la tabla de simbolos. Solo se agregan valores que no esten presentes /// </summary> /// <param name="type"></param /// <param name="value"></param> /// <returns></returns> public bool Add(string key, PyObj value) { key = key.ToLowerInvariant(); if (Table.ContainsKey(key)) { return(false); } if (value.IsNull()) { Table[key] = new MemoryBlock(MyNull.GetInstance()); } if (value.IsPrimitive()) { Table[key] = new MemoryBlock(MyPrimitiveFactory.CreateCopy((MyPrimitive)value)); } else//Only option left is for value to be customInstance { Table[key] = new MemoryBlock(value); } return(true); }
/// <summary> /// Retorna false si no se cambio el valor de la llave en la tabla de simbolos. Solo se cambian valores que ya estan presentes /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public bool Set(string key, PyObj value) { key = key.ToLowerInvariant(); MemoryBlock memoryBlock; if (!Table.TryGetValue(key, out memoryBlock)) { return(false); } if (value.IsNull()) { memoryBlock.Value = MyNull.GetInstance(); } if (value.IsPrimitive()) { memoryBlock.Value = MyPrimitiveFactory.CreateCopy((MyPrimitive)value); } else//Only option left is for value to be customInstance { memoryBlock.Value = value; } return(true); }
//Crea una nueva direccion en memoria apuntando a null public MemoryBlock() { Value = MyNull.GetInstance(); }
public Word Visit(Declaration declaration) { var idList = new List <string>(); Word lResult; foreach (var lValue in declaration.LeftValues) { lResult = lValue.Accept(this); if (IsError(lResult)) { return(lResult); } idList.Add(((MyString)lResult).StringValue); } Word rValue; PyObj rPyObj; int i; if (declaration.Indexes.IsEmpty()) { if (declaration.RightValue == null) { rValue = MyNull.GetInstance(); } else { rValue = declaration.RightValue.Accept(this); } if (IsError(rValue)) { return(rValue); } if (IsMemoryBlock(rValue))//comentar ese if else si se hace la desereferencia en atomic expr. { rPyObj = ((MemoryBlock)rValue).Value; } else { rPyObj = (PyObj)rValue; } //rPyObj = (PyObj)rValue;//Descomentar esta linea si se hace la desereferencia en atomic expr. } else //Si tiene indices la declaracion significal que es un array { Word indexResult; PyObj indexPyObj; var intIndices = new int[declaration.Indexes.Count]; //Obtiene la lista de ints en sus indices. i = 0; foreach (var index in declaration.Indexes) { indexResult = index.Accept(this); if (IsError(indexResult)) { return(indexResult); } indexPyObj = ((IndexSegment)indexResult).Index; //Chequea que sea del tipo correcto: if (indexPyObj.GetMyType() == TypeConstants.INT) { intIndices[i] = ((MyInt)indexPyObj).Int; } else if (indexPyObj.GetMyType() == TypeConstants.CHAR) { intIndices[i] = ((MyChar)indexPyObj).CharValue; } else { return(ErrorFactory.ArrayDimensionError(index, indexPyObj)); } //Chequea que tenga un rango valido if (intIndices[i] < 0) { return(ErrorFactory.ArrayDimensionError(index, indexPyObj)); } i++; } if (declaration.RightValue == null) { rValue = MyArrayFactory.Create(intIndices); } else { rValue = declaration.RightValue.Accept(this); } if (IsError(rValue)) { return(rValue); } if (IsMemoryBlock(rValue))//comentar ese if else si se hace la desereferencia en atomic expr. { rPyObj = ((MemoryBlock)rValue).Value; } else { rPyObj = (PyObj)rValue; } //rPyObj = (PyObj)rValue;//Descomentar esta linea si se hace la desereferencia en atomic expr. //Verifica que rValue sea un array con las dimensiones especificadas en intIndices if (rPyObj.GetMyType() != TypeConstants.ARRAY) { return(ErrorFactory.ArrayTypeError(declaration, intIndices, rPyObj)); } if (!((MyArray)rPyObj).IsNDimensionalArray(intIndices)) { return(ErrorFactory.ArrayTypeError(declaration, intIndices, rPyObj)); } } Word result; i = 0;//Chapus minimo foreach (var id in idList) { result = CurrentScope.Add(id, rPyObj); if (IsError(result)) { ErrorFactory.Create(declaration.LeftValues[i], (MyError)result); } i++; } return(rPyObj);//Chapuz medio alto para facilitar el for }
public Word InvokeProcedure(ProcedureSegment procedureSegment) { var name = procedureSegment.Id; name = name.ToLowerInvariant(); var arguments = procedureSegment.Arguments; var argumentCount = arguments.Count; Procedure procedure; Procedures.TryGetValue(Procedure.EmptySignature(name, argumentCount), out procedure); if (procedure == null) { return(new MyError("No existe una funcion con el nombre: " + name + " y numero de parametros: " + argumentCount + " en las definiciones globales")); } //scope antes de llamar a la funcion var previousScope = CurrentScope; //Pasamos al scope global para llamar a la funcion CurrentScope = GlobalScope; ControlType controlType; if (procedure.GetDefinitionType() == DefinitionType.Function) { controlType = ControlType.Function; } else if (procedure.GetDefinitionType() == DefinitionType.Method) { controlType = ControlType.Method; } else { throw new Exception("definicion no valida. tiene que ser funciton o method"); } ControlStack.Push(controlType); //hacemos las declaraciones del metodo en un nuevo scope PushScope(); Word result; for (int i = 0; i < argumentCount; i++) { result = CurrentScope.Add(procedure.ParamNames[i], arguments[i]); if (IsError(result)) { ControlStack.Pop(); CurrentScope = previousScope; return(result); } } //Los stmt del metodo: foreach (var stmt in procedure.Stmts) { result = stmt.Accept(this); if (IsJumper(result)) { var jumper = (Jumper)result; if (!jumper.WasPopped() && !ControlStack.PopUntil(jumper)) { ErrorFactory.NotValidJumper(stmt, jumper); continue; } CurrentScope = previousScope; return(((Return)jumper).Obj); } } //Si termina de visitar los stmt, no entro jumper y es una funcion retorna MyNull y reporta un error ControlStack.Pop(); CurrentScope = previousScope; if (controlType == ControlType.Method) { return(null); } else { ErrorFactory.NoValueReturnedInFunction(procedure.Stmts.Last()); return(MyNull.GetInstance()); } }
public Word Visit(NullLiteralNode nullLiteralNode) { return(MyNull.GetInstance()); }