public override void CheckSemantic(Scope scope, ErrorLog log) { LValue.CheckSemantic(scope, log); Value.CheckSemantic(scope, log); if (LValue.Type != null) { //if (!LValue.Type.Match(Value.Type)) //{ // log.Error("The types do not match", Line, Column); //} Type = LValue.Type; } //if (Type != null) //{ // if (Operator == AssignOp.AddAssign || // Operator == AssignOp.SubAssign || // Operator == AssignOp.MulAssign || // Operator == AssignOp.DivAssign) // { // if (!(Type.IsPrimitive && // (Type.ReflectionType.Class == Graphics.TypeClass.Vector || // Type.ReflectionType.Class == Graphics.TypeClass.Scalar || // Type.ReflectionType.Class == Graphics.TypeClass.Matrix))) // { // log.Error("The " + GetValue(Operator) + " is only allowed on type " + Type.Name, Line, Column); // } // } //} if (Type == null) { Type = ShaderRuntime.Unknow; } }
public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors) { ///chequeamos la semántica del LValue LValue.CheckSemantic(symbolTable, errors); ///chequeamos la semántica de la Expression Expression.CheckSemantic(symbolTable, errors); ///si LValue o Expression evalúan de error este evalua de error if (Object.Equals(LValue.NodeInfo, SemanticInfo.SemanticError) || Object.Equals(Expression.NodeInfo, SemanticInfo.SemanticError)) { ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; return; } ///si Expression no evaluó de error if (!Object.Equals(Expression.NodeInfo, SemanticInfo.SemanticError)) { //Expression debe retornar valor if (Expression.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Void)) { errors.Add(new CompileError { Line = Expression.Line, Column = Expression.CharPositionInLine, ErrorMessage = "Assignation expression must return value", Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } } //si LValue no evaluó de error if (!Object.Equals(LValue.NodeInfo, SemanticInfo.SemanticError)) { //el tipo de Expresion y del LValue tienen que ser compatibles if (!LValue.NodeInfo.Type.IsCompatibleWith(Expression.NodeInfo.Type)) { errors.Add(new CompileError { Line = Expression.Line, Column = Expression.CharPositionInLine, ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to '{1}'", Expression.NodeInfo.Type.Name, LValue.NodeInfo.Type.Name), Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } ///si es solamente un id if (LValue is LValueIdNode) { SemanticInfo variable; LValueIdNode lvalueId = LValue as LValueIdNode; if (symbolTable.GetDefinedVariableDeep(lvalueId.VariableName, out variable) && variable.IsReadOnly) { //no podemos modificar una variable readonly(en nuestro caso la de un for) errors.Add(new CompileError { Line = LValue.Line, Column = LValue.CharPositionInLine, ErrorMessage = "A readonly field cannot be assigned to", Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } } } ///el lvalue solo puede ser una variable, el campo de un record o el elemento de un array if (!IsLValueAssignable()) { errors.Add(new CompileError { Line = LValue.Line, Column = LValue.CharPositionInLine, ErrorMessage = "The left-hand side of an assignment must be a variable, field or indexer", Kind = ErrorKind.Semantic }); ///el nodo evalúa de error NodeInfo = SemanticInfo.SemanticError; } ///seteamos los campos necesarios if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError)) { NodeInfo.Type = SemanticInfo.Void; NodeInfo.BuiltInType = BuiltInType.Void; NodeInfo.ILType = Expression.NodeInfo.ILType; } }