Beispiel #1
0
 public ClassMember(string name, ITypeDef typeDef, IExpr initializer, bool isGetonly)
 {
     this.name        = name;
     this.typeDef     = typeDef;
     this.initializer = initializer;
     this.isGetonly   = isGetonly;
 }
Beispiel #2
0
        // Returns true if it succeeds, false if there was a name conflict.
        public bool AddMember(string name, ITypeDef typeDef, IExpr initializer = null, bool isStatic = false, bool isFunctionVariable = false, bool isGetonly = false)
        {
            // Fail if a member with that name already exists.
            if (DoesFieldExist(name, SEARCH.EITHER))
            {
                return(false);
            }

            var member = new ClassMember(name, typeDef, initializer, isGetonly);

            // This logic is weird but works because the language currently
            // doesn't allow static member functions.
            if (isStatic)
            {
                member.index = _statics.Add(member.name, member);
                staticVars.Add(new Variable(member.name, typeDef, null));
            }
            else if (!isFunctionVariable && typeDef is TypeDef_Function)
            {
                member.index = _memberFuncs.Add(member.name, member);
            }
            else
            {
                member.index = _fields.Add(member.name, member);
            }

            return(true);
        }
        /// <summary>
        /// Builds a new type from the provided list of properties. The new type implements IObjectAccessor interface
        /// </summary>
        /// <param name="typeDef">Type definition with list of property names and corresponding types.</param>
        /// <returns>Newly created type</returns>
        public static Type MakeType(ITypeDef typeDef)
        {
            if (typeDef == null)
            {
                throw new ArgumentNullException("typeDef");
            }

            string typeName = typeDef.Name;

            if (string.IsNullOrEmpty(typeName))
            {
                typeName = MakeUniqueName();
            }

            s_lock.EnterWriteLock();
            try
            {
                TypeBuilder tb = s_mb.DefineType(typeName, TypeAttributes.Public);
                tb.SetParent(typeof(ObjectAccessorBase <>).MakeGenericType(tb));

                int order = 0;
                foreach (var fb in typeDef.PropertyDefList.Select(entry => tb.DefineField(entry.Key, entry.Value.ResolveType(), FieldAttributes.Public)))
                {
                    AddOrderAttribute(fb, order++);
                }

                return(tb.CreateType());
            }
            finally
            {
                s_lock.ExitWriteLock();
            }
        }
Beispiel #4
0
        // set uses this to 1) check to see if symbol already exists, and 2) caches the variable for use during evaluate
        //		set can also be used to set global variables.
        // for uses this to 1) check to make sure symbol doesn't already exist, 2) push var on the stack for type checking
        public VarStackRef CreateTemp(string symbol, ITypeDef type, bool global = false, bool doesntCollideWithGlobal = false, bool unique = false)
        {
            if (null != GetTypeByName(symbol))
            {
                return(new VarStackRef(VarStackRef.ErrorType.AlreadyExists));
            }

            if (Pb.reservedWords.Contains(symbol))
            {
                return(new VarStackRef(VarStackRef.ErrorType.ReservedSymbol));
            }

            // Unsure about this null
            VarStackRef existingRef = stack.GetVarIndexByName(null, symbol, true);

            if (existingRef.isValid)
            {
                if (!(doesntCollideWithGlobal && existingRef.isGlobal))
                {
                    return(new VarStackRef(VarStackRef.ErrorType.AlreadyExists));
                }
            }

            if (unique)
            {
                Variable var = new Variable(symbol, type, null);
                return(stack.AddExistingVariable(symbol, global, var));
            }
            else
            {
                return(stack.AddVariable(symbol, global, type, null));
            }
        }
Beispiel #5
0
        /* Todo, perhaps: Add function which allows C# to add static functions later. Could help C#-Pebble communication.
         * public Variable AddStaticLiteralAfterFinalization(ExecContext context, string name, ITypeDef typeDef, object value) {
         *      Variable variable = new Variable(name, typeDef);
         *      staticVars.Add(variable);
         *      variable.value = value;
         *      return variable;
         * }
         */

        // Use to add an override of a member function.
        // Caller is responsible for checking that...
        //	1) we have a parent
        //	2) it has a function with this name.
        public void AddFunctionOverride(string name, ITypeDef typeDef, IExpr initializer = null)
        {
            var member = new ClassMember(name, typeDef, initializer, false);

            //var mr = GetMemberRef(name);
            member.index = _memberFuncs.Set(name, member);
        }
