diff --git a/ownlang-desktop/src/main/java/com/annimon/ownlang/Main.java b/ownlang-desktop/src/main/java/com/annimon/ownlang/Main.java index d654436..dd02879 100644 --- a/ownlang-desktop/src/main/java/com/annimon/ownlang/Main.java +++ b/ownlang-desktop/src/main/java/com/annimon/ownlang/Main.java @@ -4,7 +4,9 @@ import com.annimon.ownlang.exceptions.OwnLangParserException; import com.annimon.ownlang.exceptions.StoppedException; import com.annimon.ownlang.parser.*; import com.annimon.ownlang.parser.ast.Statement; +import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage; import com.annimon.ownlang.parser.linters.LinterStage; +import com.annimon.ownlang.parser.optimization.OptimizationStage; import com.annimon.ownlang.stages.*; import com.annimon.ownlang.utils.Repl; import com.annimon.ownlang.utils.Sandbox; @@ -142,13 +144,13 @@ public final class Main { final var scopedStages = new ScopedStageFactory(measurement::start, measurement::stop); final var stagesData = new StagesDataMap(); - stagesData.put(OptimizationStage.TAG_OPTIMIZATION_SUMMARY, options.showAst); stagesData.put(SourceLoaderStage.TAG_SOURCE, input); try { scopedStages.create("Lexer", new LexerStage()) .then(scopedStages.create("Parser", new ParserStage())) .thenConditional(options.optimizationLevel > 0, - scopedStages.create("Optimization", new OptimizationStage(options.optimizationLevel))) + scopedStages.create("Optimization", + new OptimizationStage(options.optimizationLevel, options.showAst))) .thenConditional(options.lintMode, scopedStages.create("Linter", new LinterStage())) .then(scopedStages.create("Function adding", new FunctionAddingStage())) @@ -173,8 +175,9 @@ public final class Main { if (options.showAst) { Statement program = stagesData.get(ParserStage.TAG_PROGRAM); System.out.println(program); + System.out.println(stagesData.getOrDefault(OptimizationStage.TAG_OPTIMIZATION_SUMMARY, "")); } - if (!options.showMeasurements) { + if (options.showMeasurements) { System.out.println("======================"); System.out.println(measurement.summary(TimeUnit.MILLISECONDS, true)); } diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Optimizer.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Optimizer.java deleted file mode 100644 index a4f2ff6..0000000 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/Optimizer.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.annimon.ownlang.parser; - -import com.annimon.ownlang.Console; -import com.annimon.ownlang.parser.ast.Node; -import com.annimon.ownlang.parser.ast.Statement; -import com.annimon.ownlang.parser.optimization.ConstantFolding; -import com.annimon.ownlang.parser.optimization.ConstantPropagation; -import com.annimon.ownlang.parser.optimization.DeadCodeElimination; -import com.annimon.ownlang.parser.optimization.ExpressionSimplification; -import com.annimon.ownlang.parser.optimization.InstructionCombining; -import com.annimon.ownlang.parser.optimization.Optimizable; -import com.annimon.ownlang.parser.optimization.SummaryOptimization; - -public final class Optimizer { - - private Optimizer() { } - - public static Statement optimize(Statement statement, int level, boolean showSummary) { - if (level == 0) return statement; - - final Optimizable optimization = new SummaryOptimization(new Optimizable[] { - new ConstantFolding(), - new ConstantPropagation(), - new DeadCodeElimination(), - new ExpressionSimplification(), - new InstructionCombining() - }); - - Node result = statement; - if (level >= 9) { - int iteration = 0, lastModifications = 0; - do { - lastModifications = optimization.optimizationsCount(); - result = optimization.optimize(result); - iteration++; - } while (lastModifications != optimization.optimizationsCount()); - if (showSummary) - Console.print("Performs " + iteration + " optimization iterations"); - } else { - for (int i = 0; i < level; i++) { - result = optimization.optimize(result); - } - } - if (showSummary) { - Console.println(optimization.summaryInfo()); - } - return (Statement) result; - } -} diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/OptimizationStage.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/OptimizationStage.java new file mode 100644 index 0000000..ee7811c --- /dev/null +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/OptimizationStage.java @@ -0,0 +1,56 @@ +package com.annimon.ownlang.parser.optimization; + +import com.annimon.ownlang.parser.ast.Node; +import com.annimon.ownlang.parser.ast.Statement; +import com.annimon.ownlang.stages.Stage; +import com.annimon.ownlang.stages.StagesData; + +public class OptimizationStage implements Stage { + + public static final String TAG_OPTIMIZATION_SUMMARY = "optimizationSummary"; + + private final int level; + private final boolean summary; + private final Optimizable optimization; + + public OptimizationStage(int level) { + this(level, false); + } + + public OptimizationStage(int level, boolean summary) { + this.level = level; + this.summary = summary; + optimization = new SummaryOptimization(new Optimizable[] { + new ConstantFolding(), + new ConstantPropagation(), + new DeadCodeElimination(), + new ExpressionSimplification(), + new InstructionCombining() + }); + } + + @Override + public Statement perform(StagesData stagesData, Statement input) { + if (level == 0) return input; + + Node result = input; + final int maxIterations = level >= 9 ? Integer.MAX_VALUE : level; + int lastModifications; + int iteration = 0; + do { + lastModifications = optimization.optimizationsCount(); + result = optimization.optimize(result); + iteration++; + } while (lastModifications != optimization.optimizationsCount() && iteration < maxIterations); + + if (this.summary) { + stagesData.put(TAG_OPTIMIZATION_SUMMARY, """ + Performed %d optimization iterations + %s + """.formatted(iteration, optimization.summaryInfo()) + ); + } + + return (Statement) result; + } +} diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/stages/OptimizationStage.java b/ownlang-parser/src/main/java/com/annimon/ownlang/stages/OptimizationStage.java deleted file mode 100644 index dfbe00f..0000000 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/stages/OptimizationStage.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.annimon.ownlang.stages; - -import com.annimon.ownlang.parser.Optimizer; -import com.annimon.ownlang.parser.ast.Statement; - -public record OptimizationStage(int level) - implements Stage { - - public static final String TAG_OPTIMIZATION_SUMMARY = "optimizationSummary"; - - @Override - public Statement perform(StagesData stagesData, Statement input) { - boolean showSummary = stagesData.getOrDefault(TAG_OPTIMIZATION_SUMMARY, false); - return Optimizer.optimize(input, level, showSummary); - } -}