Add the symbol type to SLIR

This commit is contained in:
Sameer Rahmani 2022-01-18 19:45:30 +00:00
parent c63425485c
commit 656adafd7e
7 changed files with 241 additions and 5 deletions

4
.gitignore vendored
View File

@ -23,4 +23,6 @@ bin/serenec_CXX_cotire.cmake
/config.h
docs/Doxyfile.docs
.ccache/
.ccache/
docs/spec.tex
docs/spec.pdf

42
docs/spec.org Normal file
View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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);
}