Spin2 Operator Syntax

2456716

Comments

  • Dave HeinDave Hein Posts: 5,095
    edited April 4 Vote Up0Vote Down
    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.

  • SeairthSeairth Posts: 2,054
    edited April 4 Vote Up0Vote Down
    Heater. wrote: »
    You mean we should write:
    x = MUL(ADD(a, b), ADD(c, d))
    
    Instead of:
    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.
  • JasonDorieJasonDorie Posts: 1,809
    edited April 4 Vote Up0Vote Down
    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.

    https://despair.com/products/tradition
  • Heater.Heater. Posts: 18,981
    edited April 4 Vote Up0Vote Down
    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.





  • JasonDorieJasonDorie Posts: 1,809
    edited April 4 Vote Up0Vote Down
    I find myself in agreement with Heater. It's a topsy-turvy world we live in. :)
    (at least for the immediately preceding point)
  • jmgjmg Posts: 9,645
    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()

  • Er, yeah, "ROL(..)" is better.

    Only because we speak English mind. For anyone else it's probably as cryptic as hell.
  • jmgjmg Posts: 9,645
    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 ? ;)


  • Is there a "WTF" instruction in PASM 2 yet? :)
  • jmgjmg Posts: 9,645
    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... ;)


  • I recall the BCF instruction from decades ago...

    Branch and Catch Fire
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Ha! "Wait Till Finalized". Love it.
  • 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.

    https://despair.com/products/tradition

    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.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • 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.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • TorTor Posts: 1,688
    jmg wrote: »
    ..is readily solved by merely adding the word operators SHR,SHL,ASR,ASL
    Hey, FORTRAN intrinsics, almost. Now we're talking!

  • 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.

    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: http://forums.parallax.com/showthread.php?123709-Commented-Graphics_Demo.spin<br>
  • 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
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • 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.

    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: http://forums.parallax.com/showthread.php?123709-Commented-Graphics_Demo.spin<br>
  • JasonDorieJasonDorie Posts: 1,809
    edited April 4 Vote Up0Vote Down
    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) ) )
    sum = F32.FAdd( x, F32.FAdd( y, F32.FAdd(z,w) ) )
    
    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.
  • 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) ) )
    sum = F32.FAdd( x, F32.FAdd( y, F32.FAdd(z,w) ) )
    
    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.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • cgraceycgracey Posts: 7,426
    edited April 11 Vote Up0Vote Down
    (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
    
  • Looks good but I would get rid of the aliases. They will just make it harder to read someone else's code.
  • 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 "&&"?
  • Nice.
    I like the "post_set " operator too.
    Melbourne, Australia
  • cgraceycgracey Posts: 7,426
    edited April 11 Vote Up0Vote Down
    Here are all the aliases (updated):
    !	NOT
    &&	AND
    ||	OR
    ^	XOR
    <<	SHL
    %	MOD
    =<	<=
    =>	>=
    <>	!=
    
  • cgracey wrote: »
    Here are all the aliases:
    !	NOT
    &&	AND
    ||	OR
    ^	XOR
    <<	SHL
    =<	<=
    =>	>=
    <>	!=
    
    I like all of them. :)

    Melbourne, Australia
  • I just got rid of the PRNG prefix and postfix. Better done with a keyword, I think.
  • jmgjmg Posts: 9,645
    edited April 11 Vote Up0Vote Down
    Looks very good to me.
    Minor comments :
    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)
  • 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 "??".
  • jmg wrote: »
    Looks very good to me.
    Minor comments :
    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.

    I'll add MOD for %.

    Good ideas!
Sign In or Register to comment.