Spin2 Operator Syntax - Page 2 — Parallax Forums

# Spin2 Operator Syntax

• Posts: 6,347
edited 2017-04-04 02:48
Ariba wrote: »
It's the normal syntax in Spin for float expressions:
```x := f.FMUL(f.FADD(a, b), f.FADD(c, d))
```
Now we're talking about something that should really be fixed. Spin understands floating point constants and constant expressions, but it is totally ignorant about floating point variables. It would be great if a float attribute could be attached to variables so that the compiler could handle floating point expressions with variables also.

• Posts: 2,474
edited 2017-04-04 03:01
Heater. wrote: »
You mean we should write:
```x = MUL(ADD(a, b), ADD(c, d))
```
```x = (a + b) * (c + d)
```
No thanks.

First, you're not a novice programmer. You have engrained preferences and expectations. You are used to operators, so anything else will just not be as comfortable for you.

Second, I don't have a problem with your example. I find that perfectly understandable. Start throwing some |< and ~~ in there and I suspect the functional equivalent will be easier to understand.

Third, It's all relative. At the one end, we have PASM, which is as simple as it can get, but also the most tedious to write. At the other end, you have well-established HLLs that fully abstract the hardware away, but allow you to write very concise code. Spin, in my opinion, falls in between. I'd even go so far as to say that it leans more towards the PASM end of the spectrum, by virtue of it being designed for direct interaction with a specific microcontroller (i.e. closer to the metal).

So, yes I think getting rid of operators is a reasonable idea. Since any number of syntaxes could target the same bytecode interpreter, how about create another language that looks like C/C++/etc and is chock full of operator shorthand. I suppose you could make the same argument about an all-function syntax, but that takes me back to my earlier point about the importance of the spin language being educational at it's​ roots.
• Posts: 1,930
edited 2017-04-04 03:09
Ariba wrote: »
It's the normal syntax in Spin for float expressions:
```x := f.FMUL(f.FADD(a, b), f.FADD(c, d))
```

It's the syntax, true, but it's not normal.

• Posts: 21,230
edited 2017-04-04 06:39
Seairth,
First, you're not a novice programmer. You have engrained preferences and expectations.
You are used to operators, so anything else will just not be as comfortable for you.
What has programming experience got to do with this? Anyone who has lived long enough to make it to high school knows something of arithmetic. They know what is the meaning of "+", "-", "×", "÷", "(" and ")". It should be blindingly obvious what those operators mean in a programming language. Given the small understanding that until Unicode computers did not have symbols for multiplication and division, "*" and "/" are obvious substitutes are they not? Keyboards still don't have those symbols.

I would suggest that use of such obvious notation is one reason why high level languages were developed in the first place. So that arithmetic formula could be expressed in a natural human readable way, rather than the cryptic mnemonics of assembler.

Where this goes wrong is in the invention of all kind of other operator symbols that are not natural to anyone. As we see in Spin. Then I agree with you that things like MAX(), ABS(), ROTL() would be better than making up cryptic symbol combinations.

• Posts: 1,930
edited 2017-04-04 06:40
I find myself in agreement with Heater. It's a topsy-turvy world we live in.
(at least for the immediately preceding point)
• Posts: 15,099
Heater. wrote: »
Where this goes wrong is in the invention of all kind of other operator symbols that are not natural to anyone. As we see in Spin. Then I agree with you that things like MAX(), ABS(), ROTL() would be better than making up cryptic symbol combinations.
I think most agree that clear function names trump cryptic symbol combinations.
The details on how this is done will be up to Chip, but he seems prepared to have the cleanup pass.
Your ROTL() may have been a typo ? - as the natural existing convention name candidate for that would be ROL()

• Posts: 21,230
Er, yeah, "ROL(..)" is better.

Only because we speak English mind. For anyone else it's probably as cryptic as hell.
• Posts: 15,099
Heater. wrote: »
Er, yeah, "ROL(..)" is better.

Only because we speak English mind. For anyone else it's probably as cryptic as hell.

Can we have a ROFL() for when someone asks to Rotate Float Left ?

• Posts: 21,230
Is there a "WTF" instruction in PASM 2 yet?
• Posts: 15,099
Heater. wrote: »
Is there a "WTF" instruction in PASM 2 yet?
Wait Till Finalized ?
That's been there for a l-o-n-g time now...

• Posts: 18,066
I recall the BCF instruction from decades ago...

Branch and Catch Fire
• Posts: 21,230
Ha! "Wait Till Finalized". Love it.
• Posts: 8,697
JasonDorie wrote: »
Ariba wrote: »
It's the normal syntax in Spin for float expressions:
```x := f.FMUL(f.FADD(a, b), f.FADD(c, d))
```

It's the syntax, true, but it's not normal.

Great posters on that site, thanks for posting it.

True, that syntax is not normal but that is due to the limitations of the spin/pasm compiler. It is at least easily understandable.
• Posts: 8,697
Heater. wrote: »
What has programming experience got to do with this? Anyone who has lived long enough to make it to high school knows something of arithmetic. They know what is the meaning of "+", "-", "×", "÷", "(" and ")". It should be blindingly obvious what those operators mean in a programming language. Given the small understanding that until Unicode computers did not have symbols for multiplication and division, "*" and "/" are obvious substitutes are they not? Keyboards still don't have those symbols.

