-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathq_operations.h
125 lines (97 loc) · 2.89 KB
/
q_operations.h
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
#ifndef Q_OPERATIONS_H
#define Q_OPERATIONS_H
#include "global.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define Q_ZERO literal_zero
#define Q_ONE literal_one
#define Q_FALSE Q_ZERO
#define Q_TRUE Q_ONE
#define Q_JUMP_WHEN_FALSE(opd) (q_jump_condition_create(opd, Q_RELATIVE_OP_EQUAL, Q_FALSE))
#define Q_JUMP_WHEN_TRUE(opd) (q_jump_condition_create(opd, Q_RELATIVE_OP_NOT_EQUAL, Q_FALSE))
#define Q_UNKNOWN_JUMP_TARGET -1
struct q_operand {
enum {
OPD_TYPE_LITERAL,
OPD_TYPE_VARIABLE
} type;
union {
symtabEntry *varEntry;
struct {
const struct variable_type *type;
union {
int int_value;
float float_value;
} value;
} literal;
} data;
};
enum q_instruction_type {
Q_INSTR_TYPE_ASSIGN,
Q_INSTR_TYPE_CALC,
Q_INSTR_TYPE_JUMP,
Q_INSTR_TYPE_COND_JUMP,
Q_INSTR_TYPE_RET
};
struct q_op {
/* Generates code for this quadrupelcode statement. Returns the number of characters
* printed in the buffer */
int (*gen_code) (struct q_op *op, char *code_buf);
};
enum q_arithmetic_operator {
Q_ARITHMETIC_OP_NONE = 0,
Q_ARITHMETIC_OP_ADD,
Q_ARITHMETIC_OP_SUB,
Q_ARITHMETIC_OP_MUL,
Q_ARITHMETIC_OP_MOD,
Q_ARITHMETIC_OP_DIV
};
struct q_op_assignment {
struct q_op op;
symtabEntry *dest;
struct q_operand left_operand;
enum q_arithmetic_operator arith_operator;
struct q_operand right_operand;
};
enum q_relative_operator {
Q_RELATIVE_OP_LOWER = 0,
Q_RELATIVE_OP_LOWER_EQUAL,
Q_RELATIVE_OP_EQUAL,
Q_RELATIVE_OP_GREATER_EQUAL,
Q_RELATIVE_OP_GREATER,
Q_RELATIVE_OP_NOT_EQUAL
};
struct q_jump_condition {
struct q_operand left_operand;
enum q_relative_operator rel_operator;
struct q_operand right_operand;
};
struct q_op_jump {
struct q_op op; /* Pointer to parent "class" */
struct q_jump_condition *condition; /* Jump condition, NULL for unconditional jump */
int target; /* Index of target instruction */
};
struct q_op_ret {
struct q_op op;
struct q_operand *ret_value;
};
struct q_op_list {
struct q_op_list *next;
struct q_op op;
};
struct q_operand q_operand_init_variable(symtabEntry *varEntry);
extern const struct q_operand literal_zero;
extern const struct q_operand literal_one;
const struct variable_type *q_operand_get_type(struct q_operand operator);
int q_op_list_get_instr_count();
struct q_op *q_instr_add(enum q_instruction_type type, ...);
void q_instr_add_rel(symtabEntry *result, struct q_operand opd1, enum q_relative_operator relop, struct q_operand opd2);
struct q_op *q_op_list_add(size_t q_op_size);
struct q_op_list *q_op_list_create(struct q_op_list *op_list, size_t q_op_size);
const struct variable_type *q_op_assignment_get_result_type(struct q_operand left_operand,
struct q_operand right_operand);
struct q_jump_condition *q_jump_condition_create(struct q_operand left_operand, enum q_relative_operator rel_operator,
struct q_operand right_operand);
void q_op_gen_code(FILE *output_file);
#endif