mirror of
https://github.com/NishiOwO/JWasm.git
synced 2025-04-22 01:04:39 +00:00
207 lines
5.7 KiB
C
207 lines
5.7 KiB
C
/****************************************************************************
|
|
*
|
|
* This code is Public Domain.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* Description: handle the line queue.
|
|
* this queue is used for "generated code".
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "globals.h"
|
|
#include "memalloc.h"
|
|
#include "reswords.h"
|
|
#include "input.h"
|
|
#include "parser.h"
|
|
#include "preproc.h"
|
|
#include "myassert.h"
|
|
|
|
extern struct ReservedWord ResWordTable[];
|
|
|
|
/* item of a line queue */
|
|
struct lq_line {
|
|
struct lq_line *next;
|
|
#ifdef DEBUG_OUT
|
|
char lineno;
|
|
#endif
|
|
char line[1];
|
|
};
|
|
|
|
#define line_queue ModuleInfo.g.line_queue
|
|
|
|
#ifdef DEBUG_OUT
|
|
static unsigned lqlines_written; /* lq lines written by AddLineQueue() */
|
|
static unsigned lqlines_read; /* lq lines read by RunLineQueue() */
|
|
unsigned GetLqLine( void ) { return( lqlines_read ); }
|
|
#endif
|
|
|
|
/* free items of current line queue */
|
|
|
|
void DeleteLineQueue( void )
|
|
/**************************/
|
|
{
|
|
struct qitem *curr;
|
|
struct qitem *next;
|
|
for( curr = line_queue.head; curr; curr = next ) {
|
|
next = curr->next;
|
|
MemFree( curr );
|
|
}
|
|
line_queue.head = NULL;
|
|
}
|
|
|
|
|
|
#if 0 /* v2.11: now a macro */
|
|
bool is_linequeue_populated( void )
|
|
/*********************************/
|
|
{
|
|
return( line_queue.head != NULL );
|
|
}
|
|
#endif
|
|
|
|
/* Add a line to the current line queue. */
|
|
|
|
void AddLineQueue( const char *line )
|
|
/***********************************/
|
|
{
|
|
unsigned i = strlen( line );
|
|
struct lq_line *new;
|
|
|
|
DebugMsg1(( "AddLineQueue(%p): #=%u >%s<\n", line, ++lqlines_written, line ));
|
|
|
|
/* v2.11: line queue has become static. */
|
|
//if ( line_queue == NULL ) {
|
|
// line_queue = MemAlloc( sizeof( struct input_queue ) );
|
|
// line_queue->tail = NULL;
|
|
//}
|
|
new = MemAlloc( sizeof( struct lq_line ) + i );
|
|
new->next = NULL;
|
|
DebugCmd( new->lineno = lqlines_written );
|
|
memcpy( new->line, line, i + 1 );
|
|
|
|
if( line_queue.head == NULL ) {
|
|
line_queue.head = new;
|
|
} else {
|
|
/* insert at the tail */
|
|
((struct qnode *)line_queue.tail)->next = new;
|
|
}
|
|
line_queue.tail = new;
|
|
return;
|
|
}
|
|
|
|
/* Add a line to the current line queue, "printf" format. */
|
|
|
|
void AddLineQueueX( const char *fmt, ... )
|
|
/****************************************/
|
|
{
|
|
va_list args;
|
|
char *d;
|
|
int i;
|
|
int_32 l;
|
|
const char *s;
|
|
const char *p;
|
|
char buffer[MAX_LINE_LEN];
|
|
|
|
//DebugMsg(("AddlineQueueX(%s) enter\n", fmt ));
|
|
va_start( args, fmt );
|
|
for ( s = fmt, d = buffer; *s; s++ ) {
|
|
if ( *s == '%' ) {
|
|
s++;
|
|
switch ( *s ) {
|
|
case 'r':
|
|
i = va_arg( args, int );
|
|
GetResWName( i , d );
|
|
/* v2.06: the name is already copied */
|
|
//memcpy( d, ResWordTable[i].name, ResWordTable[i].len );
|
|
d += ResWordTable[i].len;
|
|
break;
|
|
case 's':
|
|
p = va_arg( args, char * );
|
|
i = strlen( p );
|
|
memcpy( d, p, i );
|
|
d += i;
|
|
*d = NULLC;
|
|
break;
|
|
case 'd':
|
|
case 'u':
|
|
case 'x':
|
|
#ifdef __I86__ /* v2.08: use long only if size(int) is 16-bit */
|
|
l = va_arg( args, long );
|
|
#else
|
|
l = va_arg( args, int );
|
|
#endif
|
|
if ( *s == 'x' ) {
|
|
myltoa( l, d, 16, FALSE, FALSE );
|
|
d += strlen( d );
|
|
} else {
|
|
myltoa( l, d, 10, l < 0, FALSE );
|
|
d += strlen( d );
|
|
/* v2.07: add a 't' suffix if radix is != 10 */
|
|
if ( ModuleInfo.radix != 10 )
|
|
*d++ = 't';
|
|
}
|
|
break;
|
|
default:
|
|
*d++ = *s;
|
|
}
|
|
} else
|
|
*d++ = *s;
|
|
}
|
|
*d = NULLC;
|
|
va_end( args );
|
|
//DebugMsg(("AddlineQueueX() done\n" ));
|
|
AddLineQueue( buffer );
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* RunLineQueue() is called whenever generated code is to be assembled. It
|
|
* - saves current input status
|
|
* - processes the line queue
|
|
* - restores input status
|
|
*/
|
|
|
|
void RunLineQueue( void )
|
|
/***********************/
|
|
{
|
|
struct input_status oldstat;
|
|
struct asm_tok *tokenarray;
|
|
struct lq_line *currline = line_queue.head;
|
|
|
|
DebugMsg1(( "RunLineQueue() enter\n" ));
|
|
|
|
/* v2.03: ensure the current source buffer is still aligned */
|
|
tokenarray = PushInputStatus( &oldstat );
|
|
ModuleInfo.GeneratedCode++;
|
|
|
|
/* v2.11: line queues are no longer pushed onto the file stack.
|
|
* Instead, the queue is processed directly here.
|
|
*/
|
|
line_queue.head = NULL;
|
|
DebugCmd( lqlines_written = 0 ); /* reset counter for AddLineQueue() */
|
|
DebugCmd( lqlines_read = 0 ); /* reset counter for line-queue reads below */
|
|
|
|
for ( ; currline; ) {
|
|
struct lq_line *nextline = currline->next;
|
|
strcpy( CurrSource, currline->line );
|
|
DebugCmd ( lqlines_read++ );
|
|
MemFree( currline );
|
|
if ( PreprocessLine( CurrSource, tokenarray ) )
|
|
ParseLine( tokenarray );
|
|
currline = nextline;
|
|
}
|
|
|
|
#ifdef DEBUG_OUT
|
|
if ( ModuleInfo.EndDirFound == TRUE ) {
|
|
DebugMsg(("!!!!! Warning: End directive found in generated-code parser loop!\n"));
|
|
}
|
|
#endif
|
|
ModuleInfo.GeneratedCode--;
|
|
PopInputStatus( &oldstat );
|
|
|
|
DebugMsg1(( "RunLineQueue() exit\n" ));
|
|
return;
|
|
}
|