コード例 #1
0
ファイル: WhileStatementNode.cs プロジェクト: colinvh/DCPUC
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            var topLabel = Scope.GetLabel() + "BEGIN_WHILE";
            assembly.Add(":" + topLabel, "", "");

            var clauseOrder = CompileConditional(assembly, scope, ChildNodes[0] as CompilableNode);

            if (clauseOrder == ClauseOrder.ConstantPass)
            {
                CompileBlock(assembly, scope, ChildNodes[1] as CompilableNode);
                assembly.Add("SET", "PC", topLabel);
            }
            else if (clauseOrder == ClauseOrder.ConstantFail)
            {
            }
            else if (clauseOrder == ClauseOrder.PassFirst)
            {
                var endLabel = Scope.GetLabel() + "END";
                assembly.Add("SET", "PC", endLabel);
                CompileBlock(assembly, scope, ChildNodes[1] as CompilableNode);
                assembly.Add("SET", "PC", topLabel);
                assembly.Add(":" + endLabel, "", "");
            }
            else if (clauseOrder == ClauseOrder.FailFirst)
            {
                var elseLabel = Scope.GetLabel() + "ELSE";
                var endLabel = Scope.GetLabel() + "END";
                assembly.Add("SET", "PC", elseLabel);
                assembly.Add("SET", "PC", endLabel);
                assembly.Add(":" + elseLabel, "", "");
                CompileBlock(assembly, scope, ChildNodes[1] as CompilableNode);
                assembly.Add("SET", "PC", topLabel);
                assembly.Add(":" + endLabel, "", "");
            }
        }
コード例 #2
0
ファイル: VariableNameNode.cs プロジェクト: colinvh/DCPUC
        public override void Compile(Assembly assembly, Scope scope, Register target)
        {
            var variable = scope.FindVariable(AsString);
            if (variable == null) throw new CompileError("Could not find variable " + AsString);

            if (variable.location == Register.CONST)
            {
                assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), variable.staticLabel);
            }
            else if (variable.location == Register.STATIC)
            {
                assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "[" + variable.staticLabel + "]");
            }
            else if (variable.location == Register.STACK)
            {
                if (scope.stackDepth - variable.stackOffset > 1)
                {
                    assembly.Add("SET", Scope.TempRegister, "SP");
                    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "[" + hex(scope.stackDepth - variable.stackOffset - 1) + "+" + Scope.TempRegister + "]", "Fetching variable");
                }
                else
                    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), "PEEK", "Fetching variable");
            }
            else
            {
                if (target == variable.location) return;
                assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), Scope.GetRegisterLabelSecond((int)variable.location), "Fetching variable");
            }
            if (target == Register.STACK) scope.stackDepth += 1;
        }
コード例 #3
0
ファイル: InlineASMNode.cs プロジェクト: colinvh/DCPUC
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     var lines = AsString.Split(new String[2]{"\n", "\r"}, StringSplitOptions.RemoveEmptyEntries);
     assembly.Barrier();
     foreach (var str in lines)
         assembly.Add(str + " ;", "", "");
 }
コード例 #4
0
ファイル: BinaryOperationNode.cs プロジェクト: BigEd/DCPUC
        public override void Compile(List<String> assembly, Scope scope)
        {
            (ChildNodes[1] as CompilableNode).Compile(assembly, scope);
            (ChildNodes[0] as CompilableNode).Compile(assembly, scope);

            if (AsString == "==")
            {
                assembly.Add("SET A, 0x0");
                assembly.Add("IFE POP, POP");
                assembly.Add("SET A, 0x1");
            }
            else if (AsString == "!=")
            {
                assembly.Add("SET A, 0x0");
                assembly.Add("IFN POP, POP");
                assembly.Add("SET A, 0x1");
            }
            else
            {
                assembly.Add("SET A, POP");
                assembly.Add(opcodes[AsString] + " A, POP");
            }
            assembly.Add("SET PUSH, A");
            scope.stackDepth -= 1;
        }
コード例 #5
0
ファイル: ComparisonNode.cs プロジェクト: colinvh/DCPUC
        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);
        }
コード例 #6
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;
        }
コード例 #7
0
ファイル: ReturnStatementNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<string> assembly, Scope scope)
 {
     (ChildNodes[0] as CompilableNode).Compile(assembly, scope);
     assembly.Add("SET A, POP");
     scope.stackDepth -= 1;
     scope.activeFunction.CompileReturn(assembly);
 }
