Compiler conversion rules in Expression evaluation

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Compiler conversion rules in Expression evaluation

Post by octal » Wed Feb 03, 2010 12:03 pm

Hello,
does any one know the rules followed by SF Compiler when evaluating an expression with mixed type operands?
For example ?

Code: Select all

Dim i, j as byte
dim w, z as word

w = i * j + z
How does the compiler handle this kind of situation? What are the rules behind conversions? Are type conversions dependent on the lValue type or does the compiler evaluate the full expression (doing any type conversion depending on the terms forming the expression) and then convert final result to the type of the lvalue (if conversion is legal of course)?

Regards

User avatar
rocketbob
Registered User
Registered User
Posts: 51
Joined: Sun Apr 01, 2007 1:36 am
Location: Indiana USA

Post by rocketbob » Wed Feb 03, 2010 5:24 pm

see Appendix 1 in the docs. There it lays out operator precedence which can be controlled with parenthesis, like just about any other language.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Wed Feb 03, 2010 6:29 pm

From what I read of the manual, it's based on the types contained in the expression and not the Lvalue type, at least until the final assignment. As it evaluates the expression, it performs any promotion that may be required along the way.

For example, byte * byte produces a word value since the result may be larger than a byte.
According to the manual, you can mix types and the compiler will automatically produce the correct result based on the expression.

In your example it would produce something like

Code: Select all

Dim i, j as byte
dim w, z as word

temp_u16 = i * j      ' temp_u16 is a word
w = temp_u16 + z
Jerry

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Wed Feb 03, 2010 8:03 pm

@rocketbob
Thank you for your answer, but it's not a matter of operators predececense. The operators priority remains the same independently on data type (lenght).


@Jerry Messina

Thank you for your answer. I'll try different examples and check generated asm, I also already read the doc and help file, but I thought an "official" explanation could be helpfull, because it's a bit time wastfull to try especially for real/integer mixtures. I need this kind of details because I need to embed some asm in some calculation routines :?


Thank you for all your help !

Regards

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Feb 04, 2010 12:15 pm

Octal -

You pretty much had it right in your original question...
Are type conversions dependent on the lValue type or does the compiler evaluate the full expression (doing any type conversion depending on the terms forming the expression) and then convert final result to the type of the lvalue (if conversion is legal of course)?
It all works pretty well when using integral data types, but if you're going to be mixing floats and integers you might have to be more careful.
For example, 'byte * byte * float' produces different code than 'float * byte * byte', and depending on the expression you might not get what you're looking for.

But, I don't think any of this has an effect on mixing asm in with the calculations...you're always going to be working with the Lvalue type in your asm blocks, and you control what the Lvalue is.

Jerry

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Thu Feb 04, 2010 12:25 pm

Jerry Messina wrote:

For example, 'byte * byte * float' produces different code than 'float * byte * byte',
yes I think that the compiler handles the expressions like ISO pascal do, i.e it works and adjust types (type promotion) depending on the terms directly arround actual operator.
For example,
byte * byte * float, is handled like
byte * byte => result1 (byte)
result1(byte) * float => promotion of result1 to float before doing multiplication

float(Result1) * float => final result.

the same for float*byte*byte
float*byte => promote byte to float to generate
float * float(byte Promotion) => result1 (float)

result1(float) * byte => (byte promotion to float)
result1 * float(byte Promotion) => final result (float)

And assignment is done the same, but assignement procede also to byte truncation if needed (type downgrading)
Float = (Btye expression) => ByteExpression is converted to float
byte = FloatExpr => FLoat is converted to byte (with data loss)
byte = Word (only lsb is copied => data loss).

I think everything is done this way.
I need to check for signed/unsigned mixtures arithmetic now !

Regards

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Feb 04, 2010 1:58 pm

Yup, that's what I've seen, with the exception that
byte * byte => result1 (byte)
result1(byte) * float => promotion of result1 to float before doing multiplication
ends up being:
byte * byte => result1 (word)
result1(word) * float => promotion of result1 to float before doing multiplication

since it's smart enough to realize that 'byte * byte' may not fit into a byte result

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Thu Feb 04, 2010 2:30 pm

yep correct Jerry :)

Thx.

Post Reply