00001: package clogs; 00002: 00003: import java.io.File; 00004: import java.io.FileInputStream; 00005: import java.io.FileWriter; 00006: import java.io.PrintWriter; 00007: 00008: import javax.xml.parsers.DocumentBuilder; 00009: import javax.xml.parsers.DocumentBuilderFactory; 00010: import javax.xml.parsers.ParserConfigurationException; 00011: 00012: import org.xml.sax.InputSource; 00013: import org.xml.sax.SAXException; 00014: import org.xml.sax.SAXParseException; 00015: 00016: import org.w3c.dom.Document; 00017: import org.w3c.dom.Element; 00018: import org.w3c.dom.NodeList; 00019: 00020: import clogs.parser.*; 00021: import clogs.ast.*; 00022: import clogs.codegen.*; 00023: import clogs.staticanalysis.TypeCheck; 00024: import clogs.staticanalysis.WellFormedCheck; 00025: import clogs.transform.*; 00026: import clogs.util.*; 00027: import java_cup.runtime.*; 00028: 00029: 00030: public class Driver 00031: { 00032: public static void main (String[] args) 00033: throws Exception 00034: { 00035: String phasesConfigFilename = "config/default.xml"; 00036: if (args.length > 1) { 00037: phasesConfigFilename = args[1]; 00038: } 00039: 00040: compile (args[0], "clogs-output.s", phasesConfigFilename); 00041: } 00042: 00043: 00044: public static void compile (String clogsSourceFilename, String clogsTargetFilename, String phasesConfigFilename) 00045: throws Exception 00046: { 00047: List<ExtDecl> edecls = parse (clogsSourceFilename); 00048: // print(edecls); 00049: List<FunDefSig> externals = getExternals (); 00050: List<Factory<Phase>> phases = loadPhases (phasesConfigFilename); 00051: edecls = runPhases (phases, edecls, externals); 00052: generateCode (edecls, clogsTargetFilename); 00053: } 00054: 00055: 00056: public static List<ExtDecl> parse (String clogsSourceFilename) 00057: throws Exception 00058: { 00059: SymbolFactory sf = new ComplexSymbolFactory (); 00060: ClogsLexer lexer = new ClogsLexer (new FileInputStream (clogsSourceFilename), sf); 00061: ClogsParser parser = new ClogsParser (lexer, sf); 00062: Symbol symbol = parser.parse (); 00063: List<ExtDecl> edecls = (List<ExtDecl>) symbol.value; 00064: return edecls; 00065: } 00066: 00067: 00068: static List<FunDefSig> getExternals () 00069: { 00070: List<FunDefSig> externals = List.<FunDefSig>nil (); 00071: { 00072: List<Decl> decls = List.nil (); 00073: decls = decls.snoc (new Decl (new TypeArray (new TypeInt ()), "array", new Optional<Exp> ())); 00074: externals = externals.snoc (new FunDefSig (new TypeVoid (), "_print_array", decls)); 00075: } 00076: { 00077: List<Decl> decls = List.nil (); 00078: decls = decls.snoc (new Decl (new TypeInt (), "n", new Optional<Exp> ())); 00079: externals = externals.snoc (new FunDefSig (new TypeVoid (), "_print_char", decls)); 00080: } 00081: { 00082: List<Decl> decls = List.nil (); 00083: decls = decls.snoc (new Decl (new TypeInt (), "n", new Optional<Exp> ())); 00084: externals = externals.snoc (new FunDefSig (new TypeVoid (), "_print_int", decls)); 00085: } 00086: { 00087: List<Decl> decls = List.nil (); 00088: externals = externals.snoc (new FunDefSig (new TypeVoid (), "_print_newline", decls)); 00089: } 00090: 00091: return externals; 00092: } 00093: 00094: 00095: public static List<Factory<Phase>> loadPhases (String phasesConfigFilename) 00096: throws Exception 00097: { 00098: String url = new File (phasesConfigFilename).getAbsoluteFile ().toURI ().toURL ().toString (); 00099: InputSource inputSource = new InputSource (url); 00100: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance (); 00101: dbf.setValidating (false); 00102: DocumentBuilder db = dbf.newDocumentBuilder (); 00103: Document document = db.parse (inputSource); 00104: 00105: List<Factory<Phase>> phases = List.nil (); 00106: NodeList nl = document.getElementsByTagName ("phase"); 00107: for (int i = 0; i < nl.getLength (); i++) { 00108: Element phaseElt = (Element) nl.item (i); 00109: String className = phaseElt.getAttribute ("name"); 00110: boolean printAfterTransform = Boolean.parseBoolean (phaseElt.getAttribute ("printAfterTransform")); 00111: boolean printAfterTransformAndTypeCheck = Boolean.parseBoolean (phaseElt.getAttribute ("printAfterTransformAndTypeCheck")); 00112: phases = phases.snoc (createPhaseFactory (className, printAfterTransform, printAfterTransformAndTypeCheck)); 00113: } 00114: 00115: return phases; 00116: } 00117: 00118: 00119: static Factory<Phase> createPhaseFactory (final String className, final boolean printAfterTransform, final boolean printAfterTransformAndTypeCheck) 00120: { 00121: return new Factory<Phase> () 00122: { 00123: public Phase newInstance () 00124: { 00125: Phase p; 00126: try { 00127: Class<Phase> clazz = (Class<Phase>) Class.forName (className); 00128: p = clazz.newInstance (); 00129: } catch (Exception e) { 00130: throw new RuntimeException (e); 00131: } 00132: p.printAfterTransform = printAfterTransform; 00133: p.printAfterTransformAndTypeCheck = printAfterTransformAndTypeCheck; 00134: return p; 00135: } 00136: }; 00137: } 00138: 00139: 00140: static List<ExtDecl> runPhases (List<Factory<Phase>> phases, List<ExtDecl> edecls, List<FunDefSig> externals) 00141: { 00142: for (Factory<Phase> factory : phases) { 00143: Phase p = factory.newInstance (); 00144: edecls = p.transform (edecls); 00145: if (p.printAfterTransform) { 00146: System.out.println ("RESULT OF: " + p.getClass ().getName ()); 00147: print (edecls); separator (); 00148: } 00149: edecls = check (edecls, externals); 00150: if (p.printAfterTransformAndTypeCheck) { 00151: System.out.println ("TYPECHECKED RESULT OF: " + p.getClass ().getName ()); 00152: print (edecls); separator (); 00153: } 00154: } 00155: return edecls; 00156: } 00157: 00158: 00159: static void separator () 00160: { 00161: System.out.println (); 00162: System.out.println ("======================================="); 00163: System.out.println (); 00164: } 00165: 00166: 00167: static void print (List<ExtDecl> edecls) 00168: { 00169: //PrettyPrinter pp = new PrettyPrinter (); 00170: AnotherPrinter pp = new AnotherPrinter (); 00171: pp.printExtDecls (edecls); 00172: System.out.println (pp); 00173: } 00174: 00175: 00176: static List<ExtDecl> check (List<ExtDecl> edecls, List<FunDefSig> externals) 00177: { 00178: try { 00179: new WellFormedCheck (edecls, externals).check (); 00180: edecls = new TypeCheck (edecls, externals).check (); 00181: } catch (Exception e) { 00182: e.printStackTrace (); 00183: System.exit (1); 00184: } 00185: return edecls; 00186: } 00187: 00188: 00189: public static void generateCode (List<ExtDecl> edecls, String clogsTargetFilename) 00190: throws Exception 00191: { 00192: FileWriter fw = new FileWriter (clogsTargetFilename); 00193: PrintWriter pw = new PrintWriter (fw); 00194: new CodeGen (edecls, pw).generate (); 00195: pw.close (); 00196: fw.close (); 00197: } 00198: } 00199: