--- a
+++ b/trunk/Cm/Cm.Compiler/Main.cpp
@@ -0,0 +1,116 @@
+#include <Cm.Core/Namespace.hpp>
+#include <Cm.Core/BasicType.hpp>
+#include <Cm.Core/Assert.hpp>
+#include <Cm.Core/Error.hpp>
+#include <Cm.Core/Pointer.hpp>
+#include <Cm.Core/Util.hpp>
+#include <Cm.Core/ConversionTable.hpp>
+#include <Cm.Parser/SourceFile.hpp>
+#include <iostream>
+
+using Soul::Util::String;
+using Soul::Util::IntToString;
+using Soul::Util::ReadFile;
+
+String version = "0.1.0.0";
+
+using namespace Cm::Core;
+using namespace Cm::Parser;
+
+class InitDone
+{
+public:
+    InitDone()
+    {
+        NamespaceInit();
+        ConversionTableInit();
+        UtilInit();
+        BasicTypeInit();
+        PointerInit();
+        TypeInit();
+    }
+    ~InitDone()
+    {
+        TypeDone();
+        PointerDone();
+        BasicTypeDone();
+        UtilDone();
+        ConversionTableDone();
+        NamespaceDone();
+    }
+};
+
+int main(int argc, const char* argv[])
+{
+    std::vector<String> fileNames;
+    try
+    {
+        InitDone initDone;
+        std::cout << "Cmaj compiler version " << version << std::endl;
+        if (argc <= 1)
+        {
+            std::cout << "Usage: cmc [options] {file.cm}" << std::endl;
+            std::cout << "Options:\n";
+            std::cout << "-dp: debug parsing\n";
+        }
+        else
+        {
+            bool debugParse = false;
+            for (int i = 1; i < argc; ++i)
+            {
+                String arg = argv[i];
+                if (!arg.empty() && arg[0] == '-')
+                {
+                    if (arg == "-dp")
+                    {
+                        debugParse = true;
+                    }
+                }
+                else
+                {
+                    fileNames.push_back(arg);
+                }
+            }
+            SourceFileGrammarPtr sourceFile = SourceFile::Create();
+            if (debugParse)
+            {
+                sourceFile->SetLog(&std::cout);
+            }
+            std::vector<ScopePtr> fileScopes;
+            std::cout << "Parsing..." << std::endl;
+            int n = fileNames.size();
+            for (int i = 0; i < n; ++i)
+            {
+                String fileName = fileNames[i];
+                String content = ReadFile(fileName);
+                ScopePtr fileScope(new Scope(fileName, Position(), GlobalScope(), Scope::fileScope));
+                fileScopes.push_back(fileScope);
+                std::cout << "> " << fileName << std::endl;
+                sourceFile->Parse(content, 0, fileName, fileScope);
+            }
+            std::cout << "Type checking..." << std::endl;
+            GlobalScope()->TypeCheck();
+            for (int i = 0; i < n; ++i)
+            {
+                ScopePtr fileScope = fileScopes[i];
+                fileScope->TypeCheck();
+            }
+        }
+    }
+    catch (const Cm::Core::AssertionFailed& ex)
+    {
+        std::cout << ex.Message() << " in file " << ex.File() << " at line " << IntToString(ex.Line()) << std::endl;
+    }
+    catch (const Cm::Core::TypeCheckException& ex)
+    {
+        PrintError(T0 + ex.Number(), fileNames, ex);
+    }
+    catch (const std::exception& ex)
+    {
+        std::cout << ex.what() << std::endl;
+    }
+    catch (...)
+    {
+        std::cout << "other exception occurred" << std::endl;
+    }
+}