The Inbox: OMeta2-Preload-yo.15.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: OMeta2-Preload-yo.15.mcz

commits-2
A new version of OMeta2-Preload was added to project The Inbox:
http://source.squeak.org/inbox/OMeta2-Preload-yo.15.mcz

==================== Summary ====================

Name: OMeta2-Preload-yo.15
Author: yo
Time: 31 July 2014, 1:29:01.319 pm
UUID: 6c6bc75e-3c9f-4446-b08a-cdce7081ef2d
Ancestors: OMeta2-Preload-hmm.14

Adapt to Squeak 4.5.

==================== Snapshot ====================

SystemOrganization addCategory: #OMeta2!
SystemOrganization addCategory: #'OMeta2-Info'!

----- Method: CompiledMethod>>methodNode (in category '*OMeta2-Preload') -----
methodNode
        "Return the parse tree that represents self. If parsing fails, decompile the method."
        | aClass source |
        aClass := self methodClass.
        source := self
                                getSourceFor: (self selector ifNil: [self defaultSelector])
                                in: aClass.
        ^[(aClass parserClass new
                encoderClass: (self isBlueBookCompiled
                                                ifTrue: [EncoderForV3]
                                                ifFalse: [EncoderForV3PlusClosures]);
                parse: source class: aClass)
                        sourceText: source;
                        yourself]
                on: SyntaxErrorNotification
                do: [:ex | ex return: self decompile].!

