148 lines
3.7 KiB
C
148 lines
3.7 KiB
C
/**
|
||
* Part of the Lccrt Project, under the Apache License v2.0
|
||
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
*
|
||
* lccrt_asm.c - реализация печати ассемблера.
|
||
*/
|
||
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
#include <stdarg.h>
|
||
|
||
#include "lccrt_real.h"
|
||
|
||
#define lccrt_snprintf_max( l, j) ((j < (l)) ? ((l) - j) : 0)
|
||
#define lccrt_snprintf( s, l, j, ...) \
|
||
(j += snprintf( s + j, lccrt_snprintf_max( l, j), __VA_ARGS__))
|
||
|
||
/**
|
||
* Основная структура данных модуля печати ассемблера.
|
||
*/
|
||
typedef struct
|
||
{
|
||
lccrt_fs_ptr fs; /* выходной поток данных */
|
||
lccrt_hash_ptr types; /* множество типов, определение которых уже напечатаны */
|
||
} lccrt_asm_out_t;
|
||
|
||
/**
|
||
* Печать название идентификатора с экранированием по необходимости.
|
||
*/
|
||
void
|
||
lccrt_asm_print_name( lccrt_asm_out_t *ao, const char *name)
|
||
{
|
||
int i;
|
||
int is_simple = 1;
|
||
|
||
for ( i = 0; name[i]; ++i )
|
||
{
|
||
if ( 0 )
|
||
{
|
||
is_simple = 0;
|
||
}
|
||
}
|
||
|
||
if ( is_simple )
|
||
{
|
||
lccrt_fs_printf( ao->fs, "%s", name);
|
||
} else
|
||
{
|
||
lccrt_fs_printf( ao->fs, "\"");
|
||
for ( i = 0; name[i]; ++i )
|
||
{
|
||
if ( 0 )
|
||
{
|
||
lccrt_fs_printf( ao->fs, "%c", name[i]);
|
||
} else
|
||
{
|
||
lccrt_fs_printf( ao->fs, "\\%c", name[i]);
|
||
}
|
||
}
|
||
|
||
lccrt_fs_printf( ao->fs, "\"");
|
||
}
|
||
|
||
return;
|
||
} /* lccrt_asm_print_name */
|
||
|
||
void
|
||
lccrt_asm_print_type_definition( lccrt_asm_out_t *ao, lccrt_type_ptr type)
|
||
{
|
||
lccrt_hash_entry_ptr e;
|
||
|
||
lccrt_check_type_assert( type, lccrt_type_t);
|
||
e = lccrt_hash_find( ao->types, (uintptr_t)type);
|
||
|
||
if ( e )
|
||
{
|
||
} else if ( (type->type_name == LCCRT_TYPE_VOID)
|
||
|| (type->type_name == LCCRT_TYPE_BOOL)
|
||
|| (type->type_name == LCCRT_TYPE_INT)
|
||
|| (type->type_name == LCCRT_TYPE_FLOAT)
|
||
|| (type->type_name == LCCRT_TYPE_ELLIPSIS) )
|
||
{
|
||
} else if ( (type->type_name == LCCRT_TYPE_PTR) )
|
||
{
|
||
//lccrt_fs_printf( ao->fs, "type ");
|
||
//lccrt_asm_print_type_definition( ao, type->parent);
|
||
|
||
} else if ( (type->type_name == LCCRT_TYPE_FUNC) )
|
||
{
|
||
|
||
} else if ( (type->type_name == LCCRT_TYPE_STRUCT) )
|
||
{
|
||
|
||
} else if ( (type->type_name == LCCRT_TYPE_FIELD) )
|
||
{
|
||
|
||
} else if ( (type->type_name == LCCRT_TYPE_ARRAY) )
|
||
{
|
||
} else
|
||
{
|
||
fprintf( stderr, "type: %s\n", type->sym_name);
|
||
lccrt_assert( 0);
|
||
}
|
||
|
||
return;
|
||
} /* lccrt_asm_print_type */
|
||
|
||
void
|
||
lccrt_asm_print_var( lccrt_asm_out_t *ao, lccrt_var_ptr v, int is_global)
|
||
{
|
||
lccrt_check_type_assert( v, lccrt_var_t);
|
||
|
||
lccrt_fs_printf( ao->fs, "var ");
|
||
lccrt_asm_print_name( ao, v->name);
|
||
|
||
return;
|
||
} /* lccrt_asm_print_var */
|
||
|
||
/**
|
||
* Печатаем в выходной поток модуль.
|
||
*/
|
||
void
|
||
lccrt_asm_print_module( lccrt_fs_ptr fs, lccrt_module_ptr m)
|
||
{
|
||
lccrt_hash_entry_ptr e;
|
||
lccrt_asm_out_t ao = {0};
|
||
|
||
ao.fs = fs;
|
||
ao.types = lccrt_hash_new( m->ctx, LCCRT_HASH_KEY_INTPTR);
|
||
|
||
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
|
||
{
|
||
lccrt_asm_print_type_definition( &ao, (lccrt_type_ptr)lccrt_hash_get( e));
|
||
}
|
||
|
||
for ( e = lccrt_hash_first( m->gvars); e; e = lccrt_hash_next( e) )
|
||
{
|
||
lccrt_asm_print_var( &ao, (lccrt_var_ptr)lccrt_hash_get( e), 1);
|
||
}
|
||
|
||
lccrt_hash_delete( ao.types);
|
||
|
||
return;
|
||
} /* lccrt_asm_print_module */
|