Commits

Kareem Callender committed 1e3d2dd Draft

Split off AST creation into it's own method, and fixed build errors.

Comments (0)

Files changed (2)

gbread/Base/Assembler.cs

 
         public byte[] AssembleASM(int baseOffset, string input, ref CompError error, out bool success)
         {
+            #region Initialization
+
             // TODO: stress test assembling.
             success = false;
             error = new CompError();
             int currentOffset = baseOffset;
             int currentPreOffset = baseOffset;
             codeGen.ClearStream();
-
-            #region Dict Initialization
-
             variableDict.Clear();
             callDict.Clear();
             symFillTable.Clear();
                 variableDict.Add(kvp.Name, Utility.GetPCAddress(kvp.Value));
             }
 
-            #endregion Dict Initialization
+            #endregion Initialization
 
-            #region Build AST
-
-            var css = new CaseInsensitiveStringStream(input);
-            var gblex = new GBXLexer(css);
-            var cts = new CommonTokenStream(gblex);
-            var gbparse = new GBXParser(cts);
-            gbparse.TreeAdaptor = new CommonTreeAdaptor();
-            var syntaxTree = gbparse.program().Tree;
-            var parseErrors = gblex.GetErrors();
-            parseErrors.AddRange(gbparse.GetErrors());
-            if (parseErrors.Count != 0)
+            var syntaxTree = new CommonTree();
+            if (!CreateAST(input, out syntaxTree, ref error))
             {
-                var f = gbparse.GetErrors()[0];
-                error.lineNumber = f.error.Line;
-                error.characterNumber = f.error.CharPositionInLine;
-                error.errorMessage = ErrorMessage.CUSTOM;
-                error.extraInfo1 = f.errText;
                 return new byte[1];
             }
 
-            #endregion Build AST
-
-            if (!EvaluateAST(syntaxTree, baseOffset, ref error))
+            if (!(EvaluateAST(syntaxTree, baseOffset, ref error)
+                && EvaluateSymbols(baseOffset, ref error)))
             {
                 return new byte[1];
             }
             return codeGen.StreamToArray();
         }
 
+        private bool CreateAST(string input, out CommonTree syntaxTree, ref CompError error)
+        {
+            var css = new CaseInsensitiveStringStream(input);
+            var gblex = new GBXLexer(css);
+            var cts = new CommonTokenStream(gblex);
+            var gbparse = new GBXParser(cts);
+            gbparse.TreeAdaptor = new CommonTreeAdaptor();
+            syntaxTree = gbparse.program().Tree;
+            var parseErrors = gblex.GetErrors();
+            parseErrors.AddRange(gbparse.GetErrors());
+            if (parseErrors.Count != 0)
+            {
+                MakeErrorMessage(gbparse.GetErrors()[0], ref error);
+                return false;
+            }
+            return true;
+        }
 
         // TODO: Split up symbol filling and tree evaluation.
         private bool EvaluateAST(ITree syntaxTree, int baseOffset, ref CompError error, bool isMacro = false, List<ITree> macroArgs = null)
                             return false;
                         }
                         var result = 0L;
-                        ErrorMessage emt = EvaluateArgument(idValue, out result, isMacro, macroArgs);
-                        if (emt == ErrorMessage.General_NoError)
+                        if (!EvaluateArgument(idValue, out result, ref error, isMacro, macroArgs))
                         {
-                            variableDict.Add(idName, result);
-                        }
-                        else
-                        {
-                            error = new CompError();
-                            error.lineNumber = idValue.Line;
-                            error.characterNumber = idValue.CharPositionInLine;
-                            error.errorMessage = emt;
                             return false;
                         }