Exception subclass: #OM2Fail
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2Fail class>>initialize (in category 'class initialization') -----
initialize
        (Smalltalk at: #OMeta2Fail ifAbsent: []) class == self
                ifFalse: [Smalltalk at: #OMeta2Fail put: self new]!

----- Method: OM2Fail>>defaultAction (in category 'priv handling') -----
defaultAction

        self error: 'match failed'!

MethodReference subclass: #OM2DecompilingMethodReference
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2-Info'!

!OM2DecompilingMethodReference commentStamp: 'hmm 5/24/2010 13:15' prior: 0!
This class is a helper to OM2PreloadPackagingInfo which is used to save OMeta2 productions in their decompiled form.!

----- Method: OM2DecompilingMethodReference>>source (in category 'queries') -----
source
        ^self compiledMethod decompileString!

Compiler subclass: #OMeta2Compiler
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2Compiler>>compile:in:notifying:ifFail: (in category 'as yet unclassified') -----
compile: origCode in: cls notifying: notify ifFail: failBlock

        | origCodeStream parseTree structuredCode translatedCode |
        origCodeStream := origCode asString readStream.
        [
                parseTree := OMeta2RuleParser matchStream: origCodeStream with: #rule withArgs: #() withPlaybackDebugging: false.
                parseTree := OMeta2Optimizer match: parseTree with: #optimizeRule.
                structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {cls}.
                translatedCode := OMeta2Flattener match: structuredCode with: #flatten
        ] on: OM2Fail do: [
                self notify: '<-- parse error around here -->' at: origCodeStream position.
                ^ failBlock value
        ].
        ^ super compile: translatedCode in: cls notifying: notify ifFail: failBlock.
!

----- Method: OMeta2Compiler>>parse:class:noPattern:context:notifying:ifFail: (in category 'as yet unclassified') -----
parse: aStream class: aClass noPattern: noPattern context: ctxt notifying: req ifFail: aBlock
        | node |
        ^ [
                | parseTree structuredCode code |
                parseTree := OMeta2RuleParser matchAll: aStream contents with: #rule.
                structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {aClass}.
                code := OMeta2Flattener match: structuredCode with: #flatten.
                node := Parser new parse: code readStream class: aClass noPattern: noPattern context: ctxt notifying: req ifFail: aBlock.
                OMeta2MethodNode adoptInstance: node.
                node
        ] on: OM2Fail do: [aBlock value]!

----- Method: OMeta2Compiler>>parse:in:notifying: (in category 'as yet unclassified') -----
parse: origCode in: aClass notifying: req
        | c parseTree structuredCode translatedCode origCodeStream |
        origCodeStream := origCode asString readStream.

        parseTree := OMeta2RuleParser matchStream: origCodeStream with: #rule withArgs: #() withPlaybackDebugging: false.
        parseTree := OMeta2Optimizer match: parseTree with: #optimizeRule.
        structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {aClass}.
        translatedCode := OMeta2Flattener match: structuredCode with: #flatten.
       
        c := CompilationCue
                        source: translatedCode
                        class: aClass
                        requestor: req.
        ^ self
                parseCue: c
                noPattern: false
                ifFail: nil!

----- Method: OMeta2Compiler>>parseCue:noPattern:ifFail: (in category 'as yet unclassified') -----
parseCue: aCue noPattern: noPattern ifFail: aBlock
        ^ Parser new parseCue: aCue noPattern: noPattern ifFail: aBlock
!

----- Method: OMeta2Compiler>>parser (in category 'as yet unclassified') -----
parser
        ^ self parserClass new!

----- Method: OMeta2Compiler>>parserClass (in category 'as yet unclassified') -----
parserClass

        ^ self class!

PackageInfo subclass: #OM2PostloadPackageInfo
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2-Info'!

!OM2PostloadPackageInfo commentStamp: 'hmm 4/16/2010 17:09' prior: 0!
This class stores all OMeta2 production rules in their original format.!

----- Method: OM2PostloadPackageInfo class>>initialize (in category 'class initialization') -----
initialize
        self new register!

----- Method: OM2PostloadPackageInfo>>classes (in category 'listing') -----
classes
        ^super classes select: [:each | each inheritsFrom: OMeta2Base]!

----- Method: OM2PostloadPackageInfo>>coreMethodsForClass: (in category 'testing') -----
coreMethodsForClass: aClass
        MCMethodDefinition shutDown. "flush cache so pre- and postload don't interfere"
        ^(super coreMethodsForClass: aClass) select: [:each | OMeta2RuleParser isOMeta2Rule: each source]!

----- Method: OM2PostloadPackageInfo>>extensionMethodsForClass: (in category 'testing') -----
extensionMethodsForClass: aClass
        ^#()!

----- Method: OM2PostloadPackageInfo>>packageName (in category 'naming') -----
packageName
        ^super packageName, '-Postload'!

----- Method: OM2PostloadPackageInfo>>systemCategoryPrefix (in category 'naming') -----
systemCategoryPrefix
        ^super packageName!

PackageInfo subclass: #OM2PreloadPackageInfo
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2-Info'!

!OM2PreloadPackageInfo commentStamp: 'hmm 4/16/2010 17:08' prior: 0!
This class makes it possible to store OMeta2 using decompiled production rules, so that it can be loaded without being present first.
It uses OM2DecompilingMethodReference to decompile OMeta2 rules on the fly while creating a source file.!

----- Method: OM2PreloadPackageInfo class>>initialize (in category 'class initialization') -----
initialize
        self new register!

----- Method: OM2PreloadPackageInfo>>packageName (in category 'naming') -----
packageName
        ^super packageName, '-Preload'!

----- Method: OM2PreloadPackageInfo>>referenceForMethod:ofClass: (in category 'listing') -----
referenceForMethod: aSymbol ofClass: aClass
        MCMethodDefinition shutDown. "flush cache so pre- and postload don't interfere"
        ^((OMeta2RuleParser isOMeta2Rule: (aClass sourceCodeAt: aSymbol))
                ifTrue: [OM2DecompilingMethodReference]
                ifFalse: [MethodReference]) new setStandardClass: aClass methodSymbol: aSymbol!

----- Method: OM2PreloadPackageInfo>>systemCategoryPrefix (in category 'naming') -----
systemCategoryPrefix
        ^super packageName!

Object subclass: #OM2Failer
        instanceVariableNames: 'used'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2Failer>>initialize (in category 'initialize-release') -----
initialize

        used := false!

----- Method: OM2Failer>>used (in category 'testing') -----
used

        ^ used!

----- Method: OM2Failer>>value (in category 'evaluating') -----
value

        used := true.
        OMeta2Fail signal!

Object subclass: #OM2Stream
        instanceVariableNames: 'head tail memo'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

OM2Stream subclass: #OM2EndOfStream
        instanceVariableNames: 'stream pos'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2EndOfStream>>head (in category 'accessing') -----
head

        OMeta2Fail signal!

----- Method: OM2EndOfStream>>initStream:pos: (in category 'initialize-release') -----
initStream: s pos: p

        stream := s.
        pos := p!

----- Method: OM2EndOfStream>>inputSpecies (in category 'accessing') -----
inputSpecies

        ^ stream originalContents species!

----- Method: OM2EndOfStream>>pos (in category 'accessing') -----
pos

        ^ pos!

----- Method: OM2EndOfStream>>tail (in category 'accessing') -----
tail

        OMeta2Fail signal!

OM2Stream subclass: #OM2LazyStream
        instanceVariableNames: 'stream pos'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2LazyStream class>>for:withPos: (in category 'as yet unclassified') -----
for: aReadStream withPos: pos

        ^ aReadStream atEnd
                ifTrue: [OM2EndOfStream new initStream: aReadStream pos: pos]
                ifFalse: [self new initHead: aReadStream next stream: aReadStream pos: pos]!

----- Method: OM2LazyStream>>initHead:stream:pos: (in category 'initialize-release') -----
initHead: h stream: s pos: p

        head := h.
        stream := s.
        pos := p!

----- Method: OM2LazyStream>>inputSpecies (in category 'accessing') -----
inputSpecies

        ^ stream originalContents species!

----- Method: OM2LazyStream>>pos (in category 'accessing') -----
pos

        ^ pos!

----- Method: OM2LazyStream>>tail (in category 'accessing') -----
tail

        tail ifNil: [tail := OM2LazyStream for: stream withPos: pos + 1].
        ^ tail!

----- Method: OM2Stream>>basicTail (in category 'accessing') -----
basicTail

        ^ tail!

----- Method: OM2Stream>>forgetEverything (in category 'forgetting') -----
forgetEverything

        memo := IdentityDictionary new!

----- Method: OM2Stream>>head (in category 'accessing') -----
head

        ^ head!

----- Method: OM2Stream>>initHead:tail: (in category 'initialize-release') -----
initHead: h tail: t

        head := h.
        tail := t!

----- Method: OM2Stream>>initialize (in category 'initialize-release') -----
initialize

        memo := IdentityDictionary new!

----- Method: OM2Stream>>inputSpecies (in category 'accessing') -----
inputSpecies

        ^ Array!

----- Method: OM2Stream>>memo (in category 'accessing') -----
memo

        ^ memo!

----- Method: OM2Stream>>pos (in category 'accessing') -----
pos

        ^ -1!

----- Method: OM2Stream>>printOn: (in category 'printing') -----
printOn: aStream

        | inputIsString curr |
        inputIsString := (self inputSpecies inheritsFrom: String) and: [(self inputSpecies inheritsFrom: Symbol) not].
        curr := self.
        aStream
                nextPutAll: 'an ';
                nextPutAll: self class name;
                nextPut: $(.
        [curr notNil] whileTrue: [
                (curr isKindOf: OM2EndOfStream) ifTrue: [
                        aStream nextPut: $).
                        ^ self
                ].
                inputIsString
                        ifTrue: [aStream nextPut: curr head]
                        ifFalse: [
                                curr head printOn: aStream.
                                aStream space
                        ].
                curr := curr basicTail.
        ].
        aStream nextPutAll: '...)'!

----- Method: OM2Stream>>tail (in category 'accessing') -----
tail

        ^ tail!

----- Method: OM2Stream>>transitiveForgetEverything (in category 'forgetting') -----
transitiveForgetEverything

        | curr |
        curr := self.
        [curr notNil] whileTrue: [
                curr forgetEverything.
                curr := curr basicTail
        ]!

OM2Stream subclass: #OM2StreamDebugger
        instanceVariableNames: 'om2stream'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2StreamDebugger class>>for: (in category 'as yet unclassified') -----
for: anOM2Stream

        ^ self new initOm2stream: anOM2Stream!

----- Method: OM2StreamDebugger>>forgetEverything (in category 'forgetting') -----
forgetEverything

        om2stream forgetEverything!

----- Method: OM2StreamDebugger>>head (in category 'accessing') -----
head

        ^ om2stream head!

----- Method: OM2StreamDebugger>>initOm2stream: (in category 'initialize-release') -----
initOm2stream: anOM2Stream

        om2stream := anOM2Stream!

----- Method: OM2StreamDebugger>>memo (in category 'accessing') -----
memo

        ^ om2stream memo!

----- Method: OM2StreamDebugger>>printOn: (in category 'printing') -----
printOn: aStream

        aStream nextPutAll: 'an OM2StreamDebugger('.
        om2stream printOn: aStream.
        aStream nextPut: $)!

----- Method: OM2StreamDebugger>>tail (in category 'accessing') -----
tail

        ^ om2stream tail!

----- Method: OM2StreamDebugger>>transitiveForgetEverything (in category 'forgetting') -----
transitiveForgetEverything

        om2stream transitiveForgetEverything!

OM2Stream subclass: #OM2StreamProxy
        instanceVariableNames: 'target'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OM2StreamProxy class>>for: (in category 'as yet unclassified') -----
for: anOM2Stream

        ^ self new initTarget: anOM2Stream!

----- Method: OM2StreamProxy>>basicTail (in category 'accessing') -----
basicTail

        ^ target basicTail!

----- Method: OM2StreamProxy>>head (in category 'accessing') -----
head

        head ifNil: [head := target head].
        ^ head
!

----- Method: OM2StreamProxy>>initTarget: (in category 'initialize-release') -----
initTarget: anOM2Stream

        target := anOM2Stream!

----- Method: OM2StreamProxy>>inputSpecies (in category 'accessing') -----
inputSpecies

        ^ target inputSpecies!

----- Method: OM2StreamProxy>>pos (in category 'accessing') -----
pos

        ^ target pos!

----- Method: OM2StreamProxy>>tail (in category 'accessing') -----
tail

        tail ifNil: [tail := OM2StreamProxy for: target tail].
        ^ tail!

----- Method: OM2StreamProxy>>target (in category 'accessing') -----
target

        ^ target!

Object subclass: #OMeta2Base
        instanceVariableNames: 'input om2streams haltingPoint'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

OMeta2Base subclass: #OMeta2
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

!OMeta2 commentStamp: '<historical>' prior: 0!
TODOS:

* implement OMeta -> Squeak translator
* implement Squeak parser
* implement OMeta/Squeak "compiler", make it OMeta2's compilerClass

* rewrite #char, #digit, #empty, #end, #exactly, #firstAndRest, #fromTo, #letter, #letterOrDigit, #listOf, #lower, #notLast, #number, #range, #space, #spaces, #string, #symbol, #token, and #upper in OMeta syntax
* consider implementing position-related functionality (see http://www.tinlizzie.org/ometa-js/ometa-base.js)
* consider the optimization suggestions in the comments of OMeta2Lib's methods!

OMeta2 subclass: #O2SqueakRecognizer
        instanceVariableNames: ''
        classVariableNames: 'TypeTable'
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: O2SqueakRecognizer class>>initialize (in category 'as yet unclassified') -----
initialize

        TypeTable := #(#xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xDelimiter #xDelimiter #xBinary #xDelimiter #xDelimiter #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #doIt #xBinary #xDelimiter #xBinary #xDoubleQuote #xLitQuote #xDollar #xBinary #xBinary #xSingleQuote #leftParenthesis #rightParenthesis #xBinary #xBinary #xBinary #xBinary #period #xBinary #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xColon #semicolon #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #leftBracket #xBinary #rightBracket #upArrow #leftArrow #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #leftBrace #verticalBar #rightBrace #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xBinary)!

----- Method: O2SqueakRecognizer>>arrayConstr (in category 'rules-parsing') -----
arrayConstr
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #token withArgs: {'{'}.
                                self apply: #expr.
                                self
                                        many: [true
                                                        ifTrue: [self apply: #token withArgs: {'.'}.
                                                                self apply: #expr]].
                                self ometaOr: {[self apply: #token withArgs: {'.'}]. [self apply: #empty]}.
                                self apply: #token withArgs: {'}'}]]. [true
                        ifTrue: [self apply: #token withArgs: {'{'}.
                                self apply: #token withArgs: {'}'}]]}!

----- Method: O2SqueakRecognizer>>arrayLit (in category 'rules-parsing') -----
arrayLit
        ^ true
                ifTrue: [self apply: #token withArgs: {'#'}.
                        self apply: #token withArgs: {'('}.
                        self
                                many: [self ometaOr: {[self apply: #literal]. [self apply: #arrayLit]. [true
                                                        ifTrue: [self apply: #spaces.
                                                                self apply: #tsArraySymbol]]}].
                        self apply: #token withArgs: {')'}]!

----- Method: O2SqueakRecognizer>>binary (in category 'rules-parsing') -----
binary
        ^ true
                ifTrue: [self apply: #spaces.
                        self apply: #tsBinary]!

----- Method: O2SqueakRecognizer>>binaryExpr (in category 'rules-parsing') -----
binaryExpr
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #binaryExpr.
                                self apply: #binaryMsg]]. [self apply: #unaryExpr]}!

----- Method: O2SqueakRecognizer>>binaryMsg (in category 'rules-parsing') -----
binaryMsg
        ^ true
                ifTrue: [self apply: #binary.
                        self apply: #unaryExpr]!

----- Method: O2SqueakRecognizer>>block (in category 'rules-parsing') -----
block
        ^ true
                ifTrue: [self apply: #token withArgs: {'['}.
                        self ometaOr: {[true
                                        ifTrue: [self
                                                        many1: [true
                                                                        ifTrue: [self apply: #token withArgs: {':'}.
                                                                                self apply: #identifier]].
                                                self apply: #token withArgs: {'|'}]]. [self apply: #empty]}.
                        self ometaOr: {[true
                                        ifTrue: [self apply: #token withArgs: {'|'}.
                                                self
                                                        many: [self apply: #identifier].
                                                self apply: #token withArgs: {'|'}]]. [self apply: #empty]}.
                        self ometaOr: {[true
                                        ifTrue: [self apply: #expr.
                                                self
                                                        many: [true
                                                                        ifTrue: [self apply: #token withArgs: {'.'}.
                                                                                self apply: #expr]].
                                                self ometaOr: {[true
                                                                ifTrue: [self apply: #token withArgs: {'.'}.
                                                                        self apply: #token withArgs: {'^'}.
                                                                        self apply: #expr]]. [self apply: #empty]}]]. [true
                                        ifTrue: [self apply: #token withArgs: {'^'}.
                                                self apply: #expr]]. [self apply: #empty]}.
                        self ometaOr: {[self apply: #token withArgs: {'.'}]. [self apply: #empty]}.
                        self apply: #token withArgs: {']'}]!

----- Method: O2SqueakRecognizer>>cascade (in category 'rules-parsing') -----
cascade
        ^ self ometaOr: {[self apply: #identifier]. [self apply: #binaryMsg]. [self apply: #keywordMsg]}!

----- Method: O2SqueakRecognizer>>expr (in category 'rules-parsing') -----
expr
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #identifier.
                                self ometaOr: {[self apply: #token withArgs: {':='}]. [self apply: #token withArgs: {'_'}]}.
                                self apply: #expr]]. [self apply: #msgExpr]}!

----- Method: O2SqueakRecognizer>>identifier (in category 'rules-parsing') -----
identifier
        ^ true
                ifTrue: [self apply: #spaces.
                        self apply: #tsIdentifier.
                        self
                                not: [self apply: #exactly withArgs: {$:}]]!

----- Method: O2SqueakRecognizer>>keyword (in category 'rules-parsing') -----
keyword
        ^ true
                ifTrue: [self apply: #spaces.
                        self apply: #tsKeyword]!

----- Method: O2SqueakRecognizer>>keywordExpr (in category 'rules-parsing') -----
keywordExpr
        ^ true
                ifTrue: [self apply: #binaryExpr.
                        self apply: #keywordMsg]!

----- Method: O2SqueakRecognizer>>keywordMsg (in category 'rules-parsing') -----
keywordMsg
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #keywordMsg.
                                self apply: #keywordMsgPart]]. [self apply: #keywordMsgPart]}!

----- Method: O2SqueakRecognizer>>keywordMsgPart (in category 'rules-parsing') -----
keywordMsgPart
        ^ true
                ifTrue: [self apply: #keyword.
                        self apply: #binaryExpr]!

----- Method: O2SqueakRecognizer>>literal (in category 'rules-parsing') -----
literal
        ^ true
                ifTrue: [self apply: #spaces.
                        self ometaOr: {[self apply: #tsNumber]. [self apply: #tsCharacter]. [self apply: #tsString]. [self apply: #tsSymbol]}]!

----- Method: O2SqueakRecognizer>>msgExpr (in category 'rules-parsing') -----
msgExpr
        ^ true
                ifTrue: [self ometaOr: {[self apply: #keywordExpr]. [self apply: #binaryExpr]}.
                        self
                                many: [true
                                                ifTrue: [self apply: #token withArgs: {';'}.
                                                        self apply: #cascade]]]!

----- Method: O2SqueakRecognizer>>squeakExpr (in category 'rules-parsing') -----
squeakExpr
        ^ self
                consumedBy: [self apply: #expr]!

----- Method: O2SqueakRecognizer>>symbol (in category 'rules-parsing') -----
symbol
        ^ true
                ifTrue: [self apply: #token withArgs: {'#'}.
                        self apply: #spaces.
                        self ometaOr: {[self apply: #tsString]. [true
                                        ifTrue: [self apply: #tsKeyword.
                                                self ometaOr: {[self apply: #tsIdentifier]. [self apply: #empty]}]]}]!

----- Method: O2SqueakRecognizer>>tcBinaryChar (in category 'rules-lexing') -----
tcBinaryChar
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: (TypeTable at: t1 asciiValue)
                                        == #xBinary]!

----- Method: O2SqueakRecognizer>>tsArraySymbol (in category 'rules-lexing') -----
tsArraySymbol
        ^ self ometaOr: {[true
                        ifTrue: [self
                                        many1: [self apply: #tsKeyword].
                                self ometaOr: {[self apply: #tsIdentifier]. [self apply: #empty]}]]. [self apply: #tsIdentifier]}!

----- Method: O2SqueakRecognizer>>tsBinary (in category 'rules-lexing') -----
tsBinary
        ^ true
                ifTrue: [self ometaOr: {[self apply: #exactly withArgs: {$|}]. [self apply: #tcBinaryChar]}.
                        self
                                many: [self apply: #tcBinaryChar]]!

----- Method: O2SqueakRecognizer>>tsCharacter (in category 'rules-lexing') -----
tsCharacter
        ^ true
                ifTrue: [self apply: #exactly withArgs: {$$}.
                        self apply: #char]!

----- Method: O2SqueakRecognizer>>tsIdentifier (in category 'rules-lexing') -----
tsIdentifier
        ^ true
                ifTrue: [self apply: #letter.
                        self
                                many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]!

----- Method: O2SqueakRecognizer>>tsKeyword (in category 'rules-lexing') -----
tsKeyword
        ^ true
                ifTrue: [self apply: #tsIdentifier.
                        self apply: #exactly withArgs: {$:}]!

----- Method: O2SqueakRecognizer>>tsNatural (in category 'rules-lexing') -----
tsNatural
        ^ self
                many1: [self apply: #digit]!

----- Method: O2SqueakRecognizer>>tsNumber (in category 'rules-lexing') -----
tsNumber
        ^ true
                ifTrue: [self ometaOr: {[self apply: #exactly withArgs: {$+}]. [self apply: #exactly withArgs: {$-}]. [self apply: #empty]}.
                        self apply: #tsNatural]!

----- Method: O2SqueakRecognizer>>tsString (in category 'rules-lexing') -----
tsString
        ^ true
                ifTrue: [self apply: #exactly withArgs: {$'}.
                        self
                                many: [self ometaOr: {[true
                                                        ifTrue: [self apply: #exactly withArgs: {$'}.
                                                                self apply: #exactly withArgs: {$'}]]. [true
                                                        ifTrue: [self
                                                                        not: [self apply: #exactly withArgs: {$'}].
                                                                self apply: #char]]}].
                        self apply: #exactly withArgs: {$'}]!

----- Method: O2SqueakRecognizer>>tsSymbol (in category 'rules-lexing') -----
tsSymbol
        ^ true
                ifTrue: [self apply: #exactly withArgs: {$#}.
                        self apply: #spaces.
                        self ometaOr: {[self apply: #tsString]. [self apply: #tsArraySymbol]}]!

----- Method: O2SqueakRecognizer>>unaryExpr (in category 'rules-parsing') -----
unaryExpr
        ^ true
                ifTrue: [self apply: #unit.
                        self
                                many: [self apply: #identifier]]!

----- Method: O2SqueakRecognizer>>unit (in category 'rules-parsing') -----
unit
        ^ self ometaOr: {[self apply: #literal]. [self apply: #identifier]. [self apply: #arrayLit]. [self apply: #arrayConstr]. [self apply: #block]. [true
                        ifTrue: [self apply: #token withArgs: {'('}.
                                self apply: #expr.
                                self apply: #token withArgs: {')'}]]}!

----- Method: OMeta2>>char (in category 'rules') -----
char
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self pred: t1 isCharacter.
                        t1]!

----- Method: OMeta2>>digit (in category 'rules') -----
digit
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 isDigit.
                        t1]!

----- Method: OMeta2>>end (in category 'rules') -----
end
        ^ self
                not: [self apply: #anything]!

----- Method: OMeta2>>exactly (in category 'rules-meta') -----
exactly
        | t1 t2 |
        ^ true
                ifTrue: [t2 := self apply: #anything.
                        t1 := self apply: #anything.
                        self pred: t2 = t1.
                        t2]!

----- Method: OMeta2>>fromTo (in category 'rules') -----
fromTo
        | t1 t2 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        t2 := self apply: #anything.
                        self apply: #seq withArgs: {t1}.
                        self
                                many: [true
                                                ifTrue: [self
                                                                not: [self apply: #seq withArgs: {t2}].
                                                        self apply: #char]].
                        self apply: #seq withArgs: {t2}]!

----- Method: OMeta2>>letter (in category 'rules') -----
letter
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 isLetter.
                        t1]!

----- Method: OMeta2>>letterOrDigit (in category 'rules') -----
letterOrDigit
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 isAlphaNumeric.
                        t1]!

----- Method: OMeta2>>listOf (in category 'rules-meta') -----
listOf
        | t1 t2 t3 t5 |
        ^ true
                ifTrue: [t2 := self apply: #anything.
                        t1 := self apply: #anything.
                        self ometaOr: {[true
                                        ifTrue: [t3 := self apply: #apply withArgs: {t2}.
                                                t5 := self
                                                                        many: [true
                                                                                        ifTrue: [self apply: #token withArgs: {t1}.
                                                                                                self apply: #apply withArgs: {t2}]].
                                                t5 addFirst: t3;
                                                         yourself]]. [true
                                        ifTrue: [self apply: #empty.
                                                #()]]}]!

----- Method: OMeta2>>lower (in category 'rules') -----
lower
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 isLowercase.
                        t1]!

----- Method: OMeta2>>notLast (in category 'rules-meta') -----
notLast
        | t1 t2 |
        ^ true
                ifTrue: [t2 := self apply: #anything.
                        t1 := self apply: #apply withArgs: {t2}.
                        self
                                lookahead: [self apply: #apply withArgs: {t2}].
                        t1]!

----- Method: OMeta2>>number (in category 'rules') -----
number
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self pred: t1 isNumber.
                        t1]!

----- Method: OMeta2>>range (in category 'rules-meta') -----
range
        | t1 t2 t3 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        t2 := self apply: #anything.
                        t3 := self apply: #anything.
                        self pred: t1 <= t3 & (t3 <= t2).
                        t3]!

----- Method: OMeta2>>space (in category 'rules') -----
space
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 asciiValue <= 32.
                        t1]!

----- Method: OMeta2>>spaces (in category 'rules') -----
spaces
        ^ self
                many: [self apply: #space]!

----- Method: OMeta2>>string (in category 'rules') -----
string
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self pred: t1 isString.
                        t1]!

----- Method: OMeta2>>symbol (in category 'rules') -----
symbol
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self pred: t1 isSymbol.
                        t1]!

----- Method: OMeta2>>token (in category 'rules-meta') -----
token
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self apply: #spaces.
                        self apply: #seq withArgs: {t1}]!

----- Method: OMeta2>>upper (in category 'rules') -----
upper
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #char.
                        self pred: t1 isUppercase.
                        t1]!

OMeta2 subclass: #OMeta2Examples
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

!OMeta2Examples commentStamp: '<historical>' prior: 0!
Here's how to run these examples:

        OMeta2Examples match: 5 with: #fact.
        OMeta2Examples matchAll: '1234' with: #number.
        OMeta2Examples matchAll: 'abc123' with: #identifier.
        OMeta2Examples matchAll: #($a $b $c 1 2 3 #(4 5)) with: #structure.
        OMeta2Examples matchAll: 'howdy' with: #greeting.!

----- Method: OMeta2Examples>>aSqueakMethod (in category 'squeak methods') -----
aSqueakMethod

        self inform: 'hello world'!

----- Method: OMeta2Examples>>anotherSqueakMethod (in category 'squeak methods') -----
anotherSqueakMethod

        self inform: 'good-bye world'!

----- Method: OMeta2Examples>>digit (in category 'rules') -----
digit
        | t1 |
        ^ true
                ifTrue: [t1 := self
                                                super: OMeta2
                                                apply: #digit
                                                withArgs: {}.
                        t1 digitValue]!

----- Method: OMeta2Examples>>fact (in category 'rules') -----
fact
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #exactly withArgs: {0}.
                                1]]. [true
                        ifTrue: [t3 := self apply: #anything.
                                t1 := self apply: #fact withArgs: {t3 - 1}.
                                t3 * t1]]}!

----- Method: OMeta2Examples>>formTest (in category 'rules') -----
formTest
        ^ self ometaOr: {[self
                        form: [true
                                        ifTrue: [self inform: input hash printString.
                                                self apply: #exactly withArgs: {#foo}.
                                                self apply: #exactly withArgs: {#bar}]]]. [self
                        form: [true
                                        ifTrue: [self inform: input hash printString.
                                                self apply: #exactly withArgs: {#bar}]]]}!

----- Method: OMeta2Examples>>greeting (in category 'rules') -----
greeting
        ^ self
                consumedBy: [true
                                ifTrue: [self apply: #seq withArgs: {'howdy'}.
                                        self
                                                opt: [self apply: #seq withArgs: {'-ho'}]]]!

----- Method: OMeta2Examples>>identifier (in category 'rules') -----
identifier
        ^ true
                ifTrue: [self apply: #spaces.
                        self
                                consumedBy: [true
                                                ifTrue: [self apply: #letter.
                                                        self
                                                                many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]]]!

----- Method: OMeta2Examples>>identifierIdx (in category 'rules') -----
identifierIdx
        ^ true
                ifTrue: [self apply: #spaces.
                        self
                                indexConsumedBy: [true
                                                ifTrue: [self apply: #letter.
                                                        self
                                                                many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]]]!

----- Method: OMeta2Examples>>identifiers (in category 'rules') -----
identifiers
        ^ self
                many: [true
                                ifTrue: [self inform: self pos printString.
                                        self apply: #identifier]]!

----- Method: OMeta2Examples>>number (in category 'rules') -----
number
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [t3 := self apply: #number.
                                t1 := self apply: #digit.
                                t3 * 10 + t1]]. [self apply: #digit]}!

----- Method: OMeta2Examples>>structure (in category 'rules') -----
structure
        ^ true
                ifTrue: [self apply: #exactly withArgs: {$a}.
                        self apply: #exactly withArgs: {$b}.
                        self apply: #exactly withArgs: {$c}.
                        self apply: #exactly withArgs: {1}.
                        self apply: #exactly withArgs: {2}.
                        self apply: #exactly withArgs: {3}.
                        self
                                form: [self
                                                many: [self apply: #anything]]]!

OMeta2 subclass: #OMeta2Flattener
        instanceVariableNames: 'ws'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2Flattener>>flatten (in category 'rules') -----
flatten
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self apply: #iFlatten withArgs: {t1}.
                        ws contents]!

----- Method: OMeta2Flattener>>iFlatten (in category 'rules') -----
iFlatten
        | t1 |
        ^ self ometaOr: {[true
                        ifTrue: [t1 := self apply: #string.
                                ws nextPutAll: t1]]. [self
                        form: [self
                                        many: [self apply: #iFlatten]]]}!

----- Method: OMeta2Flattener>>initialize (in category 'initialize-release') -----
initialize

        super initialize.
        ws := (String new: 64) writeStream!

OMeta2 subclass: #OMeta2NullOpt
        instanceVariableNames: 'didSomething'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

OMeta2NullOpt subclass: #OMeta2AndOrOpt
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2AndOrOpt>>and (in category 'rules') -----
and
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [t1 := self apply: #trans.
                                self apply: #end.
                                self apply: #setHelped.
                                t1]]. [true
                        ifTrue: [t3 := self apply: #transInside withArgs: {#And}.
                                t3 addFirst: #And;
                                         yourself]]}!

----- Method: OMeta2AndOrOpt>>or (in category 'rules') -----
or
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [t1 := self apply: #trans.
                                self apply: #end.
                                self apply: #setHelped.
                                t1]]. [true
                        ifTrue: [t3 := self apply: #transInside withArgs: {#Or}.
                                t3 addFirst: #Or;
                                         yourself]]}!

----- Method: OMeta2AndOrOpt>>transInside (in category 'rules') -----
transInside
        | t1 t2 t4 t5 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self ometaOr: {[true
                                        ifTrue: [self
                                                        form: [true
                                                                        ifTrue: [self apply: #exactly withArgs: {t1}.
                                                                                t4 := self apply: #transInside withArgs: {t1}]].
                                                t5 := self apply: #transInside withArgs: {t1}.
                                                self apply: #setHelped.
                                                t4 , t5]]. [true
                                        ifTrue: [t2 := self apply: #trans.
                                                t4 := self apply: #transInside withArgs: {t1}.
                                                t4 addFirst: t2;
                                                         yourself]]. [true
                                        ifTrue: [self apply: #empty.
                                                OrderedCollection new]]}]!

----- Method: OMeta2NullOpt>>and (in category 'rules') -----
and
        | t1 |
        ^ true
                ifTrue: [t1 := self
                                                many: [self apply: #trans].
                        t1 addFirst: #And;
                                 yourself]!

----- Method: OMeta2NullOpt>>consby (in category 'rules') -----
consby
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#ConsBy. t1}]!

----- Method: OMeta2NullOpt>>form (in category 'rules') -----
form
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Form. t1}]!

----- Method: OMeta2NullOpt>>helped (in category 'rules') -----
helped
        ^ self pred: didSomething!

----- Method: OMeta2NullOpt>>idxconsby (in category 'rules') -----
idxconsby
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#IdxConsBy. t1}]!

----- Method: OMeta2NullOpt>>initialize (in category 'initialize-release') -----
initialize

        super initialize.
        didSomething := false!

----- Method: OMeta2NullOpt>>lookahead (in category 'rules') -----
lookahead
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Lookahead. t1}]!

----- Method: OMeta2NullOpt>>many (in category 'rules') -----
many
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Many. t1}]!

----- Method: OMeta2NullOpt>>many1 (in category 'rules') -----
many1
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Many1. t1}]!

----- Method: OMeta2NullOpt>>not (in category 'rules') -----
not
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Not. t1}]!

----- Method: OMeta2NullOpt>>opt (in category 'rules') -----
opt
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {#Opt. t1}]!

----- Method: OMeta2NullOpt>>optimize (in category 'rules') -----
optimize
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        self apply: #helped.
                        t1]!

----- Method: OMeta2NullOpt>>or (in category 'rules') -----
or
        | t1 |
        ^ true
                ifTrue: [t1 := self
                                                many: [self apply: #trans].
                        t1 addFirst: #Or;
                                 yourself]!

----- Method: OMeta2NullOpt>>rule (in category 'rules') -----
rule
        | t1 t2 t3 |
        ^ true
                ifTrue: [t2 := self apply: #anything.
                        t3 := self apply: #anything.
                        t1 := self apply: #trans.
                        {#Rule. t2. t3. t1}]!

----- Method: OMeta2NullOpt>>set (in category 'rules') -----
set
        | t1 t2 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        t2 := self apply: #trans.
                        {#Set. t1. t2}]!

----- Method: OMeta2NullOpt>>setHelped (in category 'rules') -----
setHelped
        ^ didSomething := true!

----- Method: OMeta2NullOpt>>trans (in category 'rules') -----
trans
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [self
                                        form: [true
                                                        ifTrue: [t3 := self apply: #anything.
                                                                t3 := t3 asLowercase asSymbol.
                                                                self
                                                                        pred: (self class canUnderstand: t3).
                                                                t1 := self apply: #apply withArgs: {t3}]].
                                t1]]. [self apply: #anything]}!

OMeta2 subclass: #OMeta2Optimizer
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2Optimizer>>optimizeRule (in category 'rules') -----
optimizeRule
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self
                                many: [t1 := self apply: #foreign withArgs: {OMeta2AndOrOpt. #optimize. t1}].
                        t1]!

OMeta2 subclass: #OMeta2RuleParser
        instanceVariableNames: 'temps'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2RuleParser class>>isOMeta2Rule: (in category 'as yet unclassified') -----
isOMeta2Rule: aString

        ^ [(self matchAll: aString with: #rule) first ~= #Squeak] on: OM2Fail do: [false]!

----- Method: OMeta2RuleParser>>application (in category 'rules') -----
application
        | t1 t3 t4 |
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #token withArgs: {'^'}.
                                t4 := self apply: #name.
                                t1 := self apply: #args.
                                {#SuperApp. t4} , t1]]. [true
                        ifTrue: [t3 := self apply: #name.
                                self apply: #exactly withArgs: {$.}.
                                t4 := self apply: #nsName.
                                t1 := self apply: #args.
                                {#App. #foreign. t3. ('#' , t4) asSymbol} , t1]]. [true
                        ifTrue: [t4 := self apply: #name.
                                t1 := self apply: #args.
                                {#App. t4} , t1]]}!

----- Method: OMeta2RuleParser>>args (in category 'rules') -----
args
        | t1 |
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #exactly withArgs: {$(}.
                                t1 := self apply: #listOf withArgs: {#squeakExpression. '.'}.
                                self apply: #token withArgs: {')'}.
                                t1]]. [true
                        ifTrue: [self
                                        not: [self apply: #exactly withArgs: {$(}].
                                #()]]}!

----- Method: OMeta2RuleParser>>characterLiteral (in category 'rules') -----
characterLiteral
        | t1 |
        ^ true
                ifTrue: [self apply: #spaces.
                        self apply: #exactly withArgs: {$$}.
                        t1 := self apply: #char.
                        {#App. #exactly. t1 storeString}]!

----- Method: OMeta2RuleParser>>characters (in category 'rules') -----
characters
        | t1 |
        ^ true
                ifTrue: [self apply: #token withArgs: {'``'}.
                        t1 := self
                                                many: [true
                                                                ifTrue: [self
                                                                                not: [true
                                                                                                ifTrue: [self apply: #exactly withArgs: {$'}.
                                                                                                        self apply: #exactly withArgs: {$'}]].
                                                                        self apply: #char]].
                        self apply: #exactly withArgs: {$'}.
                        self apply: #exactly withArgs: {$'}.
                        {#App. #seq. (String withAll: t1) storeString}]!

----- Method: OMeta2RuleParser>>expr (in category 'rules') -----
expr
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #listOf withArgs: {#expr4. '|'}.
                        (OrderedCollection with: #Or) addAll: t1;
                                 yourself]!

----- Method: OMeta2RuleParser>>expr1 (in category 'rules') -----
expr1
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [t3 := self ometaOr: {[self apply: #keyword withArgs: {'true'}]. [self apply: #keyword withArgs: {'false'}]. [self apply: #keyword withArgs: {'nil'}]}.
                                {#App. #exactly. t3}]]. [self apply: #application]. [self apply: #semanticAction]. [self apply: #semanticPredicate]. [self apply: #characters]. [self apply: #tokenSugar]. [self apply: #stringLiteral]. [self apply: #symbolLiteral]. [self apply: #numberLiteral]. [self apply: #characterLiteral]. [true
                        ifTrue: [self apply: #token withArgs: {'{'}.
                                t1 := self apply: #expr.
                                self apply: #token withArgs: {'}'}.
                                {#Form. t1}]]. [true
                        ifTrue: [self apply: #token withArgs: {'<'}.
                                t1 := self apply: #expr.
                                self apply: #token withArgs: {'>'}.
                                {#ConsBy. t1}]]. [true
                        ifTrue: [self apply: #token withArgs: {'@<'}.
                                t1 := self apply: #expr.
                                self apply: #token withArgs: {'>'}.
                                {#IdxConsBy. t1}]]. [true
                        ifTrue: [self apply: #token withArgs: {'('}.
                                t1 := self apply: #expr.
                                self apply: #token withArgs: {')'}.
                                t1]]}!

----- Method: OMeta2RuleParser>>expr2 (in category 'rules') -----
expr2
        | t1 |
        ^ self ometaOr: {[true
                        ifTrue: [self apply: #token withArgs: {'~'}.
                                t1 := self apply: #expr2.
                                {#Not. t1}]]. [true
                        ifTrue: [self apply: #token withArgs: {'&'}.
                                t1 := self apply: #expr2.
                                {#Lookahead. t1}]]. [self apply: #expr1]}!

----- Method: OMeta2RuleParser>>expr3 (in category 'rules') -----
expr3
        | t1 t3 |
        ^ self ometaOr: {[true
                        ifTrue: [t3 := self apply: #expr2.
                                t3 := self apply: #optIter withArgs: {t3}.
                                self ometaOr: {[true
                                                ifTrue: [self apply: #exactly withArgs: {$:}.
                                                        t1 := self apply: #nsName.
                                                        temps add: t1.
                                                        {#Set. t1. t3}]]. [true
                                                ifTrue: [self apply: #empty.
                                                        t3]]}]]. [true
                        ifTrue: [self apply: #token withArgs: {':'}.
                                t1 := self apply: #nsName.
                                temps add: t1.
                                {#Set. t1. {#App. #anything}}]]}!

----- Method: OMeta2RuleParser>>expr4 (in category 'rules') -----
expr4
        | t1 |
        ^ true
                ifTrue: [t1 := self
                                                many: [self apply: #expr3].
                        (OrderedCollection with: #And) addAll: t1;
                                 yourself]!

----- Method: OMeta2RuleParser>>initialize (in category 'initialize-release') -----
initialize

        super initialize.
        temps := IdentitySet new!

----- Method: OMeta2RuleParser>>keyword (in category 'rules-meta') -----
keyword
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self apply: #token withArgs: {t1}.
                        self
                                not: [self apply: #letterOrDigit].
                        t1]!

----- Method: OMeta2RuleParser>>name (in category 'rules') -----
name
        ^ true
                ifTrue: [self apply: #spaces.
                        self apply: #nsName]!

----- Method: OMeta2RuleParser>>nameFirst (in category 'rules') -----
nameFirst
        ^ self apply: #letter!

----- Method: OMeta2RuleParser>>nameRest (in category 'rules') -----
nameRest
        ^ self ometaOr: {[self apply: #nameFirst]. [self apply: #digit]}!

----- Method: OMeta2RuleParser>>nsName (in category 'rules') -----
nsName
        | t1 |
        ^ self ometaOr: {[true
                        ifTrue: [t1 := self apply: #firstAndRest withArgs: {#nameFirst. #nameRest}.
                                (String withAll: t1) asSymbol]]. [true
                        ifTrue: [self apply: #exactly withArgs: {$_}.
                                #anything]]}!

----- Method: OMeta2RuleParser>>numberLiteral (in category 'rules') -----
numberLiteral
        | t1 t2 |
        ^ true
                ifTrue: [self apply: #spaces.
                        t2 := self ometaOr: {[true
                                                        ifTrue: [self apply: #exactly withArgs: {$-}.
                                                                self apply: #spaces.
                                                                -1]]. [true
                                                        ifTrue: [self apply: #empty.
                                                                1]]}.
                        t1 := self
                                                many1: [self apply: #digit].
                        {#App. #exactly. (t2 * (String withAll: t1) asNumber) storeString}]!

----- Method: OMeta2RuleParser>>optIter (in category 'rules-meta') -----
optIter
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #anything.
                        self ometaOr: {[true
                                        ifTrue: [self apply: #token withArgs: {'*'}.
                                                {#Many. t1}]]. [true
                                        ifTrue: [self apply: #token withArgs: {'+'}.
                                                {#Many1. t1}]]. [true
                                        ifTrue: [self apply: #token withArgs: {'?'}.
                                                self
                                                        not: [self apply: #exactly withArgs: {$[}].
                                                {#Opt. t1}]]. [true
                                        ifTrue: [self apply: #empty.
                                                t1]]}]!

----- Method: OMeta2RuleParser>>rule (in category 'rules') -----
rule
        | t1 t3 t4 t5 |
        ^ self ometaOr: {[true
                        ifTrue: [self
                                        not: [true
                                                        ifTrue: [self
                                                                        many: [self
                                                                                        super: OMeta2
                                                                                        apply: #space
                                                                                        withArgs: {}].
                                                                self apply: #nsName.
                                                                self apply: #expr4.
                                                                self apply: #token withArgs: {'='}]].
                                t3 := self
                                                        consumedBy: [self
                                                                        many: [self apply: #char]].
                                {#Squeak. t3}]]. [true
                        ifTrue: [t1 := self
                                                        lookahead: [true
                                                                        ifTrue: [self
                                                                                        many: [self
                                                                                                        super: OMeta2
                                                                                                        apply: #space
                                                                                                        withArgs: {}].
                                                                                self apply: #nsName]].
                                t4 := self apply: #rulePart withArgs: {t1}.
                                t5 := self
                                                        many: [true
                                                                        ifTrue: [self apply: #token withArgs: {','}.
                                                                                self apply: #rulePart withArgs: {t1}]].
                                self apply: #spaces.
                                self apply: #end.
                                {#Rule. t1. temps asSortedCollection. (OrderedCollection with: #Or with: t4) addAll: t5;
                                         yourself}]]}!

----- Method: OMeta2RuleParser>>rulePart (in category 'rules-meta') -----
rulePart
        | t1 t2 t3 t4 |
        ^ true
                ifTrue: [t3 := self apply: #anything.
                        t2 := self apply: #name.
                        self pred: t2 = t3.
                        t1 := self apply: #expr4.
                        self ometaOr: {[true
                                        ifTrue: [self apply: #token withArgs: {'='}.
                                                t4 := self apply: #expr.
                                                {#And. t1. t4}]]. [true
                                        ifTrue: [self apply: #empty.
                                                t1]]}]!

----- Method: OMeta2RuleParser>>semanticAction (in category 'rules') -----
semanticAction
        | t1 |
        ^ true
                ifTrue: [self
                                opt: [self apply: #token withArgs: {'->'}].
                        self apply: #token withArgs: {'['}.
                        t1 := self apply: #squeakExpression.
                        self apply: #exactly withArgs: {$]}.
                        {#Act. t1}]!

----- Method: OMeta2RuleParser>>semanticPredicate (in category 'rules') -----
semanticPredicate
        | t1 |
        ^ true
                ifTrue: [self apply: #token withArgs: {'?['}.
                        t1 := self apply: #squeakExpression.
                        self apply: #exactly withArgs: {$]}.
                        {#Pred. t1}]!

----- Method: OMeta2RuleParser>>space (in category 'rules') -----
space
        ^ self ometaOr: {[self
                        super: OMeta2
                        apply: #space
                        withArgs: {}]. [self apply: #fromTo withArgs: {'/*'. '*/'}]. [self apply: #fromTo withArgs: {'//'. String cr}]}!

----- Method: OMeta2RuleParser>>squeakExpression (in category 'rules') -----
squeakExpression
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #foreign withArgs: {O2SqueakRecognizer. #squeakExpr}.
                        self apply: #spaces.
                        t1]!

----- Method: OMeta2RuleParser>>stringLiteral (in category 'rules') -----
stringLiteral
        | t1 |
        ^ true
                ifTrue: [self apply: #token withArgs: {''''}.
                        t1 := self
                                                many: [self ometaOr: {[true
                                                                        ifTrue: [self apply: #exactly withArgs: {$'}.
                                                                                self apply: #exactly withArgs: {$'}.
                                                                                $']]. [true
                                                                        ifTrue: [self
                                                                                        not: [self apply: #exactly withArgs: {$'}].
                                                                                self apply: #char]]}].
                        self apply: #exactly withArgs: {$'}.
                        {#App. #exactly. (String withAll: t1) storeString}]!

----- Method: OMeta2RuleParser>>symbolLiteral (in category 'rules') -----
symbolLiteral
        | t1 |
        ^ true
                ifTrue: [self apply: #token withArgs: {'#'}.
                        t1 := self apply: #nsName.
                        {#App. #exactly. t1 storeString}]!

----- Method: OMeta2RuleParser>>tokenSugar (in category 'rules') -----
tokenSugar
        | t1 |
        ^ true
                ifTrue: [self apply: #token withArgs: {'"'}.
                        t1 := self
                                                many: [true
                                                                ifTrue: [self
                                                                                not: [self apply: #exactly withArgs: {$"}].
                                                                        self apply: #char]].
                        self apply: #exactly withArgs: {$"}.
                        {#App. #token. (String withAll: t1) storeString}]!

OMeta2 subclass: #OMeta2RuleTranslator
        instanceVariableNames: 'grammarClass'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2RuleTranslator>>act (in category 'rules') -----
act
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #string.
                        {'('. t1. ')'}]!

----- Method: OMeta2RuleTranslator>>and (in category 'rules') -----
and
        | t1 |
        ^ true
                ifTrue: [t1 := self
                                                many: [self apply: #trans].
                        {'(true ifTrue: ['. self delim: t1 with: '. '. '])'}]!

----- Method: OMeta2RuleTranslator>>app (in category 'rules') -----
app
        | t1 t2 |
        ^ true
                ifTrue: [t1 := self apply: #symbol.
                        self ometaOr: {[true
                                        ifTrue: [t2 := self
                                                                        many1: [self apply: #anything].
                                                t2 := self delim: t2 with: '. '.
                                                {'(self apply: '. t1 storeString. ' withArgs: {'. t2. '})'}]]. [{'(self apply: '. t1 storeString. ')'}]}]!

----- Method: OMeta2RuleTranslator>>consby (in category 'rules') -----
consby
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self consumedBy: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>delim:with: (in category 'helpers') -----
delim: aSequenceableCollection  with: anObject

        | first ans |
        first := true.
        ans := OrderedCollection new.
        aSequenceableCollection do: [:x |
                first ifTrue: [first := false] ifFalse: [ans add: anObject].
                ans add: x
        ].
        ^ ans!

----- Method: OMeta2RuleTranslator>>form (in category 'rules') -----
form
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self form: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>idxconsby (in category 'rules') -----
idxconsby
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self indexConsumedBy: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>lookahead (in category 'rules') -----
lookahead
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self lookahead: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>many (in category 'rules') -----
many
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self many: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>many1 (in category 'rules') -----
many1
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self many1: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>not (in category 'rules') -----
not
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self not: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>opt (in category 'rules') -----
opt
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #trans.
                        {'(self opt: ['. t1. '])'}]!

----- Method: OMeta2RuleTranslator>>or (in category 'rules') -----
or
        | t1 t2 |
        ^ true
                ifTrue: [t1 := self
                                                many: [true
                                                                ifTrue: [t2 := self apply: #trans.
                                                                        {'['. t2. ']'}]].
                        {'(self ometaOr: {'. self delim: t1 with: '. '. '})'}]!

----- Method: OMeta2RuleTranslator>>pred (in category 'rules') -----
pred
        | t1 |
        ^ true
                ifTrue: [t1 := self apply: #string.
                        {'(self pred: ('. t1. '))'}]!

----- Method: OMeta2RuleTranslator>>rule (in category 'rules') -----
rule
        | t1 t2 t3 |
        ^ true
                ifTrue: [t2 := self apply: #symbol.
                        t3 := self apply: #anything.
                        t3 := t3
                                                select: [:t4 | (grammarClass instVarNames includes: t4) not].
                        t1 := self apply: #trans.
                        {t2. ' |'. self delim: t3 asSortedCollection with: ' '. ' | ^ '. t1}]!

----- Method: OMeta2RuleTranslator>>set (in category 'rules') -----
set
        | t1 t2 |
        ^ true
                ifTrue: [t1 := self apply: #symbol.
                        t2 := self apply: #trans.
                        {'('. t1 asString. ' := '. t2. ')'}]!

----- Method: OMeta2RuleTranslator>>squeak (in category 'rules') -----
squeak
        ^ self apply: #string!

----- Method: OMeta2RuleTranslator>>superapp (in category 'rules') -----
superapp
        | t1 t2 |
        ^ true
                ifTrue: [t2 := self apply: #symbol.
                        t1 := self
                                                many: [self apply: #anything].
                        t1 := self delim: t1 with: '. '.
                        {'(self super: '. grammarClass superclass name. ' apply: '. t2 storeString. ' withArgs: {'. t1. '})'}]!

----- Method: OMeta2RuleTranslator>>trans (in category 'rules') -----
trans
        | t1 t3 |
        ^ true
                ifTrue: [self
                                form: [true
                                                ifTrue: [t3 := self apply: #symbol.
                                                        t1 := self apply: #apply withArgs: {t3 asLowercase asSymbol}]].
                        t1]!

----- Method: OMeta2RuleTranslator>>translate (in category 'rules') -----
translate
        ^ true
                ifTrue: [grammarClass := self apply: #anything.
                        self apply: #trans]!

----- Method: OMeta2Base class>>compilerClass (in category 'as yet unclassified') -----
compilerClass

        ^ OMeta2Compiler!

----- Method: OMeta2Base class>>debugMatch:with: (in category 'as yet unclassified') -----
debugMatch: anObject with: aRule

        ^ self debugMatch: anObject with: aRule withArgs: #()!

----- Method: OMeta2Base class>>debugMatch:with:withArgs: (in category 'as yet unclassified') -----
debugMatch: anObject with: aRule withArgs: args

        ^ self debugMatchAll: {anObject} readStream with: aRule withArgs: args!

----- Method: OMeta2Base class>>debugMatchAll:with: (in category 'as yet unclassified') -----
debugMatchAll: aSequenceableCollection with: aRule

        ^ self debugMatchAll: aSequenceableCollection with: aRule withArgs: #()!

----- Method: OMeta2Base class>>debugMatchAll:with:withArgs: (in category 'as yet unclassified') -----
debugMatchAll: aSequenceableCollection with: aRule withArgs: args

        ^ self matchStream: aSequenceableCollection readStream with: aRule withArgs: args withPlaybackDebugging: true!

----- Method: OMeta2Base class>>match:with: (in category 'as yet unclassified') -----
match: anObject with: aRule

        ^ self match: anObject with: aRule withArgs: #()!

----- Method: OMeta2Base class>>match:with:withArgs: (in category 'as yet unclassified') -----
match: anObject with: aRule withArgs: args

        ^ self matchAll: {anObject} readStream with: aRule withArgs: args!

----- Method: OMeta2Base class>>matchAll:with: (in category 'as yet unclassified') -----
matchAll: aSequenceableCollection with: aRule

        ^ self matchAll: aSequenceableCollection with: aRule withArgs: #()!

----- Method: OMeta2Base class>>matchAll:with:withArgs: (in category 'as yet unclassified') -----
matchAll: aSequenceableCollection with: aRule withArgs: args

        ^ self matchStream: aSequenceableCollection readStream with: aRule withArgs: args withPlaybackDebugging: false!

----- Method: OMeta2Base class>>matchStream:with:withArgs:withPlaybackDebugging: (in category 'as yet unclassified') -----
matchStream: aReadStream with: aRule withArgs: args withPlaybackDebugging: debugging

        | input matcher ans|
        input := OM2LazyStream for: aReadStream withPos: 1.
        matcher := self new initInput: input.
        [
                matcher apply: #empty withArgs: args.
                ans := matcher apply: aRule.
                matcher apply: #end.
                ^ ans
        ] on: OM2Fail do: [:e |
                | curr prev prevPrev |
                debugging ifFalse: [e signal].
                curr := input.
                prev := nil.
                prevPrev := nil.
                [curr notNil] whileTrue: [
                        prevPrev := prev.
                        prev := curr.
                        curr := curr basicTail
                ].
                curr := prevPrev ifNotNil: [prevPrev] ifNil: [prev].
                self inform: 'will halt each time matcher reaches ', curr printString.
                matcher
                        initInput: input;
                        forgetEverything.
                curr ifNil: [self error: 'you''ve found a bug -- please tell Alex'].
                curr become: (OM2StreamDebugger for: curr copy).
                matcher haltingPoint: curr.
                matcher apply: #empty withArgs: args.
                ans := matcher apply: aRule.
                matcher apply: #end.
                ^ ans
        ]!

----- Method: OMeta2Base class>>matcherOn: (in category 'as yet unclassified') -----
matcherOn: aReadStream

        | input matcher |
        input := OM2LazyStream for: aReadStream withPos: 1.
        matcher := self new initInput: input.
        ^ matcher!

----- Method: OMeta2Base>>anything (in category 'rules-basic') -----
anything

        | ans |
        ans := input head.
        input := input tail.
        ^ ans!

----- Method: OMeta2Base>>apply (in category 'rules-basic') -----
apply

        | aRule |
        aRule := self apply: #anything.
        ^ self apply: aRule!

----- Method: OMeta2Base>>apply: (in category 'rule application') -----
apply: aRule

        " A memoRec is an association whose key is the answer,
          and whose value is the next input. Failers pretend to
     be memoRecs, but throw a fail in response to #value "
        | memo memoRec |
        input == haltingPoint ifTrue: [self halt].
        memo := input memo.
        memoRec := memo at: aRule ifAbsent: [nil].
        memoRec ifNil: [
                | origInput failer ans |
                origInput := input.
                failer := OM2Failer new.
                memo at: aRule put: failer.
                ans := self perform: aRule.
                memoRec := ans -> input.
                memo at: aRule put: memoRec.
                failer used ifTrue: [
                        " left recursion detected "
                        | sentinel keepGoing |
                        sentinel := input.
                        keepGoing := true.
                        [keepGoing] whileTrue: [
                                [
                                        input := origInput.
                                        ans := self perform: aRule.
                                        input == sentinel ifTrue: [OMeta2Fail signal].
                                        memoRec key: ans value: input.
                                ] on: OM2Fail do: [keepGoing := false]
                        ]
                ]
        ].
        input := memoRec value.
        ^ memoRec key!

----- Method: OMeta2Base>>apply:withArgs: (in category 'rule application') -----
apply: aRule withArgs: args

        args reverseDo: [:a | input := OM2Stream new initHead: a tail: input].
        ^ self perform: aRule!

----- Method: OMeta2Base>>consumedBy: (in category 'private') -----
consumedBy: aBlock

        | origInput i ws |
        origInput := input.
        aBlock value.
        ws := WriteStream on: origInput inputSpecies new.
        i := origInput.
        [i == input] whileFalse: [
                ws nextPut: i head.
                i := i tail
        ].
        ^ ws contents!

----- Method: OMeta2Base>>empty (in category 'rules-basic') -----
empty

        ^ true!

----- Method: OMeta2Base>>firstAndRest (in category 'rules-basic') -----
firstAndRest

        | first rest |
        first := self apply: #anything.
        rest := self apply: #anything.
        ^ self genericMany: [self apply: rest] into: (OrderedCollection with: (self apply: first))!

----- Method: OMeta2Base>>foreign (in category 'rules-basic') -----
foreign

        | aGrammar aRule g ans |
        aGrammar := self apply: #anything.
        aRule := self apply: #anything.
        g := aGrammar new initInput: (OM2StreamProxy for: input).
        ans := g apply: aRule.
        input := g input target.
        ^ ans!

----- Method: OMeta2Base>>forgetEverything (in category 'forgetting') -----
forgetEverything

        input transitiveForgetEverything.
        om2streams valuesDo: [:s | s transitiveForgetEverything]!

----- Method: OMeta2Base>>form: (in category 'rules-basic') -----
form: aBlock

        | v origInput |
        v := self apply: #anything.
        self pred: (v isCollection and: [v isSequenceable and: [v isSymbol not]]).
        origInput := input.
        input := om2streams at: v ifAbsentPut: [OM2LazyStream for: v readStream withPos: 1].
        aBlock value.
        self apply: #end.
        input := origInput.
        ^ v!

----- Method: OMeta2Base>>genericMany:into: (in category 'private') -----
genericMany: aBlock into: anOrderedCollection

        [
                | origInput |
                origInput := input.
                [anOrderedCollection addLast: aBlock value] on: OM2Fail do: [
                        input := origInput.
                        ^ anOrderedCollection
                ].
                true
        ] whileTrue!

----- Method: OMeta2Base>>haltingPoint: (in category 'initialize-release') -----
haltingPoint: anOM2Stream

        haltingPoint := anOM2Stream!

----- Method: OMeta2Base>>indexConsumedBy: (in category 'private') -----
indexConsumedBy: aBlock

        | from to |
        from := self pos.
        aBlock value.
        to := self pos.
        ^ from -> to!

----- Method: OMeta2Base>>initInput: (in category 'initialize-release') -----
initInput: i

        input := i!

----- Method: OMeta2Base>>initialize (in category 'initialize-release') -----
initialize

        super initialize.
        om2streams := IdentityDictionary new!

----- Method: OMeta2Base>>input (in category 'rules-basic') -----
input

        ^ input!

----- Method: OMeta2Base>>lookahead: (in category 'private') -----
lookahead: aBlock

        | origInput ans |
        origInput := input.
        ans := aBlock value.
        input := origInput.
        ^ ans!

----- Method: OMeta2Base>>many1: (in category 'private') -----
many1: aBlock

        ^ self genericMany: aBlock into: (OrderedCollection with: aBlock value)!

----- Method: OMeta2Base>>many: (in category 'private') -----
many: aBlock

        ^ self genericMany: aBlock into: OrderedCollection new!

----- Method: OMeta2Base>>not: (in category 'private') -----
not: aBlock

        | origInput |
        origInput := input.
        [aBlock value] on: OM2Fail do: [
                input := origInput.
                ^ true
        ].
        OMeta2Fail signal!

----- Method: OMeta2Base>>ometaOr: (in category 'private') -----
ometaOr: choices

        | origInput |
        origInput := input.
        choices do: [:choice |
                input := origInput.
                [^ choice value] on: OM2Fail do: []
        ].
        OMeta2Fail signal!

----- Method: OMeta2Base>>opt: (in category 'private') -----
opt: aBlock

        ^ self ometaOr: {
                [aBlock value].
                [nil]
        }!

----- Method: OMeta2Base>>pos (in category 'rules-basic') -----
pos

        ^ input pos!

----- Method: OMeta2Base>>pred: (in category 'private') -----
pred: aBooleanValue

        " may want to have the compiler inline this automatically, for performance "
        aBooleanValue ifTrue: [^ true].
        OMeta2Fail signal!

----- Method: OMeta2Base>>seq (in category 'rules-basic') -----
seq

        | xs |
        xs := self apply: #anything.
        xs do: [:x |
                " may want to inline #apply:withArgs: below as an
                  optimization, since this rule gets used a lot "
                self apply: #exactly withArgs: {x}
        ].
        ^ xs
        !

----- Method: OMeta2Base>>super:apply:withArgs: (in category 'rule application') -----
super: superclass apply: aRule withArgs: args

        args reverseDo: [:a | input := OM2Stream new initHead: a tail: input].
        ^ self perform: aRule withArguments: #() inSuperclass: superclass!

MethodNode subclass: #OMeta2MethodNode
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'OMeta2'!

----- Method: OMeta2MethodNode>>schematicTempNamesString (in category 'debugger support') -----
schematicTempNamesString
        "The decompiler wants a list of temp names. However, this mechanism depends on a number of assumptions that do not hold with OMeta2 generated methods. Therefore we simply skip the temp names, letting the decompiler build generic ones."
        ^nil!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Yoshiki Ohshima-3
Hmm, ok.  This diff has more code than it should have, but I patched
OMeta2 package to make it work in the new compiler regime in Squeak
4.5.  Hans-Martin, do you think you can take this, and update the
config map (if necessary)?

On Thu, Jul 31, 2014 at 1:31 PM,  <[hidden email]> wrote:

> A new version of OMeta2-Preload was added to project The Inbox:
> http://source.squeak.org/inbox/OMeta2-Preload-yo.15.mcz
>
> ==================== Summary ====================
>
> Name: OMeta2-Preload-yo.15
> Author: yo
> Time: 31 July 2014, 1:29:01.319 pm
> UUID: 6c6bc75e-3c9f-4446-b08a-cdce7081ef2d
> Ancestors: OMeta2-Preload-hmm.14
>
> Adapt to Squeak 4.5.
>
> ==================== Snapshot ====================
>
> SystemOrganization addCategory: #OMeta2!
> SystemOrganization addCategory: #'OMeta2-Info'!
>
> ----- Method: CompiledMethod>>methodNode (in category '*OMeta2-Preload') -----
> methodNode
>         "Return the parse tree that represents self. If parsing fails, decompile the method."
>         | aClass source |
>         aClass := self methodClass.
>         source := self
>                                 getSourceFor: (self selector ifNil: [self defaultSelector])
>                                 in: aClass.
>         ^[(aClass parserClass new
>                 encoderClass: (self isBlueBookCompiled
>                                                 ifTrue: [EncoderForV3]
>                                                 ifFalse: [EncoderForV3PlusClosures]);
>                 parse: source class: aClass)
>                         sourceText: source;
>                         yourself]
>                 on: SyntaxErrorNotification
>                 do: [:ex | ex return: self decompile].!
>
> Exception subclass: #OM2Fail
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2Fail class>>initialize (in category 'class initialization') -----
> initialize
>         (Smalltalk at: #OMeta2Fail ifAbsent: []) class == self
>                 ifFalse: [Smalltalk at: #OMeta2Fail put: self new]!
>
> ----- Method: OM2Fail>>defaultAction (in category 'priv handling') -----
> defaultAction
>
>         self error: 'match failed'!
>
> MethodReference subclass: #OM2DecompilingMethodReference
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2-Info'!
>
> !OM2DecompilingMethodReference commentStamp: 'hmm 5/24/2010 13:15' prior: 0!
> This class is a helper to OM2PreloadPackagingInfo which is used to save OMeta2 productions in their decompiled form.!
>
> ----- Method: OM2DecompilingMethodReference>>source (in category 'queries') -----
> source
>         ^self compiledMethod decompileString!
>
> Compiler subclass: #OMeta2Compiler
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2Compiler>>compile:in:notifying:ifFail: (in category 'as yet unclassified') -----
> compile: origCode in: cls notifying: notify ifFail: failBlock
>
>         | origCodeStream parseTree structuredCode translatedCode |
>         origCodeStream := origCode asString readStream.
>         [
>                 parseTree := OMeta2RuleParser matchStream: origCodeStream with: #rule withArgs: #() withPlaybackDebugging: false.
>                 parseTree := OMeta2Optimizer match: parseTree with: #optimizeRule.
>                 structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {cls}.
>                 translatedCode := OMeta2Flattener match: structuredCode with: #flatten
>         ] on: OM2Fail do: [
>                 self notify: '<-- parse error around here -->' at: origCodeStream position.
>                 ^ failBlock value
>         ].
>         ^ super compile: translatedCode in: cls notifying: notify ifFail: failBlock.
> !
>
> ----- Method: OMeta2Compiler>>parse:class:noPattern:context:notifying:ifFail: (in category 'as yet unclassified') -----
> parse: aStream class: aClass noPattern: noPattern context: ctxt notifying: req ifFail: aBlock
>         | node |
>         ^ [
>                 | parseTree structuredCode code |
>                 parseTree := OMeta2RuleParser matchAll: aStream contents with: #rule.
>                 structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {aClass}.
>                 code := OMeta2Flattener match: structuredCode with: #flatten.
>                 node := Parser new parse: code readStream class: aClass noPattern: noPattern context: ctxt notifying: req ifFail: aBlock.
>                 OMeta2MethodNode adoptInstance: node.
>                 node
>         ] on: OM2Fail do: [aBlock value]!
>
> ----- Method: OMeta2Compiler>>parse:in:notifying: (in category 'as yet unclassified') -----
> parse: origCode in: aClass notifying: req
>         | c parseTree structuredCode translatedCode origCodeStream |
>         origCodeStream := origCode asString readStream.
>
>         parseTree := OMeta2RuleParser matchStream: origCodeStream with: #rule withArgs: #() withPlaybackDebugging: false.
>         parseTree := OMeta2Optimizer match: parseTree with: #optimizeRule.
>         structuredCode := OMeta2RuleTranslator match: parseTree with: #translate withArgs: {aClass}.
>         translatedCode := OMeta2Flattener match: structuredCode with: #flatten.
>
>         c := CompilationCue
>                         source: translatedCode
>                         class: aClass
>                         requestor: req.
>         ^ self
>                 parseCue: c
>                 noPattern: false
>                 ifFail: nil!
>
> ----- Method: OMeta2Compiler>>parseCue:noPattern:ifFail: (in category 'as yet unclassified') -----
> parseCue: aCue noPattern: noPattern ifFail: aBlock
>         ^ Parser new parseCue: aCue noPattern: noPattern ifFail: aBlock
> !
>
> ----- Method: OMeta2Compiler>>parser (in category 'as yet unclassified') -----
> parser
>         ^ self parserClass new!
>
> ----- Method: OMeta2Compiler>>parserClass (in category 'as yet unclassified') -----
> parserClass
>
>         ^ self class!
>
> PackageInfo subclass: #OM2PostloadPackageInfo
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2-Info'!
>
> !OM2PostloadPackageInfo commentStamp: 'hmm 4/16/2010 17:09' prior: 0!
> This class stores all OMeta2 production rules in their original format.!
>
> ----- Method: OM2PostloadPackageInfo class>>initialize (in category 'class initialization') -----
> initialize
>         self new register!
>
> ----- Method: OM2PostloadPackageInfo>>classes (in category 'listing') -----
> classes
>         ^super classes select: [:each | each inheritsFrom: OMeta2Base]!
>
> ----- Method: OM2PostloadPackageInfo>>coreMethodsForClass: (in category 'testing') -----
> coreMethodsForClass: aClass
>         MCMethodDefinition shutDown.    "flush cache so pre- and postload don't interfere"
>         ^(super coreMethodsForClass: aClass) select: [:each | OMeta2RuleParser isOMeta2Rule: each source]!
>
> ----- Method: OM2PostloadPackageInfo>>extensionMethodsForClass: (in category 'testing') -----
> extensionMethodsForClass: aClass
>         ^#()!
>
> ----- Method: OM2PostloadPackageInfo>>packageName (in category 'naming') -----
> packageName
>         ^super packageName, '-Postload'!
>
> ----- Method: OM2PostloadPackageInfo>>systemCategoryPrefix (in category 'naming') -----
> systemCategoryPrefix
>         ^super packageName!
>
> PackageInfo subclass: #OM2PreloadPackageInfo
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2-Info'!
>
> !OM2PreloadPackageInfo commentStamp: 'hmm 4/16/2010 17:08' prior: 0!
> This class makes it possible to store OMeta2 using decompiled production rules, so that it can be loaded without being present first.
> It uses OM2DecompilingMethodReference to decompile OMeta2 rules on the fly while creating a source file.!
>
> ----- Method: OM2PreloadPackageInfo class>>initialize (in category 'class initialization') -----
> initialize
>         self new register!
>
> ----- Method: OM2PreloadPackageInfo>>packageName (in category 'naming') -----
> packageName
>         ^super packageName, '-Preload'!
>
> ----- Method: OM2PreloadPackageInfo>>referenceForMethod:ofClass: (in category 'listing') -----
> referenceForMethod: aSymbol ofClass: aClass
>         MCMethodDefinition shutDown.    "flush cache so pre- and postload don't interfere"
>         ^((OMeta2RuleParser isOMeta2Rule: (aClass sourceCodeAt: aSymbol))
>                 ifTrue: [OM2DecompilingMethodReference]
>                 ifFalse: [MethodReference]) new setStandardClass: aClass methodSymbol: aSymbol!
>
> ----- Method: OM2PreloadPackageInfo>>systemCategoryPrefix (in category 'naming') -----
> systemCategoryPrefix
>         ^super packageName!
>
> Object subclass: #OM2Failer
>         instanceVariableNames: 'used'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2Failer>>initialize (in category 'initialize-release') -----
> initialize
>
>         used := false!
>
> ----- Method: OM2Failer>>used (in category 'testing') -----
> used
>
>         ^ used!
>
> ----- Method: OM2Failer>>value (in category 'evaluating') -----
> value
>
>         used := true.
>         OMeta2Fail signal!
>
> Object subclass: #OM2Stream
>         instanceVariableNames: 'head tail memo'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> OM2Stream subclass: #OM2EndOfStream
>         instanceVariableNames: 'stream pos'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2EndOfStream>>head (in category 'accessing') -----
> head
>
>         OMeta2Fail signal!
>
> ----- Method: OM2EndOfStream>>initStream:pos: (in category 'initialize-release') -----
> initStream: s pos: p
>
>         stream := s.
>         pos := p!
>
> ----- Method: OM2EndOfStream>>inputSpecies (in category 'accessing') -----
> inputSpecies
>
>         ^ stream originalContents species!
>
> ----- Method: OM2EndOfStream>>pos (in category 'accessing') -----
> pos
>
>         ^ pos!
>
> ----- Method: OM2EndOfStream>>tail (in category 'accessing') -----
> tail
>
>         OMeta2Fail signal!
>
> OM2Stream subclass: #OM2LazyStream
>         instanceVariableNames: 'stream pos'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2LazyStream class>>for:withPos: (in category 'as yet unclassified') -----
> for: aReadStream withPos: pos
>
>         ^ aReadStream atEnd
>                 ifTrue: [OM2EndOfStream new initStream: aReadStream pos: pos]
>                 ifFalse: [self new initHead: aReadStream next stream: aReadStream pos: pos]!
>
> ----- Method: OM2LazyStream>>initHead:stream:pos: (in category 'initialize-release') -----
> initHead: h stream: s pos: p
>
>         head := h.
>         stream := s.
>         pos := p!
>
> ----- Method: OM2LazyStream>>inputSpecies (in category 'accessing') -----
> inputSpecies
>
>         ^ stream originalContents species!
>
> ----- Method: OM2LazyStream>>pos (in category 'accessing') -----
> pos
>
>         ^ pos!
>
> ----- Method: OM2LazyStream>>tail (in category 'accessing') -----
> tail
>
>         tail ifNil: [tail := OM2LazyStream for: stream withPos: pos + 1].
>         ^ tail!
>
> ----- Method: OM2Stream>>basicTail (in category 'accessing') -----
> basicTail
>
>         ^ tail!
>
> ----- Method: OM2Stream>>forgetEverything (in category 'forgetting') -----
> forgetEverything
>
>         memo := IdentityDictionary new!
>
> ----- Method: OM2Stream>>head (in category 'accessing') -----
> head
>
>         ^ head!
>
> ----- Method: OM2Stream>>initHead:tail: (in category 'initialize-release') -----
> initHead: h tail: t
>
>         head := h.
>         tail := t!
>
> ----- Method: OM2Stream>>initialize (in category 'initialize-release') -----
> initialize
>
>         memo := IdentityDictionary new!
>
> ----- Method: OM2Stream>>inputSpecies (in category 'accessing') -----
> inputSpecies
>
>         ^ Array!
>
> ----- Method: OM2Stream>>memo (in category 'accessing') -----
> memo
>
>         ^ memo!
>
> ----- Method: OM2Stream>>pos (in category 'accessing') -----
> pos
>
>         ^ -1!
>
> ----- Method: OM2Stream>>printOn: (in category 'printing') -----
> printOn: aStream
>
>         | inputIsString curr |
>         inputIsString := (self inputSpecies inheritsFrom: String) and: [(self inputSpecies inheritsFrom: Symbol) not].
>         curr := self.
>         aStream
>                 nextPutAll: 'an ';
>                 nextPutAll: self class name;
>                 nextPut: $(.
>         [curr notNil] whileTrue: [
>                 (curr isKindOf: OM2EndOfStream) ifTrue: [
>                         aStream nextPut: $).
>                         ^ self
>                 ].
>                 inputIsString
>                         ifTrue: [aStream nextPut: curr head]
>                         ifFalse: [
>                                 curr head printOn: aStream.
>                                 aStream space
>                         ].
>                 curr := curr basicTail.
>         ].
>         aStream nextPutAll: '...)'!
>
> ----- Method: OM2Stream>>tail (in category 'accessing') -----
> tail
>
>         ^ tail!
>
> ----- Method: OM2Stream>>transitiveForgetEverything (in category 'forgetting') -----
> transitiveForgetEverything
>
>         | curr |
>         curr := self.
>         [curr notNil] whileTrue: [
>                 curr forgetEverything.
>                 curr := curr basicTail
>         ]!
>
> OM2Stream subclass: #OM2StreamDebugger
>         instanceVariableNames: 'om2stream'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2StreamDebugger class>>for: (in category 'as yet unclassified') -----
> for: anOM2Stream
>
>         ^ self new initOm2stream: anOM2Stream!
>
> ----- Method: OM2StreamDebugger>>forgetEverything (in category 'forgetting') -----
> forgetEverything
>
>         om2stream forgetEverything!
>
> ----- Method: OM2StreamDebugger>>head (in category 'accessing') -----
> head
>
>         ^ om2stream head!
>
> ----- Method: OM2StreamDebugger>>initOm2stream: (in category 'initialize-release') -----
> initOm2stream: anOM2Stream
>
>         om2stream := anOM2Stream!
>
> ----- Method: OM2StreamDebugger>>memo (in category 'accessing') -----
> memo
>
>         ^ om2stream memo!
>
> ----- Method: OM2StreamDebugger>>printOn: (in category 'printing') -----
> printOn: aStream
>
>         aStream nextPutAll: 'an OM2StreamDebugger('.
>         om2stream printOn: aStream.
>         aStream nextPut: $)!
>
> ----- Method: OM2StreamDebugger>>tail (in category 'accessing') -----
> tail
>
>         ^ om2stream tail!
>
> ----- Method: OM2StreamDebugger>>transitiveForgetEverything (in category 'forgetting') -----
> transitiveForgetEverything
>
>         om2stream transitiveForgetEverything!
>
> OM2Stream subclass: #OM2StreamProxy
>         instanceVariableNames: 'target'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OM2StreamProxy class>>for: (in category 'as yet unclassified') -----
> for: anOM2Stream
>
>         ^ self new initTarget: anOM2Stream!
>
> ----- Method: OM2StreamProxy>>basicTail (in category 'accessing') -----
> basicTail
>
>         ^ target basicTail!
>
> ----- Method: OM2StreamProxy>>head (in category 'accessing') -----
> head
>
>         head ifNil: [head := target head].
>         ^ head
> !
>
> ----- Method: OM2StreamProxy>>initTarget: (in category 'initialize-release') -----
> initTarget: anOM2Stream
>
>         target := anOM2Stream!
>
> ----- Method: OM2StreamProxy>>inputSpecies (in category 'accessing') -----
> inputSpecies
>
>         ^ target inputSpecies!
>
> ----- Method: OM2StreamProxy>>pos (in category 'accessing') -----
> pos
>
>         ^ target pos!
>
> ----- Method: OM2StreamProxy>>tail (in category 'accessing') -----
> tail
>
>         tail ifNil: [tail := OM2StreamProxy for: target tail].
>         ^ tail!
>
> ----- Method: OM2StreamProxy>>target (in category 'accessing') -----
> target
>
>         ^ target!
>
> Object subclass: #OMeta2Base
>         instanceVariableNames: 'input om2streams haltingPoint'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> OMeta2Base subclass: #OMeta2
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> !OMeta2 commentStamp: '<historical>' prior: 0!
> TODOS:
>
> * implement OMeta -> Squeak translator
> * implement Squeak parser
> * implement OMeta/Squeak "compiler", make it OMeta2's compilerClass
>
> * rewrite #char, #digit, #empty, #end, #exactly, #firstAndRest, #fromTo, #letter, #letterOrDigit, #listOf, #lower, #notLast, #number, #range, #space, #spaces, #string, #symbol, #token, and #upper in OMeta syntax
> * consider implementing position-related functionality (see http://www.tinlizzie.org/ometa-js/ometa-base.js)
> * consider the optimization suggestions in the comments of OMeta2Lib's methods!
>
> OMeta2 subclass: #O2SqueakRecognizer
>         instanceVariableNames: ''
>         classVariableNames: 'TypeTable'
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: O2SqueakRecognizer class>>initialize (in category 'as yet unclassified') -----
> initialize
>
>         TypeTable := #(#xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xDelimiter #xDelimiter #xBinary #xDelimiter #xDelimiter #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #doIt #xBinary #xDelimiter #xBinary #xDoubleQuote #xLitQuote #xDollar #xBinary #xBinary #xSingleQuote #leftParenthesis #rightParenthesis #xBinary #xBinary #xBinary #xBinary #period #xBinary #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xDigit #xColon #semicolon #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #leftBracket #xBinary #rightBracket #upArrow #leftArrow #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLe
>  tter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #leftBrace #verticalBar #rightBrace #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xLetter #xBinary #xBinary #xBinary #xBinary #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #x
>  Binary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xBinary #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xLetter #xBinary)!
>
> ----- Method: O2SqueakRecognizer>>arrayConstr (in category 'rules-parsing') -----
> arrayConstr
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #token withArgs: {'{'}.
>                                 self apply: #expr.
>                                 self
>                                         many: [true
>                                                         ifTrue: [self apply: #token withArgs: {'.'}.
>                                                                 self apply: #expr]].
>                                 self ometaOr: {[self apply: #token withArgs: {'.'}]. [self apply: #empty]}.
>                                 self apply: #token withArgs: {'}'}]]. [true
>                         ifTrue: [self apply: #token withArgs: {'{'}.
>                                 self apply: #token withArgs: {'}'}]]}!
>
> ----- Method: O2SqueakRecognizer>>arrayLit (in category 'rules-parsing') -----
> arrayLit
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'#'}.
>                         self apply: #token withArgs: {'('}.
>                         self
>                                 many: [self ometaOr: {[self apply: #literal]. [self apply: #arrayLit]. [true
>                                                         ifTrue: [self apply: #spaces.
>                                                                 self apply: #tsArraySymbol]]}].
>                         self apply: #token withArgs: {')'}]!
>
> ----- Method: O2SqueakRecognizer>>binary (in category 'rules-parsing') -----
> binary
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self apply: #tsBinary]!
>
> ----- Method: O2SqueakRecognizer>>binaryExpr (in category 'rules-parsing') -----
> binaryExpr
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #binaryExpr.
>                                 self apply: #binaryMsg]]. [self apply: #unaryExpr]}!
>
> ----- Method: O2SqueakRecognizer>>binaryMsg (in category 'rules-parsing') -----
> binaryMsg
>         ^ true
>                 ifTrue: [self apply: #binary.
>                         self apply: #unaryExpr]!
>
> ----- Method: O2SqueakRecognizer>>block (in category 'rules-parsing') -----
> block
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'['}.
>                         self ometaOr: {[true
>                                         ifTrue: [self
>                                                         many1: [true
>                                                                         ifTrue: [self apply: #token withArgs: {':'}.
>                                                                                 self apply: #identifier]].
>                                                 self apply: #token withArgs: {'|'}]]. [self apply: #empty]}.
>                         self ometaOr: {[true
>                                         ifTrue: [self apply: #token withArgs: {'|'}.
>                                                 self
>                                                         many: [self apply: #identifier].
>                                                 self apply: #token withArgs: {'|'}]]. [self apply: #empty]}.
>                         self ometaOr: {[true
>                                         ifTrue: [self apply: #expr.
>                                                 self
>                                                         many: [true
>                                                                         ifTrue: [self apply: #token withArgs: {'.'}.
>                                                                                 self apply: #expr]].
>                                                 self ometaOr: {[true
>                                                                 ifTrue: [self apply: #token withArgs: {'.'}.
>                                                                         self apply: #token withArgs: {'^'}.
>                                                                         self apply: #expr]]. [self apply: #empty]}]]. [true
>                                         ifTrue: [self apply: #token withArgs: {'^'}.
>                                                 self apply: #expr]]. [self apply: #empty]}.
>                         self ometaOr: {[self apply: #token withArgs: {'.'}]. [self apply: #empty]}.
>                         self apply: #token withArgs: {']'}]!
>
> ----- Method: O2SqueakRecognizer>>cascade (in category 'rules-parsing') -----
> cascade
>         ^ self ometaOr: {[self apply: #identifier]. [self apply: #binaryMsg]. [self apply: #keywordMsg]}!
>
> ----- Method: O2SqueakRecognizer>>expr (in category 'rules-parsing') -----
> expr
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #identifier.
>                                 self ometaOr: {[self apply: #token withArgs: {':='}]. [self apply: #token withArgs: {'_'}]}.
>                                 self apply: #expr]]. [self apply: #msgExpr]}!
>
> ----- Method: O2SqueakRecognizer>>identifier (in category 'rules-parsing') -----
> identifier
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self apply: #tsIdentifier.
>                         self
>                                 not: [self apply: #exactly withArgs: {$:}]]!
>
> ----- Method: O2SqueakRecognizer>>keyword (in category 'rules-parsing') -----
> keyword
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self apply: #tsKeyword]!
>
> ----- Method: O2SqueakRecognizer>>keywordExpr (in category 'rules-parsing') -----
> keywordExpr
>         ^ true
>                 ifTrue: [self apply: #binaryExpr.
>                         self apply: #keywordMsg]!
>
> ----- Method: O2SqueakRecognizer>>keywordMsg (in category 'rules-parsing') -----
> keywordMsg
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #keywordMsg.
>                                 self apply: #keywordMsgPart]]. [self apply: #keywordMsgPart]}!
>
> ----- Method: O2SqueakRecognizer>>keywordMsgPart (in category 'rules-parsing') -----
> keywordMsgPart
>         ^ true
>                 ifTrue: [self apply: #keyword.
>                         self apply: #binaryExpr]!
>
> ----- Method: O2SqueakRecognizer>>literal (in category 'rules-parsing') -----
> literal
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self ometaOr: {[self apply: #tsNumber]. [self apply: #tsCharacter]. [self apply: #tsString]. [self apply: #tsSymbol]}]!
>
> ----- Method: O2SqueakRecognizer>>msgExpr (in category 'rules-parsing') -----
> msgExpr
>         ^ true
>                 ifTrue: [self ometaOr: {[self apply: #keywordExpr]. [self apply: #binaryExpr]}.
>                         self
>                                 many: [true
>                                                 ifTrue: [self apply: #token withArgs: {';'}.
>                                                         self apply: #cascade]]]!
>
> ----- Method: O2SqueakRecognizer>>squeakExpr (in category 'rules-parsing') -----
> squeakExpr
>         ^ self
>                 consumedBy: [self apply: #expr]!
>
> ----- Method: O2SqueakRecognizer>>symbol (in category 'rules-parsing') -----
> symbol
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'#'}.
>                         self apply: #spaces.
>                         self ometaOr: {[self apply: #tsString]. [true
>                                         ifTrue: [self apply: #tsKeyword.
>                                                 self ometaOr: {[self apply: #tsIdentifier]. [self apply: #empty]}]]}]!
>
> ----- Method: O2SqueakRecognizer>>tcBinaryChar (in category 'rules-lexing') -----
> tcBinaryChar
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: (TypeTable at: t1 asciiValue)
>                                         == #xBinary]!
>
> ----- Method: O2SqueakRecognizer>>tsArraySymbol (in category 'rules-lexing') -----
> tsArraySymbol
>         ^ self ometaOr: {[true
>                         ifTrue: [self
>                                         many1: [self apply: #tsKeyword].
>                                 self ometaOr: {[self apply: #tsIdentifier]. [self apply: #empty]}]]. [self apply: #tsIdentifier]}!
>
> ----- Method: O2SqueakRecognizer>>tsBinary (in category 'rules-lexing') -----
> tsBinary
>         ^ true
>                 ifTrue: [self ometaOr: {[self apply: #exactly withArgs: {$|}]. [self apply: #tcBinaryChar]}.
>                         self
>                                 many: [self apply: #tcBinaryChar]]!
>
> ----- Method: O2SqueakRecognizer>>tsCharacter (in category 'rules-lexing') -----
> tsCharacter
>         ^ true
>                 ifTrue: [self apply: #exactly withArgs: {$$}.
>                         self apply: #char]!
>
> ----- Method: O2SqueakRecognizer>>tsIdentifier (in category 'rules-lexing') -----
> tsIdentifier
>         ^ true
>                 ifTrue: [self apply: #letter.
>                         self
>                                 many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]!
>
> ----- Method: O2SqueakRecognizer>>tsKeyword (in category 'rules-lexing') -----
> tsKeyword
>         ^ true
>                 ifTrue: [self apply: #tsIdentifier.
>                         self apply: #exactly withArgs: {$:}]!
>
> ----- Method: O2SqueakRecognizer>>tsNatural (in category 'rules-lexing') -----
> tsNatural
>         ^ self
>                 many1: [self apply: #digit]!
>
> ----- Method: O2SqueakRecognizer>>tsNumber (in category 'rules-lexing') -----
> tsNumber
>         ^ true
>                 ifTrue: [self ometaOr: {[self apply: #exactly withArgs: {$+}]. [self apply: #exactly withArgs: {$-}]. [self apply: #empty]}.
>                         self apply: #tsNatural]!
>
> ----- Method: O2SqueakRecognizer>>tsString (in category 'rules-lexing') -----
> tsString
>         ^ true
>                 ifTrue: [self apply: #exactly withArgs: {$'}.
>                         self
>                                 many: [self ometaOr: {[true
>                                                         ifTrue: [self apply: #exactly withArgs: {$'}.
>                                                                 self apply: #exactly withArgs: {$'}]]. [true
>                                                         ifTrue: [self
>                                                                         not: [self apply: #exactly withArgs: {$'}].
>                                                                 self apply: #char]]}].
>                         self apply: #exactly withArgs: {$'}]!
>
> ----- Method: O2SqueakRecognizer>>tsSymbol (in category 'rules-lexing') -----
> tsSymbol
>         ^ true
>                 ifTrue: [self apply: #exactly withArgs: {$#}.
>                         self apply: #spaces.
>                         self ometaOr: {[self apply: #tsString]. [self apply: #tsArraySymbol]}]!
>
> ----- Method: O2SqueakRecognizer>>unaryExpr (in category 'rules-parsing') -----
> unaryExpr
>         ^ true
>                 ifTrue: [self apply: #unit.
>                         self
>                                 many: [self apply: #identifier]]!
>
> ----- Method: O2SqueakRecognizer>>unit (in category 'rules-parsing') -----
> unit
>         ^ self ometaOr: {[self apply: #literal]. [self apply: #identifier]. [self apply: #arrayLit]. [self apply: #arrayConstr]. [self apply: #block]. [true
>                         ifTrue: [self apply: #token withArgs: {'('}.
>                                 self apply: #expr.
>                                 self apply: #token withArgs: {')'}]]}!
>
> ----- Method: OMeta2>>char (in category 'rules') -----
> char
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self pred: t1 isCharacter.
>                         t1]!
>
> ----- Method: OMeta2>>digit (in category 'rules') -----
> digit
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 isDigit.
>                         t1]!
>
> ----- Method: OMeta2>>end (in category 'rules') -----
> end
>         ^ self
>                 not: [self apply: #anything]!
>
> ----- Method: OMeta2>>exactly (in category 'rules-meta') -----
> exactly
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t2 := self apply: #anything.
>                         t1 := self apply: #anything.
>                         self pred: t2 = t1.
>                         t2]!
>
> ----- Method: OMeta2>>fromTo (in category 'rules') -----
> fromTo
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         t2 := self apply: #anything.
>                         self apply: #seq withArgs: {t1}.
>                         self
>                                 many: [true
>                                                 ifTrue: [self
>                                                                 not: [self apply: #seq withArgs: {t2}].
>                                                         self apply: #char]].
>                         self apply: #seq withArgs: {t2}]!
>
> ----- Method: OMeta2>>letter (in category 'rules') -----
> letter
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 isLetter.
>                         t1]!
>
> ----- Method: OMeta2>>letterOrDigit (in category 'rules') -----
> letterOrDigit
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 isAlphaNumeric.
>                         t1]!
>
> ----- Method: OMeta2>>listOf (in category 'rules-meta') -----
> listOf
>         | t1 t2 t3 t5 |
>         ^ true
>                 ifTrue: [t2 := self apply: #anything.
>                         t1 := self apply: #anything.
>                         self ometaOr: {[true
>                                         ifTrue: [t3 := self apply: #apply withArgs: {t2}.
>                                                 t5 := self
>                                                                         many: [true
>                                                                                         ifTrue: [self apply: #token withArgs: {t1}.
>                                                                                                 self apply: #apply withArgs: {t2}]].
>                                                 t5 addFirst: t3;
>                                                          yourself]]. [true
>                                         ifTrue: [self apply: #empty.
>                                                 #()]]}]!
>
> ----- Method: OMeta2>>lower (in category 'rules') -----
> lower
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 isLowercase.
>                         t1]!
>
> ----- Method: OMeta2>>notLast (in category 'rules-meta') -----
> notLast
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t2 := self apply: #anything.
>                         t1 := self apply: #apply withArgs: {t2}.
>                         self
>                                 lookahead: [self apply: #apply withArgs: {t2}].
>                         t1]!
>
> ----- Method: OMeta2>>number (in category 'rules') -----
> number
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self pred: t1 isNumber.
>                         t1]!
>
> ----- Method: OMeta2>>range (in category 'rules-meta') -----
> range
>         | t1 t2 t3 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         t2 := self apply: #anything.
>                         t3 := self apply: #anything.
>                         self pred: t1 <= t3 & (t3 <= t2).
>                         t3]!
>
> ----- Method: OMeta2>>space (in category 'rules') -----
> space
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 asciiValue <= 32.
>                         t1]!
>
> ----- Method: OMeta2>>spaces (in category 'rules') -----
> spaces
>         ^ self
>                 many: [self apply: #space]!
>
> ----- Method: OMeta2>>string (in category 'rules') -----
> string
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self pred: t1 isString.
>                         t1]!
>
> ----- Method: OMeta2>>symbol (in category 'rules') -----
> symbol
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self pred: t1 isSymbol.
>                         t1]!
>
> ----- Method: OMeta2>>token (in category 'rules-meta') -----
> token
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self apply: #spaces.
>                         self apply: #seq withArgs: {t1}]!
>
> ----- Method: OMeta2>>upper (in category 'rules') -----
> upper
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #char.
>                         self pred: t1 isUppercase.
>                         t1]!
>
> OMeta2 subclass: #OMeta2Examples
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> !OMeta2Examples commentStamp: '<historical>' prior: 0!
> Here's how to run these examples:
>
>         OMeta2Examples match: 5 with: #fact.
>         OMeta2Examples matchAll: '1234' with: #number.
>         OMeta2Examples matchAll: 'abc123' with: #identifier.
>         OMeta2Examples matchAll: #($a $b $c 1 2 3 #(4 5)) with: #structure.
>         OMeta2Examples matchAll: 'howdy' with: #greeting.!
>
> ----- Method: OMeta2Examples>>aSqueakMethod (in category 'squeak methods') -----
> aSqueakMethod
>
>         self inform: 'hello world'!
>
> ----- Method: OMeta2Examples>>anotherSqueakMethod (in category 'squeak methods') -----
> anotherSqueakMethod
>
>         self inform: 'good-bye world'!
>
> ----- Method: OMeta2Examples>>digit (in category 'rules') -----
> digit
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 super: OMeta2
>                                                 apply: #digit
>                                                 withArgs: {}.
>                         t1 digitValue]!
>
> ----- Method: OMeta2Examples>>fact (in category 'rules') -----
> fact
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #exactly withArgs: {0}.
>                                 1]]. [true
>                         ifTrue: [t3 := self apply: #anything.
>                                 t1 := self apply: #fact withArgs: {t3 - 1}.
>                                 t3 * t1]]}!
>
> ----- Method: OMeta2Examples>>formTest (in category 'rules') -----
> formTest
>         ^ self ometaOr: {[self
>                         form: [true
>                                         ifTrue: [self inform: input hash printString.
>                                                 self apply: #exactly withArgs: {#foo}.
>                                                 self apply: #exactly withArgs: {#bar}]]]. [self
>                         form: [true
>                                         ifTrue: [self inform: input hash printString.
>                                                 self apply: #exactly withArgs: {#bar}]]]}!
>
> ----- Method: OMeta2Examples>>greeting (in category 'rules') -----
> greeting
>         ^ self
>                 consumedBy: [true
>                                 ifTrue: [self apply: #seq withArgs: {'howdy'}.
>                                         self
>                                                 opt: [self apply: #seq withArgs: {'-ho'}]]]!
>
> ----- Method: OMeta2Examples>>identifier (in category 'rules') -----
> identifier
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self
>                                 consumedBy: [true
>                                                 ifTrue: [self apply: #letter.
>                                                         self
>                                                                 many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]]]!
>
> ----- Method: OMeta2Examples>>identifierIdx (in category 'rules') -----
> identifierIdx
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self
>                                 indexConsumedBy: [true
>                                                 ifTrue: [self apply: #letter.
>                                                         self
>                                                                 many: [self ometaOr: {[self apply: #letter]. [self apply: #digit]}]]]]!
>
> ----- Method: OMeta2Examples>>identifiers (in category 'rules') -----
> identifiers
>         ^ self
>                 many: [true
>                                 ifTrue: [self inform: self pos printString.
>                                         self apply: #identifier]]!
>
> ----- Method: OMeta2Examples>>number (in category 'rules') -----
> number
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t3 := self apply: #number.
>                                 t1 := self apply: #digit.
>                                 t3 * 10 + t1]]. [self apply: #digit]}!
>
> ----- Method: OMeta2Examples>>structure (in category 'rules') -----
> structure
>         ^ true
>                 ifTrue: [self apply: #exactly withArgs: {$a}.
>                         self apply: #exactly withArgs: {$b}.
>                         self apply: #exactly withArgs: {$c}.
>                         self apply: #exactly withArgs: {1}.
>                         self apply: #exactly withArgs: {2}.
>                         self apply: #exactly withArgs: {3}.
>                         self
>                                 form: [self
>                                                 many: [self apply: #anything]]]!
>
> OMeta2 subclass: #OMeta2Flattener
>         instanceVariableNames: 'ws'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2Flattener>>flatten (in category 'rules') -----
> flatten
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self apply: #iFlatten withArgs: {t1}.
>                         ws contents]!
>
> ----- Method: OMeta2Flattener>>iFlatten (in category 'rules') -----
> iFlatten
>         | t1 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t1 := self apply: #string.
>                                 ws nextPutAll: t1]]. [self
>                         form: [self
>                                         many: [self apply: #iFlatten]]]}!
>
> ----- Method: OMeta2Flattener>>initialize (in category 'initialize-release') -----
> initialize
>
>         super initialize.
>         ws := (String new: 64) writeStream!
>
> OMeta2 subclass: #OMeta2NullOpt
>         instanceVariableNames: 'didSomething'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> OMeta2NullOpt subclass: #OMeta2AndOrOpt
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2AndOrOpt>>and (in category 'rules') -----
> and
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t1 := self apply: #trans.
>                                 self apply: #end.
>                                 self apply: #setHelped.
>                                 t1]]. [true
>                         ifTrue: [t3 := self apply: #transInside withArgs: {#And}.
>                                 t3 addFirst: #And;
>                                          yourself]]}!
>
> ----- Method: OMeta2AndOrOpt>>or (in category 'rules') -----
> or
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t1 := self apply: #trans.
>                                 self apply: #end.
>                                 self apply: #setHelped.
>                                 t1]]. [true
>                         ifTrue: [t3 := self apply: #transInside withArgs: {#Or}.
>                                 t3 addFirst: #Or;
>                                          yourself]]}!
>
> ----- Method: OMeta2AndOrOpt>>transInside (in category 'rules') -----
> transInside
>         | t1 t2 t4 t5 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self ometaOr: {[true
>                                         ifTrue: [self
>                                                         form: [true
>                                                                         ifTrue: [self apply: #exactly withArgs: {t1}.
>                                                                                 t4 := self apply: #transInside withArgs: {t1}]].
>                                                 t5 := self apply: #transInside withArgs: {t1}.
>                                                 self apply: #setHelped.
>                                                 t4 , t5]]. [true
>                                         ifTrue: [t2 := self apply: #trans.
>                                                 t4 := self apply: #transInside withArgs: {t1}.
>                                                 t4 addFirst: t2;
>                                                          yourself]]. [true
>                                         ifTrue: [self apply: #empty.
>                                                 OrderedCollection new]]}]!
>
> ----- Method: OMeta2NullOpt>>and (in category 'rules') -----
> and
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 many: [self apply: #trans].
>                         t1 addFirst: #And;
>                                  yourself]!
>
> ----- Method: OMeta2NullOpt>>consby (in category 'rules') -----
> consby
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#ConsBy. t1}]!
>
> ----- Method: OMeta2NullOpt>>form (in category 'rules') -----
> form
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Form. t1}]!
>
> ----- Method: OMeta2NullOpt>>helped (in category 'rules') -----
> helped
>         ^ self pred: didSomething!
>
> ----- Method: OMeta2NullOpt>>idxconsby (in category 'rules') -----
> idxconsby
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#IdxConsBy. t1}]!
>
> ----- Method: OMeta2NullOpt>>initialize (in category 'initialize-release') -----
> initialize
>
>         super initialize.
>         didSomething := false!
>
> ----- Method: OMeta2NullOpt>>lookahead (in category 'rules') -----
> lookahead
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Lookahead. t1}]!
>
> ----- Method: OMeta2NullOpt>>many (in category 'rules') -----
> many
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Many. t1}]!
>
> ----- Method: OMeta2NullOpt>>many1 (in category 'rules') -----
> many1
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Many1. t1}]!
>
> ----- Method: OMeta2NullOpt>>not (in category 'rules') -----
> not
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Not. t1}]!
>
> ----- Method: OMeta2NullOpt>>opt (in category 'rules') -----
> opt
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {#Opt. t1}]!
>
> ----- Method: OMeta2NullOpt>>optimize (in category 'rules') -----
> optimize
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         self apply: #helped.
>                         t1]!
>
> ----- Method: OMeta2NullOpt>>or (in category 'rules') -----
> or
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 many: [self apply: #trans].
>                         t1 addFirst: #Or;
>                                  yourself]!
>
> ----- Method: OMeta2NullOpt>>rule (in category 'rules') -----
> rule
>         | t1 t2 t3 |
>         ^ true
>                 ifTrue: [t2 := self apply: #anything.
>                         t3 := self apply: #anything.
>                         t1 := self apply: #trans.
>                         {#Rule. t2. t3. t1}]!
>
> ----- Method: OMeta2NullOpt>>set (in category 'rules') -----
> set
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         t2 := self apply: #trans.
>                         {#Set. t1. t2}]!
>
> ----- Method: OMeta2NullOpt>>setHelped (in category 'rules') -----
> setHelped
>         ^ didSomething := true!
>
> ----- Method: OMeta2NullOpt>>trans (in category 'rules') -----
> trans
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self
>                                         form: [true
>                                                         ifTrue: [t3 := self apply: #anything.
>                                                                 t3 := t3 asLowercase asSymbol.
>                                                                 self
>                                                                         pred: (self class canUnderstand: t3).
>                                                                 t1 := self apply: #apply withArgs: {t3}]].
>                                 t1]]. [self apply: #anything]}!
>
> OMeta2 subclass: #OMeta2Optimizer
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2Optimizer>>optimizeRule (in category 'rules') -----
> optimizeRule
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self
>                                 many: [t1 := self apply: #foreign withArgs: {OMeta2AndOrOpt. #optimize. t1}].
>                         t1]!
>
> OMeta2 subclass: #OMeta2RuleParser
>         instanceVariableNames: 'temps'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2RuleParser class>>isOMeta2Rule: (in category 'as yet unclassified') -----
> isOMeta2Rule: aString
>
>         ^ [(self matchAll: aString with: #rule) first ~= #Squeak] on: OM2Fail do: [false]!
>
> ----- Method: OMeta2RuleParser>>application (in category 'rules') -----
> application
>         | t1 t3 t4 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #token withArgs: {'^'}.
>                                 t4 := self apply: #name.
>                                 t1 := self apply: #args.
>                                 {#SuperApp. t4} , t1]]. [true
>                         ifTrue: [t3 := self apply: #name.
>                                 self apply: #exactly withArgs: {$.}.
>                                 t4 := self apply: #nsName.
>                                 t1 := self apply: #args.
>                                 {#App. #foreign. t3. ('#' , t4) asSymbol} , t1]]. [true
>                         ifTrue: [t4 := self apply: #name.
>                                 t1 := self apply: #args.
>                                 {#App. t4} , t1]]}!
>
> ----- Method: OMeta2RuleParser>>args (in category 'rules') -----
> args
>         | t1 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #exactly withArgs: {$(}.
>                                 t1 := self apply: #listOf withArgs: {#squeakExpression. '.'}.
>                                 self apply: #token withArgs: {')'}.
>                                 t1]]. [true
>                         ifTrue: [self
>                                         not: [self apply: #exactly withArgs: {$(}].
>                                 #()]]}!
>
> ----- Method: OMeta2RuleParser>>characterLiteral (in category 'rules') -----
> characterLiteral
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self apply: #exactly withArgs: {$$}.
>                         t1 := self apply: #char.
>                         {#App. #exactly. t1 storeString}]!
>
> ----- Method: OMeta2RuleParser>>characters (in category 'rules') -----
> characters
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'``'}.
>                         t1 := self
>                                                 many: [true
>                                                                 ifTrue: [self
>                                                                                 not: [true
>                                                                                                 ifTrue: [self apply: #exactly withArgs: {$'}.
>                                                                                                         self apply: #exactly withArgs: {$'}]].
>                                                                         self apply: #char]].
>                         self apply: #exactly withArgs: {$'}.
>                         self apply: #exactly withArgs: {$'}.
>                         {#App. #seq. (String withAll: t1) storeString}]!
>
> ----- Method: OMeta2RuleParser>>expr (in category 'rules') -----
> expr
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #listOf withArgs: {#expr4. '|'}.
>                         (OrderedCollection with: #Or) addAll: t1;
>                                  yourself]!
>
> ----- Method: OMeta2RuleParser>>expr1 (in category 'rules') -----
> expr1
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t3 := self ometaOr: {[self apply: #keyword withArgs: {'true'}]. [self apply: #keyword withArgs: {'false'}]. [self apply: #keyword withArgs: {'nil'}]}.
>                                 {#App. #exactly. t3}]]. [self apply: #application]. [self apply: #semanticAction]. [self apply: #semanticPredicate]. [self apply: #characters]. [self apply: #tokenSugar]. [self apply: #stringLiteral]. [self apply: #symbolLiteral]. [self apply: #numberLiteral]. [self apply: #characterLiteral]. [true
>                         ifTrue: [self apply: #token withArgs: {'{'}.
>                                 t1 := self apply: #expr.
>                                 self apply: #token withArgs: {'}'}.
>                                 {#Form. t1}]]. [true
>                         ifTrue: [self apply: #token withArgs: {'<'}.
>                                 t1 := self apply: #expr.
>                                 self apply: #token withArgs: {'>'}.
>                                 {#ConsBy. t1}]]. [true
>                         ifTrue: [self apply: #token withArgs: {'@<'}.
>                                 t1 := self apply: #expr.
>                                 self apply: #token withArgs: {'>'}.
>                                 {#IdxConsBy. t1}]]. [true
>                         ifTrue: [self apply: #token withArgs: {'('}.
>                                 t1 := self apply: #expr.
>                                 self apply: #token withArgs: {')'}.
>                                 t1]]}!
>
> ----- Method: OMeta2RuleParser>>expr2 (in category 'rules') -----
> expr2
>         | t1 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self apply: #token withArgs: {'~'}.
>                                 t1 := self apply: #expr2.
>                                 {#Not. t1}]]. [true
>                         ifTrue: [self apply: #token withArgs: {'&'}.
>                                 t1 := self apply: #expr2.
>                                 {#Lookahead. t1}]]. [self apply: #expr1]}!
>
> ----- Method: OMeta2RuleParser>>expr3 (in category 'rules') -----
> expr3
>         | t1 t3 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t3 := self apply: #expr2.
>                                 t3 := self apply: #optIter withArgs: {t3}.
>                                 self ometaOr: {[true
>                                                 ifTrue: [self apply: #exactly withArgs: {$:}.
>                                                         t1 := self apply: #nsName.
>                                                         temps add: t1.
>                                                         {#Set. t1. t3}]]. [true
>                                                 ifTrue: [self apply: #empty.
>                                                         t3]]}]]. [true
>                         ifTrue: [self apply: #token withArgs: {':'}.
>                                 t1 := self apply: #nsName.
>                                 temps add: t1.
>                                 {#Set. t1. {#App. #anything}}]]}!
>
> ----- Method: OMeta2RuleParser>>expr4 (in category 'rules') -----
> expr4
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 many: [self apply: #expr3].
>                         (OrderedCollection with: #And) addAll: t1;
>                                  yourself]!
>
> ----- Method: OMeta2RuleParser>>initialize (in category 'initialize-release') -----
> initialize
>
>         super initialize.
>         temps := IdentitySet new!
>
> ----- Method: OMeta2RuleParser>>keyword (in category 'rules-meta') -----
> keyword
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self apply: #token withArgs: {t1}.
>                         self
>                                 not: [self apply: #letterOrDigit].
>                         t1]!
>
> ----- Method: OMeta2RuleParser>>name (in category 'rules') -----
> name
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         self apply: #nsName]!
>
> ----- Method: OMeta2RuleParser>>nameFirst (in category 'rules') -----
> nameFirst
>         ^ self apply: #letter!
>
> ----- Method: OMeta2RuleParser>>nameRest (in category 'rules') -----
> nameRest
>         ^ self ometaOr: {[self apply: #nameFirst]. [self apply: #digit]}!
>
> ----- Method: OMeta2RuleParser>>nsName (in category 'rules') -----
> nsName
>         | t1 |
>         ^ self ometaOr: {[true
>                         ifTrue: [t1 := self apply: #firstAndRest withArgs: {#nameFirst. #nameRest}.
>                                 (String withAll: t1) asSymbol]]. [true
>                         ifTrue: [self apply: #exactly withArgs: {$_}.
>                                 #anything]]}!
>
> ----- Method: OMeta2RuleParser>>numberLiteral (in category 'rules') -----
> numberLiteral
>         | t1 t2 |
>         ^ true
>                 ifTrue: [self apply: #spaces.
>                         t2 := self ometaOr: {[true
>                                                         ifTrue: [self apply: #exactly withArgs: {$-}.
>                                                                 self apply: #spaces.
>                                                                 -1]]. [true
>                                                         ifTrue: [self apply: #empty.
>                                                                 1]]}.
>                         t1 := self
>                                                 many1: [self apply: #digit].
>                         {#App. #exactly. (t2 * (String withAll: t1) asNumber) storeString}]!
>
> ----- Method: OMeta2RuleParser>>optIter (in category 'rules-meta') -----
> optIter
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #anything.
>                         self ometaOr: {[true
>                                         ifTrue: [self apply: #token withArgs: {'*'}.
>                                                 {#Many. t1}]]. [true
>                                         ifTrue: [self apply: #token withArgs: {'+'}.
>                                                 {#Many1. t1}]]. [true
>                                         ifTrue: [self apply: #token withArgs: {'?'}.
>                                                 self
>                                                         not: [self apply: #exactly withArgs: {$[}].
>                                                 {#Opt. t1}]]. [true
>                                         ifTrue: [self apply: #empty.
>                                                 t1]]}]!
>
> ----- Method: OMeta2RuleParser>>rule (in category 'rules') -----
> rule
>         | t1 t3 t4 t5 |
>         ^ self ometaOr: {[true
>                         ifTrue: [self
>                                         not: [true
>                                                         ifTrue: [self
>                                                                         many: [self
>                                                                                         super: OMeta2
>                                                                                         apply: #space
>                                                                                         withArgs: {}].
>                                                                 self apply: #nsName.
>                                                                 self apply: #expr4.
>                                                                 self apply: #token withArgs: {'='}]].
>                                 t3 := self
>                                                         consumedBy: [self
>                                                                         many: [self apply: #char]].
>                                 {#Squeak. t3}]]. [true
>                         ifTrue: [t1 := self
>                                                         lookahead: [true
>                                                                         ifTrue: [self
>                                                                                         many: [self
>                                                                                                         super: OMeta2
>                                                                                                         apply: #space
>                                                                                                         withArgs: {}].
>                                                                                 self apply: #nsName]].
>                                 t4 := self apply: #rulePart withArgs: {t1}.
>                                 t5 := self
>                                                         many: [true
>                                                                         ifTrue: [self apply: #token withArgs: {','}.
>                                                                                 self apply: #rulePart withArgs: {t1}]].
>                                 self apply: #spaces.
>                                 self apply: #end.
>                                 {#Rule. t1. temps asSortedCollection. (OrderedCollection with: #Or with: t4) addAll: t5;
>                                          yourself}]]}!
>
> ----- Method: OMeta2RuleParser>>rulePart (in category 'rules-meta') -----
> rulePart
>         | t1 t2 t3 t4 |
>         ^ true
>                 ifTrue: [t3 := self apply: #anything.
>                         t2 := self apply: #name.
>                         self pred: t2 = t3.
>                         t1 := self apply: #expr4.
>                         self ometaOr: {[true
>                                         ifTrue: [self apply: #token withArgs: {'='}.
>                                                 t4 := self apply: #expr.
>                                                 {#And. t1. t4}]]. [true
>                                         ifTrue: [self apply: #empty.
>                                                 t1]]}]!
>
> ----- Method: OMeta2RuleParser>>semanticAction (in category 'rules') -----
> semanticAction
>         | t1 |
>         ^ true
>                 ifTrue: [self
>                                 opt: [self apply: #token withArgs: {'->'}].
>                         self apply: #token withArgs: {'['}.
>                         t1 := self apply: #squeakExpression.
>                         self apply: #exactly withArgs: {$]}.
>                         {#Act. t1}]!
>
> ----- Method: OMeta2RuleParser>>semanticPredicate (in category 'rules') -----
> semanticPredicate
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'?['}.
>                         t1 := self apply: #squeakExpression.
>                         self apply: #exactly withArgs: {$]}.
>                         {#Pred. t1}]!
>
> ----- Method: OMeta2RuleParser>>space (in category 'rules') -----
> space
>         ^ self ometaOr: {[self
>                         super: OMeta2
>                         apply: #space
>                         withArgs: {}]. [self apply: #fromTo withArgs: {'/*'. '*/'}]. [self apply: #fromTo withArgs: {'//'. String cr}]}!
>
> ----- Method: OMeta2RuleParser>>squeakExpression (in category 'rules') -----
> squeakExpression
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #foreign withArgs: {O2SqueakRecognizer. #squeakExpr}.
>                         self apply: #spaces.
>                         t1]!
>
> ----- Method: OMeta2RuleParser>>stringLiteral (in category 'rules') -----
> stringLiteral
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {''''}.
>                         t1 := self
>                                                 many: [self ometaOr: {[true
>                                                                         ifTrue: [self apply: #exactly withArgs: {$'}.
>                                                                                 self apply: #exactly withArgs: {$'}.
>                                                                                 $']]. [true
>                                                                         ifTrue: [self
>                                                                                         not: [self apply: #exactly withArgs: {$'}].
>                                                                                 self apply: #char]]}].
>                         self apply: #exactly withArgs: {$'}.
>                         {#App. #exactly. (String withAll: t1) storeString}]!
>
> ----- Method: OMeta2RuleParser>>symbolLiteral (in category 'rules') -----
> symbolLiteral
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'#'}.
>                         t1 := self apply: #nsName.
>                         {#App. #exactly. t1 storeString}]!
>
> ----- Method: OMeta2RuleParser>>tokenSugar (in category 'rules') -----
> tokenSugar
>         | t1 |
>         ^ true
>                 ifTrue: [self apply: #token withArgs: {'"'}.
>                         t1 := self
>                                                 many: [true
>                                                                 ifTrue: [self
>                                                                                 not: [self apply: #exactly withArgs: {$"}].
>                                                                         self apply: #char]].
>                         self apply: #exactly withArgs: {$"}.
>                         {#App. #token. (String withAll: t1) storeString}]!
>
> OMeta2 subclass: #OMeta2RuleTranslator
>         instanceVariableNames: 'grammarClass'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2RuleTranslator>>act (in category 'rules') -----
> act
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #string.
>                         {'('. t1. ')'}]!
>
> ----- Method: OMeta2RuleTranslator>>and (in category 'rules') -----
> and
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 many: [self apply: #trans].
>                         {'(true ifTrue: ['. self delim: t1 with: '. '. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>app (in category 'rules') -----
> app
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t1 := self apply: #symbol.
>                         self ometaOr: {[true
>                                         ifTrue: [t2 := self
>                                                                         many1: [self apply: #anything].
>                                                 t2 := self delim: t2 with: '. '.
>                                                 {'(self apply: '. t1 storeString. ' withArgs: {'. t2. '})'}]]. [{'(self apply: '. t1 storeString. ')'}]}]!
>
> ----- Method: OMeta2RuleTranslator>>consby (in category 'rules') -----
> consby
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self consumedBy: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>delim:with: (in category 'helpers') -----
> delim: aSequenceableCollection  with: anObject
>
>         | first ans |
>         first := true.
>         ans := OrderedCollection new.
>         aSequenceableCollection do: [:x |
>                 first ifTrue: [first := false] ifFalse: [ans add: anObject].
>                 ans add: x
>         ].
>         ^ ans!
>
> ----- Method: OMeta2RuleTranslator>>form (in category 'rules') -----
> form
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self form: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>idxconsby (in category 'rules') -----
> idxconsby
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self indexConsumedBy: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>lookahead (in category 'rules') -----
> lookahead
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self lookahead: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>many (in category 'rules') -----
> many
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self many: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>many1 (in category 'rules') -----
> many1
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self many1: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>not (in category 'rules') -----
> not
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self not: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>opt (in category 'rules') -----
> opt
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #trans.
>                         {'(self opt: ['. t1. '])'}]!
>
> ----- Method: OMeta2RuleTranslator>>or (in category 'rules') -----
> or
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t1 := self
>                                                 many: [true
>                                                                 ifTrue: [t2 := self apply: #trans.
>                                                                         {'['. t2. ']'}]].
>                         {'(self ometaOr: {'. self delim: t1 with: '. '. '})'}]!
>
> ----- Method: OMeta2RuleTranslator>>pred (in category 'rules') -----
> pred
>         | t1 |
>         ^ true
>                 ifTrue: [t1 := self apply: #string.
>                         {'(self pred: ('. t1. '))'}]!
>
> ----- Method: OMeta2RuleTranslator>>rule (in category 'rules') -----
> rule
>         | t1 t2 t3 |
>         ^ true
>                 ifTrue: [t2 := self apply: #symbol.
>                         t3 := self apply: #anything.
>                         t3 := t3
>                                                 select: [:t4 | (grammarClass instVarNames includes: t4) not].
>                         t1 := self apply: #trans.
>                         {t2. ' |'. self delim: t3 asSortedCollection with: ' '. ' | ^ '. t1}]!
>
> ----- Method: OMeta2RuleTranslator>>set (in category 'rules') -----
> set
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t1 := self apply: #symbol.
>                         t2 := self apply: #trans.
>                         {'('. t1 asString. ' := '. t2. ')'}]!
>
> ----- Method: OMeta2RuleTranslator>>squeak (in category 'rules') -----
> squeak
>         ^ self apply: #string!
>
> ----- Method: OMeta2RuleTranslator>>superapp (in category 'rules') -----
> superapp
>         | t1 t2 |
>         ^ true
>                 ifTrue: [t2 := self apply: #symbol.
>                         t1 := self
>                                                 many: [self apply: #anything].
>                         t1 := self delim: t1 with: '. '.
>                         {'(self super: '. grammarClass superclass name. ' apply: '. t2 storeString. ' withArgs: {'. t1. '})'}]!
>
> ----- Method: OMeta2RuleTranslator>>trans (in category 'rules') -----
> trans
>         | t1 t3 |
>         ^ true
>                 ifTrue: [self
>                                 form: [true
>                                                 ifTrue: [t3 := self apply: #symbol.
>                                                         t1 := self apply: #apply withArgs: {t3 asLowercase asSymbol}]].
>                         t1]!
>
> ----- Method: OMeta2RuleTranslator>>translate (in category 'rules') -----
> translate
>         ^ true
>                 ifTrue: [grammarClass := self apply: #anything.
>                         self apply: #trans]!
>
> ----- Method: OMeta2Base class>>compilerClass (in category 'as yet unclassified') -----
> compilerClass
>
>         ^ OMeta2Compiler!
>
> ----- Method: OMeta2Base class>>debugMatch:with: (in category 'as yet unclassified') -----
> debugMatch: anObject with: aRule
>
>         ^ self debugMatch: anObject with: aRule withArgs: #()!
>
> ----- Method: OMeta2Base class>>debugMatch:with:withArgs: (in category 'as yet unclassified') -----
> debugMatch: anObject with: aRule withArgs: args
>
>         ^ self debugMatchAll: {anObject} readStream with: aRule withArgs: args!
>
> ----- Method: OMeta2Base class>>debugMatchAll:with: (in category 'as yet unclassified') -----
> debugMatchAll: aSequenceableCollection with: aRule
>
>         ^ self debugMatchAll: aSequenceableCollection with: aRule withArgs: #()!
>
> ----- Method: OMeta2Base class>>debugMatchAll:with:withArgs: (in category 'as yet unclassified') -----
> debugMatchAll: aSequenceableCollection with: aRule withArgs: args
>
>         ^ self matchStream: aSequenceableCollection readStream with: aRule withArgs: args withPlaybackDebugging: true!
>
> ----- Method: OMeta2Base class>>match:with: (in category 'as yet unclassified') -----
> match: anObject with: aRule
>
>         ^ self match: anObject with: aRule withArgs: #()!
>
> ----- Method: OMeta2Base class>>match:with:withArgs: (in category 'as yet unclassified') -----
> match: anObject with: aRule withArgs: args
>
>         ^ self matchAll: {anObject} readStream with: aRule withArgs: args!
>
> ----- Method: OMeta2Base class>>matchAll:with: (in category 'as yet unclassified') -----
> matchAll: aSequenceableCollection with: aRule
>
>         ^ self matchAll: aSequenceableCollection with: aRule withArgs: #()!
>
> ----- Method: OMeta2Base class>>matchAll:with:withArgs: (in category 'as yet unclassified') -----
> matchAll: aSequenceableCollection with: aRule withArgs: args
>
>         ^ self matchStream: aSequenceableCollection readStream with: aRule withArgs: args withPlaybackDebugging: false!
>
> ----- Method: OMeta2Base class>>matchStream:with:withArgs:withPlaybackDebugging: (in category 'as yet unclassified') -----
> matchStream: aReadStream with: aRule withArgs: args withPlaybackDebugging: debugging
>
>         | input matcher ans|
>         input := OM2LazyStream for: aReadStream withPos: 1.
>         matcher := self new initInput: input.
>         [
>                 matcher apply: #empty withArgs: args.
>                 ans := matcher apply: aRule.
>                 matcher apply: #end.
>                 ^ ans
>         ] on: OM2Fail do: [:e |
>                 | curr prev prevPrev |
>                 debugging ifFalse: [e signal].
>                 curr := input.
>                 prev := nil.
>                 prevPrev := nil.
>                 [curr notNil] whileTrue: [
>                         prevPrev := prev.
>                         prev := curr.
>                         curr := curr basicTail
>                 ].
>                 curr := prevPrev ifNotNil: [prevPrev] ifNil: [prev].
>                 self inform: 'will halt each time matcher reaches ', curr printString.
>                 matcher
>                         initInput: input;
>                         forgetEverything.
>                 curr ifNil: [self error: 'you''ve found a bug -- please tell Alex'].
>                 curr become: (OM2StreamDebugger for: curr copy).
>                 matcher haltingPoint: curr.
>                 matcher apply: #empty withArgs: args.
>                 ans := matcher apply: aRule.
>                 matcher apply: #end.
>                 ^ ans
>         ]!
>
> ----- Method: OMeta2Base class>>matcherOn: (in category 'as yet unclassified') -----
> matcherOn: aReadStream
>
>         | input matcher |
>         input := OM2LazyStream for: aReadStream withPos: 1.
>         matcher := self new initInput: input.
>         ^ matcher!
>
> ----- Method: OMeta2Base>>anything (in category 'rules-basic') -----
> anything
>
>         | ans |
>         ans := input head.
>         input := input tail.
>         ^ ans!
>
> ----- Method: OMeta2Base>>apply (in category 'rules-basic') -----
> apply
>
>         | aRule |
>         aRule := self apply: #anything.
>         ^ self apply: aRule!
>
> ----- Method: OMeta2Base>>apply: (in category 'rule application') -----
> apply: aRule
>
>         " A memoRec is an association whose key is the answer,
>           and whose value is the next input. Failers pretend to
>      be memoRecs, but throw a fail in response to #value "
>         | memo memoRec |
>         input == haltingPoint ifTrue: [self halt].
>         memo := input memo.
>         memoRec := memo at: aRule ifAbsent: [nil].
>         memoRec ifNil: [
>                 | origInput failer ans |
>                 origInput := input.
>                 failer := OM2Failer new.
>                 memo at: aRule put: failer.
>                 ans := self perform: aRule.
>                 memoRec := ans -> input.
>                 memo at: aRule put: memoRec.
>                 failer used ifTrue: [
>                         " left recursion detected "
>                         | sentinel keepGoing |
>                         sentinel := input.
>                         keepGoing := true.
>                         [keepGoing] whileTrue: [
>                                 [
>                                         input := origInput.
>                                         ans := self perform: aRule.
>                                         input == sentinel ifTrue: [OMeta2Fail signal].
>                                         memoRec key: ans value: input.
>                                 ] on: OM2Fail do: [keepGoing := false]
>                         ]
>                 ]
>         ].
>         input := memoRec value.
>         ^ memoRec key!
>
> ----- Method: OMeta2Base>>apply:withArgs: (in category 'rule application') -----
> apply: aRule withArgs: args
>
>         args reverseDo: [:a | input := OM2Stream new initHead: a tail: input].
>         ^ self perform: aRule!
>
> ----- Method: OMeta2Base>>consumedBy: (in category 'private') -----
> consumedBy: aBlock
>
>         | origInput i ws |
>         origInput := input.
>         aBlock value.
>         ws := WriteStream on: origInput inputSpecies new.
>         i := origInput.
>         [i == input] whileFalse: [
>                 ws nextPut: i head.
>                 i := i tail
>         ].
>         ^ ws contents!
>
> ----- Method: OMeta2Base>>empty (in category 'rules-basic') -----
> empty
>
>         ^ true!
>
> ----- Method: OMeta2Base>>firstAndRest (in category 'rules-basic') -----
> firstAndRest
>
>         | first rest |
>         first := self apply: #anything.
>         rest := self apply: #anything.
>         ^ self genericMany: [self apply: rest] into: (OrderedCollection with: (self apply: first))!
>
> ----- Method: OMeta2Base>>foreign (in category 'rules-basic') -----
> foreign
>
>         | aGrammar aRule g ans |
>         aGrammar := self apply: #anything.
>         aRule := self apply: #anything.
>         g := aGrammar new initInput: (OM2StreamProxy for: input).
>         ans := g apply: aRule.
>         input := g input target.
>         ^ ans!
>
> ----- Method: OMeta2Base>>forgetEverything (in category 'forgetting') -----
> forgetEverything
>
>         input transitiveForgetEverything.
>         om2streams valuesDo: [:s | s transitiveForgetEverything]!
>
> ----- Method: OMeta2Base>>form: (in category 'rules-basic') -----
> form: aBlock
>
>         | v origInput |
>         v := self apply: #anything.
>         self pred: (v isCollection and: [v isSequenceable and: [v isSymbol not]]).
>         origInput := input.
>         input := om2streams at: v ifAbsentPut: [OM2LazyStream for: v readStream withPos: 1].
>         aBlock value.
>         self apply: #end.
>         input := origInput.
>         ^ v!
>
> ----- Method: OMeta2Base>>genericMany:into: (in category 'private') -----
> genericMany: aBlock into: anOrderedCollection
>
>         [
>                 | origInput |
>                 origInput := input.
>                 [anOrderedCollection addLast: aBlock value] on: OM2Fail do: [
>                         input := origInput.
>                         ^ anOrderedCollection
>                 ].
>                 true
>         ] whileTrue!
>
> ----- Method: OMeta2Base>>haltingPoint: (in category 'initialize-release') -----
> haltingPoint: anOM2Stream
>
>         haltingPoint := anOM2Stream!
>
> ----- Method: OMeta2Base>>indexConsumedBy: (in category 'private') -----
> indexConsumedBy: aBlock
>
>         | from to |
>         from := self pos.
>         aBlock value.
>         to := self pos.
>         ^ from -> to!
>
> ----- Method: OMeta2Base>>initInput: (in category 'initialize-release') -----
> initInput: i
>
>         input := i!
>
> ----- Method: OMeta2Base>>initialize (in category 'initialize-release') -----
> initialize
>
>         super initialize.
>         om2streams := IdentityDictionary new!
>
> ----- Method: OMeta2Base>>input (in category 'rules-basic') -----
> input
>
>         ^ input!
>
> ----- Method: OMeta2Base>>lookahead: (in category 'private') -----
> lookahead: aBlock
>
>         | origInput ans |
>         origInput := input.
>         ans := aBlock value.
>         input := origInput.
>         ^ ans!
>
> ----- Method: OMeta2Base>>many1: (in category 'private') -----
> many1: aBlock
>
>         ^ self genericMany: aBlock into: (OrderedCollection with: aBlock value)!
>
> ----- Method: OMeta2Base>>many: (in category 'private') -----
> many: aBlock
>
>         ^ self genericMany: aBlock into: OrderedCollection new!
>
> ----- Method: OMeta2Base>>not: (in category 'private') -----
> not: aBlock
>
>         | origInput |
>         origInput := input.
>         [aBlock value] on: OM2Fail do: [
>                 input := origInput.
>                 ^ true
>         ].
>         OMeta2Fail signal!
>
> ----- Method: OMeta2Base>>ometaOr: (in category 'private') -----
> ometaOr: choices
>
>         | origInput |
>         origInput := input.
>         choices do: [:choice |
>                 input := origInput.
>                 [^ choice value] on: OM2Fail do: []
>         ].
>         OMeta2Fail signal!
>
> ----- Method: OMeta2Base>>opt: (in category 'private') -----
> opt: aBlock
>
>         ^ self ometaOr: {
>                 [aBlock value].
>                 [nil]
>         }!
>
> ----- Method: OMeta2Base>>pos (in category 'rules-basic') -----
> pos
>
>         ^ input pos!
>
> ----- Method: OMeta2Base>>pred: (in category 'private') -----
> pred: aBooleanValue
>
>         " may want to have the compiler inline this automatically, for performance "
>         aBooleanValue ifTrue: [^ true].
>         OMeta2Fail signal!
>
> ----- Method: OMeta2Base>>seq (in category 'rules-basic') -----
> seq
>
>         | xs |
>         xs := self apply: #anything.
>         xs do: [:x |
>                 " may want to inline #apply:withArgs: below as an
>                   optimization, since this rule gets used a lot "
>                 self apply: #exactly withArgs: {x}
>         ].
>         ^ xs
>         !
>
> ----- Method: OMeta2Base>>super:apply:withArgs: (in category 'rule application') -----
> super: superclass apply: aRule withArgs: args
>
>         args reverseDo: [:a | input := OM2Stream new initHead: a tail: input].
>         ^ self perform: aRule withArguments: #() inSuperclass: superclass!
>
> MethodNode subclass: #OMeta2MethodNode
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
> ----- Method: OMeta2MethodNode>>schematicTempNamesString (in category 'debugger support') -----
> schematicTempNamesString
>         "The decompiler wants a list of temp names. However, this mechanism depends on a number of assumptions that do not hold with OMeta2 generated methods. Therefore we simply skip the temp names, letting the decompiler build generic ones."
>         ^nil!
>
>



--
-- Yoshiki

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Tobias Pape
Hi,

On 31.07.2014, at 22:34, Yoshiki Ohshima <[hidden email]> wrote:

> Hmm, ok.  This diff has more code than it should have, but I patched
> OMeta2 package to make it work in the new compiler regime in Squeak
> 4.5.  Hans-Martin, do you think you can take this, and update the
> config map (if necessary)?

The diff is that big becaus OMeta is not in the trunk repository (and hench
not in the inbox).
  Did you mean to commit it to http://www.squeaksource.com/OMeta ?
  This is also where the config map is.

Best
        -Tobias




signature.asc (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Frank Shearar-3
On 31 July 2014 21:37, Tobias Pape <[hidden email]> wrote:

> Hi,
>
> On 31.07.2014, at 22:34, Yoshiki Ohshima <[hidden email]> wrote:
>
>> Hmm, ok.  This diff has more code than it should have, but I patched
>> OMeta2 package to make it work in the new compiler regime in Squeak
>> 4.5.  Hans-Martin, do you think you can take this, and update the
>> config map (if necessary)?
>
> The diff is that big becaus OMeta is not in the trunk repository (and hench
> not in the inbox).
>   Did you mean to commit it to http://www.squeaksource.com/OMeta ?
>   This is also where the config map is.
>
> Best
>         -Tobias

Oh, I do like to see OMeta getting some love!

That repo (http://www.squeaksource.com/OMeta) has _only "preload" and
"postload" packages. Is that right? I'd sort've expected, from the
names, that there would be a plain "ometa" package in the middle.

frank

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Eliot Miranda-2
In reply to this post by Yoshiki Ohshima-3



On Thu, Jul 31, 2014 at 10:34 AM, Yoshiki Ohshima <[hidden email]> wrote:
Hmm, ok.  This diff has more code than it should have, but I patched
OMeta2 package to make it work in the new compiler regime in Squeak
4.5.  Hans-Martin, do you think you can take this, and update the
config map (if necessary)?

Hopefully the CompiledMethod>>methodNode override is unnecessary.

 
On Thu, Jul 31, 2014 at 1:31 PM,  <[hidden email]> wrote:
> A new version of OMeta2-Preload was added to project The Inbox:
> http://source.squeak.org/inbox/OMeta2-Preload-yo.15.mcz
>
> ==================== Summary ====================
>
> Name: OMeta2-Preload-yo.15
> Author: yo
> Time: 31 July 2014, 1:29:01.319 pm
> UUID: 6c6bc75e-3c9f-4446-b08a-cdce7081ef2d
> Ancestors: OMeta2-Preload-hmm.14
>
> Adapt to Squeak 4.5.
>
> ==================== Snapshot ====================
>
> SystemOrganization addCategory: #OMeta2!
> SystemOrganization addCategory: #'OMeta2-Info'!
>
> ----- Method: CompiledMethod>>methodNode (in category '*OMeta2-Preload') -----
> methodNode
>         "Return the parse tree that represents self. If parsing fails, decompile the method."
>         | aClass source |
>         aClass := self methodClass.
>         source := self
>                                 getSourceFor: (self selector ifNil: [self defaultSelector])
>                                 in: aClass.
>         ^[(aClass parserClass new
>                 encoderClass: (self isBlueBookCompiled
>                                                 ifTrue: [EncoderForV3]
>                                                 ifFalse: [EncoderForV3PlusClosures]);
>                 parse: source class: aClass)
>                         sourceText: source;
>                         yourself]
>                 on: SyntaxErrorNotification
>                 do: [:ex | ex return: self decompile].!
>
> Exception subclass: #OM2Fail
>         instanceVariableNames: ''
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'OMeta2'!
>
 
...

--
Aloha,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Tobias Pape
In reply to this post by Frank Shearar-3

On 31.07.2014, at 22:40, Frank Shearar <[hidden email]> wrote:

> On 31 July 2014 21:37, Tobias Pape <[hidden email]> wrote:
>> Hi,
>>
>> On 31.07.2014, at 22:34, Yoshiki Ohshima <[hidden email]> wrote:
>>
>>> Hmm, ok.  This diff has more code than it should have, but I patched
>>> OMeta2 package to make it work in the new compiler regime in Squeak
>>> 4.5.  Hans-Martin, do you think you can take this, and update the
>>> config map (if necessary)?
>>
>> The diff is that big becaus OMeta is not in the trunk repository (and hench
>> not in the inbox).
>>  Did you mean to commit it to http://www.squeaksource.com/OMeta ?
>>  This is also where the config map is.
>>
>> Best
>>        -Tobias
>
> Oh, I do like to see OMeta getting some love!
>
> That repo (http://www.squeaksource.com/OMeta) has _only "preload" and
> "postload" packages. Is that right? I'd sort've expected, from the
> names, that there would be a plain "ometa" package in the middle.
It works like this:

Load the config map, witch says:
        Load the preload
        Load the postload.

The preload is:
        “pre-compiled” Ometa in Squeak
The postload is:
        ometa in ometa (compiled on load by the “pre-compiled” ometa version)
        AND: mark both packages as non-dirty

BTW: this is also one of the instances that use non-trivial PackageInfo trickey

Best
        -Tobias




signature.asc (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Yoshiki Ohshima-3
In reply to this post by Eliot Miranda-2
Ah, yes.  It works with your version of CompiledMethod>>methodNode at
5/17/2014 17:56.


On Thu, Jul 31, 2014 at 1:41 PM, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Thu, Jul 31, 2014 at 10:34 AM, Yoshiki Ohshima <[hidden email]>
> wrote:
>>
>> Hmm, ok.  This diff has more code than it should have, but I patched
>> OMeta2 package to make it work in the new compiler regime in Squeak
>> 4.5.  Hans-Martin, do you think you can take this, and update the
>> config map (if necessary)?
>
>
> Hopefully the CompiledMethod>>methodNode override is unnecessary.
>
>
>>
>> On Thu, Jul 31, 2014 at 1:31 PM,  <[hidden email]> wrote:
>> > A new version of OMeta2-Preload was added to project The Inbox:
>> > http://source.squeak.org/inbox/OMeta2-Preload-yo.15.mcz
>> >
>> > ==================== Summary ====================
>> >
>> > Name: OMeta2-Preload-yo.15
>> > Author: yo
>> > Time: 31 July 2014, 1:29:01.319 pm
>> > UUID: 6c6bc75e-3c9f-4446-b08a-cdce7081ef2d
>> > Ancestors: OMeta2-Preload-hmm.14
>> >
>> > Adapt to Squeak 4.5.
>> >
>> > ==================== Snapshot ====================
>> >
>> > SystemOrganization addCategory: #OMeta2!
>> > SystemOrganization addCategory: #'OMeta2-Info'!
>> >
>> > ----- Method: CompiledMethod>>methodNode (in category '*OMeta2-Preload')
>> > -----
>> > methodNode
>> >         "Return the parse tree that represents self. If parsing fails,
>> > decompile the method."
>> >         | aClass source |
>> >         aClass := self methodClass.
>> >         source := self
>> >                                 getSourceFor: (self selector ifNil:
>> > [self defaultSelector])
>> >                                 in: aClass.
>> >         ^[(aClass parserClass new
>> >                 encoderClass: (self isBlueBookCompiled
>> >                                                 ifTrue: [EncoderForV3]
>> >                                                 ifFalse:
>> > [EncoderForV3PlusClosures]);
>> >                 parse: source class: aClass)
>> >                         sourceText: source;
>> >                         yourself]
>> >                 on: SyntaxErrorNotification
>> >                 do: [:ex | ex return: self decompile].!
>> >
>> > Exception subclass: #OM2Fail
>> >         instanceVariableNames: ''
>> >         classVariableNames: ''
>> >         poolDictionaries: ''
>> >         category: 'OMeta2'!
>> >
>
>
> ...
>
> --
> Aloha,
> Eliot
>
>
>



--
-- Yoshiki

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: OMeta2-Preload-yo.15.mcz

Frank Shearar-3
In reply to this post by Tobias Pape
Hm. If I do the naive thing, and run

Installer squeaksource
    project: 'OMeta';
    install: 'OMeta2'.

I get a DNU in OMeta2Compiler>>#compile:in:notifying:ifFail: that self
doesn't understand #from:class:context:notifying:.

Is this maybe behind Yoshiki's commit?

(Also, if there are any tests, and you have a handy script, I can try
get a build up & running for OMeta.)

frank

On 31 July 2014 21:43, Tobias Pape <[hidden email]> wrote:

>
> On 31.07.2014, at 22:40, Frank Shearar <[hidden email]> wrote:
>
>> On 31 July 2014 21:37, Tobias Pape <[hidden email]> wrote:
>>> Hi,
>>>
>>> On 31.07.2014, at 22:34, Yoshiki Ohshima <[hidden email]> wrote:
>>>
>>>> Hmm, ok.  This diff has more code than it should have, but I patched
>>>> OMeta2 package to make it work in the new compiler regime in Squeak
>>>> 4.5.  Hans-Martin, do you think you can take this, and update the
>>>> config map (if necessary)?
>>>
>>> The diff is that big becaus OMeta is not in the trunk repository (and hench
>>> not in the inbox).
>>>  Did you mean to commit it to http://www.squeaksource.com/OMeta ?
>>>  This is also where the config map is.
>>>
>>> Best
>>>        -Tobias
>>
>> Oh, I do like to see OMeta getting some love!
>>
>> That repo (http://www.squeaksource.com/OMeta) has _only "preload" and
>> "postload" packages. Is that right? I'd sort've expected, from the
>> names, that there would be a plain "ometa" package in the middle.
>
> It works like this:
>
> Load the config map, witch says:
>         Load the preload
>         Load the postload.
>
> The preload is:
>         “pre-compiled” Ometa in Squeak
> The postload is:
>         ometa in ometa (compiled on load by the “pre-compiled” ometa version)
>         AND: mark both packages as non-dirty
>
> BTW: this is also one of the instances that use non-trivial PackageInfo trickey
>
> Best
>         -Tobias
>
>
>
>