예제 #1
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            object host = hosttoken.Execute(context);

            PropertyInfo[] indexer = host.GetType().GetProperties().Where(p => p.GetIndexParameters().Length == parameters.Length).ToArray();
            if (indexer.Length == 0)
            {
                if (parameters.Length == 1)
                {
                    if (host is Array array)
                    {
                        return(array.GetValue(Converter.Convert <int>(parameters[0].Execute(context))));
                    }
                    if (host is IEnumerable enumerable)
                    {
                        return(enumerable.Cast <object>().Skip(Converter.Convert <int>(parameters[0].Execute(context))).First());
                    }
                }

                throw new ScriptRuntimeException($"No indexer methods found on {host}", this);
            }

            object[] parametervalues            = parameters.Select(p => p.Execute(context)).ToArray();
            Tuple <MethodInfo, int>[] evaluated = indexer.Select(i => MethodOperations.GetMethodMatchValue(i.GetMethod, parametervalues)).Where(e => e.Item2 >= 0).ToArray();

            if (evaluated.Length == 0)
            {
                throw new ScriptRuntimeException($"No index getter found on '{host.GetType().Name}' which matched the specified parameters '{string.Join(", ", parametervalues)}'", this);
            }

            MethodInfo method = evaluated.OrderBy(m => m.Item2).Select(m => m.Item1).First();

            return(MethodOperations.CallMethod(this, host, method, parametervalues, context));
        }
예제 #2
0
        /// <inheritdoc />
        protected override object AssignToken(IScriptToken token, ScriptContext context)
        {
            object host = hosttoken.Execute(context);

            if (parameters.Length == 1)
            {
                if (host is Array array)
                {
                    object value = token.Execute(context);
                    array.SetValue(value, Converter.Convert <int>(parameters[0].Execute(context)));
                    return(value);
                }
            }

            PropertyInfo[] indexer = host.GetType().GetProperties().Where(p => p.GetIndexParameters().Length == parameters.Length).ToArray();

            object[] parametervalues            = parameters.Select(p => p.Execute(context)).Concat(new[] { token.Execute(context) }).ToArray();
            Tuple <MethodInfo, int>[] evaluated = indexer.Select(i => MethodOperations.GetMethodMatchValue(i.SetMethod, parametervalues)).Where(e => e.Item2 >= 0).OrderBy(m => m.Item2).ToArray();

            if (evaluated.Length == 0)
            {
                throw new ScriptRuntimeException($"No index setter found on '{host.GetType().Name}' which matched the specified parameters '{string.Join(", ", parametervalues)}'", this);
            }

            return(MethodOperations.CallMethod(this, host, evaluated[0].Item1, parametervalues, context));
        }
        /// <inheritdoc />
        protected override object AssignToken(IScriptToken token, ScriptContext context)
        {
            object host = hosttoken.Execute(context);

            if (host is Dictionary <object, object> dictionary)
            {
                return(dictionary[Member] = token.Execute(context));
            }

            string       member   = membername.ToLower();
            PropertyInfo property = host.GetType().GetProperties().FirstOrDefault(p => p.Name.ToLower() == member);

            if (property != null)
            {
                return(SetProperty(host, property, token, context));
            }

            FieldInfo fieldinfo = host.GetType().GetFields().FirstOrDefault(f => f.Name.ToLower() == member);

            if (fieldinfo == null)
            {
                throw new ScriptRuntimeException($"A member with the name of {membername} was not found in type {host.GetType().Name}", this);
            }

            return(SetField(host, fieldinfo, token, context));
        }
예제 #4
0
        /// <inheritdoc />
        public object Execute(ScriptContext context)
        {
            object result = token.Execute(context);

            if (!(result is Task task))
            {
                throw new ScriptRuntimeException("Only tasks can get awaited", this);
            }

            if (task.Status == TaskStatus.Created)
            {
                task.Start();
            }

            try {
                task.Wait();
            }
            catch (AggregateException e) {
                Exception unwrapped = e;
                while (unwrapped is AggregateException agg && agg.InnerException != null)
                {
                    unwrapped = agg.InnerException;
                }
                throw unwrapped;
            }


            if (!task.GetType().IsGenericType)
            {
                return(null);
            }

            return(task.GetType().GetProperty("Result")?.GetValue(task));
        }
예제 #5
0
 /// <inheritdoc />
 protected override object ExecuteToken(ScriptContext context)
 {
     if (condition.Execute(context).ToBoolean())
     {
         return(Body.Execute(context));
     }
     return(Else?.Execute(context));
 }
