Exemplo n.º 1
0
        private static SObject TranslateExpandoObject(ScriptProcessor processor, ExpandoObject objIn)
        {
            var obj = new SProtoObject();

            foreach (var member in objIn)
            {
                obj.AddMember(member.Key, Translate(processor, member.Value));
            }

            return(obj);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates an instance derived from this prototype.
        /// </summary>
        internal SProtoObject CreateInstance(ScriptProcessor processor, SObject[] parameters, bool executeCtor)
        {
            SProtoObject obj = CreateBaseObject();

            obj.IsProtoInstance = true;

            obj.AddMember(MEMBER_NAME_PROTOTYPE, this);

            if (typeof(ObjectPrototype) != GetType())
            {
                // If no extends class is explicitly specified, "Object" is assumed.
                if (Extends == null)
                {
                    Extends = processor.Context.GetPrototype("Object");
                }

                var superInstance = Extends.CreateInstance(processor, null, true);
                obj.AddMember(MEMBER_NAME_SUPER, superInstance);
            }

            foreach (var member in GetInstanceMembers())
            {
                obj.AddMember(member.Identifier, member.Data);
            }

            var indexerGetFunction = GetIndexerGetFunction();

            if (indexerGetFunction != null)
            {
                obj.IndexerGetFunction = indexerGetFunction;
            }

            var indexerSetFunction = GetIndexerSetFunction();

            if (indexerSetFunction != null)
            {
                obj.IndexerSetFunction = indexerSetFunction;
            }

            if (executeCtor)
            {
                Constructor?.ToFunction().Call(processor, obj, obj, parameters);
            }

            // Lock all readonly members after the constructor call, so they can be set in the constructor:
            foreach (PrototypeMember member in GetReadOnlyInstanceMembers())
            {
                obj.Members[member.Identifier].IsReadOnly = true;
            }

            return(obj);
        }
Exemplo n.º 3
0
        private static double GetNumberMember(SProtoObject obj, string member)
        {
            var memberObj = SObject.Unbox(obj.Members[member]);

            if (memberObj is SNumber)
            {
                return(((SNumber)memberObj).Value);
            }
            else
            {
                return(-1);
            }
        }
Exemplo n.º 4
0
        private static string GetStringMember(SProtoObject obj, string member)
        {
            var memberObj = SObject.Unbox(obj.Members[member]);

            if (memberObj is SString)
            {
                return(((SString)memberObj).Value);
            }
            else
            {
                return("");
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Translates an <see cref="SObject"/> to a specific type.
        /// </summary>
        public static object Translate(SProtoObject obj, Type t)
        {
            var instance = Activator.CreateInstance(t);

            var fields = t
                         .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                         .Where(f => f.GetCustomAttribute <CompilerGeneratedAttribute>() == null)
                         .ToArray();

            foreach (var field in fields)
            {
                var varAttr = field.GetCustomAttribute <ScriptVariableAttribute>(false);
                if (varAttr != null)
                {
                    var identifier = field.Name;
                    if (!string.IsNullOrEmpty(varAttr.VariableName))
                    {
                        identifier = varAttr.VariableName;
                    }

                    var setValue = SObject.Unbox(obj.Members[identifier]);

                    try
                    {
                        field.SetValue(instance, Translate(setValue));
                    }
                    catch (Exception)
                    {
                        // This is most likely a type binding issue: Set null if the types don't fit!
                        field.SetValue(instance, null);
                    }
                }
                else
                {
                    var refAttr = field.GetCustomAttribute <ReferenceAttribute>(false);
                    if (refAttr != null)
                    {
                        var identifier = field.Name;
                        if (!string.IsNullOrEmpty(refAttr.VariableName))
                        {
                            identifier = refAttr.VariableName;
                        }

                        field.SetValue(instance, obj.ReferenceContainer[identifier]);
                    }
                }
            }

            return(instance);
        }
Exemplo n.º 6
0
        private static object TranslateDynamic(SProtoObject obj)
        {
            var returnObj = new ExpandoObject() as IDictionary <string, object>;

            foreach (var item in obj.Members)
            {
                var memberName = item.Key;
                // Do not translate back the prototype and super instances:
                if (memberName != SProtoObject.MemberNamePrototype &&
                    memberName != SProtoObject.MemberNameSuper)
                {
                    var memberContent = SObject.Unbox(item.Value);
                    returnObj.Add(memberName, Translate(memberContent));
                }
            }

            return(returnObj);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Converts a string expression into a script object.
        /// </summary>
        private SObject ToScriptObject(string exp)
        {
            exp = exp.Trim();

            // This means it's either an indexer or an array
            if (exp.EndsWith("]"))
            {
                if (!(exp.StartsWith("[") && !exp.Remove(0, 1).Contains("["))) // When there's no "[" besides the start, and it starts with [, then it is an array. Otherwise, do real check.
                {
                    // It is possible that we are having a simple array declaration here.
                    // We check that by looking if we can find a "[" before the expression ends:

                    var depth                  = 0;
                    var index                  = exp.Length - 2;
                    var indexerStartIndex      = 0;
                    var foundIndexer           = false;
                    StringEscapeHelper escaper = new RightToLeftStringEscapeHelper(exp, index);

                    while (index > 0 && !foundIndexer)
                    {
                        var t = exp[index];
                        escaper.CheckStartAt(index);

                        if (!escaper.IsString)
                        {
                            if (t == ')' || t == '}' || t == ']')
                            {
                                depth++;
                            }
                            else if (t == '(' || t == '{')
                            {
                                depth--;
                            }
                            else if (t == '[')
                            {
                                if (depth == 0)
                                {
                                    if (index > 0)
                                    {
                                        indexerStartIndex = index;
                                        foundIndexer      = true;
                                    }
                                }
                                else
                                {
                                    depth--;
                                }
                            }
                        }

                        index--;
                    }

                    if (foundIndexer)
                    {
                        var indexerCode = exp.Substring(indexerStartIndex + 1, exp.Length - indexerStartIndex - 2);

                        var identifier = exp.Remove(indexerStartIndex);

                        var statementResult = ExecuteStatement(new ScriptStatement(indexerCode));
                        return(ToScriptObject(identifier).GetMember(this, statementResult, true));
                    }
                }
            }

            // Normal object return procedure:

            // Negative number:
            var isNegative = false;

            if (exp.StartsWith("-"))
            {
                exp        = exp.Remove(0, 1);
                isNegative = true;
            }

            double  dblResult;
            SObject returnObject;

            if (exp == SObject.LITERAL_NULL)
            {
                returnObject = Null;
            }
            else if (exp == SObject.LITERAL_UNDEFINED)
            {
                returnObject = Undefined;
            }
            else if (exp == SObject.LITERAL_BOOL_FALSE)
            {
                returnObject = CreateBool(false);
            }
            else if (exp == SObject.LITERAL_BOOL_TRUE)
            {
                returnObject = CreateBool(true);
            }
            else if (exp == SObject.LITERAL_NAN)
            {
                returnObject = CreateNumber(double.NaN);
            }
            else if (exp == SObject.LITERAL_THIS)
            {
                returnObject = Context.This;
            }
            else if (SNumber.TryParse(exp, out dblResult))
            {
                returnObject = CreateNumber(dblResult);
            }
            else if (exp.StartsWith("\"") && exp.EndsWith("\"") || exp.StartsWith("\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 1), true, false);
            }
            else if (exp.StartsWith("$\"") && exp.EndsWith("\"") || exp.StartsWith("$\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 2), true, true);
            }
            else if (exp.StartsWith("@\"") && exp.EndsWith("\"") || exp.StartsWith("@\'") && exp.EndsWith("\'"))
            {
                returnObject = CreateString(exp.Remove(exp.Length - 1, 1).Remove(0, 2), false, false);
            }
            else if (exp.StartsWith("{") && exp.EndsWith("}"))
            {
                returnObject = SProtoObject.Parse(this, exp);
            }
            else if (exp.StartsWith("[") && exp.EndsWith("]"))
            {
                returnObject = SArray.Parse(this, exp);
            }
            else if (exp.StartsWith("function") && Regex.IsMatch(exp, REGEX_FUNCTION))
            {
                returnObject = new SFunction(this, exp);
            }
            else if (Context.IsAPIUsing(exp))
            {
                returnObject = Context.GetAPIUsing(exp);
            }
            else if (Context.IsVariable(exp))
            {
                returnObject = Context.GetVariable(exp);
            }
            else if (Context.This.HasMember(this, exp))
            {
                returnObject = Context.This.GetMember(this, CreateString(exp), false);
            }
            else if (Context.IsPrototype(exp))
            {
                returnObject = Context.GetPrototype(exp);
            }
            else if (exp.StartsWith("new "))
            {
                returnObject = Context.CreateInstance(exp);
            }
            else if (exp.StartsWith(ObjectBuffer.OBJ_PREFIX))
            {
                var strId = exp.Remove(0, ObjectBuffer.OBJ_PREFIX.Length);
                var id    = 0;

                if (int.TryParse(strId, out id) && ObjectBuffer.HasObject(id))
                {
                    returnObject = (SObject)ObjectBuffer.GetObject(id);
                }
                else
                {
                    returnObject = ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MESSAGE_SYNTAX_INVALID_TOKEN, exp);
                }
            }
            else
            {
                returnObject = ErrorHandler.ThrowError(ErrorType.ReferenceError, ErrorHandler.MESSAGE_REFERENCE_NOT_DEFINED, exp);
            }

            if (isNegative)
            {
                returnObject = ObjectOperators.NegateNumber(this, returnObject);
            }

            return(returnObject);
        }
Exemplo n.º 8
0
        private static double GetNumberMember(SProtoObject obj, string member)
        {
            var memberNumber = SObject.Unbox(obj.Members[member]) as SNumber;

            return(memberNumber?.Value ?? -1);
        }
Exemplo n.º 9
0
        private static string GetStringMember(SProtoObject obj, string member)
        {
            var memberString = SObject.Unbox(obj.Members[member]) as SString;

            return(memberString != null ? memberString.Value : "");
        }