forked from nick-jn/uni-project-20465
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatement.c
executable file
·214 lines (180 loc) · 6.27 KB
/
statement.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*The language statement. To be generated by the parser upon a succesful
parsing of the line. Contains all the relevant data on the statment
to be passed on to the assembly module.*/
#include <stdio.h>
#include <stdlib.h>
#include "bool.h"
#include "clist.h"
#include "token.h"
#include "statement.h"
/*Creates a new operand_t.*/
operand_t *create_operand(int starting_index, int length,
add_mode addmode, operand_data *data) {
operand_t *newoper = malloc(sizeof(operand_t));
if (newoper == NULL) {
fprintf(stderr, "Malloc failure");
exit(1);
}
newoper->starting_index = starting_index;
newoper->length = length;
newoper->addmode = addmode;
newoper->data = data;
return newoper;
}
/*Creates a new stat_instr_t.*/
stat_instr_t *create_stat_inst(int opcode, operand_t *src, operand_t *dst) {
stat_instr_t *new_statinst = malloc(sizeof(stat_instr_t));
if (new_statinst == NULL) {
puts("Error, malloc failure in get_stat: "
"instr_statement");
exit(1);
}
new_statinst->opcode = opcode;
new_statinst->operand_src = src;
new_statinst->operand_dst = dst;
return new_statinst;
}
/*Creates a new stat_ddir_t.*/
stat_ddir_t *create_stat_ddir(data_dir datadir, void *data) {
stat_ddir_t *new_statddir = malloc(sizeof(stat_ddir_t));
if (new_statddir == NULL) {
fprintf(stderr, "Error, malloc failure in create_stat_ddir.");
exit(1);
}
new_statddir->datadir = datadir;
new_statddir->data = data;
return new_statddir;
}
/*Creates a new ddir_struct_t.*/
ddir_struct_t *create_ddir_struct(int num, char *string) {
ddir_struct_t *new_structddir = malloc(sizeof(ddir_struct_t));
if (new_structddir == NULL) {
fprintf(stderr, "Error, malloc failure in create_ddir_struct.");
exit(1);
}
new_structddir->num = num;
new_structddir->string = string;
return new_structddir;
}
/*Creates a new ddir_data_t.*/
ddir_data_t *create_ddir_data(int num_of_items, c_list *last_data) {
ddir_data_t *new_data = malloc(sizeof(ddir_data_t));
if (new_data == NULL) {
fprintf(stderr, "Error, malloc failure in create_ddir_data.");
exit(1);
}
new_data->num_of_items = num_of_items;
new_data->last_data = last_data;
return new_data;
}
/*Frees the passed operand.*/
void destroy_operand(operand_t *operand) {
/*no freeing of tokens*/
if (operand != NULL) {
if (operand->addmode == addmode_struct) {
free(operand->data->structure);
}
free(operand->data);
free(operand);
}
}
/*Frees the statement.*/
void destroy_statement(void *stat, stat_type stype) {
stat_instr_t *p_inst;
stat_ddir_t *p_ddir;
if (stat != NULL) {
if (stype == stype_instruction) {
p_inst = (stat_instr_t*)stat;
destroy_operand(p_inst->operand_src);
destroy_operand(p_inst->operand_dst);
} else if (stype == stype_datadir) {
p_ddir = (stat_ddir_t*)stat;
if (p_ddir->datadir == datadir_data) {
free(p_ddir->data);
} else if (p_ddir->datadir == datadir_struct) {
free((ddir_struct_t*)p_ddir->data);
} else if (p_ddir->datadir == datadir_string) {
free(p_ddir->data);
}
}
free(stat);
}
}
/*DEBUG Prints the contents of the passed operand.*/
void print_operand(operand_t *operand) {
if (operand == NULL) {
return;
}
switch (operand->addmode) {
case addmode_imm:
printf("\tIMM, %d\n", operand->data->number);
break;
case addmode_dir:
printf("\tDIR, %s\n", operand->data->identifier->tokstr);
break;
case addmode_struct:
printf("\tSTRUCT, %s.%d\n",
operand->data->structure->identifier->tokstr,
operand->data->structure->field);
break;
case addmode_reg:
printf("\tREG, %d\n", operand->data->reg_num);
break;
}
}
/*DEBUG Prints the contents of the passed statement.*/
void print_statement(void *statement, stat_type stype) {
c_list *p_data_list;
stat_instr_t *instr;
stat_ddir_t *datadir;
if (statement == NULL) {
return;
}
if (stype == stype_instruction) {
instr = statement;
puts("Instruction statement.");
printf("Operator: %s\n",
get_toktype_string(instr->opcode+toktype_operator_mov));
if (instr->operand_src != NULL) {
puts("Operand src:");
print_operand(instr->operand_src);
} else {
puts("Operand src:\n\tNULL");
}
if (instr->operand_dst != NULL) {
puts("Operand dst:");
print_operand(instr->operand_dst);
} else {
puts("Operand dst:\n\tNULL");
}
} else if (stype == stype_datadir) {
datadir = statement;
puts("Datadir statement.");
printf("Type: %s\n",
get_toktype_string(datadir->datadir+toktype_datadir_data));
switch (datadir->datadir) {
case datadir_data:
p_data_list = ((ddir_data_t*)(datadir->data))->last_data->next;
printf("Data: ");
do {
printf("%u ", *(unsigned int*)(p_data_list->item));
p_data_list = p_data_list->next;
} while (p_data_list !=
((ddir_data_t*)(datadir->data))->last_data->next);
putchar('\n');
break;
case datadir_struct:
printf("Data: %d %s\n",
((ddir_struct_t*)(datadir->data))->num,
((ddir_struct_t*)(datadir->data))->string);
break;
case datadir_string:
printf("Data: %s\n", (char*)(datadir->data));
break;
default: /*entry, extern*/
printf("Data: %s\n", ((token*)(datadir->data))->tokstr);
break;
}
}
putchar('\n');
}