Example #1
0
        public virtual bool CanStoreValue(ExecContext context, ITypeDef valueType)
        {
            if (valueType is TypeDef && null == ((TypeDef)valueType).GetHostType())
            {
                return(true);
            }

            TypeDef_Class classValueType = valueType as TypeDef_Class;

            if (null == classValueType)
            {
                return(false);
            }

            if (!context.IsChildClass(context.GetClass(className), context.GetClass(classValueType.className)))
            {
                return(false);
            }

            // If neither has generic types, we match.
            if (null == classValueType._genericTypes && null == _genericTypes)
            {
                return(true);
            }

            // If only one has generic types, we do not.
            if (null == classValueType._genericTypes || null == _genericTypes)
            {
                return(false);
            }

            // If they don't have the same number, we do not.
            if (classValueType._genericTypes.Count != _genericTypes.Count)
            {
                return(false);
            }

            for (int ii = 0; ii < _genericTypes.Count; ++ii)
            {
                if (_genericTypes[ii] != classValueType._genericTypes[ii])
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        public override object GetDefaultValue(ExecContext context)
        {
            string        name     = GetName();
            ClassDef      classDef = context.GetClass(name);
            ClassDef_Enum enumDef  = classDef as ClassDef_Enum;

            return(enumDef.enumDef.GetDefaultValue());
        }
Example #3
0
        public static PebbleList AllocateListString(ExecContext context, string debugName = "(List<string> inst)")
        {
            if (null == _listClassDef)
            {
                _listClassDef = context.GetClass("List<string>");
            }
            PebbleList listinst = (PebbleList)_listClassDef.childAllocator();

            listinst.classDef  = _listClassDef;
            listinst.debugName = debugName;
            return(listinst);
        }
Example #4
0
            // List<Child> could be written to a binary file, but then List<Parent> read.
            // If there is no variable with type List<Parent> in the reading script, it
            // wouldn't be in the type registry.
            // This function insures it's in the registry by parsing a little script which
            // creates a temp variable of the desired type.
            // It's pretty inefficient to do this, but parsing type names can be very, very
            // tricky. It wouldn't necessarily be a *better* solution to try to replicate
            // the parser's code.
            protected bool EnsureGenericIsRegistered(ExecContext context, string name)
            {
                if (null != context.GetClass(name))
                {
                    return(true);
                }

                List <ParseErrorInst> errors = new List <ParseErrorInst>();
                // I don't think there is a way to use a variable name that is *guaranteed* not to already exist, sadly.
                IExpr expr = context.engine.Parse("{ " + name + " otehunstoeunthnsjthntxheui; }", ref errors, false);

                return(null != expr && 0 == errors.Count);
            }
Example #5
0
        public virtual object GetDefaultValue(ExecContext context)
        {
            string     name   = GetName();
            ClassDef   parent = context.GetClass(name);
            ClassValue result = parent.Allocate(context);

            if (null == result)
            {
                return(null);
            }

            result.debugName = parent.name + " Inst";
            //result.typeDef = this;
            return(result);
        }
Example #6
0
            public bool Read(ExecContext context, PebbleStreamHelper stream, Variable variable)
            {
                if (variable.type.IsConst())
                {
                    context.SetRuntimeError(RuntimeErrorType.SerializeIntoConst, "Cannot serialize into const variables.");
                    return(false);
                }

                if (variable.type.CanStoreValue(context, IntrinsicTypeDefs.BOOL))
                {
                    variable.value = reader.ReadBoolean();
                }
                else if (variable.type == IntrinsicTypeDefs.NUMBER)
                {
                    variable.value = reader.ReadDouble();
                }
                else if (variable.type == IntrinsicTypeDefs.STRING)
                {
                    variable.value = reader.ReadString();
                }
                else if (variable.type.GetName().StartsWith("List<"))
                {
                    string listTypeName = reader.ReadString();
                    if ("null" == listTypeName)
                    {
                        variable.value = null;
                        return(true);
                    }

                    // Is it possible that the specific generic class isn't registered yet.
                    if (!EnsureGenericIsRegistered(context, listTypeName))
                    {
                        return(false);
                    }

                    ClassDef listDef = context.GetClass(listTypeName);
                    if (null == listDef)
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeUnknownType, "Cannot deserialize list type '" + listTypeName + "' because it is unknown.");
                        return(false);
                    }

                    ClassValue listValue = listDef.Allocate(context);
                    PebbleList newlist   = listValue as PebbleList;
                    variable.value = listValue;

                    ITypeDef elementType = listDef.typeDef.genericTypes[0];

                    int count = reader.ReadInt32();
                    for (int ii = 0; ii < count; ++ii)
                    {
                        Variable newelem = new Variable(null, elementType);
                        if (!Read(context, stream, newelem))
                        {
                            return(false);
                        }
                        newlist.list.Add(newelem);
                    }
                }
                else if (variable.type.GetName().StartsWith("Dictionary<"))
                {
                    string listTypeName = reader.ReadString();
                    if ("null" == listTypeName)
                    {
                        variable.value = null;
                        return(true);
                    }

                    // Is it possible that the specific generic class isn't registered yet.
                    if (!EnsureGenericIsRegistered(context, listTypeName))
                    {
                        return(false);
                    }

                    ClassDef listDef = context.GetClass(listTypeName);
                    if (null == listDef)
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeUnknownType, "Cannot deserialize list type '" + listTypeName + "' because it is unknown.");
                        return(false);
                    }

                    ClassValue       listValue = listDef.Allocate(context);
                    PebbleDictionary newlist   = listValue as PebbleDictionary;
                    variable.value = listValue;

                    ITypeDef keyType   = listDef.typeDef.genericTypes[0];
                    ITypeDef valueType = listDef.typeDef.genericTypes[1];

                    int      count      = reader.ReadInt32();
                    Variable tempKeyVar = new Variable("tempKeyVar", keyType);
                    for (int ii = 0; ii < count; ++ii)
                    {
                        if (!Read(context, stream, tempKeyVar))
                        {
                            return(false);
                        }

                        Variable newelem = new Variable(null, valueType);
                        if (!Read(context, stream, newelem))
                        {
                            return(false);
                        }
                        newlist.dictionary.Add(tempKeyVar.value, newelem);
                    }
                }
                else if (variable.type is TypeDef_Enum)
                {
                    string enumName  = reader.ReadString();
                    string valueName = reader.ReadString();

                    // This happens.
                    ITypeDef streamedType = context.GetTypeByName(enumName);
                    if (null == streamedType)
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeUnknownType, "Attempt to load saved enum of unknown type '" + enumName + "'.");
                        return(false);
                    }

                    // I can't get this to happen.
                    if (!(streamedType is TypeDef_Enum))
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeUnknownType, "Type '" + enumName + "' saved as something other than an enum, but attempted to stream into an enum variable.");
                        return(false);
                    }

                    ClassDef enumClassDef = context.GetClass(enumName);
                    Pb.Assert(null != enumClassDef, "Somehow we got a type for an enum but not the def.");
                    ClassDef_Enum enumDef = enumClassDef as ClassDef_Enum;
                    Pb.Assert(null != enumClassDef, "Registered type is enum but def is classdef.");

                    // This happens.
                    ClassValue_Enum cve = enumDef.enumDef.GetValue(valueName);
                    if (null == cve)
                    {
                        context.SetRuntimeError(RuntimeErrorType.EnumValueNotFound, "Enum '" + enumName + "' does not have saved value '" + valueName + "'.");
                        return(false);
                    }

                    variable.value = cve;
                }
                else if (variable.type is TypeDef_Class)
                {
                    TypeDef_Class varType = variable.type as TypeDef_Class;

                    // Get class name.
                    string streamClassName = reader.ReadString();

                    if ("null" == streamClassName)
                    {
                        variable.value = null;
                        return(true);
                    }

                    ITypeDef streamedType = context.GetTypeByName(streamClassName);
                    if (null == streamedType)
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeUnknownType, "Serialized type '" + streamClassName + "' not found.");
                        return(false);
                    }

                    if (!varType.CanStoreValue(context, streamedType))
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeTypeMismatch, "Cannot deserialize a '" + streamClassName + "' into a variable of type '" + varType.GetName() + "'.");
                        return(false);
                    }

                    TypeDef_Class streamedClassType = streamedType as TypeDef_Class;
                    Pb.Assert(null != streamedClassType, "Somehow a streamed type is not a class but *can* be stored in a class type?!");

                    ClassDef streamedClassDef = context.GetClass(streamClassName);
                    Pb.Assert(null != streamedClassDef, "Somehow we got a type for a class but not the def.");
                    MemberRef serMemRef = streamedClassDef.GetMemberRef(null, "Serialize", ClassDef.SEARCH.NORMAL);
                    if (serMemRef.isInvalid)
                    {
                        context.SetRuntimeError(RuntimeErrorType.SerializeInvalidClass, "Serialize function of class '" + streamClassName + "' not found.");
                        return(false);
                    }

                    ClassValue    streamedClassValue = streamedClassDef.Allocate(context);
                    Variable      serFuncVar         = streamedClassValue.Get(serMemRef);
                    FunctionValue serFuncVal         = serFuncVar.value as FunctionValue;
                    serFuncVal.Evaluate(context, new List <object>()
                    {
                        stream
                    }, streamedClassValue);
                    if (context.IsRuntimeErrorSet())
                    {
                        return(false);
                    }

                    variable.value = streamedClassValue;
                }
                else
                {
                    throw new Exception("Internal error: Unexpected type of value in stream Read.");
                }

                return(true);
            }