Beispiel #6
0
        public virtual bool CanStoreValue(ExecContext context, ITypeDef valueType)
        {
            //if (valueType is TypeDef) {
            //	return null == (valueType as TypeDef).IsNull();
            //}
            if (valueType.IsNull())
            {
                return(true);
            }

            TypeDef_Function funcValueType = valueType as TypeDef_Function;

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

            if (!retType.Equals(IntrinsicTypeDefs.VOID) && !retType.CanStoreValue(context, funcValueType.retType))
            {
                return(false);
            }

            if (null != classType)
            {
                if (null == funcValueType.classType || !classType.CanStoreValue(context, funcValueType.classType))
                {
                    return(false);
                }
                // This is the point of isStatic in this class. This is saying, "I can save a reference to a class member function only if it is static."
            }
            else if (null != funcValueType.classType && !funcValueType.isStaticMember)
            {
                return(false);
            }

            // Mismatch if other's max args exceeds our max args.
            if (argTypes.Count > funcValueType.argTypes.Count)
            {
                return(false);
            }

            // Mismatch if we have fewer min args than they do.
            // (Meaning we could be called with fewer arguments than they have default values for.)
            if (minArgs < funcValueType.minArgs)
            {
                return(false);
            }

            // Make sure that for every argument WE have, THEIR argument's type matches.
            for (int ii = 0; ii < argTypes.Count; ++ii)
            {
                if (!funcValueType.argTypes[ii].CanStoreValue(context, argTypes[ii]))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #7
0
        // NOTE: isStatic = true has never been tested. Library functions are static but are neither flagged as static nor as class members,
        // so references can be saved to them by users already.
        public FunctionValue_Host(ITypeDef _retType, List <ITypeDef> _argTypes, EvaluateDelegate _Evaluate, bool _varargs = false, TypeDef_Class classType = null, bool isStatic = false, List <Expr_Literal> defaultArgVals = null)
        {
            argDefaultValues = defaultArgVals;
            BuildArgHasDefaults(_argTypes.Count);

            valType  = TypeFactory.GetTypeDef_Function(_retType, _argTypes, minArgs, _varargs, classType, true, isStatic);
            Evaluate = _Evaluate;
        }
Beispiel #8
0
        public override bool CanStoreValue(ExecContext context, ITypeDef valueType)
        {
            if (valueType is TypeDef_Enum)
            {
                return(((TypeDef_Enum)valueType).className == className);
            }

            return(false);
        }
Beispiel #9
0
        // ***************************************************************************
        // Type functions.
        // ***************************************************************************

        public bool CreateAlias(string alias, ITypeDef typeDefIn)
        {
            if (_types.ContainsKey(alias))
            {
                return(false);
            }
            _types.Add(alias, typeDefIn);
            return(true);
        }
Beispiel #10
0
 public bool UpdateAlias(string alias, ITypeDef typeDefIn)
 {
     if (!_types.ContainsKey(alias))
     {
         return(false);
     }
     _types[alias] = typeDefIn;
     return(true);
 }
Beispiel #11
0
 public Variable Set(string nameIn, ITypeDef typeIn, object valueIn = null)
 {
     Pb.Assert(null != typeIn, "Can't have a variable without a type.");
     name   = nameIn;
     type   = typeIn;
     value  = valueIn;
     unique = false;
     return(this);
 }
Beispiel #12
0
 // Use this one for class members, both regular and static.
 // Note: statics could be stored as uniques, but everything works
 // atm. If it aint broke, don't fix it.
 public VarStackRef(ITypeDef typeDefIn, int callIx, MemberRef memRef)
 {
     errorType       = ErrorType.None;
     typeDef         = typeDefIn;
     callIndexOffset = callIx;
     varIndex        = -1;
     memberRef       = memRef;
     isGlobal        = false;
     variable        = null;
 }
Beispiel #13
0
        // Convenience function for registering a List<> with a given type, because this gets done a number of times.
        public ClassDef RegisterIfUnregisteredList(ITypeDef valueType)
        {
            List <ITypeDef> genericTypes = new List <ITypeDef>();

            genericTypes.Add(valueType);

            TypeDef_Class listTypeDef = TypeFactory.GetTypeDef_Class("List", genericTypes, false);

            return(engine.defaultContext.RegisterIfUnregisteredTemplate(listTypeDef));
        }
Beispiel #14
0
 // Use this one for non-unique variables on the varStack.
 public VarStackRef(ITypeDef typeDefIn, int callIx, int ix)
 {
     errorType       = ErrorType.None;
     typeDef         = typeDefIn;
     callIndexOffset = callIx;
     varIndex        = ix;
     memberRef       = MemberRef.invalid;
     isGlobal        = false;
     variable        = null;
 }
Beispiel #15
0
 // This is for uniques, both globals and those on the stack.
 public VarStackRef(Variable uniqueVariable, bool global)
 {
     errorType       = ErrorType.None;
     callIndexOffset = -9000;
     varIndex        = -1;
     isGlobal        = global;
     memberRef       = MemberRef.invalid;
     typeDef         = uniqueVariable.type;
     variable        = uniqueVariable;
     variable.unique = true;
 }
Beispiel #16
0
 // This creates an invalid VarStackRef.
 public VarStackRef(ErrorType error)
 {
     Pb.Assert(error != ErrorType.None);
     errorType       = error;
     callIndexOffset = -9000;
     varIndex        = -1;
     isGlobal        = false;
     memberRef       = MemberRef.invalid;
     typeDef         = null;
     variable        = null;
 }
Beispiel #17
0
        public static TypeDef_Function GetTypeDef_Function(ITypeDef retType, List <ITypeDef> argTypes, int minArgs, bool _varargs, TypeDef_Class classType, bool isConst, bool isStatic)
        {
            if (minArgs < 0)
            {
                minArgs = argTypes.Count;
            }

            string args = "";

            for (int ii = 0; ii < argTypes.Count; ++ii)
            {
                string defaultValueString = "";
                if (ii >= minArgs)
                {
                    defaultValueString = " ?";
                }
                args += (ii == 0 ? "" : ", ") + argTypes[ii] + defaultValueString;
            }

            string classPart = "";

            if (null != classType)
            {
                classPart = ":" + classType.className;
            }

            string name = "function" + classPart + "<" + retType + "(" + args + ")>";

            if (_varargs)
            {
                name = name + " varargs";
            }
            if (isStatic)
            {
                name = name + " static";
            }
            if (isConst)
            {
                name = name + " const";
            }

            if (_typeRegistry.ContainsKey(name))
            {
                return(_typeRegistry[name] as TypeDef_Function);
            }

            TypeDef_Function newDef = new TypeDef_Function(retType, argTypes, minArgs, _varargs, classType, isConst, isStatic);

#if PEBBLE_TRACETYPES
            Console.WriteLine("Registering new function type: " + name);
#endif
            _typeRegistry.Add(name, newDef);
            return(newDef);
        }
Beispiel #18
0
        internal TypeDef_Function(ITypeDef _retType, List <ITypeDef> _argTypes, int _minArgs, bool _varargs, TypeDef_Class classTypeIn, bool _isConst, bool _isStaticFunction)
        {
            retType        = _retType;
            argTypes       = _argTypes;
            minArgs        = _minArgs;
            varargs        = _varargs;
            isConst        = _isConst;
            classType      = classTypeIn;
            isStaticMember = _isStaticFunction;

            Pb.Assert(!_varargs || minArgs == _argTypes.Count, "internal error: function cannot be both varArgs and have arguments with default values.");
        }
Beispiel #19
0
        public bool CreateGlobal(string symbol, ITypeDef type, object value = null)
        {
            Variable existing = stack.GetGlobalVariable(symbol);             // existence check

            if (null != existing)
            {
                return(false);
            }

            VarStackRef vsr = stack.AddVariable(symbol, true, type, value);

            return(null != stack.GetVarAtIndex(vsr));            // DoesVarExist
        }
Beispiel #20
0
        //public override bool Equals(object obj) {
        //	throw new InvalidProgramException("INTERNAL ERROR: Attempt to use type before it has been evaluated. (Equals)");
        //}

        public override ITypeDef Resolve(ExecContext context, ref bool error)
        {
            if (name == "void")
            {
                return(IntrinsicTypeDefs.VOID);
            }

            ITypeDef def = context.GetTypeByName(name);

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

            if (null == _templateTypes)
            {
                if (_isConst && !def.IsConst())
                {
                    return(def.Clone(true));
                }
                return(def);
            }

            // If we have template types, then we must be a TypeDef_Class.

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

            for (int ii = 0; ii < _templateTypes.Count; ++ii)
            {
                genericTypes.Add(_templateTypes[ii].Resolve(context, ref error));
            }

            if (error)
            {
                return(null);
            }


            //TypeDef_Class result = new TypeDef_Class(name, genericTypes, _isConst);
            TypeDef_Class result = TypeFactory.GetTypeDef_Class(name, genericTypes, _isConst);

            if (null == context.RegisterIfUnregisteredTemplate(result))
            {
                error = true;
            }
            return(result);
        }
Beispiel #21
0
        public virtual ITypeDef ResolveTemplateTypes(List <ITypeDef> genericTypes, ref bool modified)
        {
            List <ITypeDef> args = new List <ITypeDef>();

            for (int ii = 0; ii < argTypes.Count; ++ii)
            {
                args.Add(argTypes[ii].ResolveTemplateTypes(genericTypes, ref modified));
            }
            ITypeDef newRetType = retType.ResolveTemplateTypes(genericTypes, ref modified);

            if (null != classType)
            {
                classType.ResolveTemplateTypes(genericTypes, ref modified);
            }
            return(TypeFactory.GetTypeDef_Function(newRetType, args, minArgs, varargs, classType, isConst, isStaticMember));
        }
Beispiel #22
0
        public bool Comparable(ExecContext context, ITypeDef other)
        {
            if (!(other is TypeDef_Class))
            {
                return(false);
            }

            if (Equals(other))
            {
                return(true);
            }

            TypeDef_Class otherClassType = other as TypeDef_Class;

            return(null != context.DetermineAncestor(this, otherClassType));
        }
Beispiel #23
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);
        }
