help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] method categories


From: Stefan Schmiedl
Subject: [Help-smalltalk] method categories
Date: Sun, 5 Jul 2009 20:23:43 +0200

I've been browsing through the codebase for a while now,
trying to understand why the STInST compiler misses out
on the method category pragma. Since I have zero experience
with writing real parsers, I might be well off the mark here.

I've started out with the attached CategoryTest.st file,
which defines a class Thing with two methods
- demo (new syntax, defined with demo [...])
- demo2 (old syntax, !Thing methodsFor: !demo2...!!)

The test runs look like

  $ gst -f CategoryTest.st 
  'views'
  'views'

  $ gst-remote --server -f CategoryTest.st 
  gst-remote server started.
  'still unclassified'
  'views'

so they show the non-desired behavioral difference between
old and new syntax.

I've been stumbling through the code, and think that the
source of the problem lies either in compiler/StartCompiler.st
or parser/STCompiler.st.

Let me bore you a while by showing you where I went...

When an STEvaluationDriver is called upon to compile something,
it goes through

  compile: node [
    <category: 'overrides'>
    method := curCompilerClass 
          compile: node
          for: curClass
          classified: curCategory
          parser: self.
    ^method
  ]

For the old syntax, it looks like:

  An instance of STInST.STEvaluationDriver
    parser: a GSTFileInParser
    curCategory: 'views'
    curClass: Thing
    curCompilerClass: STInST.STCompiler
    evalFor: nil
    lastResult: nil
    method: Thing>>demo

When compiling a new syntax, it is

  An instance of STInST.STEvaluationDriver
    parser: a GSTFileInParser
    curCategory: nil
    curClass: Thing
    curCompilerClass: STInST.STCompiler
    evalFor: nil
    lastResult: nil
    method: nil

You spot the difference ... but all could still have a happy ending,
since the corresponding nodes are slightly different, too.

Old syntax node:

  An instance of STInST.RBMethodNode
    parent: nil
    comments: ()
    selector: nil
    selectorParts: ( RBIdentifierToken('demo2') )
    body: RBSequenceNode(^'Hi! Hi!')
    source: a MappedSourceCode
    arguments: ()
    tags: nil
    category: nil

New syntax node:

  An instance of STInST.RBMethodNode
    parent: nil
    comments: nil
    selector: nil
    selectorParts: ( RBIdentifierToken('demo') )
    body: RBSequenceNode(<category: 'views'>
  ^'Hi!')
    source: a MappedSourceCode
    arguments: ()
    tags: OrderedCollection (Interval(86 87 ... 104) )
    category: nil

But the STCompiler class method called above self-delegates to

  STCompiler class >> compile: methodNode asMethodOf: aBehavior 
    classified: aString parser: aParser environment: aNamespace [
    <category: 'compilation'>
    | compiler |
    compiler := self new.
    compiler class: aBehavior parser: aParser.
    aNamespace isNil ifFalse: [compiler addPool: aNamespace].
    ^(compiler visitNode: methodNode)
        methodCategory: aString;
        yourself
  ]

Soo... even if (compiler visitNode: methodNode) defined the category
correctly, it would get overwritten by the non-set curCategory ivar
value passed in from STEvaluationDriver.

Now, the question to the experts: Where and how should that be fixed?

Exhausted,
s.

Attachment: CategoryTest.st
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]