Machsupport Forum

Mach Discussion => Mach4 General Discussion => Topic started by: CNCharly on December 08, 2017, 05:23:50 AM

Title: Mach4 Lua don't support bitwise operators
Post by: CNCharly on December 08, 2017, 05:23:50 AM
MACH4 Lua does not support bitwise operators defined in the lua reference.
-------------------
3.4.2 – Bitwise Operators
Lua supports the following bitwise operators:
    &: bitwise AND
    |: bitwise OR
    ~: bitwise exclusive OR
    >>: right shift
    <<: left shift
    ~: unary bitwise NOT
---------------------
Using it, I get a syntax error message during compilation.
Questions.
1. Why are this standard lua operators not implemented?
2. Is there a simple possibility to do it anyway?

Regards,
CNCharly


Title: Re: Mach4 Lua don't support bitwise operators
Post by: joeaverage on December 08, 2017, 01:30:09 PM
Hi,
I haven't used bitwise operators so I can't be definitive but it says in the manual that it can be done so I assume it can be done. What manual did you take
the quote from. I think Lua as shipped with Mach4 is either 5.1 or 5.2 not the latest 5.3.

I have  some experience with Lua  text library functions, searching for, replacing text strings etc. The string functions appear on the surface at least to be
very much cruder than many other languages like Java and Python but they are in fact quite good. All of the standard text manipulation functions can be achieved
with a little creative use of Lua's text functions. The question is 'why did Lua's creators do it this way rather than the Java/Python/C++ standard?'. Surely
Lua would be lambasted with complaints by programmers familiar with the 'standard' text functions.

The reason is code size. To implement the standard text functions would have taken about 9000 lines of code whereas the existing Lua text functions require
500 lines of code. This is a recurring theme in Lua. The functionality appears somewhat limited at first glance but can usually, with some creative programming,
achieve all the functionality of all the serious language contenders and do so with such a small, read miniscule, code footprint. Lua is very clever in this regard
and makes it an excellent choice as a scripting language.

Could you post a sample of your code? I to have had a battle trying to write clean Lua code, the error messages are so terse that they don't really help you
find the syntax fault.

Craig
Title: Re: Mach4 Lua don't support bitwise operators
Post by: CNCharly on December 08, 2017, 03:12:37 PM
Hi Craig,
my reference was lua 5.3, so you are right, it is a version problem.
What I wanted to do:
12 input signals building 3 * 4 bit counters. The counters build the register variables JogXValue, JogYValue and JogZValue. Inputs 0 to 3 representing the JogXValue. Each input status change should add or remove its related bit (1, 2, 4, or 8) in the register variable.
Sample code for input 0 and 1:
[mc.ISIG_INPUT0] = function (state)
    if (state == 1) then WriteiRegs0 ("JogXValue", GetiRegs0 ("JogXValue") | 0x1) -- add bit by or 0001
    else WriteiRegs0 ("JogXValue", GetiRegs0 ("JogXValue") & 0xE) -- remove bit by and 1110
    end
end,
[mc.ISIG_INPUT1] = function (state)
    if (state == 1) then WriteiRegs0 ("JogXValue", GetiRegs0 ("JogXValue") | 0x2) -- add bit by or 0010
    else WriteiRegs0 ("JogXValue", GetiRegs0 ("JogXValue") & 0xD) -- remove bit by and 1101
    end
end,


Without the bitwise operators I have to read all other 3 inputs of a set to get the actual state and build the value anew.
Sample code for input 0 and 1:
[mc.ISIG_INPUT0] = function (state)
    local h_INPUT_Bit
    local Val = 0
    if (state == 1) then Val = 1 end -- Bit 1 = on
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT1)
    Val = Val + (mc.mcSignalGetState(h_INPUT_Bit) * 2)
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
    Val = Val + (mc.mcSignalGetState(h_INPUT_Bit) * 4)
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT3)
    Val = Val + (mc.mcSignalGetState(h_INPUT_Bit) * 8)
    WriteiRegs0 ("JogXValue", Val)
end,

[mc.ISIG_INPUT1] = function (state)
    local h_INPUT_Bit
    local Val = 0
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0)
    Val = Val + mc.mcSignalGetState(h_INPUT_Bit)
    if (state == 1) then Val = Val +  2 end -- Bit 2 = on
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
    Val = Val + (mc.mcSignalGetState(h_INPUT_Bit) * 4)
    h_INPUT_Bit = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT3)
    Val = Val + (mc.mcSignalGetState(h_INPUT_Bit) * 8)
    WriteiRegs0 ("JogXValue", Val)
end,

This is necessary for all 12 input signals. It works but doing it bitwise would save some CPU time and would be more readable.

You answered my question 1, I found one solution for my question 2 by myself. Maybe you have another suggestion.

CNCharly