Beispiel #24
0
        // Only called by the context.
        public void Initialize()
        {
            if (null != _fields)
            {
                return;
            }

            // 1) fields.
            _fields = new MemberList();
            if (null != parent)
            {
                for (int ii = 0; ii < parent._fields.Count; ++ii)
                {
                    ClassMember member       = parent._fields.Get(ii);
                    bool        modified     = false;
                    ITypeDef    resolvedType = parent.IsGeneric() ? member.typeDef.ResolveTemplateTypes(typeDef.genericTypes, ref modified) : member.typeDef;
                    ClassMember newMember    = new ClassMember(member.name, resolvedType, member.initializer, member.isGetonly);
                    newMember.index = _fields.Add(member.name, newMember);
                }
            }

            // 2) Functions
            _memberFuncs = new MemberList();
            if (null != parent)
            {
                for (int ii = 0; ii < parent._memberFuncs.Count; ++ii)
                {
                    ClassMember member       = parent._memberFuncs.Get(ii);
                    bool        modified     = false;
                    ITypeDef    resolvedType = parent.IsGeneric() ? member.typeDef.ResolveTemplateTypes(typeDef.genericTypes, ref modified) : member.typeDef;
                    ClassMember newMember    = new ClassMember(member.name, resolvedType, member.initializer, member.isGetonly);
                    newMember.index = _memberFuncs.Add(member.name, newMember);
                }

                vftableVars = new List <Variable>(parent.vftableVars);
            }
            else
            {
                vftableVars = new List <Variable>();
            }

            // 3) Statics aren't copied.
            _statics   = new MemberList();
            staticVars = new List <Variable>();
        }
