Simple-Code-Generator/src/main/java/speiger/src/builder/base/ConditionedSegment.java

116 lines
4.1 KiB
Java

package speiger.src.builder.base;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import speiger.src.builder.conditions.ICondition;
import speiger.src.builder.misc.IdGenerator;
import speiger.src.builder.processor.CompiledArguments;
public class ConditionedSegment
{
static final Pattern AND = Pattern.compile("(&&)");
static final Pattern OR = Pattern.compile("(||)");
int index;
List<Segment> segments = new ArrayList<>();
public ConditionedSegment(int index)
{
this.index = index;
}
public void addSegment(Segment segment)
{
segments.add(segment);
}
public int build(CompiledArguments process, StringBuilder builder, int baseIndex)
{
baseIndex += index;
int length = builder.length();
for(int i = 0,m=segments.size();i<m;i++)
{
if(segments.get(i).build(process, builder, baseIndex)) break;
}
return builder.length() - length;
}
public static int parse(String fileName, String currentLine, List<String> lines, int currentIndex, int startIndex, IdGenerator ignoreCounter, List<ConditionedSegment> segments, List<PostSegment> postSegments) throws IllegalStateException
{
String ignoreSegmentId = ignoreCounter.getId();
ConditionedSegment segment = new ConditionedSegment(startIndex);
ICondition condition = currentLine == null ? null : ICondition.parse(currentLine);
List<ConditionedSegment> childSegments = new ArrayList<>();
StringJoiner segmentText = new StringJoiner("\n", (currentIndex <= 0 || includeStartNewLine(lines.get(currentIndex-1).trim())) ? "\n" : "", "");
if(currentLine == null) {
lines.set(currentIndex, ignoreSegmentId);
}
for(int i = currentIndex+1;i<lines.size();i++)
{
String s = lines.get(i);
String trimmed = s.trim();
if(trimmed.startsWith("#"))
{
if(trimmed.startsWith("#else if"))
{
if(currentLine == null) throw new IllegalStateException("#else if isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
condition = ICondition.parse(trimmed.substring(8).trim());
childSegments = new ArrayList<>();
segmentText = new StringJoiner("\n", "\n", "");
}
else if(trimmed.startsWith("#else"))
{
if(currentLine == null) throw new IllegalStateException("#else isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
condition = ICondition.ALWAYS_TRUE;
childSegments = new ArrayList<>();
segmentText = new StringJoiner("\n", "\n", "");
}
else if(trimmed.startsWith("#endif"))
{
if(currentLine == null) throw new IllegalStateException("#endif isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
segments.add(segment);
return i - currentIndex;
}
else if(trimmed.startsWith("#endignore"))
{
postSegments.add(new PostSegment(segmentText.toString(), ignoreSegmentId));
segments.add(segment);
return i - currentIndex;
}
else if(trimmed.startsWith("#if"))
{
if(currentLine == null) throw new IllegalStateException("#if isn't working while in a ignore segment");
i += parse(fileName, trimmed.substring(3).trim(), lines, i, segmentText.length(), ignoreCounter, childSegments, postSegments);
}
else if(trimmed.startsWith("#ignore"))
{
if(currentLine == null) throw new IllegalStateException("#ignore lines can't be applied Recursively");
ignoreCounter.appendId();
int prev = i;
i += parse(fileName, null, lines, i, segmentText.length(), ignoreCounter, childSegments, postSegments);
segmentText.add(lines.get(prev));
}
else if(trimmed.startsWith("#iterate")) {
SegmentIterator.iterateSegment(fileName, trimmed, lines, i, segmentText.length());
i--;
}
continue;
}
segmentText.add(s);
}
throw new IllegalStateException("Unclosed #If found in ["+fileName+"] at line ["+startIndex+"]");
}
static boolean includeStartNewLine(String s)
{
return !s.startsWith("#") || s.equalsIgnoreCase("#endif") || s.equalsIgnoreCase("#endignore");
}
}