From d638e644a11565ee7c19d670ef9f3027d84c3fc9 Mon Sep 17 00:00:00 2001 From: Jaedyn Draper Date: Tue, 17 Feb 2015 13:20:59 -0600 Subject: [PATCH 1/4] Update dao_macro.c Possible fix for several syntax-related crashes as well as for `use syntax mylang` not functioning correctly. Crashes were caused by infinite recursion in DaoParser_ErrorX2 and DaoParser_ErrorX3. Use statement breakage was due to not seeking ahead far enough in the token list after parsing the use statement. This may not be the correct fix for that; there may be a need to actually do some parsing to figure out how many tokens forward to seek. But this worked in my tests. --- modules/macro/dao_macro.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/macro/dao_macro.c b/modules/macro/dao_macro.c index 35bc4d64..3f7bb0b7 100644 --- a/modules/macro/dao_macro.c +++ b/modules/macro/dao_macro.c @@ -95,12 +95,12 @@ static void DaoParser_ErrorX( DaoParser *self, int code, DString *ext ) } static void DaoParser_ErrorX2( DaoParser *self, int code, int m, int n, int single_line ) { - DaoParser_ErrorX2( self, code, m, n, single_line ); + DaoParser_Error2( self, code, m, n, single_line ); DaoParser_UpdateError( self ); } static void DaoParser_ErrorX3( DaoParser *self, int code, int m ) { - DaoParser_ErrorX3( self, code, m ); + DaoParser_Error3( self, code, m ); DaoParser_UpdateError( self ); } @@ -1429,7 +1429,7 @@ int DaoMacro_Preprocess( DaoParser *self ) }else if( tki == DKEY_USE && tki2 == DKEY_SYNTAX ){ if( DaoParser_CheckNameToken( self, start+1, to, DAO_INVALID_STATEMENT, start ) ==0 ) return -1; DaoNamespace_ImportMacro( ns, & tokens[start+1]->string ); - DList_Erase( self->tokens, start, end-start+1 ); + DList_Erase( self->tokens, start, 3 ); tokens = self->tokens->items.pToken; }else{ start ++; From 90a13b52f66f4e16b0b1d63717c8758a1984e414 Mon Sep 17 00:00:00 2001 From: Jaedyn Draper Date: Sat, 21 Feb 2015 00:11:41 -0600 Subject: [PATCH 2/4] dao_macro.c - $STR, $CAT, bugfixes - Added $STR() to stringify a macro value (i.e., $STR($ID1)) - Added $CAT() to concatenate macro values (i.e., $CAT($ID1 '_Helper')) - Fixed a bug where a value failing to be found in a ZERO_OR_ONE group nested in another ZERO_OR_ONE group would cause the higher-level group to also report a non-match - Fixed a bug where a plain identifier in the last section of a group could cause a failed match in some circumstances (i.e., { [ $ID1 '=' '4' ';' ] 'io' '.' 'writeln' '(' '{' "hello world" '}' ')' ';' } would fail to match correctly. --- modules/macro/dao_macro.c | 163 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 7 deletions(-) diff --git a/modules/macro/dao_macro.c b/modules/macro/dao_macro.c index 3f7bb0b7..6bfe88db 100644 --- a/modules/macro/dao_macro.c +++ b/modules/macro/dao_macro.c @@ -274,7 +274,7 @@ static int DaoParser_MakeMacroGroup( DaoParser *self, DMacroGroup *group, DMacro DNode *it; /* - for( i=from; ichars ); printf("\n"); + for( i=from; istring.chars ); printf("\n"); */ i = from; @@ -356,6 +356,10 @@ static int DaoParser_MakeMacroGroup( DaoParser *self, DMacroGroup *group, DMacro unit->type = DMACRO_OP; }else if( DString_FindChars( & tok->string, "BL", 0 ) == 1 ){ unit->type = DMACRO_BL; + }else if( strcmp( chs, "$STR" ) == 0 ){ + unit->type = DMACRO_STR; + }else if( strcmp( chs, "$CAT" ) == 0 ){ + unit->type = DMACRO_CAT; }else{ DaoParser_ErrorX( self, DAO_CTW_INV_MAC_SPECTOK, & tok->string ); return 0; @@ -891,20 +895,21 @@ static int DaoParser_MacroApply( DaoParser *self, DList *tokens, int level, DString *tag, int pos0, int adjust ) { DMacroUnit **units = (DMacroUnit**) group->units->items.pVoid; - DMacroUnit *unit; + DMacroUnit *unit, *strUnit; DMacroGroup *grp; DMacroNode *node, *node2; DList *toks = DList_New( DAO_DATA_TOKEN ); DaoToken *tk = DaoToken_New(); + DaoToken *literal = NULL; DaoToken *tt = NULL; DNode *kwnode = NULL; DMap *check = NULL; DMap one = { NULL, 0, 0, 0 }; int M, N = group->units->size; - int i, j, gid = -1; + int i, j, k, l, gid = -1; int repeated = 0; - int start_mbs = -1; - int start_wcs = -1; + int prevLine = -1; + int prevEnd = -1; if( group->repeat != DMACRO_AUTO ) level ++; @@ -917,10 +922,12 @@ static int DaoParser_MacroApply( DaoParser *self, DList *tokens, */ switch( unit->type ){ case DMACRO_TOK : + repeated = 1; DList_Append( tokens, unit->marker ); tokens->items.pToken[ tokens->size-1 ]->cpos += adjust; break; case DMACRO_VAR : + repeated = 1; DaoToken_Assign( tk, unit->marker ); DString_Append( & tk->string, tag ); DList_Append( tokens, tk ); @@ -982,14 +989,14 @@ static int DaoParser_MacroApply( DaoParser *self, DList *tokens, break; case DMACRO_ZERO_OR_ONE : gid = i; - repeated = (j>0); + repeated = 1; if( j >=0 ){ DList_InsertList( tokens, tokens->size, toks, 0, -1 ); } break; case DMACRO_ZERO_OR_MORE : gid = i; - repeated = (j>0); + repeated = 1; if( j >=0 ){ DList_InsertList( tokens, tokens->size, toks, 0, -1 ); } @@ -1019,6 +1026,148 @@ static int DaoParser_MacroApply( DaoParser *self, DList *tokens, break; } break; + case DMACRO_STR: + ++i; + if( tokens->size >0 ) pos0 = tokens->items.pToken[ tokens->size -1 ]->line; + self->curLine = pos0; + if(units[i]->type != DMACRO_GRP) + { + goto Failed; + } + literal = DaoToken_New(); + literal->type = literal->name = DTOK_WCS; + DString_AppendChar( &literal->string, '\"' ); + grp = (DMacroGroup*) units[i]; + for(j = 0; j < grp->units->size; ++j) + { + strUnit = ((DMacroUnit**)grp->units->items.pVoid)[j]; + //printf( ">>>\n%s level %i: \n", strUnit->marker->string.chars, level ); + switch(strUnit->type) + { + case DMACRO_EXP : + case DMACRO_ID : + case DMACRO_OP : + case DMACRO_BL : + kwnode = MAP_Find( tokMap, &strUnit->marker->string ); + if( kwnode ==NULL ){ + DaoParser_ErrorX( self, DAO_CTW_UNDEF_MAC_MARKER, & strUnit->marker->string ); + goto Failed; + } + node = (DMacroNode*) kwnode->value.pVoid; + kwnode = MAP_Find( used, strUnit ); + if( kwnode == NULL ){ + DMap_Insert( used, strUnit, & one ); + kwnode = MAP_Find( used, strUnit ); + } + check = (DMap*) kwnode->value.pVoid; + repeated = 1; + + node2 = DMacroNode_FindLeaf( node, check, level ); + if( node2 ){ + for(k = 0; k < node2->leaves->size; ++k) + { + tt = node2->leaves->items.pToken[k]; + if(k != 0) + { + if(tt->line != prevLine) + { + for(l = 0; l < tt->line - prevLine; ++l) + { + DString_AppendChar(&literal->string, '\n'); + } + for(l = 0; l < tt->cpos; ++l) + { + DString_AppendChar(&literal->string, ' '); + } + } + else + { + for(l = 0; l < tt->cpos - prevEnd; ++l) + { + DString_AppendChar(&literal->string, ' '); + } + } + } + DString_AppendChars( &literal->string, tt->string.chars ); + prevLine = tt->line; + prevEnd = tt->cpos + tt->string.size; + } + DMap_Insert( check, node2, NULL ); + }else{ + DMacroNode_RemoveEmptyLeftBranch( node, level ); + goto Failed; + } + break; + default: + repeated = 0; + break; + } + } + DString_AppendChar( &literal->string, '\"' ); + DList_Append( tokens, literal ); + + DaoToken_Delete(literal); + break; + case DMACRO_CAT: + ++i; + if( tokens->size >0 ) pos0 = tokens->items.pToken[ tokens->size -1 ]->line; + self->curLine = pos0; + if(units[i]->type != DMACRO_GRP) + { + goto Failed; + } + literal = DaoToken_New(); + literal->type = literal->name = DTOK_IDENTIFIER; + grp = (DMacroGroup*) units[i]; + for(j = 0; j < grp->units->size; ++j) + { + strUnit = ((DMacroUnit**)grp->units->items.pVoid)[j]; + switch(strUnit->type) + { + case DMACRO_TOK : + repeated = 1; + DString_AppendChars(&literal->string, strUnit->marker->string.chars ); + break; + case DMACRO_EXP : + case DMACRO_ID : + case DMACRO_OP : + case DMACRO_BL : + kwnode = MAP_Find( tokMap, &strUnit->marker->string ); + if( kwnode ==NULL ){ + DaoParser_ErrorX( self, DAO_CTW_UNDEF_MAC_MARKER, & strUnit->marker->string ); + goto Failed; + } + node = (DMacroNode*) kwnode->value.pVoid; + kwnode = MAP_Find( used, strUnit ); + if( kwnode == NULL ){ + DMap_Insert( used, strUnit, & one ); + kwnode = MAP_Find( used, strUnit ); + } + check = (DMap*) kwnode->value.pVoid; + repeated = 1; + + node2 = DMacroNode_FindLeaf( node, check, level ); + if( node2 ){ + for(k = 0; k < node2->leaves->size; ++k) + { + tt = node2->leaves->items.pToken[k]; + DString_AppendChars( &literal->string, tt->string.chars ); + } + DMap_Insert( check, node2, NULL ); + }else{ + DMacroNode_RemoveEmptyLeftBranch( node, level ); + goto Failed; + } + break; + default: + repeated = 0; + break; + } + } + DList_Append( tokens, literal ); + + DaoToken_Delete(literal); + break; default : goto Failed; } if( group->type == DMACRO_ALT && gid >=0 ) break; From 124024101ce173b6a64b2b516c866798c23ec863 Mon Sep 17 00:00:00 2001 From: Jaedyn Draper Date: Sat, 21 Feb 2015 00:13:16 -0600 Subject: [PATCH 3/4] Header update to correspond with source update Put them in different commits because I'm just copying and pasting the files into github directly, because I haven't set up a local git workspace yet on my box. --- modules/macro/dao_macro.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/macro/dao_macro.h b/modules/macro/dao_macro.h index 2dc7c16a..ec36c3ee 100644 --- a/modules/macro/dao_macro.h +++ b/modules/macro/dao_macro.h @@ -44,7 +44,9 @@ enum DMacroUnitTypes DMACRO_OP , /* $OP prefixed identifier: operator token */ DMACRO_BL , /* $BL prefixed identifier: code block tokens */ DMACRO_GRP , /* ( ... ) */ - DMACRO_ALT /* ( ... | ... ) */ + DMACRO_ALT , /* ( ... | ... ) */ + DMACRO_STR , /* $STR identifier: stringify token */ + DMACRO_CAT /* $CAT identifier: concatenate tokens */ }; enum DaoMacroGroupRepeatTypes From 65a7660806270ec8efc1c4aa8b2c8494c91a32f9 Mon Sep 17 00:00:00 2001 From: ShadauxCat Date: Sat, 21 Feb 2015 01:08:44 -0600 Subject: [PATCH 4/4] -Allowed loading files with extensions other than ".dao" using the syntax: load "modulename.ext" --- kernel/daoVmspace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/daoVmspace.c b/kernel/daoVmspace.c index f6fc541d..67fa90d7 100644 --- a/kernel/daoVmspace.c +++ b/kernel/daoVmspace.c @@ -1846,6 +1846,12 @@ int DaoVmSpace_CompleteModuleName( DaoVmSpace *self, DString *fname, int types ) }else if( (types & DAO_MODULE_DLL) && size > slen && DString_FindChars( fname, DAO_DLL_SUFFIX, 0 ) == size - slen ){ DaoVmSpace_SearchPath( self, fname, DAO_FILE_PATH, 1 ); if( DaoVmSpace_TestFile( self, fname ) ) modtype = DAO_MODULE_DLL; + //If we're given a filename (i.e., if it has an extension) and it's not a known filetype, load it anyway. + //With custom syntaxes people can use custom extensions, and we should allow them to load with those. + //In this case, always treat the extension as DAO_MODULE_DAO; that's all we'll support for custom extensions. + }else if( (types & DAO_MODULE_DAO) && size >1 && DString_FindChars( fname, ".", 0 ) != -1 ){ + DaoVmSpace_SearchPath( self, fname, DAO_FILE_PATH, 1 ); + if( DaoVmSpace_TestFile( self, fname ) ) modtype = DAO_MODULE_DAO; }else{ DString *fn = DString_New(); DString *path = DString_New();