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