Implement full support for parsing primary expressions. We can now parse
[oota-llvm.git] / tools / llvm-mc / llvm-mc.cpp
1 //===-- llvm-mc.cpp - Machine Code Hacking Driver -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This utility is a simple driver that allows command line hacking on machine
11 // code.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/ManagedStatic.h"
17 #include "llvm/Support/MemoryBuffer.h"
18 #include "llvm/Support/PrettyStackTrace.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/System/Signals.h"
22 #include "AsmParser.h"
23 using namespace llvm;
24
25 static cl::opt<std::string>
26 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
27
28 static cl::opt<std::string>
29 OutputFilename("o", cl::desc("Output filename"),
30                cl::value_desc("filename"));
31
32 static cl::list<std::string>
33 IncludeDirs("I", cl::desc("Directory of include files"),
34             cl::value_desc("directory"), cl::Prefix);
35
36 enum ActionType {
37   AC_AsLex,
38   AC_Assemble
39 };
40
41 static cl::opt<ActionType>
42 Action(cl::desc("Action to perform:"),
43        cl::init(AC_Assemble),
44        cl::values(clEnumValN(AC_AsLex, "as-lex",
45                              "Lex tokens from a .s file"),
46                   clEnumValN(AC_Assemble, "assemble",
47                              "Assemble a .s file (default)"),
48                   clEnumValEnd));
49
50 static int AsLexInput(const char *ProgName) {
51   std::string ErrorMessage;
52   MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
53                                                       &ErrorMessage);
54   if (Buffer == 0) {
55     errs() << ProgName << ": ";
56     if (ErrorMessage.size())
57       errs() << ErrorMessage << "\n";
58     else
59       errs() << "input file didn't read correctly.\n";
60     return 1;
61   }
62
63   SourceMgr SrcMgr;
64   
65   // Tell SrcMgr about this buffer, which is what TGParser will pick up.
66   SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
67   
68   // Record the location of the include directories so that the lexer can find
69   // it later.
70   SrcMgr.setIncludeDirs(IncludeDirs);
71
72   AsmLexer Lexer(SrcMgr);
73   
74   bool Error = false;
75   
76   asmtok::TokKind Tok = Lexer.Lex();
77   while (Tok != asmtok::Eof) {
78     switch (Tok) {
79     default:
80       Lexer.PrintMessage(Lexer.getLoc(), "driver: unknown token");
81       Error = true;
82       break;
83     case asmtok::Error:
84       Error = true; // error already printed.
85       break;
86     case asmtok::Identifier:
87       outs() << "identifier: " << Lexer.getCurStrVal() << '\n';
88       break;
89     case asmtok::Register:
90       outs() << "register: " << Lexer.getCurStrVal() << '\n';
91       break;
92     case asmtok::String:
93       outs() << "string: " << Lexer.getCurStrVal() << '\n';
94       break;
95     case asmtok::IntVal:
96       outs() << "int: " << Lexer.getCurIntVal() << '\n';
97       break;
98     case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break;
99     case asmtok::Colon:  outs() << "Colon\n"; break;
100     case asmtok::Plus:   outs() << "Plus\n"; break;
101     case asmtok::Minus:  outs() << "Minus\n"; break;
102     case asmtok::Tilde:  outs() << "Tilde\n"; break;
103     case asmtok::Slash:  outs() << "Slash\n"; break;
104     case asmtok::LParen: outs() << "LParen\n"; break;
105     case asmtok::RParen: outs() << "RParen\n"; break;
106     case asmtok::Star:   outs() << "Star\n"; break;
107     case asmtok::Comma:  outs() << "Comma\n"; break;
108     case asmtok::Dollar: outs() << "Dollar\n"; break;
109     }
110     
111     Tok = Lexer.Lex();
112   }
113   
114   return Error;
115 }
116
117 static int AssembleInput(const char *ProgName) {
118   std::string ErrorMessage;
119   MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
120                                                       &ErrorMessage);
121   if (Buffer == 0) {
122     errs() << ProgName << ": ";
123     if (ErrorMessage.size())
124       errs() << ErrorMessage << "\n";
125     else
126       errs() << "input file didn't read correctly.\n";
127     return 1;
128   }
129   
130   SourceMgr SrcMgr;
131   
132   // Tell SrcMgr about this buffer, which is what TGParser will pick up.
133   SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
134   
135   // Record the location of the include directories so that the lexer can find
136   // it later.
137   SrcMgr.setIncludeDirs(IncludeDirs);
138   
139   AsmParser Parser(SrcMgr);
140   return Parser.Run();
141 }  
142
143
144 int main(int argc, char **argv) {
145   // Print a stack trace if we signal out.
146   sys::PrintStackTraceOnErrorSignal();
147   PrettyStackTraceProgram X(argc, argv);
148   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
149   cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
150
151   switch (Action) {
152   default:
153   case AC_AsLex:
154     return AsLexInput(argv[0]);
155   case AC_Assemble:
156     return AssembleInput(argv[0]);
157   }
158   
159   return 0;
160 }
161