Beispiel #25
0
        public static ITypeDef GetConstVersion(ITypeDef original)
        {
            if (original.IsConst())
            {
                return(original);
            }

            string constName = original.GetName() + " const";

            if (_typeRegistry.ContainsKey(constName))
            {
                return(_typeRegistry[constName]);
            }

            ITypeDef result = original.Clone(true);

            _typeRegistry.Add(constName, result);
            return(result);
        }
Beispiel #26
0
        public string GetDebugString(string name)
        {
            string result = "";

            result += retType.ToString() + " " + name + (null != classType ? ":" + classType.className : "") + "(";
            for (int iArg = 0; iArg < argTypes.Count; ++iArg)
            {
                ITypeDef argdef = argTypes[iArg] as ITypeDef;
                if (0 != iArg)
                {
                    result += ", ";
                }
                result += argdef.ToString() + (iArg >= minArgs ? "?" : "");
            }
            if (varargs)
            {
                result += "[, ...]";
            }
            result += ");\n";
            return(result);
        }
Beispiel #27
0
        public PebbleEnum(ExecContext context, string _enumName, ITypeDef valueTypeIn)
        {
            enumName  = _enumName;
            valueType = valueTypeIn;

            // Apparently need to register non-const first.
            ITypeDef nonConstEnumType = TypeFactory.GetTypeDef_Enum(_enumName, false);

            enumType  = (TypeDef_Enum)TypeFactory.GetConstVersion(nonConstEnumType);
            _classDef = new ClassDef_Enum(this, _enumName, enumType);
            context.RegisterClass(_classDef);

            _classDef.childAllocator = () => {
                return(new ClassValue_Enum());
            };
            _classDef.Initialize();


            //don't think this is needed _classDef.AddMemberLiteral("enumName", IntrinsicTypeDefs.CONST_STRING, _enumName, false);
            _classDef.AddMember("name", IntrinsicTypeDefs.CONST_STRING);
            _classDef.AddMember("value", valueType.Clone(true), null, false, true);

            {
                FunctionValue_Host.EvaluateDelegate eval = (_context, args, thisScope) => {
                    ClassValue cv = thisScope as ClassValue;
                    return(enumName + "::" + cv.Get(mrName).value);
                };
                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.STRING, new ArgList {
                }, eval, false, _classDef.typeDef);
                _classDef.AddMemberLiteral("ThisToString", newValue.valType, newValue, false);
            }

            _classDef.FinalizeClass(context);

            if (mrName.isInvalid)
            {
                mrName  = _classDef.GetMemberRef(null, "name", ClassDef.SEARCH.NORMAL);
                mrValue = _classDef.GetMemberRef(null, "value", ClassDef.SEARCH.NORMAL);
            }
        }
