-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathir.hpp
155 lines (107 loc) · 2.42 KB
/
ir.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef SLIP_IR_HPP
#define SLIP_IR_HPP
#include "variant.hpp"
#include "ref.hpp"
#include "base.hpp"
#include "symbol.hpp"
#include "string.hpp"
#include "vector.hpp"
#include <map>
struct sexpr;
namespace ast {
struct expr;
}
namespace ir {
struct expr;
struct closure;
struct branch;
struct match;
struct call;
// local variable access
struct local {
std::size_t index;
inline local(std::size_t index) : index(index) { }
};
// capture variable access
struct capture {
std::size_t index;
inline capture(std::size_t index) : index(index) { }
};
// global variable access
struct global {
symbol name;
};
// global def
struct def {
symbol name;
};
template<class T>
struct lit {
const T value;
};
struct drop { std::size_t count=1; };
struct block {
vector<expr> items;
};
// scope exit: pop result, pop locals and push result back
struct exit {
std::size_t locals;
};
// attribute selection
struct sel {
symbol attr;
};
struct import {
const symbol package;
};
struct call {
std::size_t argc;
};
// TODO this one needs help from the typechecker
struct use;
struct record {
vector<symbol> attrs;
};
struct expr : variant<lit<unit>, lit<boolean>, lit<integer>, lit<real>, lit<string>,
local, capture, global,
call,
ref<closure>,
block, exit, drop,
ref<branch>, ref<match>,
import, ref<use>,
def,
sel, record> {
using expr::variant::variant;
};
struct use {
const expr env;
use(expr env):
env(env) { }
};
struct closure {
const std::size_t argc;
const vector<expr> captures;
const block body;
closure(std::size_t argc, vector<expr> captures, block body);
};
struct branch {
const expr then;
const expr alt;
branch(expr then, expr alt):
then(then),
alt(alt) { }
};
struct match {
using cases_type = std::map<symbol, expr>;
const cases_type cases;
const expr fallback;
match(cases_type cases, expr fallback):
cases(std::move(cases)),
fallback(fallback) { }
};
// toplevel compilation
expr compile(const ast::expr& self);
//
sexpr repr(const expr& self);
}
#endif