示例#1
0
        public void CompileCodeInPlace(string[] fileNames)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var fileName in fileNames)
            {
                sb.AppendLine("#include " + AssemblerProjectWriter.EscapeAndQuoteString(Path.GetFullPath(fileName)));
            }
            CompileCodeInPlace(sb.ToString());
        }
        static void ToStringReal(TokenExpression ex, MyIndentedTextWriter tw)
        {
            if (ex == null)
            {
                return;
            }
            switch (ex.TokenType)
            {
            default:
                if (!String.IsNullOrEmpty(ex.Token.Value) && ex.Token.Value != "...")
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.Subexpressions.Count > 0)
                {
                    tw.Write(" ");
                    ToStringReal(ex.Subexpressions, tw);
                }
                break;

            case TokenType.Array:
            case TokenType.AddressOf:
            case TokenType.At:
            case TokenType.Complement:
            case TokenType.Increment:
            case TokenType.Decrement:
                if (!String.IsNullOrEmpty(ex.Token.Value) && ex.Token.Value != "...")
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.Subexpressions.Count > 0)
                {
                    ToStringReal(ex.Subexpressions, tw);
                }
                break;

            case TokenType.Block:
                if (!tw.TabsPending)
                {
                    tw.WriteLine();
                }
                tw.WriteLine("{");
                tw.Indent++;
                ToStringReal(ex.Subexpressions, tw);
                tw.Indent--;
                if (!tw.TabsPending)
                {
                    tw.WriteLine();
                }
                tw.WriteLine("}");
                break;

            case TokenType.Statement:
                ToStringReal(ex.Subexpressions, tw);
                tw.WriteLine(";");
                break;

            case TokenType.StringLiteral:
                tw.Write(AssemblerProjectWriter.EscapeAndQuoteString(ex.Token.Value));
                break;

            case TokenType.CharLiteral:
            case TokenType.Message:
                tw.Write(AssemblerProjectWriter.EscapeAndQuoteMessage(ex.Token.Value));
                break;

            case TokenType.ArrayIndex:
                tw.Write("[");
                ToStringReal(ex.Subexpressions, tw);
                tw.Write("]");
                break;

            case TokenType.Assert:
                tw.Write("assert (");
                for (int i = 0; i < ex.Subexpressions.Count; i++)
                {
                    if (i != 0)
                    {
                        tw.Write(", ");
                    }
                    ToStringReal(ex.Subexpressions[i], tw);
                }
                tw.Write(")");
                break;

            case TokenType.For:
                tw.Write("for (");
                for (int i = 0; i < 3; i++)
                {
                    if (i != 0)
                    {
                        tw.Write("; ");
                    }
                    var subex = ex.Subexpressions.GetOrNull(i);
                    ToStringReal(subex, tw);
                }
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(3), tw);
                break;

            case TokenType.While:
                tw.Write("while (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(1), tw);
                break;

            case TokenType.If:
                tw.Write("if (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.GetOrNull(1), tw);
                {
                    var subex = ex.Subexpressions.GetOrNull(2);
                    if (subex != null)
                    {
                        ToStringReal(subex, tw);
                    }
                }
                break;

            case TokenType.Switch:
                tw.Write("switch (");
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.WriteLine(")");
                ToStringReal(ex.Subexpressions.Skip(1), tw);
                break;

            case TokenType.FunctionCall:
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);
                tw.Write("(");
                ToStringReal(ex.Subexpressions.Skip(1), tw);
                tw.Write(")");
                break;

            case TokenType.PostDecrement:
            case TokenType.PostIncrement:
                ToStringReal(ex.Subexpressions, tw);
                tw.Write(ex.Token.Value);
                break;

            //infix binary operators
            case TokenType.And:
            case TokenType.AndAssign:
            case TokenType.Assign:
            case TokenType.Colon:
            case TokenType.Comma:
            case TokenType.Divide:
            case TokenType.DivideAssign:
            case TokenType.Dot:
            case TokenType.EqualTo:
            case TokenType.LeftShift:
            case TokenType.LeftShiftAssign:
            case TokenType.LessThan:
            case TokenType.LessThanOrEqualTo:
            case TokenType.LogicalAnd:
            case TokenType.LogicalOr:
            case TokenType.Minus:
            case TokenType.MinusAssign:
            case TokenType.Modulo:
            case TokenType.ModuloAssign:
            case TokenType.Multiply:
            case TokenType.MultiplyAssign:
            case TokenType.NotEqualTo:
            case TokenType.Or:
            case TokenType.OrAssign:
            case TokenType.Plus:
            case TokenType.PlusAssign:
            case TokenType.QuestionMark:
            case TokenType.ReferenceAssign:
            case TokenType.ReferenceEqualTo:
            case TokenType.ReferenceNotEqualTo:
            case TokenType.ReferenceSwap:
            case TokenType.RightShift:
            case TokenType.RightShiftAssign:
            case TokenType.Xor:
            case TokenType.XorAssign:
                //output left side
                ToStringReal(ex.Subexpressions.GetOrNull(0), tw);

                if (ex.TokenType != TokenType.Comma && ex.TokenType != TokenType.Dot)
                {
                    tw.Write(" ");
                }

                if (String.IsNullOrEmpty(ex.Token.Value) || ex.Token.Value == "...")
                {
                    if (keywordTableInverse.ContainsKey(ex.TokenType))
                    {
                        tw.Write(keywordTableInverse[ex.TokenType]);
                    }
                }
                else
                {
                    tw.Write(ex.Token.Value);
                }
                if (ex.TokenType != TokenType.Dot)
                {
                    tw.Write(" ");
                }

                ToStringReal(ex.Subexpressions.Skip(1), tw);
                break;
            }



            //foreach (var ex in exBase.GetAllSubexpressionsRecursive())
            //{
            //    switch (ex.TokenType)
            //    {
            //        case TokenType.And:
            //            case TokenType.

            //        default:
            //            sb.Append(ex.Token.Value);
            //            break;
            //    }
            //}
            //return sb.ToString();
        }
            private void ReadReplacementFile(TextReaderWrapper tr, string textFileName)
            {
                textFileName = Path.GetFullPath(textFileName);
                if (IncludedFiles.Contains(textFileName.ToUpperInvariant()))
                {
                    return;
                }
                IncludedFiles.Set(textFileName.ToUpperInvariant());

                string line;

                while (true)
                {
                    line = tr.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    //remove initial whitespace
                    line = line.TrimStart();

                    //check for "#include"
                    if (line.StartsWith("#include "))
                    {
                        string filenameToInclude = line.Substring("#include ".Length);
                        //check for quotes?
                        if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\""))
                        {
                            filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2);
                        }
                        string basePath = tr.DirectoryName;
                        filenameToInclude = Path.Combine(basePath, filenameToInclude);
                        if (!File.Exists(filenameToInclude))
                        {
                            throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude);
                        }

                        if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant()))
                        {
                            IncludedFiles.Add(filenameToInclude.ToUpperInvariant());
                            var encoding = EncodingDetector.DetectEncoding(filenameToInclude);
                            tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding));
                        }
                        continue;
                    }


                    //remove commented text
                    int indexOfComment = line.IndexOf('#');
                    if (indexOfComment >= 0)
                    {
                        line = line.Substring(0, indexOfComment);
                    }

                    //reading one of these lines:
                    //CODE
                    //function x functionName  (or func, f)
                    //string x text (or str, s)
                    //message x text (or msg, m)
                    //id x text (or i)
                    //x text (same as id x text)

                    string lineTrim = line.Trim();

                    if (lineTrim.Equals("CODE", StringComparison.OrdinalIgnoreCase) || lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase))
                    {
                        bool          isCode2  = lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase);
                        StringBuilder codeText = new StringBuilder();
                        while (true)
                        {
                            line     = tr.ReadLine();
                            lineTrim = line.Trim();
                            if (lineTrim.StartsWith("#include"))
                            {
                                string filenameToInclude = lineTrim.Substring("#include ".Length);
                                //check for quotes?
                                if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\""))
                                {
                                    filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2);
                                }
                                string basePath = tr.DirectoryName;
                                if (!Path.IsPathRooted(filenameToInclude))
                                {
                                    filenameToInclude = Path.Combine(basePath, filenameToInclude);
                                }
                                filenameToInclude = Path.GetFullPath(filenameToInclude);

                                if (!File.Exists(filenameToInclude))
                                {
                                    throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude);
                                }

                                if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant()))
                                {
                                    IncludedFiles.Add(filenameToInclude.ToUpperInvariant());

                                    if (isCode2)
                                    {
                                        //replace with #include <fullpath>, let the compiler handle the actual include
                                        codeText.AppendLine("#include " + AssemblerProjectWriter.EscapeAndQuoteString(filenameToInclude));
                                    }
                                    else
                                    {
                                        var encoding = EncodingDetector.DetectEncoding(filenameToInclude);
                                        tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding));
                                    }
                                }
                                continue;
                            }

                            if (lineTrim.ToUpperInvariant() == "ENDCODE")
                            {
                                if (isCode2)
                                {
                                    CodePatches2.AppendLine(codeText.ToString());
                                }
                                else
                                {
                                    CodePatches.Set(currentFunctionName, codeText.ToString());
                                }
                                break;
                            }
                            else
                            {
                                codeText.AppendLine(line);
                            }
                        }
                        continue;
                    }

                    //find first space
                    int spaceIndex = line.IndexOf(' ');
                    if (spaceIndex == -1)
                    {
                        continue;
                    }
                    string tagName = line.Substring(0, spaceIndex);
                    line = line.Substring(spaceIndex + 1);
                    int number;
                    //if it starts with a number, it's a legacy text replacement
                    if (IntUtil.TryParse(tagName, out number) == true)
                    {
                        tagName = "id";
                    }
                    else
                    {
                        bool   isFunction   = false;
                        string tagNameLower = tagName.ToLowerInvariant();
                        if (tagNameLower == "f" || tagNameLower == "func" || tagNameLower == "function")
                        {
                            isFunction = true;
                        }

                        line       = line.TrimStart();
                        spaceIndex = line.IndexOf(' ');
                        if (spaceIndex == -1)
                        {
                            if (isFunction)
                            {
                                number = -1;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            string numberString = line.Substring(0, spaceIndex);
                            line = line.Substring(spaceIndex + 1);

                            if (IntUtil.TryParse(numberString, out number) == false)
                            {
                                if (isFunction)
                                {
                                    line   = numberString + " " + line;
                                    number = -1;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    line = StringExportImport.UnescapeText(line);

                    switch (tagName.ToLowerInvariant())
                    {
                    case "f":
                    case "func":
                    case "function":
                        string nextFunctionName = line.Trim();
                        var    function         = ainFile.GetFunction(number);
                        if (function == null)
                        {
                            function = ainFile.GetFunction(nextFunctionName);
                            if (function == null)
                            {
                                continue;
                            }
                        }
                        currentFunctionName = function.Name;
                        stringDictionary    = stringEntries.GetOrAddNew(currentFunctionName);
                        messageDictionary   = messageEntries.GetOrAddNew(currentFunctionName);
                        break;

                    case "string":
                    case "str":
                    case "s":
                        stringDictionary.Set(number, line);
                        break;

                    case "msg":
                    case "message":
                    case "m":
                        messageDictionary.Set(number, line);
                        break;

                    case "i":
                    case "id":
                        numberedStrings.Set(number, line);
                        break;
                    }
                }
            }