add lambda skeleton

This commit is contained in:
water 2020-09-05 18:55:07 -04:00
parent 2075dd66b6
commit 2b67b1078f
3 changed files with 72 additions and 15 deletions

10
goalc/compiler/Lambda.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef JAK_LAMBDA_H
#define JAK_LAMBDA_H
struct Lambda {
std::string debug_name;
};
#endif // JAK_LAMBDA_H

View File

@ -3,20 +3,39 @@
/*!
* Fallback to_gpr if a more optimized one is not provided.
*/
RegVal* Val::to_gpr(FunctionEnv* fe) const {
const RegVal* Val::to_gpr(FunctionEnv* fe) const {
(void)fe;
throw std::runtime_error("Val::to_gpr NYI");
throw std::runtime_error("Val::to_gpr NYI"); // todo
}
/*!
* Fallback to_xmm if a more optimized one is not provided.
*/
RegVal* Val::to_xmm(FunctionEnv* fe) const {
const RegVal* Val::to_xmm(FunctionEnv* fe) const {
(void)fe;
throw std::runtime_error("Val::to_xmm NYI");
throw std::runtime_error("Val::to_xmm NYI"); // todo
}
RegVal* None::to_reg(FunctionEnv* fe) const {
const RegVal* RegVal::to_reg(FunctionEnv* fe) const {
(void)fe;
throw std::runtime_error("Cannot put None into a register.");
return this;
}
const RegVal * RegVal::to_gpr(FunctionEnv* fe) const {
(void)fe;
if(m_ireg.kind == emitter::RegKind::GPR) {
return this;
} else {
throw std::runtime_error("RegVal::to_gpr NYI"); // todo
}
}
const RegVal * RegVal::to_xmm(FunctionEnv* fe) const {
(void)fe;
if(m_ireg.kind == emitter::RegKind::XMM) {
return this;
} else {
throw std::runtime_error("RegVal::to_xmm NYI"); // todo
}
}

View File

@ -12,6 +12,7 @@
#include "third-party/fmt/core.h"
#include "common/type_system/TypeSystem.h"
#include "goalc/regalloc/IRegister.h"
#include "Lambda.h"
class RegVal;
class FunctionEnv;
@ -30,9 +31,11 @@ class Val {
}
virtual std::string print() const = 0;
virtual RegVal* to_reg(FunctionEnv* fe) const = 0;
virtual RegVal* to_gpr(FunctionEnv* fe) const;
virtual RegVal* to_xmm(FunctionEnv* fe) const;
virtual const RegVal* to_reg(FunctionEnv* fe) const {
throw std::runtime_error("to_reg called on invalid Val: " + print());
}
virtual const RegVal* to_gpr(FunctionEnv* fe) const;
virtual const RegVal* to_xmm(FunctionEnv* fe) const;
const TypeSpec& type() const { return m_ts; }
@ -47,7 +50,6 @@ class None : public Val {
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"; }
RegVal* to_reg(FunctionEnv* fe) const override;
};
/*!
@ -59,16 +61,42 @@ class RegVal : public Val {
bool is_register() const override { return true; }
IRegister ireg() const override { return m_ireg; }
std::string print() const override { return m_ireg.to_string(); };
RegVal* to_reg(FunctionEnv* fe) const override;
RegVal* to_gpr(FunctionEnv* fe) const override;
RegVal* to_xmm(FunctionEnv* fe) const override;
const RegVal* to_reg(FunctionEnv* fe) const override;
const RegVal* to_gpr(FunctionEnv* fe) const override;
const RegVal* to_xmm(FunctionEnv* fe) const override;
protected:
IRegister m_ireg;
};
// Symbol
// Lambda
/*!
* 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)) {}
const std::string& name() { return m_name; }
std::string print() const override { return "<" + m_name + ">"; }
protected:
std::string m_name;
};
/*!
* 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:
LambdaVal(TypeSpec ts, Lambda lam) : Val(ts), m_lam(lam) {}
std::string print() const override { return "lambda-" + m_lam.debug_name; }
protected:
Lambda m_lam;
FunctionEnv* fe = nullptr;
};
// Static
// MemOffConstant
// MemOffVar