Beispiel #28
0
        public VarStackRef AddVariable(string name, bool global, ITypeDef type, object value = null)
        {
            Variable var;

            if (global)
            {
                var = new Variable(name, type, value);
                _globals.Set(name, var);
                return(new VarStackRef(var, true));
            }

            if (_varStack.Count == _varCount)
            {
                var = new Variable(name, type, value);
                _varStack.Add(var);
            }
            else
            {
                var = _varStack[_varCount];
                if (null == var)
                {
                    var = new Variable(name, type, value);
                    _varStack[_varCount] = var;
                }
                else
                {
                    var.Set(name, type, value);
                }
            }
            ++_varCount;

#if PEBBLE_TRACESTACK
            TraceLog("AddVariable " + type.ToString() + " " + name + "[" + (_varCount - 1) + "] = <" + value + ">");
#endif

            return(new VarStackRef(type, -1, _varCount - _callStack[_callCount - 1].varStackStart - 1));
        }
Beispiel #29
0
        // D B A
        // G E B A
        // This is specifically for the conditional operator.
        //   typeof(true?D:G) is B
        public ITypeDef GetMostCommonType(ITypeDef typeA, ITypeDef typeB)
        {
            bool aIsClass = typeA is TypeDef_Class;

            if (aIsClass)
            {
                bool bIsClass = typeB is TypeDef_Class;
                if (bIsClass)
                {
                    TypeDef_Class classTypeA = typeA as TypeDef_Class;
                    TypeDef_Class classTypeB = typeB as TypeDef_Class;
                    return(GetMostCommonType(classTypeA, classTypeB));
                }
            }

            // If they aren't both classes then they must be equal or they
            // have no commonality.
            if (typeA.Equals(typeB))
            {
                return(typeA);
            }

            return(null);
        }
Beispiel #30
0
        /// <summary>
        /// Builds a new type from the provided list of properties. The new type implements IObjectAccessor interface
        /// </summary>
        /// <param name="typeDef">Type definition with list of property names and corresponding types.</param>
        /// <returns>Newly created type</returns>
        public static Type MakeType(ITypeDef typeDef)
        {
            if (typeDef == null)
                throw new ArgumentNullException("typeDef");

            string typeName = typeDef.Name;
            if (string.IsNullOrEmpty(typeName))
                typeName = MakeUniqueName();

            s_lock.EnterWriteLock();
            try
            {
                TypeBuilder tb = s_mb.DefineType(typeName, TypeAttributes.Public);
                tb.SetParent(typeof(ObjectAccessorBase<>).MakeGenericType(tb));

                int order = 0;
                foreach (var fb in typeDef.PropertyDefList.Select(entry => tb.DefineField(entry.Key, entry.Value.ResolveType(), FieldAttributes.Public)))
                    AddOrderAttribute(fb, order++);

                return tb.CreateType();
            }
            finally
            {
                s_lock.ExitWriteLock();
            }
        }
Beispiel #31
0
 public static Type ResolveTypeDef(ITypeDef td)
 {
     return GetType(td.Name) ?? MakeType(td);
 }
Beispiel #32
0
        // Call this one to create a variable *during execution*.
        // Doesn't do error checking, doesn't care if variable already exists.
        // If you aren't sure what you are doing, you probably want to use CreateGlobal.
        public Variable CreateEval(string symbol, ITypeDef type, object value = null, bool isGlobal = false)
        {
            VarStackRef vsr = stack.AddVariable(symbol, isGlobal, type, value);

            return(stack.GetVarAtIndex(vsr));
        }