Title: Re: Mach4 Lua don't support bitwise operators
Post by: joeaverage on December 08, 2017, 04:48:13 PM
Hi,
very intriguing, I can see what you are trying to do but I have some questions.

Code: [Select]
WriteiRegs0 ("JogXValue", GetiRegs0 ("JogXValue") & 0xE) I assume WriteiRegs() and GetiRegs() are functions you have declared eleswhere.
Machs registers can hold Lua values, namely numbers and strings.
A Lua number can be integer or real, there is no distinction between them that I know of. Can you be sure that if JogXValue=3 say, that the bit pattern
stored in the register is 0011 for instance. Until or unless I was sure that the bit pattern is the same as the integer interpretation I would not even be
thinking of bit pattern manipulation.

Have you established that bit patterns stored in the registers behave as integers?

craig
Title: Re: Mach4 Lua don't support bitwise operators
Post by: joeaverage on December 08, 2017, 05:49:02 PM
Hi,
I've been experimenting and found this works:

Code: [Select]
function bitpattern()
local inst=mc.mcGetInstance()
local regHand=mc.mcRegGetHandle(inst,'iRegs0/XJogValue')
local XJogValue=mc.mcRegGetValue(regHand)
XJogValue=bit32.bor(XJogValue,0x1)
end
if (mc.mcInEditor()==1) then
    bitpattern()
end

Note that the bitwise function is a library function, bit32.*********x, which is in the Lua 5.2 manual. You're correct, I could not get the "| or &" symbols
to compile with Machs Lua Editor. It is I suspect based on 5.2

https://www.lua.org/manual/5.2/ (https://www.lua.org/manual/5.2/)
and the library is:
https://www.lua.org/manual/5.2/manual.html#6.7 (https://www.lua.org/manual/5.2/manual.html#6.7)

Note that I put this into a function so that I could write and edit it and use the debugger to run it. You would have to put it in your signal table.

Craig
Title: Re: Mach4 Lua don't support bitwise operators
Post by: joeaverage on December 08, 2017, 06:55:40 PM
Hi,
been experimenting some more and while the version of Lua that Mach appears to use is 5.2 the rules covering coercion as in the 5.3 manual
seem to apply and are rather more complete than the sketchiest of explanations in the 5.2 manual.

Quote
3.4.3 – Coercions and Conversions

Lua provides some automatic conversions between some types and representations at run time. Bitwise operators always convert float operands to integers. Exponentiation and float division always convert integer operands to floats. All other arithmetic operations applied to mixed numbers (integers and floats) convert the integer operand to a float; this is called the usual rule. The C API also converts both integers to floats and floats to integers, as needed. Moreover, string concatenation accepts numbers as arguments, besides strings.

Lua also converts strings to numbers, whenever a number is expected.

In a conversion from integer to float, if the integer value has an exact representation as a float, that is the result. Otherwise, the conversion gets the nearest higher or the nearest lower representable value. This kind of conversion never fails.

The conversion from float to integer checks whether the float has an exact representation as an integer (that is, the float has an integral value and it is in the range of integer representation). If it does, that representation is the result. Otherwise, the conversion fails.

The conversion from strings to numbers goes as follows: First, the string is converted to an integer or a float, following its syntax and the rules of the Lua lexer. (The string may have also leading and trailing spaces and a sign.) Then, the resulting number (float or integer) is converted to the type (float or integer) required by the context (e.g., the operation that forced the conversion).

All conversions from strings to numbers accept both a dot and the current locale mark as the radix character. (The Lua lexer, however, accepts only a dot.)

The conversion from numbers to strings uses a non-specified human-readable format. For complete control over how numbers are converted to strings, use the format function from the string library (see string.format).

Note that I found a small difference and as yet unable to explain it.

My reasoning starts from the position of my first post...a Lua register can hold a value, either integer or float. If you wish to use a register value and apply bit
pattern functions then the bit representation of the register value is critical. From the manual about coercion Lua converts a float to an integer bit pattern
when required. The manual goes on to say that if the float value has an exact integer representation all well and good. If however the float value does not
have an integer value the conversion fails.

I tested this by setting the register to 3.999 and then again to 4.4999 and in both cases Lua coerced the float to integer value 4. It appears then that Lua rounds
a float to an integer value.

Craig
Title: Re: Mach4 Lua don't support bitwise operators
Post by: CNCharly on December 09, 2017, 05:59:51 AM
Hi Craig,
great work, you guided me into the right direction, thanks.
As you can see, my start script is now much simpler and easier to read and definitely faster than before.
I extended your pattern function to bring the logic of bit manipulation from the caller side into the function for simpler/safer coding.
I am quite satisfied now.
My script is part if a solution where I bring the 3 analog signals of a 3D Joystick via an Arduino for AD conversion into digital inputs of Mach4. I use a notebook running Mach and I want to have only one (ethernet-) connection to my DIY-mill.

Thanks for your help.
Greetings from Austria,
Karl