Example #1
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);
        }
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 override bool CanStoreValue(ExecContext context, ITypeDef valueType)
        {
            if (valueType is TypeDef_Enum)
            {
                return(((TypeDef_Enum)valueType).className == className);
            }

            return(false);
        }
Example #4
0
        public static string StandardPrintFunction(ExecContext context, List <object> args)
        {
            string result = "";

            foreach (object val in args)
            {
                result += CoreLib.ValueToString(context, val, false);
            }
            return(result);
        }
Example #5
0
        // ********************************************************************

        // Checks stack, class, and global.
        public bool IsSymbolAvailable(ExecContext context, string symbol, bool ignoreGlobals = false)
        {
            if (context.DoesTypeExist(symbol))
            {
                return(false);
            }
            VarStackRef index = GetVarIndexByName(null, symbol, true);

            return(!index.isValid || (ignoreGlobals && index.isGlobal));
        }
Example #6
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 #7
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 #8
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);
        }
Example #9
0
        // Call this after creating the class and adding members to it.
        public bool FinalizeClass(ExecContext context)
        {
            Pb.Assert(0 == context.control.flags);

            // Only initializing the members that this class has added is a cool idea, but
            // leaves us f****d when it comes to overrridden functions.
            // So, I'm being lazy here and initializing them all.
            for (int ii = 0; ii < _memberFuncs.Count; ++ii)
            {
                ClassMember member = _memberFuncs.Get(ii);

                if (null != member.initializer && (member.initializer is Expr_Literal || member.initializer is Expr_Value))
                {
                    // Make sure vftableVars has a slot for this function.
                    while (vftableVars.Count < ii + 1)
                    {
                        vftableVars.Add(null);
                    }

                    object initValue = member.initializer.Evaluate(context);
                    if (context.IsRuntimeErrorSet())
                    {
                        return(false);
                    }

                    // Create the variable for the function.
                    vftableVars[ii] = new Variable(member.name, member.typeDef, initValue);
                }
            }

            // Initialize the static members. Populates the staticVars list.
            for (int ii = 0; ii < _statics.Count; ++ii)
            {
                ClassMember member    = _statics.Get(ii);
                object      initValue = null;
                if (null != member.initializer)
                {
                    initValue = member.initializer.Evaluate(context);
                    if (context.IsRuntimeErrorSet())
                    {
                        context.engine.LogCompileError(ParseErrorType.StaticMemberEvaluationError, name + "::" + member.name + " - " + context.GetRuntimeErrorString());
                        return(false);
                    }
                }
                staticVars[ii] = new Variable(member.name, member.typeDef, initValue);
            }

            return(true);
        }
Example #10
0
        public object EvaluateValues(ExecContext context)
        {
            bool   isNum       = valueType.CanStoreValue(context, IntrinsicTypeDefs.NUMBER);
            double nextInteger = 0;
            bool   isString    = valueType.CanStoreValue(context, IntrinsicTypeDefs.STRING);

            for (int ii = 0; ii < _values.Count; ++ii)
            {
                ClassValue_Enum val = (ClassValue_Enum)_classDef.Allocate(context);
                val.Get(mrName).value          = _values[ii].name;
                _classDef.staticVars[ii].value = val;

                if (null == _values[ii].initializer)
                {
                    if (isNum)
                    {
                        // If number, use next consecutive integer.
                        val.Get(mrValue).value = nextInteger;
                        nextInteger            = Math.Floor(nextInteger + 1);
                    }
                    else if (isString)
                    {
                        // If string, just use name.
                        val.Get(mrValue).value = _values[ii].name;
                    }
                    else
                    {
                        // Use the default value.
                        val.Get(mrValue).value = valueType.GetDefaultValue(context);
                    }
                }
                else
                {
                    object init = _values[ii].initializer.Evaluate(context);
                    if (context.IsRuntimeErrorSet())
                    {
                        return(null);
                    }
                    val.Get(mrValue).value = init;

                    if (isNum)
                    {
                        nextInteger = Math.Floor((double)init + 1);
                    }
                }
            }

            return(false);
        }
