PDA

View Full Version : Custrom keyword directly from lua.



Imagine Programming
08-15-2009, 11:45 AM
Okay the title is a bit misleading, because it's a function simply called the simple way.



function test(s)
return string.len(s);
end
local nLen = test "the string to count";
-- This will push the stringlength into 'nLen'.


Now we could use this for custom keywords, so I made a little class script
that allows you to make a class (an object table) and when this method is used
for all object tables, it'll make sure you don't overwrite any previous created
classes.
Here's the example script.



class "test"
class_method("make", [[(n)
if(type(n)~="number")then n=0;end
local t = {num=n}
setmetatable(t, {__index=test})
return t;
end]])
class_method("add", [[(n)
self.num = self.num + n;
setmetatable(self, {__index=test});
end]])
class_method("withdrawl", [[(n)
self.num = self.num - n;
setmetatable(self, {__index=test});
end]])
class_method("get", [[()
return self.num;
end]])
class_method("close", [[()
setmetatable(self, {});
end]])
class_function("print", [[(s)
Dialog.Message("class 'test' prints", s);
end]])
class_boolean("bool", true);
class_string("val", "The string content");
class_number("num", 10);
endclass "test"

local obj = test:make(0);
obj:add(10);
local n = obj:get();
obj:close();
if(test.bool==true)then
test.print(test.val.."\r\n"..type(test.num)..": "..tostring(test.num));
end

The previous example shows some L-OOP (Lua object oriented programming) and a simple function and some variable pushing.

Now here's the complete source, thank you AMSWaves for the initial checktablename function. (also used for variables).
This checktablename function is modified again using AMSWaves's intelligence :p



class_working_class = nil;
function lua_checktablename(s,root)
if(type(root)~="boolean")then root=false;end
local tKeywords = {
"and","break","do","else","elseif","end","false","for","function","if","this",
"in","local","nil","not","or","repeat","return","then","true","until","while"
};
local tRegisteredFunctions = {
"Application","Audio","Button","ComboBox","CheckBox","Crypto","Debug","Dialog","DialogEx","DLL","Drive",
"File","Flash","Folder","Grid","Hotspot","HTTP","Image","INIFile","Input","Label","ListBox","Math","MSI",
"Page","Paragraph","Plugin","Progress","RadioButton","Registry","RichText","Shell","SlideShow","StatusDlg","String","System","Table",
"TextFile","Tree","Video","Web","Window","XML","Zip"
};

local tNumbers = {};
for i=48, 57 do tNumbers[Table.Count(tNumbers)+1] = string.char(i); end
local tNotAllowed = {};
for n=1, 47 do tNotAllowed[Table.Count(tNotAllowed)+1] = string.char(n); end
for n2=58, 64 do tNotAllowed[Table.Count(tNotAllowed)+1] = string.char(n2); end
for n3=91, 94 do tNotAllowed[Table.Count(tNotAllowed)+1] = string.char(n3); end
tNotAllowed[Table.Count(tNotAllowed)+1] = string.char(96);
for n4=123, 255 do tNotAllowed[Table.Count(tNotAllowed)+1] = string.char(n4); end
if(String.Find(s, " ")~=-1)then return false, "Space found in name";end
for i2, v in tNumbers do
if(String.Left(s, 1)==v)then return false, "Number at start";end
end
for n5, c in tNotAllowed do
if(String.Find(s, c, 1, true)~=-1)then return false, "Illegal character(s)";end
end
for n6, k in tKeywords do
if(k==s)then return false, "Keyword";end
end
if(root==true)then
for n7, f in tRegisteredFunctions do
if(n7==f)then return false, "Overwriting object";end
end
end
return true;
end
function lua_dostring(lua) pcall(function(s) return loadstring(s)();end, lua);end
function class(s)
if(not lua_checktablename(s))then error("Illegal tablename, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
local sCheck = "if("..s..")then __InUse = true;else __InUse = false;end";
if(class_working_class~=nil)then error("Can't create a new class, '"..class_working_class.."' is still open!",2);end
lua_dostring(sCheck);
if(__InUse)then
__InUse = nil;
error("'"..s.."' already exists!",2);return false;
else
__InUse = nil;
class_working_class = s;
lua_dostring(""..s.." = {};");return true;
end
end
function endclass(s)
if(not lua_checktablename(s))then error("Illegal tablename, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
local sCheck = "if("..s..")and("..s..".__ended==true)then __Ended = true;else __Ended = false;end;if("..s..")then __InUse = true;else __InUse = false;end";
lua_dostring(sCheck);
if(__Ended)then
__Ended = nil;__InUse = nil;
error("Class '"..s.."' closed already!",2);return false;
else
if(__InUse)then
__Ended = nil;__InUse = nil;
local sEndString = s..".__ended = true;"
lua_dostring(sEndString);
class_working_class = nil;
else
__Ended = nil;__InUse = nil;
error("'"..s.."' does not exist!",2);
end
end
end
function class_method(s,f)
if(not lua_checktablename(s))then error("Illegal method name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(class_working_class)then
local sLua = "function "..class_working_class..":"..s..f;
lua_dostring(sLua);
else
error("Could not add a method, there is no current class",2);
end
end
function class_function(s,f)
if(not lua_checktablename(s))then error("Illegal function name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(class_working_class)then
local sLua = "function "..class_working_class.."."..s..f;
lua_dostring(sLua);
else
error("Could not add a function, there is no current class",2);
end
end
function class_boolean(s,b)
if(not lua_checktablename(s))then error("Illegal variable name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(type(b)~="boolean")then error("Argument #2, boolean required!",2);return false;end
if(class_working_class)then
local sLua = class_working_class.."."..s.." = "..tostring(b)..";";
lua_dostring(sLua);
else
error("Could not add a variable, there is no current class",2);
end
end
function class_number(s,n)
if(not lua_checktablename(s))then error("Illegal variable name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(type(b)~="number")then error("Argument #2, number required!",2);return false;end
if(class_working_class)then
local sLua = class_working_class.."."..s.." = "..tostring(n)..";";
lua_dostring(sLua);
else
error("Could not add a variable, there is no current class",2);
end
end
function class_string(s,v)
if(not lua_checktablename(s))then error("Illegal variable name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(type(v)~="string")then error("Argument #2, string required!",2);return false;end
if(class_working_class)then
local sLua = class_working_class.."."..s.." = \""..tostring(v).."\";";
lua_dostring(sLua);
else
error("Could not add a variable, there is no current class",2);
end
end


Could this be of any use to anyone?

This stuff is fun to do when you havn't slept all night.

Imagine Programming
08-15-2009, 02:50 PM
function class_number(); had a little bug.



function class_number(s,n)
if(not lua_checktablename(s))then error("Illegal variable name, do not start with a number and use only [_, 0~9, Aa~Zz]",2);return false;end
if(type(n)~="number")then error("Argument #2, number required!",2);return false;end
if(class_working_class)then
local sLua = class_working_class.."."..s.." = "..tostring(n)..";";
lua_dostring(sLua);
else
error("Could not add a variable, there is no current class",2);
end
end

Centauri Soldier
08-16-2009, 01:39 AM
Looks really nifty...way above my head though. What would one use classes for in AMS?

Imagine Programming
08-16-2009, 05:52 AM
Looks really nifty...way above my head though. What would one use classes for in AMS?

This is mostly an example showing how you could implement custom "keywords". Using classes, like this, in AMS could prevent you from overwriting an other class. It's rather silly but I like the structure in this :yes Mostly for the class_method part for usage of L-OOP.