Introduce the new polymorphic approach to expressions
This commit is contained in:
parent
062b24e701
commit
f73cfe7aaf
|
@ -22,7 +22,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "serene/serene.hpp"
|
#include "serene/serene.h"
|
||||||
#include "serene/reader/reader.hpp"
|
#include "serene/reader/reader.hpp"
|
||||||
#include "serene/sir/sir.hpp"
|
#include "serene/sir/sir.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* -*- C++ -*-
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXPRS_EXPRESSION_H
|
||||||
|
#define EXPRS_EXPRESSION_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace serene {
|
||||||
|
|
||||||
|
/// Contains all the builtin expressions including those which do not appear in
|
||||||
|
/// the syntax directly. Like function definitions.
|
||||||
|
namespace exprs {
|
||||||
|
|
||||||
|
/// The polymorphic type that works as the entry point to the exprs system.
|
||||||
|
/// Each expression has to define the interface of the `ExpressionConcept`
|
||||||
|
/// class as generic functions. **REMEMBER TO NOT INHERIT FROM THESE CLASSES**
|
||||||
|
class Expression {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
Expression(T e) : self(new ExpressionImpl<T>(std::move(e))){};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The generic interface which each type of expression has to implement
|
||||||
|
/// in order to act like an `Expression`
|
||||||
|
struct ExpressionConcept {
|
||||||
|
virtual ~ExpressionConcept() = default;
|
||||||
|
virtual ExpressionConcept *copy_() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The generic implementation of `ExpressionConcept` which acts as the
|
||||||
|
/// dispatcher on type.
|
||||||
|
template <typename T> struct ExpressionImpl : ExpressionConcept {
|
||||||
|
ExpressionImpl(T e) : expr(std::move(e)){};
|
||||||
|
ExpressionConcept *copy_() const { return new ExpressionImpl(*this); }
|
||||||
|
|
||||||
|
T expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The internal container to keep the object implementing the
|
||||||
|
/// `ExpressionConcept`. This might be a `List` for example or a `Symbol`.
|
||||||
|
std::unique_ptr<ExpressionConcept> self;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace exprs
|
||||||
|
} // namespace serene
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- C++ -*-
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXPRS_SYMBOL_H
|
||||||
|
#define EXPRS_SYMBOL_H
|
||||||
|
|
||||||
|
#include "serene/exprs/expression.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace serene {
|
||||||
|
|
||||||
|
namespace exprs {
|
||||||
|
|
||||||
|
struct List {
|
||||||
|
llvm::SmallVector<Expression, 0> elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace exprs
|
||||||
|
} // namespace serene
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* -*- C++ -*-
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXPRS_SYMBOL_H
|
||||||
|
#define EXPRS_SYMBOL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace serene {
|
||||||
|
|
||||||
|
namespace exprs {
|
||||||
|
|
||||||
|
struct Symbol {
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace exprs
|
||||||
|
} // namespace serene
|
||||||
|
|
||||||
|
#endif
|
|
@ -37,7 +37,7 @@
|
||||||
#include "serene/list.hpp"
|
#include "serene/list.hpp"
|
||||||
#include "serene/logger.hpp"
|
#include "serene/logger.hpp"
|
||||||
#include "serene/reader/location.hpp"
|
#include "serene/reader/location.hpp"
|
||||||
#include "serene/serene.hpp"
|
#include "serene/serene.h"
|
||||||
#include "serene/symbol.hpp"
|
#include "serene/symbol.hpp"
|
||||||
|
|
||||||
#if defined(ENABLE_READER_LOG) || defined(ENABLE_LOG)
|
#if defined(ENABLE_READER_LOG) || defined(ENABLE_LOG)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/*
|
||||||
* Serene programming language.
|
* Serene programming language.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
|
@ -55,8 +55,8 @@ private:
|
||||||
// TODO: Should we use builder here? maybe there is a better option
|
// TODO: Should we use builder here? maybe there is a better option
|
||||||
::mlir::Location toMLIRLocation(serene::reader::Location *);
|
::mlir::Location toMLIRLocation(serene::reader::Location *);
|
||||||
|
|
||||||
mlir::FuncOp generateFn(serene::reader::Location, std::string, List *,
|
// mlir::FuncOp generateFn(serene::reader::Location, std::string, List *,
|
||||||
List *);
|
// List *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Generator(mlir::MLIRContext &context, ::serene::Namespace *ns)
|
Generator(mlir::MLIRContext &context, ::serene::Namespace *ns)
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
set(HEADER_LIST
|
set(HEADER_LIST
|
||||||
|
"${INCLUDE_DIR}/serene/serene.h"
|
||||||
|
|
||||||
|
"${INCLUDE_DIR}/serene/exprs/expression.h"
|
||||||
|
"${INCLUDE_DIR}/serene/exprs/symbol.h"
|
||||||
|
"${INCLUDE_DIR}/serene/exprs/list.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"${INCLUDE_DIR}/serene/expr.hpp"
|
"${INCLUDE_DIR}/serene/expr.hpp"
|
||||||
"${INCLUDE_DIR}/serene/serene.hpp"
|
|
||||||
"${INCLUDE_DIR}/serene/number.hpp"
|
"${INCLUDE_DIR}/serene/number.hpp"
|
||||||
"${INCLUDE_DIR}/serene/symbol.hpp"
|
"${INCLUDE_DIR}/serene/symbol.hpp"
|
||||||
"${INCLUDE_DIR}/serene/list.hpp"
|
"${INCLUDE_DIR}/serene/list.hpp"
|
||||||
|
@ -19,6 +27,9 @@ set(HEADER_LIST
|
||||||
|
|
||||||
# Make an automatic library - will be static or dynamic based on user setting
|
# Make an automatic library - will be static or dynamic based on user setting
|
||||||
add_library(serene
|
add_library(serene
|
||||||
|
exprs/symbol.cpp
|
||||||
|
exprs/list.cpp
|
||||||
|
|
||||||
serene.cpp
|
serene.cpp
|
||||||
symbol.cpp
|
symbol.cpp
|
||||||
list.cpp
|
list.cpp
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serene/exprs/list.h"
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serene/exprs/symbol.h"
|
|
@ -22,6 +22,6 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "serene/serene.hpp"
|
#include "serene/serene.h"
|
||||||
#include "serene/reader/reader.hpp"
|
#include "serene/reader/reader.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -40,139 +40,144 @@ namespace serene {
|
||||||
namespace sir {
|
namespace sir {
|
||||||
|
|
||||||
mlir::ModuleOp Generator::generate() {
|
mlir::ModuleOp Generator::generate() {
|
||||||
for (auto x : ns->Tree()) {
|
// for (auto x : ns->Tree()) {
|
||||||
generate(x.get());
|
// generate(x.get());
|
||||||
}
|
// }
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
};
|
};
|
||||||
|
|
||||||
mlir::Operation *Generator::generate(AExpr *x) {
|
mlir::Operation *Generator::generate(AExpr *x) {
|
||||||
switch (x->getType()) {
|
// switch (x->getType()) {
|
||||||
case SereneType::Number: {
|
// case SereneType::Number: {
|
||||||
return generate(llvm::cast<Number>(x));
|
// return generate(llvm::cast<Number>(x));
|
||||||
}
|
// }
|
||||||
|
|
||||||
case SereneType::List: {
|
// case SereneType::List: {
|
||||||
generate(llvm::cast<List>(x));
|
// generate(llvm::cast<List>(x));
|
||||||
return nullptr;
|
// return nullptr;
|
||||||
}
|
// }
|
||||||
|
|
||||||
default: {
|
// default: {
|
||||||
return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)3);
|
return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)3);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
mlir::Value Generator::generate(List *l) {
|
mlir::Value Generator::generate(List *l) {
|
||||||
auto first = l->at(0);
|
// auto first = l->at(0);
|
||||||
|
|
||||||
if (!first) {
|
// if (!first) {
|
||||||
// Empty list.
|
// // Empty list.
|
||||||
// TODO: Return Nil or empty list.
|
// // TODO: Return Nil or empty list.
|
||||||
|
|
||||||
// Just for now.
|
// // Just for now.
|
||||||
return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)0);
|
// return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)0);
|
||||||
}
|
|
||||||
|
|
||||||
if (first->get()->getType() == SereneType::Symbol) {
|
|
||||||
auto fnNameSymbol = llvm::dyn_cast<Symbol>(first->get());
|
|
||||||
|
|
||||||
if (fnNameSymbol->getName() == "fn") {
|
|
||||||
if (l->count() <= 3) {
|
|
||||||
module.emitError("'fn' form needs exactly 2 arguments.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto args = llvm::dyn_cast<List>(l->at(1).getValue().get());
|
|
||||||
auto body = llvm::dyn_cast<List>(l->from(2).get());
|
|
||||||
|
|
||||||
if (!args) {
|
|
||||||
module.emitError("The first element of 'def' has to be a symbol.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new anonymous function and push it to the anonymous functions
|
|
||||||
// map, later on we
|
|
||||||
auto loc(fnNameSymbol->location->start);
|
|
||||||
auto anonymousName = fmt::format("__fn_{}__", anonymousFnCounter);
|
|
||||||
anonymousFnCounter++;
|
|
||||||
|
|
||||||
auto fn = generateFn(loc, anonymousName, args, body);
|
|
||||||
mlir::Identifier fnid = builder.getIdentifier(anonymousName);
|
|
||||||
anonymousFunctions.insert({fnid, fn});
|
|
||||||
return builder.create<FnIdOp>(builder.getUnknownLoc(), fnid.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// auto rest = l->from(1);
|
|
||||||
// auto loc = toMLIRLocation(&first->get()->location->start);
|
|
||||||
// for (auto x : *rest) {
|
|
||||||
// generate(x.get());
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// if (first->get()->getType() == SereneType::Symbol) {
|
||||||
|
// auto fnNameSymbol = llvm::dyn_cast<Symbol>(first->get());
|
||||||
|
|
||||||
|
// if (fnNameSymbol->getName() == "fn") {
|
||||||
|
// if (l->count() <= 3) {
|
||||||
|
// module.emitError("'fn' form needs exactly 2 arguments.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// auto args = llvm::dyn_cast<List>(l->at(1).getValue().get());
|
||||||
|
// auto body = llvm::dyn_cast<List>(l->from(2).get());
|
||||||
|
|
||||||
|
// if (!args) {
|
||||||
|
// module.emitError("The first element of 'def' has to be a symbol.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Create a new anonymous function and push it to the anonymous
|
||||||
|
// functions
|
||||||
|
// // map, later on we
|
||||||
|
// auto loc(fnNameSymbol->location->start);
|
||||||
|
// auto anonymousName = fmt::format("__fn_{}__", anonymousFnCounter);
|
||||||
|
// anonymousFnCounter++;
|
||||||
|
|
||||||
|
// auto fn = generateFn(loc, anonymousName, args, body);
|
||||||
|
// mlir::Identifier fnid = builder.getIdentifier(anonymousName);
|
||||||
|
// anonymousFunctions.insert({fnid, fn});
|
||||||
|
// return builder.create<FnIdOp>(builder.getUnknownLoc(), fnid.str());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // auto rest = l->from(1);
|
||||||
|
// // auto loc = toMLIRLocation(&first->get()->location->start);
|
||||||
|
// // for (auto x : *rest) {
|
||||||
|
// // generate(x.get());
|
||||||
|
// // }
|
||||||
|
|
||||||
return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)100);
|
return builder.create<ValueOp>(builder.getUnknownLoc(), (uint64_t)100);
|
||||||
};
|
};
|
||||||
|
|
||||||
mlir::FuncOp Generator::generateFn(serene::reader::Location loc,
|
// mlir::FuncOp Generator::generateFn(serene::reader::Location loc,
|
||||||
std::string name, List *args, List *body) {
|
// std::string name, List *args, List *body)
|
||||||
|
// {
|
||||||
|
|
||||||
auto location = toMLIRLocation(&loc);
|
// auto location = toMLIRLocation(&loc);
|
||||||
llvm::SmallVector<mlir::Type, 4> arg_types(args->count(),
|
// llvm::SmallVector<mlir::Type, 4> arg_types(args->count(),
|
||||||
builder.getI64Type());
|
// builder.getI64Type());
|
||||||
auto func_type = builder.getFunctionType(arg_types, builder.getI64Type());
|
// auto func_type = builder.getFunctionType(arg_types, builder.getI64Type());
|
||||||
auto proto = mlir::FuncOp::create(location, name, func_type);
|
// auto proto = mlir::FuncOp::create(location, name, func_type);
|
||||||
mlir::FuncOp fn(proto);
|
// mlir::FuncOp fn(proto);
|
||||||
|
|
||||||
if (!fn) {
|
// if (!fn) {
|
||||||
module.emitError("Can not create the function.");
|
// module.emitError("Can not create the function.");
|
||||||
}
|
|
||||||
|
|
||||||
auto &entryBlock = *fn.addEntryBlock();
|
|
||||||
llvm::ScopedHashTableScope<llvm::StringRef, mlir::Value> scope(symbolTable);
|
|
||||||
|
|
||||||
// Declare all the function arguments in the symbol table.
|
|
||||||
for (const auto arg :
|
|
||||||
llvm::zip(args->asArrayRef(), entryBlock.getArguments())) {
|
|
||||||
|
|
||||||
auto argSymbol = llvm::dyn_cast<Symbol>(std::get<0>(arg).get());
|
|
||||||
if (!argSymbol) {
|
|
||||||
module.emitError("Function parameters must be symbols");
|
|
||||||
}
|
|
||||||
if (symbolTable.count(argSymbol->getName())) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
symbolTable.insert(argSymbol->getName(), std::get<1>(arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the insertion point in the builder to the beginning of the function
|
|
||||||
// body, it will be used throughout the codegen to create operations in this
|
|
||||||
// function.
|
|
||||||
builder.setInsertionPointToStart(&entryBlock);
|
|
||||||
|
|
||||||
// Emit the body of the function.
|
|
||||||
if (!generate(body)) {
|
|
||||||
fn.erase();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Implicitly return void if no return statement was emitted.
|
|
||||||
// // FIXME: we may fix the parser instead to always return the last
|
|
||||||
// expression
|
|
||||||
// // (this would possibly help the REPL case later)
|
|
||||||
// ReturnOp returnOp;
|
|
||||||
|
|
||||||
// if (!entryBlock.empty())
|
|
||||||
// returnOp = dyn_cast<ReturnOp>(entryBlock.back());
|
|
||||||
// if (!returnOp) {
|
|
||||||
// builder.create<ReturnOp>(loc(funcAST.getProto()->loc()));
|
|
||||||
// } else if (returnOp.hasOperand()) {
|
|
||||||
// // Otherwise, if this return operation has an operand then add a result
|
|
||||||
// to
|
|
||||||
// // the function.
|
|
||||||
// function.setType(builder.getFunctionType(function.getType().getInputs(),
|
|
||||||
// getType(VarType{})));
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return fn;
|
// auto &entryBlock = *fn.addEntryBlock();
|
||||||
}
|
// llvm::ScopedHashTableScope<llvm::StringRef, mlir::Value>
|
||||||
|
// scope(symbolTable);
|
||||||
|
|
||||||
|
// // Declare all the function arguments in the symbol table.
|
||||||
|
// for (const auto arg :
|
||||||
|
// llvm::zip(args->asArrayRef(), entryBlock.getArguments())) {
|
||||||
|
|
||||||
|
// auto argSymbol = llvm::dyn_cast<Symbol>(std::get<0>(arg).get());
|
||||||
|
// if (!argSymbol) {
|
||||||
|
// module.emitError("Function parameters must be symbols");
|
||||||
|
// }
|
||||||
|
// if (symbolTable.count(argSymbol->getName())) {
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
// symbolTable.insert(argSymbol->getName(), std::get<1>(arg));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Set the insertion point in the builder to the beginning of the function
|
||||||
|
// // body, it will be used throughout the codegen to create operations in
|
||||||
|
// this
|
||||||
|
// // function.
|
||||||
|
// builder.setInsertionPointToStart(&entryBlock);
|
||||||
|
|
||||||
|
// // Emit the body of the function.
|
||||||
|
// if (!generate(body)) {
|
||||||
|
// fn.erase();
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // // Implicitly return void if no return statement was emitted.
|
||||||
|
// // // FIXME: we may fix the parser instead to always return the last
|
||||||
|
// // expression
|
||||||
|
// // // (this would possibly help the REPL case later)
|
||||||
|
// // ReturnOp returnOp;
|
||||||
|
|
||||||
|
// // if (!entryBlock.empty())
|
||||||
|
// // returnOp = dyn_cast<ReturnOp>(entryBlock.back());
|
||||||
|
// // if (!returnOp) {
|
||||||
|
// // builder.create<ReturnOp>(loc(funcAST.getProto()->loc()));
|
||||||
|
// // } else if (returnOp.hasOperand()) {
|
||||||
|
// // // Otherwise, if this return operation has an operand then add a
|
||||||
|
// result
|
||||||
|
// // to
|
||||||
|
// // // the function.
|
||||||
|
// // function.setType(builder.getFunctionType(function.getType().getInputs(),
|
||||||
|
// // getType(VarType{})));
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// return fn;
|
||||||
|
// }
|
||||||
|
|
||||||
mlir::Operation *Generator::generate(Number *x) {
|
mlir::Operation *Generator::generate(Number *x) {
|
||||||
return builder.create<ValueOp>(builder.getUnknownLoc(), x->toI64());
|
return builder.create<ValueOp>(builder.getUnknownLoc(), x->toI64());
|
||||||
|
|
Loading…
Reference in New Issue