⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.h

📁 一个编译器修改的例子
💻 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 + -