コード例 #8
0
ファイル: BranchStatementNode.cs プロジェクト: colinvh/DCPUC
 public static void CompileBlock(Assembly assembly, Scope scope, CompilableNode block)
 {
     var blockScope = BeginBlock(scope);
     assembly.Barrier();
     block.Compile(assembly, blockScope, Register.DISCARD);
     assembly.Barrier();
     EndBlock(assembly, blockScope);
 }
コード例 #9
0
ファイル: BlockNode.cs プロジェクト: colinvh/DCPUC
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     foreach (var child in ChildNodes)
     {
         assembly.Barrier();
         (child as CompilableNode).Compile(assembly, scope, Register.DISCARD);
     }
 }
コード例 #10
0
ファイル: Scope.cs プロジェクト: BigEd/DCPUC
 internal Scope Push(Scope child)
 {
     child.parent = this;
     child.stackDepth = stackDepth;
     child.parentDepth = stackDepth;
     child.activeFunction = activeFunction;
     return child;
 }
コード例 #11
0
ファイル: LibraryFunctionNode.cs プロジェクト: colinvh/DCPUC
 public override void CompileFunction(Assembly assembly, Scope topscope)
 {
     //if (references == 0) return;
     foreach (var line in code)
     {
         assembly.Barrier();
         assembly.Add(line, "", "");
     }
 }
コード例 #12
0
ファイル: FunctionCallNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<string> assembly, Scope scope)
 {
     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);
     foreach (var child in ChildNodes)
         (child as CompilableNode).Compile(assembly, scope);
     assembly.Add("JSR " + func.label);
     assembly.Add("SET PUSH, A");
 }
コード例 #13
0
ファイル: ReturnStatementNode.cs プロジェクト: colinvh/DCPUC
 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", "", "");
 }
コード例 #14
0
ファイル: DataLiteralNode.cs プロジェクト: colinvh/DCPUC
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     //if (data.Count == 1)
     //    assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), hex(data[0]));
     //else
     //{
         assembly.Add("SET", Scope.GetRegisterLabelFirst((int)target), dataLabel);
         Scope.AddData(dataLabel, data);
     //}
     if (target == Register.STACK) scope.stackDepth += 1;
 }
コード例 #15
0
        public override void Compile(List<string> assembly, Scope scope)
        {
            var newVariable = new Variable();
            newVariable.name = AsString;
            newVariable.scope = scope;
            newVariable.stackOffset = scope.stackDepth;

            (ChildNodes[0] as CompilableNode).Compile(assembly, scope);
            scope.variables.Add(newVariable);
            scope.stackDepth += 1;
        }
コード例 #16
0
ファイル: InlineASMNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<string> assembly, Scope scope)
 {
     var lines = AsString.Split(new String[2]{"\n", "\r"}, StringSplitOptions.RemoveEmptyEntries);
     int stackChange = 0;
     foreach (var str in lines)
     {
         if (str.ToUpper().Contains("PUSH")) stackChange += 1;
         if (str.ToUpper().Contains("POP")) stackChange -= 1;
         assembly.Add(str);
     }
     scope.stackDepth += stackChange;
 }
コード例 #17
0
ファイル: NumberLiteralNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<String> assembly, Scope scope)
 {
     if (AsString.StartsWith("0x"))
     {
         var hexPart = AsString.Substring(2).ToUpper();
         while (hexPart.Length < 4) hexPart = "0" + hexPart;
         assembly.Add("SET PUSH, 0x" + hexPart);
     }
     else
         assembly.Add("SET PUSH, " + hex(AsString));
     scope.stackDepth += 1;
 }
コード例 #18
0
ファイル: VariableNameNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<string> assembly, Scope scope)
 {
     var variable = scope.FindVariable(AsString);
     if (variable == null) throw new CompileError("Could not find variable " + AsString);
     if (scope.stackDepth - variable.stackOffset > 0)
     {
         assembly.Add("SET A, SP");
         assembly.Add("SET PUSH, [" + hex(scope.stackDepth - variable.stackOffset) + "+A]");
     }
     else
         assembly.Add("SET PUSH, PEEK");
     scope.stackDepth += 1;
 }
コード例 #19
0
ファイル: BinaryOperationNode.cs プロジェクト: colinvh/DCPUC
        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);
        }
