Ejemplo n.º 1
0
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            throw new CompileError("Comparisons in general expressions are not implemented");
            //Evaluate in reverse in case both need to go on the stack
            var secondTarget = scope.FindFreeRegister();
            if (Scope.IsRegister((Register)secondTarget)) scope.UseRegister(secondTarget);
            (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondTarget);

            if (AsString == "==" || AsString == "!=")
            {
                (ChildNodes[0] as CompilableNode).Compile(assembly, scope, Register.STACK);
                if (target == Register.STACK)
                {
                    assembly.Add("SET", Scope.TempRegister, "0x0", "Equality onto stack");
                    assembly.Add((AsString == "==" ? "IFE" : "IFN"), "POP", Scope.GetRegisterLabelSecond(secondTarget));
                    assembly.Add("SET", Scope.TempRegister, "0x1");
                    assembly.Add("SET", "PUSH", Scope.TempRegister);
                }
                else
                {
                    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "0x0",  "Equality into register");
                    assembly.Add((AsString == "==" ? "IFE" : "IFN"), "POP", Scope.GetRegisterLabelSecond(secondTarget));
                    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "0x1");
                }
            }

            if (secondTarget == (int)Register.STACK)
                scope.stackDepth -= 1;
            else
                scope.FreeRegister(secondTarget);
        }
Ejemplo n.º 2
0
        public override void Init(Irony.Parsing.ParsingContext context, Irony.Parsing.ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);
            AddChild("Block", treeNode.ChildNodes[3]);

            localScope = new Scope();

            var parameters = treeNode.ChildNodes[2].ChildNodes;

            for (int i = 0; i < parameters.Count; ++i)
            {
                var variable = new Variable();
                variable.scope = localScope;
                variable.name = parameters[i].ChildNodes[0].FindTokenAndGetText();
                localScope.variables.Add(variable);

                if (i < 3)
                {
                    variable.location = (Register)i;
                    localScope.UseRegister(i);
                }
                else
                {
                    variable.location = Register.STACK;
                    variable.stackOffset = localScope.stackDepth;
                    localScope.stackDepth += 1;
                }

                parameterCount += 1;
            }

            this.AsString = treeNode.ChildNodes[1].FindTokenAndGetText();
            label = Scope.GetLabel() + "_" + AsString;
            localScope.activeFunction = this;
        }
Ejemplo n.º 3
0
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            var func = findFunction(this, AsString);
            if (func == null) throw new CompileError("Can't find function - " + AsString);
            if (func.parameterCount != ChildNodes.Count) throw new CompileError("Incorrect number of arguments - " + AsString);
            func.references += 1;

            //Marshall registers
            var startingRegisterState = scope.SaveRegisterState();

            for (int i = 0; i < 3; ++i)
            {
                if (startingRegisterState[i] == RegisterState.Used)
                {
                    PushRegister(assembly, scope, (Register)i);
                    if (scope.activeFunction != null && scope.activeFunction.parameterCount > i)
                    {
                        scope.activeFunction.localScope.variables[i].location = Register.STACK;
                        scope.activeFunction.localScope.variables[i].stackOffset = scope.stackDepth - 1;
                    }
                }
                if (func.parameterCount > i)
                {
                    scope.UseRegister(i);
                    (ChildNodes[i] as CompilableNode).Compile(assembly, scope, (Register)i);
                }
            }

            for (int i = 3; i < 7; ++i)
                if (startingRegisterState[i] == RegisterState.Used)
                    PushRegister(assembly, scope, (Register)i);

            if (func.parameterCount > 3)
                for (int i = 3; i < func.parameterCount; ++i)
                    (ChildNodes[i] as CompilableNode).Compile(assembly, scope, Register.STACK);

            assembly.Add("JSR", func.label, "", "Calling function");

            if (func.parameterCount > 3) //Need to remove parameters from stack
            {
                assembly.Add("ADD", "SP", hex(func.parameterCount - 3), "Remove parameters");
                scope.stackDepth -= (func.parameterCount - 3);
            }

            if (scope.activeFunction != null)
                for (int i = 0; i < 3 && i < scope.activeFunction.parameterCount; ++i)
                    scope.activeFunction.localScope.variables[i].location = (Register)i;

            var saveA = startingRegisterState[0] == RegisterState.Used;
            if (saveA && target != Register.DISCARD) assembly.Add("SET", Scope.TempRegister, "A", "Save return value from being overwritten by stored register");

            for (int i = 6; i >= 0; --i)
            {
                if (startingRegisterState[i] == RegisterState.Used)
                {
                    assembly.Add("SET", Scope.GetRegisterLabelFirst(i), "POP", "Restoring register");
                    scope.UseRegister(i);
                    scope.stackDepth -= 1;
                }
            }

            if (target == Register.A && !saveA) return;
            else if (Scope.IsRegister(target)) assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), saveA ? Scope.TempRegister : "A");
            else if (target == Register.STACK)
            {
                assembly.Add("SET", "PUSH", saveA ? Scope.TempRegister : "A", "Put return value on stack");
                scope.stackDepth += 1;
            }
        }