Skip to content

Commit

Permalink
Rough version of closures working! Need to fix some hacky implementat…
Browse files Browse the repository at this point in the history
…ions and do further testing
  • Loading branch information
chutasano committed Apr 29, 2018
1 parent 75b2ce4 commit dd5213f
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 227 deletions.
2 changes: 2 additions & 0 deletions compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ static string to_asm(r0::P &p)
{
p.uniquify();
p.type_check();
p.lambda_lift();
p.type_check(true);
c0::P c = p.flatten();
x0s::P xs = c.select();
x0::P x0 = xs.assign();
Expand Down
63 changes: 37 additions & 26 deletions rep/c0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,26 @@
using namespace std;
using namespace c0;

static unordered_map<string, unsigned int> count;
// figures out whether to use movq or leaq depending on the type of src
// note that src is a c0::Arg while dst is x0s::Dst
static inline x0s::ISrcDst* x0s_move(const unordered_map<string, int> &vmap, const Arg* src, x0s::Dst* dst)
{
bool is_ref;
if (typeid(*src) == typeid(Var))
{
//is_ref = false;
is_ref = type_is_func(vmap.at(static_cast<const Var*>(src)->name));
}
else if (typeid(*src) == typeid(GlobalVar))
{
is_ref = true;
}
else
{
is_ref = false;
}
return new x0s::ISrcDst(is_ref ? LEAQ : MOVQ, src->to_arg(), dst);
}

x0s::Arg* Var::to_arg() const
{
Expand All @@ -26,26 +45,19 @@ x0s::Arg* Num::to_arg() const
return new x0s::Con(this->value);
}

list<x0s::I*> Arg::select(x0s::Var* var)
list<x0s::I*> Arg::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
// moving globals should be done as lea because globals are always
// memory locations
if (typeid(*this) == typeid(GlobalVar))
{
return { new x0s::ISrcDst(LEAQ, this->to_arg(), var) };
}
else
{
return { new x0s::ISrcDst(MOVQ, this->to_arg(), var) };
}
return { x0s_move(vmap, this, var) };
}

list<x0s::I*> Read::select(x0s::Var* var)
list<x0s::I*> Read::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
return { new x0s::ICall(new x0s::Global("_lang_read_num"), { }, var) };
}

list<x0s::I*> Binop::select(x0s::Var* var)
list<x0s::I*> Binop::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
switch(this->op)
{
Expand Down Expand Up @@ -83,7 +95,7 @@ list<x0s::I*> Binop::select(x0s::Var* var)
}
}

list<x0s::I*> Unop::select(x0s::Var* var)
list<x0s::I*> Unop::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
switch(this->op)
{
Expand All @@ -99,7 +111,7 @@ list<x0s::I*> Unop::select(x0s::Var* var)
};
}

list<x0s::I*> FunCall::select(x0s::Var* var)
list<x0s::I*> FunCall::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
vector<x0s::Arg*> x0sargs;
for (auto a : args)
Expand All @@ -109,7 +121,7 @@ list<x0s::I*> FunCall::select(x0s::Var* var)
return { new x0s::ICall(func->to_arg(), x0sargs, var) };
}

list<x0s::I*> Alloc::select(x0s::Var* var)
list<x0s::I*> Alloc::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
int total_size = 8*(1+size);
// TODO abstractify this a bit more to reuse code
Expand All @@ -126,27 +138,26 @@ list<x0s::I*> Alloc::select(x0s::Var* var)
new x0s::ISrcDst(ADDQ, new x0s::Con(total_size), new x0s::Reg("r15")) };
}

list<x0s::I*> VecRef::select(x0s::Var* var)
list<x0s::I*> VecRef::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
return { new x0s::ISrcDst(MOVQ, vec->to_arg(), new x0s::Reg("r8")),
new x0s::ISrcDst(MOVQ, new x0s::Deref(new x0s::Reg("r8"), 8*(1+index)), var) };
}

list<x0s::I*> VecSet::select(x0s::Var* var)
list<x0s::I*> VecSet::select(const unordered_map<string, int> &vmap, x0s::Var* var)
{
return { new x0s::ISrcDst(MOVQ, vec->to_arg(), new x0s::Reg("r8")),
new x0s::ISrcDst(MOVQ, asg->to_arg(),
new x0s::Deref(new x0s::Reg("r8"), 8*(1+index))),
x0s_move(vmap, asg, new x0s::Deref(new x0s::Reg("r8"), 8*(1+index))),
//new x0s::ISrcDst(MOVQ, asg->to_arg(),
new x0s::ISrcDst(MOVQ, new x0s::Con(TV_VOID), var) };
}