Example #11
0
        public bool PushClassScope(ClassValue instance, ExecContext context, string msg = "")
        {
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

            _callStack[_callCount].Set(_varCount, instance, true);
            ++_callCount;

#if PEBBLE_TRACESTACK
            TraceScope("PushClassScope");
#endif
            return(true);
        }
Example #12
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 #13
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));
        }
Example #14
0
        // This pushes a non-terminal scope ("block") onto the stack.
        // Use for "if", "for", and exrpession lists.
        public bool PushBlock(string name, ExecContext context)
        {
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

            _callStack[_callCount].Set(_varCount, name);
            ++_callCount;

#if PEBBLE_TRACESTACK
            TraceScope("PushBlock " + name);
#endif

            return(true);
        }
Example #15
0
        public bool AddValue_Default(ExecContext context, string valueName)
        {
            if (_names.ContainsKey(valueName))
            {
                return(false);
            }
            _names.Add(valueName, true);

            _classDef.AddMember(valueName, enumType, null, true);

            EnumValue ev = new EnumValue();

            ev.name = valueName;
            _values.Add(ev);
            return(true);
        }
Example #16
0
        public virtual string ToString(ExecContext context)
        {
            Variable var = GetByName("ThisToString");

            if (null != var && var.type is TypeDef_Function)
            {
                TypeDef_Function tdf = (TypeDef_Function)var.type;
                if (null != var.value && tdf.retType.Equals(IntrinsicTypeDefs.STRING) && tdf.argTypes.Count == 0)
                {
                    FunctionValue funcVal = (FunctionValue)var.value;
                    return((string)funcVal.Evaluate(context, new List <object>(), this));
                }
            }

            return("[" + classDef.name + " instance]");
        }
Example #17
0
        public bool PushDefstructorScope(ClassValue instance, ExecContext context)
        {
            Pb.Assert(_callCount < CALLSTACKMAXDEPTH);
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

#if PEBBLE_TRACESTACK
            TraceLog("PushDefstructorScope " + instance.classDef.name + " '" + instance.debugName + "'");
#endif
            _callStack[_callCount].Set(_varCount, instance, false);
            ++_callCount;

            return(true);
        }
Example #18
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 #19
0
            public bool OpenFileRead(ExecContext context, string path)
            {
                if (IsOpen())
                {
                    lastError = "Stream already open.";
                    return(false);
                }

                try {
                    reader = new BinaryReader(File.Open(path, FileMode.Open));
                } catch (Exception e) {
                    lastError = "Runtime error attempting to create BinaryReader: " + e.ToString();
                    return(false);
                }

                return(true);
            }
Example #20
0
        public EnumValue AddValue_Literal(ExecContext context, string valueName, object litValue)
        {
            if (_names.ContainsKey(valueName))
            {
                return(null);
            }
            _names.Add(valueName, true);

            _classDef.AddMember(valueName, enumType, null, true);

            EnumValue ev = new EnumValue();

            ev.name         = valueName;
            ev.literalValue = litValue;
            _values.Add(ev);

            return(ev);
        }
Example #21
0
        // ***************************************************************************
        // Variable functions.
        //  Note - These are nearly-trivial wrappers for stack functions.
        //         These could be removed at some point.
        // ***************************************************************************

        public VarStackRef GetVarRefByName(ExecContext context, string symbol, bool globalOnly = false)
        {
            VarStackRef index;

            if (globalOnly)
            {
                index = stack.GetGlobalVarIndexByName(symbol);
            }
            else
            {
                index = stack.GetVarIndexByName(context, symbol);
            }
#if PEBBLE_TRACESTACK
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(symbol + " -> " + index.ToString());
            Console.ForegroundColor = ConsoleColor.Gray;
#endif
            return(index);
        }
Example #22
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);
            }
        }
