blob: 58ef8d710bb25a3390fb3007dc73cb03713e5780 [file] [log] [blame]
Chris Lattner767a1e42003-11-23 18:01:26 +00001//===--- stkrc.cpp --- The Stacker Compiler -------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and donated to the LLVM research
6// group and is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10//
11// This is the "main" program for the Stacker Compiler. It is simply a utility
12// that invokes the StackerCompiler::compile method (see StackerCompiler.cpp)
13//
14// To get help using this utility, you can invoke it with:
15// stkrc --help - Output information about command line switches
16//
17//
18//===------------------------------------------------------------------------===
19
20#include "../../lib/compiler/StackerCompiler.h"
21#include "llvm/Assembly/Parser.h"
22#include "llvm/Bytecode/Writer.h"
23#include "llvm/Analysis/Verifier.h"
24#include "Support/CommandLine.h"
Chris Lattner6f9e6072004-05-27 05:37:32 +000025#include "llvm/System/Signals.h"
Chris Lattner767a1e42003-11-23 18:01:26 +000026#include <fstream>
Reid Spencer321f8312004-07-04 12:22:14 +000027#include <iostream>
Chris Lattner767a1e42003-11-23 18:01:26 +000028#include <memory>
29
30using namespace llvm;
31
32static cl::opt<std::string>
33InputFilename(cl::Positional, cl::desc("<input .st file>"), cl::init("-"));
34
35static cl::opt<std::string>
36OutputFilename("o", cl::desc("Override output filename"),
37 cl::value_desc("filename"));
38
39static cl::opt<bool>
40Force("f", cl::desc("Overwrite output files"));
41
42static cl::opt<bool>
43DumpAsm("d", cl::desc("Print LLVM Assembly as parsed"), cl::Hidden);
44
45static cl::opt<uint32_t>
46StackSize("s", cl::desc("Specify program maximum stack size"),
47 cl::value_desc("stacksize"));
48
49#ifdef PARSE_DEBUG
50static cl::opt<bool>
51ParseDebug("g", cl::desc("Turn on Bison Debugging"), cl::Hidden);
52#endif
53
54#ifdef FLEX_DEBUG
55static cl::opt<bool>
56FlexDebug("x", cl::desc("Turn on Flex Debugging"), cl::Hidden);
57#endif
58
59static cl::opt<bool>
60EchoSource("e", cl::desc("Print Stacker Source as parsed"),
61 cl::value_desc("echo"));
62
63int main(int argc, char **argv)
64{
65 cl::ParseCommandLineOptions(argc, argv, " stacker .st -> .bc compiler\n");
66
67 std::ostream *Out = 0;
68 StackerCompiler compiler;
69 try
70 {
71#ifdef PARSE_DEBUG
72 {
73 extern int Stackerdebug;
74 Stackerdebug = ParseDebug;
75 }
76#endif
77#ifdef FLEX_DEBUG
78 {
79 extern int Stacker_flex_debug;
80 Stacker_flex_debug = FlexDebug;
81 }
82#endif
83 // Parse the file now...
84
85 std::auto_ptr<Module> M (
86 compiler.compile(InputFilename,EchoSource, 1024) );
87 if (M.get() == 0) {
88 std::cerr << argv[0] << ": assembly didn't read correctly.\n";
89 return 1;
90 }
91
92 if (verifyModule(*M.get())) {
93 std::cerr << argv[0]
94 << ": assembly parsed, but does not verify as correct!\n";
95 return 1;
96 }
97
98 if (DumpAsm) std::cerr << "Here's the assembly:\n" << M.get();
99
100 if (OutputFilename != "") { // Specified an output filename?
101 if (OutputFilename != "-") { // Not stdout?
102 if (!Force && std::ifstream(OutputFilename.c_str())) {
103 // If force is not specified, make sure not to overwrite a file!
104 std::cerr << argv[0] << ": error opening '" << OutputFilename
105 << "': file exists!\n"
106 << "Use -f command line argument to force output\n";
107 return 1;
108 }
109 Out = new std::ofstream(OutputFilename.c_str());
110 } else { // Specified stdout
111 Out = &std::cout;
112 }
113 } else {
114 if (InputFilename == "-") {
115 OutputFilename = "-";
116 Out = &std::cout;
117 } else {
118 std::string IFN = InputFilename;
119 int Len = IFN.length();
120 if (IFN[Len-3] == '.' && IFN[Len-2] == 's' && IFN[Len-1] == 't') {
121 // Source ends in .ll
122 OutputFilename = std::string(IFN.begin(), IFN.end()-3);
123 } else {
124 OutputFilename = IFN; // Append a .bc to it
125 }
126 OutputFilename += ".bc";
127
128 if (!Force && std::ifstream(OutputFilename.c_str())) {
129 // If force is not specified, make sure not to overwrite a file!
130 std::cerr << argv[0] << ": error opening '" << OutputFilename
131 << "': file exists!\n"
132 << "Use -f command line argument to force output\n";
133 return 1;
134 }
135
136 Out = new std::ofstream(OutputFilename.c_str());
137 // Make sure that the Out file gets unlinked from the disk if we get a
138 // SIGINT
139 RemoveFileOnSignal(OutputFilename);
140 }
141 }
142
143 if (!Out->good()) {
144 std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
145 return 1;
146 }
147
148 WriteBytecodeToFile(M.get(), *Out);
149 } catch (const ParseException &E) {
150 std::cerr << argv[0] << ": " << E.getMessage() << "\n";
151 return 1;
152 }
153
154 if (Out != &std::cout) delete Out;
155 return 0;
156}