list<x0s::I*> S::select()
list<x0s::I*> S::select(const unordered_map<string, int> &vmap)
{
return this->e->select(new x0s::Var(this->v));
return this->e->select(vmap, new x0s::Var(this->v));
}


list<x0s::I*> If::select()
list<x0s::I*> If::select(const unordered_map<string, int> &vmap)
{
x0s::Dst* var = new x0s::Reg("rax"); // TODO?
x0s::Var* tv = new x0s::Var(this->v);
Expand Down Expand Up @@ -179,7 +190,7 @@ list<x0s::I*> If::select()
list<x0s::I*> elsei;
for (auto s : elses)
{
list<x0s::I*> is = s->select();
list<x0s::I*> is = s->select(vmap);
elsei.splice(elsei.end(), is);
}
elsei.push_back(new x0s::ISrcDst(MOVQ, elsev->to_arg(), tv));
Expand All @@ -189,7 +200,7 @@ list<x0s::I*> If::select()
list<x0s::I*> theni;
for (auto s : thens)
{
list<x0s::I*> is = s->select();
list<x0s::I*> is = s->select(vmap);
theni.splice(theni.end(), is);
}
theni.push_back(new x0s::ISrcDst(MOVQ, thenv->to_arg(), tv));
Expand All @@ -202,7 +213,7 @@ x0s::F F::select() const
list<x0s::I*> instrs;
for (auto s : this->stmts)
{
list<x0s::I*> is = s->select();
list<x0s::I*> is = s->select(vars);
instrs.splice(instrs.end(), is);
}
instrs.push_back(new x0s::IRet(this->arg->to_arg()));
Expand Down
34 changes: 14 additions & 20 deletions rep/c0.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <list>
#include <string>
#include <vector>
#include <unordered_map>

#include "operators.h"
#include "type.h"
Expand All @@ -13,13 +14,13 @@ namespace c0
struct E
{
virtual ~E() { }
virtual std::list<x0s::I*> select(x0s::Var*) = 0;
virtual std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) = 0;
};

struct Arg : E
{
virtual ~Arg() { }
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
virtual x0s::Arg* to_arg() const = 0;
};

Expand All @@ -44,25 +45,18 @@ namespace c0
x0s::Arg* to_arg() const;
};

struct Global : Arg
{
Global(std::string varname) : name(varname) { }
std::string name;
x0s::Arg* to_arg() const;
};

// abstract statement either contains an if or a statement
struct AS
{
virtual ~AS() { }
virtual std::list<x0s::I*> select() = 0;
virtual std::list<x0s::I*> select(const std::unordered_map<std::string, int>&) = 0;
};


struct Read : E
{
Read() { }
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct Binop : E
Expand All @@ -72,7 +66,7 @@ namespace c0
b_ops op;
Arg* l;
Arg* r;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct Unop : E
Expand All @@ -81,7 +75,7 @@ namespace c0
~Unop() { delete v; }
u_ops op;
Arg* v;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct FunCall : E
Expand All @@ -90,15 +84,15 @@ namespace c0
~FunCall() { for (auto a : args) delete a; }
Arg* func;
std::vector<Arg*> args;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct Alloc : E
{
Alloc(int size, int tag) : size(size), tag(tag) { }
int size;
int tag;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct VecRef : E
Expand All @@ -107,7 +101,7 @@ namespace c0
~VecRef() { delete vec; }
Var* vec;
int index;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

struct VecSet : E
Expand All @@ -117,7 +111,7 @@ namespace c0
Var* vec;
int index;
Arg* asg;
std::list<x0s::I*> select(x0s::Var*);
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&, x0s::Var*) override;
};

//stmt
Expand All @@ -127,7 +121,7 @@ namespace c0
~S() { delete e; }
std::string v;
E* e;
std::list<x0s::I*> select();
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&);
};

struct If : AS
Expand All @@ -141,7 +135,7 @@ namespace c0
std::vector<AS*> elses;
Arg* thenv;
Arg* elsev;
std::list<x0s::I*> select();
std::list<x0s::I*> select(const std::unordered_map<std::string, int>&);
};

struct F
Expand All @@ -159,7 +153,7 @@ namespace c0
Arg* arg; //ret
int t;
x0s::F select() const;
};
};

struct P
{
Expand Down
Loading

0 comments on commit dd5213f

Please sign in to comment.