summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/DumpIR.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/DumpIR.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/DumpIR.c')
-rw-r--r--compiler_and_linker/unsorted/DumpIR.c729
1 files changed, 729 insertions, 0 deletions
diff --git a/compiler_and_linker/unsorted/DumpIR.c b/compiler_and_linker/unsorted/DumpIR.c
new file mode 100644
index 0000000..5f6eea4
--- /dev/null
+++ b/compiler_and_linker/unsorted/DumpIR.c
@@ -0,0 +1,729 @@
+#include "compiler/DumpIR.h"
+#include "compiler/CFunc.h"
+#include "compiler/CInt64.h"
+#include "compiler/CMachine.h"
+#include "compiler/CMangler.h"
+#include "compiler/CParser.h"
+#include "compiler/Exceptions.h"
+#include "compiler/Switch.h"
+#include "compiler/enode.h"
+#include "compiler/objects.h"
+#include "compiler/types.h"
+
+static FILE *outfile;
+
+// forward decls
+static void spell(Type *type, char *buf);
+
+static void WritePString(FILE *file, char *str, int len) {
+ while (len--) {
+ switch (*str) {
+ case 0:
+ fputs("\\x00", file);
+ break;
+ case 7:
+ fputs("\\a", file);
+ break;
+ case 8:
+ fputs("\\b", file);
+ break;
+ case 12:
+ fputs("\\f", file);
+ break;
+ case 10:
+ fputs("\\n", file);
+ break;
+ case 13:
+ fputs("\\r", file);
+ break;
+ case 9:
+ fputs("\\t", file);
+ break;
+ case 11:
+ fputs("\\v", file);
+ break;
+ case '"':
+ case '\'':
+ case '?':
+ case '\\':
+ fputc('\\', file);
+ default:
+ fputc(*str, file);
+ break;
+ }
+ str++;
+ }
+}
+
+static void WriteCString(FILE *file, char *str) {
+ WritePString(file, str, strlen(str));
+}
+
+static void StaticSetupDumpIR(void) {
+}
+
+void SetupDumpIR(void) {
+ // unknown args
+ StaticSetupDumpIR();
+}
+
+void CleanupDumpIR(void) {
+#ifdef CW_ENABLE_PCODE_DEBUG
+ // this code is not based on the original as we don't have it
+ if (outfile) {
+ fclose(outfile);
+ outfile = NULL;
+ }
+#endif
+}
+
+void DumpIR(Statement *statements, Object *func) {
+#ifdef CW_ENABLE_PCODE_DEBUG
+ // this code is not based on the original as we don't have it
+ if (copts.debuglisting) {
+ if (!outfile)
+ outfile = fopen("irdump.txt", "a");
+
+ fputs("--- BEGIN IR DUMP ---\r", outfile);
+ while (statements) {
+ switch (statements->type) {
+ case ST_NOP:
+ fputs("ST_NOP\r", outfile);
+ break;
+ case ST_LABEL:
+ fputs("ST_LABEL\r", outfile);
+ break;
+ case ST_GOTO:
+ fputs("ST_GOTO\r", outfile);
+ break;
+ case ST_EXPRESSION:
+ fputs("ST_EXPRESSION\r", outfile);
+ DumpExpression(statements->expr, 1);
+ break;
+ case ST_SWITCH:
+ fputs("ST_SWITCH\r", outfile);
+ DumpExpression(statements->expr, 1);
+ break;
+ case ST_IFGOTO:
+ fputs("ST_IFGOTO\r", outfile);
+ DumpExpression(statements->expr, 1);
+ break;
+ case ST_IFNGOTO:
+ fputs("ST_IFNGOTO\r", outfile);
+ DumpExpression(statements->expr, 1);
+ break;
+ case ST_RETURN:
+ fputs("ST_RETURN\r", outfile);
+ if (statements->expr)
+ DumpExpression(statements->expr, 1);
+ break;
+ case ST_OVF:
+ fputs("ST_OVF\r", outfile);
+ break;
+ case ST_EXIT:
+ fputs("ST_EXIT\r", outfile);
+ break;
+ case ST_ENTRY:
+ fputs("ST_ENTRY\r", outfile);
+ break;
+ case ST_BEGINCATCH:
+ fputs("ST_BEGINCATCH\r", outfile);
+ break;
+ case ST_ENDCATCH:
+ fputs("ST_ENDCATCH\r", outfile);
+ break;
+ case ST_ENDCATCHDTOR:
+ fputs("ST_ENDCATCHDTOR\r", outfile);
+ break;
+ case ST_GOTOEXPR:
+ fputs("ST_GOTOEXPR\r", outfile);
+ break;
+ case ST_ASM:
+ fputs("ST_ASM\r", outfile);
+ break;
+ case ST_BEGINLOOP:
+ fputs("ST_BEGINLOOP\r", outfile);
+ break;
+ case ST_ENDLOOP:
+ fputs("ST_ENDLOOP\r", outfile);
+ break;
+ }
+ statements = statements->next;
+ }
+ fputs("--- END IR DUMP ---\r", outfile);
+ fflush(outfile);
+ }
+#endif
+}
+
+void DumpExpression(ENode *expr, int indent) {
+ static int bt;
+ static int i;
+ static char *nodenames[] = {
+ "EPOSTINC",
+ "EPOSTDEC",
+ "EPREINC",
+ "EPREDEC",
+ "EINDIRECT",
+ "EMONMIN",
+ "EBINNOT",
+ "ELOGNOT",
+ "EFORCELOAD",
+ "EMUL",
+ "EMULV",
+ "EDIV",
+ "EMODULO",
+ "EADDV",
+ "ESUBV",
+ "EADD",
+ "ESUB",
+ "ESHL",
+ "ESHR",
+ "ELESS",
+ "EGREATER",
+ "ELESSEQU",
+ "EGREATEREQU",
+ "EEQU",
+ "ENOTEQU",
+ "EAND",
+ "EXOR",
+ "EOR",
+ "ELAND",
+ "ELOR",
+ "EASS",
+ "EMULASS",
+ "EDIVASS",
+ "EMODASS",
+ "EADDASS",
+ "ESUBASS",
+ "ESHLASS",
+ "ESHRASS",
+ "EANDASS",
+ "EXORASS",
+ "EORASS",
+ "ECOMMA",
+ "EPMODULO",
+ "EROTL",
+ "EROTR",
+ "EBCLR",
+ "EBTST",
+ "EBSET",
+ "ETYPCON",
+ "EBITFIELD",
+ "EINTCONST",
+ "EFLOATCONST",
+ "ESTRINGCONST",
+ "ECOND",
+ "EFUNCCALL",
+ "EFUNCCALLP",
+ "EOBJREF",
+ "EMFPOINTER",
+ "ENULLCHECK",
+ "EPRECOMP",
+ "ETEMP",
+ "EARGOBJ",
+ "ELOCOBJ",
+ "ELABEL",
+ "ESETCONST",
+ "ENEWEXCEPTION",
+ "ENEWEXCEPTIONARRAY",
+ "EINITTRYCATCH",
+ "EOBJLIST",
+ "EMEMBER",
+ "ETEMPLDEP",
+ "EINSTRUCTION",
+ "EDEFINE",
+ "EREUSE",
+ "EASSBLK",
+ "EVECTOR128CONST",
+ "ECONDASS",
+ NULL
+ };
+ char buf[64];
+ ENodeList *list;
+
+ while (1) {
+ for (i = 0; i < indent; i++)
+ fputc('\t', outfile);
+
+ if (expr->flags)
+ fprintf(outfile, "%s {%02X}", nodenames[expr->type], expr->flags);
+ else
+ fprintf(outfile, "%s", nodenames[expr->type]);
+
+ switch (expr->type) {
+ case EINTCONST:
+ if (expr->rtype->size > 4) {
+ fprintf(outfile,
+ "[0x%.8" PRIX32 "%.8" PRIX32 "]",
+ expr->data.intval.hi, expr->data.intval.lo);
+ } else {
+ fprintf(outfile,
+ "[%" PRId32 "]",
+ expr->data.intval.lo);
+ }
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case EFLOATCONST:
+ CMach_PrintFloat(buf, expr->data.floatval);
+ fprintf(outfile, "[%s]", buf);
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case ESTRINGCONST:
+ if (expr->data.string.ispascal) {
+ fputs("[\"", outfile);
+ WritePString(outfile, expr->data.string.data, expr->data.string.size);
+ fputs("\"]", outfile);
+ } else {
+ fputs("[\"", outfile);
+ WriteCString(outfile, expr->data.string.data);
+ fputs("\"]", outfile);
+ }
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case EVECTOR128CONST:
+ fprintf(outfile,
+ "[0x%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "%.8" PRIX32 "]",
+ expr->data.vector128val.ul[0],
+ expr->data.vector128val.ul[1],
+ expr->data.vector128val.ul[2],
+ expr->data.vector128val.ul[3]);
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case ECOND:
+ case ECONDASS:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ DumpExpression(expr->data.cond.cond, indent + 1);
+ DumpExpression(expr->data.cond.expr1, indent + 1);
+ expr = expr->data.cond.expr2;
+ indent++;
+ break;
+
+ case EFUNCCALL:
+ case EFUNCCALLP:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ DumpExpression(expr->data.funccall.funcref, indent + 1);
+ for (list = expr->data.funccall.args; list; list = list->next)
+ DumpExpression(list->node, indent + 1);
+ return;
+
+ case EOBJREF:
+ switch (expr->data.objref->datatype) {
+ case DFUNC:
+ fprintf(outfile, "[%s{PR}]", CMangler_GetLinkName(expr->data.objref)->name);
+ break;
+ case DDATA:
+ fprintf(outfile, "[%s{RW}]", CMangler_GetLinkName(expr->data.objref)->name);
+ break;
+ case DNONLAZYPTR:
+ fprintf(outfile, "[%s{NL}]", CMangler_GetLinkName(expr->data.objref)->name);
+ break;
+ default:
+ fprintf(outfile, "[%s]", expr->data.objref->name->name);
+ break;
+ }
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ ENODE_CASE_DIADIC_1:
+ case ELAND:
+ case ELOR:
+ ENODE_CASE_ASSIGN:
+ case ECOMMA:
+ case EPMODULO:
+ case EROTL:
+ case EROTR:
+ case EBTST:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ DumpExpression(expr->data.diadic.left, indent + 1);
+ expr = expr->data.diadic.right;
+ indent++;
+ break;
+
+ ENODE_CASE_MONADIC:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ expr = expr->data.monadic;
+ indent++;
+ break;
+
+ case EMFPOINTER:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ DumpExpression(expr->data.mfpointer.accessnode, indent + 1);
+ expr = expr->data.mfpointer.mfpointer;
+ indent++;
+ break;
+
+ case ENULLCHECK:
+ fprintf(outfile, " unique [%" PRId32 "]", expr->data.nullcheck.precompid);
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ DumpExpression(expr->data.nullcheck.nullcheckexpr, indent + 1);
+ expr = expr->data.nullcheck.condexpr;
+ indent++;
+ break;
+
+ case EPRECOMP:
+ fprintf(outfile, " unique [%" PRId32 "]", expr->data.precompid);
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case ELABEL:
+ fprintf(outfile, "[%s]", expr->data.label->uniquename->name);
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ return;
+
+ case ETEMP:
+ DumpType(expr->data.temp.type);
+ fprintf(outfile, "\r");
+ return;
+
+ case EINITTRYCATCH:
+ DumpType(expr->rtype);
+ fprintf(outfile, "\r");
+ if (expr->data.itc.initexpr)
+ DumpExpression(expr->data.itc.initexpr, indent + 1);
+ if (expr->data.itc.tryexpr)
+ DumpExpression(expr->data.itc.tryexpr, indent + 1);
+ if (expr->data.itc.catchexpr)
+ DumpExpression(expr->data.itc.catchexpr, indent + 1);
+ if (expr->data.itc.result)
+ DumpExpression(expr->data.itc.result, indent + 1);
+ return;
+
+ case EDEFINE:
+ fprintf(outfile, "[%.8" PRIX32 "]", expr);
+ DumpType(expr->rtype);
+ fputs("\r", outfile);
+ expr = expr->data.monadic;
+ indent++;
+ break;
+
+ case EREUSE:
+ fprintf(outfile, "[%.8" PRIX32 "]", expr->data.monadic);
+ DumpType(expr->rtype);
+ fputs("\r", outfile);
+ return;
+
+ default:
+ return;
+ }
+ }
+}
+
+void DumpSwitch(SwitchInfo *info) {
+ char buf[32];
+ SwitchCase *cs;
+
+ for (cs = info->cases; cs; cs = cs->next) {
+ CInt64_PrintDec(buf, cs->min);
+ CInt64_PrintDec(buf, cs->min);
+ fprintf(outfile, "\t\t%11s: %s\r", buf, cs->label->uniquename->name);
+ }
+
+ fprintf(outfile, "\t\t default: %s\r", info->defaultlabel->uniquename->name);
+}
+
+void DumpType(Type *type) {
+ char buf[256];
+
+ spell(type, buf);
+ fprintf(outfile, " (%s)", buf);
+}
+
+static void spell(Type *type, char *buf) {
+ char mybuf[256];
+ char mybuf2[256];
+
+ switch (type->type) {
+ case TYPEVOID:
+ strcpy(buf, "void");
+ break;
+ case TYPEINT:
+ switch (TYPE_INTEGRAL(type)->integral) {
+ case IT_BOOL:
+ strcpy(buf, "bool");
+ break;
+ case IT_CHAR:
+ strcpy(buf, "char");
+ break;
+ case IT_WCHAR_T:
+ strcpy(buf, "wchar_t");
+ break;
+ case IT_SCHAR:
+ strcpy(buf, "signed char");
+ break;
+ case IT_UCHAR:
+ strcpy(buf, "unsigned char");
+ break;
+ case IT_SHORT:
+ strcpy(buf, "short");
+ break;
+ case IT_USHORT:
+ strcpy(buf, "unsigned short");
+ break;
+ case IT_INT:
+ strcpy(buf, "int");
+ break;
+ case IT_UINT:
+ strcpy(buf, "unsigned int");
+ break;
+ case IT_LONG:
+ strcpy(buf, "long");
+ break;
+ case IT_ULONG:
+ strcpy(buf, "unsigned long");
+ break;
+ case IT_LONGLONG:
+ strcpy(buf, "long long");
+ break;
+ case IT_ULONGLONG:
+ strcpy(buf, "unsigned long long");
+ break;
+ }
+ break;
+ case TYPEFLOAT:
+ switch (TYPE_INTEGRAL(type)->integral) {
+ case IT_FLOAT:
+ strcpy(buf, "float");
+ break;
+ case IT_SHORTDOUBLE:
+ strcpy(buf, "short double");
+ break;
+ case IT_DOUBLE:
+ strcpy(buf, "double");
+ break;
+ case IT_LONGDOUBLE:
+ strcpy(buf, "long double");
+ break;
+ }
+ break;
+ case TYPEENUM:
+ strcpy(buf, "enum ");
+ if (TYPE_ENUM(type)->enumname)
+ strcat(buf, TYPE_ENUM(type)->enumname->name);
+ break;
+ case TYPESTRUCT:
+ if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) {
+ switch (TYPE_STRUCT(type)->stype) {
+ case STRUCT_VECTOR_UCHAR:
+ strcpy(buf, "vector unsigned char ");
+ break;
+ case STRUCT_VECTOR_SCHAR:
+ strcpy(buf, "vector signed char ");
+ break;
+ case STRUCT_VECTOR_BCHAR:
+ strcpy(buf, "vector bool char ");
+ break;
+ case STRUCT_VECTOR_USHORT:
+ strcpy(buf, "vector unsigned short ");
+ break;
+ case STRUCT_VECTOR_SSHORT:
+ strcpy(buf, "vector signed short ");
+ break;
+ case STRUCT_VECTOR_BSHORT:
+ strcpy(buf, "vector bool short ");
+ break;
+ case STRUCT_VECTOR_UINT:
+ strcpy(buf, "vector unsigned int ");
+ break;
+ case STRUCT_VECTOR_SINT:
+ strcpy(buf, "vector signed int ");
+ break;
+ case STRUCT_VECTOR_BINT:
+ strcpy(buf, "vector bool int ");
+ break;
+ case STRUCT_VECTOR_FLOAT:
+ strcpy(buf, "vector float ");
+ break;
+ case STRUCT_VECTOR_PIXEL:
+ strcpy(buf, "vector pixel ");
+ break;
+ }
+ } else {
+ strcpy(buf, "struct ");
+ if (TYPE_STRUCT(type)->name)
+ strcat(buf, TYPE_STRUCT(type)->name->name);
+ }
+ break;
+ case TYPECLASS:
+ strcpy(buf, "class ");
+ if (TYPE_CLASS(type)->classname)
+ strcat(buf, TYPE_CLASS(type)->classname->name);
+ break;
+ case TYPEFUNC:
+ spell(TYPE_FUNC(type)->functype, mybuf);
+ strcpy(buf, "freturns(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEBITFIELD:
+ spell(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
+ sprintf(buf,
+ "bitfield(%s){%d:%d}",
+ mybuf,
+ TYPE_BITFIELD(type)->offset,
+ TYPE_BITFIELD(type)->bitlength);
+ break;
+ case TYPELABEL:
+ strcpy(buf, "label");
+ break;
+ case TYPEPOINTER:
+ spell(TPTR_TARGET(type), mybuf);
+ strcpy(buf, "pointer(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEARRAY:
+ spell(TPTR_TARGET(type), mybuf);
+ strcpy(buf, "array(");
+ strcat(buf, mybuf);
+ strcat(buf, ")");
+ break;
+ case TYPEMEMBERPOINTER:
+ spell(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
+ spell(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
+ strcpy(buf, "memberpointer(");
+ strcat(buf, mybuf);
+ strcat(buf, ",");
+ strcat(buf, mybuf2);
+ strcat(buf, ")");
+ break;
+ }
+}
+
+void DumpStack(ExceptionAction *act) {
+ while (act) {
+ fprintf(outfile, "\t\t:");
+ switch (act->type) {
+ case EAT_DESTROYLOCAL:
+ fprintf(outfile,
+ "EAT_DESTROYLOCAL %s(&%s)%s",
+ CMangler_GetLinkName(act->data.destroy_local.dtor)->name,
+ act->data.destroy_local.local->name->name,
+ "\r");
+ break;
+ case EAT_DESTROYLOCALCOND:
+ fprintf(outfile,
+ "EAT_DESTROYLOCALCOND%s",
+ "\r");
+ break;
+ case EAT_DESTROYLOCALOFFSET:
+ fprintf(outfile,
+ "EAT_DESTROYLOCALOFFSET %s(&%s+%" PRId32 ")%s",
+ CMangler_GetLinkName(act->data.destroy_local_offset.dtor)->name,
+ act->data.destroy_local_offset.local->name->name,
+ act->data.destroy_local_offset.offset,
+ "\r");
+ break;
+ case EAT_DESTROYLOCALPOINTER:
+ fprintf(outfile,
+ "EAT_DESTROYLOCALPOINTER%s",
+ "\r");
+ break;
+ case EAT_DESTROYLOCALARRAY:
+ fprintf(outfile,
+ "EAT_DESTROYLOCALARRAY%s",
+ "\r");
+ break;
+ case EAT_DESTROYBASE:
+ fprintf(outfile,
+ "EAT_DESTROYBASE %s(this+%" PRId32 ")%s",
+ CMangler_GetLinkName(act->data.destroy_base.dtor)->name,
+ act->data.destroy_base.offset,
+ "\r");
+ break;
+ case EAT_DESTROYMEMBER:
+ fprintf(outfile,
+ "EAT_DESTROYMEMBER %s(%s+%" PRId32 ")%s",
+ CMangler_GetLinkName(act->data.destroy_member.dtor)->name,
+ act->data.destroy_member.objectptr->name->name,
+ act->data.destroy_member.offset,
+ "\r");
+ break;
+ case EAT_DESTROYMEMBERCOND:
+ fprintf(outfile,
+ "EAT_DESTROYMEMBERCOND if(%s) %s(this+%" PRId32 ")%s",
+ act->data.destroy_member_cond.cond->name->name,
+ CMangler_GetLinkName(act->data.destroy_member_cond.dtor)->name,
+ act->data.destroy_member_cond.offset,
+ "\r");
+ break;
+ case EAT_DESTROYMEMBERARRAY:
+ fprintf(outfile,
+ "EAT_DESTROYMEMBERARRAY %s(this+%" PRId32 ")[%" PRId32 "] size: %" PRId32 "%s",
+ CMangler_GetLinkName(act->data.destroy_member_array.dtor)->name,
+ act->data.destroy_member_array.offset,
+ act->data.destroy_member_array.elements,
+ act->data.destroy_member_array.element_size,
+ "\r");
+ break;
+ case EAT_DELETEPOINTER:
+ fprintf(outfile,
+ "EAT_DELETEPOINTER(%s)%s",
+ act->data.delete_pointer.pointerobject->name->name,
+ "\r");
+ break;
+ case EAT_DELETELOCALPOINTER:
+ fprintf(outfile,
+ "EAT_DELETELOCALPOINTER(%s)%s",
+ act->data.delete_pointer.pointerobject->name->name,
+ "\r");
+ break;
+ case EAT_DELETEPOINTERCOND:
+ fprintf(outfile,
+ "EAT_DELETEPOINTERCOND if (%s)(%s)%s",
+ act->data.delete_pointer_cond.cond->name->name,
+ act->data.delete_pointer_cond.pointerobject->name->name,
+ "\r");
+ break;
+ case EAT_CATCHBLOCK:
+ fprintf(outfile, "EAT_CATCHBLOCK ");
+ if (act->data.catch_block.catch_type) {
+ if (act->data.catch_block.catch_object)
+ fprintf(outfile, "[%s]", act->data.catch_block.catch_object->name->name);
+ else
+ fprintf(outfile, "[]");
+ DumpType(act->data.catch_block.catch_type);
+ } else {
+ fprintf(outfile, "[...] ");
+ }
+ fprintf(outfile,
+ " Label: %s%s",
+ act->data.catch_block.catch_label->uniquename->name,
+ "\r");
+ break;
+ case EAT_SPECIFICATION:
+ fprintf(outfile,
+ "EAT_SPECIFICATION%s",
+ "\r");
+ break;
+ case EAT_ACTIVECATCHBLOCK:
+ fprintf(outfile,
+ "EAT_ACTIVECATCHBLOCK%s",
+ "\r");
+ break;
+ case EAT_TERMINATE:
+ fprintf(outfile,
+ "EAT_TERMINATE%s",
+ "\r");
+ break;
+ }
+ act = act->prev;
+ }
+}