Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type guided '&' translation #683

Open
wants to merge 10 commits into
base: pharo-12
Choose a base branch
from
9 changes: 9 additions & 0 deletions smalltalksrc/Slang-Tests/SlangBasicTranslationTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -6611,6 +6611,15 @@ SlangBasicTranslationTest >> testTypeGuidedbitAnd [
self assert: (translation includesSubstring: 'receiver & 1')
]

{ #category : #'tests-send' }
SlangBasicTranslationTest >> testTypeMismatchedAnd [

| method |
method := self getTMethodFrom:
#methodWithAndIntegerReceiverAndBooleanArgument.
self should: [ self translate: method ] raise: TypeError
]

{ #category : #'tests-assignment' }
SlangBasicTranslationTest >> testVariableAssignment [

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@ SlangBasicTranslationTestClass >> methodWithAndIntegerReceiver [
result := receiver & 1
]

{ #category : #'as yet unclassified' }
SlangBasicTranslationTestClass >> methodWithAndIntegerReceiverAndBooleanArgument [

| receiver result |

receiver := 1000.
result := receiver & false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the boolean is an argument?

methodWithAndIntegerReceiverAndBooleanArgument: arg [

	| receiver result |

	receiver := 1000.
	result := receiver & arg

and all variantas :)

  • boolean & boolean
  • boolean & int
  • int & boolean
  • int & int

Copy link
Collaborator Author

@ivojawer ivojawer Aug 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cases where both (arg and receiver) are boolean/int are covered with methodWithAndBooleanReceiver and methodWithAndIntegerReceiver. Maybe the name should reference the argument 馃槄

The other cases I considered them all the same test case (covered by this method), as they fall under the "if they are different types then throw an error" logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but my point is that those tests are on literal booleans/integers!!!
What if the receiver are the result of a more complex expression, say a variable? Do we need a type annotation for booleans?

]

{ #category : #inline }
SlangBasicTranslationTestClass >> methodWithIfAndShiftRight: var [

Expand Down
31 changes: 19 additions & 12 deletions smalltalksrc/Slang/CCodeGenerator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,24 @@ CCodeGenerator >> generateCASTIfTrueIfFalseAsArgument: tast [
^ self generateCASTIfElseAsArgument: tast reverseArms: false
]

{ #category : #generation }
CCodeGenerator >> generateCASTInferredAnd: aTSendNode [

| receiverType argumentType |
receiverType := self
tTypeFor: aTSendNode receiver
in: self currentMethod.
argumentType := self
tTypeFor: aTSendNode arguments first
in: self currentMethod.

receiverType ~= argumentType ifTrue: [ TypeError signal: 'Cannot infer & type'].

^ receiverType isBoolean
ifTrue: [ self generateCASTAnd: aTSendNode ]
ifFalse: [ self generateCASTBitAnd: aTSendNode ]
]

{ #category : #'CAST translation' }
CCodeGenerator >> generateCASTInlineCCode: aTSendNode [

Expand Down Expand Up @@ -3039,17 +3057,6 @@ CCodeGenerator >> generateDeadCode: aBool [
generateDeadCode := aBool
]

{ #category : #generation }
CCodeGenerator >> generateInferredAnd: aTSendNode [

| type |
type := self tTypeFor: aTSendNode receiver in: self currentMethod.

^type isBoolean
ifTrue: [ self generateCASTAnd: aTSendNode ]
ifFalse: [ self generateCASTBitAnd: aTSendNode ]
]

{ #category : #public }
CCodeGenerator >> globalsAsSet [
"Used by the inliner to avoid name clashes with global variables."
Expand Down Expand Up @@ -3172,7 +3179,7 @@ CCodeGenerator >> initializeCASTTranslationDictionary [

castTranslationDict := Dictionary new: 200.
pairs := #(
#& #generateInferredAnd:
#& #generateCASTInferredAnd:
#| #forbiddenSelector:
#abs #generateCASTAbs:
#and: #generateCASTSequentialAnd:
Expand Down
5 changes: 5 additions & 0 deletions smalltalksrc/Slang/TypeError.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Class {
#name : #TypeError,
#superclass : #Error,
#category : #Slang
}