コード例 #20
0
ファイル: AssignmentNode.cs プロジェクト: BigEd/DCPUC
        public override void Compile(List<string> assembly, Scope scope)
        {
            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);

                (ChildNodes[1] as CompilableNode).Compile(assembly, scope);
                assembly.Add("SET A, SP");
                assembly.Add("SET [" + hex(scope.stackDepth - variable.stackOffset) + "+A], POP");
                scope.stackDepth -= 1;
            }
            else if (ChildNodes[0] is DereferenceNode)
            {
                (ChildNodes[1] as CompilableNode).Compile(assembly, scope);
                (ChildNodes[0].ChildNodes[0] as CompilableNode).Compile(assembly, scope);
                assembly.Add("SET A, POP");
                assembly.Add("SET [A], POP");
                scope.stackDepth -= 2;
            }
        }
コード例 #21
0
ファイル: IfStatementNode.cs プロジェクト: BigEd/DCPUC
 public override void Compile(List<string> assembly, Scope scope)
 {
     (ChildNodes[0] as CompilableNode).Compile(assembly, scope);
     var hasElseBlock = ChildNodes.Count == 3;
     var elseBranchLabel = hasElseBlock ? Scope.GetLabel() + "ELSE" : "";
     var endLabel = Scope.GetLabel() + "END";
     assembly.Add("IFE POP, 0x0");
     assembly.Add("SET PC, " + (hasElseBlock ? elseBranchLabel : endLabel));
     scope.stackDepth -= 1;
     var blockScope = BeginBlock(scope);
     (ChildNodes[1] as CompilableNode).Compile(assembly, blockScope);
     EndBlock(assembly, blockScope);
     if (hasElseBlock)
     {
         assembly.Add("SET PC, " + endLabel);
         assembly.Add(":" + elseBranchLabel);
         var elseScope = BeginBlock(scope);
         (ChildNodes[2] as CompilableNode).Compile(assembly, elseScope);
         EndBlock(assembly, elseScope);
     }
     assembly.Add(":" + endLabel);
 }
コード例 #22
0
 public virtual void CompileFunction(Assembly assembly, Scope topscope)
 {
     Scope lScope;
     if (localScope != null)
     {
         foreach (var variable in topscope.variables)
             if (variable.location == Register.STATIC)
                 localScope.variables.Add(variable);
         lScope = localScope.Push(new Scope());
         assembly.Add(":" + label, "", "");
     }
     else
         lScope = topscope;
     assembly.Barrier();
     if (localScope != null) lScope.stackDepth += 1; //account for return address
     (ChildNodes[0] as CompilableNode).Compile(assembly, lScope, Register.DISCARD);
     if (localScope != null) CompileReturn(assembly, lScope);
     else assembly.Add("BRK", "", "");
     assembly.Barrier();
     //Should leave the return value, if any, in A.
     foreach (var function in lScope.pendingFunctions)
         function.CompileFunction(assembly, topscope);
 }
コード例 #23
0
ファイル: DereferenceNode.cs プロジェクト: colinvh/DCPUC
 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);
     }
 }
コード例 #24
0
 internal void CompileReturn(Assembly assembly, Scope lScope)
 {
     if (lScope.stackDepth - localScope.stackDepth > 1)
         assembly.Add("ADD", "SP", hex(lScope.stackDepth - localScope.stackDepth - 1), "Cleanup stack");
     assembly.Add("SET", "PC", "POP", "Return");
 }
コード例 #25
0
 public override void Compile(Assembly assembly, Scope scope, Register target)
 {
     scope.pendingFunctions.Add(this);
 }
コード例 #26
0
ファイル: CompilableNode.cs プロジェクト: BigEd/DCPUC
 public virtual void Compile(List<String> assembly, Scope scope)
 {
     throw new NotImplementedException();
 }
コード例 #27
0
ファイル: CompilableNode.cs プロジェクト: BigEd/DCPUC
 public static void EndBlock(List<String> assembly, Scope scope)
 {
     if (scope.stackDepth - scope.parentDepth > 0)
         assembly.Add("ADD SP, " + hex(scope.stackDepth - scope.parentDepth) + " ;End block");
 }
コード例 #28
0
ファイル: CompilableNode.cs プロジェクト: BigEd/DCPUC
 public static Scope BeginBlock(Scope scope)
 {
     return scope.Push(new Scope());
 }
コード例 #29
0
ファイル: CompilableNode.cs プロジェクト: colinvh/DCPUC
 public virtual void Compile(Assembly assembly, Scope scope, Register target)
 {
     throw new NotImplementedException();
 }
コード例 #30
0
ファイル: CompilableNode.cs プロジェクト: colinvh/DCPUC
 public static void EndBlock(Assembly assembly, Scope scope)
 {
     if (scope.stackDepth - scope.parentDepth > 0)
         assembly.Add("ADD", "SP", hex(scope.stackDepth - scope.parentDepth), "End block");
 }