jak-project/goalc/compiler/Val.h

146 lines
3.7 KiB
C
Raw Normal View History

/*!
* @file Val.h
* The GOAL Value. A value represents a place (where the value is stored) and a type.
*/
#ifndef JAK_VAL_H
#define JAK_VAL_H
#include <utility>
#include <string>
#include <stdexcept>
#include "third-party/fmt/core.h"
#include "common/type_system/TypeSystem.h"
#include "goalc/regalloc/IRegister.h"
2020-09-05 18:55:07 -04:00
#include "Lambda.h"
#include "StaticObject.h"
class RegVal;
2020-09-07 13:28:16 -04:00
class Env;
class FunctionEnv;
/*!
* Parent class for every Val.
*/
class Val {
public:
explicit Val(TypeSpec ts) : m_ts(std::move(ts)) {}
virtual bool is_register() const { return false; }
virtual IRegister ireg() const {
throw std::runtime_error("get_ireg called on invalid Val: " + print());
}
virtual std::string print() const = 0;
2020-09-07 13:28:16 -04:00
virtual RegVal* to_reg(Env* fe) {
(void)fe;
2020-09-05 18:55:07 -04:00
throw std::runtime_error("to_reg called on invalid Val: " + print());
}
2020-09-07 13:28:16 -04:00
virtual RegVal* to_gpr(Env* fe);
virtual RegVal* to_xmm(Env* fe);
const TypeSpec& type() const { return m_ts; }
void set_type(TypeSpec ts) { m_ts = std::move(ts); }
protected:
TypeSpec m_ts;
};
/*!
* Special None Val used for the value of anything returning (none).
*/
class None : public Val {
public:
explicit None(TypeSpec _ts) : Val(std::move(_ts)) {}
explicit None(const TypeSystem& _ts) : Val(_ts.make_typespec("none")) {}
std::string print() const override { return "none"; }
};
/*!
* A Val stored in a register.
*/
class RegVal : public Val {
public:
RegVal(IRegister ireg, TypeSpec ts) : Val(std::move(ts)), m_ireg(ireg) {}
bool is_register() const override { return true; }
IRegister ireg() const override { return m_ireg; }
std::string print() const override { return m_ireg.to_string(); };
2020-09-07 13:28:16 -04:00
RegVal* to_reg(Env* fe) override;
RegVal* to_gpr(Env* fe) override;
RegVal* to_xmm(Env* fe) override;
protected:
IRegister m_ireg;
};
2020-09-05 18:55:07 -04:00
/*!
* A Val representing a symbol. This is confusing but it's not actually the value of the symbol,
* but instead the symbol itself.
*/
class SymbolVal : public Val {
public:
SymbolVal(std::string name, TypeSpec ts) : Val(std::move(ts)), m_name(std::move(name)) {}
2020-09-07 13:28:16 -04:00
const std::string& name() const { return m_name; }
2020-09-05 18:55:07 -04:00
std::string print() const override { return "<" + m_name + ">"; }
2020-09-07 13:28:16 -04:00
RegVal* to_reg(Env* fe) override;
2020-09-05 18:55:07 -04:00
protected:
std::string m_name;
};
2020-09-07 13:28:16 -04:00
class SymbolValueVal : public Val {
public:
SymbolValueVal(const SymbolVal* sym, TypeSpec ts, bool sext)
: Val(std::move(ts)), m_sym(sym), m_sext(sext) {}
const std::string& name() const { return m_sym->name(); }
std::string print() const override { return "[<" + name() + ">]"; }
RegVal* to_reg(Env* fe) override;
protected:
const SymbolVal* m_sym = nullptr;
bool m_sext = false;
};
2020-09-05 18:55:07 -04:00
/*!
* A Val representing a GOAL lambda. It can be a "real" x86-64 function, in which case the
* FunctionEnv is set. Otherwise, just contains a Lambda.
*/
class LambdaVal : public Val {
public:
explicit LambdaVal(TypeSpec ts) : Val(std::move(ts)) {}
std::string print() const override { return "lambda-" + lambda.debug_name; }
2020-09-07 13:28:16 -04:00
FunctionEnv* func = nullptr;
Lambda lambda;
RegVal* to_reg(Env* fe) override;
};
2020-09-05 18:55:07 -04:00
class StaticVal : public Val {
public:
StaticVal(StaticObject* _obj, TypeSpec _ts) : Val(std::move(_ts)), obj(_obj) {}
StaticObject* obj = nullptr;
std::string print() const override { return "[" + obj->print() + "]"; }
RegVal* to_reg(Env* fe) override;
2020-09-05 18:55:07 -04:00
};
// MemOffConstant
// MemOffVar
// MemDeref
// PairEntry
// Alias
class IntegerConstantVal : public Val {
public:
IntegerConstantVal(TypeSpec ts, s64 value) : Val(ts), m_value(value) {}
std::string print() const override { return "integer-constant-" + std::to_string(m_value); }
2020-09-07 13:28:16 -04:00
RegVal* to_reg(Env* fe) override;
protected:
s64 m_value = -1;
};
// IntegerConstant
// FloatConstant
// Bitfield
#endif // JAK_VAL_H