public static IExecutionTreeNode ImplicitCast(ScriptParser parser, int level, ScriptVariableType requiredType, IExecutionTreeNode node) { ScriptVariableType acceptableTypes = ScriptVariableType.Undefined; // implicit cast is allowed only in loseless cases (except floating point types) switch (requiredType) { case ScriptVariableType.Short: acceptableTypes = ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; case ScriptVariableType.UShort: acceptableTypes = ScriptVariableType.UShort | ScriptVariableType.Byte; break; case ScriptVariableType.Int: acceptableTypes = ScriptVariableType.Int | ScriptVariableType.UShort | ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; case ScriptVariableType.UInt: acceptableTypes = ScriptVariableType.UInt | ScriptVariableType.UShort | ScriptVariableType.Byte; break; case ScriptVariableType.Long: acceptableTypes = ScriptVariableType.Long | ScriptVariableType.UInt | ScriptVariableType.Int | ScriptVariableType.UShort | ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; case ScriptVariableType.ULong: acceptableTypes = ScriptVariableType.ULong | ScriptVariableType.UInt | ScriptVariableType.UShort | ScriptVariableType.Byte; break; case ScriptVariableType.Float: acceptableTypes = ScriptVariableType.Float | ScriptVariableType.UInt | ScriptVariableType.Int | ScriptVariableType.UShort | ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; case ScriptVariableType.Double: acceptableTypes = ScriptVariableType.Double | ScriptVariableType.Float | ScriptVariableType.ULong | ScriptVariableType.Long | ScriptVariableType.UInt | ScriptVariableType.Int | ScriptVariableType.UShort | ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; case ScriptVariableType.Decimal: acceptableTypes = ScriptVariableType.Decimal | ScriptVariableType.Double | ScriptVariableType.Float | ScriptVariableType.ULong | ScriptVariableType.Long | ScriptVariableType.UInt | ScriptVariableType.Int | ScriptVariableType.UShort | ScriptVariableType.Short | ScriptVariableType.Byte | ScriptVariableType.SByte; break; } acceptableTypes = acceptableTypes | requiredType; ScriptVariableType type = node.Process(parser, level); if (type == requiredType) { return(node); } if ((type & acceptableTypes) == ScriptVariableType.Undefined) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.NoImplicitConversion, node, type, requiredType)); return(node); // assume when the error is fixed no implicit cast will be required } TypeCastExecutionNode typeCast = new TypeCastExecutionNode(node.Parent, node.Line, node.Character); node.Parent = typeCast; typeCast.CastFromType = type; typeCast.CastToType = requiredType; typeCast.Value = node; typeCast.IsImplicit = true; typeCast.CastToSystemType = typeCast.CastToType.GetSystemType(); if (parser.DebugParsing) { Utils.IndentedOutput(level, "Inserting implicit cast from '{0}' to '{1}' ({2})", typeCast.CastFromType, typeCast.CastToType, typeCast.CastToSystemType); } return(typeCast); }
public static IExecutionTreeNode ExplicitCast(IExecutionTreeNode node, ScriptVariableType fromType, ScriptVariableType toType) { TypeCastExecutionNode typeCast = new TypeCastExecutionNode(node.Parent, node.Line, node.Character); node.Parent = typeCast; typeCast.CastFromType = fromType; typeCast.CastToType = toType; typeCast.Value = node; return(typeCast); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); Condition = TypeCastExecutionNode.ImplicitCast(parser, level + 1, ScriptVariableType.Bool, Condition); if (TrueNode != null) { TrueNode.Process(parser, level + 1); } if (FalseNode != null) { FalseNode.Process(parser, level + 1); } return(ScriptVariableType.Undefined); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); ResultType = ScriptVariableType.Undefined; try { ScriptVariableDefinition v = parser.GetVariable(VarName.Value); ResultType = v.VarType; } catch { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.UndefinedVariable, VarName, VarName.Value)); } Value = TypeCastExecutionNode.ImplicitCast(parser, level + 1, ResultType, Value); return(ResultType); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); if (Condition != null) { Condition = TypeCastExecutionNode.ImplicitCast(parser, level + 1, ScriptVariableType.Bool, Condition); } if (Code != null) { Code.Process(parser, level + 1); } if (Code == null && Condition == null) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.LoopWithNoConditionNorCode, this)); } return(ScriptVariableType.Undefined); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); ScriptVariableType retType1, retType2; Condition = TypeCastExecutionNode.ImplicitCast(parser, level + 1, ScriptVariableType.Bool, Condition); retType1 = TrueNode.Process(parser, level + 1); retType2 = FalseNode.Process(parser, level + 1); if (retType1 != retType2) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.TrueAndFalseNodesMustBeOfSameValueInTernaryOperation, this, retType1, retType2)); } return(retType1); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); foreach (Definition def in Definitions) { if (!parser.AddVariable(new ScriptVariableDefinition(VarType, def.Name))) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.VariableAlreadyExists, def.Name, def.Name.Value)); } if (def.DefaultValue != null) { def.DefaultValue = TypeCastExecutionNode.ImplicitCast(parser, level + 1, VarType, def.DefaultValue); } else { def.UnassignedDefaultValue = VarType.GetDefaultValue(); } } return(ScriptVariableType.Undefined); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); parser.IncrementScopeLevel(false); if (Init != null) { Init.Process(parser, level + 1); } if (Condition != null) { Condition = TypeCastExecutionNode.ImplicitCast(parser, level + 1, ScriptVariableType.Bool, Condition); } if (Final != null) { Final.Process(parser, level + 1); } if (Code != null) { Code.Process(parser, level + 1); } parser.DecrementScopeLevel(false); return(ScriptVariableType.Undefined); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); if (parser.RequiredReturnType != ScriptVariableType.Undefined) { // Within a function if (parser.RequiredReturnType == ScriptVariableType.Void && ReturnValue != null) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.FunctionMustNotReturnAValue, this)); } else if (parser.RequiredReturnType != ScriptVariableType.Void) { if (ReturnValue == null) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.FunctionMustReturnAValue, this)); } else { ReturnValue = TypeCastExecutionNode.ImplicitCast(parser, level + 1, parser.RequiredReturnType, ReturnValue); ReturnValueType = parser.RequiredReturnType; } } IsInGlobalScope = false; } else { // Within the global scope. Anything or nothing may be returned (works same as 'exit'). if (ReturnValue != null) { ReturnValueType = ReturnValue.Process(parser, level + 1); } IsInGlobalScope = true; } return(ScriptVariableType.Undefined); }
public override ScriptVariableType Process(ScriptParser parser, int level) { base.Process(parser, level); // check script if it has a function we can execute if (parser.GetFunction(Name.Value, out ScriptFunction)) { if (ScriptFunction.Parameters.Count < Parameters.Count) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.TooManyParameters, this)); } else { ParamDefault = new bool[ScriptFunction.Parameters.Count]; for (int i = 0; i < ScriptFunction.Parameters.Count; i++) { if (Parameters.Count <= i || Parameters[i] == null) { if (ScriptFunction.Parameters[i].HasDefaultValue) { ParamDefault[i] = true; } else { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.ParameterIsRequired, this, i, Name.Value)); } } else { ParamDefault[i] = false; Parameters[i] = TypeCastExecutionNode.ImplicitCast(parser, level, ScriptFunction.Parameters[i].ParamType, Parameters[i]); } } } ResultType = (ScriptFunction.ReturnType == ScriptVariableType.Void) ? ScriptVariableType.Undefined : ScriptFunction.ReturnType; return(ResultType); } // check environment if it has a function we can execute if (parser.Script.Environment.GetFunction(Name.Value, out EnvironmentFunction)) { ResultType = EnvironmentFunction.ReturnType; ParameterInfo[] envFuncParams = EnvironmentFunction.Function.GetParameters(); FuncParamCount = envFuncParams.Length; if (envFuncParams.Length < Parameters.Count) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.TooManyParameters, this)); } else { for (int i = 1, j = 0; i < envFuncParams.Length; i++, j++) { if (Parameters.Count <= j || Parameters[j] == null) { parser.Errors.Add(new ErrorInfo(ErrorLevel.Error, ErrorCode.ParameterIsRequired, this, j, Name.Value)); } else { if (!envFuncParams[i].ParameterType.Equals(typeof(object))) { Parameters[j] = TypeCastExecutionNode.ImplicitCast(parser, level, ScriptVariableTypeExtension.GetScriptVariableTypeFromType(envFuncParams[i].ParameterType), Parameters[j]); } else { Parameters[j].Process(parser, level); } } } } return(ResultType); } parser.Errors.Add(new ErrorInfo(ErrorLevel.CriticalError, ErrorCode.FunctionNotFound, this, Name.Value)); throw new ScriptCriticalErrorException(); }