Files
triton/include/ast.h

442 lines
8.9 KiB
C
Raw Normal View History

2018-12-17 10:43:49 -05:00
#ifndef TDL_INCLUDE_AST_H
#define TDL_INCLUDE_AST_H
2018-12-15 22:29:36 -05:00
#include "parser.hpp"
#include "llvm/IR/IRBuilder.h"
2018-12-15 22:29:36 -05:00
#include <cassert>
#include <vector>
2018-12-15 22:29:36 -05:00
#include <string>
namespace llvm{
class Function;
class Value;
class Type;
}
2018-12-17 10:43:49 -05:00
namespace tdl{
class module;
2018-12-15 22:29:36 -05:00
namespace ast{
// Enumerations
enum ASSIGN_OP_T{
ASSIGN,
INPLACE_MUL, INPLACE_DIV, INPLACE_MOD,
INPLACE_ADD, INPLACE_SUB,
INPLACE_LSHIFT, INPLACE_RSHIFT,
INPLACE_AND, INPLACE_XOR,
INPLACE_OR
};
enum BIN_OP_T{
MUL, DIV, MOD,
ADD, SUB,
LEFT_SHIFT, RIGHT_SHIFT,
LT, GT,
LE, GE,
EQ, NE,
AND, XOR, OR,
LAND, LOR
};
enum UNARY_OP_T{
INC, DEC,
PLUS, MINUS,
ADDR, DEREF,
COMPL, NOT
};
enum TYPE_T{
VOID_T,
UINT8_T, UINT16_T, UINT32_T, UINT64_T,
INT8_T, INT16_T, INT32_T, INT64_T,
FLOAT32_T, FLOAT64_T
};
class pointer;
class identifier;
// AST
2018-12-17 10:43:49 -05:00
class node {
public:
virtual llvm::Value* codegen(module*) const { return nullptr; }
2018-12-17 10:43:49 -05:00
};
2018-12-15 22:29:36 -05:00
template<class T>
class list: public node {
public:
list(const T& x): values_{x} {}
node* append(const T& x){
values_.push_back(x);
return this;
}
llvm::Value* codegen(module* mod) const{
for(T x: values_){
x->codegen(mod);
}
return nullptr;
}
const std::vector<T> &values() const
{ return values_; }
2018-12-15 22:29:36 -05:00
private:
std::vector<T> values_;
2018-12-15 22:29:36 -05:00
};
class expression: public node{
public:
virtual llvm::Value* codegen(module *) const = 0;
};
class unary_expression: public node{
public:
unary_expression(node *id): id_((const identifier*)id) {}
const identifier *id() const;
private:
const identifier *id_;
};
class named_expression: public unary_expression {
public:
named_expression(node *id): unary_expression(id){ }
llvm::Value* codegen(module* mod) const;
};
class binary_operator: public expression{
private:
llvm::Value* llvm_op(llvm::IRBuilder<> &bld, llvm::Value *lhs, llvm::Value *rhs, const std::string &name) const;
2018-12-15 22:29:36 -05:00
public:
binary_operator(BIN_OP_T op, node *lhs, node *rhs)
: op_(op), lhs_((expression*)lhs), rhs_((expression*)rhs) { }
llvm::Value* codegen(module *) const;
2018-12-15 22:29:36 -05:00
private:
const BIN_OP_T op_;
const expression *lhs_;
const expression *rhs_;
2018-12-15 22:29:36 -05:00
};
class constant: public expression{
2018-12-15 22:29:36 -05:00
public:
constant(int value): value_(value) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
private:
const int value_;
};
class string_literal: public expression{
2018-12-15 22:29:36 -05:00
public:
string_literal(char *&value): value_(value) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
std::string value_;
};
class unary_operator: public expression{
private:
llvm::Value *llvm_op(llvm::IRBuilder<> &builder, llvm::Value *arg, const std::string &name) const;
2018-12-15 22:29:36 -05:00
public:
unary_operator(UNARY_OP_T op, node *arg)
: op_(op),
arg_((expression*)arg) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
private:
const UNARY_OP_T op_;
const expression *arg_;
2018-12-15 22:29:36 -05:00
};
class type_name;
class cast_operator: public expression{
private:
llvm::Value *llvm_op(llvm::IRBuilder<> &builder, llvm::Type *T, llvm::Value *arg, const std::string &name) const;
2018-12-15 22:29:36 -05:00
public:
cast_operator(node *T, node *arg):
T_((type_name*)T),
arg_((expression*)arg) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
const type_name *T_;
const expression *arg_;
2018-12-15 22:29:36 -05:00
};
class conditional_expression: public expression{
private:
llvm::Value *llvm_op(llvm::IRBuilder<> &builder,
llvm::Value *cond, llvm::Value *true_value, llvm::Value *false_value,
const std::string &name) const;
2018-12-15 22:29:36 -05:00
public:
conditional_expression(node *cond, node *true_value, node *false_value)
: cond_((expression*)cond),
true_value_((expression*)true_value),
false_value_((expression*)false_value) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
const expression *cond_;
const expression *true_value_;
const expression *false_value_;
2018-12-15 22:29:36 -05:00
};
class assignment_expression: public expression{
2018-12-15 22:29:36 -05:00
public:
2018-12-16 16:15:40 -05:00
assignment_expression(node *lvalue, ASSIGN_OP_T op, node *rvalue)
: lvalue_((unary_expression*)lvalue), op_(op), rvalue_((expression*)rvalue) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
ASSIGN_OP_T op_;
const unary_expression *lvalue_;
const expression *rvalue_;
2018-12-15 22:29:36 -05:00
};
2018-12-19 11:25:29 -05:00
class initializer;
class declaration_specifier;
class declaration: public node{
public:
declaration(node *spec, node *init)
: spec_((declaration_specifier*)spec), init_((list<initializer*>*)init) { }
2018-12-19 11:25:29 -05:00
llvm::Value* codegen(module* mod) const;
public:
const declaration_specifier *spec_;
2018-12-19 11:25:29 -05:00
const list<initializer*> *init_;
};
class statement: public node{
};
class compound_statement: public statement{
typedef list<declaration*>* declarations_t;
typedef list<statement*>* statements_t;
2018-12-15 22:29:36 -05:00
public:
compound_statement(node* decls, node* statements)
: decls_((declarations_t)decls), statements_((statements_t)statements) {}
2018-12-15 22:29:36 -05:00
llvm::Value* codegen(module* mod) const;
2018-12-19 11:25:29 -05:00
2018-12-15 22:29:36 -05:00
private:
declarations_t decls_;
statements_t statements_;
2018-12-15 22:29:36 -05:00
};
class selection_statement: public statement{
2018-12-15 22:29:36 -05:00
public:
selection_statement(node *cond, node *if_value, node *else_value = nullptr)
: cond_(cond), then_value_(if_value), else_value_(else_value) { }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
const node *cond_;
const node *then_value_;
2018-12-15 22:29:36 -05:00
const node *else_value_;
};
class iteration_statement: public statement{
2018-12-15 22:29:36 -05:00
public:
iteration_statement(node *init, node *stop, node *exec, node *statements)
: init_(init), stop_(stop), exec_(exec), statements_(statements)
{ }
llvm::Value* codegen(module *mod) const;
2018-12-15 22:29:36 -05:00
private:
const node *init_;
const node *stop_;
const node *exec_;
const node *statements_;
};
class no_op: public statement { };
2018-12-15 22:29:36 -05:00
// Types
class declaration_specifier: public node{
2018-12-15 22:29:36 -05:00
public:
declaration_specifier(TYPE_T spec)
: spec_(spec) { }
2018-12-15 22:29:36 -05:00
llvm::Type* type(module *mod) const;
2018-12-15 22:29:36 -05:00
private:
const TYPE_T spec_;
2018-12-15 22:29:36 -05:00
};
class declarator;
class parameter: public node {
2018-12-15 22:29:36 -05:00
public:
parameter(node *spec, node *decl)
: spec_((declaration_specifier*)spec),
decl_((declarator*)decl) { }
2018-12-15 22:29:36 -05:00
llvm::Type* type(module *mod) const;
const identifier* id() const;
2018-12-15 22:29:36 -05:00
public:
const declaration_specifier *spec_;
const declarator *decl_;
2018-12-15 22:29:36 -05:00
};
/* Declarators */
class declarator: public node{
virtual llvm::Type* type_impl(module*mod, llvm::Type *type) const = 0;
2018-12-15 22:29:36 -05:00
public:
declarator(node *lhs)
: lhs_((declarator*)lhs), ptr_(nullptr){ }
llvm::Type* type(module*mod, llvm::Type *type) const;
const identifier* id() const {
return (const identifier*)lhs_;
}
declarator *set_ptr(node *ptr){
ptr_ = (pointer*)ptr;
return this;
}
protected:
declarator *lhs_;
pointer *ptr_;
2018-12-15 22:29:36 -05:00
};
class identifier: public declarator {
llvm::Type* type_impl(module*mod, llvm::Type *type) const;
2018-12-15 22:29:36 -05:00
public:
identifier(char *&name): declarator(this), name_(name) { }
const std::string &name() const;
2018-12-15 22:29:36 -05:00
private:
std::string name_;
};
class pointer: public declarator{
private:
llvm::Type* type_impl(module *mod, llvm::Type *type) const;
2018-12-15 22:29:36 -05:00
public:
pointer(node *id): declarator(id) { }
2018-12-15 22:29:36 -05:00
};
class tile: public declarator{
private:
llvm::Type* type_impl(module *mod, llvm::Type *type) const;
2018-12-15 22:29:36 -05:00
public:
tile(node *id, node *shapes)
: declarator(id), shapes_((list<constant*>*)(shapes)) { }
2018-12-15 22:29:36 -05:00
public:
const list<constant*>* shapes_;
};
class function: public declarator{
private:
llvm::Type* type_impl(module *mod, llvm::Type *type) const;
2018-12-15 22:29:36 -05:00
public:
function(node *id, node *args)
: declarator(id), args_((list<parameter*>*)args) { }
void bind_parameters(module *mod, llvm::Function *fn) const;
public:
const list<parameter*>* args_;
2018-12-15 22:29:36 -05:00
};
class initializer : public declarator{
private:
llvm::Type* type_impl(module* mod, llvm::Type *type) const;
public:
2018-12-19 11:25:29 -05:00
initializer(node *decl, node *init)
: declarator((node*)((declarator*)decl)->id()),
decl_((declarator*)decl), expr_((expression*)init){ }
void specifier(const declaration_specifier *spec);
llvm::Value* codegen(module *) const;
public:
const declaration_specifier *spec_;
2018-12-19 11:25:29 -05:00
const declarator *decl_;
const expression *expr_;
};
2018-12-15 22:29:36 -05:00
class type_name: public node{
2018-12-15 22:29:36 -05:00
public:
type_name(node *spec, node * decl)
: spec_((declaration_specifier*)spec), decl_((declarator*)decl) { }
llvm::Type *type(module *mod) const;
2018-12-15 22:29:36 -05:00
public:
const declaration_specifier *spec_;
const declarator *decl_;
2018-12-15 22:29:36 -05:00
};
2018-12-17 10:43:49 -05:00
/* Function definition */
class function_definition: public node{
public:
function_definition(node *spec, node *header, node *body)
: spec_((declaration_specifier*)spec), header_((function *)header), body_((compound_statement*)body) { }
llvm::Value* codegen(module* mod) const;
2018-12-17 10:43:49 -05:00
public:
const declaration_specifier *spec_;
const function *header_;
2018-12-17 10:43:49 -05:00
const compound_statement *body_;
};
/* Translation Unit */
2018-12-15 22:29:36 -05:00
class translation_unit: public node{
public:
translation_unit(node *item)
2018-12-17 10:43:49 -05:00
: decls_((list<node*>*)item) { }
2018-12-15 22:29:36 -05:00
translation_unit *add(node *item) {
2018-12-17 10:43:49 -05:00
decls_->append(item);
2018-12-15 22:29:36 -05:00
return this;
}
llvm::Value* codegen(module* mod) const;
2018-12-17 10:43:49 -05:00
2018-12-15 22:29:36 -05:00
private:
2018-12-17 10:43:49 -05:00
list<node*>* decls_;
2018-12-15 22:29:36 -05:00
};
2018-12-17 10:43:49 -05:00
}
2018-12-15 22:29:36 -05:00
}
2018-12-17 10:43:49 -05:00
#endif