Beispiel #1
0
        public SkryptEngine(Options options)
        {
            GlobalEnvironment = new LexicalEnvironment();

            ErrorHandler          = new DefaultErrorHandler(this);
            ExpressionInterpreter = new ExpressionInterpreter(this);
            TemplateMaker         = new TemplateMaker(this);
            FileHandler           = new DefaultFileHandler(this);
            Visitor = new SkryptVisitor(this);

            Enumerable         = FastAdd(new EnumerableTrait(this));
            Iterator           = FastAdd(new IteratorTrait(this));
            AddableTrait       = FastAdd(new AddableTrait(this));
            SubtractableTrait  = FastAdd(new SubtractableTrait(this));
            DividableTrait     = FastAdd(new DividableTrait(this));
            MultiplicableTrait = FastAdd(new MultiplicableTrait(this));

            Number    = FastAdd(new NumberType(this));
            String    = FastAdd(new StringType(this));
            Boolean   = FastAdd(new BooleanType(this));
            Vector    = FastAdd(new VectorType(this));
            Vector2   = FastAdd(new Vector2Type(this));
            Vector3   = FastAdd(new Vector3Type(this));
            Vector4   = FastAdd(new Vector4Type(this));
            Array     = FastAdd(new ArrayType(this));
            Exception = FastAdd(new ExceptionType(this));

            Math   = FastAdd(new MathModule(this));
            IO     = FastAdd(new IOModule(this));
            Memory = FastAdd(new MemoryModule(this));
            Debug  = FastAdd(new DebugModule(this));

            if (options != null)
            {
                _discardGlobal     = options.DiscardGlobal;
                _maxRecursionDepth = options.MaxRecursionDepth;
                MemoryLimit        = options.MaxMemory;
                HaltMemory         = options.MemoryHalt;
            }
        }
Beispiel #2
0
        public SkryptObject Run(SkryptEngine engine, SkryptObject self, Arguments args)
        {
            var blockStmnt         = Context.StmntBlock;
            var visitor            = new SkryptVisitor(engine);
            var lexicalEnvironment = LexicalEnvironment.MakeCopy(Context.LexicalEnvironment);

            if (BaseEnvironment != null)
            {
                lexicalEnvironment.Parent = BaseEnvironment;
            }
            lexicalEnvironment.Variables["self"].Value = self;

            for (int i = 0; i < Parameters.Length; i++)
            {
                var parameter = Parameters[i];
                var input     = args[i];

                if (input is IValue noref)
                {
                    input = noref.Copy();
                }

                if (i < args.Values.Length)
                {
                    lexicalEnvironment.Variables[parameter.Name].Value = input;
                }
                else
                {
                    lexicalEnvironment.Variables[parameter.Name].Value = parameter.Default == null ? null : engine.Visitor.Visit(parameter.Default);
                }
            }

            var returnValue = default(SkryptObject);
            var block       = blockStmnt.block();
            var expr        = blockStmnt.expression();
            var assignStmnt = blockStmnt.assignStmnt();
            var returnStmnt = blockStmnt.returnStmnt();

            visitor.CurrentEnvironment = lexicalEnvironment;

            if (block != null)
            {
                var prev = visitor.CurrentEnvironment;

                visitor.CurrentEnvironment = visitor.CurrentEnvironment.Children.Find(x => x.Context == block);

                for (int i = 0; i < block.ChildCount; i++)
                {
                    var c = block.GetChild(i);

                    visitor.Visit(c);

                    if (Context.JumpState == JumpState.Return)
                    {
                        Context.JumpState = JumpState.None;
                        break;
                    }
                }

                returnValue = Context.ReturnValue;
            }
            else if (expr != null)
            {
                returnValue = visitor.Visit(expr);
            }
            else if (assignStmnt != null)
            {
                visitor.Visit(assignStmnt);
            }
            else if (returnStmnt != null)
            {
                visitor.Visit(returnStmnt);

                returnValue = Context.ReturnValue;
            }

            if (returnValue is FunctionInstance functionInstance && functionInstance.Function is ScriptFunction scriptFunction)
            {
                var checkParent = scriptFunction.Context.Context;
                var isDefinedInCurrentFunction = false;

                while (checkParent.Parent != null)
                {
                    if (checkParent == Context.Context)
                    {
                        isDefinedInCurrentFunction = true;
                        break;
                    }

                    checkParent = checkParent.Parent;
                }

                if (isDefinedInCurrentFunction)
                {
                    scriptFunction.BaseEnvironment = visitor.CurrentEnvironment;
                }
            }

            // BaseEnvironment = null;

            return(returnValue);
        }