From 0002c81205289bf6426a8fe137ff71edd4cae36a Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 23 Jun 2016 22:46:50 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/annimon/ownlang/Main.java | 41 ++++++++++++++++--- src/com/annimon/ownlang/parser/Optimizer.java | 32 +++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/com/annimon/ownlang/parser/Optimizer.java diff --git a/src/com/annimon/ownlang/Main.java b/src/com/annimon/ownlang/Main.java index feea6c8..6a4fb94 100644 --- a/src/com/annimon/ownlang/Main.java +++ b/src/com/annimon/ownlang/Main.java @@ -1,15 +1,16 @@ package com.annimon.ownlang; -import com.annimon.ownlang.utils.TimeMeasurement; import com.annimon.ownlang.exceptions.LexerException; import com.annimon.ownlang.parser.Beautifier; import com.annimon.ownlang.parser.Lexer; import com.annimon.ownlang.parser.Linter; +import com.annimon.ownlang.parser.Optimizer; import com.annimon.ownlang.parser.Parser; import com.annimon.ownlang.parser.SourceLoader; import com.annimon.ownlang.parser.Token; import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.visitors.FunctionAdder; +import com.annimon.ownlang.utils.TimeMeasurement; import java.io.IOException; import java.util.List; import java.util.Scanner; @@ -35,7 +36,8 @@ public final class Main { options.showAst = true; options.showTokens = true; options.showMeasurements = true; - options.lintMode = true; + options.lintMode = false; + options.optimizationLevel = 2; run(SourceLoader.readSource("program.own"), options); } catch (IOException ioe) { System.out.println("OwnLang version " + VERSION + "\n\n" + @@ -44,6 +46,7 @@ public final class Main { " -f, --file [input] Run program file. Required.\n" + " -r, --repl Enter to a REPL mode\n" + " -l, --lint Find bugs in code\n" + + " -o N, --optimize N Perform optimization with N passes\n" + " -b, --beautify Beautify source code\n" + " -a, --showast Show AST of program\n" + " -t, --showtokens Show lexical tokens\n" + @@ -77,6 +80,20 @@ public final class Main { options.showMeasurements = true; break; + case "-o": + case "--optimize": + if (i + 1 < args.length) { + try { + options.optimizationLevel = Integer.parseInt(args[i + 1]); + } catch (NumberFormatException nfe) { + options.optimizationLevel = 2; + } + i++; + } else { + options.optimizationLevel = 2; + } + return; + case "-r": case "--repl": repl(); @@ -134,19 +151,30 @@ public final class Main { measurement.start("Parse time"); final Parser parser = new Parser(tokens); - final Statement program = parser.parse(); + final Statement parsedProgram = parser.parse(); measurement.stop("Parse time"); if (options.showAst) { - System.out.println(program.toString()); + System.out.println(parsedProgram.toString()); } if (parser.getParseErrors().hasErrors()) { System.out.println(parser.getParseErrors()); return; } if (options.lintMode) { - Linter.lint(program); + Linter.lint(parsedProgram); return; } + final Statement program; + if (options.optimizationLevel > 0) { + measurement.start("Optimization time"); + program = Optimizer.optimize(parsedProgram, options.optimizationLevel); + measurement.stop("Optimization time"); + if (options.showAst) { + System.out.println(program.toString()); + } + } else { + program = parsedProgram; + } program.accept(new FunctionAdder()); try { measurement.start("Execution time"); @@ -203,12 +231,14 @@ public final class Main { private static class Options { boolean showTokens, showAst, showMeasurements; boolean lintMode; + int optimizationLevel; public Options() { showTokens = false; showAst = false; showMeasurements = false; lintMode = false; + optimizationLevel = 1; } public void validate() { @@ -216,6 +246,7 @@ public final class Main { showTokens = false; showAst = false; showMeasurements = false; + optimizationLevel = 0; } } } diff --git a/src/com/annimon/ownlang/parser/Optimizer.java b/src/com/annimon/ownlang/parser/Optimizer.java new file mode 100644 index 0000000..0940dc3 --- /dev/null +++ b/src/com/annimon/ownlang/parser/Optimizer.java @@ -0,0 +1,32 @@ +package com.annimon.ownlang.parser; + +import com.annimon.ownlang.parser.ast.Statement; +import com.annimon.ownlang.parser.visitors.ConstantFolding; +import com.annimon.ownlang.parser.visitors.DeadCodeElimination; + +public final class Optimizer { + + public interface Info { + + int optimizationsCount(); + + String summaryInfo(); + } + + public static Statement optimize(Statement statement, int level) { + if (level == 0) return statement; + + final ConstantFolding constantFolding = new ConstantFolding(); + final DeadCodeElimination deadCodeElimination = new DeadCodeElimination(); + + Statement result = statement; + for (int i = 0; i < level; i++) { + result = (Statement) result.accept(constantFolding, null); + result = (Statement) result.accept(deadCodeElimination, null); + } + System.out.print(constantFolding.summaryInfo()); + System.out.print(deadCodeElimination.summaryInfo()); + System.out.println(); + return result; + } +}