Example #23
0
        public bool PushTerminalScope(string name, ExecContext context, bool hard = false)
        {
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

            if (hard)
            {
                _callStack[_callCount].SetHardTerminal(_varCount, name);
            }
            else
            {
                _callStack[_callCount].SetTerminal(_varCount, name);
            }
            ++_callCount;

#if PEBBLE_TRACESTACK
            TraceScope("PushTerminalScope" + (hard ? "(hard)" : ""));
#endif

            return(true);
        }
Example #24
0
        public static string ValueToString(ExecContext context, object val, bool quoteStrings)
        {
            string result = "";

            if (null == val)
            {
                result += "null";
            }
            else if (val is bool)
            {
                result += (bool)val ? "true" : "false";
            }
            else if (val is string)
            {
                result += quoteStrings ? "\"" + (string)val + "\"" : (string)val;
            }
            else if (val is double)
            {
                result += val.ToString();
            }
            else if (val is ClassValue)
            {
                if (null != context)
                {
                    result += ((ClassValue)val).ToString(context);                     // this searches the class for a ToString member
                }
                else
                {
                    result += ((ClassValue)val).debugName;
                }
            }
            else
            {
                result += val.ToString();
            }
            return(result);
        }
Example #25
0
            public bool OpenFileWrite(ExecContext context, string path, bool textMode)
            {
                if (IsOpen())
                {
                    lastError = "Stream already open.";
                    return(false);
                }

                try {
                    if (textMode)
                    {
                        textWriter = new StreamWriter(path);
                    }
                    else
                    {
                        writer = new BinaryWriter(File.Open(path, FileMode.Create));
                    }
                } catch (Exception e) {
                    lastError = "Runtime error attempting to create BinaryWriter: " + e.ToString();
                    return(false);
                }

                return(true);
            }
Example #26
0
        public static string ValueToScript(ExecContext context, object value, string prefix = "", bool topLevel = true)
        {
            string result  = "";
            string postfix = topLevel ? ";" : "";

            if (value is double)
            {
                return(Convert.ToString((double)value) + postfix);
            }
            else if (value is bool)
            {
                return(((bool)value ? "true" : "false") + postfix);
            }
            else if (value is string)
            {
                return("\"" + (string)value + "\"" + postfix);
            }
            else if (value is ClassValue_Enum)                 // is enum
            {
                return(((ClassValue_Enum)value).ToString() + postfix);
            }
            else if (value is ClassValue)
            {
                ClassValue table = value as ClassValue;
                result = "new " + table.classDef.typeDef.ToString() + " {\n";

                // ThisToScript must not be static. It's going to be printing info about a class instance, right?
                MemberRef toStrMem = table.classDef.GetMemberRef(null, "ThisToScript", ClassDef.SEARCH.NORMAL);
                Variable  funcVar  = null;
                if (!toStrMem.isInvalid)
                {
                    funcVar = table.Get(toStrMem) as Variable;
                }
                if (null != funcVar)
                {
                    FunctionValue funcVal = funcVar.value as FunctionValue;
                    result += funcVal.Evaluate(context, new List <object> {
                        prefix
                    }, table) as string;
                }
                else
                {
                    foreach (Variable kvp in table.fieldVars)
                    {
                        if (!(kvp.type is TypeDef_Function) && !kvp.type.IsConst())
                        {
                            result += prefix + "\t" + kvp.name + " = " + ValueToScript(context, kvp.value, prefix + "\t", false);
                            if (!result.EndsWith(";"))
                            {
                                result += ";";
                            }
                            result += "\n";
                        }
                    }
                }
                result += prefix + "}" + postfix;
            }
            else if (null == value)
            {
                result = "null" + postfix;
            }
            return(result);
        }
Example #27
0
        /*
         * delegate bool LibraryTestFunc(Engine engine, bool verbose);
         *
         * public static void RegisterLibraryTests(LibraryTestFunc testFunc) {
         *      testFunc();
         * }
         */

        // **************************************************************************

        public Engine()
        {
            defaultContext = new ExecContext(this);
            CoreLib.Register(this);
        }
