/// <summary> /// Checks function call expressions for correct number of parameters. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The functioncallexpression</param> private SemanticCheckResult CheckFunctionCall(SemActs semActs, FunctionCallExpr exp) { var functionName = exp.ToQualifiedName(); var exists = exp.SymScope.IsFunction(functionName); // 1. Function does not exist. if (!exists) { return(AddErrorCode(ErrorCodes.Func1000, exp, functionName)); } var sym = exp.SymScope.GetSymbol(functionName) as SymbolFunction; var func = sym.FuncExpr as FunctionExpr; // 5. Check that named parameters exist. foreach (var argExpr in exp.ParamListExpressions) { if (argExpr.IsNodeType(NodeTypes.SysNamedParameter)) { var argName = ((NamedParameterExpr)argExpr).Name; if (!func.Meta.ArgumentsLookup.ContainsKey(argName)) { AddErrorCode(ErrorCodes.Func1002, exp, argName); } } } return(SemanticCheckResult.Valid); }
private SemanticCheckResult CheckFunctionDeclaration(SemActs semActs, FunctionDeclareExpr exp) { // 1. Number of params var func = exp.Function; var initialErrorCount = _errors.Count; if (func.Meta.Arguments.Count > 12) { AddErrorCode(ErrorCodes.Func1004, exp); } // 2. Too many aliases on function if (func.Meta.Aliases != null && func.Meta.Aliases.Count > 5) { AddError(ErrorCodes.Func1005, exp); } // 3. Parameter named arguments? if (func.Meta.ArgumentsLookup.ContainsKey("arguments")) { AddErrorCode(ErrorCodes.Func1003, exp); } return(initialErrorCount == _errors.Count ? SemanticCheckResult.Valid : SemanticCheckResult.ErrorContinue); }
/// <summary> /// Check that variable exists and that it is not used befor it is declared. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The variable expression</param> private SemanticCheckResult CheckVariable(SemActs semActs, VariableExpr exp) { if (!_currentSymScope.Contains(exp.Name)) { return(NodeError("Variable " + exp.Name + " does not exist", exp)); } return(SemanticCheckResult.Valid); }
/// <summary> /// Validates all the statements in the script. /// </summary> public override PhaseResult Execute(PhaseContext phaseCtx) { // 1. Check number of statements. var statements = _execAllNodes ? phaseCtx.Nodes : phaseCtx.NodesStack[phaseCtx.NodesStack.Count - 1]; var now = DateTime.Now; // 2. No statements ? return if (statements == null || statements.Count == 0) return ToPhaseResult(now, now, true, "There are 0 nodes to lint"); var semacts = new SemActs(); var result = semacts.Validate(statements); // 4. Simply wrap the run-result ( success, message, start/end times ) // inside of a phase result. return new PhaseResult(result); }
/// <summary> /// Check new expressions. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The newexpression</param> private SemanticCheckResult CheckNewExpression(SemActs semActs, NewExpr exp) { var typeName = exp.TypeName; // 1. Check # params to Date if (string.Compare(typeName, "Date", StringComparison.InvariantCultureIgnoreCase) == 0) { if (!DateTimeTypeHelper.CanCreateDateFrom(exp.ParamListExpressions.Count)) { return(AddError("Unexpected number of inputs when creating date", exp)); } } // 2. Check # params to Time else if (string.Compare(typeName, "Time", StringComparison.InvariantCultureIgnoreCase) == 0) { if (!DateTimeTypeHelper.CanCreateTimeFrom(exp.ParamListExpressions.Count)) { return(AddError("Unexpected number of inputs when creating time", exp)); } } return(SemanticCheckResult.Valid); }
/// <summary> /// Checks for division by zero. /// </summary> /// <param name="semActs"></param> /// <param name="exp"></param> private SemanticCheckResult CheckDivisionByZero(SemActs semActs, BinaryExpr exp) { if (exp.Op != Operator.Divide) { return(SemanticCheckResult.Valid); } if (!(exp.Right.IsNodeType(NodeTypes.SysConstant))) { return(SemanticCheckResult.Valid); } var val = (LObject)((ConstantExpr)exp.Right).Value; if (val.Type == LTypes.Number) { var d = ((LNumber)val).Value; if (d == 0) { AddError("Division by zero", exp.Right); } } return(SemanticCheckResult.Valid); }
/// <summary> /// Checks if there is an if condition that always evaluates to false. /// </summary> /// <param name="semActs"></param> /// <param name="node"></param> private SemanticCheckResult CheckIfFalse(SemActs semActs, AstNode node) { var stmt = node as IfExpr; if (!(stmt.Condition.IsNodeType(NodeTypes.SysConstant))) { return(SemanticCheckResult.Valid); } var exp = stmt.Condition as ConstantExpr; if (!(exp.Value is bool)) { return(SemanticCheckResult.Valid); } bool val = (bool)exp.Value; if (val == false) { return(AddError("If statement condition is always false", stmt)); } return(SemanticCheckResult.Valid); }
/// <summary> /// Check that variable exists and that it is not used befor it is declared. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The variable expression</param> private SemanticCheckResult CheckVariable(SemActs semActs, VariableExpr exp) { if(!_currentSymScope.Contains(exp.Name)) return NodeError("Variable " + exp.Name + " does not exist", exp); return SemanticCheckResult.Valid; }
/// <summary> /// Check new expressions. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The newexpression</param> private SemanticCheckResult CheckNewExpression(SemActs semActs, NewExpr exp) { var typeName = exp.TypeName; // 1. Check # params to Date if (string.Compare(typeName, "Date", StringComparison.InvariantCultureIgnoreCase) == 0) { if (!DateTimeTypeHelper.CanCreateDateFrom(exp.ParamListExpressions.Count)) return AddError("Unexpected number of inputs when creating date", exp); } // 2. Check # params to Time else if (string.Compare(typeName, "Time", StringComparison.InvariantCultureIgnoreCase) == 0) { if (!DateTimeTypeHelper.CanCreateTimeFrom(exp.ParamListExpressions.Count)) return AddError("Unexpected number of inputs when creating time", exp); } return SemanticCheckResult.Valid; }
/// <summary> /// Checks function call expressions for correct number of parameters. /// </summary> /// <param name="semActs">The semantic analyser</param> /// <param name="exp">The functioncallexpression</param> private SemanticCheckResult CheckFunctionCall(SemActs semActs, FunctionCallExpr exp) { var functionName = exp.ToQualifiedName(); var exists = exp.SymScope.IsFunction(functionName); // 1. Function does not exist. if (!exists) { return AddErrorCode(ErrorCodes.Func1000, exp, functionName); } var sym = exp.SymScope.GetSymbol(functionName) as SymbolFunction; var func = sym.FuncExpr as FunctionExpr; // 5. Check that named parameters exist. foreach(var argExpr in exp.ParamListExpressions) { if(argExpr.IsNodeType(NodeTypes.SysNamedParameter)) { var argName = ((NamedParameterExpr) argExpr).Name; if (!func.Meta.ArgumentsLookup.ContainsKey(argName)) AddErrorCode(ErrorCodes.Func1002, exp, argName); } } return SemanticCheckResult.Valid; }
private SemanticCheckResult CheckFunctionDeclaration(SemActs semActs, FunctionDeclareExpr exp) { // 1. Number of params var func = exp.Function; var initialErrorCount = _errors.Count; if (func.Meta.Arguments.Count > 12) AddErrorCode(ErrorCodes.Func1004, exp); // 2. Too many aliases on function if (func.Meta.Aliases != null && func.Meta.Aliases.Count > 5) AddError(ErrorCodes.Func1005, exp); // 3. Parameter named arguments? if (func.Meta.ArgumentsLookup.ContainsKey("arguments")) AddErrorCode(ErrorCodes.Func1003, exp); return initialErrorCount == _errors.Count ? SemanticCheckResult.Valid : SemanticCheckResult.ErrorContinue; }
/// <summary> /// Checks if there is an if condition that always evaluates to false. /// </summary> /// <param name="semActs"></param> /// <param name="node"></param> private SemanticCheckResult CheckIfFalse(SemActs semActs, AstNode node) { var stmt = node as IfExpr; if (!(stmt.Condition.IsNodeType(NodeTypes.SysConstant))) return SemanticCheckResult.Valid; var exp = stmt.Condition as ConstantExpr; if (!(exp.Value is bool)) return SemanticCheckResult.Valid; bool val = (bool)exp.Value; if (val == false) return AddError("If statement condition is always false", stmt); return SemanticCheckResult.Valid; }
/// <summary> /// Checks for division by zero. /// </summary> /// <param name="semActs"></param> /// <param name="exp"></param> private SemanticCheckResult CheckDivisionByZero(SemActs semActs, BinaryExpr exp) { if(exp.Op != Operator.Divide) return SemanticCheckResult.Valid; if (!(exp.Right.IsNodeType(NodeTypes.SysConstant))) return SemanticCheckResult.Valid; var val = (LObject)((ConstantExpr)exp.Right).Value; if (val.Type == LTypes.Number) { var d = ((LNumber)val).Value; if (d == 0) AddError("Division by zero", exp.Right); } return SemanticCheckResult.Valid; }