@@ -435,7 +435,7 @@ static inline bool IsPunctuationToken(metac_token_enum_t tok)
435435 return (
436436 (IsBinaryOperator (tok , expr_flags_none )
437437 && tok != tok_star && tok != tok_lParen
438- && tok != tok_lBracket )
438+ && tok != tok_lBracket && tok != tok_and )
439439 || tok == tok_dotdot
440440 || tok == tok_comma
441441/*
@@ -741,10 +741,52 @@ metac_expr_t* MetaCParser_ParsePrimaryExpr(metac_parser_t* self, parse_expr_flag
741741 {
742742 // result = GetOrAddStringLiteral(_string_table, currentToken);
743743 MetaCParser_Match (self , tok_string );
744+ uint32_t stringLength = LENGTH_FROM_STRING_KEY (currentToken -> StringKey );
745+ uint32_t currentLen = LENGTH_FROM_STRING_KEY (currentToken -> StringKey );
746+ uint32_t adjacentStrings = 1 ;
747+ const char * currentStringP = IdentifierPtrToCharPtr (& self -> Lexer -> StringTable , currentToken -> StringPtr );
748+ uint32_t stringHash = crc32c_nozero (~0 , currentStringP , currentLen );
749+ char stringBuffer [8192 ]; // let's just hope we don't need to concat huge strings;
750+ char * stringBufferP = stringBuffer ;
751+
744752 result = AllocNewExpr (expr_string );
745- result -> StringPtr = RegisterString (self , currentToken );
746- result -> StringKey = currentToken -> StringKey ;
747- result -> Hash = currentToken -> StringKey ;
753+
754+ for (metac_token_t * peekToken = 0 ; (peekToken = MetaCParser_PeekToken (self , 1 ))-> TokenType == tok_string ;)
755+ {
756+ MetaCParser_Match (self , tok_string );
757+ memcpy (stringBufferP , currentStringP , currentLen );
758+ stringBufferP += currentLen ;
759+
760+ currentLen = LENGTH_FROM_STRING_KEY (peekToken -> StringKey );
761+ currentStringP = IdentifierPtrToCharPtr (& self -> Lexer -> StringTable , peekToken -> StringPtr );
762+ stringHash = crc32c_nozero (stringHash , currentStringP , currentLen );
763+ stringLength += currentLen ;
764+
765+ adjacentStrings += 1 ;
766+ if (stringLength >= sizeof (stringBuffer )) { assert (!"concat string too long" ); }
767+ }
768+
769+ if (adjacentStrings == 1 )
770+ {
771+ result -> StringPtr = RegisterString (self , currentToken );
772+ result -> StringKey = currentToken -> StringKey ;
773+ result -> Hash = currentToken -> StringKey ;
774+ }
775+ else
776+ {
777+ // for the last one
778+ memcpy (stringBufferP , currentStringP , currentLen );
779+ // we can now compute the string key
780+ assert (crc32c_nozero (~0 , stringBuffer , stringLength ) == stringHash );
781+
782+ result -> StringKey = STRING_KEY (stringHash , stringLength );
783+ // GetOrAddIdentifier copies the string into string table memory
784+ // therefore we can just concat it into a temporary buffer
785+ result -> StringPtr = GetOrAddIdentifier (& self -> StringTable ,
786+ result -> StringKey , stringBuffer );
787+ result -> Hash = result -> StringKey ;
788+
789+ }
748790 //PushOperand(result);
749791 }
750792 else if (tokenType == tok_char )
0 commit comments