private static void CheckIfReturnsSpecifiedType(ExpressionNode expression, IList<Error> errors, TigerType type) { if (!(expression.ReturnType == type)) { errors.Add(new UnexpectedTypeError(expression.Line, expression.Column, expression.ReturnType, IntegerType.Create())); } }
public VariableDeclarationNode(string name, ExpressionNode body, string type = null) : base(name) { Body = body; Type = type; Body.Parent = this; }
public EqualOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "=") { //Este nodo tambien admite la comparacion de Records y Arrays AllowedTypes.Add(typeof(RecordType)); AllowedTypes.Add(typeof(ArrayType)); }
public ArrayAccessNode(ExpressionNode left, ExpressionNode index) { Left = left; Index = index; Left.Parent = this; Index.Parent = this; }
public WhileNode(ExpressionNode condition, ExpressionNode body) { Condition = condition; Body = body; Condition.Parent = this; Body.Parent = this; }
public ArrayLiteralNode(string name, ExpressionNode count, ExpressionNode initialValue) : base(name) { Count = count; InitialValue = initialValue; Count.Parent = this; InitialValue.Parent = this; }
protected BinaryOperatorNode(ExpressionNode left, ExpressionNode right, string operatorName) { Left = left; Right = right; OperatorName = operatorName; //El tipo Int esta permitido en todos los operadores AllowedTypes = new List<Type>(); }
public CallableDeclarationNode(string name, IList<TypeField> fields, ExpressionNode body, string type = null) : base(name) { Fields = fields; Type = type; Body = body; Body.Parent = this; }
public ForToDoNode(string variableName, ExpressionNode expressionInitial, ExpressionNode expressionFinal, ExpressionNode body) { VariableName = variableName; ExpressionInitial = expressionInitial; ExpressionFinal = expressionFinal; Body = body; ExpressionInitial.Parent = this; ExpressionFinal.Parent = this; Body.Parent = this; }
public static bool CheckIfReturnsValue(ExpressionNode expression, IList<Error> errors, string nonValueMessage = null) { //Comprobamos que la expresion retorne algun valor if (!expression.ReturnsValue()) { errors.Add(new NonValueReturnError(expression.Line, expression.Column, nonValueMessage)); return false; } return true; }
public IfThenElseNode(ExpressionNode condition, ExpressionNode thenBody, ExpressionNode elseBody) { Condition = condition; ThenBody = thenBody; ElseBody = elseBody; Condition.Parent = this; ThenBody.Parent = this; if (ElseBody != null) { ElseBody.Parent = this; } }
/// <summary> /// Chequea: /// - Que la expresion retorne algun tipo /// - Que el tipo de retorno de la expresion sea entero /// </summary> /// <param name="expression"></param> /// <param name="errors"></param> /// <param name="nonValueMessage">Mensaje a anadir en caso de que no retorne valor la expresion</param> /// <param name="nonIntegerMessage">Mensaje a anadir en caso de que no retorne un entero la expresion</param> public static void CheckIfReturnTypeIsInt(ExpressionNode expression, IList<Error> errors, string nonValueMessage = null, string nonIntegerMessage = null) { int errorsCount = errors.Count; //Comprobamos que retorne valor CheckIfReturnsValue(expression, errors, nonValueMessage); if (errorsCount != errors.Count) { return; } //Comprobamos que la expresion retorne un entero CheckIfReturnsSpecifiedType(expression, errors, IntegerType.Create()); }
public AssignmentNode(AccessNode left, ExpressionNode body) : base(body) { Left = left; Left.Parent = this; }
public AndOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "&") { }
protected ArithmeticalBinaryOperatorNode(ExpressionNode left, ExpressionNode right, string operatorName) : base(left, right, operatorName) { //Esta expresion solamente acepta tipos enteros AllowedTypes.Add(typeof(IntegerType)); }
public void GenerateCode(ExpressionNode expressionNode, string outputFile) { //TODO: Eliminar este codigo IList<Error> errors = new List<Error>(); expressionNode.CheckSemantic(new MainScope(), errors); if (errors.Count > 0) { throw new Exception("Semantic check error"); } //Nombre del fichero (includa extension) string filename = Path.GetFileName(outputFile); //Nombre del directorio donde se encuentra el fichero string directory = Path.GetDirectoryName(outputFile); //Creamos un assembly AppDomain domain = System.Threading.Thread.GetDomain(); AssemblyName assemblyName = new AssemblyName { Name = Path.GetFileNameWithoutExtension(outputFile) }; AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, directory); //Creamos un modulo ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(filename); moduleBuilder.CreateGlobalFunctions(); //Guardamos el modulo y el assembly para que lo puedan usar directamente los nodos que quieran Builders.Module = moduleBuilder; Builders.Assembly = assemblyBuilder; //Creamos una clase 'Program' TypeBuilder programClassBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public | TypeAttributes.Class); //Creamos su constructor var programCtorBuilder = programClassBuilder.DefineDefaultConstructor(MethodAttributes.Public); // ConstructorBuilder programCtorBuilder = programClassBuilder.DefineConstructor( // MethodAttributes.Public, // CallingConventions.Standard, // new Type[0] // ); //Hacemos que retorne para crearlo satisfactoriamente (sino da un error) // var gen = programCtorBuilder.GetILGenerator(); // gen.Emit(OpCodes.Ret); //Creamos un metodo 'Run' (publico y no estatico) que es el que ejecutara el codigo del programa MethodBuilder run = programClassBuilder.DefineMethod("Run", MethodAttributes.Public, CallingConventions.HasThis, typeof (void), new Type[0]); var runGen = run.GetILGenerator(); //AHORA: El codigo generarlo en el metodo 'Run' expressionNode.GenerateCode(runGen, programClassBuilder); #if DEBUG Type[] types = expressionNode.ReturnType == null ? new Type[0] : new Type[] {expressionNode.ReturnType.GetILType()}; MethodInfo writeLine = typeof(Console).GetMethod("WriteLine", types); runGen.EmitCall(OpCodes.Call, writeLine, null); #endif runGen.Emit(OpCodes.Ret); //Creamos un metodo 'Main' MethodBuilder mainMethodBuilder = programClassBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), null); //Cogemos el ILGenerator del metodo ILGenerator mainGen = mainMethodBuilder.GetILGenerator(); //Creamos una instancia de la clase 'Program' mainGen.Emit(OpCodes.Newobj, programCtorBuilder); //Llamamos al metodo 'Run' de la clase que instanciamos mainGen.Emit(OpCodes.Callvirt, run); //Retornamos mainGen.Emit(OpCodes.Ret); //Terminamos programClassBuilder.CreateType(); assemblyBuilder.SetEntryPoint(mainMethodBuilder); assemblyBuilder.Save(moduleBuilder.ToString()); }
protected RelationalBinaryOperatorNode(ExpressionNode left, ExpressionNode right, string operatorName) : base(left, right, operatorName) { AllowedTypes.Add(typeof(IntegerType)); AllowedTypes.Add(typeof(StringType)); }
public LowerEqualOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "<") { }
private bool ParentIs(IList<ExpressionNode> parameters, ExpressionNode parent ) { return parameters.All(p => p.Parent == parent); }
protected AssignmentBaseNode(ExpressionNode body ) { Body = body; Body.Parent = this; }
public ProdOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "*") { }
public DivOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "/") { }
public NotEqualOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "<>") { AllowedTypes.Add(typeof(RecordType)); AllowedTypes.Add(typeof(ArrayType)); }
public void AddToSequence(ExpressionNode expr) { expr.Parent = this; Sequence.Add(expr); }
public OrOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "|") { }
public GreatherOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, ">") { }
public MinusUnaryOperatorNode(ExpressionNode body) : base(body) { }
public LowerOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "-") { }
public PlusOperatorNode(ExpressionNode left, ExpressionNode right) : base(left, right, "+") { }
public RecordAccessNode(ExpressionNode left, string fieldName) { Left = left; FieldName = fieldName; Left.Parent = this; }