Example #28
0
        // BIG IMPORTANT FUNCTION.
        // Searches the current call stack for a variable with the given name and returns a VarStackRef,
        // which can be used by GetVarAtIndex to find the variable, usually later at execution time.
        // This saves us from having to do string searches for variables at execution time, but also
        // adds a lot of complexity to the system. Since the idea is to create these Refs during
        // TypeCheck, any discrepancy between the order scopes are pushed/popped and variables created
        // between TypeCheck and Evaluate WILL result in a grave error.
        public VarStackRef GetVarIndexByName(ExecContext context, string name, bool stopAtTerminals = false)
        {
            bool onlyUnique = false;
            int  callIx     = _callCount;
            int  varIx      = _varCount - 1;

            while (--callIx >= 0)
            {
                StackScope scope = _callStack[callIx];

                if (!onlyUnique && null != scope.classInstance)
                {
                    // If this scope is a class function call, search that class for
                    // a member with that name.
                    ITypeDef  typeDef = null;
                    MemberRef memRef  = _callStack[callIx].classInstance.classDef.GetMemberRef(context, name, scope.isStatic ? ClassDef.SEARCH.STATIC : ClassDef.SEARCH.EITHER, ref typeDef);
                    if (!memRef.isInvalid)
                    {
                        return(new VarStackRef(typeDef, callIx - _callCount, memRef));
                    }
                }

                if (!onlyUnique && null != scope.classDef)
                {
                    ITypeDef  typeDef = null;
                    MemberRef memRef  = _callStack[callIx].classDef.GetMemberRef(context, name, scope.isStatic ? ClassDef.SEARCH.STATIC : ClassDef.SEARCH.EITHER, ref typeDef);
                    if (!memRef.isInvalid)
                    {
                        return(new VarStackRef(typeDef, callIx - _callCount, memRef));
                    }
                }

                // Otherwise, search the variable stack for it.
                while (varIx >= scope.varStackStart)
                {
                    if (null != _varStack[varIx] && _varStack[varIx].name == name)
                    {
                        Variable var = _varStack[varIx];
                        if (var.unique)
                        {
                            return(new VarStackRef(var, false));
                        }
                        else if (!onlyUnique)
                        {
                            return(new VarStackRef(_varStack[varIx].type, callIx - _callCount, varIx - scope.varStackStart));
                        }
                        else
                        {
                            return(new VarStackRef(VarStackRef.ErrorType.NonUnique));
                        }
                    }
                    --varIx;
                }

                if (scope.hardTerminal)
                {
                    break;
                }

                if (scope.terminal)
                {
                    if (stopAtTerminals)
                    {
                        break;
                    }
                    else
                    {
                        onlyUnique = true;
                    }
                }
            }

            // Search globals last. Globals are always in scope.
            int globIx = _globals.GetIndex(name);

            if (globIx >= 0)
            {
                Variable var = _globals.Get(globIx);
                return(new VarStackRef(var, true));
            }

            return(new VarStackRef(VarStackRef.ErrorType.NotFound));
        }
Example #29
0
        public bool PushClassCall_StaticOrTypeCheck(TypeDef_Function funcType, ClassDef classDef, bool isStatic, ExecContext context)
        {
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

            _callStack[_callCount].Set(_varCount, funcType, classDef, isStatic);
            ++_callCount;

#if PEBBLE_TRACESTACK
            TraceScope("PushClassCall_StaticOrTypeCheck(" + classDef.name + ", " + (isStatic ? "static)" : "type check)"));
#endif

            return(true);
        }
Example #30
0
        public bool PushCall(TypeDef_Function funcType, string funcName, ClassValue instance, bool isStatic, ExecContext context)
        {
            if (CALLSTACKMAXDEPTH == _callCount)
            {
                return(false);
            }

            _callStack[_callCount].Set(_varCount, funcName, funcType, instance, isStatic);
            ++_callCount;

#if PEBBLE_TRACESTACK
            TraceScope("PushCall");
#endif

            return(true);
        }