Tidy up the target files for episode 7

This commit is contained in:
Sameer Rahmani 2021-08-21 18:46:49 +01:00
parent a1d3ae8c9c
commit 36b95fe1e5
5 changed files with 58 additions and 7 deletions

View File

@ -118,7 +118,9 @@ in python.
*** TODO Error handling
Create proper error handling for the internal infra
*** TODO Replace =llvm::outs()= with debug statements
* ** TODO Move the generatable logic out of its files and remove them
*** TODO Move the generatable logic out of its files and remove them
*** TODO Add a CLI option to get any extra pass
*** TODO Add support for =sourcemgr= for input files
*** TODO Language Spec :DOCS:
*** TODO A proper List implementation
*** TODO Vector implementation

View File

@ -130,7 +130,8 @@ a data structure describing the syntax.
- Expressions vs Statements
- Serene(Lisp) and expressions
** Node & AST
* Episode 6 - The Semantic Analyzer
* DONE Episode 6 - The Semantic Analyzer
CLOSED: [2021-08-21 Sat 18:44]
** Qs
- Why didn't we implement a linked list?
- Why we are using the =std::vector= instead of llvm collections?
@ -158,3 +159,13 @@ We need to reform the AST to reflect the semantics of Serene closly.
Let's run the compiler to see the semantic analysis in action.
** Let's check out the code
* Episode 7 - The Context and Namespace
** Namespaces
*** Unit of compilation
*** Usually maps to a file
*** keeps the state and evironment
** SereneContext vs LLVM Context vs MLIR Context
*** Compilers global state
*** The owner of LLVM/MLIR contexts
*** Holds the namespace table
*** Probably will contain the primitive types as well

View File

@ -79,8 +79,11 @@ public:
/// will fail if the namespace does not exist in the namespace table.
bool setCurrentNS(llvm::StringRef ns_name);
/// Return the current namespace that is being processed at the moment
std::shared_ptr<Namespace> getCurrentNS();
/// Lookup the namespace with the give name in the current context and
/// return a shared pointer to it or a `nullptr` in it doesn't exist.
std::shared_ptr<Namespace> getNS(llvm::StringRef ns_name);
SereneContext()
@ -89,15 +92,24 @@ public:
mlirContext.getOrLoadDialect<mlir::StandardOpsDialect>();
// TODO: Get the crash report path dynamically from the cli
// pm.enableCrashReproducerGeneration("/home/lxsameer/mlir.mlir");
// TODO: Set the target triple with respect to the CLI args
targetTriple = llvm::sys::getDefaultTargetTriple();
};
/// Set the target compilation phase of the compiler. The compilation
/// phase dictates the behavior and the output type of the compiler.
void setOperationPhase(CompilationPhase phase);
CompilationPhase getTargetPhase() { return targetPhase; };
int getOptimizatioLevel();
private:
CompilationPhase targetPhase;
// The namespace table. Every namespace that needs to be compiled has
// to register itself with the context and appear on this table.
// This table acts as a cache as well.
std::map<std::string, std::shared_ptr<Namespace>> namespaces;
// Why string vs pointer? We might rewrite the namespace and

View File

@ -25,22 +25,29 @@
#ifndef SERENE_ENVIRONMENT_H
#define SERENE_ENVIRONMENT_H
#include "mlir/Support/LogicalResult.h"
#include "serene/llvm/patches.h"
#include "llvm/ADT/DenseMap.h"
#include <llvm/ADT/DenseMap.h>
#include <mlir/Support/LogicalResult.h>
namespace serene {
/// This class represents a classic lisp environment (or scope) that holds the
/// bindings from type `K` to type `V`. For example an environment of symbols
/// to expressions would be `Environment<Symbol, Node>`
template <typename K, typename V>
class Environment {
Environment<K, V> *parent;
// The actual bindings storage
llvm::DenseMap<K, V> pairs;
public:
Environment() : parent(nullptr) {}
Environment(Environment *parent) : parent(parent){};
/// Look up the given `key` in the environment and return it.
llvm::Optional<V> lookup(K key) {
if (auto value = pairs.lookup(key)) {
return value;
@ -53,6 +60,8 @@ public:
return llvm::None;
};
/// Insert the given `key` with the given `value` into the storage. This
/// operation will shadow an aleady exist `key` in the parent environment
mlir::LogicalResult insert_symbol(K key, V value) {
pairs.insert(std::pair<K, V>(key, value));
return mlir::success();

View File

@ -66,8 +66,13 @@ using MaybeModuleOp = Result<mlir::OwningOpRef<mlir::ModuleOp>, bool>;
class Namespace {
private:
SereneContext &ctx;
bool initialized = false;
bool initialized = false;
// Anonymous function counter. We need to assing a unique name to each
// anonymous function and we use this counter to generate those names
std::atomic<uint> fn_counter = 0;
// The content of the namespace
exprs::Ast tree;
public:
@ -78,22 +83,30 @@ public:
/// Which is a mapping from names to AST nodes ( no evaluation ).
Environment<std::string, exprs::Node> semanticEnv;
/// Th root environmanet to store the MLIR value during the IR generation
/// phase.
Environment<llvm::StringRef, mlir::Value> symbolTable;
Namespace(SereneContext &ctx, llvm::StringRef ns_name,
llvm::Optional<llvm::StringRef> filename);
exprs::Ast &getTree();
mlir::LogicalResult setTree(exprs::Ast &);
/// Increase the function counter by one
uint nextFnCounter();
SereneContext &getContext();
/// Generate the IR of the namespace with respect to the compilation phase
/// Generate and return a MLIR ModuleOp tha contains the IR of the namespace
/// with respect to the compilation phase
MaybeModuleOp generate();
/// Compile the given namespace to the llvm module. It will call the
/// Compile the namespace to a llvm module. It will call the
/// `generate` method of the namespace to generate the IR.
MaybeModule compileToLLVM();
/// Run all the passes specified in the context on the given MLIR ModuleOp.
mlir::LogicalResult runPasses(mlir::ModuleOp &m);
/// Dumps the namespace with respect to the compilation phase
@ -102,6 +115,10 @@ public:
~Namespace();
};
/// Create a naw namespace with the given `name` and optional `filename` and
/// return a shared pointer to it in the given Serene context. If the
/// `setCurrent` argument is set to true, the created NS will become the curret
/// namespace in the context
std::shared_ptr<Namespace>
makeNamespace(SereneContext &ctx, llvm::StringRef name,
llvm::Optional<llvm::StringRef> filename, bool setCurrent = true);