001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2007 New York University
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019:
020: package xtc.typical;
021:
022: import java.io.BufferedWriter;
023: import java.io.File;
024: import java.io.IOException;
025: import java.io.Reader;
026: import java.io.PrintWriter;
027: import java.io.FileWriter;
028:
029: import xtc.lang.JavaPrinter;
030:
031: import xtc.parser.ParseException;
032: import xtc.tree.GNode;
033: import xtc.tree.Node;
034: import xtc.tree.Printer;
035: import xtc.tree.Visitor;
036:
037: import xtc.util.Tool;
038: import xtc.util.Runtime;
039:
040: import xtc.util.SymbolTable;
041:
042: /**
043: * The Typical compiler.
044: *
045: * @author Laune Harris, Anh Le
046: * @version $Revision: 1.30 $
047: */
048: public class Typical extends Tool {
049:
050: /**The Analyzer to run the test*/
051: protected Object analyser;
052:
053: /**The name of the analyzer*/
054: protected String checker;
055:
056: /**The name of the typical file */
057: protected String typicalName;
058:
059: /** Create a new Typical compiler. */
060: public Typical() { /* Nothing to do. */
061: }
062:
063: public String getName() {
064: return "Typical";
065: }
066:
067: public void init() {
068: super .init();
069:
070: runtime
071: .bool("checkOnly", "optionCheckOnly", false,
072: "Type check, but do not generate code.")
073: .bool("typesOnly", "optionTypesOnly", false,
074: "Generate external type definitions.")
075: .word("o", "optionOutput", false,
076: "Specify the base name of the generated checker.")
077: .bool("printAST", "printAST", false,
078: "Print the AST of the of the pre-transformed program.")
079: .bool("printSymbolTable", "printSymbolTable", false,
080: "Print the symbol table.")
081: .bool("printSource", "printSource", false,
082: "Print the java source code of the generated checker.")
083: .bool("Oswitch", "optimizeMatch", false,
084: "Use switch statements and type tags for pattern matches.")
085: .bool("Ofold-let", "optimizeLet", false,
086: "Collapse let expressions where possible.")
087: .bool("Otype", "optimizeType", false,
088: "Eliminate type records, if not attributes are defined.")
089: .word("node", "optionNodeType", false,
090: "Specify the name of the node type.");
091: }
092:
093: public Node parse(Reader in, File file) throws IOException,
094: ParseException {
095: typicalName = file.toString();
096: TypicalParser parser = new TypicalParser(in, file.toString(),
097: (int) file.length());
098: return (Node) parser.value(parser.pModule(0));
099: }
100:
101: public void process(Node ast) {
102: //Check we should print the pre AST
103: if (runtime.test("printAST")) {
104: runtime.console().pln().format(ast).pln().flush();
105: }
106:
107: //It's a compilation run
108: GNode result_ast = null;
109: GNode types_ast = null;
110: GNode support_ast = null;
111:
112: String output = (String) runtime.getValue("optionOutput");
113: if (null == output) {
114: output = typicalName.substring(0, typicalName.length() - 5);
115: }
116:
117: String nodeType = (String) runtime.getValue("optionNodeType");
118: if (null == nodeType)
119: nodeType = "node";
120:
121: SymbolTable table = null;
122: TypicalAnalyzer analyzer = new TypicalAnalyzer(runtime,
123: nodeType);
124: table = analyzer.run(ast);
125:
126: if (0 < runtime.errorCount())
127: return;
128:
129: if (runtime.test("printSymbolTable")) {
130: if (null != table) {
131: Visitor visitor = runtime.console().visitor();
132: try {
133: table.root().dump(runtime.console());
134: } finally {
135: runtime.console().register(visitor);
136: }
137: runtime.console().flush();
138: } else {
139: runtime.error("symbol table not initialized");
140: runtime.exit();
141: }
142: }
143:
144: if (!runtime.test("optionCheckOnly")) {
145: Transformer transformer = null;
146: transformer = new Transformer((GNode) ast, table, output,
147: runtime);
148: transformer.run();
149: result_ast = transformer.getCheckerAST();
150: types_ast = transformer.getTypesAST();
151: support_ast = transformer.getSupportAST();
152:
153: //write type checker file
154: File dir = runtime.getFile(Runtime.OUTPUT_DIRECTORY);
155: File file = new File(dir, output + "Analyzer.java");
156: Printer out;
157: // Write the xxxAnalyzer.java file
158: if (!runtime.test("optionTypesOnly")) {
159: try {
160: out = new Printer(new PrintWriter(
161: new BufferedWriter(new FileWriter(file))));
162: } catch (IOException x) {
163: if (null == x.getMessage()) {
164: runtime.error(file.toString() + ": I/O error");
165: } else {
166: runtime.error(file.toString() + ": "
167: + x.getMessage());
168: }
169: return;
170: }
171: printHeader(out);
172: new JavaPrinter(out).dispatch(result_ast);
173: out.flush();
174: }
175:
176: // Write the xxxTypes.java
177: file = new File(dir, output + "Types.java");
178: try {
179: out = new Printer(new PrintWriter(new BufferedWriter(
180: new FileWriter(file))));
181: } catch (IOException x) {
182: if (null == x.getMessage()) {
183: runtime.error(file.toString() + ": I/O error");
184: } else {
185: runtime.error(file.toString() + ": "
186: + x.getMessage());
187: }
188: return;
189: }
190: printHeader(out);
191: new JavaPrinter(out).dispatch(types_ast);
192: out.flush();
193:
194: // Write the xxxSupport.java
195: file = new File(dir, output + "Support.java");
196: try {
197: out = new Printer(new PrintWriter(new BufferedWriter(
198: new FileWriter(file))));
199: } catch (IOException x) {
200: if (null == x.getMessage()) {
201: runtime.error(file.toString() + ": I/O error");
202: } else {
203: runtime.error(file.toString() + ": "
204: + x.getMessage());
205: }
206: return;
207: }
208: printHeader(out);
209: new JavaPrinter(out).dispatch(support_ast);
210: out.flush();
211: }
212:
213: if (runtime.test("printSource")) {
214: new JavaPrinter(runtime.console()).dispatch(result_ast);
215: runtime.console().flush();
216: }
217: }
218:
219: /** Run the compiler with the specified command line arguments. */
220: public static void main(String[] args) {
221: new Typical().run(args);
222: }
223: }
|