-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathcgen.c
113 lines (95 loc) · 2.93 KB
/
cgen.c
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
#include "defs.h"
#define extern_
#include "data.h"
#undef extern_
#include "gen.h"
#include "misc.h"
#include "sym.h"
#include "tree.h"
#include "types.h"
// Assembly code generator.
// Copyright (c) 2023,2024 Warren Toomey, GPL3
// Allocate space for the variables
// then free the symbol table.
void allocateGlobals(void) {
struct symtable *sym, *litsym;
int i;
// Load all the types and all the globals
loadGlobals();
// We now have all the types and all the globals in memory
// Generate the string literals first
for (sym=Symhead; sym!=NULL; sym=sym->next) {
if (sym->stype== S_STRLIT)
sym->st_label= genglobstr(sym->name);
}
// Now do the non string literals
// XXX To fix: sym=sym->next
for (sym=Symhead; sym!=NULL; ) {
if (sym->stype== S_STRLIT) { sym=sym->next; continue; }
// If this is a char pointer or an array of char pointers,
// replace any values in the initlist (which are symbol ids)
// with the associated string literal labels.
// Yes, P_CHAR+2 means array of char pointers.
if (sym->initlist!=NULL &&
(sym->type== pointer_to(P_CHAR) || sym->type == P_CHAR+2)) {
for (i=0; i<sym->nelems; i++)
if (sym->initlist[i]!=0) {
litsym= findSymbol(NULL, 0, sym->initlist[i]);
sym->initlist[i]= litsym->st_label;
}
}
genglobsym(sym);
sym=sym->next;
}
freeSymtable(); // Clear the symbol table
}
// Open the symbol table file and AST file
// Loop:
// Read in the next AST tree
// Generate the assembly code
// Free the in-memory symbol tables
int main(int argc, char **argv) {
struct ASTnode *node;
if (argc !=4) {
fprintf(stderr, "Usage: %s symfile astfile idxfile\n", argv[0]);
exit(1);
}
// Open the symbol table file
Symfile= fopen(argv[1], "r");
if (Symfile == NULL) {
fprintf(stderr, "Can't open %s\n", argv[1]); exit(1);
}
// Open the AST file
Infile= fopen(argv[2], "r");
if (Infile == NULL) {
fprintf(stderr, "Can't open %s\n", argv[2]); exit(1);
}
// Open the AST index offset file for read/writing
Idxfile= fopen(argv[3], "w+");
if (Idxfile == NULL) {
fprintf(stderr, "Can't open %s\n", argv[3]); exit(1);
}
// We write assembly to stdout
Outfile=stdout;
mkASTidxfile(); // Build the AST index offset file
freeSymtable(); // Clear the symbol table
genpreamble(); // Output the preamble
allocateGlobals(); // Allocate global variables
while (1) {
// Read the next function's top node in from file
node= loadASTnode(0, 1);
if (node==NULL) break;
// Generate the assembly code for the tree
genAST(node, NOLABEL, NOLABEL, NOLABEL, 0);
// Free the symbols in the in-memory symbol tables.
// Also free the AST node we loaded in
freeSymtable();
freeASTnode(node);
}
genpostamble(); // Output the postamble
freeSymtable();
fclose(Infile);
fclose(Symfile);
exit(0);
return(0);
}