Skip to content

Commit ff83f01

Browse files
authored
Merge pull request #189 from ChAoSUnItY/feat/pragma
Support '#pragma once' and refine codebase
2 parents d4bd334 + 0d1b898 commit ff83f01

12 files changed

+149
-97
lines changed

mk/arm.mk

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export ARM_EXEC
1414
arm-specific-defs = \
1515
$(Q)$(PRINTF) \
1616
"/* target: ARM */\n$\
17+
\#pragma once\n$\
1718
\#define ARCH_PREDEFINED \"__arm__\" /* defined by GNU C and RealView */\n$\
1819
\#define ELF_MACHINE 0x28 /* up to ARMv7/Aarch32 */\n$\
1920
\#define ELF_FLAGS 0x5000200\n$\

mk/riscv.mk

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export RISCV_EXEC
1010
riscv-specific-defs = \
1111
$(Q)$(PRINTF) \
1212
"/* target: RISCV */\n$\
13+
\#pragma once\n$\
1314
\#define ARCH_PREDEFINED \"__riscv\" /* Older versions of the GCC toolchain defined __riscv__ */\n$\
1415
\#define ELF_MACHINE 0xf3\n$\
1516
\#define ELF_FLAGS 0\n$\

src/arm-codegen.c

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
/* Translate IR to target machine code */
99

1010
#include "arm.c"
11+
#include "defs.h"
12+
#include "globals.c"
1113

