brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · a60738d Raw
147 lines · cpp
1//===- toyc.cpp - The Toy Compiler ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the entry point for the Toy compiler.10//11//===----------------------------------------------------------------------===//12 13#include "toy/AST.h"14#include "toy/Dialect.h"15#include "toy/Lexer.h"16#include "toy/MLIRGen.h"17#include "toy/Parser.h"18#include <memory>19#include <string>20#include <system_error>21#include <utility>22 23#include "mlir/IR/AsmState.h"24#include "mlir/IR/BuiltinOps.h"25#include "mlir/IR/MLIRContext.h"26#include "mlir/Parser/Parser.h"27 28#include "llvm/ADT/StringRef.h"29#include "llvm/Support/CommandLine.h"30#include "llvm/Support/ErrorOr.h"31#include "llvm/Support/MemoryBuffer.h"32#include "llvm/Support/SourceMgr.h"33#include "llvm/Support/raw_ostream.h"34 35using namespace toy;36namespace cl = llvm::cl;37 38static cl::opt<std::string> inputFilename(cl::Positional,39                                          cl::desc("<input toy file>"),40                                          cl::init("-"),41                                          cl::value_desc("filename"));42 43namespace {44enum InputType { Toy, MLIR };45} // namespace46static cl::opt<enum InputType> inputType(47    "x", cl::init(Toy), cl::desc("Decided the kind of output desired"),48    cl::values(clEnumValN(Toy, "toy", "load the input file as a Toy source.")),49    cl::values(clEnumValN(MLIR, "mlir",50                          "load the input file as an MLIR file")));51 52namespace {53enum Action { None, DumpAST, DumpMLIR };54} // namespace55static cl::opt<enum Action> emitAction(56    "emit", cl::desc("Select the kind of output desired"),57    cl::values(clEnumValN(DumpAST, "ast", "output the AST dump")),58    cl::values(clEnumValN(DumpMLIR, "mlir", "output the MLIR dump")));59 60/// Returns a Toy AST resulting from parsing the file or a nullptr on error.61static std::unique_ptr<toy::ModuleAST>62parseInputFile(llvm::StringRef filename) {63  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileOrErr =64      llvm::MemoryBuffer::getFileOrSTDIN(filename);65  if (std::error_code ec = fileOrErr.getError()) {66    llvm::errs() << "Could not open input file: " << ec.message() << "\n";67    return nullptr;68  }69  auto buffer = fileOrErr.get()->getBuffer();70  LexerBuffer lexer(buffer.begin(), buffer.end(), std::string(filename));71  Parser parser(lexer);72  return parser.parseModule();73}74 75static int dumpMLIR() {76  mlir::MLIRContext context;77  // Load our Dialect in this MLIR Context.78  context.getOrLoadDialect<mlir::toy::ToyDialect>();79 80  // Handle '.toy' input to the compiler.81  if (inputType != InputType::MLIR &&82      !llvm::StringRef(inputFilename).ends_with(".mlir")) {83    auto moduleAST = parseInputFile(inputFilename);84    if (!moduleAST)85      return 6;86    mlir::OwningOpRef<mlir::ModuleOp> module = mlirGen(context, *moduleAST);87    if (!module)88      return 1;89 90    module->dump();91    return 0;92  }93 94  // Otherwise, the input is '.mlir'.95  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileOrErr =96      llvm::MemoryBuffer::getFileOrSTDIN(inputFilename);97  if (std::error_code ec = fileOrErr.getError()) {98    llvm::errs() << "Could not open input file: " << ec.message() << "\n";99    return -1;100  }101 102  // Parse the input mlir.103  llvm::SourceMgr sourceMgr;104  sourceMgr.AddNewSourceBuffer(std::move(*fileOrErr), llvm::SMLoc());105  mlir::OwningOpRef<mlir::ModuleOp> module =106      mlir::parseSourceFile<mlir::ModuleOp>(sourceMgr, &context);107  if (!module) {108    llvm::errs() << "Error can't load file " << inputFilename << "\n";109    return 3;110  }111 112  module->dump();113  return 0;114}115 116static int dumpAST() {117  if (inputType == InputType::MLIR) {118    llvm::errs() << "Can't dump a Toy AST when the input is MLIR\n";119    return 5;120  }121 122  auto moduleAST = parseInputFile(inputFilename);123  if (!moduleAST)124    return 1;125 126  dump(*moduleAST);127  return 0;128}129 130int main(int argc, char **argv) {131  // Register any command line options.132  mlir::registerAsmPrinterCLOptions();133  mlir::registerMLIRContextCLOptions();134  cl::ParseCommandLineOptions(argc, argv, "toy compiler\n");135 136  switch (emitAction) {137  case Action::DumpAST:138    return dumpAST();139  case Action::DumpMLIR:140    return dumpMLIR();141  default:142    llvm::errs() << "No action specified (parsing only?), use -emit=<action>\n";143  }144 145  return 0;146}147