forked from justinmeza/lci
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.h
202 lines (174 loc) · 9.13 KB
/
interpreter.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
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
/** Structures and functions for interpreting a parse tree. The interpreter
* traverses a parse tree in a depth-first manner, interpreting each node it
* reaches along the way. This is the last stage of the processing of a source
* code file.
*
* \file interpreter.h
*
* \author Justin J. Meza
*
* \date 2010 */
#ifndef __INTERPRETER_H__
#define __INTERPRETER_H__
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include "parser.h"
#include "unicode.h"
/** Gets the integer data associated with a ValueObject structure. */
#define getInteger(value) (value->data.i)
/** Gets the floating point data associated with a ValueObject structure. */
#define getFloat(value) (value->data.f)
/** Gets the string data associated with a ValueObject structure. */
#define getString(value) (value->data.s)
/** Denotes the type of a value. */
typedef enum {
VT_INTEGER, /**< An integer value. */
VT_FLOAT, /**< A floating point decimal value. */
VT_BOOLEAN, /**< A true/false value. */
VT_STRING, /**< A character string value. */
VT_NIL /**< Represents no value. */
} ValueType;
/** Stores the data associated with a ValueObject structure. */
typedef union {
int i; /**< Integer data. */
float f; /**< Floating point data. */
char *s; /**< Character string data. */
} ValueData;
/** Increments the semaphore of a ValueObject structure. */
#define V(value) (value->semaphore++)
/** Decrements the semaphore of a ValueObject structure. */
#define P(value) (value->semaphore--)
/** Stores a value.
*
* \see copyValueObject(ValueObject *)
* \see deleteValueObject(ValueObject *) */
typedef struct {
ValueType type; /**< The type of value stored. */
ValueData data; /**< The stored data. */
unsigned short semaphore; /**< A semaphore for value usage. */
} ValueObject;
/** Denotes the type of return encountered. */
typedef enum {
RT_DEFAULT, /**< A block of code returned after evaluating all of its statements. */
RT_BREAK, /**< A block of code within a LoopStmtNode or SwitchStmtNode returned via a break statement. */
RT_RETURN /**< A block of code within a FuncDefStmtNode called by a FuncCallExprNode returned (either with or without a value). */
} ReturnType;
/** Stores a return state. Returns are encountered when
* - a block of code evaluates all of its statements,
* - a block of code within a LoopStmt or SwitchStmt encountered a break statement, or
* - a block of code within a FunctionDefStmt called by a FunctionCallExpr encounters a ReturnStmt. */
typedef struct {
ReturnType type; /**< The type of return encountered. */
ValueObject *value; /**< The optional return value. */
} ReturnObject;
/** Stores the variables in a particular scope. Scopes are arranged
* heirarchically from global (the ancestor of all other scopes) to local (the
* temporary scope of a BlockNode).
*
* \see createScopeObject(ScopeObject *)
* \see deleteScopeObject(ScopeObject *) */
typedef struct scopeobject {
struct scopeobject *parent; /**< A pointer to the parent ScopeObject. */
ValueObject *impvar; /**< A pointer to the ValueObject representing the implicit variable for this scope. */
unsigned int numvals; /**< The number of ValueObject structures in \a values. */
IdentifierNode **names; /**< A pointer to the IdentifierNode structures naming the values in the scope. */
ValueObject **values; /**< A pointer to an array of ValueObject structures in the scope. */
} ScopeObject;
char *createString(char *);
ValueObject *createNilValueObject(void);
ValueObject *createBooleanValueObject(int);
ValueObject *createIntegerValueObject(int);
ValueObject *createFloatValueObject(float);
ValueObject *createStringValueObject(char *);
ValueObject *copyValueObject(ValueObject *);
void deleteValueObject(ValueObject *);
ReturnObject *createReturnObject(ReturnType, ValueObject *);
void deleteReturnObject(ReturnObject *);
ScopeObject *createScopeObject(ScopeObject *);
void deleteScopeObject(ScopeObject *);
ValueObject *getScopeValue(ScopeObject *, IdentifierNode *);
ValueObject *getLocalScopeValue(ScopeObject *, IdentifierNode *);
ValueObject *createScopeValue(ScopeObject *, IdentifierNode *);
ValueObject *updateScopeValue(ScopeObject *, IdentifierNode *, ValueObject *);
unsigned int isNumString(const char *);
unsigned int isHexString(const char *);
ValueObject *castBooleanExplicit(ValueObject *, ScopeObject *);
ValueObject *castIntegerExplicit(ValueObject *, ScopeObject *);
ValueObject *castFloatExplicit(ValueObject *, ScopeObject *);
ValueObject *castStringExplicit(ValueObject *, ScopeObject *);
ValueObject *castBooleanImplicit(ValueObject *, ScopeObject *);
ValueObject *castIntegerImplicit(ValueObject *, ScopeObject *);
ValueObject *castFloatImplicit(ValueObject *, ScopeObject *);
ValueObject *castStringImplicit(ValueObject *, ScopeObject *);
ValueObject *interpretExprNode(ExprNode *, ScopeObject *);
ReturnObject *interpretStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretStmtNodeList(StmtNodeList *, ScopeObject *);
ReturnObject *interpretBlockNode(BlockNode *, ScopeObject *);
int interpretMainNode(MainNode *);
ValueObject *interpretImpVarExprNode(ExprNode *, ScopeObject *);
ValueObject *interpretCastExprNode(ExprNode *, ScopeObject *);
ValueObject *interpretFuncCallExprNode(ExprNode *, ScopeObject *);
ValueObject *interpretIdentifierExprNode(ExprNode *, ScopeObject *);
ValueObject *interpretConstantExprNode(ExprNode *, ScopeObject *);
ValueObject *interpretNotOpExprNode(OpExprNode *, ScopeObject *);
ValueObject *interpretArithOpExprNode(OpExprNode *, ScopeObject *);
ValueObject *interpretBoolOpExprNode(OpExprNode *, ScopeObject *);
ValueObject *interpretEqualityOpExprNode(OpExprNode *, ScopeObject *);
ValueObject *interpretConcatOpExprNode(OpExprNode *, ScopeObject *);
ValueObject *interpretOpExprNode(ExprNode *, ScopeObject *);
ReturnObject *interpretCastStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretPrintStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretInputStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretAssignmentStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretDeclarationStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretIfThenElseStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretSwitchStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretBreakStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretReturnStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretLoopStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretFuncDefStmtNode(StmtNode *, ScopeObject *);
ReturnObject *interpretExprStmtNode(StmtNode *, ScopeObject *);
ValueObject *opAddIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opSubIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opMultIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opDivIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opMaxIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opMinIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opModIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opAddIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opSubIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opMultIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opDivIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opMaxIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opMinIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opModIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opAddFloatInteger(ValueObject *, ValueObject *);
ValueObject *opSubFloatInteger(ValueObject *, ValueObject *);
ValueObject *opMultFloatInteger(ValueObject *, ValueObject *);
ValueObject *opDivFloatInteger(ValueObject *, ValueObject *);
ValueObject *opMaxFloatInteger(ValueObject *, ValueObject *);
ValueObject *opMinFloatInteger(ValueObject *, ValueObject *);
ValueObject *opModFloatInteger(ValueObject *, ValueObject *);
ValueObject *opAddFloatFloat(ValueObject *, ValueObject *);
ValueObject *opSubFloatFloat(ValueObject *, ValueObject *);
ValueObject *opMultFloatFloat(ValueObject *, ValueObject *);
ValueObject *opDivFloatFloat(ValueObject *, ValueObject *);
ValueObject *opMaxFloatFloat(ValueObject *, ValueObject *);
ValueObject *opMinFloatFloat(ValueObject *, ValueObject *);
ValueObject *opModFloatFloat(ValueObject *, ValueObject *);
ValueObject *opEqBooleanBoolean(ValueObject *, ValueObject *);
ValueObject *opNeqBooleanBoolean(ValueObject *, ValueObject *);
ValueObject *opEqIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opNeqIntegerInteger(ValueObject *, ValueObject *);
ValueObject *opEqIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opNeqIntegerFloat(ValueObject *, ValueObject *);
ValueObject *opEqFloatInteger(ValueObject *, ValueObject *);
ValueObject *opNeqFloatInteger(ValueObject *, ValueObject *);
ValueObject *opEqFloatFloat(ValueObject *, ValueObject *);
ValueObject *opNeqFloatFloat(ValueObject *, ValueObject *);
ValueObject *opEqStringString(ValueObject *, ValueObject *);
ValueObject *opNeqStringString(ValueObject *, ValueObject *);
ValueObject *opEqNilNil(ValueObject *, ValueObject *);
ValueObject *opNeqNilNil(ValueObject *, ValueObject *);
#endif /* __INTERPRETER_H__ */