1 /* pkl-gen.h - Code generation pass for the poke compiler. */
2
3 /* Copyright (C) 2019, 2020, 2021 Jose E. Marchesi */
4
5 /* This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef PKL_GEN_H
20 #define PKL_GEN_H
21
22 #include <config.h>
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "pkl.h"
28 #include "pkl-ast.h"
29 #include "pkl-pass.h"
30 #include "pkl-asm.h"
31 #include "pkl-asm.h"
32 #include "pvm.h"
33
34 /* It would be very unlikely to have more than 24 declarations nested
35 in a poke program... if it ever happens, we will just increase
36 this, thats a promise :P (don't worry, there is an assertion that
37 will fire if this limit is surpassed.) */
38
39 #define PKL_GEN_MAX_PASM 25
40
41 /* Likewise for the contexts. If this hard limit is exceeded it is
42 most likely due to a bug in the gen pass. */
43
44 #define PKL_GEN_MAX_CTX 25
45
46 /* The following struct defines the payload of the code generation
47 phase.
48
49 COMPILER is the Pkl compiler driving the compilation.
50
51 PASM and PASM2 are stacks of macro-assemblers. Assemblers in PASM
52 are used for assembling the main program, struct mappers, and
53 functions. Assemblers in PASM2 are used for compiling struct
54 constructors.
55
56 CUR_PASM and CUR_PASM2 are the pointers to the top of PASM and
57 PASM2, respectively.
58
59 PROGRAM is the main PVM program being compiled. When the phase is
60 completed, the program is "finished" (in PVM parlance) and ready
61 to be used.
62
63 CONTEXT is an array implementing a stack of contexts. Each context
64 is a bitmap. See hte PKL_GEN_CTX_* constants below for the
65 significance of each bit. The initial context is initialized to 0.
66
67 CUR_CONTEXT is the index to CONTEXT and marks the top of the stack
68 of contexts. Initially 0.
69
70 ENDIAN is the endianness to be used when mapping and writing
71 integral types.
72
73 MAPPER_DEPTH and CONSTRUCTOR_DEPTH are used in the array mapper and
74 constructor generation handlers.
75
76 IN_FILE_P indicates whether the current source is a file, as
77 opposed to stdin (i.e. as opposed of compiling a statement.) */
78
79
80 struct pkl_gen_payload
81 {
82 pkl_compiler compiler;
83 pkl_asm pasm[PKL_GEN_MAX_PASM];
84 pkl_asm pasm2[PKL_GEN_MAX_PASM];
85 uint32_t context[PKL_GEN_MAX_CTX];
86 int cur_pasm;
87 int cur_pasm2;
88 int cur_context;
89 pvm_program program;
90 int endian;
91 int constructor_depth;
92 int mapper_depth;
93 int in_file_p;
94 };
95
96 typedef struct pkl_gen_payload *pkl_gen_payload;
97
98 /* At any given time the code generation phase can be in a set of
99 several possible contexts, which are generally mutually inclusive.
100 This set of contexts in maintained in a 32-bit long bitmap. The
101 following constants identify the supported contexts and their
102 corresponding bits in the bitmap. */
103
104 #define PKL_GEN_CTX_IN_STRUCT_DECL 0x01
105 #define PKL_GEN_CTX_IN_MAPPER 0x02
106 #define PKL_GEN_CTX_IN_CONSTRUCTOR 0x04
107 #define PKL_GEN_CTX_IN_WRITER 0x08
108 #define PKL_GEN_CTX_IN_LVALUE 0x10
109 #define PKL_GEN_CTX_IN_COMPARATOR 0x20
110 #define PKL_GEN_CTX_IN_PRINTER 0x40
111 #define PKL_GEN_CTX_IN_ARRAY_BOUNDER 0x80
112 #define PKL_GEN_CTX_IN_FUNCALL 0x200
113 #define PKL_GEN_CTX_IN_TYPE 0x400
114
115 extern struct pkl_phase pkl_phase_gen;
116
117 static inline void
pkl_gen_init_payload(pkl_gen_payload payload,pkl_compiler compiler)118 pkl_gen_init_payload (pkl_gen_payload payload, pkl_compiler compiler)
119 {
120 memset (payload, 0, sizeof (struct pkl_gen_payload));
121 payload->compiler = compiler;
122 }
123
124
125 #endif /* !PKL_GEN_H */
126