예제 #6
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            VariableContext loopvariables = new VariableContext(context.Variables);
            ScriptContext   forcontext    = new ScriptContext(loopvariables, context.Arguments, context.CancellationToken);

            initializer?.Execute(forcontext);

            while (condition.Execute(forcontext).ToBoolean())
            {
                forcontext.CancellationToken.ThrowIfCancellationRequested();

                object value = Body?.Execute(forcontext);
                if (value is Return)
                {
                    return(value);
                }
                if (value is Break breaktoken)
                {
                    int depth = breaktoken.Depth.Execute <int>(forcontext);
                    if (depth <= 1)
                    {
                        return(null);
                    }
                    return(new Break(new ScriptValue(depth - 1)));
                }

                if (value is Continue continuetoken)
                {
                    int depth = continuetoken.Depth.Execute <int>(forcontext);
                    if (depth <= 1)
                    {
                        step?.Execute(forcontext);
                        continue;
                    }

                    return(new Continue(new ScriptValue(depth - 1)));
                }

                step?.Execute(forcontext);
            }

            return(null);
        }
예제 #7
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            object value = condition.Execute(context);
            Case   @case = cases.FirstOrDefault(c => c.Matches(value, context));

            if (@case == null)
            {
                return(Default?.Execute(context));
            }
            return(@case.Execute(context));
        }
        /// <summary>
        /// invokes the method
        /// </summary>
        /// <param name="arguments">arguments for lamda</param>
        /// <returns>execution result</returns>
        public object Invoke(params object[] arguments)
        {
            if (parameters.Length != arguments.Length)
            {
                throw new ScriptRuntimeException($"Argument count doesn't match up parameter count:\n{string.Join(", ", parameters)}", expression);
            }

            for (int i = 0; i < parameters.Length; ++i)
            {
                context.Variables.SetVariable(parameters[i], arguments[i]);
            }

            return(expression.Execute(context));
        }
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            object host = hosttoken.Execute(context);

            if (host is Dictionary <object, object> dictionary)
            {
                return(dictionary[Member]);
            }

            string       member   = membername.ToLower();
            PropertyInfo property = host.GetType().GetProperties().FirstOrDefault(p => p.Name.ToLower() == member);

            if (property != null)
            {
                try {
                    return(property.GetValue(host));
                }
                catch (Exception e) {
                    throw new ScriptRuntimeException("Unable to read property", null, e);
                }
            }


            FieldInfo fieldinfo = host.GetType().GetFields().FirstOrDefault(f => f.Name.ToLower() == member);

            if (fieldinfo == null)
            {
                throw new ScriptRuntimeException($"A member with the name of {membername} was not found in type {host.GetType().Name}", this);
            }

            try {
                return(fieldinfo.GetValue(host));
            }
            catch (Exception e) {
                throw new ScriptRuntimeException("Unable to read field", null, e);
            }
        }
예제 #10
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            object timeargument = timetoken.Execute(context);

            if (timeargument == null)
            {
                throw new ScriptRuntimeException("Specified waiting time was null", this);
            }

            if (timeargument is TimeSpan timespan)
            {
                Thread.Sleep(timespan);
            }
            else
            {
                switch (Type.GetTypeCode(timeargument.GetType()))
                {
                case TypeCode.Byte:
                case TypeCode.Char:
                case TypeCode.Decimal:
                case TypeCode.Double:
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.SByte:
                case TypeCode.Single:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    Thread.Sleep(Converter.Convert <int>(timeargument));
                    break;

                case TypeCode.String:
                    if (((string)timeargument).Contains(":"))
                    {
                        Thread.Sleep(Converter.Convert <TimeSpan>(timeargument));
                    }
                    else
                    {
                        Thread.Sleep(Converter.Convert <int>(timeargument));
                    }
                    break;

                default:
                    throw new ScriptRuntimeException("argument to wait can not be converted to a valid time", this);
                }
            }
            return(null);
        }
        object SetField(object host, FieldInfo fieldinfo, IScriptToken valuetoken, ScriptContext context)
        {
            object targetvalue = Converter.Convert(valuetoken.Execute(context), fieldinfo.FieldType);

            try
            {
                fieldinfo.SetValue(host, targetvalue);
            }
            catch (Exception e)
            {
                throw new ScriptRuntimeException("Unable to set field", null, e);
            }

            return(targetvalue);
        }
        object SetProperty(object host, PropertyInfo property, IScriptToken valuetoken, ScriptContext context)
        {
            object targetvalue = Converter.Convert(valuetoken.Execute(context), property.PropertyType);

            try
            {
                property.SetValue(host, targetvalue, null);
            }
            catch (Exception e)
            {
                throw new ScriptRuntimeException("Unable to set property", null, e);
            }

            return(targetvalue);
        }