I would suggest that use of such obvious notation is one reason why high level languages were developed in the first place. So that arithmetic formula could be expressed in a natural human readable way, rather than the cryptic mnemonics of assembler.

Where this goes wrong is in the invention of all kind of other operator symbols that are not natural to anyone. As we see in Spin. Then I agree with you that things like MAX(), ABS(), ROTL() would be better than making up cryptic symbol combinations.

Agreed, although there are a few additions that would also work if they were used consistently across languages. For instance "&" for "and", "<<" for rotate left, ">>" for rotate right, etc.
• Posts: 2,010
jmg wrote: »
Hey, FORTRAN intrinsics, almost. Now we're talking!

• Posts: 10,250
I like the changes to eliminate some really common gaffes. I really don't like the longer function syntax and would prefer we do as few of those as makes sense. LOG and friends maybe.

• Posts: 23,514
I agree with potatohead. Keep the infix operators as-is. Function notation for infix operators not only adds to text bloat, but it makes the code less readable when you have to visually parse a bunch of nested parentheses.

Once you get into Spin, the infix operators become second-nature. The only thing I have to refer to constantly is the precedence table. And sometimes, when I'm in a hurry, I just say "screw it" and add parens, even if it turns out they're not necessary. (Actually, the precedence table is so deep -- and at odds in places with those of other languages -- that it helps to add parens, even when I know they're not necessary.)

-Phil
• Posts: 10,250
The only thing I have to refer to constantly is the precedence table. And sometimes, when I'm in a hurry, I just say "screw it" and add parens, even if it turns out they're not necessary. (Actually, the precedence table is so deep -- and at odds in places with those of other languages -- that it helps to add parens, even when I know they're not necessary.)

Same.

• Posts: 1,930
edited 2017-04-04 19:36
kwinn wrote: »
True, that syntax is not normal but that is due to the limitations of the spin/pasm compiler. It is at least easily understandable.

It's comprehensible, but it's very difficult to see things at a glance.

I greatly prefer:
```len =  sqrt( (dx*dx) + (dy*dy) )
sum = x + y + z + w
```
over
```len = F32.FSqr( F32.FAdd( F32.FMul(dx,dx), F32.FMul(dy,dy) ) )
```
I wrote a compiler for the Elev8 FPU so I could write the former and have it generate the latter for me. It's too hard to maintain and iterate on the "function" style once it gets past a certain level of complexity.
• Posts: 8,697
JasonDorie wrote: »
kwinn wrote: »
True, that syntax is not normal but that is due to the limitations of the spin/pasm compiler. It is at least easily understandable.

It's comprehensible, but it's very difficult to see things at a glance.

I greatly prefer:
```len =  sqrt( (dx*dx) + (dy*dy) )
sum = x + y + z + w
```
over
```len = F32.FSqr( F32.FAdd( F32.FMul(dx,dx), F32.FMul(dy,dy) ) )
```
I wrote a compiler for the Elev8 FPU so I could write the former and have it generate the latter for me. It's too hard to maintain and iterate on the "function" style once it gets past a certain level of complexity.

Of course the former is preferable but the latter is what you have to work with if the only tools you have are the Propeller Tool and the F32 object.
• Posts: 13,950
edited 2017-04-11 02:26
(UPDATED)

Thanks for all your thoughts on these operators.

For ease of adoption, the common operators are now the same as C and Verilog.

For all those persnickety operators in Spin, I've substituted keywords that are self-explanatory. I decided against the function() syntax for them, as this way provides a simple and self-consistent way of doing (even buried) assignments. And I used "\" as a variable postfix to reassign the variable after it's been read (i.e. "IF flag\0" reads "flag", but post-sets it to 0).

For some operators, aliases are available (! same as NOT, && same as AND, etc).

Here is what I've got:
```Operator	Term Usage	Assign Usage	Type		Description
----------------------------------------------------------------------------------------------------------------
:=		x := y		x := y		assign		set x to y

++ (pre)	++x		++x		var prefix	pre-increment
-- (pre)	--x		--x		var prefix	pre-decrement
?? (pre)	??x		??x		var prefix	PRNG reverse, var must be long
++ (post)	x++		x++		var postfix	post-increment
-- (post)	x--		x--		var postfix	post-decrement
?? (post)	x??		x??		var postfix	PRNG forward, var must be long
~  (post)	x~		x~		var postfix	post-bitwise NOT
\  (post)	x\y		x\y		var postfix	post-set to y

!, NOT		!x		!= x		unary		Boolean NOT (0 = -1, non-0 = 0)
~		~x		~= x		unary		Bitwise NOT, 1's complement
-		-x		-= x		unary		Negation, 2's complement
ABS		ABS x		ABS= x		unary		Absolute value
ENCOD		ENCOD x		ENCOD= x	unary		Encode MSB, 31..0
DECOD		DECOD x		DECOD= x	unary		Decode, 1 shl (x & \$1F)
SQRT		SQRT x		SQRT= x		unary		Square root
LOG2		LOG2 x		LOG2= x		unary		Unsigned to logarithm-base2
EXP2		EXP2 x		EXP2= x		unary		Logarithm-base2 to unsigned

&&, AND		x && y		x &&= y		binary		Boolean AND (x <> 0 AND y <> 0, returns 0 or -1)
||, OR		x || y		x ||= y		binary		Boolean OR  (x <> 0 OR  y <> 0, returns 0 or -1)
&		x & y		x &= y		binary		Bitwise AND
|		x | y		x |= y		binary		Bitwise OR
^, XOR		x ^ y		x ^= y		binary		Bitwise XOR
>>, SAR		x >> y		x >>= y		binary		Shift right, preserve sign
<<, SHL		x << y		x <<= y		binary		Shift left
SHR		x SHR y		x SHR= y	binary		Shift right, 0's into MSB's
ROR		x ROR y		x ROR= y	binary		Rotate right
ROL		x ROL y		x ROL= y	binary		Rotate left
REV		x REV y		x REV= y	binary		Reverse y LSBs of x and zero-extend
AT_LEAST	x AT_LEAST y	x AT_LEAST= y	binary		Ensure x => y
AT_MOST		x AT_MOST y	x AT_MOST= y	binary		Ensure x <= y
+		x + y		x += y		binary		Add
-		x - y		x -= y		binary		Subtract
*		x * y		x *= y		binary		Multiply
/		x / y		x /= y		binary		Divide, return quotient
%, MOD		x % y		x %= y		binary		Divide, return remainder
SCAL		x SCAL y	x SCAL= y	binary		Scale, unsigned (x * y) >> 32
FRAC		x FRAC y	x FRAC= y	binary		Fraction, unsigned {x, 32'b0}/y
SIGNX		x SIGNX y	x SIGNX= y	binary		Sign-extend from bit y

<		x < y		<n/a>		equality	Check less than,		returns 0 or -1
=<, <=		x <= y		<n/a>		equality	Check equal or less than,	returns 0 or -1
==		x == y		<n/a>		equality	Check equal,			returns 0 or -1
<>, !=		x <> y		<n/a>		equality	Check not equal,		returns 0 or -1
=>, >=		x => y		<n/a>		equality	Check equal or greater than,	returns 0 or -1
>		x > y		<n/a>		equality	Check greater than,		returns 0 or -1

? :		x ? y : z	<n/a>		ternary		choose between y and z
```
• Posts: 14,503
Looks good but I would get rid of the aliases. They will just make it harder to read someone else's code.
• Posts: 13,950
David Betz wrote: »
Looks good but I would get rid of the aliases. They will just make it harder to read someone else's code.

So, which would you keep, "AND" or "&&"?
• Posts: 2,791
Nice.
I like the "post_set " operator too.
• Posts: 13,950
edited 2017-04-11 02:06
Here are all the aliases (updated):
```!	NOT
&&	AND
||	OR
^	XOR
<<	SHL
%	MOD
=<	<=
=>	>=
<>	!=
```
• Posts: 2,791
cgracey wrote: »
Here are all the aliases:
```!	NOT
&&	AND
||	OR
^	XOR
<<	SHL
=<	<=
=>	>=
<>	!=
```
I like all of them.

• Posts: 13,950
I just got rid of the PRNG prefix and postfix. Better done with a keyword, I think.
• Posts: 15,099
edited 2017-04-11 02:02
Looks very good to me.
Can you add MOD as an alias for % ? (brings that into line with AND.OR.XOR)

SHR is a little unclear, as you have separate lines for >> and SHR ?
Seems that needs a shift arithmetic right (SAR) to cover all the choices that were in Spin ?
(& maybe SAL, which I guess copies LSB, given SAR copies MSB ?)

Is LOG natural, or base 10 ? - This is the usual naming convention around logs :
LN Natural logarithm
LOG Logarithm base 10
EXP Natural exponential (e to the given power)
• Posts: 13,950
ozpropdev wrote: »
cgracey wrote: »
Here are all the aliases:
```!	NOT
&&	AND
||	OR
^	XOR
<<	SHL
=<	<=
=>	>=
<>	!=
```
I like all of them.

I think they're all useful, too.

I just added the PRNG prefix and postfix operators back in, using "??".
• Posts: 13,950
jmg wrote: »
Looks very good to me.
Can you add MOD as an alias for % ? (brings that into line with AND.OR.XOR)

SHR is a little unclear, as you have separate lines for >> and SHR ?
Seems that needs a shift arithmetic right (SAR) to cover all the choices that were in Spin ?
(& maybe SAL, which I guess copies LSB, given SAR copies MSB ?)

Is LOG natural, or base 10 ? - This is the usual naming convention around logs :
LN Natural logarithm
LOG Logarithm base 10
EXP Natural exponential (e to the given power)

SHR shifts 0's into the MSB's, whereas ">>" does an arithmetic shift, as one would expect from other languages.

LOG and EXP are base-2, what would you suggest? LOG2 and EXP2, maybe?

I don't know if there's any call for SAL in SPIN. Nice to have in assembler, though.