+                        variableDict.Add(idName, result);
                     }
                     else if (statementTree.Text == MacroToken)
                     {
                                         diff = memLoc - (codeGen.Position + 2);
                                         if (diff < -128 || diff > 127)
                                         {
-                                            MakeErrorMessage(arg, ErrorMessage.JR_OUT_OF_RANGE, ref error);
+                                            MakeErrorMessage(arg, ErrorMessage.Build_JROutOfRange, ref error);
                                             return false;
                                         }
                                     }
                                                 if (arg2.Text == ExpressionToken)
                                                 {
                                                     var result = 0L;
-                                                    ErrorMessage emt = EvaluateArgument(arg2, out result, isMacro, macroArgs);
-                                                    if (emt == ErrorMessage.General_NoError)
+                                                    if (!EvaluateArgument(arg2, out result, ref error, isMacro, macroArgs))
                                                     {
-                                                        codeGen.EmitLdRN("a", result);
-                                                    }
-                                                    else
-                                                    {
-                                                        MakeErrorMessage(arg2, emt, ref error);
                                                         return false;
                                                     }
+                                                    codeGen.EmitLdRN("a", result);
                                                 }
                                                 else if (arg2.Text == MemRefToken)
                                                 {
                                                     var result = 0L;
-                                                    ErrorMessage emt = EvaluateArgument(arg2.GetChild(0), out result, isMacro, macroArgs);
-                                                    if (emt == ErrorMessage.General_NoError)
+                                                    if (!EvaluateArgument(arg2.GetChild(0), out result, ref error, isMacro, macroArgs))
                                                     {
-                                                        codeGen.EmitLdANRef(result);
-                                                    }
-                                                    else
-                                                    {
-                                                        MakeErrorMessage(arg2, emt, ref error);
                                                         return false;
                                                     }
+                                                    codeGen.EmitLdANRef(result);
                                                 }
                                                 else
                                                 {
                                                 if (arg2.Text == ExpressionToken)
                                                 {
                                                     var result = 0L;
-                                                    ErrorMessage emt = EvaluateArgument(arg2, out result, isMacro, macroArgs);
-                                                    if (emt == ErrorMessage.General_NoError)
+                                                    if (!EvaluateArgument(arg2, out result, ref error, isMacro, macroArgs))
                                                     {
-                                                        codeGen.EmitLdRN(arg1.Text, result);
-                                                    }
-                                                    else
-                                                    {
-                                                        MakeErrorMessage(arg2, emt, ref error);
                                                         return false;
                                                     }
+                                                    codeGen.EmitLdRN(arg1.Text, result);
                                                 }
                                                 else
                                                 {
                                         case "hl":
                                             {
                                                 var result = 0L;
-                                                ErrorMessage emt = EvaluateArgument(arg2, out result, isMacro, macroArgs);
-                                                if (emt == ErrorMessage.General_NoError)
+                                                if (!EvaluateArgument(arg2, out result, ref error, isMacro, macroArgs))
                                                 {
-                                                    codeGen.EmitLdRRN(arg1.Text, result);
-                                                }
-                                                else
-                                                {
-                                                    MakeErrorMessage(arg2, emt, ref error);
                                                     return false;
                                                 }
+                                                codeGen.EmitLdRRN(arg1.Text, result);
                                             }
                                             break;
 
                                                 if (arg2.Text == ExpressionToken)
                                                 {
                                                     var result = 0L;
-                                                    ErrorMessage emt = EvaluateArgument(arg2, out result, isMacro, macroArgs);
-                                                    if (emt == ErrorMessage.General_NoError)
+                                                    if (!EvaluateArgument(arg2, out result, ref error, isMacro, macroArgs))
                                                     {
-                                                        codeGen.EmitLdRN(HLRefToken, result);
-                                                    }
-                                                    else
-                                                    {
-                                                        MakeErrorMessage(arg2, emt, ref error);
                                                         return false;
                                                     }
+                                                    codeGen.EmitLdRN(HLRefToken, result);
                                                 }
                                                 else
                                                 {
                                         case "MEM_REF":
                                             {
                                                 var result = 0L;
-                                                ErrorMessage emt = EvaluateArgument(arg1.GetChild(0), out result, isMacro, macroArgs);
-                                                if (emt == ErrorMessage.General_NoError)
+                                                if (!EvaluateArgument(arg1.GetChild(0), out result, ref error, isMacro, macroArgs))
                                                 {
-                                                    if (arg2.Text == "a")
-                                                    {
-                                                        codeGen.EmitLdNRefA(result);
-                                                    }
-                                                    else
-                                                    {
-                                                        codeGen.EmitLdNRefSP(result);
-                                                    }
+                                                    return false;
+                                                }
+                                                if (arg2.Text == "a")
+                                                {
+                                                    codeGen.EmitLdNRefA(result);
                                                 }
                                                 else
                                                 {
-                                                    MakeErrorMessage(arg2, emt, ref error);
-                                                    return false;
+                                                    codeGen.EmitLdNRefSP(result);
                                                 }
                                             }
                                             break;
                                                 if (arg2.Text == ExpressionToken)
                                                 {
                                                     var result = 0L;
-                                                    ErrorMessage emt = EvaluateArgument(arg2, out result, isMacro, macroArgs);
-                                                    if (emt == ErrorMessage.General_NoError)
+                                                    if (!(EvaluateArgument(arg2, out result, ref error, isMacro, macroArgs)))
                                                     {
-                                                        codeGen.EmitLdRRN(arg1.Text, result);
-                                                    }
-                                                    else
-                                                    {
-                                                        MakeErrorMessage(arg2, emt, ref error);
                                                         return false;
                                                     }
+                                                    codeGen.EmitLdRRN(arg1.Text, result);
                                                 }
                                                 else
                                                 {
                         }
                     }
                 }
-                foreach (SymEntry se in symFillTable)
+            }
+            return true;
+        }
+
+        private bool EvaluateSymbols(int baseOffset, ref CompError error, bool isMacro = false, List<ITree> macroArgs = null)
+        {
+            foreach (SymEntry se in symFillTable)
+            {
+                if (callDict.ContainsKey(se.label))
                 {
-                    if (callDict.ContainsKey(se.label))
+                    codeGen.Seek(se.offsetToFill);
+                    var memLoc = callDict[se.label];
+                    if (se.isJR)
                     {
-                        codeGen.Seek(se.offsetToFill);
-                        var memLoc = callDict[se.label];
-                        if (se.isJR)
+                        long diff = memLoc - (se.instructionPosition + 2);
+                        if (diff < -128 || diff > 127)
                         {
-                            long diff = memLoc - (se.instructionPosition + 2);
-                            if (diff < -128 || diff > 127)
-                            {
-                                MakeErrorMessage(se, ErrorMessage.JR_OUT_OF_RANGE, ref error);
-                                return false;
-                            }
-                            codeGen.EmitByte(diff);
+                            MakeErrorMessage(se, ErrorMessage.Build_JROutOfRange, ref error);
+                            return false;
                         }
-                        else
-                        {
-                            codeGen.EmitWord(memLoc);
-                        }
+                        codeGen.EmitByte(diff);
                     }
                     else
                     {
-                        MakeErrorMessage(se, ErrorMessage.UNKNOWN_ARGUMENT, ref error);
-                        return false;
+                        codeGen.EmitWord(memLoc);
                     }
                 }
+                else
+                {
+                    MakeErrorMessage(se, ErrorMessage.Build_UnknownArgument, ref error);
+                    return false;
+                }
             }
             return true;
         }
             error.extraInfo1 = arg.Text;
         }
 