예제 #13
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            ScriptContext loopcontext = new ScriptContext(new VariableContext(context.Variables), context.Arguments, context.CancellationToken);

            object collectionvalue = collection.Execute(loopcontext);

            if (collectionvalue is IEnumerable enumeration)
            {
                foreach (object value in enumeration.Cast <object>())
                {
                    context.CancellationToken.ThrowIfCancellationRequested();

                    variable.Assign(new ScriptValue(value), loopcontext);
                    object bodyvalue = Body?.Execute(loopcontext);
                    if (bodyvalue is Return)
                    {
                        return(bodyvalue);
                    }
                    if (bodyvalue is Break breaktoken)
                    {
                        int depth = breaktoken.Depth.Execute <int>(loopcontext);
                        if (depth <= 1)
                        {
                            return(null);
                        }
                        return(new Break(new ScriptValue(depth - 1)));
                    }

                    if (value is Continue continuetoken)
                    {
                        int depth = continuetoken.Depth.Execute <int>(loopcontext);
                        if (depth <= 1)
                        {
                            continue;
                        }

                        return(new Continue(new ScriptValue(depth - 1)));
                    }
                }
            }
            else
            {
                throw new ScriptRuntimeException("Foreach value is not a collection", collection);
            }

            return(null);
        }
예제 #14
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            string typename = TargetType.Execute(context)?.ToString();

            if (typename == null)
            {
                throw new ScriptRuntimeException("cannot cast to null", this);
            }
            Type type = TypeProvider.DetermineType(this, typename);

            object value = Value.Execute(context);

            if (IsDynamic?.Execute(context)?.ToBoolean() ?? false)
            {
                if (value == null)
                {
                    if (type.IsValueType)
                    {
                        return(Activator.CreateInstance(type));
                    }
                    return(null);
                }

                if (type.IsInstanceOfType(value))
                {
                    return(value);
                }
                return(null);
            }

            if (value == null)
            {
                if (type.IsValueType)
                {
                    throw new ScriptRuntimeException($"null cannot get cast to '{typename}'", this);
                }
                return(null);
            }

            if (!type.IsInstanceOfType(value))
            {
                throw new ScriptRuntimeException($"Unable to cast {value} to '{typename}'", this);
            }

            return(value);
        }
        /// <inheritdoc />
        protected override object AssignToken(IScriptToken token, ScriptContext context)
        {
            IVariableProvider provider = context.Variables.GetProvider(Name);

            if (provider == null)
            {
                // auto declare variable in current scope if variable is not found
                provider = context.Variables;
            }

            if (!(provider is IVariableContext variablecontext))
            {
                throw new ScriptRuntimeException($"Variable {Name} not writable", this);
            }

            object value = token.Execute(context);

            variablecontext.SetVariable(Name, value);
            return(value);
        }
예제 #16
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext scriptcontext)
        {
            string messagetext;
            object contextdata;

            try {
                contextdata = Context?.Execute(scriptcontext);
            }
            catch (Exception e) {
                throw new ScriptRuntimeException($"Unable to create context data for throw\n{e.Message}", this, e);
            }

            try {
                messagetext = message.Execute(scriptcontext)?.ToString();
            }
            catch (Exception e) {
                throw new ScriptRuntimeException($"Unable to create message for throw\n{e.Message}", this, e);
            }

            throw new ScriptRuntimeException(messagetext, this)
                  {
                      ContextData = contextdata
                  };
        }
 /// <inheritdoc />
 protected override object ExecuteToken(ScriptContext context)
 {
     return(inner.Execute(context));
 }
예제 #18
0
 /// <inheritdoc />
 public object Execute(params Variable[] variables)
 {
     return(script.Execute(new ScriptContext(new VariableContext(scriptvariables), new VariableProvider(null, variables))));
 }
예제 #19
0
 /// <inheritdoc />
 protected override object ExecuteToken(ScriptContext context)
 {
     return(new Return(new ScriptValue(Value?.Execute(context))));
 }
예제 #20
0
 /// <summary>
 /// executes a script and converts the result
 /// </summary>
 /// <typeparam name="T">type to convert result to</typeparam>
 /// <param name="token">token to execute</param>
 /// <param name="context">context to provide for execution</param>
 /// <returns>converted token result</returns>
 public static T Execute <T>(this IScriptToken token, ScriptContext context)
 {
     return(Converter.Convert <T>(token.Execute(context)));
 }
