static void checkOtherBits( FILE *fp, int indent, int size, char *prefix, char *var, int which_long ) { //***************************************************************************************************** if( which_long >= _NLONGS( size ) ) { doShift( fp, indent, size, var ); } else { char buffer[ 80 ]; sprintf( buffer, "if( %s->_%d & 0x80000000 ) {", var, which_long ); emitStmt( fp, indent, buffer ); doSet( fp, indent + 1, size, prefix, var, which_long + 1 ); emitStmt( fp, indent, "} else {" ); checkOtherBits( fp, indent + 1, size, prefix, var, which_long + 1 ); emitStmt( fp, indent, "}" ); } }
/* * Write generated code to file. * * Parameters: * fileName: name of the .asc file to which to write. * Return: * 0 on success, * non-zero otherwise */ int emitToFile(char *fileName) { FILE *ascfp = NULL; if (doNotEmit) { return 1; } /* open the file */ ascfp = fopen(fileName, "w"); /* append end-of-program stuff here (like a STOP) */ emitComment("End of user-defined pgram"); emitStmt(STMT_LEN, "STOP"); /* * append pre-defined ASC code here, so that it's at the bottom * of the file */ #ifndef ASC_SIMPLE emitPreDefCode(); #endif /* write the emitted code to file */ writeStmtLL(ascfp, stmts); /* close the file */ if (fclose(ascfp) != 0) { err(EXIT_FAILURE, "File IO error."); } return 0; }
/* * Emit code to goto the endo of the loop. Used for exit statments. */ void emitGotoLoopEnd() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("Go to end of %s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack)); emitStmt(STMT_LEN, "GOTO %s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1); }
static void doShift( FILE *fp, int indent, int size, char *var ) //************************************************************** { int i; char buffer[ 80 ]; for( i = 0; i < _NLONGS( size ); i++ ) { sprintf( buffer, "(*%s)._%d <<= 1;", var, i ); emitStmt( fp, indent, buffer ); } }
/* * Check that expr is true to do loop, otherwise skip loop */ void emitWhileLoopCondCheck(Symbol *s) { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(s); if (! (s->kind == CONST_KIND && isConstResultSym(s))) { emitPushSymbolValue(s); } emitComment("If expr is false, skip loop body"); emitStmt(STMT_LEN, "IFZ %s%d", LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1); }
/* * Emit ASC code for a then statment as part of IF-THEN-ELSE. * Assumes the corresposding statement or matched_stat code has already * been emitted. */ void emitThenMatchedStat() { /* we don't have a symbol pointer, so just pass in non-null */ CHECK_CAN_EMIT(1); emitComment("Bottom of an IF-THEN."); emitComment("Either THEN was executed, so GOTO,"); emitComment("or land at %s%d if 'expr' was false", LABEL_PREFIX, peekLabelStackTop(labelStack)); emitStmt(STMT_LEN, "GOTO %s%d", LABEL_PREFIX, peekLabelStackTop(labelStack) + 1); emitLabel(STMT_LEN, "%s%d", LABEL_PREFIX, peekLabelStackTop(labelStack)); }
/* * Emit ASC code to start an if statement. * Assumes the correspoding expression has already been emitted * * Note that both IF-THEN-ELSE and IF-THEN statements * reserve two labels, but only one is ever used in IF-THEN statements. */ void emitIfStat(Symbol *s) { CHECK_CAN_EMIT(s); /* reserve labels for THEN and ELSE */ reserveLabels(labelStack, 2); if (! (s->kind == CONST_KIND && isConstResultSym(s))) { emitPushSymbolValue(s); } emitComment("IF expr THEN. If 'expr' is false skip to %s%d", LABEL_PREFIX, peekLabelStackTop(labelStack)); emitStmt(STMT_LEN, "IFZ %s%d", LABEL_PREFIX, peekLabelStackTop(labelStack)); }
static void emitBitNext( FILE *fp, int size, char *prefix, char *type_name ) //************************************************************************** { int indent; fprintf( fp, "#ifdef %s_DEFINE_BITNEXT\n", prefix ); fprintf( fp, "static void %sNext( %s *set ) {\n\n", prefix, type_name ); indent = 1; if( size > 32 ) { emitStmt( fp, indent, "if( set->_0 & 0x80000000 ) {" ); doSet( fp, indent + 1, size, prefix, "set", 1 ); emitStmt( fp, indent, "} else {" ); if( size > 64 ) { checkOtherBits( fp, indent + 1, size, prefix, "set", 1 ); } else { doShift( fp, indent + 1, size, "set" ); } emitStmt( fp, indent, "}" ); } else { doShift( fp, indent, size, "set" ); } fprintf( fp, "}\n" ); fprintf( fp, "#endif\n\n" ); }
static void doSet( FILE *fp, int indent, int size, char *prefix, char *var, int which_long ) //****************************************************************************************** // set the given long in the bitset (_0 == 0) to 1, and all other bits // to 0 { char *buffer; int i; char *ptr; buffer = alloca( strlen( var ) + strlen( prefix ) + _NLONGS( size ) * 3 + 100 ); sprintf( buffer, "%sSet( *%s, ", prefix, var ); ptr = buffer + strlen( buffer ); for( i = 0; i < _NLONGS( size ) - 1; i++ ) { sprintf( ptr, "%d, ", ( i == which_long ) ? 1 : 0 ); ptr += 3; } sprintf( ptr, "%d );", ( i == which_long ) ? 1 : 0 ); emitStmt( fp, indent, buffer ); }