Пример #1
0
        public void Visit(ASTWhile whileStatement, Function function)
        {
            // do condition
            int condition = function.Code.Count;

            whileStatement.Condition.Accept(this, function);

            // branch out if condition evaluates to false
            function.Code.Write(OpCodeFactory.BranchIfFalse(0));
            int conditionBranch = function.Code.Count - 1;

            // compile body
            whileStatement.Body.Accept(this, function);

            // branch back to the condition
            function.Code.Write(OpCodeFactory.Branch((uint)condition));
            int end = function.Code.Count;

            // set the conditional branch offset
            function.Code[conditionBranch].As <BranchIfFalse>().Argument = (uint)end;

            // fill breaks/continues

            for (int i = condition; i < end; i++)
            {
                var instruction = function.Code[i];
                if (instruction is Branch breakBranch && breakBranch.Argument == Break) // break, jump to end
                {
                    breakBranch.Argument = (uint)end;
                }
Пример #2
0
        public void Visit(ASTMemberFunction functionDeclaration)
        {
            var _class = _environment.FindClass(functionDeclaration.BaseClass);

            if (_class == null)
            {
                throw new CompilerException($"Class '{functionDeclaration.BaseClass}' does not exist.");
            }

            var function = _class.FindFunction(functionDeclaration.Name);

            if (function == null)
            {
                throw new CompilerException($"Class '{functionDeclaration.BaseClass}' does not define function '{functionDeclaration.Name}'.");
            }

            for (int i = functionDeclaration.Arguments.Count - 1; i >= 0; i--)
            {
                function.Code.Write(OpCodeFactory.Set(ObjectFactory.String(functionDeclaration.Arguments[i])));
                function.Code.Write(OpCodeFactory.Pop);
            }

            if (functionDeclaration.Body != null)
            {
                functionDeclaration.Body.Accept(this, function);

                // We add this in case the user explicitly doesn't return anything in which case the function is void.
                function.Code.Write(OpCodeFactory.Push(ObjectFactory.Null));
                function.Code.Write(OpCodeFactory.Return);
            }
        }
Пример #3
0
        public void Visit(ASTFunctionDefinition functionDefinition, Class _class)
        {
            var func = ObjectFactory.Function(functionDefinition.Name, functionDefinition.Arguments);

            if (functionDefinition.Body != null)
            {
                functionDefinition.Body.Accept(this, func);

                // return null if script doesn't explicitly return something
                func.Code.Write(OpCodeFactory.Push(ObjectFactory.Null));
                func.Code.Write(OpCodeFactory.Return);
            }
            _class.AddFunction(func);
        }
Пример #4
0
        public void Visit(ASTIf astIf, Function function)
        {
            // Compile condition
            astIf.Condition.Accept(this, function);

            // If condition evaluates to false, branch past the if part
            function.Code.Write(OpCodeFactory.BranchIfFalse(0));
            var index = function.Code.Count - 1;

            // Compile if-part
            astIf.IfPart.Accept(this, function);

            // Set the offset after compiling the if-part
            function.Code[index].As <BranchIfFalse>().Argument = (uint)function.Code.Count;

            if (astIf.ElsePart != null)
            {
                astIf.ElsePart.Accept(this, function);
            }
        }
Пример #5
0
        private void CreateGeneralClasses()
        {
            // TODO: work on class implementation
            var table = new Class("table");
            var func  = new Function("count", new List <string> {
                "tname"
            });

            func.Code.Write(OpCodeFactory.Set(ObjectFactory.String("tname")));
            func.Code.Write(OpCodeFactory.Pop);
            func.Code.Write(OpCodeFactory.Reference(ObjectFactory.String("tname")));
            func.Code.Write(OpCodeFactory.Return);
            table.AddFunction(func);
            var constructor = new Function("table", new List <string>());

            constructor.Code.Write(OpCodeFactory.Push(ObjectFactory.Null));
            constructor.Code.Write(OpCodeFactory.Return);
            table.AddFunction(constructor);
            _classes.Add(table);
        }
Пример #6
0
        public void Visit(ASTGlobalFunction functionDeclaration)
        {
            var newFunction = ObjectFactory.Function(functionDeclaration.Name, functionDeclaration.Arguments);

            _environment.AddFunction(newFunction);

            for (int i = functionDeclaration.Arguments.Count - 1; i >= 0; i--)
            {
                newFunction.Code.Write(OpCodeFactory.Set(ObjectFactory.String(functionDeclaration.Arguments[i])));
                newFunction.Code.Write(OpCodeFactory.Pop);
            }

            if (functionDeclaration.Body != null)
            {
                functionDeclaration.Body.Accept(this, newFunction);

                // We add this in case the user explicitly doesn't return anything in which case the function is void.
                newFunction.Code.Write(OpCodeFactory.Push(ObjectFactory.Null));
                newFunction.Code.Write(OpCodeFactory.Return);
            }
        }
Пример #7
0
    public static SVRule Build(SVRuleGene gene)
    {
        var OpCodes = gene.OpCodes.Select(t => OpCodeFactory.Build(t)).ToList();

        return(new SVRule(OpCodes));
    }