1214
void update_elf_offset(ph2_ir_t *ph2_ir)
1315
{

src/arm.c

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
* the current instruction.
2727
*/
2828

29+
#include "defs.h"
30+
2931
/* opcode */
3032
typedef enum {
3133
arm_and = 0,

src/defs.h

+86-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
* file "LICENSE" for information on usage and redistribution of this file.
66
*/
77

8-
#ifndef SHECC_DEFS_H
9-
#define SHECC_DEFS_H
8+
#pragma once
9+
#include <stdbool.h>
1010

1111
/* definitions */
1212

@@ -40,6 +40,7 @@
4040
#define MAX_NESTING 128
4141
#define MAX_OPERAND_STACK_SIZE 32
4242
#define MAX_ANALYSIS_STACK_SIZE 800
43+
#define MAX_INCLUSIONS 16
4344

4445
/* Default capacities for common data structures */
4546
/* Default arena size is initialized with 256 KiB */
@@ -92,6 +93,89 @@ typedef struct {
9293
hashmap_node_t **buckets;
9394
} hashmap_t;
9495

96+
/* lexer tokens */
97+
typedef enum {
98+
T_start, /* FIXME: it was intended to start the state machine. */
99+
T_numeric,
100+
T_identifier,
101+
T_comma, /* , */
102+
T_string, /* null-terminated string */
103+
T_char,
104+
T_open_bracket, /* ( */
105+
T_close_bracket, /* ) */
106+
T_open_curly, /* { */
107+
T_close_curly, /* } */
108+
T_open_square, /* [ */
109+
T_close_square, /* ] */
110+
T_asterisk, /* '*' */
111+
T_divide, /* / */
112+
T_mod, /* % */
113+
T_bit_or, /* | */
114+
T_bit_xor, /* ^ */
115+
T_bit_not, /* ~ */
116+
T_log_and, /* && */
117+
T_log_or, /* || */
118+
T_log_not, /* ! */
119+
T_lt, /* < */
120+
T_gt, /* > */
121+
T_le, /* <= */
122+
T_ge, /* >= */
123+
T_lshift, /* << */
124+
T_rshift, /* >> */
125+
T_dot, /* . */
126+
T_arrow, /* -> */
127+
T_plus, /* + */
128+
T_minus, /* - */
129+
T_minuseq, /* -= */
130+
T_pluseq, /* += */
131+
T_asteriskeq, /* *= */
132+
T_divideeq, /* /= */
133+
T_modeq, /* %= */
134+
T_lshifteq, /* <<= */
135+
T_rshifteq, /* >>= */
136+
T_xoreq, /* ^= */
137+
T_oreq, /* |= */
138+
T_andeq, /* &= */
139+
T_eq, /* == */
140+
T_noteq, /* != */
141+
T_assign, /* = */
142+
T_increment, /* ++ */
143+
T_decrement, /* -- */
144+
T_question, /* ? */
145+
T_colon, /* : */
146+
T_semicolon, /* ; */
147+
T_eof, /* end-of-file (EOF) */
148+
T_ampersand, /* & */
149+
T_return,
150+
T_if,
151+
T_else,
152+
T_while,
153+
T_for,
154+
T_do,
155+
T_typedef,
156+
T_enum,
157+
T_struct,
158+
T_sizeof,
159+
T_elipsis, /* ... */
160+
T_switch,
161+
T_case,
162+
T_break,
163+
T_default,
164+
T_continue,
165+
/* C pre-processor directives */
166+
T_cppd_include,
167+
T_cppd_define,
168+
T_cppd_undef,
169+
T_cppd_error,
170+
T_cppd_if,
171+
T_cppd_elif,
172+
T_cppd_else,
173+
T_cppd_endif,
174+
T_cppd_ifdef,
175+
T_cppd_ifndef,
176+
T_cppd_pragma
177+
} token_t;
178+
95179
/* builtin types */
96180
typedef enum {
97181
TYPE_void = 0,
@@ -467,5 +551,3 @@ typedef struct {
467551
var_t *var;
468552
int polluted;
469553
} regfile_t;
470-
471-
#endif

src/globals.c

+20
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,25 @@
55
* file "LICENSE" for information on usage and redistribution of this file.
66
*/
77

8+
#pragma once
89
#include <stdbool.h>
910
#include <stdlib.h>
1011

12+
#include "defs.h"
13+
14+
/* Lexer */
15+
char token_str[MAX_TOKEN_LEN];
16+
token_t next_token;
17+
char next_char;
18+
bool skip_newline = true;
19+
20+
bool preproc_match;
21+
22+
/* Point to the first character after where the macro has been called. It is
23+
* needed when returning from the macro body.
24+
*/
25+
int macro_return_idx;
26+
1127
/* Global objects */
1228

1329
block_list_t BLOCKS;
@@ -58,6 +74,8 @@ int constants_idx = 0;
5874

5975
source_t *SOURCE;
6076

77+
hashmap_t *INCLUSION_MAP;
78+
6179
/* ELF sections */
6280

6381
char *elf_code;
@@ -968,6 +986,7 @@ void global_init()
968986
PH2_IR_FLATTEN = malloc(MAX_IR_INSTR * sizeof(ph2_ir_t *));
969987
LABEL_LUT = malloc(MAX_LABEL * sizeof(label_lut_t));
970988
SOURCE = create_source(MAX_SOURCE);
989+
INCLUSION_MAP = hashmap_create(MAX_INCLUSIONS);
971990
ALIASES = malloc(MAX_ALIASES * sizeof(alias_t));
972991
CONSTANTS = malloc(MAX_CONSTANTS * sizeof(constant_t));
973992

@@ -1000,6 +1019,7 @@ void global_release()
10001019
free(PH2_IR_FLATTEN);
10011020
free(LABEL_LUT);
10021021
source_release(SOURCE);
1022+
hashmap_free(INCLUSION_MAP);
10031023
free(ALIASES);
10041024
free(CONSTANTS);
10051025

src/lexer.c

+4-93
Original file line numberDiff line numberDiff line change
@@ -7,99 +7,8 @@
77

88
#include <stdbool.h>
99

10-
/* lexer tokens */
11-
typedef enum {
12-
T_start, /* FIXME: it was intended to start the state machine. */
13-
T_numeric,
14-
T_identifier,
15-
T_comma, /* , */
16-
T_string, /* null-terminated string */
17-
T_char,
18-
T_open_bracket, /* ( */
19-
T_close_bracket, /* ) */
20-
T_open_curly, /* { */
21-
T_close_curly, /* } */
22-
T_open_square, /* [ */
23-
T_close_square, /* ] */
24-
T_asterisk, /* '*' */
25-
T_divide, /* / */
26-
T_mod, /* % */
27-
T_bit_or, /* | */
28-
T_bit_xor, /* ^ */
29-
T_bit_not, /* ~ */
30-
T_log_and, /* && */
31-
T_log_or, /* || */
32-
T_log_not, /* ! */
33-
T_lt, /* < */
34-
T_gt, /* > */
35-
T_le, /* <= */
36-
T_ge, /* >= */
37-
T_lshift, /* << */
38-
T_rshift, /* >> */
39-
T_dot, /* . */
40-
T_arrow, /* -> */
41-
T_plus, /* + */
42-
T_minus, /* - */
43-
T_minuseq, /* -= */
44-
T_pluseq, /* += */
45-
T_asteriskeq, /* *= */
46-
T_divideeq, /* /= */
47-
T_modeq, /* %= */
48-
T_lshifteq, /* <<= */
49-
T_rshifteq, /* >>= */
50-
T_xoreq, /* ^= */
51-
T_oreq, /* |= */
52-
T_andeq, /* &= */
53-
T_eq, /* == */
54-
T_noteq, /* != */
55-
T_assign, /* = */
56-
T_increment, /* ++ */
57-
T_decrement, /* -- */
58-
T_question, /* ? */
59-
T_colon, /* : */
60-
T_semicolon, /* ; */
61-
T_eof, /* end-of-file (EOF) */
62-
T_ampersand, /* & */
63-
T_return,
64-
T_if,
65-
T_else,
66-
T_while,
67-
T_for,
68-
T_do,
69-
T_typedef,
70-
T_enum,
71-
T_struct,
72-
T_sizeof,
73-
T_elipsis, /* ... */
74-
T_switch,
75-
T_case,
76-
T_break,
77-
T_default,
78-
T_continue,
79-
/* C pre-processor directives */
80-
T_cppd_include,
81-
T_cppd_define,
82-
T_cppd_undef,
83-
T_cppd_error,
84-
T_cppd_if,
85-
T_cppd_elif,
86-
T_cppd_else,
87-
T_cppd_endif,
88-
T_cppd_ifdef,
89-
T_cppd_ifndef
90-
} token_t;
91-
92-
char token_str[MAX_TOKEN_LEN];
93-
token_t next_token;
94-
char next_char;
95-
bool skip_newline = true;
96-
97-
bool preproc_match;
98-
99-
/* Point to the first character after where the macro has been called. It is
100-
* needed when returning from the macro body.
101-
*/
102-
int macro_return_idx;
10+
#include "defs.h"
11+
#include "globals.c"
10312

10413
bool is_whitespace(char c)
10514
{
@@ -223,6 +132,8 @@ token_t lex_token_internal(bool aliasing)
223132
return T_cppd_else;
224133
if (!strcmp(token_str, "#endif"))
225134
return T_cppd_endif;
135+
if (!strcmp(token_str, "#pragma"))
136+
return T_cppd_pragma;
226137
error("Unknown directive");
227138
}
228139

src/parser.c

+15
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
*/
77

88
#include <stdbool.h>
9+
#include <stdio.h>
910
#include <stdlib.h>
1011

12+
#include "../config"
13+
#include "defs.h"
14+
#include "globals.c"
15+
1116
/* C language syntactic analyzer */
1217
int global_var_idx = 0;
1318
int global_label_idx = 0;
@@ -513,6 +518,10 @@ bool read_preproc_directive()
513518
cppd_control_flow_skip_lines();
514519
return true;
515520
}
521+
if (lex_accept_internal(T_cppd_pragma, false)) {
522+
lex_expect(T_identifier);
523+
return true;
524+
}
516525

517526
return false;
518527
}
@@ -3399,6 +3408,10 @@ void load_source_file(char *file)
33993408

34003409
for (;;) {
34013410
if (!fgets(buffer, MAX_LINE_LEN, f)) {
3411+
break;
3412+
}
3413+
if (!strncmp(buffer, "#pragma once", 12) &&
3414+
hashmap_contains(INCLUSION_MAP, file)) {
34023415
fclose(f);
34033416
return;
34043417
}
@@ -3419,6 +3432,8 @@ void load_source_file(char *file)
34193432
SOURCE->size += strlen(buffer);
34203433
}
34213434
}
3435+
3436+
hashmap_put(INCLUSION_MAP, file, NULL);
34223437
fclose(f);
34233438
}
34243439

src/peephole.c

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
* file "LICENSE" for information on usage and redistribution of this file.
66
*/
77

8+
#include <stdbool.h>
9+
10+
#include "defs.h"
11+
#include "globals.c"
12+
813
bool is_fusible_insn(ph2_ir_t *ph2_ir)
914
{
1015
switch (ph2_ir->op) {

src/reg-alloc.c

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
* dead variable and does NOT wrtie it back to the stack.
1313
*/
1414

15+
#include <stdbool.h>
16+
17+
#include "defs.h"
18+
#include "globals.c"
19+
1520
/* Aligns size to nearest multiple of 4, this meets
1621
* ARMv7's alignment requirement.
1722
*

src/riscv-codegen.c

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
/* Translate IR to target machine code */
99

10+
#include "defs.h"
11+
#include "globals.c"
1012
#include "riscv.c"
1113

1214
void update_elf_offset(ph2_ir_t *ph2_ir)

0 commit comments

Comments
 (0)