From 54ebcde82c8f5bdfc2e9770cab32c6e3d2aadfb7 Mon Sep 17 00:00:00 2001 From: Ignacio Losiggio Date: Wed, 17 Jan 2024 21:04:21 -0300 Subject: [PATCH] modules/Compiler: Add AstcodeDecoder --- modules/Compiler/ArgumentBinding.st | 5 + modules/Compiler/AstcodeDecoder.st | 349 +++++++++++++++++++++++ modules/Compiler/Binding.st | 5 + modules/Compiler/CompilerModule.st | 1 + modules/Compiler/DynamicBinding.st | 5 + modules/Compiler/LiteralBinding.st | 5 + modules/Compiler/NestedDynamicBinding.st | 5 + modules/Compiler/SAssignmentNode.st | 5 + modules/Compiler/SBlockNode.st | 5 + modules/Compiler/SCascadeMessageNode.st | 5 + modules/Compiler/SCascadeNode.st | 5 + modules/Compiler/SIdentifierNode.st | 5 + modules/Compiler/SLiteralNode.st | 5 + modules/Compiler/SMessageNode.st | 10 + modules/Compiler/SReturnNode.st | 18 +- modules/Compiler/SScriptNode.st | 5 + modules/Compiler/SelfBinding.st | 5 + modules/Compiler/TemporaryBinding.st | 5 + modules/Compiler/package.st | 3 +- 19 files changed, 449 insertions(+), 2 deletions(-) create mode 100644 modules/Compiler/AstcodeDecoder.st diff --git a/modules/Compiler/ArgumentBinding.st b/modules/Compiler/ArgumentBinding.st index 376da737..8ee317a1 100644 --- a/modules/Compiler/ArgumentBinding.st +++ b/modules/Compiler/ArgumentBinding.st @@ -53,3 +53,8 @@ ArgumentBinding >> isArgument [ ArgumentBinding >> isInlined [ ^environment isInlinedArgument ] + +{ #category : #decoding } +ArgumentBinding class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeArgument +] diff --git a/modules/Compiler/AstcodeDecoder.st b/modules/Compiler/AstcodeDecoder.st new file mode 100644 index 00000000..1603603e --- /dev/null +++ b/modules/Compiler/AstcodeDecoder.st @@ -0,0 +1,349 @@ +Class { + #name : #AstcodeDecoder, + #superclass : #Object, + #instVars : [ + 'method', + 'stream', + 'builder' + ], + #classVars : [ + 'BindingTypes', + 'NodeTypes' + ], + #pools : [ + 'AstBindingTypes', + 'AstNodeTypes' + ], + #category : #'Powerlang-Core-SExpressions' +} + +{ #category : #'class initialization' } +AstcodeDecoder class >> initialize [ + NodeTypes := Dictionary new. + BindingTypes := Dictionary new. + NodeTypes + at: AssignmentId put: SAssignmentNode; + at: BlockId put: SBlockNode; + at: CascadeId put: SCascadeNode; + at: LiteralId put: SLiteralNode; + at: IdentifierId put: SIdentifierNode; + at: MessageId put: SMessageNode; + at: ReturnId put: SReturnNode. + BindingTypes + at: NilId put: NilBinding; + at: TrueId put: TrueBinding; + at: FalseId put: FalseBinding; + at: ArgumentId put: ArgumentBinding; + at: TemporaryId put: TemporaryBinding; + at: SelfId put: SelfBinding; + at: SuperId put: SuperBinding; + at: DynamicVarId put: DynamicBinding; + at: NestedDynamicVarId put: NestedDynamicBinding +] + +{ #category : #'class initialization' } +AstcodeDecoder class >> initializeTreecodeIds [ + | named | + named := self addNamespaceAs: #TreecodeIds. + named + at: #MethodId put: 101; + at: #BlockId put: 102; + at: #IdentifierId put: 103; + at: #LiteralId put: 104; + at: #MessageId put: 105; + at: #CascadeId put: 106; + at: #BraceId put: 107; + at: #AssignmentId put: 108; + at: #ReturnId put: 109; + at: #PragmaId put: 110 +] + +{ #category : #'class initialization' } +AstcodeDecoder class >> initializeBindingIds [ + | named | + named := self addNamespaceAs: #BindingIds. + named + at: #NilId put: 1; + at: #TrueId put: 2; + at: #FalseId put: 3; + at: #ArgumentId put: 4; + at: #TemporaryId put: 5; + at: #SelfId put: 6; + at: #SuperId put: 7; + at: #DynamicVarId put: 14; + at: #NestedDynamicVarId put: 15; + at: #PushRid put: 50; + at: #PopRid put: 51 +] + +{ #category : #'class initialization' } +AstcodeDecoder class >> initializeClosureElementIds [ + | named | + named := self addNamespaceAs: #ClosureElementIds. + named + at: #Self put: 0; + at: #LocalArgument put: 1; + at: #Environment put: 2; + at: #EnvironmentValue put: 3 +] + + +{ #category : #'instance creation' } +AstcodeDecoder class >> new [ + "return an initialized instance" + + ^ self basicNew initialize. + +] + +{ #category : #public } +AstcodeDecoder >> bindingTypeOf: id [ + ^ BindingTypes at: id +] + +{ #category : #accessing } +AstcodeDecoder >> builder: aRuntime [ + builder := aRuntime +] + +{ #category : #public } +AstcodeDecoder >> decodeArgument [ + ^ ArgumentBinding new + index: self nextInteger; + environment: self nextEnvironment +] + +{ #category : #public } +AstcodeDecoder >> decodeAssignment [ + | assignment assignees | + assignment := SAssignmentNode new. + + assignees := self nextExpressionArray. + assignment expression: self nextExpression. + assignees do: [ :identifier | assignment assign: identifier ]. + ^ assignment +] + +{ #category : #public } +AstcodeDecoder >> decodeBlock [ + + | expression inlined block index code | + expression := SBlockNode new. + inlined := self nextBoolean. + inlined + ifTrue: [ expression inlinedArgs: self nextArray ] + ifFalse: [ + index := self nextInteger. + block := self literalAt: index. + builder ifNotNil: [ + code := builder newExecutableCodeFor: expression. + builder blockExecutableCode: block put: code ]. + expression + index: index; + capturedVariables: self nextArray ]. + expression statements: self nextExpressionArray. + ^ expression +] + +{ #category : #public } +AstcodeDecoder >> decodeCascade [ + | cascade receiver messages message count | + cascade := SCascadeNode new. + receiver := self nextExpression. + count := self nextInteger. + messages := (1 to: count) + collect: [ :i | + message := SCascadeMessageNode decodeUsing: self. + message cascade: cascade ]. + ^ cascade + receiver: receiver; + messages: messages +] + +{ #category : #public } +AstcodeDecoder >> decodeCascadeMessage [ + | selector arguments | + selector := self nextSymbol. + arguments := self nextExpressionArray. + ^ SCascadeMessageNode new + selector: selector; + arguments: arguments +] + +{ #category : #public } +AstcodeDecoder >> decodeDynamicVar [ + ^ DynamicBinding new name: self nextSymbol +] + +{ #category : #public } +AstcodeDecoder >> decodeIdentifier [ + | type binding | + type := self bindingTypeOf: self nextInteger. + binding := type decodeUsing: self. + ^ SIdentifierNode new binding: binding +] + +{ #category : #public } +AstcodeDecoder >> decodeLiteral [ + | index value | + index := self nextInteger. + value := index = 0 + ifTrue: [ self nextLiteralInteger ] + ifFalse: [ self literalAt: index ]. + ^ SLiteralNode new + value: value +] + +{ #category : #public } +AstcodeDecoder >> decodeMessage [ + | inlined selector receiver arguments | + inlined := self nextBoolean. + selector := self nextSymbol. + receiver := self nextExpression. + arguments := self nextExpressionArray. + ^ SMessageNode new + receiver: receiver; + selector: selector; + arguments: arguments; + inlined: inlined +] + +{ #category : #public } +AstcodeDecoder >> decodeMethod [ + | type node next pragma | + type := stream next. + type != MethodId + ifTrue: [ self error: 'method astcode expected' ]. + node := SMethodNode new. + next := stream peek. + next = PragmaId + ifTrue: [ stream next. + pragma := SPragmaNode new name: self nextSymbolOrNil. + node pragma: pragma ]. + node + statements: self nextExpressionArray. + ^ node +] + +{ #category : #public } +AstcodeDecoder >> decodeNestedDynamicVar [ + ^ NestedDynamicBinding new + name: + self nextSymbol. + +] + +{ #category : #public } +AstcodeDecoder >> decodeReturn [ + | expression local | + local := self nextBoolean. + expression := self nextExpression. + ^ SReturnNode new + local: local; + expression: expression +] + +{ #category : #public } +AstcodeDecoder >> decodeTemporary [ + ^ TemporaryBinding new + index: self nextInteger; + environment: self nextEnvironment +] + +{ #category : #unclassified } +AstcodeDecoder >> literalAt: anInteger [ + ^ builder ifNil: [method at: anInteger] ifNotNil: [builder method: method literalAt: anInteger] +] + +{ #category : #accessing } +AstcodeDecoder >> method: aMethod [ + method := aMethod +] + +{ #category : #public } +AstcodeDecoder >> nextArray [ + | count | + count := self nextInteger. + ^ stream next: count +] + +{ #category : #initialization } +AstcodeDecoder >> nextBoolean [ + ^ stream next = 1 +] + +{ #category : #public } +AstcodeDecoder >> nextEnvironment [ + | value | + value := self nextInteger. + ^ value != -2 + ifTrue: [ value ] +] + +{ #category : #public } +AstcodeDecoder >> nextExpression [ + | type | + type := self nodeTypeOf: stream next. + ^type decodeUsing: self. + +] + +{ #category : #public } +AstcodeDecoder >> nextExpressionArray [ + | count | + count := self nextInteger. + ^(1 to: count) collect: [ :arg | self nextExpression ] +] + +{ #category : #initialization } +AstcodeDecoder >> nextInteger [ + | value | + value := stream next. + value = 16r80 + ifTrue: [ ^ stream int64 ]. + ^ value <= 127 + ifTrue: [ value ] + ifFalse: [ value - 16r100 ] +] + +{ #category : #unclassified } +AstcodeDecoder >> nextLiteralInteger [ + | value | + value := self nextInteger. + ^ builder + ifNil: [ value ] + ifNotNil: [ builder newInteger: value ] +] + +{ #category : #public } +AstcodeDecoder >> nextSymbol [ + | index | + index := self nextInteger. + ^ self literalAt: index +] + +{ #category : #public } +AstcodeDecoder >> nextSymbolOrNil [ + | index | + index := self nextInteger. + ^index != 0 ifTrue: [ self literalAt: index] +] + +{ #category : #initialization } +AstcodeDecoder >> nextUnsignedInteger [ + | value | + value := self nextByte. + ^value < 128 + ifTrue: [value] + ifFalse: [value - 128 + (self nextUnsignedInteger bitShift: 7)] +] + +{ #category : #public } +AstcodeDecoder >> nodeTypeOf: id [ + ^NodeTypes at: id +] + +{ #category : #accessing } +AstcodeDecoder >> stream: aStream [ + stream := aStream +] diff --git a/modules/Compiler/Binding.st b/modules/Compiler/Binding.st index fd88962f..8fbe320c 100644 --- a/modules/Compiler/Binding.st +++ b/modules/Compiler/Binding.st @@ -132,3 +132,8 @@ Binding >> printOn: aStream [ super printOn: aStream. aStream nextPutAll: ')' ] + +{ #category : #decoding } +Binding class >> decodeUsing: anAstcodeDecoder [ + ^self subclassResponsibility +] diff --git a/modules/Compiler/CompilerModule.st b/modules/Compiler/CompilerModule.st index 87707bc4..95be24ac 100644 --- a/modules/Compiler/CompilerModule.st +++ b/modules/Compiler/CompilerModule.st @@ -13,6 +13,7 @@ Class { { #category : #initializing } CompilerModule >> justLoaded [ super justLoaded. + AstcodeDecoder initializeBindingIds; initializeTreecodeIds; initializeClosureElementIds; initialize. AstcodeEncoder initializeBindingIds; initializeTreecodeIds; initializeClosureElementIds ] diff --git a/modules/Compiler/DynamicBinding.st b/modules/Compiler/DynamicBinding.st index c0d4461c..3a8f909e 100644 --- a/modules/Compiler/DynamicBinding.st +++ b/modules/Compiler/DynamicBinding.st @@ -42,3 +42,8 @@ DynamicBinding >> isDynamic [ DynamicBinding >> literal [ ^name asSymbol ] + +{ #category : #decoding } +DynamicBinding class >> decodeUsing: anAstcodeDecoder [ + ^ anAstcodeDecoder decodeDynamicVar +] diff --git a/modules/Compiler/LiteralBinding.st b/modules/Compiler/LiteralBinding.st index 8f7f96b0..a9a6d0ca 100644 --- a/modules/Compiler/LiteralBinding.st +++ b/modules/Compiler/LiteralBinding.st @@ -8,3 +8,8 @@ Class { LiteralBinding >> isLiteral [ ^true ] + +{ #category : #decoding } +LiteralBinding class >> decodeUsing: anAstcodeDecoder [ + ^self new +] diff --git a/modules/Compiler/NestedDynamicBinding.st b/modules/Compiler/NestedDynamicBinding.st index 6574a419..2b9e3663 100644 --- a/modules/Compiler/NestedDynamicBinding.st +++ b/modules/Compiler/NestedDynamicBinding.st @@ -21,3 +21,8 @@ NestedDynamicBinding >> literal [ NestedDynamicBinding >> printNameOn: aStream [ name do: [ :n | aStream nextPutAll: n ] separatedBy: [ aStream nextPut: $. ] ] + +{ #category : #decoding } +NestedDynamicBinding class >> decodeUsing: anAstcodeDecoder [ + ^ anAstcodeDecoder decodeNestedDynamicVar +] diff --git a/modules/Compiler/SAssignmentNode.st b/modules/Compiler/SAssignmentNode.st index 2dd22ad2..ffc020e9 100644 --- a/modules/Compiler/SAssignmentNode.st +++ b/modules/Compiler/SAssignmentNode.st @@ -68,3 +68,8 @@ SAssignmentNode >> nodesDo: aBlock includingDeclarations: aBoolean [ SAssignmentNode >> operators [ ^operators ] + +{ #category : #decoding } +SAssignmentNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeAssignment +] diff --git a/modules/Compiler/SBlockNode.st b/modules/Compiler/SBlockNode.st index a8e762a4..7d8fc85f 100644 --- a/modules/Compiler/SBlockNode.st +++ b/modules/Compiler/SBlockNode.st @@ -107,3 +107,8 @@ SBlockNode >> usesHome [ ifTrue: [children anySatisfy: [:block | block usesHome]] ifFalse: [scope capturesHome] ] + +{ #category : #decoding } +SBlockNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeBlock +] diff --git a/modules/Compiler/SCascadeMessageNode.st b/modules/Compiler/SCascadeMessageNode.st index 00572b29..699a082f 100644 --- a/modules/Compiler/SCascadeMessageNode.st +++ b/modules/Compiler/SCascadeMessageNode.st @@ -38,3 +38,8 @@ SCascadeMessageNode >> nodesDo: aBlock includingDeclarations: aBoolean [ aBlock value: self. arguments do: [:arg | arg nodesDo: aBlock includingDeclarations: aBoolean] ] + +{ #category : #decoding } +SCascadeMessageNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeCascadeMessage +] diff --git a/modules/Compiler/SCascadeNode.st b/modules/Compiler/SCascadeNode.st index 33494ed2..fa05a09d 100644 --- a/modules/Compiler/SCascadeNode.st +++ b/modules/Compiler/SCascadeNode.st @@ -52,3 +52,8 @@ SCascadeNode >> receiver [ SCascadeNode >> receiver: rcvr [ receiver := rcvr ] + +{ #category : #decoding } +SCascadeNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeCascade +] diff --git a/modules/Compiler/SIdentifierNode.st b/modules/Compiler/SIdentifierNode.st index 703be79b..2b2c34ab 100644 --- a/modules/Compiler/SIdentifierNode.st +++ b/modules/Compiler/SIdentifierNode.st @@ -159,3 +159,8 @@ SIdentifierNode >> sourceIntervals [ whileTrue: [stretchs add: (index to: index + string size - 1)]. ^stretchs ] + +{ #category : #decoding } +SIdentifierNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeIdentifier +] diff --git a/modules/Compiler/SLiteralNode.st b/modules/Compiler/SLiteralNode.st index c2c8bfca..23d32de3 100644 --- a/modules/Compiler/SLiteralNode.st +++ b/modules/Compiler/SLiteralNode.st @@ -46,3 +46,8 @@ SLiteralNode >> value [ SLiteralNode >> value: anObject [ value := anObject ] + +{ #category : #decoding } +SLiteralNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeLiteral +] diff --git a/modules/Compiler/SMessageNode.st b/modules/Compiler/SMessageNode.st index 06c72b5c..f8197288 100644 --- a/modules/Compiler/SMessageNode.st +++ b/modules/Compiler/SMessageNode.st @@ -121,3 +121,13 @@ SMessageNode >> selector: node [ SMessageNode >> symbol [ ^selector symbol ] + +{ #category : #accessing } +SMessageNode >> inlined: aBoolean [ + inlined := aBoolean +] + +{ #category : #decoding } +SMessageNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeMessage +] diff --git a/modules/Compiler/SReturnNode.st b/modules/Compiler/SReturnNode.st index 76544d75..7f512580 100644 --- a/modules/Compiler/SReturnNode.st +++ b/modules/Compiler/SReturnNode.st @@ -3,7 +3,8 @@ Class { #superclass : #SParseNode, #instVars : [ 'expression', - 'return' + 'return', + 'local' ], #category : #'Powerlang-Core-SCompiler-Smalltalk-Parser' } @@ -43,3 +44,18 @@ SReturnNode >> nodesDo: aBlock includingDeclarations: aBoolean [ SReturnNode >> return: aSmalltalkToken [ return := aSmalltalkToken ] + +{ #category : #accessing } +SReturnNode >> local: aBoolean [ + local := aBoolean +] + +{ #category : #accessing } +SReturnNode >> local [ + ^local +] + +{ #category : #decoding } +SReturnNode class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeReturn +] diff --git a/modules/Compiler/SScriptNode.st b/modules/Compiler/SScriptNode.st index 8fdbd9e1..b3bd3679 100644 --- a/modules/Compiler/SScriptNode.st +++ b/modules/Compiler/SScriptNode.st @@ -106,6 +106,11 @@ SScriptNode >> statements [ ^statements ] +{ #category : #accessing } +SScriptNode >> statements: aCollection [ + statements := aCollection +] + { #category : #accessing } SScriptNode >> temporaries [ ^temporaries diff --git a/modules/Compiler/SelfBinding.st b/modules/Compiler/SelfBinding.st index 4730fb3b..af39a079 100644 --- a/modules/Compiler/SelfBinding.st +++ b/modules/Compiler/SelfBinding.st @@ -28,3 +28,8 @@ SelfBinding >> isSelf [ SelfBinding >> name [ ^'self' ] + +{ #category : #decoding } +SelfBinding class >> decodeUsing: anAstcodeDecoder [ + ^self new +] diff --git a/modules/Compiler/TemporaryBinding.st b/modules/Compiler/TemporaryBinding.st index 97aebd56..d8709de8 100644 --- a/modules/Compiler/TemporaryBinding.st +++ b/modules/Compiler/TemporaryBinding.st @@ -32,3 +32,8 @@ TemporaryBinding >> initialize [ TemporaryBinding >> isTemporary [ ^true ] + +{ #category : #decoding } +TemporaryBinding class >> decodeUsing: anAstcodeDecoder [ + ^anAstcodeDecoder decodeTemporary +] diff --git a/modules/Compiler/package.st b/modules/Compiler/package.st index 3593cb23..27194195 100644 --- a/modules/Compiler/package.st +++ b/modules/Compiler/package.st @@ -3,11 +3,12 @@ See (MIT) license in root directory. " -Package { #name : #Compiler', +Package { #name : #Compiler, #classes : [ 'ArgumentBinding', 'ArgumentEnvironment', 'ArrayEnvironment', + 'AstcodeDecoder', 'AstcodeEncoder', 'BlockScope', 'Binding',