Introduce the notion of ns and filename in the reader and location

This commit is contained in:
Sameer Rahmani 2021-09-07 21:47:29 +01:00
parent f357b5e9d3
commit 800e3c5fc8
8 changed files with 87 additions and 27 deletions

View File

@ -68,6 +68,9 @@ Then here is the list or parsers that we have considered
- [[https://www.hboehm.info/gc/][Boehm GC]]
** JIT
- [[https://asmjit.com/][Machine code generator for C++]]
** Optimizations
- [[https://sunfishcode.github.io/blog/2018/10/22/Canonicalization.html][Canonicalization]]
** Compiler
- [[https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64][Stack frame layout on x86-64]]
*** Branch instructions

View File

@ -70,8 +70,11 @@ public:
// --------------------------------------------------------------------------
llvm::LLVMContext llvmContext;
mlir::MLIRContext mlirContext;
mlir::PassManager pm;
mlir::DiagnosticEngine &diagEngine;
/// The source manager is responsible for loading namespaces and practically
/// managing the source code in form of memory buffers.
SourceMgr sourceManager;
@ -96,7 +99,8 @@ public:
std::shared_ptr<Namespace> getNS(llvm::StringRef ns_name);
SereneContext()
: pm(&mlirContext), targetPhase(CompilationPhase::NoOptimization) {
: pm(&mlirContext), diagEngine(mlirContext.getDiagEngine()),
targetPhase(CompilationPhase::NoOptimization) {
mlirContext.getOrLoadDialect<serene::slir::SereneDialect>();
mlirContext.getOrLoadDialect<mlir::StandardOpsDialect>();
// TODO: Get the crash report path dynamically from the cli

View File

@ -25,24 +25,22 @@
#ifndef LOCATION_H
#define LOCATION_H
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/Diagnostics.h"
#include <mlir/IR/Location.h>
#include <string>
namespace serene {
class SereneContext;
namespace reader {
/// It represents a location in the input string to the parser via `line`,
struct Location {
llvm::StringRef ns;
/// A pointer to the character that this location is pointing to
/// it the input buffer
const char *c;
/// The id of the buffer that this location belongs too.
unsigned bufferId;
const char *c = nullptr;
/// At this stage we only support 65535 lines of code in each file
unsigned short int line;
@ -52,6 +50,8 @@ struct Location {
::std::string toString() const;
Location() = default;
Location clone();
mlir::Location toMLIRLocation(SereneContext &ctx, llvm::StringRef ns);
};
class LocationRange {

View File

@ -55,6 +55,9 @@ class Reader {
private:
SereneContext &ctx;
llvm::StringRef ns;
llvm::Optional<llvm::StringRef> filename;
const char *current_char = NULL;
llvm::StringRef buf;
@ -91,8 +94,10 @@ private:
bool isEndOfBuffer(const char *);
public:
Reader(SereneContext &ctx, llvm::StringRef buf);
Reader(SereneContext &ctx, llvm::MemoryBufferRef buf);
Reader(SereneContext &ctx, llvm::StringRef buf, llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename);
Reader(SereneContext &ctx, llvm::MemoryBufferRef buf, llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename);
// void setInput(const llvm::StringRef string);
@ -105,7 +110,11 @@ public:
/// Parses the given `input` string and returns a `Result<ast>`
/// which may contains an AST or an `llvm::Error`
Result<exprs::Ast> read(SereneContext &ctx, const llvm::StringRef input);
Result<exprs::Ast> read(SereneContext &ctx, const llvm::MemoryBufferRef but);
Result<exprs::Ast> read(SereneContext &ctx, const llvm::StringRef input,
llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename);
Result<exprs::Ast> read(SereneContext &ctx, const llvm::MemoryBufferRef but,
llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename);
} // namespace serene::reader
#endif

View File

@ -101,6 +101,10 @@ private:
/// This is all of the buffers that we are reading from.
std::vector<SrcBuffer> buffers;
/// A mapping from the ns name to buffer id. The ns name is a reference to
/// the actual name that is stored in the Namespace instance.
llvm::DenseMap<llvm::StringRef, unsigned> nsToBufId;
// This is the list of directories we should search for include files in.
std::vector<std::string> loadPaths;

View File

@ -24,6 +24,8 @@
#include "serene/reader/location.h"
#include "serene/context.h"
#include <llvm/Support/FormatVariadic.h>
#include <mlir/IR/Identifier.h>
@ -40,8 +42,14 @@ std::string Location::toString() const {
return llvm::formatv("{0}:{1}", line, col);
};
Location Location::clone() { return Location{c, bufferId, line, col}; }
Location Location::clone() { return Location{ns, c, line, col}; }
mlir::Location Location::toMLIRLocation(SereneContext &ctx,
llvm::StringRef ns) {
// TODO: Create a new Location attribute that is namespace base
return mlir::FileLineColLoc::get(&ctx.mlirContext, ns, line, col);
}
/// Increase the given location by one and set the line/col value in respect to
/// the `newline` in place.
/// \param loc The `Location` data

View File

@ -24,11 +24,16 @@
#include "serene/reader/reader.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
#include "mlir/Support/LogicalResult.h"
#include "serene/exprs/list.h"
#include "serene/exprs/number.h"
#include "serene/exprs/symbol.h"
#include "serene/namespace.h"
#include "clang/AST/Stmt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <assert.h>
@ -46,11 +51,17 @@ namespace serene {
namespace reader {
Reader::Reader(SereneContext &ctx, llvm::StringRef buffer)
: ctx(ctx), buf(buffer){};
Reader::Reader(SereneContext &ctx, llvm::StringRef buffer, llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename)
: ctx(ctx), ns(ns), filename(filename), buf(buffer) {
current_location.ns = ns;
};
Reader::Reader(SereneContext &ctx, llvm::MemoryBufferRef buffer)
: ctx(ctx), buf(buffer.getBuffer()){};
Reader::Reader(SereneContext &ctx, llvm::MemoryBufferRef buffer,
llvm::StringRef ns, llvm::Optional<llvm::StringRef> filename)
: ctx(ctx), ns(ns), filename(filename), buf(buffer.getBuffer()) {
current_location.ns = ns;
};
Reader::~Reader() { READER_LOG("Destroying the reader"); }
@ -136,7 +147,7 @@ exprs::Node Reader::readNumber(bool neg) {
loc.start = getCurrentLocation();
while (!isEndOfBuffer(c) &&
((!(isspace(*c)) && ((isdigit(*c)) | (*c == '.'))))) {
((!(isspace(*c)) && (isdigit(*c) || *c == '.')))) {
if (*c == '.' && floatNum == true) {
ctx.sourceManager.PrintMessage(
@ -155,6 +166,14 @@ exprs::Node Reader::readNumber(bool neg) {
empty = false;
}
if (std::isalpha(*c)) {
ctx.sourceManager.PrintMessage(
llvm::errs(), llvm::SMLoc::getFromPointer(c),
ctx.sourceManager.DK_Error,
llvm::formatv("Invalid digit for a number. Are you drunk?\n", c));
exit(1);
}
if (!empty) {
ungetChar();
loc.end = getCurrentLocation();
@ -260,7 +279,7 @@ exprs::Node Reader::readList() {
/// Reads an expression by dispatching to the proper reader function.
exprs::Node Reader::readExpr() {
auto c = getChar(true);
auto c = getChar(false);
READER_LOG("Read char at `readExpr`: " << *c << " << " << current_pos << "|"
<< buf.size() << " BB "
<< isEndOfBuffer(c));
@ -274,6 +293,7 @@ exprs::Node Reader::readExpr() {
case '(': {
return readList();
}
default:
return readSymbol();
}
@ -283,11 +303,16 @@ exprs::Node Reader::readExpr() {
/// Each expression type (from the reader perspective) has a
/// reader function.
Result<exprs::Ast> Reader::read() {
// auto c = getChar(true);
// while (!isEndOfBuffer(c)) {
for (size_t current_pos = 0; current_pos < buf.size();) {
// ungetChar();
auto c = getChar(true);
if (isEndOfBuffer(c)) {
break;
}
ungetChar();
auto tmp{readExpr()};
if (tmp) {
@ -301,14 +326,19 @@ Result<exprs::Ast> Reader::read() {
return Result<exprs::Ast>::success(std::move(this->ast));
};
Result<exprs::Ast> read(SereneContext &ctx, const llvm::StringRef input) {
reader::Reader r(ctx, input);
Result<exprs::Ast> read(SereneContext &ctx, const llvm::StringRef input,
llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename) {
reader::Reader r(ctx, input, ns, filename);
auto ast = r.read();
return ast;
}
Result<exprs::Ast> read(SereneContext &ctx, const llvm::MemoryBufferRef input) {
reader::Reader r(ctx, input);
Result<exprs::Ast> read(SereneContext &ctx, const llvm::MemoryBufferRef input,
llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename) {
reader::Reader r(ctx, input, ns, filename);
auto ast = r.read();
return ast;
}

View File

@ -87,7 +87,8 @@ NSPtr SourceMgr::readNamespace(SereneContext &ctx, std::string name,
auto *buf = getMemoryBuffer(bufferId);
// Read the content of the buffer by passing it the reader
auto maybeAst = reader::read(ctx, buf->getBuffer());
auto maybeAst = reader::read(ctx, buf->getBuffer(), name,
llvm::Optional(llvm::StringRef(includedFile)));
if (!maybeAst) {
SMGR_LOG("Couldn't Read namespace: " + name)
@ -97,6 +98,7 @@ NSPtr SourceMgr::readNamespace(SereneContext &ctx, std::string name,
// Create the NS and set the AST
auto ns =
makeNamespace(ctx, name, llvm::Optional(llvm::StringRef(includedFile)));
if (mlir::failed(ns->setTree(maybeAst.getValue()))) {
SMGR_LOG("Couldn't set the AST for namespace: " + name)
return nullptr;