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
|
#ifndef POSTHASTE_LOWER_H
#define POSTHASTE_LOWER_H
/* stuff related to lowering AST to bytecode */
#include <posthaste/ast.h>
#include <posthaste/vec.h>
#include <ejit/ejit.h>
enum insn_kind {
LABEL, /* no-op during interpretation,
used by JIT engine to keep track of jump branch destinations.
Each branch/jump must have a corresponding label!*/
CALL,
MOVE,
ADD,
SUB,
MUL,
DIV,
ARG, /* push location to arg stack */
RETVAL, /* move return value to location */
PRINT_DATE,
PRINT_STRING,
PRINT_INT,
PRINT_BOOL,
PRINT_NEWLINE,
PRINT_SPACE,
DATE_ADD,
DATE_SUB,
DATE_DIFF,
STORE_DAY, /* x.day etc */
STORE_MONTH,
STORE_YEAR,
LOAD_DAY, /* x'day etc */
LOAD_MONTH,
LOAD_YEAR,
LOAD_WEEKDAY,
LOAD_WEEKNUM,
TODAY, /* the builtin Today() is lowered to a single instruction */
RET, /* return with value */
STOP, /* return without value */
CONST, /* push a constant value to loc */
EQ,
LT,
NEG, /* negation, -x */
B, /* branch if non-zero */
BZ, /* branch if zero */
J, /* jump */
};
struct insn {
enum insn_kind k;
/* output location */
struct loc o;
/* input locations */
struct loc i0;
struct loc i1;
/* potential constant value */
union {
int64_t v;
char *s;
};
};
/* after lowering, there's no real difference between posthaste 'functions' and
* 'procedures', so I just use fn to refer to either or */
struct fn {
char *name;
size_t idx;
/* virtual stack pointer used during lowering to choose where to place
* values */
size_t sp;
/* maximum stack pointer value to know how much stack space to allocate */
size_t max_sp;
/* used by jit */
/* how many formal parameters */
size_t params;
struct ejit_func *f;
};
int lower_ast(struct ast *tree);
struct fn *find_fn(size_t idx);
size_t num_globals();
void destroy_lowering();
static inline bool is_null_loc(struct loc l)
{
return l.g == 1 && l.s == 0;
}
#endif /* POSTHASTE_LOWER_H */
|