--[[ I'm planning on making a chatcmd_parse_coords function to remedy the situation that everytime there are coords involved in a chatcommand it's a different syntax: sometimes it's x,y,z, sometimes it's x y z, sometimes it's (x,y,z) sometimes tilde notation is supported sometimes it isn't. I'm planning on making a function like this: local coords,param_rest=chatcmd_parse_coords(param,base_pos) on failure it should return nil,"remaining portion of param after failure" otherwise return with coords parsed and anything that is left behind in param after parsing the coords (therefore you can have further parameters to your chatcommand). ok so first version of the code, questions, suggestions etc are welcome, also where should be this inserted as a PR? --]] -- copied from MT: local is_pos = function(v) return type(v) == "table" and type(v.x) == "number" and type(v.y) == "number" and type(v.z) == "number" end -- to make me feel home: minetest={} function minetest.pos_to_string(c) local s="nil" if c then s='('..c.x..','..c.y..','..c.z..')' end return s end -- until further notice proposed library functions follow: function is_digit(c) return #c == 1 and c >= "0" and c <= "9" end function chatcmd_parse_ws(cmdparams) while(string.sub(cmdparams,1,1)==" ") do cmdparams=string.sub(cmdparams,2) end return cmdparams end function chatcmd_parse_expect(cmdparams,expected) cmdparams=chatcmd_parse_ws(cmdparams) while cmdparams~="" and expected~="" and string.sub(cmdparams,1,1)==string.sub(expected,1,1) do cmdparams=string.sub(cmdparams,2) expected=string.sub(expected,2) end return expected=="",cmdparams end --this one right now does only parse integer numbers (negative numbers and optional tilde notation included) --TODO: could be improved to work with non-integer numbers as well function chatcmd_parse_num_OLD(cmdparams,base_num) local parsed=0 local sign local tilde local count_digit=0 if base_num then tilde,cmdparams=chatcmd_parse_expect(cmdparams,"~") end sign,cmdparams=chatcmd_parse_expect(cmdparams,"-") while(is_digit(string.sub(cmdparams,1,1))) do parsed=parsed*10 parsed=parsed+tonumber(string.sub(cmdparams,1,1)) cmdparams=string.sub(cmdparams,2) count_digit=count_digit+1 end parsed=parsed*(sign and -1 or 1) if tilde then parsed=base_num+parsed end if count_digit == 0 then parsed=nil end return parsed,cmdparams end function chatcmd_parse_num_OLD2(cmdparams,base_num) local tilde if base_num then tilde,cmdparams=chatcmd_parse_expect(cmdparams,"~") end cmdparams=chatcmd_parse_ws(cmdparams) if cmdparams=="" then return nil,"" end local max=0 local maxnum=nil for i=1,#cmdparams do local parsed=tonumber(string.sub(cmdparams,1,i)) if parsed ~= nil then max=i maxnum=parsed end end if max == 0 then return nil,cmdparams end if tilde then maxnum=base_num+maxnum end return maxnum,string.sub(cmdparams,max+1) end function chatcmd_parse_num(cmdparams,base_num) local tilde if base_num then tilde,cmdparams=chatcmd_parse_expect(cmdparams,"~") end cmdparams=chatcmd_parse_ws(cmdparams) if cmdparams=="" then return nil,"" end local parse_cases={ string.match(cmdparams,"^%-?[0-9.]*e%-?[1-9][0-9]*"), string.match(cmdparams,"^-?[0-9.]*"), string.match(cmdparams,"^-?[1-9][0-9]*") } for i = 1,3 do local s=parse_cases[i] local parsed=tonumber(s) if parsed ~= nil then cmdparams=string.sub(cmdparams,#s+1) if tilde then parsed=base_num+parsed end return parsed,cmdparams end end return nil,cmdparams end function chatcmd_parse_comma(cmdparams) local l l,cmdparams=chatcmd_parse_expect(cmdparams,",") return (l and "," or ""),cmdparams end function chatcmd_parse_parentheses(cmdparams) local l l,cmdparams=chatcmd_parse_expect(cmdparams,"(") if l then return "(",cmdparams else return nil,cmdparams end end function chatcmd_parse_matching_parentheses(cmdparams,par) if par=="" or par==nil then return true,cmdparams end if par=="(" then return chatcmd_parse_expect(cmdparams,")") end return false,cmdparams end -- all chatcmd_parse_ routines assume the cmdparams to start with optional whitespaces -- all chatcmd_parse_ routines return with parsed_result,remaining_cmdparams function chatcmd_parse_coords(cmdparams,base_pos) local x,y,z if is_pos(base_pos) then x=base_pos.x y=base_pos.y z=base_pos.z end cmdparams=chatcmd_parse_ws(cmdparams) local par par,cmdparams=chatcmd_parse_parentheses(cmdparams) local result={} result.x,cmdparams=chatcmd_parse_num(cmdparams,x) if not result.x then return nil,cmdparams end local comma comma,cmdparams=chatcmd_parse_comma(cmdparams) result.y,cmdparams=chatcmd_parse_num(cmdparams,y) if not result.y then return nil,cmdparams end local comma2 comma2,cmdparams=chatcmd_parse_comma(cmdparams) if comma2~=comma then return nil,cmdparams end result.z,cmdparams=chatcmd_parse_num(cmdparams,z) if not result.z then return nil,cmdparams end par,cmdparams=chatcmd_parse_matching_parentheses(cmdparams,par) if not par then return nil,cmdparams end return result,cmdparams end -- until further notice example code to test the library functions (user code, mod code): local function test0(s,base_pos) local output="input=\""..s.."\", output: " local c0,c1 c0,s=chatcmd_parse_coords(s,base_pos) if c0 then c1,s=chatcmd_parse_coords(s,base_pos) end if c1 then s=chatcmd_parse_ws(s) end if c0 and c1 and s=="" then --[[ if you were to -- for example -- work on a chat command /myawesomechatcmd <pos1> <pos2> somerandomparam3, at this point your s string would only contain somerandomparam3. Given the fact that in this case you only wrote test0 (as a chatcmd handler) It took you zero efforts to parse 2 coordinates in one string, and position yourself to the start of your next parameter --]] output=output.."parsing of 2 coordinates succeeded: " output=output..minetest.pos_to_string(c0)..", " output=output..minetest.pos_to_string(c1) else -- also take note of the awesome parsing error presented here: output=output.."parsing failed somewhere near \""..s.."\"" end return output end local function test(s) local output=" tilde "..test0(s,{x=3,y=6,z=5}) print(output) local output="notilde "..test0(s ) print(output) end test(" ( 1x1 , 2 , 3 ) (~1,~-1,~1) ") test(" ( 1 , 2 ; 3 ) (~1,~-1,~1) ") test(" ( 1 , 2 3 ) (~1,~-1,~1) ") test(" ( 1 , 2 , 3 (~1,~-1,~1) ") test(" ( 1 , 2 , 3 ) (~1,~-1,~1) ") test(" ( 1 f, 2 , 3 ) (~1,~-1,~1) ") test(" ( 1 ,g2 , 3 ) (~1,~-1,~1) ") test(" ( 1 2 3 ) ~1,~-1,~1 ") test(" ( 1 2 3 ) ~1,~-1,~1 k ") test(" ( 1 2 3 ) u ~-1,~1 k ") test(" ( 1 h 2 3 ) ~1,~-1,~1 ") test("abc") test("") test(" ") test(" ( 1 2 3 ) 4, 5, 6 ") test(" 123 456 789 111 -222 333") test(" 1.111 -2.22222e3 3e-2 .4 .5e2 6e-4")
Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.3. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.
OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.
name = io.read("*a")
print ("Hello ", name)
Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.
-- global variables
a = 10
-- local variables
local x = 30
Value Type | Description |
---|---|
number | Represents numbers |
string | Represents text |
nil | Differentiates values whether it has data or not |
boolean | Value can be either true or false |
function | Represents a sub-routine |
userdata | Represents arbitary C data |
thread | Represents independent threads of execution. |
table | Can hold any value except nil |
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while(condition)
do
--code
end
Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.
repeat
--code
until( condition )
For loop is used to iterate a set of statements based on a condition.
for init,max/min value, increment
do
--code
end
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.
optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end