diff --git a/DwarfOne2C/CWriter/Function.cs b/DwarfOne2C/CWriter/Function.cs index b21be60..e762ea6 100644 --- a/DwarfOne2C/CWriter/Function.cs +++ b/DwarfOne2C/CWriter/Function.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System; namespace DwarfOne2C { @@ -57,6 +58,11 @@ private static List GenerateFunction( hasParams = true; line += pPart1 + name + pPart2 + ", "; } + else if(child.tagType == TagType.VariadicParam) + { + hasParams = true; + line += name + ", "; + } else if(child.tagType == TagType.LocalVar) { if(firstLocal) diff --git a/DwarfOne2C/CWriter/Types.cs b/DwarfOne2C/CWriter/Types.cs index 487724d..8b15db3 100644 --- a/DwarfOne2C/CWriter/Types.cs +++ b/DwarfOne2C/CWriter/Types.cs @@ -89,11 +89,26 @@ private static (string part1, string part2) GetArray( type += GetModifiers(allTags, IDToIndex, current); } - part2 += string.Format( - "[{0}]", - current.length < 0 - ? "" - : "" + (current.length + 1)); + if (current.isMultidimArray) + { + foreach (int len in current.arrayDimLengths) + { + part2 += string.Format( + "[{0}]", + len < 0 + ? "" + : "" + (len + 1)); + } + } + else + { + part2 += string.Format( + "[{0}]", + current.length < 0 + ? "" + : "" + (current.length + 1)); + } + return (type, part2); } diff --git a/DwarfOne2C/Parsing/BlockParser.cs b/DwarfOne2C/Parsing/BlockParser.cs index 79c0fa0..6535791 100644 --- a/DwarfOne2C/Parsing/BlockParser.cs +++ b/DwarfOne2C/Parsing/BlockParser.cs @@ -1,3 +1,4 @@ +using System.Text; using System; using System.Text.RegularExpressions; @@ -92,24 +93,64 @@ private Tag ParseArray( if(line.StartsWith("AT_subscr_data")) { - if(!line.Contains("FT_long")) + Regex regex; + int count = 0; + string searchFull = @"(?>AT_subscr_data\(<\d+>"; + if(line.Contains("FT_long[")) + { + string searchStr = @"FT_long\[0:(\d+)\], "; + count = Regex.Matches(line, searchStr).Count; + for (int i = count; i > 0; --i) + { + searchFull += searchStr; + } + regex = new(searchFull + @"FMT_ET: (.*)\))"); + } + else if(line.Contains("FT_integer[")) + { + string searchStr = @"FT_integer\[0:(\d+)\], "; + count = Regex.Matches(line, searchStr).Count; + for (int i = count; i > 0; --i) + { + searchFull += searchStr; + } + regex = new(searchFull + @"FMT_ET: (.*)\))"); + } + else { throw new NotImplementedException( - "Array with size type other than " + - "FT_long is not supported"); + "Arrays with size type other than " + + "FT_long or FT_integer are not supported"); } - Regex regex = new( - @"(?>AT_subscr_data\(<\d+>FT_long\[0:(\d+)\], FMT_ET: (.*)\))"); - Match match = regex.Match(line); - GroupCollection groups = match.Groups; - - uint length = Convert.ToUInt32(groups[1].Value); - tag.length = unchecked((int)length); - - string typeRef = groups[2].Value; - ParseTypes(typeRef, tag); + if (match.Success) + { + GroupCollection groups = match.Groups; + tag.isMultidimArray = count > 1; + string typeRef; + if (tag.isMultidimArray) + { + for (int i = 0; i < count; ++i) + { + uint length = Convert.ToUInt32(groups[1 + i].Value); + tag.arrayDimLengths.Add(unchecked((int)length)); + } + typeRef = groups[1 + count].Value; + } + else + { + uint length = Convert.ToUInt32(groups[1].Value); + tag.length = unchecked((int)length); + typeRef = groups[2].Value; + } + ParseTypes(typeRef, tag); + } + else + { + throw new NotImplementedException( + "Unknown array format: " + line + " @" + current); + } } else Console.WriteLine("Unknown attribute: " + line + " @" + current); @@ -177,12 +218,13 @@ private Tag ParseParameter( string[] lines, ref int current, int ID, - int sibling) + int sibling, + bool isVariadic) { Tag tag = new(); tag.ID = ID; tag.sibling = sibling; - tag.tagType = Tag.TagType.Param; + tag.tagType = isVariadic ? Tag.TagType.VariadicParam : Tag.TagType.Param; for(; lines[current].StartsWith(' '); ++current) { diff --git a/DwarfOne2C/Parsing/CompilationUnit.cs b/DwarfOne2C/Parsing/CompilationUnit.cs index ecafe98..fc61b03 100644 --- a/DwarfOne2C/Parsing/CompilationUnit.cs +++ b/DwarfOne2C/Parsing/CompilationUnit.cs @@ -62,7 +62,12 @@ public void FirstPass(string[] lines, int current) case "TAG_formal_parameter": { allTags.Add( - ParseParameter(lines, ref current, ID, sibling)); + ParseParameter(lines, ref current, ID, sibling, false)); + } break; + case "TAG_unspecified_parameters": + { + allTags.Add( + ParseParameter(lines, ref current, ID, sibling, true)); } break; case "TAG_global_subroutine": { diff --git a/DwarfOne2C/Parsing/Helpers.cs b/DwarfOne2C/Parsing/Helpers.cs index 248a109..16578cb 100644 --- a/DwarfOne2C/Parsing/Helpers.cs +++ b/DwarfOne2C/Parsing/Helpers.cs @@ -73,22 +73,22 @@ private static void ParseModifiers(string line, int index, Tag tag) if(line[index] != 'M') break; - if(line.Substring(index, pointerLen) == "MOD_pointer_to") + if(index + pointerLen <= line.Length && line.Substring(index, pointerLen) == "MOD_pointer_to") { tag.modifiers.Add(Type.Modifier.Pointer); index += pointerLen + 1; } - else if(line.Substring(index, refLen) == "MOD_reference_to") + else if(index + refLen <= line.Length && line.Substring(index, refLen) == "MOD_reference_to") { tag.modifiers.Add(Type.Modifier.Reference); index += refLen + 1; } - else if(line.Substring(index, constLen) == "MOD_const") + else if(index + constLen <= line.Length && line.Substring(index, constLen) == "MOD_const") { tag.modifiers.Add(Type.Modifier.Const); index += constLen + 1; } - else if(line.Substring(index, volatileLen) == "MOD_volatile") + else if(index + volatileLen <= line.Length && line.Substring(index, volatileLen) == "MOD_volatile") { tag.modifiers.Add(Type.Modifier.Volatile); index += volatileLen + 1; diff --git a/DwarfOne2C/Tags.cs b/DwarfOne2C/Tags.cs index f020a2e..86242b2 100644 --- a/DwarfOne2C/Tags.cs +++ b/DwarfOne2C/Tags.cs @@ -47,6 +47,7 @@ public enum TagType Union, Padding, // Local variable OR member... MemberFunc, + VariadicParam, } public TagType tagType; @@ -105,6 +106,11 @@ public enum TagType // Typedef public bool isPointer = false; // Size helper public bool isReference = false; // size helper + + // ArrayType + // + public bool isMultidimArray = false; + public List arrayDimLengths = new(); // Inheritance // Member