"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/codegen.cc" between
ragel-7.0.0.10.tar.gz and ragel-7.0.0.11.tar.gz

About: Ragel compiles executable finite state machines from regular languages (C, C++, Obj-C, C#, D, Java, Go and Ruby). Development version.

codegen.cc  (ragel-7.0.0.10):codegen.cc  (ragel-7.0.0.11)
/* /*
* Copyright 2001-2014 Adrian Thurston <thurston@colm.net> * Copyright 2001-2018 Adrian Thurston <thurston@colm.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in al l * The above copyright notice and this permission notice shall be included in al l
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
skipping to change at line 95 skipping to change at line 95
{ {
values += 1; values += 1;
if ( v < min ) if ( v < min )
min = v; min = v;
if ( v > max ) if ( v > max )
max = v; max = v;
} }
void TableArray::finishAnalyze() void TableArray::finishAnalyze()
{ {
/* Calculate the type if it is not already set. */ if ( codeGen.backend == Direct ) {
if ( type.empty() ) { /* Calculate the type if it is not already set. */
if ( min >= S8BIT_MIN && max <= S8BIT_MAX ) { if ( type.empty() ) {
type = "char"; if ( min >= S8BIT_MIN && max <= S8BIT_MAX ) {
width = sizeof(char); type = "char";
} width = sizeof(char);
else if ( min >= S16BIT_MIN && max <= S16BIT_MAX ) { }
type = "short"; else if ( min >= S16BIT_MIN && max <= S16BIT_MAX ) {
width = sizeof(short); type = "short";
} width = sizeof(short);
else if ( min >= S32BIT_MIN && max <= S32BIT_MAX ) { }
type = "int"; else if ( min >= S32BIT_MIN && max <= S32BIT_MAX ) {
width = sizeof(int); type = "int";
} width = sizeof(int);
else if ( min >= S64BIT_MAX && max <= S64BIT_MAX ) { }
type = "long"; else if ( min >= S64BIT_MAX && max <= S64BIT_MAX ) {
width = sizeof(long); type = "long";
} width = sizeof(long);
else { }
type = "long long"; else {
width = sizeof(long long); type = "long long";
width = sizeof(long long);
}
}
}
else {
/* Calculate the type if it is not already set. */
if ( type.empty() ) {
if ( min >= S8BIT_MIN && max <= S8BIT_MAX ) {
type = "s8";
width = sizeof(char);
}
else if ( min >= S16BIT_MIN && max <= S16BIT_MAX ) {
type = "s16";
width = sizeof(short);
}
else if ( min >= S32BIT_MIN && max <= S32BIT_MAX ) {
type = "s32";
width = sizeof(int);
}
else if ( min >= S64BIT_MAX && max <= S64BIT_MAX ) {
type = "s64";
width = sizeof(long);
}
else {
type = "s128";
width = sizeof(long long);
}
} }
} }
} }
void TableArray::startGenerate() void TableArray::startGenerate()
{ {
if ( stringTables ) { if ( codeGen.backend == Direct ) {
out << "static const char S_" << codeGen.DATA_PREFIX() << name << if ( stringTables ) {
"[] __attribute__((aligned (16))) = \n\t\""; out << "static const char S_" << codeGen.DATA_PREFIX() <<
name <<
"[] __attribute__((aligned (16))) = \n\t\"";
}
else {
out << "static const " << type << " " <<
"_" << codeGen.DATA_PREFIX() << name <<
"[] = {\n\t";
}
} }
else { else {
out << "static const " << type << " " << out << "array " << type << " " <<
"_" << codeGen.DATA_PREFIX() << name << "_" << codeGen.DATA_PREFIX() << name <<
"[] = {\n\t"; "( " << min << ", " << max << " ) = { ";
} }
} }
void TableArray::stringGenerate( long long value ) void TableArray::stringGenerate( long long value )
{ {
char c; char c;
short h; short h;
int i; int i;
long l; long l;
unsigned char *p = 0; unsigned char *p = 0;
skipping to change at line 181 skipping to change at line 215
out << 'x'; out << 'x';
out << std::setw(2) << (unsigned int) *p++; out << std::setw(2) << (unsigned int) *p++;
} }
out.flags( prevFlags ); out.flags( prevFlags );
out.fill( prevFill ); out.fill( prevFill );
} }
void TableArray::valueGenerate( long long v ) void TableArray::valueGenerate( long long v )
{ {
if ( stringTables ) { if ( codeGen.backend == Direct ) {
stringGenerate( v ); if ( stringTables ) {
stringGenerate( v );
if ( ++ln % iall == 0 ) {
out << "\"\n\t\""; if ( ++ln % iall == 0 ) {
ln = 0; out << "\"\n\t\"";
ln = 0;
}
}
else {
if ( isChar )
out << "c(" << v << ")";
else if ( !isSigned )
out << v << "u";
else
out << v;
if ( ( ++ln % iall ) == 0 ) {
out << ",\n\t";
ln = 0;
}
else {
out << ", ";
}
} }
} }
else { else {
if ( isChar ) if ( isChar )
out << "c(" << v << ")"; out << "c(" << v << ")";
else if ( !isSigned ) else if ( !isSigned )
out << v << "u"; out << "u(" << v << ")";
else else
out << v; out << v;
out << ", ";
if ( ( ++ln % iall ) == 0 ) {
out << ",\n\t";
ln = 0;
}
else {
out << ", ";
}
} }
} }
void TableArray::finishGenerate() void TableArray::finishGenerate()
{ {
if ( stringTables ) { if ( codeGen.backend == Direct ) {
out << "\";\nconst " << type << " *_" << codeGen.DATA_PREFIX() << if ( stringTables ) {
name << out << "\";\nconst " << type << " *_" << codeGen.DATA_PREFIX() <<
" = (const " << type << "*) S_" << codeGen.DATA_P name <<
REFIX() << name << ";\n\n"; " = (const " << type << "*) S_" << codeGen.DATA_PREFIX()
<< name << ";\n\n";
}
else {
if ( isChar )
out << "c(0)\n};\n\n";
else if ( !isSigned )
out << "0u\n};\n\n";
else
out << "0\n};\n\n";
}
} }
else { else {
if ( isChar ) if ( isChar )
out << "c(0)\n};\n\n"; out << "c(0) };\n\n";
else if ( !isSigned ) else if ( !isSigned )
out << "0u\n};\n\n"; out << "u(0) };\n\n";
else else
out << "0\n};\n\n"; out << "0 };\n\n";
} }
if ( codeGen.red->id->printStatistics ) { if ( codeGen.red->id->printStatistics ) {
codeGen.red->id->stats() << name << "\t" << values << "\t" << codeGen.red->id->stats() << name << "\t" << values << "\t" <<
size() << "\t" << endl; size() << "\t" << endl;
} }
codeGen.tableData += size(); codeGen.tableData += size();
} }
skipping to change at line 277 skipping to change at line 332
case GeneratePass: case GeneratePass:
finishGenerate(); finishGenerate();
break; break;
} }
} }
/* Init code gen with in parameters. */ /* Init code gen with in parameters. */
CodeGen::CodeGen( const CodeGenArgs &args ) CodeGen::CodeGen( const CodeGenArgs &args )
: :
CodeGenData( args ), CodeGenData( args ),
cpc( "_cpc" ),
tableData( 0 ), tableData( 0 ),
stringTables( args.id->stringTables ) backend( args.id->hostLang->backend ),
stringTables( args.id->stringTables ),
nfaTargs( "nfa_targs", *this ),
nfaOffsets( "nfa_offsets", *this ),
nfaPushActions( "nfa_push_actions", *this ),
nfaPopTrans( "nfa_pop_trans", *this )
{ {
} }
void CodeGen::statsSummary() void CodeGen::statsSummary()
{ {
if ( red->id->printStatistics ) if ( red->id->printStatistics )
red->id->stats() << "table-data\t\t" << tableData << endl << endl ; red->id->stats() << "table-data\t\t" << tableData << endl << endl ;
} }
string CodeGen::CAST( string type ) string CodeGen::CAST( string type )
{ {
return "(" + type + ")"; if ( backend == Direct )
return "(" + type + ")";
else
return "cast(" + type + ")";
} }
/* Write out the fsm name. */ /* Write out the fsm name. */
string CodeGen::FSM_NAME() string CodeGen::FSM_NAME()
{ {
return fsmName; return fsmName;
} }
/* Emit the offset of the start state as a decimal integer. */ /* Emit the offset of the start state as a decimal integer. */
string CodeGen::START_STATE_ID() string CodeGen::START_STATE_ID()
skipping to change at line 467 skipping to change at line 532
string result; string result;
while ( level-- > 0 ) while ( level-- > 0 )
result += "\t"; result += "\t";
return result; return result;
} }
/* Write out a key from the fsm code gen. Depends on wether or not the key is /* Write out a key from the fsm code gen. Depends on wether or not the key is
* signed. */ * signed. */
string CodeGen::KEY( Key key ) string CodeGen::KEY( Key key )
{ {
ostringstream ret; if ( backend == Direct ) {
if ( alphType->isChar ) ostringstream ret;
ret << "c(" << (unsigned long) key.getVal() << ")"; if ( alphType->isChar )
else if ( keyOps->isSigned || !keyOps->explicitUnsigned ) ret << "c(" << (unsigned long) key.getVal() << ")";
ret << key.getVal(); else if ( keyOps->isSigned || !keyOps->explicitUnsigned )
else ret << key.getVal();
ret << (unsigned long) key.getVal() << "u"; else
return ret.str(); ret << (unsigned long) key.getVal() << "u";
return ret.str();
}
else {
ostringstream ret;
if ( alphType->isChar )
ret << "c(" << (unsigned long) key.getVal() << ")";
else if ( keyOps->isSigned || !keyOps->explicitUnsigned )
ret << key.getVal();
else
ret << "u(" << (unsigned long) key.getVal() << ")";
return ret.str();
}
} }
bool CodeGen::isAlphTypeSigned() bool CodeGen::isAlphTypeSigned()
{ {
return keyOps->isSigned; return keyOps->isSigned;
} }
void CodeGen::DECLARE( std::string type, Variable &var, std::string init )
{
if ( var.isReferenced )
out << type << " " << var.name << init << ';';
}
void CodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFini sh ) void CodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFini sh )
{ {
/* The parser gives fexec two children. The double brackets are for D /* The parser gives fexec two children. The double brackets are for D
* code. If the inline list is a single word it will get interpreted as a * code. If the inline list is a single word it will get interpreted as a
* C-style cast by the D compiler. */ * C-style cast by the D compiler. */
ret << OPEN_GEN_BLOCK() << P() << " = (("; ret << OPEN_GEN_BLOCK() << P() << " = ((";
INLINE_LIST( ret, item->children, targState, inFinish, false ); INLINE_LIST( ret, item->children, targState, inFinish, false );
ret << "))-1;" << CLOSE_GEN_BLOCK() << "\n"; ret << "))-1;" << CLOSE_GEN_BLOCK() << "\n";
} }
skipping to change at line 817 skipping to change at line 900
{ {
GenAction *action = condition->inlineList->head->wrappedAction; GenAction *action = condition->inlineList->head->wrappedAction;
ACTION( out, action, IlOpts( 0, false, false ) ); ACTION( out, action, IlOpts( 0, false, false ) );
ret << "\n"; ret << "\n";
} }
else if ( condition->inlineList->length() == 1 && else if ( condition->inlineList->length() == 1 &&
condition->inlineList->head->type == condition->inlineList->head->type ==
GenInlineItem::NfaWrapConds ) GenInlineItem::NfaWrapConds )
{ {
ret << ret <<
" _cpc = 0;\n"; " " << cpc << " = 0;\n";
GenCondSpace *condSpace = condition->inlineList->head->condSpace; GenCondSpace *condSpace = condition->inlineList->head->condSpace;
for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
ret << ret <<
" if ( "; " if ( ";
CONDITION( out, *csi ); CONDITION( out, *csi );
Size condValOffset = (1 << csi.pos()); Size condValOffset = (1 << csi.pos());
ret << " ) _cpc += " << condValOffset << ";\n"; ret << " ) " << cpc << " += " << condValOffset << ";\n";
} }
const CondKeySet &keys = condition->inlineList->head->condKeySet; const CondKeySet &keys = condition->inlineList->head->condKeySet;
if ( keys.length() > 0 ) { if ( keys.length() > 0 ) {
ret << "_pop_test = "; ret << "_pop_test = ";
for ( CondKeySet::Iter cki = keys; cki.lte(); cki++ ) { for ( CondKeySet::Iter cki = keys; cki.lte(); cki++ ) {
ret << "_cpc == " << *cki; ret << "" << cpc << " == " << *cki;
if ( !cki.last() ) if ( !cki.last() )
ret << " || "; ret << " || ";
} }
ret << ";\n"; ret << ";\n";
} }
else { else {
ret << "_pop_test = 0;\n"; ret << "_pop_test = 0;\n";
} }
if ( !last ) if ( !last )
skipping to change at line 924 skipping to change at line 1007
string ret = alphType->data1; string ret = alphType->data1;
if ( alphType->data2 != 0 ) { if ( alphType->data2 != 0 ) {
ret += " "; ret += " ";
ret += + alphType->data2; ret += + alphType->data2;
} }
return ret; return ret;
} }
void CodeGen::VALUE( string type, string name, string value ) void CodeGen::VALUE( string type, string name, string value )
{ {
out << "static const " << type << " " << name << " = " << value << ";\n"; if ( backend == Direct )
out << "static const " << type << " " << name << " = " << value <
< ";\n";
else
out << "value " << type << " " << name << " = " << value << ";\n"
;
} }
string CodeGen::STR( int v ) string CodeGen::STR( int v )
{ {
ostringstream s; ostringstream s;
s << v; s << v;
return s.str(); return s.str();
} }
void CodeGen::STATE_IDS() void CodeGen::STATE_IDS()
skipping to change at line 981 skipping to change at line 1067
void CodeGen::writeExports() void CodeGen::writeExports()
{ {
if ( red->exportList.length() > 0 ) { if ( red->exportList.length() > 0 ) {
for ( ExportList::Iter ex = red->exportList; ex.lte(); ex++ ) { for ( ExportList::Iter ex = red->exportList; ex.lte(); ex++ ) {
out << EXPORT( ALPH_TYPE(), out << EXPORT( ALPH_TYPE(),
DATA_PREFIX() + "ex_" + ex->name, KEY(ex->key) ) << "\n"; DATA_PREFIX() + "ex_" + ex->name, KEY(ex->key) ) << "\n";
} }
out << "\n"; out << "\n";
} }
} }
void CodeGen::NFA_PUSH( std::string state )
{
if ( redFsm->anyNfaStates() ) {
out <<
" if ( " << ARR_REF( nfaOffsets ) << "[" << state <
< "] ) {\n"
" int alt = 0; \n"
" int new_recs = " << ARR_REF( nfaTargs ) <
< "[" << CAST("int") <<
ARR_REF( nfaOffsets ) << "[" << s
tate << "]];\n";
if ( red->nfaPrePushExpr != 0 ) {
out << OPEN_HOST_BLOCK( red->nfaPrePushExpr );
INLINE_LIST( out, red->nfaPrePushExpr->inlineList, 0, fal
se, false );
out << CLOSE_HOST_BLOCK();
}
out <<
" while ( alt < new_recs ) { \n";
out <<
" nfa_bp[nfa_len].state = " << ARR_
REF( nfaTargs ) << "[" << CAST("int") <<
ARR_REF( nfaOffsets ) <<
"[" << state << "] + 1 + alt];\n"
" nfa_bp[nfa_len].p = " << P() << "
;\n";
if ( redFsm->bAnyNfaPops ) {
out <<
" nfa_bp[nfa_len].popTrans
= " << CAST("long") <<
ARR_REF( nfaOffse
ts ) << "[" << state << "] + 1 + alt;\n"
"\n"
;
}
if ( redFsm->bAnyNfaPushes ) {
out <<
" switch ( " << ARR_REF( nf
aPushActions ) << "[" << CAST("int") <<
ARR_REF( nfaOffse
ts ) << "[" << state << "] + 1 + alt] ) {\n";
/* Loop the actions. */
for ( GenActionTableMap::Iter redAct = redFsm->actionMap;
redAct.lte(); redAct++ )
{
if ( redAct->numNfaPushRefs > 0 ) {
/* Write the entry label. */
out << "\t " << CASE( STR( redAct->actLis
tId+1 ) ) << " {\n";
/* Write each action in the list of actio
n items. */
for ( GenActionTable::Iter item = redAct-
>key; item.lte(); item++ )
ACTION( out, item->value, IlOpts(
0, false, false ) );
out << "\n\t" << CEND() << "}\n";
}
}
out <<
" }\n";
}
out <<
" nfa_len += 1;\n"
" alt += 1;\n"
" }\n"
" }\n"
;
}
}
 End of changes. 23 change blocks. 
64 lines changed or deleted 153 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)