public static bool ValidateParameters(Context context, Scope scope, FunctionParameterDefinitionStatement[] schemeParameters, EvaluationStatement[] parameters, out Exception exception ) { var passedCount = parameters?.Length ?? 0; var expectedCount = schemeParameters?.Length ?? 0; if (passedCount != expectedCount) { exception = new InvalidFunctionCallParametersCompilerException(expectedCount, passedCount, null); return(false); } if (parameters != null && schemeParameters != null) { for (var i = 0; i < parameters.Length; i++) { var passed = parameters[i]; var scheme = schemeParameters[i]; var passedType = passed.GetDataType(context, scope); if (!StatementHelpers.IsAssignableFrom(context, scope, scheme.TypeDescriptor, passedType)) { if (scheme.DynamicType) { continue; } exception = new TypeMismatchCompilerException(passedType, scheme.TypeDescriptor, passed.Info); return(false); } } } exception = null; return(true); }
public override void WriteBlock(Context context, Scope scope, TextWriter writer, TextWriter metaWriter, IStatement statement) { if (!(statement is VariableDefinitionStatement varDefStt)) { throw new InvalidOperationException(); } if (varDefStt.IsConstant) { if (!varDefStt.HasDefaultValue) { throw new InvalidOperationException(); } var result = EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, varDefStt.DefaultValue); if (!(result is ConstantValueStatement constantValueStatement)) { throw new InvalidOperationException(ErrorMessages.ConstantValueRequired); } if (!StatementHelpers.IsAssignableFrom(context, scope, varDefStt.TypeDescriptor, constantValueStatement.TypeDescriptor)) { throw new TypeMismatchCompilerException(constantValueStatement.TypeDescriptor, varDefStt.TypeDescriptor, varDefStt.Info); } scope.ReserveNewConstant(varDefStt.TypeDescriptor, varDefStt.Name, constantValueStatement.Value); } else { var skipDefinition = false; if (varDefStt.HasDefaultValue) { var def = varDefStt.DefaultValue; var transpiler = context.GetEvaluationTranspilerForStatement(def); if (transpiler == null) { throw new InvalidOperationException(); } //it pins non-inlinable values to a helper variable: //int x = 34 * myFunc(); //becomes: //myFuncResult=myFunc() //x=$((34 * myFuncResult)) if (varDefStt.TypeDescriptor.IsArray()) { var p = new ExpressionBuilderParams(context, scope, metaWriter, writer, new BlockStatement(null, varDefStt.Info)); scope.ReserveNewVariable(varDefStt.TypeDescriptor, varDefStt.Name); skipDefinition = true; var targetVar = new VariableAccessStatement(varDefStt.Name, varDefStt.Info); var call = transpiler.CallApiFunction <ApiArray.Copy>(p, new[] { targetVar, def }, varDefStt, varDefStt.Info); if (!call.IsEmptyResult) { WriteVariableDefinition(context, scope, writer, varDefStt.Name, call.Expression); } } else { var result = transpiler.GetExpression(context, scope, metaWriter, writer, null, def); WriteVariableDefinition(context, scope, writer, varDefStt.Name, result.Expression); } } else { WriteVariableDefinition(context, scope, writer, varDefStt.Name, context.Platform.GetDefaultValue(varDefStt.TypeDescriptor.DataType)); } if (!skipDefinition) { scope.ReserveNewVariable(varDefStt.TypeDescriptor, varDefStt.Name); } scope.IncrementStatements(); } }