So i have recently been attempting to do alegbra in lua and this was the closet way i could come up with of doing it is this how you are even supposed to do it correctly? An other problem that i find with doing alegbra in lua is that in alegbra there is both a constant and a variable beside eachother well the problem with that is that lua does not like both a Number and a letter beside eachother so it errors is there any way how i could go about doing alegbra inside lua without getting errors?
local a = 5
-- ALEGBRA?
print(((a * 2) / 10) + 15 - 20)
-- 5 * 2 = 10
-- 10/10 = 1
-- 1 + 15 = 16
-- 16 - 20 = -4
-- The Problem lies right here when there is a Variable and a constant together lua does not like that :/
local x = 10
print(5x + 5)
print(5x + 5) will trigger a syntax error; Lua does not allow implicit multiplication. The fix is trivial: Explicitly use the multiplication operator as in your first example: print(5*x + 5) works just fine.
Related
We are performing task as Accept a number as the seed value for math.randomseed(), and generate a random integer (interval [1,6]) using math.random() during each iteration of a loop, and continue the loop till the number is 6.
For which we had written code as
i = io.read()
local count = 0
math.randomseed(i)
for x = 1, 4 do
value = math.random(1, 6)
print(value)
count = count + 1
end
print(count)
We failed to pass test because
Input (stdin)
Run as Custom Input
0
Your Output (stdout)
3
5
5
6
2
Expected Output
3
5
5
6
4
Please help us
OP code seems to be having loop problems. I encourage the OP to read the Lua documentation about Control Structures, where Lua's while, repeat until, and goto are described, as well as the following manual section about Lua's For Statement. It is difficult to write any program in any language without understanding the fundamental control structures of the language.
OP problem can be solved in a variety of ways.
Using for
-- for version
i = io.read()
math.randomseed(i)
local count
for i = 1, math.huge do
local value = math.random(1, 6)
print(value)
count = i
if value == 6 then break end
end
print(count)
Here math.huge is the largest representable number in Lua, typically the special value inf, making this effectively an infinite loop. The variable i keeps track of how many random numbers have been generated, but since i will not be visible outside of the loop, the count variable is needed to copy the value of i so that it can be printed at the end.
Using while
-- while version
i = io.read()
math.randomseed(i)
local value = math.random(1, 6)
local count = 1
while value < 6 do
print(value)
count = count + 1
value = math.random(1, 6)
end
print(value)
print(count)
Here the looping construct begins with a test, so a test value must be created before the loop begins. This means that the count must be initialized to 1 before the loop begins, and it also means that the call to math.random will be duplicated. Not pretty.
Using repeat until
-- repeat until version
i = io.read()
math.randomseed(i)
local count = 0
repeat
local value = math.random(1, 6)
print(value)
count = count + 1
until value == 6
print(count)
Here the test comes at the end of the loop construct. This allows the code to call math.random only once.
Using goto
-- goto version
i = io.read()
math.randomseed(i)
local count = 0
::loop::
local value = math.random(1, 6)
print(value)
count = count + 1
if value < 6 then goto loop end
print(count)
You probably should not use goto to solve this problem, but you can. You have to be careful with goto in Lua; you can't jump into a block, out of a function, or into the scope of a local variable.
As you can see, there are some subtleties to these looping constructs, and using them requires some familiarity with the details.
All four versions produce identical outputs for the same inputs:
$ lua loops.lua
42
2
5
3
2
2
4
6
7
I'm using luacheck (within the Atom editor), but open to other static analysis tools.
Is there a way to check that I'm using an uninitialized table field? I read the docs (http://luacheck.readthedocs.io/en/stable/index.html) but maybe I missed how to do this?
In all three cases in the code below I'm trying to detect that I'm (erroneously) using field 'y1'. None of them do. (At run-time it is detected, but I'm trying to catch it before run-time).
local a = {}
a.x = 10
a.y = 20
print(a.x + a.y1) -- no warning about uninitialized field y1 !?
-- luacheck: globals b
b = {}
b.x = 10
b.y = 20
print(b.x + b.y1) -- no warning about uninitialized field y1 !?
-- No inline option for luacheck re: 'c', so plenty of complaints
-- about "non-standard global variable 'c'."
c = {} -- warning about setting
c.x = 10 -- warning about mutating
c.y = 20 -- " " "
print(c.x + c.y1) -- more warnings (but NOT about field y1)
The point is this: as projects grow (files grow, and the number & size of modules grow), it would be nice to prevent simple errors like this from creeping in.
Thanks.
lua-inspect should be able to detect and report these instances. I have it integrated into ZeroBrane Studio IDE and when running with the deep analysis it reports the following on this fragment:
unknown-field.lua:4: first use of unknown field 'y1' in 'a'
unknown-field.lua:7: first assignment to global variable 'b'
unknown-field.lua:10: first use of unknown field 'y1' in 'b'
unknown-field.lua:14: first assignment to global variable 'c'
unknown-field.lua:17: first use of unknown field 'y1' in 'c'
(Note that the integration code only reports first instances of these errors to minimize the number of instances reported; I also fixed an issue that only reported first unknown instance of a field, so you may want to use the latest code from the repository.)
People who look into questions related to "Lua static analysis" may also be interested in the various dialects of typed Lua, for example:
Typed Lua
Titan
Pallene
Ravi
But you may not have heard of "Teal". (early in its life it was called "tl"); .
I'm taking the liberty to answer my original question using Teal, since I find it intriguing.
-- 'record' (like a 'struct')
local Point = record
x : number
y : number
end
local a : Point = {}
a.x = 10
a.y = 20
print(a.x + a.y1) -- will trigger an error
-- (in VS Code using teal extension & at command line)
From command line:
> tl check myfile.tl
========================================
1 error:
myfile.tl:44:13: invalid key 'y1' in record 'a'
By the way...
> tl gen myfile.tl'
creates a pure Lua file: 'myfile.lua' that has no type information in it. Note: running this Lua file will trigger the 'nil' error... lua: myfile.lua:42: attempt to index a nil value (local 'a').
So, Teal gives you a chance to catch 'type' errors, but it doesn't require you to fix them before generating Lua files.
I'm adding some code to the ws2812 module to be able to have some kind of reusable buffer where we could store led values.
The current version is there.
I've two problems.
First I wanted to have some "OO-style" interface. So I did:
local buffer = ws2812.newBuffer(300);
for j = 0,299 do
buffer:set(j, 255, 255, 255)
end
buffer:write(pin);
The probleme here is that buffer:set is resolved at each loop turn, which is costly (this loop takes ~20.2ms):
8 [2] FORPREP 1 6 ; to 15
9 [3] SELF 5 0 -7 ; "set"
10 [3] MOVE 7 4
11 [3] LOADK 8 -8 ; 255
12 [3] LOADK 9 -8 ; 255
13 [3] LOADK 10 -8 ; 255
14 [3] CALL 5 6 1
15 [2] FORLOOP 1 -7 ; to 9
I found a workaround for this problem which doesn't look "nice":
local buffer = ws2812.newBuffer(300);
local set = getmetatable(buffer).set;
for j = 0,299 do
set(buffer, j, 255, 255, 255)
end
buffer:write(pin);
It works well (4.3ms for the loop, more than 4 times faster), but it's more like a hack. :/ Is there a better way to "cache" the buffer:set resolution?
Second question, in my C code, I use:
ws2812_buffer * buffer = (ws2812_buffer*)luaL_checkudata(L, 1, "ws2812.buffer");
Which gives back my buffer ptr and check if it is really a ws2812.buffer. But this call is sloooooow: on my ESP8266, ~50us. If it's done on each call (for my 300 time buffer:set for example), it's ~15ms!
Is there a better way to fetch some user data and check its type, or should I add some "canary" at the beginning of my structure to do my own check (which will almost be "free" compared to 50us...)?
To make it look less of a hack you could try using
local set = buffer.set
This is essentially the same code, but without the getmetatable as the metatable is used implicitly through the __index metamethod.
On our project we made our own implementation of luaL_checkudata.
One option - as you similarly suggested - was to use a wrapper object that holds the type. As all userdata was assumed to be wrapped in the wrapper we could use it to get and confirm the type of the userdata. But there was no benchmarking done and testing metatables was used instead.
I would say testing the metatables is slower than the wrapping since luaL_checkudata does a lot of work to get and test the metatables and with wrapping we have access to the type directly. However benchmarking will tell for sure.
How Can I tell if line number x in a Lua script will respond to the Lua line hook?
Example:
1 first = 1
2
3 function test ( data )
4 if first == 0 then
5 print ("\r\n")
6 end
7 print(data)
8 --[[
9 first = 0
10 ]]
11 end
12
13 test()
14
Line 2,6,8,9,10,12 and 14 does not call a line hook. After I have loaded and executed the script, can I some how, from C/C++, get a table of the executable line numbers?
lua_getinfo can return a table of valid lines if you include L in what.
Some code sample:
local exec_lines = {}
local function exec_line_counter(event, line)
table.insert(exec_lines, line)$
end
local function count_exec_lines(lua_file)
local external_chunk = loadfile(lua_file)
debug.sethook(exec_line_counter, "l")
external_chunk()
debug.sethook()
-- Removing `debug.sethook()` lines:
table.remove(exec_lines, 1)
table.remove(exec_lines, #exec_lines)
end
count_exec_lines("test.lua")
Output of:
table.sort(exec_lines)
for i, num in ipairs(exec_lines) do
print(num)
end
is
1
3
4
7
11
11 <--- not sure why this duplicates. Lack of return? Or because following tailcall?
13
NOTE: it would log only lines being parsed. In Your test case, it does not cover 5th and 6th line, because first not being 0.
Another way of doing this and solving noted case - just simply parsing Lua source: counting and skipping lines which consists only of Lua comments:
--lines
--[[ blocks ]]
EDIT: ah, shoot, edited Your question of doing this with C/C++. Hooking functions can be done with plain C API too. Might make an example if You didn't get a basic idea from an my answer already made :)
I'm writing an interpreter. I've done that before but never tried one which can work with expressions like 3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3.
I'm not having a problem with the parsing process, actually it is about my VM which then executes the code.
My goal was a fast interpreter and so I decided not to use a stack-based VM where you would need more than one instruction for a multiplication, for example (push, push, mul)
The "assembly" code for the VM generated by the parser looks as following:
3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3
becomes
sub 1 5
pow result 2
pow result 3
div 2 result
mul 4 result
add 3 result
(The result is correct)
As you can see: Every instruction takes no, one or two arguments. There is the result register which holds the result of the last instruction. And that's it.
Can a VM with a language of this structure and only one register calculate every mathematical expression for example Python or PHP can?
If it is not possible without a stack I'll start over right now!
What do you do about (1 + 2) * (3 + 4), or any other that would require you to calculate more than one intermediate result?