📄 expression.h
字号:
#ifndef EXPRESSION_H
#define EXPRESSION_H
typedef struct expression Expression;
#include <assert.h>
#include "bool.h"
#include "list.h"
#include "scope.h"
#include "token.h"
#include "type.h"
typedef enum
{
expr_and = 10,
expr_bool_const,
expr_char_const,
expr_div,
expr_eq,
expr_func_call,
expr_ge,
expr_gt,
expr_ident,
expr_index,
expr_int_const,
expr_min,
expr_mul,
expr_ne,
expr_new,
expr_not,
expr_null,
expr_or,
expr_plus,
expr_real_const,
expr_se,
expr_size,
expr_st,
expr_string_const,
expr_unary_min,
expr_unary_plus,
expr_record /* add : adding a new record type of an expression*/
}
Expr_subtype;
/* Expressions are stored in 'Expression'-type structures. The subtype
* field indicates the type of the expression (listed in Expr_subtype).
* Depending on this type, the union un may contain fields specific to
* function call, indentifier, or string constant expressions. These
* should be accessed using the EXPR_FUNC_CALL, EXPR_IDENT,
* EXPR_STRING_CONSTANT defines! For most expressions all necessary data
* is stored in the two operand fields, which point to other expressions.
* For example, '3+4' would be represented as an expression of type
* expr_plus, with operand[0] and operand[1] pointing to two expressions
* of type expr_int_const.
*/
struct expression
{
Expr_subtype subtype;
Token *token;
Expression *operand [2];
Type *type;
union
{
struct
{
List *formal_args; /* List<Declaration *> */
List *actual_args; /* List<Expression *> */
}
func_call;
struct
{
Scope *scope;
}
identifier;
struct
{
unsigned index;
unsigned length;
}
string_const;
}
un;
};
/* Enforce that expression e is of subtype st. The result is again e. To
* prevent double evaluation of the macro argument, the argument is temporarily
* stored in the __expr variable.
*/
#define ASSERT_EXPR_SUBTYPE(e,st) (__expr = (e), assert(__expr->subtype == st), __expr)
extern Expression *__expr;
/* Macros for less verbose access to the members of the structs within
* the union. These macros also check that they are applied to appropriate
* instances of the Expression struct.
*
* In essence, these macros perform (e)->un.xxx
*/
#define EXPR_FUNC_CALL(e) \
(ASSERT_EXPR_SUBTYPE(e, expr_func_call)->un.func_call)
#define EXPR_IDENT(e) \
(ASSERT_EXPR_SUBTYPE(e, expr_ident)->un.identifier)
#define EXPR_STRING_CONST(e) \
(ASSERT_EXPR_SUBTYPE(e, expr_string_const)->un.string_const)
/*
#define EXPR_RECORD(e) \
(ASSERT_EXPR_SUBTYPE(e, expr_record)->un.record_var)
*/
Expression *new_expression(Expr_subtype, Token *,
Expression *left, Expression *right);
void delete_expression(Expression *);
Type *type_check_expression(Expression *);
Bool is_lvalue_(Expression *, char **);
#define is_lvalue(e) is_lvalue_((e), NULL)
void generate_expression(Expression *);
/* During type checking, all string constants are listed in 'string_list'.
* At code generation time, this list is converted to a C as an array of
* strings.
*/
void generate_string_list(void);
extern List *string_list;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -