polserver/pol-core/bscript/compctx.cpp

171 lines
3.1 KiB
C++
Raw Permalink Normal View History

/** @file
*
* @par History
*/
2016-02-11 22:54:43 +01:00
#include "compctx.h"
#include <cstring>
#include <ctype.h>
#include <format/format.h>
2016-02-11 22:54:43 +01:00
namespace Pol
{
namespace Bscript
{
2018-01-01 21:49:30 +01:00
namespace
{
/**
* Skips to the end of the line (or to the end of the file, whathever comes first)
*/
int eatToEndOfLine( CompilerContext& ctx )
{
const char* t = ctx.s;
while ( *t && ( *t != '\r' ) && ( *t != '\n' ) )
t++;
ctx.s = t;
return 0;
}
/**
* Skips to the end of a multiline comment, supports nested comments
*
* @return 0 on success
*/
int eatToCommentEnd( CompilerContext& ctx )
{
CompilerContext tmp( ctx );
while ( tmp.s[0] )
{
if ( strncmp( tmp.s, "*/", 2 ) == 0 )
{
tmp.s += 2;
ctx = tmp;
return 0;
}
else if ( strncmp( tmp.s, "/*", 2 ) == 0 ) // nested comment
{
tmp.s += 2;
int res = eatToCommentEnd( tmp );
if ( res )
return res;
}
else if ( strncmp( tmp.s, "//", 2 ) == 0 ) // nested eol-comment
{
int res = eatToEndOfLine( tmp );
if ( res )
return res;
}
if ( tmp.s[0] == '\n' )
++tmp.line;
tmp.s++;
}
return -1;
}
} // namespace
2018-01-01 21:49:30 +01:00
CompilerContext::CompilerContext()
: s( nullptr ),
line( 1 ),
filename( "" ),
s_begin( nullptr ),
dbg_filenum( 0 ),
silence_unicode_warnings( false )
{
}
CompilerContext::CompilerContext( const std::string& filename, int dbg_filenum, const char* s )
: s( s ),
line( 1 ),
filename( filename ),
s_begin( s ),
dbg_filenum( dbg_filenum ),
silence_unicode_warnings( false )
{
}
/**
* Skips whitespaces. Moves the pointer forward until a non-whitespace is found
*/
void CompilerContext::skipws()
{
while ( isspace( s[0] ) )
{
if ( s[0] == '\n' )
++line;
s++;
}
}
int CompilerContext::skipcomments()
{
CompilerContext tctx( *this );
for ( ;; )
{
while ( tctx.s[0] && isspace( tctx.s[0] ) )
2016-02-11 22:54:43 +01:00
{
// FIXME: if (tctx.s[0] == '\t')
// FIXME: contains_tabs = true;
if ( tctx.s[0] == '\n' )
++tctx.line;
tctx.s++; // wow neat, already take care of newlines
2016-02-11 22:54:43 +01:00
}
if ( !tctx.s[0] )
{
( *this ) = tctx;
return 1;
}
2016-02-11 22:54:43 +01:00
// look for comments
if ( strncmp( tctx.s, "/*", 2 ) == 0 ) // got a start of comment
{
int res;
tctx.s += 2;
res = eatToCommentEnd( tctx );
if ( res )
return res;
}
else if ( strncmp( tctx.s, "//", 2 ) == 0 ) // comment, one line only
2016-02-11 22:54:43 +01:00
{
int res;
res = eatToEndOfLine( tctx );
if ( res )
return res;
2016-02-11 22:54:43 +01:00
}
else
{
break;
}
}
( *this ) = tctx;
return 0;
}
void CompilerContext::printOn( std::ostream& os ) const
{
os << "File: " << filename << ", Line " << line << std::endl;
}
void CompilerContext::printOn( fmt::Writer& writer ) const
{
writer << "File: " << filename << ", Line " << line << "\n";
}
2016-02-11 22:54:43 +01:00
void CompilerContext::printOnShort( std::ostream& os ) const
{
os << filename << ", Line " << line << std::endl;
}
2016-02-11 22:54:43 +01:00
void CompilerContext::printOnShort( fmt::Writer& writer ) const
{
writer << filename << ", Line " << line << "\n";
}
} // namespace Bscript
} // namespace Pol