Add the symbol type to SLIR
This commit is contained in:
parent
c63425485c
commit
656adafd7e
|
@ -23,4 +23,6 @@ bin/serenec_CXX_cotire.cmake
|
|||
/config.h
|
||||
|
||||
docs/Doxyfile.docs
|
||||
.ccache/
|
||||
.ccache/
|
||||
docs/spec.tex
|
||||
docs/spec.pdf
|
|
@ -0,0 +1,42 @@
|
|||
#+TITLE: Serene's Language Specification
|
||||
#+AUTHOR: Sameer Rahmani
|
||||
#+SEQ_TODO: TODO(t/!) | DONE(d%)
|
||||
#+TAGS:
|
||||
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty nolatexpreview
|
||||
#+OPTIONS: tex:t
|
||||
#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Eule
|
||||
# book style has to be remapped to koma scripts scrbook
|
||||
#+LATEX_CLASS: book
|
||||
#+LATEX_HEADER: \usepackage[english]{babel}
|
||||
#+LATEX_CLASS_OPTIONS: [fontsize=11pt,paper=a5, pagesize=auto]
|
||||
#+LATEX_HEADER: \KOMAoptions{fontsize=11pt}
|
||||
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
|
||||
#+LATEX_HEADER: \usepackage{microtype}
|
||||
#+LATEX_HEADER: \usepackage{pxfonts}
|
||||
|
||||
#+LATEX_HEADER: \usepackage{amsmath}
|
||||
#+LATEX_HEADER: \usepackage{amssymb}
|
||||
#+LATEX_HEADER: \usepackage{mathabx}
|
||||
|
||||
#+LATEX_HEADER: \usepackage{tcolorbox}
|
||||
#+LATEX_HEADER: \setlength{\parskip}{1em}
|
||||
|
||||
#+LATEX_HEADER: \newtcolorbox{infobox}[2][]{colback=cyan!5!white,before skip=14pt,after skip=8pt,colframe=cyan!75!black,sharp corners,title={#2},#1}
|
||||
#+LATEX_HEADER: \newcommand\tab[1][1cm]{\hspace*{#1}}
|
||||
#+LATEX_HEADER: \let\oldsection\section
|
||||
#+LATEX_HEADER: \newcommand\caution[1]{\textcolor{blue}{\textbf{#1}}}
|
||||
#+LATEX_HEADER: \renewcommand\section{\pagebreak\oldsection}
|
||||
#+LATEX_HEADER: \hypersetup{hidelinks}
|
||||
|
||||
#+LATEX_HEADER: \renewcommand{\contentsname}{Serene's Spec}
|
||||
|
||||
\clearpage\null\newpage
|
||||
|
||||
\chapter{Overview of Serene}
|
||||
|
||||
* Basic Types
|
||||
|
||||
* Unsorted
|
||||
** Eval
|
||||
Evaluating any form using =eval= will add the form to the namespace containing the
|
||||
=eval= expression.
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef SERENE_SLIR_DIALECT_H
|
||||
#define SERENE_SLIR_DIALECT_H
|
||||
|
||||
#include <llvm/ADT/TypeSwitch.h>
|
||||
#include <mlir/IR/BuiltinOps.h>
|
||||
#include <mlir/IR/Dialect.h>
|
||||
#include <mlir/Interfaces/ControlFlowInterfaces.h>
|
||||
|
@ -26,12 +27,12 @@
|
|||
// Include the auto-generated header file containing the declaration of the
|
||||
// serene's dialect.
|
||||
#include "serene/slir/dialect.h.inc"
|
||||
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#include "serene/slir/types.h.inc"
|
||||
// Include the auto-generated header file containing the declarations of the
|
||||
// serene's operations.
|
||||
// for more on GET_OP_CLASSES: https://mlir.llvm.org/docs/OpDefinitions/
|
||||
#define GET_OP_CLASSES
|
||||
|
||||
#include "serene/slir/ops.h.inc"
|
||||
|
||||
#endif // SERENE_SLIR_DIALECT_H
|
||||
|
|
|
@ -22,6 +22,7 @@ def Serene_Dialect : Dialect {
|
|||
This dialect tries to map the special forms of a lisp into
|
||||
IR level operations.
|
||||
}];
|
||||
let useDefaultTypePrinterParser = 1;
|
||||
}
|
||||
|
||||
// Base class for Serene dialect operations. This operation inherits from the base
|
||||
|
@ -37,6 +38,22 @@ class Serene_Op<string mnemonic, list<OpTrait> traits = []> :
|
|||
class Serene_Type<string name> : TypeDef<Serene_Dialect, name> { }
|
||||
|
||||
|
||||
def SereneSymbol : Serene_Type<"Symbol"> {
|
||||
let mnemonic = "symbol";
|
||||
|
||||
let summary = "A Lisp symbol type";
|
||||
|
||||
let description = [{
|
||||
A Lisp symbol type
|
||||
}];
|
||||
|
||||
let parameters = (ins "std::string":$ns, "std::string":$name);
|
||||
let assemblyFormat = "`<` $ns `,` $name `>`";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
def ValueOp: Serene_Op<"value"> {
|
||||
|
||||
let summary = "This operation represent a value";
|
||||
|
@ -58,6 +75,20 @@ def ValueOp: Serene_Op<"value"> {
|
|||
];
|
||||
}
|
||||
|
||||
// Def
|
||||
def DefOp: Serene_Op<"def"> {
|
||||
|
||||
let summary = "This operation defines a global binding";
|
||||
let description = [{
|
||||
DefOp
|
||||
}];
|
||||
|
||||
let arguments = (ins TypeAttr:$type,
|
||||
StrAttr:$name,
|
||||
OptionalAttr<StrAttr>:$sym_visibility);
|
||||
|
||||
let results = (outs SereneSymbol);
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add the FunctionLike trait here and include its header file in dialect.h
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/* -*- C++ -*-
|
||||
* Serene Programming Language
|
||||
*
|
||||
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// SereneSymbol is the Symbil type in SLIT that represents an expr::Sympol
|
||||
|
||||
#ifndef SERENE_SLIR_SYMBOL_H
|
||||
#define SERENE_SLIR_SYMBOL_H
|
||||
|
||||
#include <llvm/Support/ErrorHandling.h>
|
||||
#include <mlir/IR/TypeSupport.h>
|
||||
|
||||
namespace serene {
|
||||
namespace slir {
|
||||
namespace detail {
|
||||
/// This is the storage class for the `SymbolType` (SereneSymbol in ODS)
|
||||
// class SymbolTypeStorage : public mlir::TypeStorage {
|
||||
// using KeyTy = std::string;
|
||||
|
||||
// SymbolTypeStorage(std::string &ns, std::string &name) : ns(ns), name(name)
|
||||
// {} SymbolTypeStorage(const KeyTy &k) {
|
||||
|
||||
// auto partDelimiter = k.find('/');
|
||||
// if (partDelimiter == std::string::npos) {
|
||||
// llvm::llvm_unreachable_internal("SLIR symbol has to have NS");
|
||||
// } else {
|
||||
// name = k.substr(partDelimiter + 1, k.size());
|
||||
// ns = k.substr(0, partDelimiter);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// The hash key for this storage is a pair of the integer and type params.
|
||||
|
||||
// /// Define the comparison function for the key type.
|
||||
// bool operator==(const KeyTy &key) const {
|
||||
// // TODO: Use formatv to concat strings
|
||||
// return key == ns + "/" + name;
|
||||
// }
|
||||
|
||||
// static llvm::hash_code hashKey(const KeyTy &key) {
|
||||
// return llvm::hash_combine(key);
|
||||
// }
|
||||
|
||||
// /// Define a construction function for the key type.
|
||||
// /// Note: This isn't necessary because KeyTy can be directly constructed
|
||||
// with
|
||||
// /// the given parameters.
|
||||
// static KeyTy getKey(std::string &ns, std::string &name) {
|
||||
// // TODO: Use formatv to concat strings
|
||||
// return KeyTy(ns + "/" + name);
|
||||
// }
|
||||
|
||||
// /// Define a construction method for creating a new instance of this
|
||||
// storage. static SymbolTypeStorage *construct(mlir::TypeStorageAllocator
|
||||
// &allocator,
|
||||
// const KeyTy &key) {
|
||||
// return new (allocator.allocate<SymbolTypeStorage>())
|
||||
// SymbolTypeStorage(key);
|
||||
// }
|
||||
|
||||
// std::string ns;
|
||||
// std::string name;
|
||||
// };
|
||||
}; // namespace detail
|
||||
}; // namespace slir
|
||||
}; // namespace serene
|
||||
#endif
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
#include <mlir/IR/Builders.h>
|
||||
#include <mlir/IR/BuiltinTypes.h>
|
||||
#include <mlir/IR/OpImplementation.h>
|
||||
#include <mlir/IR/Dialect.h>
|
||||
#include <mlir/IR/DialectImplementation.h>
|
||||
#include <mlir/IR/MLIRContext.h>
|
||||
|
||||
namespace serene {
|
||||
namespace slir {
|
||||
|
@ -33,10 +35,87 @@ void SereneDialect::initialize() {
|
|||
#define GET_OP_LIST
|
||||
#include "serene/slir/ops.cpp.inc"
|
||||
>();
|
||||
addTypes<
|
||||
#define GET_TYPEDEF_LIST
|
||||
#include "serene/slir/types.cpp.inc"
|
||||
>();
|
||||
}
|
||||
|
||||
// static SymbolType parseSymbolType(mlir::MLIRContext &ctx,
|
||||
// mlir::AsmParser &parser) {
|
||||
// llvm::SMLoc loc = parser.getCurrentLocation();
|
||||
// if (parser.parseLess()) {
|
||||
// return SymbolType();
|
||||
// }
|
||||
// std::string fqsym;
|
||||
// if(parser.parseString(&fqsym)) {
|
||||
|
||||
// }
|
||||
// };
|
||||
|
||||
// /// Parses a type appearing inside another LLVM dialect-compatible type. This
|
||||
// /// will try to parse any type in full form (including types with the `!llvm`
|
||||
// /// prefix), and on failure fall back to parsing the short-hand version of
|
||||
// the
|
||||
// /// LLVM dialect types without the `!llvm` prefix.
|
||||
// static mlir::Type dispatchParse(mlir::AsmParser &parser, bool allowAny =
|
||||
// true) {
|
||||
// llvm::SMLoc keyLoc = parser.getCurrentLocation();
|
||||
|
||||
// // Try parsing any MLIR type.
|
||||
// mlir::Type type;
|
||||
// mlir::OptionalParseResult result = parser.parseOptionalType(type);
|
||||
|
||||
// if (result.hasValue()) {
|
||||
// if (failed(result.getValue())) {
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// if (!allowAny) {
|
||||
// parser.emitError(keyLoc) << "unexpected type, expected keyword";
|
||||
// return nullptr;
|
||||
// }
|
||||
// return type;
|
||||
// }
|
||||
|
||||
// // If no type found, fallback to the shorthand form.
|
||||
// llvm::StringRef key;
|
||||
|
||||
// if (failed(parser.parseKeyword(&key))) {
|
||||
// return mlir::Type();
|
||||
// }
|
||||
|
||||
// mlir::MLIRContext *ctx = parser.getContext();
|
||||
// return mlir::StringSwitch<mlir::function_ref<mlir::Type()>>(key)
|
||||
// .Case("symbol", [&] { return parseSymbolType(ctx, parser); })
|
||||
// .Default([&] {
|
||||
// parser.emitError(keyLoc) << "unknown LLVM type: " << key;
|
||||
// return mlir::Type();
|
||||
// })();
|
||||
// }
|
||||
// //.Case("struct", [&] { return parseStructType(parser); })
|
||||
// /// Parse an instance of a type registered to the dialect.
|
||||
// mlir::Type SereneDialect::parseType(mlir::DialectAsmParser &parser) const {
|
||||
// llvm::SMLoc loc = parser.getCurrentLocation();
|
||||
// mlir::Type type = dispatchParse(parser, /*allowAny=*/false);
|
||||
// if (!type) {
|
||||
// return type;
|
||||
// }
|
||||
// if (!isCompatibleOuterType(type)) {
|
||||
// parser.emitError(loc) << "unexpected type, expected keyword";
|
||||
// return nullptr;
|
||||
// }
|
||||
// return type;
|
||||
// };
|
||||
|
||||
// // /// Print an instance of a type registered to the dialect.
|
||||
// void SereneDialect::printType(
|
||||
// mlir::Type type, mlir::DialectAsmPrinter &printer) const override{};
|
||||
|
||||
} // namespace slir
|
||||
} // namespace serene
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#include "serene/slir/types.cpp.inc"
|
||||
|
||||
#define GET_OP_CLASSES
|
||||
#include "serene/slir/ops.cpp.inc"
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace serene::slir {
|
|||
auto file = ns.filename;
|
||||
std::string filename{file.getValueOr("REPL")};
|
||||
|
||||
return mlir::FileLineColLoc::get(builder.getIdentifier(filename), loc.line,
|
||||
return mlir::FileLineColLoc::get(builder.getStringAttr(filename), loc.line,
|
||||
loc.col);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue