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!
squeak-dev@lists.squeakfoundation.org