protected override object DoEvaluate(ScriptThread thread) { // standard prolog thread.CurrentNode = this; var binding = thread.Bind(FunctionName, BindingRequestFlags.Read); var result = binding.GetValueRef(thread); if (result == null) { thread.ThrowScriptError("Unknown identifier: {0}", FunctionName); return(null); } CallTarget = result as ICallTarget; if (CallTarget == null) { thread.ThrowScriptError("This identifier cannot be called: {0}", FunctionName); return(null); } // set Evaluate pointer Evaluate = DoCall; // standard epilog is done by DoCall return(DoCall(thread)); }
public override void DoSetValue(ScriptThread thread, object value) { thread.CurrentNode = this; //standard prolog var targetValue = _target.Evaluate(thread); if (targetValue == null) { thread.ThrowScriptError("Target object is null."); } var type = targetValue.GetType(); var indexValue = _index.Evaluate(thread); //string and array are special cases if (type == typeof(string)) { thread.ThrowScriptError("String is read-only."); } else if (type.IsArray) { var arr = targetValue as Array; var iIndex = Convert.ToInt32(indexValue); arr.SetValue(value, iIndex); } else if (targetValue is IDictionary) { var dict = (IDictionary)targetValue; dict[indexValue] = value; } else { const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; type.InvokeMember("set_Item", flags, null, targetValue, new object[] { indexValue, value }); } thread.CurrentNode = Parent; //standard epilog }//method
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog object result = null; var leftValue = _left.Evaluate(thread); if (leftValue == null) thread.ThrowScriptError("Target object is null."); var type = leftValue.GetType(); var members = type.GetMember(_memberName); if (members == null || members.Length == 0) thread.ThrowScriptError("Member {0} not found in object of type {1}.", _memberName, type); var member = members[0]; switch (member.MemberType) { case MemberTypes.Property: var propInfo = member as PropertyInfo; result = propInfo.GetValue(leftValue, null); break; case MemberTypes.Field: var fieldInfo = member as FieldInfo; result = fieldInfo.GetValue(leftValue); break; case MemberTypes.Method: result = new ClrMethodBindingTargetInfo(type, _memberName, leftValue); //this bindingInfo works as a call target break; default: thread.ThrowScriptError("Invalid member type ({0}) for member {1} of type {2}.", member.MemberType, _memberName, type); result = null; break; }//switch thread.CurrentNode = Parent; //standard epilog return result; }
public override void DoSetValue(ScriptThread thread, object value) { thread.CurrentNode = this; //standard prolog var leftValue = _left.Evaluate(thread); if (leftValue == null) thread.ThrowScriptError("Target object is null."); var type = leftValue.GetType(); var members = type.GetMember(_memberName); if (members == null || members.Length == 0) thread.ThrowScriptError("Member {0} not found in object of type {1}.", _memberName, type); var member = members[0]; switch (member.MemberType) { case MemberTypes.Property: var propInfo = member as PropertyInfo; propInfo.SetValue(leftValue, value, null); break; case MemberTypes.Field: var fieldInfo = member as FieldInfo; fieldInfo.SetValue(leftValue, value); break; default: thread.ThrowScriptError("Cannot assign to member {0} of type {1}.", _memberName, type); break; }//switch thread.CurrentNode = Parent; //standard epilog }//method
private void EvaluateNormal(ScriptThread thread) { var mTable = target.Evaluate(thread) as MethodTable; bool createNew = mTable == null; var binding = thread.Runtime.BuiltIns.Bind(new BindingRequest(thread, this, target.Symbol, TypeInfo.NotDefined, BindingRequestFlags.Existing | BindingRequestFlags.Extern | BindingRequestFlags.Read)); if (binding == null) { thread.ThrowScriptError("Extern Symbol {0} not found.", target.Symbol); } var obj = binding.GetValueRef(thread) as MethodTable; if (obj == null) { thread.ThrowScriptError("Extern symbol {0} was not a method table!", target.Symbol); } var tar = obj.GetIndex(parameters.ParamTypes) as BuiltInCallTarget; if (tar == null) { thread.ThrowScriptError("Extern symbol {0} with {1} parameters was not found.", target.Symbol, parameters.ChildNodes.Count); } tar.ParamCount = parameters.ChildNodes.Count; tar.ParamNames = parameters.ParamNames; tar.HasParamsArg = parameters.HasParamsArg; tar.ParamTypes = parameters.ParamTypes; if (createNew) { mTable = new MethodTable(target.Symbol); mTable.Add(tar); target.DoCreate(thread, mTable, TypeInfo.Function); } else { if (mTable.GetIndex(parameters.ParamTypes) != null) { thread.ThrowScriptError("Function {0}({1}) is already defined!", target.Symbol, string.Join(", ", parameters.ParamNames)); } mTable.Add(tar); target.DoSetValue(thread, mTable, TypeInfo.Function); } }
protected override object DoEvaluate(ScriptThread thread) { // standard prolog thread.CurrentNode = this; object result = null; // is this variable a part of a pattern? if (UseType == NodeUseType.Name) { // don't evaluate it result = CreateVariable(); } else { // get last recognized pattern var pattern = thread.GetLastPattern(); if (pattern == null) { thread.ThrowScriptError("No pattern recognized!"); return(null); } // read variable from the last recognized pattern result = pattern.GetVariable(Index); } // standard epilog thread.CurrentNode = Parent; return(result); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog object result = null; var targetValue = _target.Evaluate(thread); if (targetValue == null) thread.ThrowScriptError("Target object is null."); var type = targetValue.GetType(); var indexValue = _index.Evaluate(thread); //string and array are special cases if (type == typeof(string)) { var sTarget = targetValue as string; var iIndex = Convert.ToInt32(indexValue); result = sTarget[iIndex]; } else if (type.IsArray) { var arr = targetValue as Array; var iIndex = Convert.ToInt32(indexValue); result = arr.GetValue(iIndex); } else if (targetValue is IDictionary) { var dict = (IDictionary)targetValue; result = dict[indexValue]; } else { const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; result = type.InvokeMember("get_Item", flags, null, targetValue, new object[] { indexValue }); } thread.CurrentNode = Parent; //standard epilog return result; }
private object EvaluateWithTailCheck(ScriptThread thread) { thread.CurrentNode = this; //standard prolog var target = TargetRef.Evaluate(thread); var iCall = target as ICallTarget; if (iCall == null) { thread.ThrowScriptError(Resources.ErrVarIsNotCallable, _targetName); } var args = (object[])Arguments.Evaluate(thread); object result = null; result = iCall.Call(thread, args); //Note that after invoking tail we can get another tail. // So we need to keep calling tails while they are there. while (thread.Tail != null) { var tail = thread.Tail; var tailArgs = thread.TailArgs; thread.Tail = null; thread.TailArgs = null; result = tail.Call(thread, tailArgs); } thread.CurrentNode = Parent; //standard epilog return(result); }
protected override object DoEvaluate(ScriptThread thread) { // standard prolog thread.CurrentNode = this; if (EntryPoint == null) { thread.ThrowScriptError("No entry point defined (entry point is a function named «Go»)"); return(null); } // define built-in runtime library functions var libraryFunctions = LibraryFunction.ExtractLibraryFunctions(thread, new RefalLibrary(thread)); foreach (var libFun in libraryFunctions) { var binding = thread.Bind(libFun.Name, BindingRequestFlags.Write | BindingRequestFlags.ExistingOrNew); binding.SetValueRef(thread, libFun); } // define functions declared in the compiled program foreach (var fun in FunctionList) { fun.Evaluate(thread); } // call entry point with an empty expression EntryPoint.Call(thread, new object[] { PassiveExpression.Build() }); // standard epilog thread.CurrentNode = Parent; return(null); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; object ret = null; string originalPath = target.Evaluate(thread) as string; List <Type> delegetateParamsHelper = new List <Type> { typeof(ScriptThread), typeof(object), typeof(object[]) }; string path = Path.GetFullPath(originalPath); if (!GetFilePath(ref path)) { path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), originalPath); if (!GetFilePath(ref path)) { thread.ThrowScriptError("LibraryNotFoundException. " + path + " could not be found."); } } if (Path.GetExtension(path) == ".dll") { ret = LoadAssembly(thread, path, delegetateParamsHelper); } else { ret = LoadFile(path, thread); } thread.CurrentNode = Parent; return(ret); }
public static void CheckTypeMatch(ScriptThread thread, TypeInfo expectedType, TypeInfo actualType) { if (!Runtime.IsTypeMatch(expectedType, actualType)) { thread.ThrowScriptError("Type mismatch! Expected {0} but got {1}", expectedType, actualType); } }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog object result; var leftValue = _left.Evaluate(thread); if (leftValue == null) { thread.ThrowScriptError("Target object is null."); } var type = leftValue.GetType(); var members = type.GetMember(_memberName); if (members.Length == 0) { thread.ThrowScriptError("Member {0} not found in object of type {1}.", _memberName, type); } var member = members[0]; switch (member.MemberType) { case MemberTypes.Property: var propInfo = (PropertyInfo)member; result = propInfo.GetValue(leftValue, null); break; case MemberTypes.Field: var fieldInfo = (FieldInfo)member; result = fieldInfo.GetValue(leftValue); break; case MemberTypes.Method: result = new ClrMethodBindingTargetInfo(type, _memberName, leftValue); //this bindingInfo works as a call target break; default: thread.ThrowScriptError("Invalid member type ({0}) for member {1} of type {2}.", member.MemberType, _memberName, type); result = null; break; } thread.CurrentNode = Parent; //standard epilog return(result); }
private void EvaluateExtension(ScriptThread thread) { var ident = target.Symbol; IBindingSource cons; MethodTable mTable = null; if (thread.Runtime.ExtensionFunctions.TryGetValue(ident, out cons)) { mTable = ((cons as BuiltInCallableTargetInfo).BindingInstance as ConstantBinding).Target as MethodTable; } else { mTable = new MethodTable(ident); var targetInfo = new BuiltInCallableTargetInfo(mTable); thread.Runtime.ExtensionFunctions.Add(ident, targetInfo); } var binding = thread.Runtime.BuiltIns.Bind(new BindingRequest(thread, this, ident, TypeInfo.Function, BindingRequestFlags.Existing | BindingRequestFlags.Extern | BindingRequestFlags.Read)); if (binding == null) { thread.ThrowScriptError("Extern Symbol {0} not found.", ident); } var obj = binding.GetValueRef(thread) as MethodTable; if (obj == null) { thread.ThrowScriptError("Extern symbol {0} was not a method table!", ident); } var tar = obj.GetIndex(parameters.ParamTypes) as BuiltInCallTarget; if (tar == null) { thread.ThrowScriptError("Extern symbol {0} with {1} parameters was not found.", target.Symbol, parameters.ChildNodes.Count); } tar.ParamCount = parameters.ChildNodes.Count; tar.ParamNames = parameters.ParamNames; tar.HasParamsArg = parameters.HasParamsArg; tar.ParamTypes = parameters.ParamTypes; mTable.Add(tar); }
protected override object DoEvaluate(ScriptThread thread) { // standard prolog thread.CurrentNode = this; // evaluate expression var expression = Expression.EvaluateExpression(thread); object result = null; // extract last recognized pattern (it contains bound variables) var lastPattern = thread.GetLastPattern(); if (lastPattern == null) { thread.ThrowScriptError("Internal error: last recognized pattern is lost."); return(null); // never gets here } // with-clause if (Block != null) { Block.InputExpression = expression; Block.BlockPattern = lastPattern; result = Block.Evaluate(thread); } // where-clause else if (Pattern != null) { result = EvaluateWhereClause(expression, lastPattern, thread); } // internal compiler error else { thread.ThrowScriptError("Internal error: AST node doen't represent neither where- nor when-clause."); return(null); // never get here } // standard epilog thread.CurrentNode = Parent; return(result); }
// Evaluation for non-tail languages private object EvaluateNoTail(ScriptThread thread) { thread.CurrentNode = this; //standard prolog var target = TargetRef.Evaluate(thread); var iCall = target as ICallTarget; if (iCall == null) thread.ThrowScriptError(Resources.ErrVarIsNotCallable, _targetName); var args = (object[])Arguments.Evaluate(thread); object result = iCall.Call(thread, args); thread.CurrentNode = Parent; //standard epilog return result; }
public override void DoSetValue(ScriptThread thread, object value, TypeInfo type = TypeInfo.NotDefined) { thread.CurrentNode = this; thread.ThrowScriptError("this is not writable."); //binding = thread.Bind("this", BindingRequestFlags.Write); //SetValue = binding.SetValueRef; //SetValue(thread, value); thread.CurrentNode = Parent; }
public override void DoSetValue(ScriptThread thread, object value) { thread.CurrentNode = this; //standard prolog var targetValue = _target.Evaluate(thread); if (targetValue == null) { thread.ThrowScriptError("Target object is null."); } var type = targetValue.GetType(); var indexValue = _index.Evaluate(thread); //string and array are special cases if (type == typeof(string)) { thread.ThrowScriptError("String is read-only."); } else if (type.IsArray) { var arr = (Array)targetValue; var iIndex = Convert.ToInt32(indexValue); arr.SetValue(value, iIndex); } else if (targetValue is IDictionary dict) { dict[indexValue] = value; } else { // Cannot use IndexerNameAttribute, see: // https://social.msdn.microsoft.com/Forums/en-US/60de101a-278d-4674-bc1a-0a04210d566c/identifying-the-indexername-attribute-on-an-indexer-property?forum=vstscode var defaultMemberAttr = type.GetCustomAttribute <DefaultMemberAttribute>(); var indexerName = defaultMemberAttr?.MemberName ?? "Item"; const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; type.InvokeMember("set_" + indexerName, flags, null, targetValue, new[] { indexValue, value }); } thread.CurrentNode = Parent; //standard epilog }
public override void DoSetValue(ScriptThread thread, object value) { thread.CurrentNode = this; //standard prolog var leftValue = _left.Evaluate(thread); if (leftValue == null) { thread.ThrowScriptError("Target object is null."); } var type = leftValue.GetType(); var members = type.GetMember(_memberName); if (members.Length == 0) { thread.ThrowScriptError("Member {0} not found in object of type {1}.", _memberName, type); } var member = members[0]; switch (member.MemberType) { case MemberTypes.Property: var propInfo = (PropertyInfo)member; propInfo.SetValue(leftValue, value, null); break; case MemberTypes.Field: var fieldInfo = (FieldInfo)member; fieldInfo.SetValue(leftValue, value); break; default: thread.ThrowScriptError("Cannot assign to member {0} of type {1}.", _memberName, type); break; } thread.CurrentNode = Parent; //standard epilog }
public override void DoSetValue(ScriptThread thread, object value) { thread.CurrentNode = this; //standard prolog var targetValue = _target.Evaluate(thread); if (targetValue == null) thread.ThrowScriptError("Target object is null."); var type = targetValue.GetType(); var indexValue = _index.Evaluate(thread); //string and array are special cases if (type == typeof(string)) { thread.ThrowScriptError("String is read-only."); } else if (type.IsArray) { var arr = targetValue as Array; var iIndex = Convert.ToInt32(indexValue); arr.SetValue(value, iIndex); } else if (targetValue is IDictionary) { var dict = (IDictionary)targetValue; dict[indexValue] = value; } else { const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; type.InvokeMember("set_Item", flags, null, targetValue, new object[] { indexValue, value }); } thread.CurrentNode = Parent; //standard epilog }//method
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; var result = new DataTable(ChildNodes.Count); int indexCounter = 0; foreach (AstNode t in ChildNodes) { var tmp = t.Evaluate(thread); var arr = tmp as object[]; if (arr != null) { if (arr.Length != 2) { thread.ThrowScriptError("Failed to create array."); } var name = (string)arr[0]; var iCall = arr[1] as ICallTarget; var mTable = result.GetString(thread, name) as MethodTable; if (iCall != null) { if (mTable != null) { mTable.Add(iCall); arr[1] = mTable; } else { mTable = new MethodTable(name); mTable.Add(iCall); arr[1] = mTable; } } result.SetString(thread, name, arr[1]); } else { result.SetInt(thread, indexCounter, tmp); indexCounter++; } } thread.CurrentNode = Parent; return(result); }
// Evaluation for non-tail languages private object EvaluateNoTail(ScriptThread thread) { thread.CurrentNode = this; //standard prolog var target = TargetRef.Evaluate(thread); var iCall = target as ICallTarget; if (iCall == null) { thread.ThrowScriptError(Resources.ErrVarIsNotCallable, _targetName); } var args = (object[])Arguments.Evaluate(thread); object result = iCall.Call(thread, args); thread.CurrentNode = Parent; //standard epilog return(result); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog object result = null; var targetValue = _target.Evaluate(thread); if (targetValue == null) { thread.ThrowScriptError("Target object is null."); } var type = targetValue.GetType(); var indexValue = _index.Evaluate(thread); //string and array are special cases if (type == typeof(string)) { var sTarget = targetValue as string; var iIndex = Convert.ToInt32(indexValue); result = sTarget[iIndex]; } else if (type.IsArray) { var arr = targetValue as Array; var iIndex = Convert.ToInt32(indexValue); result = arr.GetValue(iIndex); } else if (targetValue is IDictionary) { var dict = (IDictionary)targetValue; result = dict[indexValue]; } else { //const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; //result = type.InvokeMember("get_Item", flags, null, targetValue, new object[] { indexValue }); var methodInfo = type.GetTypeInfo().GetDeclaredMethod("get_Item"); methodInfo.Invoke(targetValue, new object[] { indexValue }); } thread.CurrentNode = Parent; //standard epilog return(result); }
public void DoCreate(ScriptThread thread, object value, TypeInfo type) { thread.CurrentNode = this; var valueType = Runtime.TypeToTypeInfo(value.GetType()); Runtime.CheckTypeMatch(thread, type, valueType); if (binding == null || binding is NullBinding) { binding = thread.Bind(Symbol, type, BindingRequestFlags.Write | BindingRequestFlags.NewOnly); } if (binding?.SetValueRef == null) { thread.ThrowScriptError("could not create {0} for writing", Symbol); } binding.SetValueRef(thread, value, valueType); thread.CurrentNode = Parent; }
public override void DoSetValue(ScriptThread thread, object value, TypeInfo type = TypeInfo.NotDefined) { thread.CurrentNode = this; var valueType = Runtime.TypeToTypeInfo(value.GetType()); Runtime.CheckTypeMatch(thread, type, valueType); if (binding == null || binding is NullBinding) { binding = thread.Bind(Symbol, type, BindingRequestFlags.Write | BindingRequestFlags.ExistingOrNew | BindingRequestFlags.PreferExisting); } if (binding?.SetValueRef == null) { thread.ThrowScriptError("ups {0} is not writable", Symbol); } binding.SetValueRef(thread, value, valueType); thread.CurrentNode = Parent; }
protected override object DoEvaluate(ScriptThread thread) { // standard prolog thread.CurrentNode = this; foreach (var sentence in Sentences) { sentence.InputExpression = InputExpression; sentence.BlockPattern = BlockPattern; var result = sentence.Evaluate(thread); if (result != null) { // standard epilog thread.CurrentNode = Parent; return(result); } } // standard Refal exception: input expression doesn't match any pattern thread.ThrowScriptError("Recognition impossible"); return(null); }
public override object Call(ScriptThread thread, object[] parameters) { thread.ThrowScriptError("Calling external function is not supported"); return(null); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; object result = thread.Runtime.NullValue; var target = TargetRef.Evaluate(thread); var args = (object[])Arguments.Evaluate(thread); int argCount = Arguments.ChildNodes.Count; var argsType = args.Select(e => Runtime.TypeToTypeInfo(e.GetType())).ToArray(); var iCall = target as ICallTarget; var mTable = target as MethodTable; if (mTable != null) { iCall = mTable.GetIndex(argsType); if (iCall == null) { thread.ThrowScriptError("There is no function with name {0}({2}), that takes {1} arguments.", targetName, argCount, string.Join(", ", argsType)); } } if (iCall == null) { thread.ThrowScriptError("Variable {0} of type {1} is not a callable function.", targetName, target.GetType().Name); } if (iCall.GetParameterCount() != argCount && iCall.GetParameterCount() != -1 && !iCall.GetHasParamsArg()) { thread.ThrowScriptError("{0}({2}) does not take {1} arguments.", targetName, argCount, string.Join(", ", iCall.GetFunctionInfo().ParamTypes)); } if (iCall.GetHasParamsArg() && (iCall.GetParameterCount() != argCount || !(args[args.Length - 1] is DataTable))) { var tempArgs = new object[iCall.GetParameterCount()]; Array.Copy(args, tempArgs, tempArgs.Length - 1); int lastIndex = tempArgs.Length - 1; var tempDT = new DataTable(args.Length - lastIndex); for (int i = lastIndex; i < args.Length; i++) { tempDT.SetInt(thread, i - lastIndex, args[i]); } tempArgs[lastIndex] = tempDT; args = tempArgs; } var fi = iCall.GetFunctionInfo(); PushCallStack(thread); var back = thread.CurrentFuncInfo; thread.CurrentFuncInfo = fi; object thisRef = thread.Runtime.NullValue; if (TargetRef is MemberAccessNode) { var man = (MemberAccessNode)TargetRef; thisRef = man.lastTargetValue; } else { var bind = thread.Bind("this", BindingRequestFlags.Existing | BindingRequestFlags.NullOk | BindingRequestFlags.Read); if (bind != null && !(bind is NullBinding) && bind.GetValueRef != null) { thisRef = bind.GetValueRef(thread); } } result = iCall.Call(thread, thisRef, args); thread.CallStack.Pop(); thread.CurrentFuncInfo = back; thread.CurrentNode = Parent; return(result); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog thread.ThrowScriptError(Resources.ErrConstructNotSupported, Name); return(null); //never happens }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog thread.ThrowScriptError(Resources.ErrNullNodeEval, Term); return(null); //never happens }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; //standard prolog thread.ThrowScriptError(Resources.ErrConstructNotSupported, Name); return null; //never happens }
public override void DoSetValue(ScriptThread thread, object value, Interpreter.TypeInfo type = Interpreter.TypeInfo.NotDefined) { thread.CurrentNode = this; var targetValue = target.Evaluate(thread); if (targetValue == null) { thread.ThrowScriptError("Target object is null"); } if (targetValue == thread.Runtime.NullValue) { thread.ThrowScriptError("NullReferenceException. target was null (" + target.AsString + ")"); } var valueType = targetValue.GetType(); var indexValue = index.Evaluate(thread); if (valueType == typeof(string)) { thread.ThrowScriptError("String is read-only"); } else if (valueType == typeof(DataTable)) { try { var dtTarget = targetValue as DataTable; var dtIndex = indexValue as IEnumerable; if (indexValue is string sIndex) { dtTarget.SetString(thread, sIndex, value); } else if (dtIndex != null) { dtTarget.FilterSet(thread, dtIndex, value); } else { int iIndex = Convert.ToInt32(indexValue); dtTarget.SetInt(thread, iIndex, value); } } catch (OutOfMemoryException e) { thread.ThrowScriptError("Out of Memory exception!"); } catch (Exception e) { thread.ThrowScriptError("Index must be string, number or table. Exception was " + e.GetType() + " " + e.Message); } } else if (valueType.IsArray) { var arr = targetValue as Array; var iIndex = (int)Convert.ToDecimal(indexValue); arr.SetValue(value, iIndex); } else if (targetValue is System.Collections.IDictionary dict) { dict[indexValue] = value; } else { BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; valueType.InvokeMember("set_Item", flags, null, targetValue, new object[] { indexValue, value }); } thread.CurrentNode = Parent; }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; object result = thread.Runtime.NullValue; var targetValue = target.Evaluate(thread); if (targetValue == null) { thread.ThrowScriptError("Target object is null."); } var type = targetValue.GetType(); var indexValue = index.Evaluate(thread); if (type == typeof(Range) || type == typeof(RangeWithStep)) { targetValue = new DataTable(targetValue as IEnumerable, thread); type = typeof(DataTable); } if (type == typeof(string)) { var sTarget = targetValue as string; if (indexValue is Range r) { if (r.Start <= r.End) { int start = (int)r.Start; start = start > 0 ? start : 0; start = start < sTarget.Length ? start : sTarget.Length - 1; int length = (int)r.Length; length = length + start <= sTarget.Length ? length : sTarget.Length - start; result = sTarget.Substring(start, length); } else { result = string.Join("", sTarget.Reverse().Skip((int)r.End).Take((int)r.Length)); } } else if (indexValue is RangeWithStep rs) { result = string.Join("", rs.Where(e => e >= 0 && e < sTarget.Length).Select(e => sTarget[(int)e])); } else { var iIndex = Convert.ToInt32(indexValue); if (iIndex < sTarget.Length) { result = sTarget[iIndex]; } else { result = '\0'; } } } else if (type == typeof(DataTable)) { try { var dtTarget = targetValue as DataTable; string sIndex = indexValue as string; var dtIndex = indexValue as IEnumerable; if (sIndex != null) { result = dtTarget.GetString(thread, sIndex); } else if (dtIndex != null) { result = dtTarget.Filter(thread, dtIndex); } else { int iIndex = Convert.ToInt32(indexValue); result = dtTarget.GetInt(thread, iIndex); } } catch (Exception) { thread.ThrowScriptError("Index must be string, number or table."); } } else if (type.IsArray) { var arr = targetValue as Array; var iIndex = Convert.ToInt32(indexValue); result = arr.GetValue(iIndex); } else if (targetValue is System.Collections.IDictionary dict) { result = dict[indexValue]; } else { BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.InvokeMethod; result = type.InvokeMember("get_Item", flags, null, targetValue, new object[] { indexValue }); } thread.CurrentNode = Parent; return(result); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; object result = thread.Runtime.NullValue; FlowControl = FlowControl.Next; if (DependentScopeInfo == null) { DependentScopeInfo = new ScopeInfo(this, Parent?.AsString ?? ""); } thread.PushScope(DependentScopeInfo, null); IterVarBlock?.Evaluate(thread); DataTable foreachObject = null; var rawobject = InExpr.Evaluate(thread); if (rawobject is string) { foreachObject = new DataTable((string)rawobject, thread); } else if (rawobject is DataTable) { foreachObject = (DataTable)rawobject; } else if (rawobject is IEnumerable) { foreachObject = new DataTable((IEnumerable)rawobject, thread); } else { thread.ThrowScriptError("Can't iterate over object of type {0}", rawobject.GetType().Name); } foreach (var e in foreachObject) { IterVarBlock.SetValue(thread, e, TypeInfo.NotDefined); result = Block.Evaluate(thread); if (Block.FlowControl == FlowControl.Break) { break; } if (Block.FlowControl == FlowControl.Continue) { FlowControl = FlowControl.Next; } if (Block.FlowControl == FlowControl.Return) { break; } } thread.PopScope(); if (Block.FlowControl == FlowControl.Return) { FlowControl = FlowControl.Return; } thread.CurrentNode = Parent; return(result); }
protected override object DoEvaluate(ScriptThread thread) { thread.CurrentNode = this; thread.ThrowScriptError(Irony.Resources.ErrNullNodeEval, Term); return(null); }
private object EvaluateWithTailCheck(ScriptThread thread) { thread.CurrentNode = this; //standard prolog var target = TargetRef.Evaluate(thread); var iCall = target as ICallTarget; if (iCall == null) thread.ThrowScriptError(Resources.ErrVarIsNotCallable, _targetName); var args = (object[])Arguments.Evaluate(thread); object result = null; result = iCall.Call(thread, args); //Note that after invoking tail we can get another tail. // So we need to keep calling tails while they are there. while (thread.Tail != null) { var tail = thread.Tail; var tailArgs = thread.TailArgs; thread.Tail = null; thread.TailArgs = null; result = tail.Call(thread, tailArgs); } thread.CurrentNode = Parent; //standard epilog return result; }