2016-09-19 16:24 GMT+02:00 Henrik Johansen <henrik.s.johan...@veloxit.no>:
> > On 19 Sep 2016, at 4:03 , Henrik Johansen <henrik.s.johan...@veloxit.no> > wrote: > > > On 17 Sep 2016, at 4:17 , Ben Coman <b...@openinworld.com > <b...@openinworld.com>> wrote: > > On Sat, Sep 17, 2016 at 3:45 AM, Nicolai Hess <nicolaih...@gmail.com> > wrote: > > > > 2016-09-16 18:42 GMT+02:00 Eliot Miranda <eliot.mira...@gmail.com>: > > > Hi All, > > > > _,,,^..^,,,_ (phone) > > On Sep 14, 2016, at 10:50 PM, Marcus Denker <marcus.den...@inria.fr> > wrote: > > > > We can change it back and maybe add support for the reformatter to not > convert it to the literal array #(3 #+ 4) . > > > I do not know in fact this is why I asked :) > Now may be my idea to use pragma to get something like pythondoctest is > a bad idea > but I really want to have literal programming. > What do you think? > > I like the idea to show examples/tests close to code, but pragmas are > not really good... > > If we have ' ' then it would be good that the syntax higlighter works > with a special mode inside the ' ' > > > it is just a string. How do you know that it contains code? > > Would you highlight all string in all code as if it contained code? Or > would you add this just for > Pragmas? But even there, strings are string, not code. > > I think we can conclude that pragmas are not a good solution to the > problem, as they are far > too limited to express code. > > > I think that's not a safe conclusion. We know from Igor's use of Kieran > arrays for C signatures in the UFFI, and can easily extrapolate here, that > arbitrary Smalltalk expressions /can/ be expressed in literal arrays. S > expressions work for lisp. > > In this particular case special casing pretty printing of literal arrays > in pragmas would be all that's needed to make the code look beautiful. Why > throw the baby out with the bath water? It would be so easy to make this > work well. > > > > We can try this as well. And it is far more easier to work with this > expressions if they are pragma arguments, than to parse the comment to find > some code within. > On the other hand, it looks much nicer if we have the examples right in the > method doc. you have some text describing the method, some code, some more > text about the reslt. > > > > > The only thing I'd do would be to print like this to make it clear that > the argument t is a literal Array and not some magic form of code: > > <expr: #(3 + 4) result: 7> > > > Yes, I would like to change this anyway, even for literal arrays for ffi, > calls like > > mouseStateX: x y: y > <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: > errorCode> > ^ self nbCall: #( Uint32 SDL_GetMouseState ( int* x , int* y ) ) > > this will be reformatted to > > mouseStateX: x y: y > <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: > 'errorCode'> > ^ self nbCall: #(#Uint32 #SDL_GetMouseState #(#int #* #x #, #int #* #y)) > > > errr, yuck! Thats not pretty at all. Is there some way to avoid > that? As I've been getting started with FFI its been really nice > visually to see a *direct* correspondence between the C header file > declaration and the in-Image method. > > > +1, that's about the main thought behind it... > As long as the only required use of a # inside of literal arrays is > differentiating whether something is a literal string or symbol, changing > to format *all* symbols using it seems somewhat overzealous. > > Personally, if a solution using method properties/+ browser improvements > to show/create them in a good way is out of the question, > I have a weakness for using empty blocks as method-local, > syntax-highlighted code comments (at least compared to special comment > syntax, or pragmas backed by a whole literal -> ST parser). > Though lately, the code critic (rightly, and very usefully, in the cases > where it's a user error) points out they are dead code, and the IR > optimizes them out entirely, meaning they miss out on > senders/implementors/refactorings > functionality. (Full blocks would potentially let us change the IR to leave > them alone, put them in the literal slot and be searchable, at no > additional runtime-cost/use in bytecodes) > > Cheers, > Henry > > > Now imagine if tags were scoped, and you could do > > Number >> #+ aNumber > <prim ....> > [ <insertInlineExampleTagNameHere> 3 + 4 == 7 ]. > ^self fallbackAdd: aNumber > > And have the browser pick it up, and either > - collapse it > - display text with alpha < 1 > > Make the code critic aware as well, and no more warnings of unused blocks > when used for examples! > > Cheers, > Henry > Hm, dead blocks, nice idea. see attached cs, you can file it in and have to uncomment one line in RBParser>>#parseBlock (the parsePragmasInto: aNode line) to activate pragmas in blocks, now you can add a "dead block" like [<example> 3+4] and the icon styler lets you execute (inspect) the code. (Just a quick and dirty implementation)
'From Pharo6.0 of 13 May 2016 [Latest update: #60231] on 20 September 2016 at 10:31:13.740364 pm'! IconStyler subclass: #ExampleIconStyler instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Reflectivity-Tools-Breakpoints'! !BIConfigurableFormatter methodsFor: 'private-formatting' stamp: 'NicolaiHess 9/20/2016 12:51'! formatBlock: aBlockNode codeStream nextPutAll: self stringInsideBlocks. self formatBlockArgumentsFor: aBlockNode. self formatBlockCommentFor: aBlockNode. aBlockNode pragmaNodes do:[:pnode | self visitNode: pnode; newLine]. self visitNode: aBlockNode body. (self lineUpBlockBrackets and: [ self willBeMultiline: aBlockNode body ]) ifTrue: [ self newLine ] ifFalse: [ codeStream nextPutAll: self stringInsideBlocks ]! ! !ExampleIconStyler methodsFor: 'defaults' stamp: 'NicolaiHess 9/20/2016 14:54'! iconBlock: aNode ^ [ (Smalltalk compiler class evaluate: aNode formattedCode) value inspect ]! ! !ExampleIconStyler methodsFor: 'defaults' stamp: 'NicolaiHess 9/20/2016 14:54'! iconFor: aNode ^ self iconProvider iconNamed: #flag! ! !ExampleIconStyler methodsFor: 'defaults' stamp: 'NicolaiHess 9/20/2016 13:07'! highlightColor ^ Smalltalk ui theme backgroundColor darker! ! !ExampleIconStyler methodsFor: 'defaults' stamp: 'NicolaiHess 9/20/2016 15:06'! iconLabel: aNode ^ 'inspect it'! ! !ExampleIconStyler methodsFor: 'testing' stamp: 'NicolaiHess 9/20/2016 14:54'! shouldStyleNode: aNode ^ aNode isBlock and: [ aNode hasExampleTag ]! ! !RBParser methodsFor: 'private-parsing' stamp: 'NicolaiHess 9/20/2016 12:48'! parsePragmaInto: aNode | start pragma | start := currentToken start. self step. pragma := self basicParsePragma. (currentToken isBinary and: [ currentToken value == #> ]) ifFalse: [ ^ self parserError: '''>'' expected' ]. pragma left: start; right: currentToken start. aNode addPragma: pragma.! ! !RBParser methodsFor: 'private-parsing' stamp: 'NicolaiHess 9/20/2016 22:30'! parseBlock | position node | position := currentToken start. self step. node := self blockNodeClass new. "self parsePragmasInto: node." self parseBlockArgsInto: node. self addCommentsTo: node. node left: position. node body: self sequenceNodeClass new. (self parseStatements: false into: node body). (currentToken isSpecial and: [currentToken value = $]]) ifFalse: [ self addParserError: ''']'' expected' to: node body. ^ node]. node right: currentToken start. self step. ^node! ! !RBParser methodsFor: 'private-parsing' stamp: 'NicolaiHess 9/20/2016 12:47'! parsePragmasInto: aNode [ currentToken isBinary and: [ currentToken value = #< ] ] whileTrue: [ self parsePragmaInto: aNode. self step ]! ! !RBProgramNode methodsFor: 'iterating' stamp: 'NicolaiHess 9/20/2016 12:58'! exampleNodes ^ self allChildren select:[:k | k isBlock and:[ k hasProperty:#pragmas]].! ! !RBBlockNode methodsFor: 'visiting' stamp: 'NicolaiHess 9/20/2016 12:47'! addPragma: aPragmaNode (self hasProperty: #pragmas) ifFalse: [ self propertyAt: #pragmas put: OrderedCollection new ]. (self propertyAt: #pragmas) addLast: aPragmaNode! ! !RBBlockNode methodsFor: 'visiting' stamp: 'NicolaiHess 9/20/2016 12:50'! pragmaNodes ^ (self hasProperty: #pragmas) ifFalse: [ #() ] ifTrue: [ self propertyAt: #pragmas ]! ! !RBBlockNode methodsFor: 'testing' stamp: 'NicolaiHess 9/20/2016 13:00'! hasExampleTag ^ self hasProperty:#pragmas! ! !SHRBTextStyler methodsFor: 'visiting rb nodes' stamp: 'NicolaiHess 9/20/2016 16:52'! visitBlockNode: aBlockNode aBlockNode comments do: [ :comment | self addStyle: #comment from: comment start to: comment stop ]. aBlockNode arguments do: [ :argument | self addStyle: #blockPatternArg forNode: argument ]. self styleOpenBracket: aBlockNode. aBlockNode hasExampleTag ifTrue:[ (aBlockNode propertyAt:#pragmas) do:[:pnode | self visitNode: pnode]]. self visitNode: aBlockNode body. self styleCloseBracket: aBlockNode! !