Example #7
0
        /*
         * public override string ToString() {
         *      string argString = "ARGS";
         *      return (_isConst ? "const " : "") + "<" + retType + "(" + argString + ")>";
         * }
         */

        public override ITypeDef Resolve(ExecContext context, ref bool error)
        {
            ITypeDef retValType = retType.Resolve(context, ref error);

            if (null == retValType)
            {
                context.engine.LogCompileError(ParseErrorType.TypeNotFound, "Type '" + retType + "' not found.");
                error = true;
                return(null);
            }

            if (null != argHasDefaults && argHasDefaults.Count < argTypes.Count)
            {
                context.engine.LogCompileError(ParseErrorType.DefaultArgGap, "An argument with a default value is followed by an argument without one.");
                error = true;
                return(null);
            }

            int minArgs = argTypes.Count;

            if (null != argHasDefaults)
            {
                int firstDefault = -1;
                for (int ii = 0; ii < argHasDefaults.Count; ++ii)
                {
                    if (argHasDefaults[ii])
                    {
                        if (firstDefault < 0)
                        {
                            firstDefault = ii;
                            minArgs      = ii;
                        }
                    }
                    else if (firstDefault >= 0)
                    {
                        context.engine.LogCompileError(ParseErrorType.DefaultArgGap, "An argument with a default value is followed by an argument without one.");
                        error = true;
                        return(null);
                    }
                }
            }

            List <ITypeDef> argValTypes = new List <ITypeDef>();

            for (int ii = 0; ii < argTypes.Count; ++ii)
            {
                ITypeDef argValType = argTypes[ii].Resolve(context, ref error);
                if (null == argValType)
                {
                    context.engine.LogCompileError(ParseErrorType.TypeNotFound, "Type '" + argTypes[ii] + "' not found.");
                    error = true;
                    return(null);
                }

                argValTypes.Add(argValType);
            }

            TypeDef_Class classType = null;

            if (null != className)
            {
                ClassDef classDef = context.GetClass(className);
                if (null == classDef)
                {
                    Pb.Assert(false, "Internal error: error resolving class type.");
                }
                classType = classDef.typeDef;
            }

            var ret = TypeFactory.GetTypeDef_Function(retValType, argValTypes, minArgs, varArgs, classType, _isConst, false);

            return(ret);
        }