forked from eugenechevski/CodeGeneratorSPL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode_seq.c
More file actions
executable file
·135 lines (124 loc) · 3.14 KB
/
code_seq.c
File metadata and controls
executable file
·135 lines (124 loc) · 3.14 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* $Id: code_seq.c,v 1.4 2024/11/08 21:01:43 leavens Exp $ */
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include "utilities.h"
#include "regname.h"
#include "code_seq.h"
static void code_seq_okay(code_seq seq)
{
// seq.first and seq.last are either both null or both not null
assert((seq.first == NULL) == (seq.last == NULL));
}
// Return an empty code_seq
code_seq code_seq_empty()
{
code_seq ret;
ret.first = NULL;
ret.last = NULL;
code_seq_okay(ret);
return ret;
}
// Requires: c != NULL
// Return a code_seq containing just the given code
code_seq code_seq_singleton(code *c)
{
code_seq ret;
ret.first = c;
ret.last = c;
code_seq_okay(ret);
return ret;
}
// Is seq empty?
bool code_seq_is_empty(code_seq seq)
{
code_seq_okay(seq);
return seq.first == NULL;
}
// Requires: !code_seq_is_empty(seq)
// Return the first element of the given code sequence, seq
code *code_seq_first(code_seq seq)
{
assert(!code_seq_is_empty(seq));
return seq.first;
}
// Requires: !code_seq_is_empty(seq)
// Return a new code_seq containing
// the rest of the given sequence, seq
// Note that seq is not modified
code_seq code_seq_rest(code_seq seq)
{
assert(!code_seq_is_empty(seq));
code *first = seq.first;
code_seq ret;
ret.first = first->next;
if (ret.first == NULL) {
ret.last = NULL;
} else {
ret.last = seq.last;
}
code_seq_okay(ret);
return ret;
}
// Return the size (number of instructions/words) in seq
unsigned int code_seq_size(code_seq seq)
{
unsigned int ret = 0;
while (!code_seq_is_empty(seq)) {
ret++;
seq = code_seq_rest(seq);
}
return ret;
}
// Requires: !code_seq_is_empty(seq)
// Return the last element in the given sequence
code *code_seq_last_elem(code_seq seq)
{
assert(!code_seq_is_empty(seq));
return seq.last;
}
// Requires: c != NULL && seq != NULL
// Modify seq to add the given code *c added to its end
void code_seq_add_to_end(code_seq *seq, code *c)
{
assert(c != NULL);
if (code_seq_is_empty(*seq)) {
seq->first = c;
seq->last = c;
} else {
// assert(!code_seq_is_empty(seq));
code *last = code_seq_last_elem(*seq);
last->next = c;
c->next = NULL;
seq->last = c;
}
code_seq_okay(*seq);
}
// Requires: s1 != NULL && s2 != NULL
// Modifies s1 to be the concatenation of s1 followed by s2
void code_seq_concat(code_seq *s1, code_seq s2)
{
if (code_seq_is_empty(*s1)) {
s1->first = s2.first;
s1->last = s2.last;
} else if (code_seq_is_empty(s2)) {
; // s1 is already their concatenation
} else {
code *last = code_seq_last_elem(*s1);
// assert(last != NULL);
last->next = s2.first;
s1->last = s2.last;
}
code_seq_okay(*s1);
}
// Requires: out is open for writing.
// Print the instructions in the code_seq to out
// in assembly language format
void code_seq_debug_print(FILE *out, code_seq seq)
{
while(!code_seq_is_empty(seq)) {
fprintf(out, "%s\n",
instruction_assembly_form(0, code_seq_first(seq)->instr));
seq = code_seq_rest(seq);
}
}