예제 #1
0
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     var reg = scope.FindAndUseFreeRegister();
     (ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)reg);
     if (reg != (int)Register.A) assembly.Add("SET", "A", Scope.GetRegisterLabelSecond(reg));
     scope.FreeMaybeRegister(reg);
     if (reg == (int)Register.STACK) scope.stackDepth -= 1;
     if (scope.activeFunction != null) scope.activeFunction.CompileReturn(assembly, scope);
     else assembly.Add("BRK", "", "");
 }
예제 #2
0
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     var destRegister = target == Register.STACK ? scope.FindAndUseFreeRegister() : (int)target;
     (ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)destRegister);
     if (target == Register.STACK)
     {
         if (destRegister == (int)Register.STACK)
             assembly.Add("SET", "PEEK", "[PEEK]");
         else
         {
             assembly.Add("SET", "PUSH", "[" + Scope.GetRegisterLabelSecond(destRegister) + "]");
             scope.stackDepth += 1;
             scope.FreeMaybeRegister(destRegister);
         }
     }
     else
     {
         assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "[" + Scope.GetRegisterLabelSecond(destRegister) + "]");
         if (destRegister == (int)Register.STACK)
             scope.stackDepth -= 1;
         else if (destRegister != (int)target)
             scope.FreeMaybeRegister(destRegister);
     }
 }
예제 #3
0
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            int secondTarget = (int)Register.STACK;

            var secondConstant = (ChildNodes[1] as CompilableNode).IsConstant();
            var firstConstant = (ChildNodes[0] as CompilableNode).IsConstant();

            if (firstConstant && secondConstant)
            {
                assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), hex(GetConstantValue()));
                if (target == Register.STACK) scope.stackDepth += 1;
                return;
            }

            if (!secondConstant)
            {
                secondTarget = scope.FindAndUseFreeRegister();
                (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondTarget);
            }

            if (!firstConstant)
                (ChildNodes[0] as CompilableNode).Compile(assembly, scope, target);

            if (target == Register.STACK)
            {
                assembly.Add("SET", Scope.TempRegister,
                     firstConstant ? hex((ChildNodes[0] as CompilableNode).GetConstantValue()) : "POP");
                assembly.Add(opcodes[AsString], Scope.TempRegister,
                    secondConstant ? hex((ChildNodes[1] as CompilableNode).GetConstantValue()) : Scope.GetRegisterLabelSecond(secondTarget));
                assembly.Add("SET", "PUSH", Scope.TempRegister);
            }
            else
            {
                if (firstConstant)
                    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), hex((ChildNodes[0] as CompilableNode).GetConstantValue()));
                assembly.Add(opcodes[AsString], Scope.GetRegisterLabelFirst((int)target),
                    secondConstant ? hex((ChildNodes[1] as CompilableNode).GetConstantValue()) : Scope.GetRegisterLabelSecond(secondTarget));
            }

            if (secondTarget == (int)Register.STACK && !secondConstant)
                scope.stackDepth -= 1;
            else
                scope.FreeMaybeRegister(secondTarget);
        }
