<commit_before>Class {
	#name : #ViennaAbstractFormatter,
	#superclass : #Object,
	#instVars : [
		'maxSizePerLine',
		'indent'
	],
	#classVars : [
		'DefaultMaxSizePerLine',
		'OperatorGrouping',
		'OperatorPrecedence'
	],
	#category : 'ViennaTalk-Parser-Formatters'
}

{ #category : #accessing }
ViennaAbstractFormatter class >> defaultMaxSizePerLine [
	^ DefaultMaxSizePerLine ifNil: [ DefaultMaxSizePerLine := 65 ]
]

{ #category : #accessing }
ViennaAbstractFormatter class >> defaultMaxSizePerLine: anInteger [
	DefaultMaxSizePerLine := anInteger asInteger
]

{ #category : #utilities }
ViennaAbstractFormatter class >> format: aViennaNode [
	^ self new format: aViennaNode
]

{ #category : #utilities }
ViennaAbstractFormatter class >> formatSource: aString ifError: errorBlock [
	| ast |
	ast := ViennaVDMParser new parse: aString asString.
	ast isPetitFailure
		ifTrue: [ ^ errorBlock value ].
	^ self format: ast
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initialize [
	super initialize.
	self initializeOperatorPrecedence.
	self initializeOperatorGrouping
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initializeOperatorGrouping [
	OperatorGrouping := Dictionary new
		at: 'Iterate' put: #right;
		at: 'Composition' put: #right;
		at: 'Subsequence' put: #left;
		at: 'Apply' put: #left;
		at: 'FunctionTypeInstantiation' put: #left;
		at: 'FieldSelect' put: #left;
		at: 'MapRangeRestrictedBy' put: #left;
		at: 'MapRangeRestrictedTo' put: #left;
		at: 'MapDomainRestrictedBy' put: #right;
		at: 'MapDomainRestrictedTo' put: #right;
		at: 'ArithmeticMultiplication' put: #left;
		at: 'ArithmeticDivide' put: #left;
		at: 'ArithmeticRem' put: #left;
		at: 'ArithmeticMod' put: #left;
		at: 'ArithmeticIntegerDivision' put: #left;
		at: 'ArithmeticMinus' put: #left;
		at: 'ArithmeticPlus' put: #left;
		at: 'SetDifference' put: #left;
		at: 'MapMerge' put: #left;
		at: 'MapOrSequenceModify' put: #left;
		at: 'SequenceConcatenate' put: #left;
		at: 'Imply' put: #right;
		at: 'PartialFunctionType' put: #right;
		at: 'TotalFunctionType' put: #right;
		yourself
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initializeOperatorPrecedence [
	OperatorPrecedence := Dictionary new
		at: 'Iterate' put: 52;
		at: 'Composition' put: 51;
		at: 'Subsequence' put: 40;
		at: 'Apply' put: 40;
		at: 'FunctionTypeInstantiation' put: 40;
		at: 'FieldSelect' put: 40;
		at: 'UnaryPlus' put: 36;
		at: 'UnaryMinus' put: 36;
		at: 'ArithmeticAbs' put: 36;
		at: 'Floor' put: 36;
		at: 'SetCardinality' put: 36;
		at: 'FinitePowerSet' put: 36;
		at: 'DistributedSetIntersection' put: 36;
		at: 'DistributedSetUnion' put: 36;
		at: 'MapDomain' put: 36;
		at: 'MapRange' put: 36;
		at: 'DistributedMapMerge' put: 36;
		at: 'SequenceLength' put: 36;
		at: 'SequenceElements' put: 36;
		at: 'SequenceHead' put: 36;
		at: 'SequenceTail' put: 36;
		at: 'DistributedSequenceConcatenation' put: 36;
		at: 'SequenceIndices' put: 36;
		at: 'SequenceReverse' put: 36;
		at: 'MapRangeRestrictedBy' put: 35;
		at: 'MapRangeRestrictedTo' put: 35;
		at: 'MapDomainRestrictedBy' put: 34;
		at: 'MapDomainRestrictedTo' put: 34;
		at: 'MapInverse' put: 33;
		at: 'ArithmeticMultiplication' put: 32;
		at: 'ArithmeticDivide' put: 32;
		at: 'ArithmeticRem' put: 32;
		at: 'ArithmeticMod' put: 32;
		at: 'ArithmeticIntegerDivision' put: 32;
		at: 'SetIntersection' put: 32;
		at: 'ArithmeticPlus' put: 31;
		at: 'ArithmeticMinus' put: 31;
		at: 'SetUnion' put: 31;
		at: 'SetDifference' put: 31;
		at: 'MapMerge' put: 31;
		at: 'MapOrSequenceModify' put: 31;
		at: 'SequenceConcatenate' put: 31;
		at: 'IotaExpression' put: 30;
		at: 'LessThanOrEqual' put: 21;
		at: 'LessThan' put: 21;
		at: 'GreaterThanOrEqual' put: 21;
		at: 'GreaterThan' put: 21;
		at: 'Equal' put: 21;
		at: 'NotEqual' put: 21;
		at: 'Subset' put: 21;
		at: 'ProperSubset' put: 21;
		at: 'InSet' put: 21;
		at: 'NotInSet' put: 21;
		at: 'ForallExpression' put: 10;
		at: 'ExistsExpression' put: 10;
		at: 'Exists1Expression' put: 10;
		at: 'Not' put: 15;
		at: 'And' put: 14;
		at: 'Or' put: 13;
		at: 'Imply' put: 12;
		at: 'LogicalEquivalence' put: 11;
		at: 'LambdaExpression' put: 10;
		at: 'LetExpression' put: 10;
		at: 'LetBeExpression' put: 10;
		at: 'DefExpression' put: 10;
		at: 'ForallExpression' put: 10;
		at: 'ExistsExpression' put: 10;
		at: 'Exists1Expression' put: 10;
		at: 'IfExpression' put: 10;
		at: 'IotaExpression' put: 10;
		at: 'SetType' put: 5;
		at: 'SeqType' put: 5;
		at: 'Seq1Type' put: 5;
		at: 'MapType' put: 4;
		at: 'InmapType' put: 4;
		at: 'ProductType' put: 3;
		at: 'UnionType' put: 2;
		at: 'PartialFunctionType' put: 1;
		at: 'TotalFunctionType' put: 1;
		yourself
]

{ #category : #settings }
ViennaAbstractFormatter class >> viennaSettingsOn: aBuilder [
	<systemsettings>
	(aBuilder setting: #defaultFormatWidth)
		parent: #ViennaTalkAppearances;
		target: self;
		getSelector: #defaultMaxSizePerLine;
		setSelector: #defaultMaxSizePerLine:;
		description: 'The default width to format VDM sources.';
		label: 'Format width';
		order: 0.51
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> access: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessFunctionDefinition: aViennaNode [
	^ ' ' join: ((self formatAll: aViennaNode) reject: #isEmpty)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessOperationDefinition: aViennaNode [
	^ ' ' join: ((self formatAll: aViennaNode) reject: #isEmpty)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessTypeDefinition: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessValueDefinition: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> act [
	^ '#act'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> actExpression: aViennaNode [
	^ self act, '(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> activeExpression: aViennaNode [
	^ '#active(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> alwaysStatement: aViennaNode [
	| handler statement |
	handler := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ (self needsIndent: handler)
		ifTrue: [ (self indentString: 'always' insertCr: handler) , String cr
				, (self indentString: 'in' insertCr: statement) ]
		ifFalse: [ self indentString: 'always ' , handler , ' in' insertCrIfNeeded: statement ]
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> and [
	^ 'and'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> and: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: self and arg: (self format: aViennaNode second)
]

{ #category : #private }
ViennaAbstractFormatter >> anyNeedsIndent: anArrayOfString [
	^ (anArrayOfString contains: [ :string | string includes: Character cr ])
		or: [ (anArrayOfString inject: 0 into: [ :len :str | len + (self strlen: str) ]) > self maxSizePerLine ]
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> anyType [
	^ '?'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> apply: aViennaNode [
	| expression args |
	expression := self format: aViennaNode first.
	args := self format: aViennaNode second.
	^ expression , '('
		,
			((self needsIndent: expression , args)
				ifTrue: [ String cr , indent , (self indentString: args) ]
				ifFalse: [ args ]) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticAbs: aViennaNode [
	^ 'abs ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticDivide: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '/' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticIntegerDivision: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'div' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMinus: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '-' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMod: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'mod' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMultiplication: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: self mul arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticPlus: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '+' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticRem: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'rem' arg: (self format: aViennaNode second)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> arrow [
	^ '->'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> assignStatement: aViennaNode [
	^ self indentString: (self format: aViennaNode first) insertCrIfNeeded: ':= ' , (self format: aViennaNode second)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> assignmentDefinition: aViennaNode [
	^ aViennaNode first , ':' , (self format: aViennaNode second)
		, (aViennaNode third ifNotNil: [ ' := ' , (self format: aViennaNode third) ] ifNil: [ '' ])
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> basicType: aViennaNode [
	| type |
	type := aViennaNode first.
	type = 'bool'
		ifTrue: [ ^ self bool ].
	type = 'nat'
		ifTrue: [ ^ self nat ].
	type = 'nat1'
		ifTrue: [ ^ self nat1 ].
	type = 'int'
		ifTrue: [ ^ self int ].
	type = 'real'
		ifTrue: [ ^ self real ].
	type = 'any'
		ifTrue: [ ^ self anyType ].
	^ type
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> bindList: aViennaNode [
	| binds |
	binds := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: binds)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: binds
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> blockStatement: aViennaNode [
	^ '(' , (';' , String cr join: (self formatAll: aViennaNode)) , ')'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> bool [
	^ 'bool'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> callStatement: aViennaNode [
	| args |
	args := self format: aViennaNode second.
	^ (self format: aViennaNode first) , '('
		,
			((self needsIndent: args)
				ifTrue: [ self newlineIndentString: args ]
				ifFalse: [ args ]) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpression: aViennaNode [
	| value alternatives others |
	value := self format: aViennaNode first.
	alternatives := self format: aViennaNode second.
	others := aViennaNode third ifNil: [ '' ] ifNotNil: [ :node | ',' , String cr , (self format: node) ].
	^ self
		indentString:
			'cases ' , (self format: aViennaNode first) , ':' , String cr , (self format: aViennaNode second) , others , String cr
				, 'end'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpressionAlternative: aViennaNode [
	| patternList expression |
	patternList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self indentString: patternList , ' ', self arrow insertCrIfNeeded: expression
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpressionAlternatives: aViennaNode [
	^ ',' , String cr join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatement: aViennaNode [
	| value alternatives others |
	value := self format: aViennaNode first.
	alternatives := self format: aViennaNode second.
	others := aViennaNode third ifNil: [ '' ] ifNotNil: [ :node | ',' , String cr , (self format: node) ].
	^ self
		indentString:
			'cases ' , (self format: aViennaNode first) , ':' , String cr , (self format: aViennaNode second) , others , String cr
				, 'end'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatementAlternative: aViennaNode [
	| patternList statement |
	patternList := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ self indentString: patternList , ' ', self arrow insertCrIfNeeded: statement
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatementAlternatives: aViennaNode [
	^ ',' , String cr join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> compositeType: aViennaNode [
	| constructor fields |
	constructor := self format: aViennaNode first.
	fields := self format: aViennaNode second.
	^ self
		noIndentString: (self indentString: 'compose ' , constructor , ' of' insertCrIfNeeded: fields)
		insertCrIfNeeded: 'end'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> composition: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'comp' arg: (self format: aViennaNode second)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> concat [
	^ '^'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> conditionalExpression: aViennaNode [
	^ 'elseif ' , (self indentString: (self format: aViennaNode first)) , String cr , indent , 'then '
		, (self indentString: (self format: aViennaNode second))
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> conditionalStatement: aViennaNode [
	^ 'elseif ' , (self indentString: (self format: aViennaNode first)) , String cr , indent , 'then '
		, (self indentString: (self format: aViennaNode second))
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> dclStatement: aViennaNode [
	| assigns |
	assigns := self formatAll: aViennaNode.
	^ 'dcl'
		,
			((self anyNeedsIndent: assigns)
				ifTrue: [ 
					String cr , indent
						, (self indentAllStrings: assigns withSeparator: ',') ]
				ifFalse: [ String space , (', ' join: assigns) ])
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> defExpression: aViennaNode [
	| defs expression |
	defs := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: 'def' insertCrIfNeeded: defs)
		insertCrIfNeeded: (self indentString: 'in' insertCrIfNeeded: expression)
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> defStatement: aViennaNode [
	| equalDefinitionList statement |
	equalDefinitionList := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ self
		noIndentString: (self indentString: 'def' insertCrIfNeeded: equalDefinitionList)
		insertCrIfNeeded: (self indentString: 'in' insertCrIfNeeded: statement)
]

{ #category : #defaults }
ViennaAbstractFormatter >> defaultIndent [
	^ '    '
]

{ #category : #defaults }
ViennaAbstractFormatter >> defaultMaxSizePerLine [
	^ self class defaultMaxSizePerLine
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> definitionBlock: aViennaNode [
	^ (self format: aViennaNode first) , String cr
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dinter [
	^ 'dinter'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedMapMerge: aViennaNode [
	^ 'merge ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSequenceConcatenation: aViennaNode [
	^ 'conc ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSetIntersection: aViennaNode [
	^ self dinter , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSetUnion: aViennaNode [
	^ self dunion , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> document: aViennaNode [
	^ String cr join: (self formatAll: aViennaNode)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> domainRestrictedBy [
	^ '<-:'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> domainRestrictedTo [
	^ '<:'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dot [
	^ '&'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dots [
	^ '...'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dunion [
	^ 'dunion'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> equal: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '=' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> equalDefinition: aViennaNode [
	| patternBind expression |
	patternBind := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self indentString: patternBind , ' =' insertCrIfNeeded: expression
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> equalDefinitionList: aViennaNode [
	| defs |
	defs := self formatAll: aViennaNode.
	^ (';' , String cr join: defs) , ';'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> equiv [
	^ '<=>'
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> error: aViennaNode [
	^ aViennaNode first , ':' , (self format: aViennaNode second) , '->'
		, (self format: aViennaNode third)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> errorList: aViennaNode [
	^ String
		new: 1024
		streamContents: [ :stream | 
			aViennaNode
				do: [ :node | 
					stream
						space;
						nextPutAll: (self format: node) ] ]
]

{ #category : #private }
ViennaAbstractFormatter >> escapeString: aString [
	^ aString
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> exceptions: aViennaNode [
	^ 'errs' , (self format: aViennaNode first)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> exists [
	^ 'exists'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> exists1 [
	^ 'exists1'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> exists1Expression: aViennaNode [
	| bind expression |
	bind := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self exists1 insertCrIfNeeded: bind , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> existsExpression: aViennaNode [
	| bindList expression |
	bindList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self exists insertCrIfNeeded: bindList trim , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> exitStatement: aViennaNode [
	^ 'exit ' , (self indentString: (self format: aViennaNode first))
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> explicitFunctionDefinition: aViennaNode [
	| identifier1 typeVariableList functionType identifier2 parametersList expression pre post measure |
	identifier1 := self format: aViennaNode first.
	typeVariableList := self format: aViennaNode second.
	functionType := self format: aViennaNode third.
	identifier2 := self format: aViennaNode fourth.
	parametersList := self format: aViennaNode fifth.
	expression := self format: aViennaNode sixth.
	pre := aViennaNode seventh ifNotNil: [ :node | String cr , 'pre ' , (self format: node) ] ifNil: [ '' ].
	post := aViennaNode eighth ifNotNil: [ :node | String cr , 'post ' , (self format: node) ] ifNil: [ '' ].
	measure := aViennaNode ninth ifNotNil: [ :node | String cr , 'measure ' , (self format: node) ] ifNil: [ '' ].
	^ identifier1 , typeVariableList , ' : ' , functionType , String cr
		, (self indentString: identifier2 , parametersList , ' ==' insertCrIfNeeded: expression) , pre , post , measure
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> explicitOperationDefinition: aViennaNode [
	| identifier1 operationType identifier2 parameters expression pre post |
	identifier1 := self format: aViennaNode first.
	operationType := self format: aViennaNode second.
	identifier2 := self format: aViennaNode third.
	parameters := self format: aViennaNode fourth.
	expression := self format: aViennaNode fifth.
	pre := aViennaNode sixth
		ifNotNil: [ :node | String cr , (self indentString: 'pre ' insertCrIfNeeded: (self format: node)) ]
		ifNil: [ '' ].
	post := aViennaNode seventh
		ifNotNil: [ :node | String cr , (self indentString: 'post ' insertCrIfNeeded: (self format: node)) ]
		ifNil: [ '' ].
	^ identifier1 , ' : ' , operationType , String cr
		, (self indentString: identifier2 , parameters , ' ==' insertCrIfNeeded: expression) , pre , post
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportDefinition: aViennaNode [
	| exportSig |
	exportSig := self format: aViennaNode first.
	^ self indentString: 'exports' insertCrIfNeeded: exportSig
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportFunctionsSignature: aViennaNode [
	| functionExports |
	functionExports := self formatAll: aViennaNode.
	^ self indentString: 'functions' insertCrIfNeeded: (';' , String cr join: functionExports) , ';'
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportModuleSignatrueAll: aViennaNode [
	^ 'all'
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportModuleSignature: aViennaNode [
	| exportSignatures |
	exportSignatures := self formatAll: aViennaNode.
	^ String cr join: exportSignatures
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportTypesSignature: aViennaNode [
	| typeExports |
	typeExports := self formatAll: aViennaNode.
	^ self indentString: 'types' insertCrIfNeeded: (';' , String cr join: typeExports) , ';'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> expressionList: aViennaNode [
	| expressions |
	expressions := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: expressions)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: expressions
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> extendedExplicitFunctionDefinition: aViennaNode [
	| identifier typeVariableList parameterTypes identifierTypePairList body pre post |
	identifier := aViennaNode first.
	typeVariableList := aViennaNode second.
	parameterTypes := aViennaNode third.
	identifierTypePairList := aViennaNode fourth.
	body := aViennaNode fifth.
	pre := aViennaNode sixth.
	post := aViennaNode seventh.
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream
				nextPutAll: (self format: identifier);
				nextPutAll: (self format: typeVariableList);
				nextPutAll: (self format: parameterTypes);
				nextPutAll: (self format: identifierTypePairList);
				nextPutAll: ' ==';
				cr;
				nextPutAll: indent;
				nextPutAll: (self indentString: (self format: body)).
			pre
				ifNotNil: [ stream
						cr;
						nextPutAll: 'pre ';
						nextPutAll: (self format: pre) ].
			stream
				cr;
				nextPutAll: 'post ';
				nextPutAll: (self format: post) ]
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> extendedExplicitOperationDefinition: aViennaNode [
	| identifier parameterTypes identifierTypePairList body externals pre post exceptions |
	identifier := aViennaNode first.
	parameterTypes := aViennaNode second.
	identifierTypePairList := aViennaNode third.
	body := aViennaNode fourth.
	externals := aViennaNode fifth.
	pre := aViennaNode sixth.
	post := aViennaNode seventh.
	exceptions := aViennaNode eighth.
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream
				nextPutAll: (self format: identifier);
				nextPutAll: (self format: parameterTypes);
				nextPutAll: (self format: identifierTypePairList);
				nextPutAll: ' ==';
				cr;
				nextPutAll: indent;
				nextPutAll: (self indentString: (self format: body)).
			externals
				ifNotNil: [ stream
						cr;
						nextPutAll: (self format: externals) ].
			pre
				ifNotNil: [ stream
						cr;
						nextPutAll: 'pre ';
						nextPutAll: (self format: pre) ].
			stream
				cr;
				nextPutAll: 'post ';
				nextPutAll: (self format: post).
			exceptions
				ifNotNil: [ stream
						cr;
						nextPutAll: (self format: exceptions) ] ]
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> externals: aViennaNode [
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream nextPutAll: 'ext'.
			aViennaNode
				do: [ :varInfo | 
					stream
						space;
						nextPutAll: (self format: varInfo) ] ]
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> field: aViennaNode [
	| name equalityAbstraction type |
	name := aViennaNode first.
	equalityAbstraction := aViennaNode second.
	type := self format: aViennaNode third.
	^ (name
		ifNil: [ '' ]
		ifNotNil: [ 
			name
				,
					(equalityAbstraction
						ifTrue: [ ' :- ' ]
						ifFalse: [ ' : ' ]) ]) , type
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> fieldList: aViennaNode [
	| fields |
	fields := self formatAll: aViennaNode.
	^ ((self anyNeedsIndent: fields)
		ifTrue: [ String cr ]
		ifFalse: [ String space ]) join: fields
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> fieldPattern: aViennaNode [
	| identifier pattern |
	identifier := self format: aViennaNode first.
	pattern := self format: aViennaNode second.
	^ identifier , ' ', self maplet, ' ', pattern
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> fieldPatternList: aViennaNode [
	| fieldPatterns |
	fieldPatterns := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: fieldPatterns)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: fieldPatterns
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> fieldReference: aViennaNode [
	| stateDesignator field |
	stateDesignator := self format: aViennaNode first.
	field := self format: aViennaNode second.
	^ self indentString: stateDesignator insertCrIfNeeded: '.' , field
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> fieldSelect: aViennaNode [
	| record field |
	record := self format: aViennaNode first.
	field := self format: aViennaNode second.
	^ record , '.' , field
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> finExpression: aViennaNode [
	^ '#fin(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> finitePowerSet: aViennaNode [
	^ self power , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> floor: aViennaNode [
	^ 'floor ' , (self format: aViennaNode first)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> forall [
	^ 'forall'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> forallExpression: aViennaNode [
	| bindList expression |
	bindList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self forall insertCrIfNeeded: bindList trim , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #formatting }
ViennaAbstractFormatter >> format: aViennaNode [
	| string |
	aViennaNode isString
		ifTrue: [ ^ aViennaNode ].
	string := self perform: (aViennaNode label uncapitalized , ':') asSymbol with: aViennaNode.
	self needsParen
		ifTrue: [ string := '(' , (self indentString: string) , ')' ].
	^ string asViennaTracingString: aViennaNode
]

{ #category : #formatting }
ViennaAbstractFormatter >> formatAll: aViennaNodeOrArray [
	| array |
	array := Array new: aViennaNodeOrArray size.
	1 to: array size do: [ :i | array at: i put: (self format: (aViennaNodeOrArray at: i)) ].
	^ array
]

{ #category : #private }
ViennaAbstractFormatter >> formatEnumerate: anArrayOfString ifEmpty: aBlock [
	^ self formatEnumerate: anArrayOfString separator: ',' ifEmpty: aBlock
]

{ #category : #private }
ViennaAbstractFormatter >> formatEnumerate: anArrayOfString separator: aString ifEmpty: aBlock [
	| lines |
	anArrayOfString size = 0
		ifTrue: [ ^ aBlock value ].
	lines := Array
		new: anArrayOfString size
		streamContents: [ :stream | 
			| line |
			line := anArrayOfString first.<commit_msg>moving ViennaTalk-Parsers-Code Generators to ViennaTalk-Transpiler-Core, -Debugger, -Runtime.<commit_after>Class {
	#name : #ViennaAbstractFormatter,
	#superclass : #Object,
	#instVars : [
		'maxSizePerLine',
		'indent'
	],
	#classVars : [
		'DefaultMaxSizePerLine',
		'OperatorGrouping',
		'OperatorPrecedence'
	],
	#category : 'ViennaTalk-Parser-Formatters'
}

{ #category : #accessing }
ViennaAbstractFormatter class >> defaultMaxSizePerLine [
	^ DefaultMaxSizePerLine ifNil: [ DefaultMaxSizePerLine := 65 ]
]

{ #category : #accessing }
ViennaAbstractFormatter class >> defaultMaxSizePerLine: anInteger [
	DefaultMaxSizePerLine := anInteger asInteger
]

{ #category : #utilities }
ViennaAbstractFormatter class >> format: aViennaNode [
	^ self new format: aViennaNode
]

{ #category : #utilities }
ViennaAbstractFormatter class >> formatSource: aString ifError: errorBlock [
	| ast |
	ast := ViennaVDMParser new parse: aString asString.
	ast isPetitFailure
		ifTrue: [ ^ errorBlock value ].
	^ self format: ast
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initialize [
	super initialize.
	self initializeOperatorPrecedence.
	self initializeOperatorGrouping
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initializeOperatorGrouping [
	OperatorGrouping := Dictionary new
		at: 'Iterate' put: #right;
		at: 'Composition' put: #right;
		at: 'Subsequence' put: #left;
		at: 'Apply' put: #left;
		at: 'FunctionTypeInstantiation' put: #left;
		at: 'FieldSelect' put: #left;
		at: 'MapRangeRestrictedBy' put: #left;
		at: 'MapRangeRestrictedTo' put: #left;
		at: 'MapDomainRestrictedBy' put: #right;
		at: 'MapDomainRestrictedTo' put: #right;
		at: 'ArithmeticMultiplication' put: #left;
		at: 'ArithmeticDivide' put: #left;
		at: 'ArithmeticRem' put: #left;
		at: 'ArithmeticMod' put: #left;
		at: 'ArithmeticIntegerDivision' put: #left;
		at: 'ArithmeticMinus' put: #left;
		at: 'ArithmeticPlus' put: #left;
		at: 'SetDifference' put: #left;
		at: 'MapMerge' put: #left;
		at: 'MapOrSequenceModify' put: #left;
		at: 'SequenceConcatenate' put: #left;
		at: 'Imply' put: #right;
		at: 'PartialFunctionType' put: #right;
		at: 'TotalFunctionType' put: #right;
		yourself
]

{ #category : #'class initialization' }
ViennaAbstractFormatter class >> initializeOperatorPrecedence [
	OperatorPrecedence := Dictionary new
		at: 'Iterate' put: 52;
		at: 'Composition' put: 51;
		at: 'Subsequence' put: 40;
		at: 'Apply' put: 40;
		at: 'FunctionTypeInstantiation' put: 40;
		at: 'FieldSelect' put: 40;
		at: 'UnaryPlus' put: 36;
		at: 'UnaryMinus' put: 36;
		at: 'ArithmeticAbs' put: 36;
		at: 'Floor' put: 36;
		at: 'SetCardinality' put: 36;
		at: 'FinitePowerSet' put: 36;
		at: 'DistributedSetIntersection' put: 36;
		at: 'DistributedSetUnion' put: 36;
		at: 'MapDomain' put: 36;
		at: 'MapRange' put: 36;
		at: 'DistributedMapMerge' put: 36;
		at: 'SequenceLength' put: 36;
		at: 'SequenceElements' put: 36;
		at: 'SequenceHead' put: 36;
		at: 'SequenceTail' put: 36;
		at: 'DistributedSequenceConcatenation' put: 36;
		at: 'SequenceIndices' put: 36;
		at: 'SequenceReverse' put: 36;
		at: 'MapRangeRestrictedBy' put: 35;
		at: 'MapRangeRestrictedTo' put: 35;
		at: 'MapDomainRestrictedBy' put: 34;
		at: 'MapDomainRestrictedTo' put: 34;
		at: 'MapInverse' put: 33;
		at: 'ArithmeticMultiplication' put: 32;
		at: 'ArithmeticDivide' put: 32;
		at: 'ArithmeticRem' put: 32;
		at: 'ArithmeticMod' put: 32;
		at: 'ArithmeticIntegerDivision' put: 32;
		at: 'SetIntersection' put: 32;
		at: 'ArithmeticPlus' put: 31;
		at: 'ArithmeticMinus' put: 31;
		at: 'SetUnion' put: 31;
		at: 'SetDifference' put: 31;
		at: 'MapMerge' put: 31;
		at: 'MapOrSequenceModify' put: 31;
		at: 'SequenceConcatenate' put: 31;
		at: 'IotaExpression' put: 30;
		at: 'LessThanOrEqual' put: 21;
		at: 'LessThan' put: 21;
		at: 'GreaterThanOrEqual' put: 21;
		at: 'GreaterThan' put: 21;
		at: 'Equal' put: 21;
		at: 'NotEqual' put: 21;
		at: 'Subset' put: 21;
		at: 'ProperSubset' put: 21;
		at: 'InSet' put: 21;
		at: 'NotInSet' put: 21;
		at: 'ForallExpression' put: 10;
		at: 'ExistsExpression' put: 10;
		at: 'Exists1Expression' put: 10;
		at: 'Not' put: 15;
		at: 'And' put: 14;
		at: 'Or' put: 13;
		at: 'Imply' put: 12;
		at: 'LogicalEquivalence' put: 11;
		at: 'LambdaExpression' put: 10;
		at: 'LetExpression' put: 10;
		at: 'LetBeExpression' put: 10;
		at: 'DefExpression' put: 10;
		at: 'ForallExpression' put: 10;
		at: 'ExistsExpression' put: 10;
		at: 'Exists1Expression' put: 10;
		at: 'IfExpression' put: 10;
		at: 'IotaExpression' put: 10;
		at: 'SetType' put: 5;
		at: 'SeqType' put: 5;
		at: 'Seq1Type' put: 5;
		at: 'MapType' put: 4;
		at: 'InmapType' put: 4;
		at: 'ProductType' put: 3;
		at: 'UnionType' put: 2;
		at: 'PartialFunctionType' put: 1;
		at: 'TotalFunctionType' put: 1;
		yourself
]

{ #category : #settings }
ViennaAbstractFormatter class >> viennaSettingsOn: aBuilder [
	<systemsettings>
	(aBuilder setting: #defaultFormatWidth)
		parent: #ViennaTalkAppearances;
		target: self;
		getSelector: #defaultMaxSizePerLine;
		setSelector: #defaultMaxSizePerLine:;
		description: 'The default width to format VDM sources.';
		label: 'Format width';
		order: 0.51
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> access: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessFunctionDefinition: aViennaNode [
	^ ' ' join: ((self formatAll: aViennaNode) reject: #isEmpty)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessOperationDefinition: aViennaNode [
	^ ' ' join: ((self formatAll: aViennaNode) reject: #isEmpty)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessTypeDefinition: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> accessValueDefinition: aViennaNode [
	^ ' ' join: (self formatAll: aViennaNode)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> act [
	^ '#act'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> actExpression: aViennaNode [
	^ self act, '(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> activeExpression: aViennaNode [
	^ '#active(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> alwaysStatement: aViennaNode [
	| handler statement |
	handler := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ (self needsIndent: handler)
		ifTrue: [ (self indentString: 'always' insertCr: handler) , String cr
				, (self indentString: 'in' insertCr: statement) ]
		ifFalse: [ self indentString: 'always ' , handler , ' in' insertCrIfNeeded: statement ]
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> and [
	^ 'and'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> and: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: self and arg: (self format: aViennaNode second)
]

{ #category : #private }
ViennaAbstractFormatter >> anyNeedsIndent: anArrayOfString [
	^ (anArrayOfString contains: [ :string | string includes: Character cr ])
		or: [ (anArrayOfString inject: 0 into: [ :len :str | len + (self strlen: str) ]) > self maxSizePerLine ]
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> anyType [
	^ '?'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> apply: aViennaNode [
	| expression args |
	expression := self format: aViennaNode first.
	args := self format: aViennaNode second.
	^ expression , '('
		,
			((self needsIndent: expression , args)
				ifTrue: [ String cr , indent , (self indentString: args) ]
				ifFalse: [ args ]) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticAbs: aViennaNode [
	^ 'abs ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticDivide: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '/' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticIntegerDivision: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'div' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMinus: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '-' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMod: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'mod' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticMultiplication: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: self mul arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticPlus: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '+' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> arithmeticRem: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'rem' arg: (self format: aViennaNode second)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> arrow [
	^ '->'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> assignStatement: aViennaNode [
	^ self indentString: (self format: aViennaNode first) insertCrIfNeeded: ':= ' , (self format: aViennaNode second)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> assignmentDefinition: aViennaNode [
	^ aViennaNode first , ':' , (self format: aViennaNode second)
		, (aViennaNode third ifNotNil: [ ' := ' , (self format: aViennaNode third) ] ifNil: [ '' ])
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> basicType: aViennaNode [
	| type |
	type := aViennaNode first.
	type = 'bool'
		ifTrue: [ ^ self bool ].
	type = 'nat'
		ifTrue: [ ^ self nat ].
	type = 'nat1'
		ifTrue: [ ^ self nat1 ].
	type = 'int'
		ifTrue: [ ^ self int ].
	type = 'real'
		ifTrue: [ ^ self real ].
	type = 'any'
		ifTrue: [ ^ self anyType ].
	^ type
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> bindList: aViennaNode [
	| binds |
	binds := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: binds)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: binds
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> blockStatement: aViennaNode [
	^ '(' , (';' , String cr join: (self formatAll: aViennaNode)) , ')'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> bool [
	^ 'bool'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> callStatement: aViennaNode [
	| args |
	args := self format: aViennaNode second.
	^ (self format: aViennaNode first) , '('
		,
			((self needsIndent: args)
				ifTrue: [ self newlineIndentString: args ]
				ifFalse: [ args ]) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpression: aViennaNode [
	| value alternatives others |
	value := self format: aViennaNode first.
	alternatives := self format: aViennaNode second.
	others := aViennaNode third ifNil: [ '' ] ifNotNil: [ :node | ',' , String cr , (self format: node) ].
	^ self
		indentString:
			'cases ' , (self format: aViennaNode first) , ':' , String cr , (self format: aViennaNode second) , others , String cr
				, 'end'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpressionAlternative: aViennaNode [
	| patternList expression |
	patternList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self indentString: patternList , ' ', self arrow insertCrIfNeeded: expression
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> casesExpressionAlternatives: aViennaNode [
	^ ',' , String cr join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatement: aViennaNode [
	| value alternatives others |
	value := self format: aViennaNode first.
	alternatives := self format: aViennaNode second.
	others := aViennaNode third ifNil: [ '' ] ifNotNil: [ :node | ',' , String cr , (self format: node) ].
	^ self
		indentString:
			'cases ' , (self format: aViennaNode first) , ':' , String cr , (self format: aViennaNode second) , others , String cr
				, 'end'
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatementAlternative: aViennaNode [
	| patternList statement |
	patternList := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ self indentString: patternList , ' ', self arrow insertCrIfNeeded: statement
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> casesStatementAlternatives: aViennaNode [
	^ ',' , String cr join: (self formatAll: aViennaNode)
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> compositeType: aViennaNode [
	| constructor fields |
	constructor := self format: aViennaNode first.
	fields := self format: aViennaNode second.
	^ self
		noIndentString: (self indentString: 'compose ' , constructor , ' of' insertCrIfNeeded: fields)
		insertCrIfNeeded: 'end'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> composition: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: 'comp' arg: (self format: aViennaNode second)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> concat [
	^ '^'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> conditionalExpression: aViennaNode [
	^ 'elseif ' , (self indentString: (self format: aViennaNode first)) , String cr , indent , 'then '
		, (self indentString: (self format: aViennaNode second))
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> conditionalStatement: aViennaNode [
	^ 'elseif ' , (self indentString: (self format: aViennaNode first)) , String cr , indent , 'then '
		, (self indentString: (self format: aViennaNode second))
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> dclStatement: aViennaNode [
	| assigns |
	assigns := self formatAll: aViennaNode.
	^ 'dcl'
		,
			((self anyNeedsIndent: assigns)
				ifTrue: [ 
					String cr , indent
						, (self indentAllStrings: assigns withSeparator: ',') ]
				ifFalse: [ String space , (', ' join: assigns) ])
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> defExpression: aViennaNode [
	| defs expression |
	defs := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: 'def' insertCrIfNeeded: defs)
		insertCrIfNeeded: (self indentString: 'in' insertCrIfNeeded: expression)
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> defStatement: aViennaNode [
	| equalDefinitionList statement |
	equalDefinitionList := self format: aViennaNode first.
	statement := self format: aViennaNode second.
	^ self
		noIndentString: (self indentString: 'def' insertCrIfNeeded: equalDefinitionList)
		insertCrIfNeeded: (self indentString: 'in' insertCrIfNeeded: statement)
]

{ #category : #defaults }
ViennaAbstractFormatter >> defaultIndent [
	^ '    '
]

{ #category : #defaults }
ViennaAbstractFormatter >> defaultMaxSizePerLine [
	^ self class defaultMaxSizePerLine
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> definitionBlock: aViennaNode [
	^ (self format: aViennaNode first) , String cr
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dinter [
	^ 'dinter'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedMapMerge: aViennaNode [
	^ 'merge ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSequenceConcatenation: aViennaNode [
	^ 'conc ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSetIntersection: aViennaNode [
	^ self dinter , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> distributedSetUnion: aViennaNode [
	^ self dunion , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> document: aViennaNode [
	^ String cr join: (self formatAll: aViennaNode)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> domainRestrictedBy [
	^ '<-:'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> domainRestrictedTo [
	^ '<:'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dot [
	^ '&'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dots [
	^ '...'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> dunion [
	^ 'dunion'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> equal: aViennaNode [
	^ self print: (self format: aViennaNode first) infix: '=' arg: (self format: aViennaNode second)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> equalDefinition: aViennaNode [
	| patternBind expression |
	patternBind := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self indentString: patternBind , ' =' insertCrIfNeeded: expression
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> equalDefinitionList: aViennaNode [
	| defs |
	defs := self formatAll: aViennaNode.
	^ (';' , String cr join: defs) , ';'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> equiv [
	^ '<=>'
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> error: aViennaNode [
	^ aViennaNode first , ':' , (self format: aViennaNode second) , '->'
		, (self format: aViennaNode third)
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> errorList: aViennaNode [
	^ String
		new: 1024
		streamContents: [ :stream | 
			aViennaNode
				do: [ :node | 
					stream
						space;
						nextPutAll: (self format: node) ] ]
]

{ #category : #private }
ViennaAbstractFormatter >> escapeString: aString [
	^ aString
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> exceptions: aViennaNode [
	^ 'errs' , (self format: aViennaNode first)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> exists [
	^ 'exists'
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> exists1 [
	^ 'exists1'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> exists1Expression: aViennaNode [
	| bind expression |
	bind := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self exists1 insertCrIfNeeded: bind , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> existsExpression: aViennaNode [
	| bindList expression |
	bindList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self exists insertCrIfNeeded: bindList trim , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> exitStatement: aViennaNode [
	^ 'exit ' , (self indentString: (self format: aViennaNode first))
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> explicitFunctionDefinition: aViennaNode [
	| identifier1 typeVariableList functionType identifier2 parametersList expression pre post measure |
	identifier1 := self format: aViennaNode first.
	typeVariableList := self format: aViennaNode second.
	functionType := self format: aViennaNode third.
	identifier2 := self format: aViennaNode fourth.
	parametersList := self format: aViennaNode fifth.
	expression := self format: aViennaNode sixth.
	pre := aViennaNode seventh ifNotNil: [ :node | String cr , 'pre ' , (self format: node) ] ifNil: [ '' ].
	post := aViennaNode eighth ifNotNil: [ :node | String cr , 'post ' , (self format: node) ] ifNil: [ '' ].
	measure := aViennaNode ninth ifNotNil: [ :node | String cr , 'measure ' , (self format: node) ] ifNil: [ '' ].
	^ identifier1 , typeVariableList , ' : ' , functionType , String cr
		, (self indentString: identifier2 , parametersList , ' ==' insertCrIfNeeded: expression) , pre , post , measure
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> explicitOperationDefinition: aViennaNode [
	| identifier1 operationType identifier2 parameters expression pre post |
	identifier1 := self format: aViennaNode first.
	operationType := self format: aViennaNode second.
	identifier2 := self format: aViennaNode third.
	parameters := self format: aViennaNode fourth.
	expression := self format: aViennaNode fifth.
	pre := aViennaNode sixth
		ifNotNil: [ :node | String cr , (self indentString: 'pre ' insertCrIfNeeded: (self format: node)) ]
		ifNil: [ '' ].
	post := aViennaNode seventh
		ifNotNil: [ :node | String cr , (self indentString: 'post ' insertCrIfNeeded: (self format: node)) ]
		ifNil: [ '' ].
	^ identifier1 , ' : ' , operationType , String cr
		, (self indentString: identifier2 , parameters , ' ==' insertCrIfNeeded: expression) , pre , post
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportDefinition: aViennaNode [
	| exportSig |
	exportSig := self format: aViennaNode first.
	^ self indentString: 'exports' insertCrIfNeeded: exportSig
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportFunctionsSignature: aViennaNode [
	| functionExports |
	functionExports := self formatAll: aViennaNode.
	^ self indentString: 'functions' insertCrIfNeeded: (';' , String cr join: functionExports) , ';'
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportModuleSignatrueAll: aViennaNode [
	^ 'all'
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportModuleSignature: aViennaNode [
	| exportSignatures |
	exportSignatures := self formatAll: aViennaNode.
	^ String cr join: exportSignatures
]

{ #category : #'formatting-interfaces' }
ViennaAbstractFormatter >> exportTypesSignature: aViennaNode [
	| typeExports |
	typeExports := self formatAll: aViennaNode.
	^ self indentString: 'types' insertCrIfNeeded: (';' , String cr join: typeExports) , ';'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> expressionList: aViennaNode [
	| expressions |
	expressions := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: expressions)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: expressions
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> extendedExplicitFunctionDefinition: aViennaNode [
	| identifier typeVariableList parameterTypes identifierTypePairList body pre post |
	identifier := aViennaNode first.
	typeVariableList := aViennaNode second.
	parameterTypes := aViennaNode third.
	identifierTypePairList := aViennaNode fourth.
	body := aViennaNode fifth.
	pre := aViennaNode sixth.
	post := aViennaNode seventh.
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream
				nextPutAll: (self format: identifier);
				nextPutAll: (self format: typeVariableList);
				nextPutAll: (self format: parameterTypes);
				nextPutAll: (self format: identifierTypePairList);
				nextPutAll: ' ==';
				cr;
				nextPutAll: indent;
				nextPutAll: (self indentString: (self format: body)).
			pre
				ifNotNil: [ stream
						cr;
						nextPutAll: 'pre ';
						nextPutAll: (self format: pre) ].
			stream
				cr;
				nextPutAll: 'post ';
				nextPutAll: (self format: post) ]
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> extendedExplicitOperationDefinition: aViennaNode [
	| identifier parameterTypes identifierTypePairList body externals pre post exceptions |
	identifier := aViennaNode first.
	parameterTypes := aViennaNode second.
	identifierTypePairList := aViennaNode third.
	body := aViennaNode fourth.
	externals := aViennaNode fifth.
	pre := aViennaNode sixth.
	post := aViennaNode seventh.
	exceptions := aViennaNode eighth.
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream
				nextPutAll: (self format: identifier);
				nextPutAll: (self format: parameterTypes);
				nextPutAll: (self format: identifierTypePairList);
				nextPutAll: ' ==';
				cr;
				nextPutAll: indent;
				nextPutAll: (self indentString: (self format: body)).
			externals
				ifNotNil: [ stream
						cr;
						nextPutAll: (self format: externals) ].
			pre
				ifNotNil: [ stream
						cr;
						nextPutAll: 'pre ';
						nextPutAll: (self format: pre) ].
			stream
				cr;
				nextPutAll: 'post ';
				nextPutAll: (self format: post).
			exceptions
				ifNotNil: [ stream
						cr;
						nextPutAll: (self format: exceptions) ] ]
]

{ #category : #'formatting-definitions' }
ViennaAbstractFormatter >> externals: aViennaNode [
	^ String
		new: 1024
		streamContents: [ :stream | 
			stream nextPutAll: 'ext'.
			aViennaNode
				do: [ :varInfo | 
					stream
						space;
						nextPutAll: (self format: varInfo) ] ]
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> field: aViennaNode [
	| name equalityAbstraction type |
	name := aViennaNode first.
	equalityAbstraction := aViennaNode second.
	type := self format: aViennaNode third.
	^ (name
		ifNil: [ '' ]
		ifNotNil: [ 
			name
				,
					(equalityAbstraction
						ifTrue: [ ' :- ' ]
						ifFalse: [ ' : ' ]) ]) , type
]

{ #category : #'formatting-types' }
ViennaAbstractFormatter >> fieldList: aViennaNode [
	| fields |
	fields := self formatAll: aViennaNode.
	^ ((self anyNeedsIndent: fields)
		ifTrue: [ String cr ]
		ifFalse: [ String space ]) join: fields
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> fieldPattern: aViennaNode [
	| identifier pattern |
	identifier := self format: aViennaNode first.
	pattern := self format: aViennaNode second.
	^ identifier , ' ', self maplet, ' ', pattern
]

{ #category : #'formatting-patterns and binds' }
ViennaAbstractFormatter >> fieldPatternList: aViennaNode [
	| fieldPatterns |
	fieldPatterns := self formatAll: aViennaNode.
	^ ','
		,
			((self anyNeedsIndent: fieldPatterns)
				ifTrue: [ String cr ]
				ifFalse: [ String space ]) join: fieldPatterns
]

{ #category : #'formatting-statements' }
ViennaAbstractFormatter >> fieldReference: aViennaNode [
	| stateDesignator field |
	stateDesignator := self format: aViennaNode first.
	field := self format: aViennaNode second.
	^ self indentString: stateDesignator insertCrIfNeeded: '.' , field
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> fieldSelect: aViennaNode [
	| record field |
	record := self format: aViennaNode first.
	field := self format: aViennaNode second.
	^ record , '.' , field
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> finExpression: aViennaNode [
	^ '#fin(' , ', ' join: (self formatAll: aViennaNode) , ')'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> finitePowerSet: aViennaNode [
	^ self power , ' ' , (self format: aViennaNode first)
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> floor: aViennaNode [
	^ 'floor ' , (self format: aViennaNode first)
]

{ #category : #'symbol access' }
ViennaAbstractFormatter >> forall [
	^ 'forall'
]

{ #category : #'formatting-expressions' }
ViennaAbstractFormatter >> forallExpression: aViennaNode [
	| bindList expression |
	bindList := self format: aViennaNode first.
	expression := self format: aViennaNode second.
	^ self
		indentString: (self indentString: self forall insertCrIfNeeded: bindList trim , ' ' , self dot)
		insertCrIfNeeded: expression
]

{ #category : #formatting }
ViennaAbstractFormatter >> format: aViennaNode [
	| string |
	aViennaNode isString
		ifTrue: [ ^ aViennaNode ].
	string := self perform: (aViennaNode label uncapitalized , ':') asSymbol with: aViennaNode.
	self needsParen
		ifTrue: [ string := '(' , (self indentString: string) , ')' ].
	^ string
]

{ #category : #formatting }
ViennaAbstractFormatter >> formatAll: aViennaNodeOrArray [
	| array |
	array := Array new: aViennaNodeOrArray size.
	1 to: array size do: [ :i | array at: i put: (self format: (aViennaNodeOrArray at: i)) ].
	^ array
]

{ #category : #private }
ViennaAbstractFormatter >> formatEnumerate: anArrayOfString ifEmpty: aBlock [
	^ self formatEnumerate: anArrayOfString separator: ',' ifEmpty: aBlock
]

{ #category : #private }
ViennaAbstractFormatter >> formatEnumerate: anArrayOfString separator: aString ifEmpty: aBlock [
	| lines |
	anArrayOfString size = 0
		ifTrue: [ ^ aBlock value ].
	lines := Array
		new: anArrayOfString size
		streamContents: [ :stream | 
			| line |
			line := anArrayOfString first.
{'fraction_non_alphanumeric': 0.12886642399986198, 'fraction_numerical': 0.006693463522348923, 'mean_word_length': 4.747372595677176, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 433, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4265894', 'n_tokens_mistral': 21120, 'n_tokens_neox': 19041, 'n_words': 4865}