Skip to content

Commit

Permalink
Investigate various stuffs: #1028
Browse files Browse the repository at this point in the history
  • Loading branch information
mayanje committed Jul 31, 2018
1 parent 1404c8b commit e1c1985
Show file tree
Hide file tree
Showing 10 changed files with 822 additions and 39 deletions.
10 changes: 9 additions & 1 deletion Codegen/src/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,23 @@ public List<Diagnostic> Diagnostics
private set;
}


public TypeCobol.Codegen.IGeneratorContext GeneratorContext
{
get; set;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="Document"> The compilation document </param>
/// <param name="destination">The Output stream for the generated code</param>
/// <param name="skeletons">All skeletons pattern for code generation </param>
public Generator(TypeCobol.Compiler.CompilationDocument document, StringBuilder destination, List<Skeleton> skeletons, string typeCobolVersion)
public Generator(TypeCobol.Compiler.CompilationDocument document, StringBuilder destination, List<Skeleton> skeletons, string typeCobolVersion,
TypeCobol.Codegen.IGeneratorContext context = null)
{
this.CompilationResults = document;
this.TypeCobolVersion = typeCobolVersion;
this.GeneratorContext = context;
Destination = destination;

//Add version to output file
Expand Down Expand Up @@ -330,4 +337,5 @@ public void AddDiagnostic(Diagnostic diag)

public string TypeCobolVersion { get; set; }
}

}
146 changes: 132 additions & 14 deletions Codegen/src/Generators/DefaultGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class DefaultGenerator : Generator
/// <param name="destination">The Output stream for the generated code</param>
/// <param name="skeletons">All skeletons pattern for code generation </param>
public DefaultGenerator(TypeCobol.Compiler.CompilationDocument document, StringBuilder destination, List<Skeleton> skeletons, string typeCobolVersion)
: base(document, destination, skeletons, null)
: base(document, destination, skeletons, null, new DefaultGeneratorContext())
{
TypeCobolVersion = typeCobolVersion;
}
Expand All @@ -76,7 +76,7 @@ protected override void TreeToCode()
{
LinearNodeSourceCodeMapper mapper = new LinearNodeSourceCodeMapper(this);
mapper.Accept(RootNode);
//mapper.DebugDump();
mapper.DebugDump();
SourceText generatedDocument = LinearGeneration(mapper, CompilationResults.TokensLines);
// Step 3: Write target document
//TCCODEGEN_NO_TRAILING_SPACES
Expand Down Expand Up @@ -190,6 +190,9 @@ private SourceText LinearGeneration<A>(LinearNodeSourceCodeMapper mapper, IReadO
previousBuffer = null;
}
Node node = mapper.Nodes[node_index].node;
//Before generating the node
GeneratorContext?.BeforeNode(mapper, node);

bool bGenerated = node is Generated;
bool bForceGenerateLines = true;
if (!bGenerated)
Expand All @@ -216,30 +219,40 @@ private SourceText LinearGeneration<A>(LinearNodeSourceCodeMapper mapper, IReadO
Position to = mapper.Nodes[node_index].To;
bool bIsGenerateAndReplace = node is GeneratedAndReplace;
if (bIsGenerateAndReplace)
{//The node has a source code that must be replaced
{
//The node has a source code that must be replaced
string code = (node as GeneratedAndReplace).ReplaceCode;
GenerateIntoBufferCheckLineExceed(from, to, curSourceText, code, i + 1);
}
else foreach (var line in NodeLines(node, generated_node))
else
{
//First deal with pre code
if (curSourceText != null)
GenPrecode(node, from.Pos, to.Pos, curSourceText);
foreach (var line in NodeLines(node, generated_node))
{
bool bInsertSplit = false;
StringWriter sw = new StringWriter();
if (bFirst && !bIsFunctionDecl && curSourceText != null)
{//The first element don't ident it just insert it a the right position
//issue #892 => Anyway Handle splitting
{
//The first element don't ident it just insert it a the right position
//issue #892 => Anyway Handle splitting
sw.WriteLine(line.Text);
bFirst = false;
bInsertSplit = true;
}
else foreach (var l in Indent(line, null))
else
foreach (var l in Indent(line, null))
{
sw.WriteLine(l.Text.TrimEnd());
}
sw.Flush();
string text = sw.ToString();
if (bIsFunctionDecl)
{ //This the Function Header output.
LinearNodeSourceCodeMapper.NodeFunctionData funData = mapper.Nodes[node_index] as LinearNodeSourceCodeMapper.NodeFunctionData;
{
//This the Function Header output.
LinearNodeSourceCodeMapper.NodeFunctionData funData =
mapper.Nodes[node_index] as LinearNodeSourceCodeMapper.NodeFunctionData;
int f = Math.Min(from.Pos, curSourceText.Size);
int t = Math.Min(to.Pos, curSourceText.Size);
if (f != t)
Expand All @@ -249,22 +262,28 @@ private SourceText LinearGeneration<A>(LinearNodeSourceCodeMapper mapper, IReadO
//Erase in the original source code the Function header?
ReplaceByBlanks(curSourceText, f, t);
//Output the pre-stored comment header
InsertLineMaybeSplit(funData.FunctionDeclBuffer, funData.CommentedHeader.ToString(), funData.FunctionDeclBuffer.Size, funData.FunctionDeclBuffer.Size, bInsertSplit);
InsertLineMaybeSplit(funData.FunctionDeclBuffer,
funData.CommentedHeader.ToString(), funData.FunctionDeclBuffer.Size,
funData.FunctionDeclBuffer.Size, bInsertSplit);
}
//Insert the sequence
InsertLineMaybeSplit(funData.FunctionDeclBuffer, text, funData.FunctionDeclBuffer.Size, funData.FunctionDeclBuffer.Size, bInsertSplit);
InsertLineMaybeSplit(funData.FunctionDeclBuffer, text,
funData.FunctionDeclBuffer.Size, funData.FunctionDeclBuffer.Size, bInsertSplit);
}
else
{
if (curSourceText == null)
InsertLineMaybeSplit(targetSourceText, text, targetSourceText.Size, targetSourceText.Size, bInsertSplit);
InsertLineMaybeSplit(targetSourceText, text, targetSourceText.Size,
targetSourceText.Size, bInsertSplit);
else
InsertLineMaybeSplit(curSourceText, text, Math.Min(from.Pos, curSourceText.Size), Math.Min(to.Pos, curSourceText.Size), bInsertSplit);
InsertLineMaybeSplit(curSourceText, text, Math.Min(from.Pos, curSourceText.Size),
Math.Min(to.Pos, curSourceText.Size), bInsertSplit);
}
from = to;
sw.Close();
}
//Don't pad in case of replacement or insertion in a function declaration
}
//Don't pad in case of replacement or insertion in a function declaration
if (!bIsGenerateAndReplace && !bIsFunctionDecl)
{
//Pad a splitted segment
Expand All @@ -285,6 +304,18 @@ private SourceText LinearGeneration<A>(LinearNodeSourceCodeMapper mapper, IReadO
curSourceText = null;
}
}

//Epilogue code
GeneratorContext?.AfterNode(mapper, node);
if (!bForceGenerateLines && curSourceText != null)
{ //This node has not been generated force to generate: precode, prologue and epilogue code.
Position from = mapper.Nodes[node_index].From;
Position to = mapper.Nodes[node_index].To;
GenPrecode(node, from.Pos, to.Pos, curSourceText);
GenPrologueOrEpiloguecode(node, from.Pos, to.Pos, curSourceText, true);
GenPrologueOrEpiloguecode(node, from.Pos, to.Pos, curSourceText, false);
}

//This node is now generated.
generated_node[node_index] = true;
if (mapper.Nodes[node_index].node.IsFlagSet(Node.Flag.EndFunctionDeclarationNode))
Expand Down Expand Up @@ -329,6 +360,72 @@ private SourceText LinearGeneration<A>(LinearNodeSourceCodeMapper mapper, IReadO
return targetSourceText;
}

/// <summary>
/// Generate Any PreCode associated to this node.
/// </summary>
/// <param name="node">The Nod eto Generate the PreCode</param>
/// <param name="from">Starting position in the generation buffer</param>
/// <param name="to">End position in the generation buffer</param>
/// <param name="curSourceText">The generation buffer</param>
private void GenPrecode(Node node, int from, int to, StringSourceText curSourceText)
{
if (node.PrecodeLines == null)
return;
int lineStartOffset = 0;
int lineEndOffset = 0;
int lineLen = curSourceText.GetLineInfo(from, out lineStartOffset, out lineEndOffset);
string pad = new string(' ', from - lineStartOffset);
StringWriter sw = new StringWriter();
sw.WriteLine();
foreach (var line in node.PrecodeLines)
{
foreach (var l in Indent(line, null))
{
sw.WriteLine(l.Text.TrimEnd());
}
}
sw.WriteLine();
sw.Write(pad);
sw.Flush();
string text = sw.ToString();
curSourceText.Insert(text, from, from);
}

/// <summary>
/// Generate Any Prologue or Epilogue associated to this node.
/// </summary>
/// <param name="node">The Node to Generate the PreCode</param>
/// <param name="from">Starting position in the generation buffer</param>
/// <param name="to">End position in the generation buffer</param>
/// <param name="curSourceText">The generation buffer</param>
/// <param name="bPrologue">True if prologue code, flase otherwise.</param>
private void GenPrologueOrEpiloguecode(Node node, int from, int to, StringSourceText curSourceText, bool bPrologue)
{
if (bPrologue && node.PrologueLines == null)
return;
if (node.EpilogueLines == null)
return;

int lineStartOffset = 0;
int lineEndOffset = 0;
int lineLen = curSourceText.GetLineInfo(from, out lineStartOffset, out lineEndOffset);
string pad = new string(' ', to - lineStartOffset);
StringWriter sw = new StringWriter();
sw.WriteLine();
foreach (var line in node.PrecodeLines)
{
foreach (var l in Indent(line, null))
{
sw.WriteLine(l.Text.TrimEnd());
}
}
sw.WriteLine();
sw.Write(pad);
sw.Flush();
string text = sw.ToString();
curSourceText.Insert(text, to, to);
}

/// <summary>
/// Insert in the buffer a text line that can be split.
/// </summary>
Expand Down Expand Up @@ -654,6 +751,17 @@ void RecursiveNodeLines(Node node, BitArray generated_node, List<ITextLine> all_
/// <returns></returns>
public virtual IEnumerable<ITextLine> NodeLines(Node node, BitArray generated_node)
{
//Prologue lines
if (node.PrologueLines != null)
{
var prologueLines = node.PrologueLines;
if (prologueLines != null)
{
foreach (var l in prologueLines)
yield return l;
}
}

if (node.IsFlagSet(Node.Flag.FullyGenerateRecursivelyFactoryGeneratedNode))
{
List<ITextLine> all_lines = new List<ITextLine>();
Expand Down Expand Up @@ -683,6 +791,16 @@ public virtual IEnumerable<ITextLine> NodeLines(Node node, BitArray generated_no
}
}
}
//Epilogue lines
if (node.EpilogueLines != null)
{
var epilogueLines = node.EpilogueLines;
if (epilogueLines != null)
{
foreach (var l in epilogueLines)
yield return l;
}
}
}
/// <summary>
/// Check if the given commented text is one of a Function declaration Header, if so the text is added to the
Expand Down
Loading

0 comments on commit e1c1985

Please sign in to comment.