예제 #4
0
        public static ClauseOrder CompileConditional(Assembly assembly, Scope scope, CompilableNode conditionNode)
        {
            if (!(conditionNode is ComparisonNode))
            {
                var condTarget = scope.FindAndUseFreeRegister();
                conditionNode.Compile(assembly, scope, (Register)condTarget);
                assembly.Add("IFE", Scope.GetRegisterLabelSecond(condTarget), "0x0", "If from expression");
                scope.FreeMaybeRegister(condTarget);
                return ClauseOrder.PassFirst;
            }
            else
            {
                var op = conditionNode.AsString;
                ushort firstConstantValue = 0, secondConstantValue = 0;

                var firstIsConstant = (conditionNode.ChildNodes[0] as CompilableNode).IsConstant();
                var secondIsConstant = (conditionNode.ChildNodes[1] as CompilableNode).IsConstant();

                int firstRegister = (int)Register.STACK;
                int secondRegister = (int)Register.STACK;

                if (secondIsConstant)
                    secondConstantValue = (conditionNode.ChildNodes[1] as CompilableNode).GetConstantValue();
                else
                {
                    secondRegister = scope.FindAndUseFreeRegister();
                    (conditionNode.ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondRegister);
                }

                if (firstIsConstant)
                    firstConstantValue = (conditionNode.ChildNodes[0] as CompilableNode).GetConstantValue();
                else
                {
                    firstRegister = scope.FindAndUseFreeRegister();
                    (conditionNode.ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)firstRegister);
                }

                if (op == "==")
                {
                    if (firstIsConstant && secondIsConstant)
                    {
                        if (firstConstantValue == secondConstantValue) { return ClauseOrder.ConstantPass; }
                        else { return ClauseOrder.ConstantFail; }
                    }
                    else if (firstIsConstant)
                    {
                        assembly.Add("IFE", (conditionNode.ChildNodes[0] as CompilableNode).GetConstantToken(), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else if (secondIsConstant)
                    {
                        assembly.Add("IFE", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue));
                        releaseRegister(scope, firstRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else
                    {
                        assembly.Add("IFE", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, firstRegister);
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                }
                else if (op == "!=")
                {
                    if (firstIsConstant && secondIsConstant)
                    {
                        if (firstConstantValue != secondConstantValue) { return ClauseOrder.ConstantPass; }
                        else { return ClauseOrder.ConstantFail; }
                    }
                    else if (firstIsConstant)
                    {
                        assembly.Add("IFN", hex(firstConstantValue), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else if (secondIsConstant)
                    {
                        assembly.Add("IFN", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue));
                        releaseRegister(scope, firstRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else
                    {
                        assembly.Add("IFN", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, firstRegister);
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                }
                else if (op == ">")
                {
                    if (firstIsConstant && secondIsConstant)
                    {
                        if (firstConstantValue > secondConstantValue) { return ClauseOrder.ConstantPass; }
                        else { return ClauseOrder.ConstantFail; }
                    }
                    else if (firstIsConstant)
                    {
                        assembly.Add("IFG", hex(firstConstantValue), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else if (secondIsConstant)
                    {
                        assembly.Add("IFG", Scope.GetRegisterLabelSecond(firstRegister), hex(secondConstantValue));
                        releaseRegister(scope, firstRegister);
                        return ClauseOrder.FailFirst;
                    }
                    else
                    {
                        assembly.Add("IFG", Scope.GetRegisterLabelSecond(firstRegister), Scope.GetRegisterLabelSecond(secondRegister));
                        releaseRegister(scope, firstRegister);
                        releaseRegister(scope, secondRegister);
                        return ClauseOrder.FailFirst;
                    }
                }

            }

            throw new CompileError("Impossible situation reached");
        }
예제 #5
0
 private static void releaseRegister(Scope scope, int reg)
 {
     scope.FreeMaybeRegister(reg);
     if (reg == (int)Register.STACK) scope.stackDepth -= 1;
 }
예제 #6
0
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            if (ChildNodes[0] is VariableNameNode)
            {
                var variable = scope.FindVariable(ChildNodes[0].AsString);
                if (variable == null) throw new CompileError("Could not find variable " + ChildNodes[0].AsString);

                if (variable.location == Register.STACK)
                {
                    var register = scope.FindAndUseFreeRegister();
                    (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)register);
                    scope.FreeMaybeRegister(register);

                    if (scope.stackDepth - variable.stackOffset > 1)
                    {
                        assembly.Add("SET", Scope.TempRegister, "SP");
                        assembly.Add("SET", "[" + hex(scope.stackDepth - variable.stackOffset - 1) + "+" + Scope.TempRegister + "]",
                            Scope.GetRegisterLabelSecond(register), "Fetching variable");
                    }
                    else
                        assembly.Add("SET", "PEEK", Scope.GetRegisterLabelSecond(register), "Fetching variable");

                    if (register == (int)Register.STACK) scope.stackDepth -= 1;
                }
                else if (variable.location == Register.STATIC)
                {
                    //if (!variable.emitBrackets) throw new CompileError("Can't assign to data pointers!");
                     var register = scope.FindAndUseFreeRegister();
                    (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)register);
                    scope.FreeMaybeRegister(register);
                    assembly.Add("SET", "[" + variable.staticLabel + "]", Scope.GetRegisterLabelSecond(register));
                    if (register == (int)Register.STACK) scope.stackDepth -= 1;
                }
                else if (variable.location == Register.CONST)
                {
                    throw new CompileError("Can't assign to const");
                }
                else
                    (ChildNodes[1] as CompilableNode).Compile(assembly, scope, variable.location);

            }
            else if (ChildNodes[0] is DereferenceNode)
            {
                bool firstConstant = false;
                int firstRegister = (int)Register.STACK;

                if ((ChildNodes[0].ChildNodes[0] as CompilableNode).IsConstant())
                    firstConstant = true;
                else
                {
                    firstRegister = scope.FindAndUseFreeRegister();
                    (ChildNodes[0].ChildNodes[0] as CompilableNode).Compile(assembly, scope, (Register)firstRegister);
                }

                var secondRegister = scope.FindAndUseFreeRegister();
                (ChildNodes[1] as CompilableNode).Compile(assembly, scope, (Register)secondRegister);

                if (firstConstant)
                {
                    assembly.Add("SET", "[" + hex((ChildNodes[0].ChildNodes[0] as CompilableNode).GetConstantValue()) + "]",
                        Scope.GetRegisterLabelSecond(secondRegister));
                    if (secondRegister == (int)Register.STACK)
                        scope.stackDepth -= 1;
                    else
                        scope.FreeMaybeRegister(secondRegister);
                }
                else
                {
                    if (firstRegister == (int)Register.STACK && secondRegister == (int)Register.STACK)
                    {
                        assembly.Add("SET", Scope.TempRegister, "POP");
                        assembly.Add("SET", "[" + Scope.TempRegister + "]", "POP");
                        scope.stackDepth -= 2;
                    }
                    else if (secondRegister == (int)Register.STACK)
                    {
                        assembly.Add("SET", "[" + Scope.GetRegisterLabelFirst(firstRegister) + "]", "POP");
                        scope.stackDepth -= 1;
                        scope.FreeMaybeRegister(firstRegister);
                        return;
                    }
                    else if (firstRegister == (int)Register.STACK)
                    {
                        throw new CompileError("Impossible situation entered");
                    }
                    else
                    {
                        assembly.Add("SET", "[" + Scope.GetRegisterLabelFirst(firstRegister) + "]", Scope.GetRegisterLabelSecond(secondRegister));
                        scope.FreeMaybeRegister(firstRegister);
                        scope.FreeMaybeRegister(secondRegister);
                    }
                }
            }
        }