2023-08-21 17:30:13 -07:00
|
|
|
#pragma once
|
|
|
|
#include "interface.hpp"
|
|
|
|
|
2023-08-03 08:01:43 -07:00
|
|
|
void AST::append( AST* other )
|
|
|
|
{
|
|
|
|
if ( other->Parent )
|
|
|
|
other = other->duplicate();
|
|
|
|
|
|
|
|
other->Parent = this;
|
|
|
|
|
|
|
|
if ( Front == nullptr )
|
|
|
|
{
|
|
|
|
Front = other;
|
|
|
|
Back = other;
|
|
|
|
|
|
|
|
NumEntries++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
AST*
|
|
|
|
Current = Back;
|
|
|
|
Current->Next = other;
|
|
|
|
other->Prev = Current;
|
|
|
|
Back = other;
|
|
|
|
NumEntries++;
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* AST::debug_str()
|
|
|
|
{
|
|
|
|
if ( Parent )
|
|
|
|
{
|
|
|
|
char const* fmt = stringize(
|
|
|
|
\nType : %s
|
|
|
|
\nParent : %s %s
|
|
|
|
\nName : %s
|
|
|
|
);
|
|
|
|
|
|
|
|
// These should be used immediately in a log.
|
|
|
|
// Thus if its desired to keep the debug str
|
|
|
|
// for multiple calls to bprintf,
|
|
|
|
// allocate this to proper string.
|
|
|
|
return str_fmt_buf( fmt
|
|
|
|
, type_str()
|
|
|
|
, Parent->Name
|
|
|
|
, Parent->type_str()
|
|
|
|
, Name ? Name : ""
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* fmt = stringize(
|
|
|
|
\nType : %s
|
|
|
|
\nName : %s
|
|
|
|
);
|
|
|
|
|
|
|
|
// These should be used immediately in a log.
|
|
|
|
// Thus if its desired to keep the debug str
|
|
|
|
// for multiple calls to bprintf,
|
|
|
|
// allocate this to proper string.
|
|
|
|
return str_fmt_buf( fmt
|
|
|
|
, type_str()
|
|
|
|
, Name ? Name : ""
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Code& AST::entry( u32 idx )
|
|
|
|
{
|
|
|
|
AST** current = & Front;
|
|
|
|
while ( idx >= 0 && current != nullptr )
|
|
|
|
{
|
|
|
|
if ( idx == 0 )
|
|
|
|
return * rcast( Code*, current);
|
|
|
|
|
|
|
|
current = & ( * current )->Next;
|
|
|
|
idx--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return * rcast( Code*, current);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AST::has_entries()
|
|
|
|
{
|
|
|
|
return NumEntries;
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* AST::type_str()
|
|
|
|
{
|
|
|
|
return ECode::to_str( Type );
|
|
|
|
}
|
|
|
|
|
|
|
|
AST::operator Code()
|
|
|
|
{
|
|
|
|
return { this };
|
|
|
|
}
|
|
|
|
|
|
|
|
Code& Code::operator ++()
|
|
|
|
{
|
|
|
|
if ( ast )
|
|
|
|
ast = ast->Next;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeClass::add_interface( CodeType type )
|
|
|
|
{
|
|
|
|
if ( ! ast->Next )
|
|
|
|
{
|
|
|
|
ast->Next = type;
|
|
|
|
ast->Last = ast->Next;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ast->Next->Next = type;
|
|
|
|
ast->Last = ast->Next->Next;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeParam::append( CodeParam other )
|
|
|
|
{
|
|
|
|
AST* self = (AST*) ast;
|
|
|
|
AST* entry = (AST*) other.ast;
|
|
|
|
|
|
|
|
if ( entry->Parent )
|
|
|
|
entry = entry->duplicate();
|
|
|
|
|
|
|
|
entry->Parent = self;
|
|
|
|
|
|
|
|
if ( self->Last == nullptr )
|
|
|
|
{
|
|
|
|
self->Last = entry;
|
|
|
|
self->Next = entry;
|
|
|
|
self->NumEntries++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
self->Last->Next = entry;
|
|
|
|
self->Last = entry;
|
|
|
|
self->NumEntries++;
|
|
|
|
}
|
|
|
|
|
|
|
|
CodeParam CodeParam::get( s32 idx )
|
|
|
|
{
|
|
|
|
CodeParam param = *this;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( ! ++ param )
|
|
|
|
return { nullptr };
|
|
|
|
|
|
|
|
return { (AST_Param*) param.raw()->Next };
|
|
|
|
}
|
|
|
|
while ( --idx );
|
|
|
|
|
|
|
|
return { nullptr };
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CodeParam::has_entries()
|
|
|
|
{
|
|
|
|
return ast->NumEntries > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CodeParam& CodeParam::operator ++()
|
|
|
|
{
|
|
|
|
ast = ast->Next.ast;
|
|
|
|
return * this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeStruct::add_interface( CodeType type )
|
|
|
|
{
|
|
|
|
if ( ! ast->Next )
|
|
|
|
{
|
|
|
|
ast->Next = type;
|
|
|
|
ast->Last = ast->Next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ast->Next->Next = type;
|
|
|
|
ast->Last = ast->Next->Next;
|
|
|
|
}
|
|
|
|
|
|
|
|
CodeBody def_body( CodeT type )
|
|
|
|
{
|
|
|
|
switch ( type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Class_Body:
|
|
|
|
case Enum_Body:
|
|
|
|
case Export_Body:
|
|
|
|
case Extern_Linkage:
|
|
|
|
case Function_Body:
|
|
|
|
case Global_Body:
|
|
|
|
case Namespace_Body:
|
|
|
|
case Struct_Body:
|
|
|
|
case Union_Body:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) );
|
|
|
|
return (CodeBody)Code::Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
Code
|
|
|
|
result = make_code();
|
|
|
|
result->Type = type;
|
|
|
|
return (CodeBody)result;
|
|
|
|
}
|
|
|
|
|
|
|
|
StrC token_fmt_impl( sw num, ... )
|
|
|
|
{
|
|
|
|
local_persist thread_local
|
|
|
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
|
|
|
mem_set( buf, 0, GEN_PRINTF_MAXLEN );
|
|
|
|
|
|
|
|
va_list va;
|
|
|
|
va_start(va, num );
|
|
|
|
sw result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
|
|
|
va_end(va);
|
|
|
|
|
|
|
|
return { result, buf };
|
|
|
|
}
|