You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
3.6 KiB
C++
184 lines
3.6 KiB
C++
/**
|
|
* lisp-compiler: Compiles LISP using LLVM.
|
|
* Copyright (C) 2022 Clyne Sullivan
|
|
*
|
|
* 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, either version 3 of the License, or (at your option) any later
|
|
* version.
|
|
*
|
|
* 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/>.
|
|
*
|
|
* @file ast.hpp
|
|
* @brief Abstract Syntax Tree (AST) implementation.
|
|
*/
|
|
|
|
#ifndef AST_HPP
|
|
#define AST_HPP
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <variant>
|
|
|
|
struct CompilerState;
|
|
|
|
namespace llvm {
|
|
struct Value;
|
|
}
|
|
|
|
namespace AST {
|
|
|
|
using Value = llvm::Value *;
|
|
|
|
struct Node
|
|
{
|
|
virtual ~Node() {};
|
|
|
|
virtual Value codegen(CompilerState&) = 0;
|
|
virtual std::string desc() {
|
|
return "Node";
|
|
}
|
|
};
|
|
|
|
struct Identifier : public Node
|
|
{
|
|
std::string name;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
return std::string("Identifier: ") + name;
|
|
}
|
|
};
|
|
|
|
struct Literal : public Node
|
|
{
|
|
enum Type {
|
|
Unknown,
|
|
Number,
|
|
} type = Unknown;
|
|
std::variant<int, double> value;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
std::string str ("Literal: ");
|
|
|
|
switch (type) {
|
|
default:
|
|
case Unknown:
|
|
str += "unknown";
|
|
break;
|
|
case Number:
|
|
str += std::visit([](auto&& v) { return std::to_string(v); }, value);
|
|
break;
|
|
}
|
|
|
|
return str;
|
|
}
|
|
};
|
|
|
|
struct ProcedureCall : public Node
|
|
{
|
|
Node *callee;
|
|
std::vector<Node *> operands;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
std::string str ("ProcedureCall: ");
|
|
|
|
str = str + "<" + (callee ? callee->desc() : "unknown") + ">";
|
|
str += '(';
|
|
if (!operands.empty()) {
|
|
for (const auto& op : operands) {
|
|
str = str + "<" + (op ? op->desc() : "unknown") + ">";
|
|
str += ", ";
|
|
}
|
|
|
|
str.pop_back();
|
|
str.pop_back();
|
|
}
|
|
str += ')';
|
|
|
|
return str;
|
|
}
|
|
};
|
|
|
|
struct LambdaExpression : public Node
|
|
{
|
|
std::vector<Identifier *> operands;
|
|
std::vector<Node *> body;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
return "LambdaExpression";
|
|
}
|
|
};
|
|
|
|
struct Conditional : public Node
|
|
{
|
|
Node *cond;
|
|
Node *iftrue;
|
|
Node *iffalse;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
return "Conditional";
|
|
}
|
|
};
|
|
|
|
struct Definition : public Node
|
|
{
|
|
Identifier *ident;
|
|
Node *value;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
return "Definition";
|
|
}
|
|
};
|
|
|
|
struct Assignment : public Node
|
|
{
|
|
Identifier *ident;
|
|
Node *value;
|
|
|
|
virtual Value codegen(CompilerState&) final;
|
|
|
|
virtual std::string desc() final {
|
|
return "Assignment";
|
|
}
|
|
};
|
|
|
|
struct DerivedExpression : public Node
|
|
{
|
|
std::string name;
|
|
|
|
virtual Value codegen(CompilerState&) final {
|
|
return nullptr;
|
|
}
|
|
|
|
virtual std::string desc() final {
|
|
return "DerivedExpression";
|
|
}
|
|
};
|
|
|
|
// MacroUse
|
|
// MacroBlock
|
|
// Includer
|
|
|
|
}
|
|
|
|
#endif // AST_HPP
|
|
|