[squeak-dev] The Inbox: OMeta2-Preload-yo.15.mcz
Yoshiki Ohshima
Yoshiki.Ohshima at acm.org
Thu Jul 31 20:34:44 UTC 2014
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, <commits at source.squeak.org> 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
More information about the Squeak-dev
mailing list
|