+        private void MakeErrorMessage(ErrInfo arg, ref CompError error)
+        {
+            error.lineNumber = arg.error.Line;
+            error.characterNumber = arg.error.CharPositionInLine;
+            error.errorMessage = ErrorMessage.General_CustomError;
+            error.extraInfo1 = arg.errText;
+        }
+
         #region Evaluation
 
         private bool EvalDataFunc(CodeGenerator.DataFuncDelegate dataFunc, ITree instField, ref CompError error, bool isMacro, List<ITree> macroArgs)
                         }
                     case 2:
                         {
-                            if (! (EvaluateArgument(eval.GetChild(0), out res1, ref error, isMacro, macroArgs)
+                            if (!(EvaluateArgument(eval.GetChild(0), out res1, ref error, isMacro, macroArgs)
                                 && EvaluateArgument(eval.GetChild(1), out res2, ref error, isMacro, macroArgs)))
                             {
                                 return false;
                         }
                     case 3:
                         {
-                            if (! (EvaluateArgument(eval.GetChild(0), out res1, ref error, isMacro, macroArgs)
+                            if (!(EvaluateArgument(eval.GetChild(0), out res1, ref error, isMacro, macroArgs)
                                 && EvaluateArgument(eval.GetChild(1), out res2, ref error, isMacro, macroArgs)
                                 && EvaluateArgument(eval.GetChild(2), out res3, ref error, isMacro, macroArgs)))
                             {
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[0], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[0], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\2":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[1], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[1], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\3":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[2], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[2], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\4":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[3], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[3], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\5":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[4], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[4], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\6":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[5], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[5], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\7":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[6], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[6], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\8":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[7], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[7], out result, ref error, isMacro, macroArgs);
                         }
 
                     case "\\9":
                         }
                         else
                         {
-                            return EvaluateArgument(macroArgs[8], out result, isMacro, macroArgs);
+                            return EvaluateArgument(macroArgs[8], out result, ref error, isMacro, macroArgs);
                         }
                     default:
                         {
             }
             else if (eval.Text == ExpressionToken)
             {
-                return EvaluateExpression(eval.GetChild(0), out result, isMacro, macroArgs);
+                return EvaluateExpression(eval.GetChild(0), out result, ref error, isMacro, macroArgs);
             }
             else if (eval.Text == MacroArgToken)
             {
-                return EvaluateMacroArg(eval.GetChild(0), out result, isMacro, macroArgs);
+                return EvaluateMacroArg(eval.GetChild(0), out result, ref error, isMacro, macroArgs);
             }
             else if (!Utility.NumStringToInt(eval.Text, out result))
             {
         END_INVALID,
         FILE_TOO_LARGE,
         INCORRECT_ARGUMENT, 
-        JR_OUT_OF_RANGE, 
+        Build_JROutOfRange, 
         LABEL_ALREADY_DEFINED, 
         LDD_LDI_HL_A_ONLY, 
         LDHL_SP_OUT_OF_RANGE, 
         Build_MacroDoesNotExist,
         Build_UnknownArgument,
         Build_UnknownError,
-        CUSTOM,
+        General_CustomError,
     }
 
     public struct CompError
             {ErrorMessage.DATA_SINGLE_ARG_UNRECOGNIZED, "This data argument ({0}) is unrecognized."}, 
             {ErrorMessage.DOUBLE_ARG_UNRECOGNIZED,      "This instruction's arguments({0}, {1}) are not recognized."}, 
             {ErrorMessage.INCORRECT_ARGUMENT,           "This instruction has an incorrect argument."}, 
-            {ErrorMessage.JR_OUT_OF_RANGE,              "The jump location cannot be reached from this instruction, because it is either more than 127 bytes ahead, or 128 bytes behind, this instruction."}, 
+            {ErrorMessage.Build_JROutOfRange,              "The jump location cannot be reached from this instruction, because it is either more than 127 bytes ahead, or 128 bytes behind, this instruction."}, 
             {ErrorMessage.LABEL_ALREADY_DEFINED,        "The label {0} is already defined."}, 
             {ErrorMessage.LDD_LDI_HL_A_ONLY,            "The instruction ldi/ldd can only be used with 'a' and '[hl]'"}, 
             {ErrorMessage.LDHL_SP_OUT_OF_RANGE,         "The LDHL SP instruction takes an argument between -128 and 127, or between 0x00 and 0xFF."}, 
             {ErrorMessage.Build_MacroArgUsedOutsideOfDef,"Macro arguments can only be used inside of macro definitions."},
             {ErrorMessage.Build_MacroDoesNotExist,      "There is no macro with the name \"{0}\"."},
             {ErrorMessage.Build_UnknownArgument,        "Unable to evaluate the expression due to an unknown variable."},
-            {ErrorMessage.CUSTOM,                       "{0}"},
+            {ErrorMessage.General_CustomError,                       "{0}"},
         };
         public static void ShowErrorMessage(ErrorMessage errorOptions)
         {