'From Cuis 5.0 [latest update: #3923] on 16 October 2019 at 4:15:12 pm'!

!OMeta2Compiler methodsFor: 'private-ometa2preload' stamp: 'jmv 10/16/2019 10:27:30'!
compile: origCode in: cls notifying: notify ifFail: failBlock

	| origCodeStream parseTree structuredCode translatedCode failed |
	origCodeStream := origCode asString readStream.
	self from: origCodeStream class: cls context: nil notifying: notify.
	failed := false.
	[
		parseTree := cls ometa2RuleParserClass matchStream: origCodeStream with: #rule withArgs: #() withPlaybackDebugging: false.
		parseTree := cls ometa2OptimizerClass match: parseTree with: #optimizeRule.
		structuredCode := cls ometa2RuleTranslatorClass match: parseTree with: #translate withArgs: {cls}.
		translatedCode := cls ometa2FlattenerClass match: structuredCode with: #flatten
	] on: OM2Fail do: [
		failed := true
	].
	failed ifTrue: [
		self notify: '<-- parse error around here -->' at: origCodeStream position.
		^ failBlock value ].
	^ Compiler new
		compile: translatedCode readStream
		in: cls
		notifying: notify
		ifFail: failBlock! !


!OMeta2Base methodsFor: 'ometa grammar' stamp: 'jmv 10/16/2019 10:25:33'!
not: aBlock

	| answerTrue origInput |
	origInput := input.
	answerTrue := false.
	[aBlock value] on: OM2Fail do: [
		input := origInput.
		answerTrue := true.
	].
	answerTrue ifTrue: [ ^true ].
	OM2Fail parserFailedAt: input pos! !

!OMeta2Base methodsFor: 'private' stamp: 'jmv 10/16/2019 10:19:23'!
genericMany: aBlock into: anOrderedCollection
	| continue |
	continue _ true.
	[
		| origInput |
		origInput := input.
		[anOrderedCollection addLast: aBlock value] on: OM2Fail do: [
			input := origInput.
			continue _ false.
		].
		continue
	] whileTrue.
	^ anOrderedCollection! !


!OMeta2Base class methodsFor: 'private-ometa2preload' stamp: 'jmv 10/16/2019 15:47:15'!
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.
	] on: OM2Fail do: [:e |
		| curr prev prevPrev |
		debugging ifFalse: [e pass].
		curr := input.
		prev := nil.
		prevPrev := nil.
		[curr notNil] whileTrue: [
			prevPrev := prev.
			prev := curr.
			curr := curr basicTail
		].
		curr := prevPrev ifNotNil: [prevPrev] ifNil: [prev].
		"fixme - does this add any value?
		self inform: 'will halt each time matcher reaches ', curr printString.
		"
		matcher
			initInput: input;
			forgetEverything.
		curr ifNil: [self error: 'you''ve found a bug -- please report it'].
		curr become: (OM2StreamDebugger for: curr copy).
		matcher haltingPoint: curr.
		matcher apply: #empty withArgs: args.
		ans := matcher apply: aRule.
		matcher apply: #end.
	].
	^ ans! !

