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

📄 statement.c

📁 一个编译器修改的例子
💻 C
字号:
#include "error.h"#include "io.h"#include "salloc.h"#include "statement.h"int stackpointer = 0;int while_counter = 0;int global_if = 0;int global_end = 0;int global_repeat = 0;int global_for = 0;Statement *new_assignment_statement(Expression *lvalue, Expression *rvalue){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= assignment_stat;    ASSIGNMENT_STAT(stat).lvalue	= lvalue;    ASSIGNMENT_STAT(stat).rvalue	= rvalue;    return stat;}Statement *new_compound_statement(List *declarations, List *statements,				  Scope *scope){    Statement *stat			  = safe_malloc(sizeof(Statement));    stat->subtype			  = compound_stat;    COMPOUND_STAT(stat).declarations	  = declarations;    COMPOUND_STAT(stat).statements	  = statements;    COMPOUND_STAT(stat).scope		  = scope != 0 ? scope : current_scope;    COMPOUND_STAT(stat).must_delete_scope = scope != 0;    return stat;}Statement *new_delete_statement(Expression *expr){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= delete_stat;    DELETE_STAT(stat).expression	= expr;    return stat;}Statement *new_expression_statement(Expression *expr){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= expr_stat;    EXPR_STAT(stat).expression		= expr;    return stat;}Statement *new_for_statement(Expression *loop_variable,			     Expression *begin_value,			     Expression *end_value,			     Expression *increment_value,			     Statement  *body){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= for_stat;    FOR_STAT(stat).loop_variable	= loop_variable;    FOR_STAT(stat).begin_value		= begin_value;    FOR_STAT(stat).end_value		= end_value;    FOR_STAT(stat).increment_value	= increment_value;    FOR_STAT(stat).body			= body;    return stat;}Statement *new_if_statement(Expression *condition,			    Statement  *then_body,			    Statement  *else_body){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= if_stat;    IF_STAT(stat).condition		= condition;    IF_STAT(stat).then_body		= then_body;    IF_STAT(stat).else_body		= else_body;    return stat;}Statement *new_repeat_statement(Statement *body, Expression *condition){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= repeat_stat;    LOOP_STAT(stat).condition		= condition;    LOOP_STAT(stat).body		= body;    return stat;}Statement *new_return_statement(Expression *return_value, Token *token){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= return_stat;    RETURN_STAT(stat).return_value	= return_value;    RETURN_STAT(stat).token		= token;    return stat;}Statement *new_while_statement(Expression *condition, Statement *body){    Statement *stat			= safe_malloc(sizeof(Statement));    stat->subtype			= while_stat;    LOOP_STAT(stat).condition		= condition;    LOOP_STAT(stat).body		= body;    return stat;}void delete_statement(Statement *stat){    if (stat!= 0)    {	switch (stat->subtype)	{	    unsigned i;	    List     *declarations, *statements;	    case assignment_stat:		delete_expression(ASSIGNMENT_STAT(stat).lvalue);		delete_expression(ASSIGNMENT_STAT(stat).rvalue);		break;	    case compound_stat:		declarations = COMPOUND_STAT(stat).declarations;		statements   = COMPOUND_STAT(stat).statements;		for (i = 0; i < list_size(declarations); i ++)		    delete_declaration(list_index(declarations, i));		for (i = 0; i < list_size(statements); i ++)		    delete_statement(list_index(statements, i));		delete_list(declarations);		delete_list(statements);		if (COMPOUND_STAT(stat).must_delete_scope)		    delete_scope(COMPOUND_STAT(stat).scope);		break;	    case delete_stat:		delete_expression(DELETE_STAT(stat).expression);		break;	    case expr_stat:		delete_expression(EXPR_STAT(stat).expression);		break;	    case for_stat:		delete_expression(FOR_STAT(stat).loop_variable);		delete_expression(FOR_STAT(stat).begin_value);		delete_expression(FOR_STAT(stat).end_value);		delete_expression(FOR_STAT(stat).increment_value);		delete_statement(FOR_STAT(stat).body);		break;	    case if_stat:		delete_expression(IF_STAT(stat).condition);		delete_statement(IF_STAT(stat).then_body);		delete_statement(IF_STAT(stat).else_body);		break;	    case repeat_stat:		delete_expression(LOOP_STAT(stat).condition);		delete_statement(LOOP_STAT(stat).body);		break;	    case return_stat:		delete_expression(RETURN_STAT(stat).return_value);		delete_token(RETURN_STAT(stat).token);		break;	    case while_stat:		delete_expression(LOOP_STAT(stat).condition);		delete_statement(LOOP_STAT(stat).body);		break;	}	free(stat);    }}static void type_check_assigment_statement(Statement *stat){    char        *err;    Expression	*lvalue = ASSIGNMENT_STAT(stat).lvalue;    Expression	*rvalue = ASSIGNMENT_STAT(stat).rvalue;    Type	*ltype  = type_check_expression(lvalue);    Type	*rtype  = type_check_expression(rvalue);    if (!types_compatible(ltype, rtype))	error(lvalue->token, "Incompatible types in assignment");    if (!is_lvalue_(lvalue, &err))	error(lvalue->token, "%s is not an lvalue", err);}static void type_check_compound_statement(Statement *stat, Declaration *subprog){    unsigned i;    List     *statements = COMPOUND_STAT(stat).statements;    for (i = 0; i < list_size(statements); i ++)	type_check_statement(list_index(statements, i), subprog);}static void type_check_delete_statement(Statement *stat){    Type *t = type_check_expression(DELETE_STAT(stat).expression);    if (t != 0 && t->subtype != array_type && t->subtype != null_type)	error(DELETE_STAT(stat).expression->token,		"can only delete arrays or null expressions");}static void type_check_expression_statement(Statement *stat){    Type *t = type_check_expression(EXPR_STAT(stat).expression);    if (t == 0)	return;    if (t->subtype == subprog_type)	error(EXPR_STAT(stat).expression->token, "%s: a procedure or function may not be used as a value", EXPR_STAT(stat).expression->token->name);    else if (EXPR_STAT(stat).expression->subtype == expr_eq)	warning(EXPR_STAT(stat).expression->token, "the value of the equality operator is ignored (the assignment operator is ':=')");}static void type_check_for_statement(Statement *stat, Declaration *subprog){    struct for_stat *for_stat = &FOR_STAT(stat);    Type *loop_type  = type_check_expression(for_stat->loop_variable);    Type *begin_type = type_check_expression(for_stat->begin_value);    Type *end_type   = type_check_expression(for_stat->end_value);    Type *inc_type   = type_check_expression(for_stat->increment_value);    if (loop_type != 0 && loop_type->subtype != int_type)	error(for_stat->loop_variable->token, "loop variable must be int");    if (begin_type != 0 && begin_type->subtype != int_type)	error(for_stat->begin_value->token, "begin value must be int");    if (end_type != 0 && end_type->subtype != int_type)	error(for_stat->end_value->token, "end value must be int");    if (inc_type != 0 && inc_type->subtype != int_type)	error(for_stat->increment_value->token, "increment value must be int");    if (!is_lvalue(for_stat->loop_variable))	error(for_stat->loop_variable->token,	      "loop expression is not an lvalue");    type_check_statement(for_stat->body, subprog);}static void type_check_if_statement(Statement *stat, Declaration *subprog){    struct if_stat *if_stat = &IF_STAT(stat);    Type	   *type    = type_check_expression(if_stat->condition);    if (type != 0 && type->subtype != bool_type)	error(if_stat->condition->token, "if condition must be boolean");    type_check_statement(if_stat->then_body, subprog);    type_check_statement(if_stat->else_body, subprog);}static void type_check_repetition_statement(Statement *stat,					    Declaration *subprog){    struct loop_stat *loop_stat = &LOOP_STAT(stat);    Type	     *type	= type_check_expression(loop_stat->condition);    if (type != 0 && type->subtype != bool_type)	error(loop_stat->condition->token, "loop condition must be boolean");    type_check_statement(loop_stat->body, subprog);}static void type_check_return_statement(Statement *stat, Declaration *subprog){    struct return_stat *ret_stat = &RETURN_STAT(stat);    Expression	       *ret_val  = ret_stat->return_value;    if (subprog == 0)	return;    if (SUBPROG_DECL(subprog).return_type == 0)	abort();    if (SUBPROG_DECL(subprog).return_type->subtype != void_type)	if (ret_val != 0)	{	    Type *type = type_check_expression(ret_val);	    	    if (!types_compatible(SUBPROG_DECL(subprog).return_type, type))		error(ret_val->token, "incompatible types in return statement");	}	else	    error(ret_stat->token,	    	  "return statement must return value in function");    else if (ret_val != 0)	error(ret_val->token, "return statement returns value in procedure");}void type_check_statement(Statement *stat, Declaration *subprog){    if (stat != 0)	switch (stat->subtype)	{	    case assignment_stat:		type_check_assigment_statement(stat);		break;	    case compound_stat:		type_check_compound_statement(stat, subprog);		break;	    case delete_stat:		type_check_delete_statement(stat);		break;	    case expr_stat:		type_check_expression_statement(stat);		break;	    case for_stat:		type_check_for_statement(stat, subprog);		break;	    case if_stat:		type_check_if_statement(stat, subprog);		break;	    case repeat_stat:	    case while_stat:		type_check_repetition_statement(stat, subprog);		break;	    case return_stat:		type_check_return_statement(stat, subprog);	}}static void generate_assignment_statement(Statement *stat){    generate_expression(ASSIGNMENT_STAT(stat).lvalue);    putc('=', c_out);	#ifdef DEBUG	printf("=");	#endif    generate_expression(ASSIGNMENT_STAT(stat).rvalue);    fprintf(c_out, ";\n");	#ifdef DEBUG	printf(";\n");	#endif}static void generate_compound_statement(Statement *stat){    unsigned i;    List     *statements = COMPOUND_STAT(stat).statements;    fprintf(c_out, "{\n");	#ifdef DEBUG	printf("{\n");	#endif    generate_declaration_list(COMPOUND_STAT(stat).declarations);    for (i = 0; i < list_size(statements); i ++)	generate_statement(list_index(statements, i));    fprintf(c_out, "}\n");	#ifdef DEBUG	printf("}\n");	#endif}static void generate_delete_statement(Statement *stat){	    Expression *expr = DELETE_STAT(stat).expression;	    fprintf(c_out, "delete_array(");	#ifdef DEBUG	printf("delete_array(");	#endif    generate_expression(expr);    fprintf(c_out, ");\n");	#ifdef DEBUG	printf(");\n");	#endif}static void generate_expression_statement(Statement *stat){    generate_expression(EXPR_STAT(stat).expression);    fprintf(c_out, ";\n");	#ifdef DEBUG	printf(";\n");	#endif}static void generate_for_statement(Statement *stat){    if (FOR_STAT(stat).increment_value != 0)    {	fprintf(c_out, "{int e,s;for(");	#ifdef DEBUG	printf("{int e,s;for(");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	putc('=', c_out);	#ifdef DEBUG	printf("=");	#endif	generate_expression(FOR_STAT(stat).begin_value);	fprintf(c_out, ",e=");	#ifdef DEBUG	printf(",e=");	#endif	generate_expression(FOR_STAT(stat).end_value);	fprintf(c_out, ",s=");	#ifdef DEBUG	printf(",s=");	#endif	generate_expression(FOR_STAT(stat).increment_value);	fprintf(c_out, ";s<0?");	#ifdef DEBUG	printf(";s<0?");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	fprintf(c_out, ">=e:");	#ifdef DEBUG	printf(">=e:");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	fprintf(c_out, "<=e;");	#ifdef DEBUG	printf("<=e;");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	fprintf(c_out, "+=s){\n");	#ifdef DEBUG	printf("+=s){\n");	#endif    }    else    {	fprintf(c_out, "{int e;for(");	#ifdef DEBUG	printf("{int e;for(");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	putc('=', c_out);	#ifdef DEBUG	printf("=");	#endif	generate_expression(FOR_STAT(stat).begin_value);	fprintf(c_out, ",e=");	#ifdef DEBUG	printf(",e=");	#endif	generate_expression(FOR_STAT(stat).end_value);	putc(';', c_out);	#ifdef DEBUG	printf(";");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	fprintf(c_out, "<=e;");	#ifdef DEBUG	printf("<=e;");	#endif	generate_expression(FOR_STAT(stat).loop_variable);	fprintf(c_out, "++){\n");	#ifdef DEBUG	printf("++){\n");	#endif    }    generate_statement(FOR_STAT(stat).body);    fprintf(c_out, "}}\n");	#ifdef DEBUG	printf("}}\n");	#endif}static void generate_if_statement(Statement *stat){    fprintf(c_out, "if(");	#ifdef DEBUG	printf("if(");	#endif    generate_expression(IF_STAT(stat).condition);    fprintf(c_out, "){\n");	#ifdef DEBUG	printf("){\n");	#endif	    generate_statement(IF_STAT(stat).then_body);    if (IF_STAT(stat).else_body != 0)    {	fprintf(c_out, "}else{\n");	#ifdef DEBUG	printf("}else{\n");	#endif	generate_statement(IF_STAT(stat).else_body);    }    fprintf(c_out, "}\n");	#ifdef DEBUG	printf("}\n");	#endif}static void generate_repeat_statement(Statement *stat){    fprintf(c_out, "do{\n");	#ifdef DEBUG	printf("do{\n");	#endif    generate_statement(LOOP_STAT(stat).body);    fprintf(c_out, "}while(!(");	#ifdef DEBUG	printf("}while(!(");	#endif    generate_expression(LOOP_STAT(stat).condition);    fprintf(c_out, "));\n");	#ifdef DEBUG	printf("));\n");	#endif}static void generate_return_statement(Statement *stat){    if (RETURN_STAT(stat).return_value == 0)	{		fprintf(c_out, "return;\n");		#ifdef DEBUG		printf("return;\n");		#endif	}	else    {	fprintf(c_out, "return ");	#ifdef DEBUG	printf("return ");	#endif	generate_expression(RETURN_STAT(stat).return_value);	fprintf(c_out, ";\n");	#ifdef DEBUG	printf(";\n");	#endif    }}static void generate_while_statement(Statement *stat){    fprintf(c_out, "while(");	#ifdef DEBUG	printf("while(");	#endif    generate_expression(LOOP_STAT(stat).condition);    fprintf(c_out, "){\n");	#ifdef DEBUG	printf("){\n");	#endif    generate_statement(LOOP_STAT(stat).body);    fprintf(c_out, "}\n");	#ifdef DEBUG	printf("}\n");	#endif}void generate_statement(Statement *stat){    switch (stat->subtype)    {	case assignment_stat:	    generate_assignment_statement(stat);	    break;	case compound_stat:	    generate_compound_statement(stat);	    break;	case delete_stat:	    generate_delete_statement(stat);	    break;	case expr_stat:	    generate_expression_statement(stat);	    break;	case for_stat:	    generate_for_statement(stat);	    break;	case if_stat:	    generate_if_statement(stat);	    break;	case repeat_stat:	    generate_repeat_statement(stat);	    break;	case return_stat:	    generate_return_statement(stat);	    break;	case while_stat:	    generate_while_statement(stat);	    break;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -