<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
@Levente: Would this be okay-ish from a performance-perspective? :-)<div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div><blockquote class="history_container" type="cite" style="border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;">
<p style="color: #AAAAAA; margin-top: 10px;">Am 12.06.2020 17:28:25 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">A new version of ShoutCore was added to project The Inbox:<br>http://source.squeak.org/inbox/ShoutCore-mt.78.mcz<br><br>==================== Summary ====================<br><br>Name: ShoutCore-mt.78<br>Author: mt<br>Time: 12 June 2020, 5:28:15.527851 pm<br>UUID: 7decada5-8996-304c-ba9c-a93b00f0cc33<br>Ancestors: ShoutCore-mt.77<br><br>Complements Compiler-mt.436 (inbox).<br><br>Adds a (extension) method-based hook to install custom pragma-parsing methods. Use it to move FFI-specific pragma-parsing, i.e. <apicall: ...=""> and <cdecl: ...="">, into FFI packages.<br><br>=============== Diff against ShoutCore-mt.77 ===============<br><br>Item was removed:<br>- ----- Method: SHParserST80>>isTokenExternalFunctionCallingConvention (in category 'token testing') -----<br>- isTokenExternalFunctionCallingConvention<br>- <br>- currentToken ifNil: [ ^false ].<br>- ^(Smalltalk classNamed: #ExternalFunction)<br>- ifNil: [ false ]<br>- ifNotNil: [ :descriptorClass |<br>- (descriptorClass callingConventionFor: currentToken) notNil ]!<br><br>Item was removed:<br>- ----- Method: SHParserST80>>parseExternalCall (in category 'parse') -----<br>- parseExternalCall<br>- [self scanNext.<br>- ((Smalltalk at: #ExternalFunction) callingConventionModifierFor: currentToken) notNil]<br>- whileTrue.<br>- self failUnless: currentToken notNil.<br>- self scanPast: #externalCallType.<br>- currentToken = '*' <br>- ifTrue: [self scanPast: #externalCallTypePointerIndicator].<br>- currentTokenFirst isDigit<br>- ifTrue: [self scanPast: #integer]<br>- ifFalse: [<br>- self failUnless: currentTokenFirst == $'.<br>- self parseString].<br>- self failUnless: currentTokenFirst == $(.<br>- self scanPast: #leftParenthesis.<br>- [currentTokenFirst ~= $)] <br>- whileTrue: [<br>- self failUnless: currentToken notNil.<br>- self scanPast: #externalCallType.<br>- currentToken = '*' <br>- ifTrue: [self scanPast: #externalCallTypePointerIndicator]].<br>- self scanPast: #rightParenthesis.<br>- currentToken = 'module:' <br>- ifTrue: [<br>- self scanPast: #module.<br>- self parseStringOrSymbol ].<br>- currentToken = 'error:' ifTrue: [<br>- self scanPast: #primitive. "there's no rangeType for error"<br>- self currentTokenType == #name<br>- ifTrue: [ self parseTemporary: #patternTempVar ]<br>- ifFalse: [ self parseStringOrSymbol ] ].<br>- self failUnless: currentToken = '>'.<br>- self scanPast: #primitiveOrExternalCallEnd!<br><br>Item was changed:<br>+ ----- Method: SHParserST80>>parsePragmaBinary (in category 'parse pragma') -----<br>- ----- Method: SHParserST80>>parsePragmaBinary (in category 'parse') -----<br> parsePragmaBinary<br> <br> self scanPast: #pragmaBinary.<br> self currentTokenType == #name<br> ifTrue:[self scanPast: (self resolvePragmaArgument: currentToken)] <br> ifFalse:[ self parseLiteral: false].<br> self failUnless: currentToken = '>'.<br> self scanPast: #primitiveOrExternalCallEnd!<br><br>Item was changed:<br>+ ----- Method: SHParserST80>>parsePragmaKeyword (in category 'parse pragma') -----<br>- ----- Method: SHParserST80>>parsePragmaKeyword (in category 'parse') -----<br> parsePragmaKeyword<br> <br> [self currentTokenType == #keyword]<br> whileTrue:[<br> self scanPast: #pragmaKeyword.<br> self currentTokenType == #name<br> ifTrue:[self scanPast: (self resolvePragmaArgument: currentToken)] <br> ifFalse:[ self parseLiteral: false]].<br> self failUnless: currentToken = '>'.<br> self scanPast: #primitiveOrExternalCallEnd!<br><br>Item was changed:<br>+ ----- Method: SHParserST80>>parsePragmaSequence (in category 'parse pragma') -----<br>- ----- Method: SHParserST80>>parsePragmaSequence (in category 'parse') -----<br> parsePragmaSequence<br>+ <br> [currentToken = '<'></'><br>+ whileTrue: [<br>- whileTrue:[<br> self scanPast: #primitiveOrExternalCallStart.<br>+ self parsePragmaStatement].!<br>- currentToken = 'primitive:' <br>- ifTrue: [<br>- self addRangeType: #primitive.<br>- self parsePrimitive]<br>- ifFalse:[<br>- self isTokenExternalFunctionCallingConvention <br>- ifTrue: [<br>- self addRangeType: #externalFunctionCallingConvention.<br>- self parseExternalCall]<br>- ifFalse:[<br>- self currentTokenType<br>- caseOf: {<br>- [ #name ] -> [ <br>- self scanPast: #pragmaUnary.<br>- self failUnless: currentToken = '>'.<br>- self scanPast: #primitiveOrExternalCallEnd ].<br>- [ #binary ] -> [ self parsePragmaBinary ].<br>- [ #keyword ] -> [ self parsePragmaKeyword ] }<br>- otherwise: [ self fail ": 'Invalid External Function Calling convention'" ] ] ] ]!<br><br>Item was added:<br>+ ----- Method: SHParserST80>>parsePragmaStatement (in category 'parse pragma') -----<br>+ parsePragmaStatement<br>+ <br>+ | parserSelector parserMethod |<br>+ currentToken last == $: ifFalse: [<br>+ "Quick exit to not break one-word pragmas such as <primitive> or <foobar>."<br>+ ^ self parsePragmaStatementKeywords].<br>+ <br>+ (self class includesSelector: (parserSelector := currentToken asSimpleGetter)) ifTrue: [<br>+ ((parserMethod := self class compiledMethodAt: parserSelector) pragmas<br>+ anySatisfy: [:pragma | pragma keyword == #pragmaParser])<br>+ ifTrue: [^ self executeMethod: parserMethod]].<br>+ <br>+ ^ self parsePragmaStatementKeywords!<br><br>Item was added:<br>+ ----- Method: SHParserST80>>parsePragmaStatementKeywords (in category 'parse pragma') -----<br>+ parsePragmaStatementKeywords<br>+ <br>+ self currentTokenType<br>+ caseOf: {<br>+ [ #name ] -> [ <br>+ self scanPast: #pragmaUnary.<br>+ self failUnless: currentToken = '>'.<br>+ self scanPast: #primitiveOrExternalCallEnd ].<br>+ [ #binary ] -> [ self parsePragmaBinary ].<br>+ [ #keyword ] -> [ self parsePragmaKeyword ] }<br>+ otherwise: [ self fail ": 'Invalid External Function Calling convention'" ]. !<br><br>Item was removed:<br>- ----- Method: SHParserST80>>parsePrimitive (in category 'parse') -----<br>- parsePrimitive<br>- <br>- self scanNext.<br>- currentTokenFirst isDigit<br>- ifTrue: [ self scanPast: #integer ]<br>- ifFalse: [<br>- self parseStringOrSymbol.<br>- currentToken = 'module:' ifTrue: [<br>- self scanPast: #module.<br>- self parseStringOrSymbol ] ].<br>- currentToken = 'error:' ifTrue: [<br>- self scanPast: #primitive. "there's no rangeType for error"<br>- self currentTokenType == #name<br>- ifTrue: [ self parseTemporary: #patternTempVar ]<br>- ifFalse: [ self parseStringOrSymbol ] ].<br>- self failUnless: currentToken = '>'.<br>- self scanPast: #primitiveOrExternalCallEnd!<br><br>Item was added:<br>+ ----- Method: SHParserST80>>primitive (in category 'parse pragma') -----<br>+ primitive<br>+ "Parse keywords and literals of primitive pragmas differently to emit different range tokens for different UI styling. This hook exists so that packages do not break primitive-pragma parsing by accident. Instead, this method needs to be replaced intentionally."<br>+ <pragmaparser><br>+ <br>+ self addRangeType: #primitive.<br>+ <br>+ self scanNext.<br>+ currentTokenFirst isDigit<br>+ ifTrue: [ self scanPast: #integer ]<br>+ ifFalse: [<br>+ self parseStringOrSymbol.<br>+ currentToken = 'module:' ifTrue: [<br>+ self scanPast: #module.<br>+ self parseStringOrSymbol ] ].<br>+ currentToken = 'error:' ifTrue: [<br>+ self scanPast: #primitive. "there's no rangeType for error"<br>+ self currentTokenType == #name<br>+ ifTrue: [ self parseTemporary: #patternTempVar ]<br>+ ifFalse: [ self parseStringOrSymbol ] ].<br>+ self failUnless: currentToken = '>'.<br>+ self scanPast: #primitiveOrExternalCallEnd!<br><br><br></pragmaparser></foobar></primitive></cdecl:></apicall:></div></blockquote>
</div></body>