예제 #21
0
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            object host = hosttoken.Execute(context);

            if (host == null)
            {
                throw new ScriptRuntimeException($"'{hosttoken}' results in null", this);
            }

            if (host is IExternalMethod externmethod && MethodName.ToLower() == "invoke")
            {
                try {
                    return(externmethod.Invoke(context.Arguments, Parameters.Select(a => a.Execute(context)).ToArray()));
                }
                catch (Exception e) {
                    throw new ScriptRuntimeException($"Error calling external method '{externmethod}'", this, e);
                }
            }

            MethodInfo[] methods = host.GetType().GetMethods().Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters)).ToArray();

            object[] parametervalues = parameters.Select(p => p.Execute(context)).ToArray();

            List <ReferenceParameter> references = new List <ReferenceParameter>();

            for (int i = 0; i < parameters.Length; ++i)
            {
                if (!(parameters[i] is Reference r))
                {
                    continue;
                }
                references.Add(new ReferenceParameter(i, r));
            }

            Tuple <MethodInfo, int>[] evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues)).Where(e => e.Item2 >= 0).OrderBy(m => m.Item2).ToArray();
            if (evaluation.Length > 0)
            {
                return(MethodOperations.CallMethod(this, host, evaluation[0].Item1, parametervalues, context, references));
            }

            if (extensions != null)
            {
                Type extensionbase = host.GetType();
                while (extensionbase != null)
                {
                    Type lookuptype = extensionbase;
                    if (lookuptype.IsGenericType)
                    {
                        lookuptype = lookuptype.GetGenericTypeDefinition();
                    }

                    methods    = extensions.GetExtensions(lookuptype).Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters, true)).ToArray();
                    evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues, true)).OrderBy(m => m.Item2).ToArray();
                    if (evaluation.Length > 0)
                    {
                        MethodInfo method = evaluation[0].Item1;
                        if (method.IsGenericMethodDefinition)
                        {
                            method = method.MakeGenericMethod(extensionbase.GetGenericArguments());
                        }

                        return(MethodOperations.CallMethod(this, host, method, parametervalues, context, references, true));
                    }

                    if (extensionbase == typeof(object))
                    {
                        break;
                    }
                    extensionbase = extensionbase.BaseType;
                }


                foreach (Type interfacetype in host.GetType().GetInterfaces().OrderBy(i => i.IsGenericType ? 0 : 1))
                {
                    Type lookuptype = interfacetype;
                    if (lookuptype.IsGenericType)
                    {
                        lookuptype = lookuptype.GetGenericTypeDefinition();
                    }

                    methods    = extensions.GetExtensions(lookuptype).Where(m => m.Name.ToLower() == methodname && MethodOperations.MatchesParameterCount(m, parameters, true)).ToArray();
                    evaluation = methods.Select(m => MethodOperations.GetMethodMatchValue(m, parametervalues, true)).OrderBy(m => m.Item2).ToArray();
                    if (evaluation.Length > 0)
                    {
                        MethodInfo method = evaluation[0].Item1;
                        if (method.IsGenericMethodDefinition)
                        {
                            method = method.MakeGenericMethod(interfacetype.GetGenericArguments());
                        }

                        return(MethodOperations.CallMethod(this, host, method, parametervalues, context, references, true));
                    }
                }
            }

            throw new ScriptRuntimeException($"Method '{methodname}' matching the parameters '({string.Join(",", parametervalues)})' not found on type {host.GetType().Name}", this);
        }
        /// <inheritdoc />
        protected override object ExecuteToken(ScriptContext context)
        {
            string typename = Type.Execute(context)?.ToString();

            if (typename == null)
            {
                throw new ScriptRuntimeException("Invalid parameter type specification", this);
            }

            bool isarray = typename.EndsWith("[]");

            if (isarray)
            {
                typename = typename.Substring(0, typename.Length - 2);
            }

            Type type = TypeProvider.DetermineType(this, typename);

            if (isarray)
            {
                type = typeof(IEnumerable <>).MakeGenericType(type);
            }

            object value;

            if (context.Variables.ContainsVariable(Variable.Name) || (context.Arguments.ContainsVariable(Variable.Name)))
            {
                value = Variable.Execute(context);
            }
            else
            {
                if (DefaultValue != null)
                {
                    value = DefaultValue.Execute(context);
                }
                else
                {
                    throw new ScriptRuntimeException($"Variable {Variable.Name} not provided by script call and no default value provided", this);
                }
            }

            if (value == null)
            {
                if (type.IsValueType)
                {
                    throw new ScriptRuntimeException("Unable to pass null to a value parameter", this);
                }
                return(null);
            }

            if (!type.IsInstanceOfType(value))
            {
                try {
                    value = value = Converter.Convert(value, type);
                }
                catch (Exception e) {
                    throw new ScriptRuntimeException($"Unable to convert parameter '{value}' to '{typename}'", this, e);
                }
            }

            ((VariableProvider)context.Arguments).ReplaceVariable(Variable.Name, value);
            return(value);
        }
 /// <inheritdoc />
 protected override object ExecuteToken(ScriptContext context)
 {
     return(Converter.Convert(token.Execute(context), targettype));
 }