diff --git a/samples/serversideviews_lua/lua4delphi/LICENSE b/samples/serversideviews_lua/lua4delphi/LICENSE
new file mode 100644
index 00000000..8dada3ed
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj b/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj
new file mode 100644
index 00000000..7c47aacd
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj
@@ -0,0 +1,60 @@
+
+
+ {162C2B63-ECD5-4626-8E5B-156604960725}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default.Personality.12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas
new file mode 100644
index 00000000..92ef9107
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas
@@ -0,0 +1,129 @@
+unit LuaBind.CustomType.DataSet;
+
+interface
+
+uses
+ Data.DB,
+ LuaBind;
+
+type
+ TLuaDataSetExposerLibraries = class(TInterfacedObject, ILuaLibraryLoader)
+
+ public
+ procedure Execute(ALuaEngine: TLuaEngine);
+ end;
+
+procedure ExposeDataSet(ALuaEngine: TLuaEngine; ADataSet: TDataSet; AVariableName: AnsiString);
+
+implementation
+
+uses LuaBind.Intf;
+
+function _dataset_eof(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+ s : ansistring;
+begin
+ s := lua_typename(L, lua_type(L, - 1));
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ if ds.Eof then
+ lua_pushboolean(L, 1)
+ else
+ lua_pushboolean(L, 0);
+ Result := 1;
+end;
+
+function _dataset_move_next(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+begin
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ ds.Next;
+ Result := 0;
+end;
+
+function _dataset_field_by_name(L: plua_state): Integer; cdecl;
+var
+ fieldname: AnsiString;
+ ds : TDataSet;
+ sdata : AnsiString;
+begin
+ assert(lua_isstring(L, - 1) = 1);
+ assert(lua_islightuserdata(L, - 2));
+ fieldname := lua_tostring(L, - 1);
+ lua_pop(L, 1);
+ ds := TDataSet(lua_topointer(L, - 1));
+ lua_pop(L, 1);
+
+ sdata := ds.FieldByName(String(fieldname)).AsAnsiString;
+ lua_pushstring(L, pansichar(sdata));
+ Result := 1;
+end;
+
+function _dataset_close(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+begin
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ ds.Close;
+ Result := 0;
+end;
+
+function _dataset_first(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+begin
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ ds.First;
+ Result := 0;
+end;
+
+function _dataset_is_open(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+ o : Integer;
+begin
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ if ds.State = dsInactive then
+ o := 0
+ else
+ o := 1;
+ lua_pushboolean(L, o);
+ Result := 1;
+end;
+
+function _dataset_open(L: plua_state): Integer; cdecl;
+var
+ ds: TDataSet;
+begin
+ assert(lua_islightuserdata(L, - 1));
+ ds := TDataSet(lua_topointer(L, - 1));
+ ds.Open;
+ Result := 0;
+end;
+
+procedure ExposeDataSet(ALuaEngine: TLuaEngine; ADataSet: TDataSet; AVariableName: AnsiString);
+begin
+ ALuaEngine.DeclareGlobalLightUserData(AVariableName, ADataSet);
+end;
+
+{ TLuaDataSetExportlibraries }
+
+procedure TLuaDataSetExposerLibraries.Execute(ALuaEngine: TLuaEngine);
+begin
+ ALuaEngine.
+ DeclareGlobalFunction('_dataset_eof', @_dataset_eof).
+ DeclareGlobalFunction('_dataset_move_next', @_dataset_move_next).
+ DeclareGlobalFunction('_dataset_field_by_name', @_dataset_field_by_name).
+ DeclareGlobalFunction('_dataset_first', @_dataset_first).
+ DeclareGlobalFunction('_dataset_is_open', @_dataset_is_open).
+ DeclareGlobalFunction('_dataset_open', @_dataset_open).
+ DeclareGlobalFunction('_dataset_close', @_dataset_close);
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas
new file mode 100644
index 00000000..9e30569e
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas
@@ -0,0 +1,285 @@
+unit LuaBind.CustomType.PODO;
+
+interface
+
+uses
+ LuaBind;
+
+type
+ TLuaDelphiObjectExposerLibraries = class(TInterfacedObject, ILuaLibraryLoader)
+ public
+ procedure Execute(ALuaEngine: TLuaEngine);
+ end;
+
+procedure ExposeDelphiObject(ALuaEngine: TLuaEngine; AObject: TObject;
+ AVariableName: AnsiString);
+
+implementation
+
+uses
+ LuaBind.Intf,
+ System.Rtti,
+ System.SysUtils,
+ System.TypInfo;
+
+function InvokeMethod(Obj: TObject; MethodName: AnsiString; params: TArray): TValue;
+var
+ ctx : TRTTIContext;
+ _type: TRttiType;
+ _m : TRttiMethod;
+ _p : TRttiProperty;
+ _pars: TArray;
+ par : TRttiParameter;
+ i : Integer;
+begin
+ ctx := TRTTIContext.Create;
+ try
+ _type := ctx.GetType(Obj.ClassInfo);
+ _m := _type.GetMethod(MethodName);
+ if _m = nil then
+ begin
+ _p := _type.GetProperty(MethodName);
+ if _p = nil then
+ raise Exception.CreateFmt('Method or property [%s] not found', [MethodName]);
+ Result := _p.GetValue(Obj);
+ end
+ else
+ begin
+ _pars := _m.GetParameters;
+ i := 0;
+ for par in _pars do
+ begin
+ if par.ParamType.TypeKind in [tkInteger, tkInt64] then
+ begin
+ if params[i].Kind in [tkFloat] then
+ params[i] := Trunc(params[i].AsExtended);
+ end;
+ end;
+ Result := _m.Invoke(Obj, params);
+ end;
+ finally
+ ctx.Free;
+ end;
+end;
+
+procedure SetProperty(Obj: TObject; const PropertyName: string;
+ const Value: TValue);
+var
+ Prop : TRttiProperty;
+ ARttiType: TRttiType;
+ ctx : TRTTIContext;
+begin
+ ARttiType := ctx.GetType(Obj.ClassType);
+ if not Assigned(ARttiType) then
+ raise Exception.CreateFmt('Cannot get RTTI for type [%s]',
+ [ARttiType.ToString]);
+ Prop := ARttiType.GetProperty(PropertyName);
+ if not Assigned(Prop) then
+ raise Exception.CreateFmt('Cannot get RTTI for property [%s.%s]',
+ [ARttiType.ToString, PropertyName]);
+ if Prop.IsWritable then
+ begin
+ if Prop.PropertyType.TypeKind in [tkInteger, tkInt64] then
+ Prop.SetValue(Obj, Trunc(Value.AsExtended))
+ else
+ Prop.SetValue(Obj, Value);
+ end
+ else
+ raise Exception.CreateFmt('Property is not writeable [%s.%s]',
+ [ARttiType.ToString, PropertyName]);
+end;
+
+function _delphi_is_a_property(L: Plua_State): Integer; cdecl;
+var
+ lvt : TLuaValueType;
+ PropertyName: string;
+ Obj : TObject;
+ propname : TValue;
+ ctx : TRTTIContext;
+ _rttitype : TRttiType;
+begin
+ Result := 0;
+ try
+ assert(lua_isstring(L, - 1) = 1);
+ assert(lua_islightuserdata(L, - 2));
+ PropertyName := TLuaValue.PopTValueFromStack(L).AsString;
+ Obj := TLuaValue.PopTValueFromStack(L).AsObject;
+ ctx := TRTTIContext.Create;
+ try
+ _rttitype := ctx.GetType(Obj.ClassType);
+ if Assigned(_rttitype.GetProperty(PropertyName)) then
+ TLuaUtils.PushTValue(L, true)
+ else
+ TLuaUtils.PushTValue(L, false);
+ finally
+ ctx.Free;
+ end;
+ Result := 1;
+ except
+ on E: Exception do
+ begin
+ lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
+ lua_error(L);
+ end;
+ end;
+end;
+
+// allows to create a delphi object using a parametersless constructor
+function _delphi_create_object(L: Plua_State): Integer; cdecl;
+var
+ ParCount : Integer;
+ _classname: string;
+ ctx : TRTTIContext;
+ _type : TRttiType;
+ Obj : TObject;
+ _m : TRttiMethod;
+ _mm : TRttiMethod;
+begin
+ Result := 0;
+ try
+ ParCount := lua_gettop(L) - 1;
+ if ParCount > 0 then
+ raise ELuaConstructorException.Create('Constructor parameters are not supported');
+
+ // Create the object
+ _classname := TLuaValue.PopTValueFromStack(L).AsString;
+ _type := ctx.FindType(_classname);
+ if _type = nil then
+ raise ELuaException.Create('Cannot find type ' + _classname +
+ '. Is it a Fully Qualified Name?');
+
+ _m := nil;
+ for _mm in _type.AsInstance.GetDeclaredMethods do
+ if _mm.IsConstructor and (Length(_mm.GetParameters) = 0) then
+ begin
+ _m := _mm;
+ Break;
+ end;
+
+ if Assigned(_m) then
+ Obj := _m.Invoke(_type.AsInstance.MetaclassType, []).AsObject
+ else
+ raise ELuaConstructorException.Create
+ ('Cannot find a suitable constructor for ' + _type.AsInstance.QualifiedName);
+ TLuaUtils.PushTValue(L, Obj);
+ Result := 1;
+ except
+ on E: Exception do
+ begin
+ lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
+ lua_error(L);
+ end;
+ end;
+end;
+
+function _delphi_set_property(L: Plua_State): Integer; cdecl;
+var
+ Value : TValue;
+ PropertyName: AnsiString;
+ Obj : TObject;
+begin
+ Result := 0;
+ try
+ assert(lua_isstring(L, - 2) = 1);
+ assert(lua_islightuserdata(L, - 3));
+ Value := TLuaValue.PopTValueFromStack(L);
+ PropertyName := TLuaValue.PopTValueFromStack(L).AsString;
+ Obj := TLuaValue.PopTValueFromStack(L).AsObject;
+ SetProperty(Obj, PropertyName, Value);
+ Result := 0;
+ except
+ on E: Exception do
+ begin
+ lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
+ lua_error(L);
+ end;
+ end;
+end;
+
+function _delphi_call_method(L: Plua_State): Integer; cdecl;
+var
+ s : AnsiString;
+ params : TArray;
+ maxindex : Integer;
+ i : Integer;
+ LuaValueType: TLuaValueType;
+ MethodName : AnsiString;
+ Obj : TObject;
+ v : TValue;
+begin
+ Result := 0;
+ try
+ assert(lua_istable(L, - 1));
+ assert(lua_isstring(L, - 2) = 1);
+ assert(lua_islightuserdata(L, - 3));
+
+ lua_getfield(L, - 1, 'maxindex');
+ maxindex := lua_tointeger(L, - 1);
+ lua_pop(L, 1);
+ if maxindex > - 1 then
+ begin
+ SetLength(params, maxindex + 1);
+ for i := 0 to maxindex do
+ begin
+ s := '_' + IntToStr(i);
+ lua_getfield(L, - 1, PAnsiChar(s));
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ params[i] := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1);
+ lua_pop(L, 1);
+ end;
+ end;
+ lua_pop(L, 1); // pop the table
+
+ // read the method name
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ if LuaValueType <> lvtString then
+ raise ELuaException.Create('Bad error! Cannot find the method name');
+ MethodName := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsString;
+ lua_pop(L, 1); // remove the methodname
+
+ // read the pointer
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ if LuaValueType <> lvtLightUserData then
+ raise ELuaException.Create('Bad error! Cannot find the object ref');
+ Obj := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsObject;
+ lua_pop(L, 1); // remove the lightuserdata
+
+ v := InvokeMethod(Obj, MethodName, params);
+ if v.IsEmpty then
+ Result := 0
+ else
+ begin
+ Result := 1;
+ TLuaUtils.PushTValue(L, v);
+ end;
+ except
+ on E: Exception do
+ begin
+ lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
+ lua_error(L);
+ end;
+ end;
+end;
+
+procedure ExposeDelphiObject(ALuaEngine: TLuaEngine;
+ AObject:
+ TObject;
+ AVariableName:
+ AnsiString);
+begin
+ ALuaEngine.DeclareGlobalLightUserData(AVariableName, AObject);
+end;
+
+{ TLuaDelphiObjectExposerLibraries }
+
+procedure TLuaDelphiObjectExposerLibraries.Execute(ALuaEngine: TLuaEngine);
+begin
+ inherited;
+ ALuaEngine.
+ DeclareGlobalFunction('_delphi_call_method', @_delphi_call_method).
+ DeclareGlobalFunction('_delphi_create_object', @_delphi_create_object).
+ DeclareGlobalFunction('_delphi_is_a_property', @_delphi_is_a_property).
+ DeclareGlobalFunction('_delphi_set_property', @_delphi_set_property);
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas
new file mode 100644
index 00000000..3a4b674d
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas
@@ -0,0 +1,95 @@
+unit LuaBind.CustomType.UserType;
+
+interface
+
+uses
+ LuaBind;
+
+type
+ TLuaMyTest = class(TInterfacedObject, ILuaLibraryLoader)
+ public
+ procedure Execute(ALuaEngine: TLuaEngine);
+ end;
+
+procedure ExposeMyTest(ALuaEngine: TLuaEngine; AObject: TObject;
+ AVariableName: AnsiString);
+
+implementation
+
+uses
+ LuaBind.Intf,
+ System.Classes;
+
+var
+ MyTest: TArray;
+
+ { TLuaMyTest }
+
+type
+ PStringList = ^TStringlist;
+
+function _NewObject(L: Plua_State): Integer; cdecl;
+var
+ psl: PStringList;
+begin
+ if lua_gettop(L) <> 0 then
+ Exit(luaL_error(L, PAnsiChar('Got arguments expected no arguments')));
+ psl := lua_newuserdata(L, SizeOf(PStringList));
+ psl^ := TStringlist.Create;
+ lua_getglobal(L, PAnsiChar('TStringList'));
+ lua_setmetatable(L, - 2);
+ Result := 1;
+end;
+
+function _TStringList_free(L: Plua_State): Integer; cdecl;
+var
+ s: string;
+ p: PStringList;
+begin
+ if (lua_gettop(L) <> 1) or (lua_isuserdata(L, - 1) = 0) then
+ Exit(luaL_error(L, PAnsiChar('No params allowed or no valid userdata')));
+ p := PStringList(lua_touserdata(L, - 1));
+ lua_pop(L, 1);
+ p^.Free;
+ p^ := nil;
+ Result := 0;
+end;
+
+function _TStringList_add(L: Plua_State): Integer; cdecl;
+var
+ s: string;
+ p: PStringList;
+begin
+ if lua_gettop(L) <> 2 then
+ Exit(luaL_error(L, PAnsiChar('Wrong number of parameters: 2 expected')));
+ s := TLuaValue.PopTValueFromStack(L).AsString;
+ p := PStringList(lua_touserdata(L, - 1));
+ lua_pop(L, 1);
+ p^.Add(s);
+ Result := 0;
+end;
+
+procedure TLuaMyTest.Execute(ALuaEngine: TLuaEngine);
+begin
+ SetLength(MyTest, 4);
+ MyTest[0].name := PAnsiChar('new');
+ MyTest[0].func := @_NewObject;
+ MyTest[1].name := PAnsiChar('add');
+ MyTest[1].func := @_TStringList_add;
+ MyTest[2].name := PAnsiChar('__gc');
+ MyTest[2].func := @_TStringList_free;
+ MyTest[3].name := nil;
+ MyTest[3].func := nil;
+
+ luaL_register(ALuaEngine.GetRawLuaState, 'TStringList', @MyTest[0]);
+ lua_pushvalue(ALuaEngine.GetRawLuaState, - 1);
+ lua_setfield(ALuaEngine.GetRawLuaState, - 2, '__index');
+end;
+
+procedure ExposeMyTest(ALuaEngine: TLuaEngine; AObject: TObject;
+ AVariableName: AnsiString);
+begin
+
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas
new file mode 100644
index 00000000..35d61dd2
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas
@@ -0,0 +1,131 @@
+unit LuaBind.DelphiObjects;
+
+interface
+
+uses
+ LuaBind.Intf;
+
+function _delphi_call_method(const L: Plua_State): Integer; cdecl;
+
+implementation
+
+uses
+ System.Rtti,
+ LuaBind,
+ System.SysUtils,
+ System.TypInfo;
+
+function InvokeMethod(Obj: TObject; MethodName: AnsiString; params: TArray): TValue;
+var
+ ctx: TRTTIContext;
+ _type: TRttiType;
+ _m: TRttiMethod;
+ _p: TRttiProperty;
+ _pars: TArray;
+ par: TRttiParameter;
+ i: Integer;
+ LMethodName: String;
+begin
+ LMethodName := String(MethodName);
+ ctx := TRTTIContext.Create;
+ try
+ _type := ctx.GetType(Obj.ClassInfo);
+ _m := _type.GetMethod(LMethodName);
+ if _m = nil then
+ begin
+ _p := _type.GetProperty(LMethodName);
+ if _p = nil then
+ raise Exception.CreateFmt('Method or property [%s] not found', [LMethodName]);
+ Result := _p.GetValue(Obj);
+ end
+ else
+ begin
+ _pars := _m.GetParameters;
+ i := 0;
+ for par in _pars do
+ begin
+ if par.ParamType.TypeKind in [tkInteger, tkInt64] then
+ begin
+ if params[i].Kind in [tkFloat] then
+ params[i] := Trunc(params[i].AsExtended);
+ end;
+ end;
+ Result := _m.Invoke(Obj, params);
+ end;
+ finally
+ ctx.Free;
+ end;
+end;
+
+function _delphi_call_method(const L: Plua_State): Integer; cdecl;
+var
+ s: AnsiString;
+ params: TArray;
+ maxindex: Integer;
+ i: Integer;
+ LuaValueType: TLuaValueType;
+ MethodName: AnsiString;
+ Obj: TObject;
+ v: TValue;
+begin
+ Result := 0;
+ try
+ Result := lua_gettop(L);
+ assert(lua_istable(L, 1));
+ assert(lua_isstring(L, 2) = 1);
+
+ MethodName := lua_tostring(L, 2);
+
+ // assert(lua_islightuserdata(L, - 3));
+
+ // lua_getfield(L, - 1, 'maxindex');
+ // maxindex := lua_tointeger(L, - 1); //decomment this?7
+ maxindex := 0; { TODO -oOwner -cGeneral : this method is in alpha stage }
+
+ lua_pop(L, 1);
+ if maxindex > - 1 then
+ begin
+ SetLength(params, maxindex + 1);
+ for i := 0 to maxindex do
+ begin
+ s := '_' + AnsiString(IntToStr(i));
+ lua_getfield(L, - 1, PAnsiChar(s));
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ params[i] := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1);
+ lua_pop(L, 1);
+ end;
+ end;
+ lua_pop(L, 1); // pop the table
+
+ // read the method name
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ if LuaValueType <> lvtString then
+ raise ELuaException.Create('Bad error! Cannot find the method name');
+ MethodName := AnsiString(TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsString);
+ lua_pop(L, 1); // remove the methodname
+
+ // read the pointer
+ LuaValueType := TLuaValue.GetLuaValueType(L, - 1);
+ if LuaValueType <> lvtLightUserData then
+ raise ELuaException.Create('Bad error! Cannot find the object ref');
+ Obj := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsObject;
+ lua_pop(L, 1); // remove the lightuserdata
+
+ v := InvokeMethod(Obj, MethodName, params);
+ if v.IsEmpty then
+ Result := 0
+ else
+ begin
+ Result := 1;
+ TLuaUtils.PushTValue(L, v);
+ end;
+ except
+ on E: Exception do
+ begin
+ lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message)));
+ lua_error(L);
+ end;
+ end;
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas
new file mode 100644
index 00000000..8d65fc1a
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas
@@ -0,0 +1,388 @@
+{$WARNINGS OFF}
+unit LuaBind.Filters.Text;
+
+interface
+
+uses
+ System.SysUtils;
+
+type
+ TLuaEmbeddedTextFilter = class
+ private
+ FTemplateCode: string;
+ FLuaCode: string;
+ FCurrCharIndex: int64;
+ FOutputStringBuilder: TStringBuilder;
+ FCurrChar: Char;
+ FOutputFunction: string;
+ procedure SetLuaCode(const Value: string);
+ procedure SetTemplateCode(const Value: string);
+ procedure NextChar;
+ function LookAhead(Offset: Integer): Char;
+ procedure PushToOutput(const AChar: Char);
+ procedure SetOutputFunction(const Value: string);
+
+ public
+ constructor Create;
+ procedure Execute;
+ property TemplateCode: string read FTemplateCode write SetTemplateCode;
+ property LuaCode: string read FLuaCode write SetLuaCode;
+ property OutputFunction: string read FOutputFunction write SetOutputFunction;
+ // helpers
+ class function ExecuteWithResult(eLuaScript: AnsiString; const ParamNames: array of string;
+ const ParamValues: array of string): string;
+ end;
+
+implementation
+
+uses
+ LuaBind.Intf,
+ System.Classes,
+ LuaBind;
+
+threadvar _OutputBuffer: TStringBuilder;
+
+function __lua_stream_out(L: Plua_State): Integer; cdecl;
+var
+ s: string;
+ o: TObject;
+ stream: TStreamWriter;
+begin
+ if lua_gettop(L) <> 2 then
+ begin
+ luaL_error(L, PAnsiChar('Wrong parameters number'));
+ Exit(0);
+ end;
+
+ if lua_isstring(L, - 1) = 1 then
+ begin
+ s := lua_tostring(L, - 1);
+ lua_pop(L, 1);
+ end
+ else
+ begin
+ luaL_error(L, PAnsiChar('Type mismatch, expected String'));
+ Exit(0);
+ end;
+
+ if lua_islightuserdata(L, - 1) then
+ begin
+ o := TObject(lua_topointer(L, - 1));
+ lua_pop(L, 1);
+ end
+ else
+ begin
+ luaL_error(L, PAnsiChar('Type mismatch, expected LightUserData'));
+ Exit(0);
+ end;
+
+ stream := o as TStreamWriter;
+ stream.Write(s);
+ Result := 0;
+end;
+
+{ TLuaEmbeddedTextFilter }
+
+constructor TLuaEmbeddedTextFilter.Create;
+begin
+ inherited;
+ FOutputFunction := 'response:out';
+end;
+
+procedure TLuaEmbeddedTextFilter.Execute;
+var
+ StartCode: Boolean;
+ State: Integer;
+const
+ PARSER_VERBATIM_TEXT = $8000;
+ PARSER_VERBATIM_CODE = PARSER_VERBATIM_TEXT + 1;
+ PARSER_VERBATIM_EXPRESSION = PARSER_VERBATIM_CODE + 1;
+ PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED = PARSER_VERBATIM_EXPRESSION + 1;
+ PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED = PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED + 1;
+begin
+ FCurrCharIndex := 0;
+ State := PARSER_VERBATIM_TEXT;
+
+ NextChar;
+ FOutputStringBuilder := TStringBuilder.Create;
+ try
+ StartCode := True;
+ while FCurrChar <> #0 do
+ begin
+ case State of
+ PARSER_VERBATIM_TEXT:
+ begin
+ if FCurrChar = '<' then
+ begin
+ if (LookAhead(1) = '?') and (LookAhead(2) = 'l') and (LookAhead(3) = 'u') and
+ (LookAhead(4) = 'a') then
+ begin
+ NextChar; // ?
+ NextChar; // l
+ NextChar; // u
+ NextChar; // a
+ NextChar; // _
+ if not StartCode then
+ FOutputStringBuilder.Append(']]');
+ StartCode := False;
+
+ if FCurrChar = '=' then // expression
+ begin
+ State := PARSER_VERBATIM_EXPRESSION;
+ FOutputStringBuilder.Append(FOutputFunction + '(');
+ NextChar;
+ end
+ else
+ State := PARSER_VERBATIM_CODE;
+ end
+ else
+ begin
+ if StartCode then
+ begin
+ StartCode := False;
+ FOutputStringBuilder.Append(FOutputFunction + ' [[' + sLineBreak);
+ end;
+ PushToOutput('<');
+ NextChar;
+ end;
+ end
+ else // FCurrChar <> '<'
+ begin
+ if StartCode then
+ begin
+ StartCode := False;
+ FOutputStringBuilder.Append(FOutputFunction + ' [[' + sLineBreak);
+ end;
+ PushToOutput(FCurrChar);
+ NextChar;
+ end;
+ end;
+
+ PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED:
+ begin
+ if FCurrChar = '''' then
+ begin
+ State := PARSER_VERBATIM_CODE;
+ PushToOutput('''');
+ NextChar;
+ end
+ else if (FCurrChar = '\') and (LookAhead(1) = '''') then
+ begin
+ PushToOutput('\');
+ PushToOutput('''');
+ NextChar;
+ NextChar;
+ end
+ else
+ begin
+ PushToOutput(FCurrChar);
+ NextChar;
+ end;
+ end;
+
+ PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED:
+ begin
+ if FCurrChar = '"' then
+ begin
+ State := PARSER_VERBATIM_CODE;
+ PushToOutput('"');
+ NextChar;
+ end
+ else if (FCurrChar = '\') and (LookAhead(1) = '"') then
+ begin
+ PushToOutput('\');
+ PushToOutput('"');
+ NextChar;
+ NextChar;
+ end
+ else
+ begin
+ PushToOutput(FCurrChar);
+ NextChar;
+ end;
+ end;
+
+ PARSER_VERBATIM_CODE:
+ begin
+ if FCurrChar = '''' then
+ begin
+ State := PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED;
+ PushToOutput('''');
+ NextChar;
+ end
+ else if FCurrChar = '"' then
+ begin
+ State := PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED;
+ PushToOutput('"');
+ NextChar;
+ end
+ else if FCurrChar = '?' then
+ begin
+ if (LookAhead(1) = '>') then
+ begin
+ NextChar; // >
+ NextChar; // _
+ FOutputStringBuilder.Append(sLineBreak + FOutputFunction + ' [[' + sLineBreak);
+ State := PARSER_VERBATIM_TEXT;
+ end
+ else
+ begin
+ PushToOutput('?');
+ NextChar;
+ end;
+ end
+ else // FCurrChar <> '?'
+ begin
+ PushToOutput(FCurrChar);
+ NextChar;
+ end;
+ end; // PARSER_VERBATIM_CODE
+
+ PARSER_VERBATIM_EXPRESSION:
+ begin
+ if FCurrChar = '?' then
+ begin
+ if (LookAhead(1) = '>') then
+ begin
+ NextChar; // >
+ NextChar; // _
+ FOutputStringBuilder.Append(')');
+ FOutputStringBuilder.Append(sLineBreak + FOutputFunction + ' [[' + sLineBreak);
+ State := PARSER_VERBATIM_TEXT;
+ end
+ else
+ begin
+ PushToOutput('?');
+ NextChar;
+ end;
+ end
+ else // FCurrChar <> '?'
+ begin
+ PushToOutput(FCurrChar);
+ NextChar;
+ end;
+ end;
+ end; // case
+ end; // while
+
+ if (State = PARSER_VERBATIM_TEXT) and (not StartCode) then
+ FOutputStringBuilder.Append(']]')
+ else if not StartCode then
+ raise ELuaFilterException.Create('Expected closing Lua tag');
+
+ FLuaCode := FOutputStringBuilder.ToString;
+ finally
+ FOutputStringBuilder.Free;
+ end;
+end;
+
+function __lua_out(L: Plua_State): Integer; cdecl;
+var
+ s: string;
+begin
+ if lua_gettop(L) <> 1 then
+ begin
+ luaL_error(L, PAnsiChar('Wrong parameters number'));
+ Exit(0);
+ end;
+
+ if lua_isstring(L, - 1) = 1 then
+ begin
+ s := lua_tostring(L, - 1);
+ lua_pop(L, 1);
+ end
+ else
+ begin
+ luaL_error(L, PAnsiChar('Type mismatch, expected String'));
+ Exit(0);
+ end;
+ _OutputBuffer.Append(s);
+ Result := 0;
+end;
+
+class function TLuaEmbeddedTextFilter.ExecuteWithResult(eLuaScript: AnsiString;
+ const ParamNames, ParamValues: array of string): string;
+var
+ LuaFilter: TLuaEmbeddedTextFilter;
+ L: TLuaEngine;
+ I: Integer;
+
+ function GetOutputBuffer: TStringBuilder;
+ begin
+ Result := _OutputBuffer;
+ end;
+
+begin
+ if Length(ParamNames) <> Length(ParamValues) then
+ raise ELuaRuntimeException.Create('Number of params names and param values is not equals');
+
+ LuaFilter := TLuaEmbeddedTextFilter.Create;
+ try
+ LuaFilter.OutputFunction := '_out';
+ LuaFilter.TemplateCode := eLuaScript;
+ LuaFilter.Execute;
+
+ _OutputBuffer := TStringBuilder.Create;
+ try
+ L := TLuaEngine.Create;
+ try
+ for I := 0 to Length(ParamNames) - 1 do
+ L.DeclareGlobalString(ParamNames[I], ParamValues[I]);
+ L.DeclareGlobalFunction('_out', @__lua_out);
+ L.LoadScript(LuaFilter.LuaCode);
+ L.Execute;
+ Result := _OutputBuffer.ToString;
+ finally
+ L.Free;
+ end;
+ finally
+ FreeAndNil(_OutputBuffer);
+ end;
+ finally
+ LuaFilter.Free;
+ end;
+end;
+
+function TLuaEmbeddedTextFilter.LookAhead(Offset: Integer): Char;
+begin
+ if FCurrCharIndex + Offset <= Length(FTemplateCode) then
+ Result := FTemplateCode[FCurrCharIndex + Offset]
+ else
+ Result := #0;
+end;
+
+procedure TLuaEmbeddedTextFilter.NextChar;
+begin
+ if FCurrCharIndex = Length(FTemplateCode) then
+ begin
+ FCurrCharIndex := - 1;
+ FCurrChar := #0;
+ end
+ else
+ begin
+ FCurrCharIndex := FCurrCharIndex + 1;
+ FCurrChar := FTemplateCode[FCurrCharIndex];
+ end;
+end;
+
+procedure TLuaEmbeddedTextFilter.PushToOutput(const AChar: Char);
+begin
+ FOutputStringBuilder.Append(AChar);
+end;
+
+procedure TLuaEmbeddedTextFilter.SetLuaCode(const Value: string);
+begin
+ FLuaCode := Value;
+end;
+
+procedure TLuaEmbeddedTextFilter.SetOutputFunction(const Value: string);
+begin
+ FOutputFunction := Value;
+end;
+
+procedure TLuaEmbeddedTextFilter.SetTemplateCode(const Value: string);
+begin
+ FTemplateCode := Value;
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas
new file mode 100644
index 00000000..99dea15c
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas
@@ -0,0 +1,1221 @@
+(* *****************************************************************************
+ * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************** *)
+
+{$IFDEF FPC}
+{$MODE OBJFPC}{$M+}
+{$DEFINE HAVEINLINE}
+{$ENDIF}
+
+unit LuaBind.Intf;
+
+interface
+
+uses classes;
+
+type
+ size_t = Cardinal;
+ Psize_t = ^size_t;
+
+ {$IFNDEF FPC}
+
+ PtrInt = Integer;
+
+ {$ENDIF}
+
+
+const
+
+ {$IFDEF UNIX}
+
+ LUA_LIB = 'liblua5.1.so';
+
+ {$ELSE}
+
+ LUA_LIB = 'lua5.1.dll';
+
+ {$ENDIF}
+
+
+const
+ LUA_IDSIZE = 60;
+ LUAL_BUFFERSIZE = 512;
+
+ (*
+ ** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
+ ** Lua - An Extensible Extension Language
+ ** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+ ** See Copyright Notice at the end of this file
+ *)
+
+
+ // #include "luaconf.h"
+
+const
+ LUA_VERSION = 'Lua 5.1';
+ LUA_RELEASE = 'Lua 5.1.4';
+ LUA_VERSION_NUM = 501;
+ LUA_COPYRIGHT = 'Copyright (C) 1994-2008 Lua.org, PUC-Rio';
+ LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes';
+
+ (* mark for precompiled code (`Lua') *)
+ LUA_SIGNATURE = #33'Lua';
+
+ (* option for multiple returns in `lua_pcall' and `lua_call' *)
+ LUA_MULTRET = - 1;
+
+ (*
+ ** pseudo-indices
+ *)
+ LUA_REGISTRYINDEX = - 10000;
+ LUA_ENVIRONINDEX = - 10001;
+ LUA_GLOBALSINDEX = - 10002;
+function lua_upvalueindex(i: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+(* thread status; 0 is OK *)
+const
+ LUA_YIELD_ = 1;
+ LUA_ERRRUN = 2;
+ LUA_ERRSYNTAX = 3;
+ LUA_ERRMEM = 4;
+ LUA_ERRERR = 5;
+
+type
+ Plua_State = ^lua_State;
+
+ lua_State = record
+
+ end;
+
+ lua_CFunction = function(L: Plua_State): Integer; cdecl;
+
+ (*
+ ** functions that read/write blocks when loading/dumping Lua chunks
+ *)
+ lua_Reader = function(L: Plua_State; ud: Pointer; sz: Psize_t): PAnsiChar; cdecl;
+ lua_Writer = function(L: Plua_State; const p: Pointer; sz: Psize_t; ud: Pointer): Integer; cdecl;
+
+ (*
+ ** prototype for memory-allocation functions
+ *)
+ lua_Alloc = function(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl;
+
+ (*
+ ** basic types
+ *)
+const
+ LUA_TNONE = - 1;
+
+ LUA_TNIL = 0;
+ LUA_TBOOLEAN = 1;
+ LUA_TLIGHTUSERDATA = 2;
+ LUA_TNUMBER = 3;
+ LUA_TSTRING = 4;
+ LUA_TTABLE = 5;
+ LUA_TFUNCTION = 6;
+ LUA_TUSERDATA = 7;
+ LUA_TTHREAD = 8;
+
+ (* minimum Lua stack available to a C function *)
+ LUA_MINSTACK = 20;
+
+ (*
+ ** generic extra include file
+ *)
+ // #if defined(LUA_USER_H)
+ // #include LUA_USER_H
+ // #endif
+
+type
+ (* type of numbers in Lua *)
+ lua_Number = Double; // LUA_NUMBER
+
+ (* type for integer functions *)
+ lua_Integer = PtrInt; // LUA_INTEGER
+
+ (*
+ ** state manipulation
+ *)
+function lua_newstate(f: lua_Alloc; ud: Pointer): Plua_State; cdecl;
+ external LUA_LIB name 'lua_newstate';
+procedure lua_close(L: Plua_State); cdecl; external LUA_LIB name 'lua_close';
+function lua_newthread(L: Plua_State): Plua_State; cdecl; external LUA_LIB name 'lua_newthread';
+
+function lua_atpanic(L: Plua_State; panicf: lua_CFunction): lua_CFunction; cdecl;
+ external LUA_LIB name 'lua_atpanic';
+
+(*
+ ** basic stack manipulation
+*)
+function lua_gettop(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gettop';
+procedure lua_settop(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_settop';
+procedure lua_pushvalue(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_pushvalue';
+procedure lua_remove(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_remove';
+procedure lua_insert(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_insert';
+procedure lua_replace(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_replace';
+function lua_checkstack(L: Plua_State; sz: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_checkstack';
+
+procedure lua_xmove(from: Plua_State; to_: Plua_State; n: Integer); cdecl;
+ external LUA_LIB name 'lua_xmove';
+
+(*
+ ** access functions (stack -> C)
+*)
+
+function lua_isnumber(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_isnumber';
+function lua_isstring(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_isstring';
+function lua_iscfunction(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_iscfunction';
+function lua_isuserdata(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_isuserdata';
+function lua_type(L: Plua_State; idx: Integer): Integer; cdecl; external LUA_LIB name 'lua_type';
+function lua_typename(L: Plua_State; tp: Integer): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_typename';
+
+function lua_equal(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_equal';
+function lua_rawequal(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_rawequal';
+function lua_lessthan(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_lessthan';
+
+function lua_tonumber(L: Plua_State; idx: Integer): lua_Number; cdecl;
+ external LUA_LIB name 'lua_tonumber';
+function lua_tointeger(L: Plua_State; idx: Integer): lua_Integer; cdecl;
+ external LUA_LIB name 'lua_tointeger';
+function lua_toboolean(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_toboolean';
+function lua_tolstring(L: Plua_State; idx: Integer; len: Psize_t): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_tolstring';
+function lua_objlen(L: Plua_State; idx: Integer): size_t; cdecl; external LUA_LIB name 'lua_objlen';
+function lua_tocfunction(L: Plua_State; idx: Integer): lua_CFunction; cdecl;
+ external LUA_LIB name 'lua_tocfunction';
+function lua_touserdata(L: Plua_State; idx: Integer): Pointer; cdecl;
+ external LUA_LIB name 'lua_touserdata';
+function lua_tothread(L: Plua_State; idx: Integer): Plua_State; cdecl;
+ external LUA_LIB name 'lua_tothread';
+function lua_topointer(L: Plua_State; idx: Integer): Pointer; cdecl;
+ external LUA_LIB name 'lua_topointer';
+
+(*
+ ** push functions (C -> stack)
+*)
+procedure lua_pushnil(L: Plua_State); cdecl; external LUA_LIB name 'lua_pushnil';
+procedure lua_pushnumber(L: Plua_State; n: lua_Number); cdecl;
+ external LUA_LIB name 'lua_pushnumber';
+procedure lua_pushinteger(L: Plua_State; n: lua_Integer); cdecl;
+ external LUA_LIB name 'lua_pushinteger';
+procedure lua_pushlstring(L: Plua_State; const s: PAnsiChar; len: size_t); cdecl;
+ external LUA_LIB name 'lua_pushlstring';
+procedure lua_pushstring(L: Plua_State; const s: PAnsiChar); cdecl;
+ external LUA_LIB name 'lua_pushstring';
+function lua_pushvfstring(L: Plua_State; const fmt: PAnsiChar): PAnsiChar; varargs; cdecl;
+ external LUA_LIB name 'lua_pushvfstring';
+function lua_pushfstring(L: Plua_State; const fmt: PAnsiChar): PAnsiChar; varargs; cdecl;
+ external LUA_LIB name 'lua_pushfstring';
+procedure lua_pushcclosure(L: Plua_State; fn: lua_CFunction; n: Integer); cdecl;
+ external LUA_LIB name 'lua_pushcclosure';
+procedure lua_pushboolean(L: Plua_State; b: Integer); cdecl;
+ external LUA_LIB name 'lua_pushboolean';
+procedure lua_pushlightuserdata(L: Plua_State; p: Pointer); cdecl;
+ external LUA_LIB name 'lua_pushlightuserdata';
+function lua_pushthread(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_pushthread';
+
+(*
+ ** get functions (Lua -> stack)
+*)
+procedure lua_gettable(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_gettable';
+procedure lua_getfield(L: Plua_State; idx: Integer; const k: PAnsiChar); cdecl;
+ external LUA_LIB name 'lua_getfield';
+procedure lua_rawget(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_rawget';
+procedure lua_rawgeti(L: Plua_State; idx: Integer; n: Integer); cdecl;
+ external LUA_LIB name 'lua_rawgeti';
+procedure lua_createtable(L: Plua_State; narr: Integer; nrec: Integer); cdecl;
+ external LUA_LIB name 'lua_createtable';
+function lua_newuserdata(L: Plua_State; sz: size_t): Pointer; cdecl;
+ external LUA_LIB name 'lua_newuserdata';
+function lua_getmetatable(L: Plua_State; objindex: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_getmetatable';
+procedure lua_getfenv(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_getfenv';
+
+(*
+ ** set functions (stack -> Lua)
+*)
+procedure lua_settable(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_settable';
+procedure lua_setfield(L: Plua_State; idx: Integer; const k: PAnsiChar); cdecl;
+ external LUA_LIB name 'lua_setfield';
+procedure lua_rawset(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_rawset';
+procedure lua_rawseti(L: Plua_State; idx: Integer; n: Integer); cdecl;
+ external LUA_LIB name 'lua_rawseti';
+function lua_setmetatable(L: Plua_State; objindex: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_setmetatable';
+function lua_setfenv(L: Plua_State; idx: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_setfenv';
+
+(*
+ ** `load' and `call' functions (load and run Lua code)
+*)
+procedure lua_call(L: Plua_State; nargs: Integer; nresults: Integer); cdecl;
+ external LUA_LIB name 'lua_call';
+function lua_pcall(L: Plua_State; nargs: Integer; nresults: Integer; errfunc: Integer): Integer;
+ cdecl; external LUA_LIB name 'lua_pcall';
+function lua_cpcall(L: Plua_State; func: lua_CFunction; ud: Pointer): Integer; cdecl;
+ external LUA_LIB name 'lua_cpcall';
+function lua_load(L: Plua_State; reader: lua_Reader; dt: Pointer; const chunkname: PAnsiChar)
+ : Integer; cdecl; external LUA_LIB name 'lua_load';
+
+function lua_dump(L: Plua_State; writer: lua_Writer; data: Pointer): Integer; cdecl;
+ external LUA_LIB name 'lua_dump';
+
+(*
+ ** coroutine functions
+*)
+function lua_yield(L: Plua_State; nresults: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_yield';
+function lua_resume(L: Plua_State; narg: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_resume';
+function lua_status(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_status';
+
+(*
+ ** garbage-collection function and options
+*)
+
+const
+ LUA_GCSTOP = 0;
+ LUA_GCRESTART = 1;
+ LUA_GCCOLLECT = 2;
+ LUA_GCCOUNT = 3;
+ LUA_GCCOUNTB = 4;
+ LUA_GCSTEP = 5;
+ LUA_GCSETPAUSE = 6;
+ LUA_GCSETSTEPMUL = 7;
+
+function lua_gc(L: Plua_State; what: Integer; data: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_gc';
+
+(*
+ ** miscellaneous functions
+*)
+
+function lua_error(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_error';
+
+function lua_next(L: Plua_State; idx: Integer): Integer; cdecl; external LUA_LIB name 'lua_next';
+
+procedure lua_concat(L: Plua_State; n: Integer); cdecl; external LUA_LIB name 'lua_concat';
+
+function lua_getallocf(L: Plua_State; var ud: Pointer): lua_Alloc; cdecl;
+ external LUA_LIB name 'lua_getallocf';
+procedure lua_setallocf(L: Plua_State; f: lua_Alloc; ud: Pointer); cdecl;
+ external LUA_LIB name 'lua_setallocf ';
+
+(*
+ ** ===============================================================
+ ** some useful macros
+ ** ===============================================================
+*)
+
+procedure lua_pop(L: Plua_State; n: Integer); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure lua_newtable(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure lua_register(L: Plua_State; n: PAnsiChar; f: lua_CFunction); {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+procedure lua_pushcfunction(L: Plua_State; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_strlen(L: Plua_State; i: Integer): size_t; cdecl; external LUA_LIB name 'lua_objlen';
+function lua_isfunction(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_istable(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_islightuserdata(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+function lua_isnil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_isboolean(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_isthread(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_isnone(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_isnoneornil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure lua_pushliteral(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure lua_setglobal(L: Plua_State; s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure lua_getglobal(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_tostring(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+(*
+ ** compatibility macros and functions
+*)
+
+function lua_open: Plua_State; cdecl; external LUA_LIB name 'luaL_newstate';
+procedure lua_getregistry(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_getgccount(L: Plua_State): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+type
+ lua_Chunkreader = type lua_Reader;
+ lua_Chunkwriter = type lua_Writer;
+
+ (* hack *)
+procedure lua_setlevel(from: Plua_State; to_: Plua_State); cdecl;
+ external LUA_LIB name 'lua_setlevel ';
+
+(*
+ ** {======================================================================
+ ** Debug API
+ ** =======================================================================
+*)
+
+(*
+ ** Event codes
+*)
+const
+ LUA_HOOKCALL = 0;
+ LUA_HOOKRET = 1;
+ LUA_HOOKLINE = 2;
+ LUA_HOOKCOUNT = 3;
+ LUA_HOOKTAILRET = 4;
+
+ (*
+ ** Event masks
+ *)
+ LUA_MASKCALL = (1 shl LUA_HOOKCALL);
+ LUA_MASKRET = (1 shl LUA_HOOKRET);
+ LUA_MASKLINE = (1 shl LUA_HOOKLINE);
+ LUA_MASKCOUNT = (1 shl LUA_HOOKCOUNT);
+ LUA_MASKTAILRET = (1 shl LUA_HOOKTAILRET);
+
+type
+ Plua_Debug = ^lua_Debug;
+
+ lua_Debug = record
+ event: Integer;
+ name: PAnsiChar; (* (n) *)
+ namewhat: PAnsiChar; (* (n) `global', `local', `field', `method' *)
+ what: PAnsiChar; (* (S) `Lua', `C', `main', `tail' *)
+ source: PAnsiChar; (* (S) *)
+ currentline: Integer; (* (l) *)
+ nups: Integer; (* (u) number of upvalues *)
+ linedefined: Integer; (* (S) *)
+ lastlinedefined: Integer; (* (S) *)
+ short_src: array [0 .. LUA_IDSIZE - 1] of AnsiChar; (* (S) *)
+ (* private part *)
+ i_ci: Integer; (* active function *)
+ end; (* activation record *)
+
+ (* Functions to be called by the debuger in specific events *)
+ lua_Hook = procedure(L: Plua_State; ar: Plua_Debug); cdecl;
+
+function lua_getstack(L: Plua_State; level: Integer; ar: Plua_Debug): Integer; cdecl;
+ external LUA_LIB name 'lua_getstack';
+function lua_getinfo(L: Plua_State; const what: PAnsiChar; ar: Plua_Debug): Integer; cdecl;
+ external LUA_LIB name 'lua_getinfo';
+function lua_getlocal(L: Plua_State; const ar: Plua_Debug; n: Integer): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_getlocal';
+function lua_setlocal(L: Plua_State; const ar: Plua_Debug; n: Integer): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_setlocal';
+function lua_getupvalue(L: Plua_State; funcindex: Integer; n: Integer): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_getupvalue';
+function lua_setupvalue(L: Plua_State; funcindex: Integer; n: Integer): PAnsiChar; cdecl;
+ external LUA_LIB name 'lua_setupvalue';
+
+function lua_sethook(L: Plua_State; func: lua_Hook; mask: Integer; count: Integer): Integer; cdecl;
+ external LUA_LIB name 'lua_sethook';
+function lua_gethook(L: Plua_State): lua_Hook; cdecl; external LUA_LIB name 'lua_gethook';
+function lua_gethookmask(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gethookmask';
+function lua_gethookcount(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gethookcount';
+
+(* }====================================================================== *)
+
+(*
+ ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
+ ** Auxiliary functions for building Lua libraries
+ ** See Copyright Notice in lua.h
+*)
+
+// #if defined(LUA_COMPAT_GETN)
+// LUALIB_API int (luaL_getn) (lua_State *L, int t);
+// LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
+// #else
+function luaL_getn(L: Plua_State; idx: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+// #define luaL_setn(L,i,j) ((void)0) (* no op! *)
+// #endif
+
+// #if defined(LUA_COMPAT_OPENLIB)
+// #define luaI_openlib luaL_openlib
+// #endif
+
+(* extra error code for `luaL_load' *)
+const
+ LUA_ERRFILE = LUA_ERRERR + 1;
+
+type
+ PluaL_Reg = ^luaL_Reg;
+
+ luaL_Reg = record
+ name: PAnsiChar;
+ func: lua_CFunction;
+ end;
+
+procedure luaI_openlib(L: Plua_State; const libname: PAnsiChar; const lr: PluaL_Reg; nup: Integer);
+ cdecl; external LUA_LIB name 'luaI_openlib';
+procedure luaL_register(L: Plua_State; const libname: PAnsiChar; const lr: PluaL_Reg); cdecl;
+ external LUA_LIB name 'luaL_register';
+function luaL_getmetafield(L: Plua_State; obj: Integer; const e: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_getmetafield';
+function luaL_callmeta(L: Plua_State; obj: Integer; const e: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_callmeta';
+function luaL_typerror(L: Plua_State; narg: Integer; const tname: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_typerror';
+function luaL_argerror(L: Plua_State; numarg: Integer; const extramsg: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_argerror';
+function luaL_checklstring(L: Plua_State; numarg: Integer; len: Psize_t): PAnsiChar; cdecl;
+ external LUA_LIB name 'luaL_checklstring';
+function luaL_optlstring(L: Plua_State; numarg: Integer; const def: PAnsiChar; len: Psize_t)
+ : PAnsiChar; cdecl; external LUA_LIB name 'luaL_optlstring';
+function luaL_checknumber(L: Plua_State; numarg: Integer): lua_Number; cdecl;
+ external LUA_LIB name 'luaL_checknumber';
+function luaL_optnumber(L: Plua_State; narg: Integer; def: lua_Number): lua_Number; cdecl;
+ external LUA_LIB name 'luaL_optnumber';
+function luaL_checkinteger(L: Plua_State; numarg: Integer): lua_Integer; cdecl;
+ external LUA_LIB name 'luaL_checkinteger';
+function luaL_optinteger(L: Plua_State; narg: Integer; def: lua_Integer): lua_Integer; cdecl;
+ external LUA_LIB name 'luaL_optinteger';
+procedure luaL_checkstack(L: Plua_State; sz: Integer; const msg: PAnsiChar); cdecl;
+ external LUA_LIB name 'luaL_checkstack';
+procedure luaL_checktype(L: Plua_State; narg: Integer; t: Integer); cdecl;
+ external LUA_LIB name 'luaL_checktype';
+procedure luaL_checkany(L: Plua_State; narg: Integer); cdecl; external LUA_LIB name 'luaL_checkany';
+function luaL_newmetatable(L: Plua_State; const tname: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_newmetatable';
+function luaL_checkudata(L: Plua_State; ud: Integer; const tname: PAnsiChar): Pointer; cdecl;
+ external LUA_LIB name 'luaL_checkudata';
+procedure luaL_where(L: Plua_State; lvl: Integer); cdecl; external LUA_LIB name 'luaL_where';
+function luaL_error(L: Plua_State; const fmt: PAnsiChar): Integer; varargs; cdecl;
+ external LUA_LIB name 'luaL_error';
+function luaL_checkoption(L: Plua_State; narg: Integer; const def: PAnsiChar; const lst: PPAnsiChar)
+ : Integer; cdecl; external LUA_LIB name 'luaL_checkoption';
+function luaL_ref(L: Plua_State; t: Integer): Integer; cdecl; external LUA_LIB name 'luaL_ref';
+procedure luaL_unref(L: Plua_State; t: Integer; ref: Integer); cdecl;
+ external LUA_LIB name 'luaL_unref';
+function luaL_loadfile(L: Plua_State; const filename: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_loadfile';
+function luaL_loadbuffer(L: Plua_State; const buff: PAnsiChar; sz: size_t; const name: PAnsiChar)
+ : Integer; cdecl; external LUA_LIB name 'luaL_loadbuffer';
+function luaL_loadstring(L: Plua_State; const s: PAnsiChar): Integer; cdecl;
+ external LUA_LIB name 'luaL_loadstring';
+function luaL_newstate: Plua_State; cdecl; external LUA_LIB name 'luaL_newstate:';
+function luaL_gsub(L: Plua_State; const s: PAnsiChar; const p: PAnsiChar; const r: PAnsiChar)
+ : PAnsiChar; cdecl; external LUA_LIB name 'luaL_gsub';
+function luaL_findtable(L: Plua_State; idx: Integer; const fname: PAnsiChar; szhint: Integer)
+ : PAnsiChar; cdecl; external LUA_LIB name 'luaL_findtable';
+
+(*
+ ** ===============================================================
+ ** some useful macros
+ ** ===============================================================
+*)
+
+function luaL_argcheck(L: Plua_State; cond: Boolean; numarg: Integer; const extramsg: PAnsiChar)
+ : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_checkstring(L: Plua_State; n: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_optstring(L: Plua_State; n: Integer; d: PAnsiChar): PAnsiChar;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_checkint(L: Plua_State; n: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_optint(L: Plua_State; n: Integer; d: lua_Integer): Integer; {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+function luaL_checklong(L: Plua_State; n: Integer): LongInt; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_optlong(L: Plua_State; n: Integer; d: lua_Integer): LongInt;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_typename(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_dofile(L: Plua_State; fn: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function luaL_dostring(L: Plua_State; s: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+procedure luaL_getmetatable(L: Plua_State; n: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+// #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+(*
+ ** {======================================================
+ ** Generic Buffer manipulation
+ ** =======================================================
+*)
+
+type
+ PluaL_Buffer = ^luaL_Buffer;
+
+ luaL_Buffer = record
+ p: PAnsiChar; (* current position in buffer *)
+ lvl: Integer; (* number of strings in the stack (level) *)
+ L: Plua_State;
+ buffer: array [0 .. LUAL_BUFFERSIZE - 1] of AnsiChar;
+ end;
+
+ // #define luaL_addchar(B,c) \
+ // ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
+ // (*(B)->p++ = (char)(c)))
+ //
+ // (* compatibility only *)
+ // #define luaL_putchar(B,c) luaL_addchar(B,c)
+ //
+ // #define luaL_addsize(B,n) ((B)->p += (n))
+
+procedure luaL_buffinit(L: Plua_State; b: PluaL_Buffer); cdecl;
+ external LUA_LIB name 'luaL_buffinit';
+function luaL_prepbuffer(b: PluaL_Buffer): PAnsiChar; cdecl;
+ external LUA_LIB name 'luaL_prepbuffer';
+procedure luaL_addlstring(b: PluaL_Buffer; const s: PAnsiChar; L: size_t); cdecl;
+ external LUA_LIB name 'luaL_addlstring';
+procedure luaL_addstring(b: PluaL_Buffer; const s: PAnsiChar); cdecl;
+ external LUA_LIB name 'luaL_addstring';
+procedure luaL_addvalue(b: PluaL_Buffer); cdecl; external LUA_LIB name 'luaL_addvalue';
+procedure luaL_pushresult(b: PluaL_Buffer); cdecl; external LUA_LIB name 'luaL_pushresult';
+
+(* }====================================================== *)
+
+(* compatibility with ref system *)
+
+(* pre-defined references *)
+const
+ LUA_NOREF = - 2;
+ LUA_REFNIL = - 1;
+
+ // #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
+ // (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
+ //
+ // #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
+ //
+ // #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
+
+ (*
+ ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
+ ** Lua standard libraries
+ ** See Copyright Notice in lua.h
+ *)
+
+ (* Key to file-handle type *)
+const
+ LUA_FILEHANDLE = 'FILE*';
+ LUA_COLIBNAME = 'coroutine';
+ LUA_TABLIBNAME = 'table';
+ LUA_IOLIBNAME = 'io';
+ LUA_OSLIBNAME = 'os';
+ LUA_STRLIBNAME = 'string';
+ LUA_MATHLIBNAME = 'math';
+ LUA_DBLIBNAME = 'debug';
+ LUA_LOADLIBNAME = 'package';
+
+function luaopen_base(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_base';
+function luaopen_table(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_table';
+function luaopen_io(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_io';
+function luaopen_os(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_os';
+function luaopen_string(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_string';
+function luaopen_math(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_math';
+function luaopen_debug(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_debug';
+function luaopen_package(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_package';
+
+(* open all previous libraries *)
+procedure luaL_openlibs(L: Plua_State); cdecl; external LUA_LIB name 'luaL_openlibs';
+
+// usefull
+function lua_app_alloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl;
+function lua_processsor_loadstream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Integer;
+function lua_processsor_loadfile(L: Plua_State; const filename: string;
+ chunkname: PAnsiChar): Integer;
+function lua_processsor_dofile(L: Plua_State; const filename: string; chunkname: PAnsiChar)
+ : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+function lua_processsor_dostream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Boolean;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+implementation
+
+uses
+ sysutils;
+
+procedure lua_pop(L: Plua_State; n: Integer); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_settop(L, - (n) - 1)
+end;
+
+procedure lua_newtable(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_createtable(L, 0, 0)
+end;
+
+procedure lua_register(L: Plua_State; n: PAnsiChar; f: lua_CFunction); {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+begin
+ lua_pushcfunction(L, f);
+ lua_setglobal(L, n);
+end;
+
+procedure lua_pushcfunction(L: Plua_State; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_pushcclosure(L, f, 0)
+end;
+
+function lua_isfunction(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TFUNCTION;
+end;
+
+function lua_istable(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TTABLE;
+end;
+
+function lua_islightuserdata(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+begin
+ Result := lua_type(L, n) = LUA_TLIGHTUSERDATA;
+end;
+
+function lua_isnil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TNIL;
+end;
+
+function lua_isboolean(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TBOOLEAN;
+end;
+
+function lua_isthread(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TTHREAD;
+end;
+
+function lua_isnone(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) = LUA_TNONE;
+end;
+
+function lua_isnoneornil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_type(L, n) <= 0;
+end;
+
+procedure lua_setglobal(L: Plua_State; s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_setfield(L, LUA_GLOBALSINDEX, s)
+end;
+
+procedure lua_getglobal(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_getfield(L, LUA_GLOBALSINDEX, s);
+end;
+
+function lua_tostring(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_tolstring(L, i, nil);
+end;
+
+procedure lua_pushliteral(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_pushlstring(L, s, StrLen(s))
+end;
+
+procedure lua_getregistry(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_pushvalue(L, LUA_REGISTRYINDEX);
+end;
+
+function lua_getgccount(L: Plua_State): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_gc(L, LUA_GCCOUNT, 0);
+end;
+
+function luaL_argcheck(L: Plua_State; cond: Boolean; numarg: Integer; const extramsg: PAnsiChar)
+ : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := cond or (luaL_argerror(L, numarg, extramsg) <> 0)
+end;
+
+function luaL_checkstring(L: Plua_State; n: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := luaL_checklstring(L, n, nil);
+end;
+
+function luaL_optstring(L: Plua_State; n: Integer; d: PAnsiChar): PAnsiChar;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := luaL_optlstring(L, n, d, nil)
+end;
+
+function luaL_getn(L: Plua_State; idx: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_objlen(L, idx);
+end;
+
+function luaL_checkint(L: Plua_State; n: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := luaL_checkinteger(L, n);
+end;
+
+function luaL_optint(L: Plua_State; n: Integer; d: lua_Integer): Integer; {$IFDEF HAVEINLINE}inline;
+
+{$ENDIF}
+
+begin
+ Result := luaL_optinteger(L, n, d);
+end;
+
+function luaL_checklong(L: Plua_State; n: Integer): LongInt; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := luaL_checkinteger(L, n);
+end;
+
+function luaL_optlong(L: Plua_State; n: Integer; d: lua_Integer): LongInt;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := luaL_optinteger(L, n, d);
+end;
+
+function luaL_typename(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := lua_typename(L, lua_type(L, i));
+end;
+
+function luaL_dofile(L: Plua_State; fn: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := (luaL_loadfile(L, fn) <> 0) or (lua_pcall(L, 0, LUA_MULTRET, 0) <> 0);
+end;
+
+function luaL_dostring(L: Plua_State; s: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+begin
+ Result := (luaL_loadstring(L, s) <> 0) or (lua_pcall(L, 0, LUA_MULTRET, 0) <> 0);
+end;
+
+procedure luaL_getmetatable(L: Plua_State; n: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ lua_getfield(L, LUA_REGISTRYINDEX, n);
+end;
+
+function lua_upvalueindex(i: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := (LUA_GLOBALSINDEX - (i));
+end;
+
+function lua_app_alloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl;
+begin
+ if (nsize > 0) then
+ begin
+ if ptr = nil then
+ GetMem(Result, nsize)
+ else
+ begin
+ ReallocMem(ptr, nsize);
+ Result := ptr;
+ end;
+ end
+ else
+ begin
+ if ptr <> nil then
+ FreeMem(ptr);
+ Result := nil;
+ end;
+end;
+
+type
+ TLuaState = (
+ lsStart,
+ lsLessThan,
+ lsEscape,
+ lsEscapeClose,
+ lsLua,
+ lsLuaBody,
+ lsLuaBodyEnd,
+ lsLuaEqual,
+ lsLuaEqualEnd
+ );
+ PLuaTextProcessor = ^TLuaTextProcessor;
+
+ TLuaTextProcessor = record
+ stream: TStream;
+ state: TLuaState;
+ outbuffer: array [0 .. 1023] of AnsiChar;
+ end;
+
+function lua_stream_reader(L: Plua_State; ud: Pointer; sz: Psize_t): PAnsiChar; cdecl;
+var
+ inbuffer : array [0 .. 1023] of AnsiChar;
+ inlen, outlen: Integer;
+ pr : PLuaTextProcessor;
+ pin, pout : PAnsiChar;
+ c : AnsiChar;
+ function Append(const str: PAnsiChar; L: Integer): Boolean;
+ begin
+ if outlen + L <= sizeof(pr.outbuffer) then
+ begin
+ move(str^, pout^, L);
+ inc(pout, L);
+ inc(outlen, L);
+ Result := true;
+ end
+ else
+ Result := false;
+ end;
+
+label
+ redo,
+ needspace;
+begin
+ pr := PLuaTextProcessor(ud);
+ inlen := pr.stream.Read(inbuffer, sizeof(inbuffer));
+ outlen := 0;
+ pin := @inbuffer;
+ pout := @pr.outbuffer;
+ while (inlen > 0) do
+ begin
+ c := pin^;
+ redo:
+ case pr.state of
+ lsStart:
+ begin
+ case c of
+ '<':
+ pr.state := lsLessThan;
+ else
+ if not Append('print("', 7) then
+ goto needspace;
+ pr.state := lsEscape;
+ goto redo;
+ end;
+ end;
+ lsLessThan:
+ begin
+ case c of
+ '%':
+ pr.state := lsLua;
+ else
+ if not Append('print("<', 8) then
+ goto needspace;
+ pr.state := lsEscape;
+ goto redo;
+ end;
+ end;
+ lsEscape:
+ begin
+ case c of
+ '<':
+ pr.state := lsEscapeClose;
+ else
+ case c of
+ #7:
+ if not Append('\a', 2) then
+ goto needspace;
+ #8:
+ if not Append('\b', 2) then
+ goto needspace;
+ #9:
+ if not Append('\t', 2) then
+ goto needspace;
+ #10:
+ if not Append('\n")'#10'print("', 12) then
+ goto needspace;
+ #11:
+ if not Append('\v', 2) then
+ goto needspace;
+ #13:
+ if not Append('\r', 2) then
+ goto needspace;
+ '\':
+ if not Append('\\', 2) then
+ goto needspace;
+ '"':
+ if not Append('\"', 2) then
+ goto needspace;
+ '''':
+ if not Append('\''', 2) then
+ goto needspace;
+ else
+ if not Append(pin, 1) then
+ goto needspace;
+ end;
+ end;
+ end;
+ lsEscapeClose:
+ begin
+ case c of
+ '%':
+ begin
+ if not Append('");', 3) then
+ goto needspace;
+ pr.state := lsLua;
+ end;
+ else
+ if not Append('<', 1) then
+ goto needspace;
+ pr.state := lsEscape;
+ goto redo;
+ end;
+ end;
+ lsLua:
+ begin
+ case c of
+ '=':
+ begin
+ if not Append('print((', 7) then
+ goto needspace;
+ pr.state := lsLuaEqual;
+ end;
+ '%':
+ pr.state := lsLuaBodyEnd;
+ else
+ if not Append(pin, 1) then
+ goto needspace;
+ pr.state := lsLuaBody;
+ end;
+ end;
+ lsLuaBody:
+ begin
+ case c of
+ '%':
+ pr.state := lsLuaBodyEnd;
+ else
+ if not Append(pin, 1) then
+ goto needspace;
+ end;
+ end;
+ lsLuaBodyEnd:
+ begin
+ case c of
+ '>':
+ pr.state := lsStart;
+ else
+ if not Append('%', 1) then
+ goto needspace;
+ pr.state := lsLuaBody;
+ goto redo;
+ end;
+ end;
+ lsLuaEqual:
+ begin
+ case c of
+ '%':
+ pr.state := lsLuaEqualEnd;
+ else
+ if not Append(pin, 1) then
+ goto needspace;
+ end;
+ end;
+ lsLuaEqualEnd:
+ begin
+ case c of
+ '>':
+ begin
+ if not Append('));', 3) then
+ goto needspace;
+ pr.state := lsStart;
+ end;
+ else
+ if not Append('%', 1) then
+ goto needspace;
+ pr.state := lsLuaEqual;
+ goto redo;
+ end;
+ end;
+ end;
+ inc(pin);
+ dec(inlen);
+ end;
+ if outlen = 0 then
+ begin
+ case pr.state of
+ lsLessThan:
+ Append('print("<")', 10);
+ lsEscape:
+ Append('")', 2);
+ lsEscapeClose:
+ Append('%")', 3);
+ end;
+ pr.state := lsStart;
+ end;
+ Result := @pr.outbuffer;
+ sz^ := outlen;
+ Exit;
+needspace:
+ pr.stream.Seek( - inlen, soFromCurrent);
+ Result := @pr.outbuffer;
+ sz^ := outlen;
+end;
+
+function lua_processsor_loadstream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Integer;
+var
+ bom : array [0 .. 2] of Byte;
+ processor: TLuaTextProcessor;
+begin
+ processor.stream := stream;
+ processor.state := lsStart;
+ // skip utf8 bom
+ stream.Seek(0, soFromBeginning);
+ if not ((stream.Read(bom, 3) = 3) and (bom[0] = $EF) and (bom[1] = $BB) and (bom[2] = $BF)) then
+ stream.Seek(0, soFromBeginning);
+ Result := lua_load(L, @lua_stream_reader, @processor, chunkname);
+end;
+
+function lua_processsor_loadfile(L: Plua_State; const filename: string;
+ chunkname: PAnsiChar): Integer;
+var
+ stream: TFileStream;
+begin
+ stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
+ try
+ Result := lua_processsor_loadstream(L, stream, chunkname);
+ finally
+ stream.Free;
+ end;
+end;
+
+function lua_processsor_dofile(L: Plua_State; const filename: string; chunkname: PAnsiChar)
+ : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := (lua_processsor_loadfile(L, filename, chunkname) = 0) and
+ (lua_pcall(L, 0, LUA_MULTRET, 0) = 0);
+end;
+
+function lua_processsor_dostream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Boolean;
+
+{$IFDEF HAVEINLINE}inline; {$ENDIF}
+
+
+begin
+ Result := (lua_processsor_loadstream(L, stream, chunkname) = 0) and
+ (lua_pcall(L, 0, LUA_MULTRET, 0) = 0);
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.pas
new file mode 100644
index 00000000..348b502c
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/LuaBind.pas
@@ -0,0 +1,903 @@
+{$WARNINGS OFF}
+unit LuaBind;
+
+interface
+
+uses LuaBind.Intf,
+ System.Classes,
+ System.SysUtils,
+ System.Rtti,
+ System.Generics.Collections;
+
+type
+ ELuaException = class(Exception)
+
+ end;
+
+ ELuaRuntimeException = class(ELuaException)
+
+ end;
+
+ ELuaConstructorException = class(ELuaException)
+
+ end;
+
+ ELuaSyntaxError = class(ELuaException)
+
+ end;
+
+ ELuaFilterException = class(ELuaSyntaxError)
+
+ end;
+
+ ILuaValue = interface
+ ['{8621BAD3-B847-4176-937F-2CD016BBE13E}']
+ /// ///
+ function IsNil: boolean;
+
+ function IsNumber: boolean;
+ function IsInteger: boolean;
+ function IsString: boolean;
+ function IsBoolean: boolean;
+ function IsLightUserData: boolean;
+ /// ///
+ function GetAsNumber: Double;
+ function GetAsInteger: Integer;
+ function GetAsString: AnsiString;
+ function GetAsBoolean: boolean;
+ function GetAsLightUserData: Pointer;
+ end;
+
+ TLuaValueType = (lvtNil, lvtNumber, lvtInteger, lvtString, lvtBoolean,
+ lvtLightUserData, lvtTable, lvtFunction, lvtUserData, lvtThread);
+
+ TLuaValue = class(TInterfacedObject, ILuaValue)
+ strict private
+ FLuaValueType: TLuaValueType;
+
+ strict private
+
+ protected
+ /// ///
+ function IsNil: boolean;
+ function IsNumber: boolean;
+ function IsInteger: boolean;
+ function IsString: boolean;
+ function IsBoolean: boolean;
+ function IsLightUserData: boolean;
+ /// ///
+ function GetAsNumber: Double;
+ function GetAsInteger: Integer;
+ function GetAsString: AnsiString;
+ function GetAsBoolean: boolean;
+ function GetAsLightUserData: Pointer;
+
+ private
+ procedure CheckType(LuaValueType: TLuaValueType);
+
+ protected
+ FValue: TValue;
+ constructor Create(LuaState: Plua_State; StackIndex: Integer);
+
+ public
+ class function GetAsLuaTable(LuaState: Plua_State;
+ StackIndex: Integer): TValue;
+ class function GetLuaValueType(LuaState: Plua_State; StackIndex: Integer)
+ : TLuaValueType;
+ class function GetTValueFromLuaValueType(LuaValueType: TLuaValueType;
+ LuaState: Plua_State; StackIndex: Integer): TValue; static;
+ class function PopTValueFromStack(LuaState: Plua_State): TValue; static;
+ end;
+
+ ILuaLibraryLoader = interface;
+
+ TLuaEngine = class
+ strict private
+ procedure CheckLuaError(const r: Integer);
+
+ private
+ procedure InternalDeclareTable(AObject: TObject);
+
+ protected
+ LState: Plua_State;
+ procedure InitLua;
+ procedure CloseLua;
+
+ public
+ constructor Create; overload; virtual;
+ constructor Create(const AScript: string); overload; virtual;
+ destructor Destroy; override;
+ function GetRawLuaState: Plua_State;
+
+ procedure Reset;
+ procedure LoadScript(const AScript: AnsiString); overload;
+ procedure LoadScript(const AStream: TStream;
+ AOwnStream: boolean = true); overload;
+ procedure LoadFromFile(const AFileName: AnsiString);
+ procedure Execute;
+ procedure ExecuteFile(const AFileName: AnsiString);
+ procedure ExecuteScript(const AScript: AnsiString);
+
+ // PUSH methods for simple types
+ function DeclareGlobalNil(AName: AnsiString): TLuaEngine;
+ function DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine;
+ function DeclareGlobalInteger(AName: AnsiString; AValue: Integer)
+ : TLuaEngine;
+ function DeclareGlobalString(AName: AnsiString; AValue: AnsiString)
+ : TLuaEngine;
+ function DeclareGlobalBoolean(AName: AnsiString; AValue: boolean)
+ : TLuaEngine;
+ function DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer)
+ : TLuaEngine;
+ function DeclareGlobalUserData(AName: AnsiString; AValue: Pointer)
+ : TLuaEngine;
+
+ // PUSH complex types
+ function DeclareGlobalFunction(AName: AnsiString; AFunction: lua_CFunction)
+ : TLuaEngine;
+
+ function DeclareGlobalDelphiObjectAsTable(AObject: TObject;
+ AVariableName: string): TLuaEngine;
+
+ // Helpers to PUSH specific types coping properties or data into Lua tables
+ function DeclareTable(const ATableName: AnsiString; AKeys: array of string;
+ AValues: array of string): TLuaEngine; overload;
+ function DeclareTable(const ATableName: AnsiString; AKeys: array of Integer;
+ AValues: array of string): TLuaEngine; overload;
+ function DeclareTable(const ATableName: AnsiString;
+ ADictionary: TDictionary): TLuaEngine; overload;
+ function DeclareTable(const ATableName: AnsiString;
+ ADictionary: TDictionary): TLuaEngine; overload;
+ function DeclareTable(const ATableName: AnsiString; AObject: TObject)
+ : TLuaEngine; overload;
+
+ function DeclareTable(const ATableName: AnsiString; __self: Pointer;
+ AFunctions: TDictionary;
+ AData: TDictionary
+ ): TLuaEngine; overload;
+
+ // GET methods for simple types
+ function GetGlobal(AName: AnsiString): ILuaValue;
+
+ // External load libraries
+ procedure LoadExternalLibraries(ALuaLibraryLoader: ILuaLibraryLoader);
+
+ // function
+ function ExecuteFunction(FunctionName: AnsiString;
+ const Params: array of TValue): TValue;
+
+ // helpers
+ class function ExecuteWithResult(AScript: AnsiString;
+ const ParamNames: array of string;
+ const ParamValues: array of string): string;
+ end;
+
+ ILuaLibraryLoader = interface
+ ['{46A7894C-DDA8-4E15-95EB-B52463341FF1}']
+ procedure Execute(ALuaEngine: TLuaEngine);
+ end;
+
+ TLuaUtils = class sealed
+ public
+ class procedure PushTValue(L: Plua_State; Value: TValue); static;
+ end;
+
+implementation
+
+uses
+ typinfo,
+ LuaBind.DelphiObjects;
+
+function internal_call_method(LState: Plua_State): Integer; cdecl;
+begin
+ // raise Exception.Create('Error Message');
+ lua_pop(LState, 1);
+ lua_pop(LState, 1);
+ lua_pushcfunction(LState, @_delphi_call_method);
+ Result := 1;
+ // Result := lua_gettop(LState);
+ // for I := 1 to Result do
+ // begin
+ // v := TLuaValue.PopTValueFromStack(LState);
+ // end
+ // // Result := _delphi_call_method(LState)
+end;
+
+class procedure TLuaUtils.PushTValue(L: Plua_State; Value: TValue);
+var
+ utf8s: RawByteString;
+begin
+ case Value.Kind of
+ tkUnknown, tkChar, tkSet, tkMethod, tkVariant, tkArray, tkProcedure,
+ tkRecord, tkInterface, tkDynArray, tkClassRef:
+ begin
+ lua_pushnil(L);
+ // raise Exception.Create('Unsupported return type: ' + Value.ToString);
+ end;
+ tkInteger:
+ lua_pushinteger(L, Value.AsInteger);
+ tkEnumeration:
+ begin
+ if Value.IsType then
+ begin
+ if Value.AsBoolean then
+ lua_pushboolean(L, 1)
+ else
+ lua_pushboolean(L, 0);
+ end
+ else
+ lua_pushinteger(L, Value.AsInteger);
+ end;
+ tkFloat:
+ lua_pushnumber(L, Value.AsExtended);
+ tkString, tkWChar, tkLString, tkWString, tkUString:
+ begin
+ utf8s := UTF8Encode(Value.AsString);
+ lua_pushstring(L, PAnsiChar(utf8s));
+ end;
+ tkClass:
+ lua_pushlightuserdata(L, Pointer(Value.AsObject));
+ tkInt64:
+ lua_pushnumber(L, Value.AsInt64);
+ tkPointer:
+ lua_pushlightuserdata(L, Pointer(Value.AsObject));
+ end;
+end;
+
+{ TLuaEngine }
+
+constructor TLuaEngine.Create;
+begin
+ inherited Create;
+ InitLua;
+end;
+
+procedure TLuaEngine.CloseLua;
+begin
+ lua_close(LState);
+end;
+
+constructor TLuaEngine.Create(const AScript: string);
+begin
+ Create;
+ LoadScript(AScript);
+end;
+
+function TLuaEngine.DeclareGlobalBoolean(AName: AnsiString; AValue: boolean)
+ : TLuaEngine;
+var
+ b: Integer;
+begin
+ if AValue then
+ b := 1
+ else
+ b := 0;
+ lua_pushboolean(LState, b);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalDelphiObjectAsTable(AObject: TObject;
+ AVariableName: string): TLuaEngine;
+begin
+ // lua_createtable(L, 0, 0);
+ // lua_createtable(L, 0, 1);
+ assert(lua_isnil(LState, -1));
+ lua_newtable(LState);
+ assert(lua_istable(LState, -1));
+ lua_newtable(LState);
+ lua_pushcfunction(LState, @internal_call_method);
+ lua_setfield(LState, -2, '__index');
+ lua_setmetatable(LState, -2);
+ lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName)));
+
+ // http://stackoverflow.com/questions/3449759/lua-c-api-and-metatable-functions
+ // lua_newtable(LState);
+ // lua_pushstring(LState, PAnsiChar('__handle__'));
+ // lua_pushlightuserdata(LState, Pointer(AObject));
+ // lua_settable(LState, - 3);
+ // {
+ // for prop in ctx.GetType(AObject.ClassInfo).GetProperties do
+ // begin
+ // v := prop.GetValue(AObject);
+ // if v.Kind = tkUnknown then
+ // continue;
+ // k := prop.Name;
+ // TLuaUtils.PushTValue(LState, k);
+ // TLuaUtils.PushTValue(LState, v);
+ // lua_settable(LState, - 3);
+ // end;
+ //
+ // for method in ctx.GetType(AObject.ClassInfo).GetMethods
+ // begin
+ // if not (method.Visibility in [mvPublic, mvPublished]) then
+ // continue;
+ // k := method.Name;
+ // TLuaUtils.PushTValue(LState, k);
+ // lua_pushcfunction(LState, @internal_call_method);
+ // lua_settable(LState, - 3);
+ // end;
+ // }
+ //
+ // lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName)));
+ //
+ // // define metatable
+ // // lua_createtable(LState, 0, 0);
+ // lua_createtable(LState, 0, 1);
+ // lua_pushcfunction(LState, @internal_call_method);
+ // lua_setfield(LState, - 2, AnsiString('__index'));
+ // lua_setmetatable(LState, - 2);
+ // lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName)));
+end;
+
+function TLuaEngine.DeclareGlobalFunction(AName: AnsiString;
+ AFunction: lua_CFunction): TLuaEngine;
+begin
+ lua_pushcfunction(LState, AFunction);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalInteger(AName: AnsiString; AValue: Integer)
+ : TLuaEngine;
+begin
+ lua_pushinteger(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalLightUserData(AName: AnsiString;
+ AValue: Pointer): TLuaEngine;
+begin
+ lua_pushlightuserdata(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalNil(AName: AnsiString): TLuaEngine;
+begin
+ lua_pushnil(LState);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalNumber(AName: AnsiString; AValue: Double)
+ : TLuaEngine;
+begin
+ lua_pushnumber(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalString(AName: AnsiString; AValue: AnsiString)
+ : TLuaEngine;
+begin
+ lua_pushstring(LState, PAnsiChar(AValue));
+ lua_setglobal(LState, PAnsiChar(AName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareGlobalUserData(AName: AnsiString; AValue: Pointer)
+ : TLuaEngine;
+begin
+ raise ELuaException.Create('Not implemented');
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString;
+ AKeys: array of Integer; AValues: array of string): TLuaEngine;
+var
+ I: Integer;
+ k: Integer;
+ v: string;
+begin
+ lua_newtable(LState);
+ for I := 0 to high(AKeys) do
+ begin
+ k := AKeys[I];
+ v := AValues[I];
+ TLuaUtils.PushTValue(LState, k);
+ TLuaUtils.PushTValue(LState, v);
+ lua_settable(LState, -3);
+ end;
+ lua_setglobal(LState, PAnsiChar(ATableName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString;
+ ADictionary: TDictionary): TLuaEngine;
+var
+ key: TValue;
+begin
+ lua_newtable(LState);
+ for key in ADictionary.Keys do
+ begin
+ TLuaUtils.PushTValue(LState, key);
+ TLuaUtils.PushTValue(LState, ADictionary.Items[key]);
+ lua_settable(LState, -3);
+ end;
+ lua_setglobal(LState, PAnsiChar(ATableName));
+ Result := Self;
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString;
+ ADictionary: TDictionary): TLuaEngine;
+var
+ key: string;
+begin
+ lua_newtable(LState);
+ for key in ADictionary.Keys do
+ begin
+ TLuaUtils.PushTValue(LState, key);
+ TLuaUtils.PushTValue(LState, ADictionary.Items[key]);
+ lua_settable(LState, -3);
+ end;
+ lua_setglobal(LState, PAnsiChar(ATableName));
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString;
+ AKeys: array of string; AValues: array of string): TLuaEngine;
+var
+ I: Integer;
+ k: string;
+ v: string;
+begin
+ lua_newtable(LState);
+ for I := 0 to high(AKeys) do
+ begin
+ k := AKeys[I];
+ v := AValues[I];
+ TLuaUtils.PushTValue(LState, k);
+ TLuaUtils.PushTValue(LState, v);
+ lua_settable(LState, -3);
+ end;
+ lua_setglobal(LState, PAnsiChar(ATableName));
+end;
+
+destructor TLuaEngine.Destroy;
+begin
+ CloseLua;
+ inherited;
+end;
+
+procedure TLuaEngine.Execute;
+var
+ r: Integer;
+begin
+ r := lua_pcall(LState, 0, 0, 0);
+ CheckLuaError(r);
+end;
+
+procedure TLuaEngine.CheckLuaError(const r: Integer);
+var
+ err: PAnsiChar;
+begin
+ case r of
+ // success
+ 0:
+ begin
+
+ end;
+ // a runtime error.
+ LUA_ERRRUN:
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaRuntimeException.CreateFmt('Runtime error [%s]', [err]);
+ end;
+ // memory allocation error. For such errors, Lua does not call the error handler function.
+ LUA_ERRMEM:
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.CreateFmt('Memory allocation error [%s]', [err]);
+ end;
+ // error while running the error handler function.
+ LUA_ERRERR:
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.CreateFmt
+ ('Error while running the error handler function [%s]', [err]);
+ end;
+ LUA_ERRSYNTAX:
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaSyntaxError.CreateFmt('Syntax Error [%s]', [err]);
+ end
+ else
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.CreateFmt('Unknown Error [%s]', [err]);
+ end;
+ end;
+end;
+
+procedure TLuaEngine.ExecuteFile(const AFileName: AnsiString);
+begin
+ LoadFromFile(AFileName);
+ Execute;
+end;
+
+function TLuaEngine.ExecuteFunction(FunctionName: AnsiString;
+ const Params: array of TValue): TValue;
+var
+ p: TValue;
+ r: Integer;
+begin
+ lua_getglobal(LState, PAnsiChar(FunctionName));
+ for p in Params do
+ TLuaUtils.PushTValue(LState, p);
+ r := lua_pcall(LState, Length(Params), 1, 0);
+ CheckLuaError(r);
+ Result := TLuaValue.PopTValueFromStack(LState);
+end;
+
+function TLuaEngine.GetGlobal(AName: AnsiString): ILuaValue;
+begin
+ lua_getglobal(LState, PAnsiChar(AName));
+ Result := TLuaValue.Create(LState, -1);
+end;
+
+function TLuaEngine.GetRawLuaState: Plua_State;
+begin
+ Result := LState;
+end;
+
+procedure TLuaEngine.InitLua;
+begin
+ LState := lua_open;
+ if not assigned(LState) then
+ raise ELuaException.Create('Cannot initialize Lua');
+ luaL_openlibs(LState);
+end;
+
+procedure TLuaEngine.LoadExternalLibraries(ALuaLibraryLoader
+ : ILuaLibraryLoader);
+begin
+ ALuaLibraryLoader.Execute(Self);
+end;
+
+procedure TLuaEngine.LoadFromFile(const AFileName: AnsiString);
+var
+ err: PAnsiChar;
+begin
+ if luaL_loadfile(LState, PAnsiChar(AFileName)) <> 0 then
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.Create(err);
+ end;
+end;
+
+procedure TLuaEngine.LoadScript(const AStream: TStream; AOwnStream: boolean);
+var
+ sr: TStreamReader;
+ s: string;
+begin
+ sr := TStreamReader.Create(AStream);
+ try
+ if AOwnStream then
+ sr.OwnStream;
+ s := sr.ReadToEnd;
+ LoadScript(s);
+ finally
+ sr.Free;
+ end;
+end;
+
+procedure TLuaEngine.Reset;
+begin
+ CloseLua;
+ InitLua;
+end;
+
+procedure TLuaEngine.ExecuteScript(const AScript: AnsiString);
+var
+ err: PAnsiChar;
+begin
+ if luaL_dostring(LState, PAnsiChar(AScript)) then
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.Create(err);
+ end;
+end;
+
+class function TLuaEngine.ExecuteWithResult(AScript: AnsiString;
+ const ParamNames, ParamValues: array of string): string;
+var
+ L: TLuaEngine;
+ I: Integer;
+begin
+ L := TLuaEngine.Create;
+ try
+ L.LoadScript(AScript);
+ if Length(ParamNames) <> Length(ParamValues) then
+ raise ELuaRuntimeException.Create
+ ('Number of params names and param values is not equals');
+ for I := 0 to Length(ParamNames) - 1 do
+ L.DeclareGlobalString(ParamNames[I], ParamValues[I]);
+ L.Execute;
+ finally
+ L.Free;
+ end;
+end;
+
+procedure TLuaEngine.LoadScript(const AScript: AnsiString);
+var
+ err: PAnsiChar;
+begin
+ if luaL_loadstring(LState, PAnsiChar(AScript)) <> 0 then
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.Create(err);
+ end;
+end;
+
+procedure TLuaEngine.InternalDeclareTable(AObject: TObject);
+var
+ prop: TRTTIProperty;
+ ctx: TRTTIContext;
+ properties: TArray;
+ k: AnsiString;
+ Value: TValue;
+ o: TObject;
+begin
+ ctx := TRTTIContext.Create;
+ try
+ lua_newtable(LState);
+ properties := ctx.GetType(AObject.ClassType).GetProperties;
+ for prop in properties do
+ begin
+ if not(prop.Visibility in [mvPublic, mvPublished]) then
+ continue;
+ k := prop.Name;
+ TLuaUtils.PushTValue(LState, k);
+ Value := prop.GetValue(AObject);
+ if Value.TypeInfo^.Kind = tkClass then
+ begin
+ o := Value.AsObject;
+ if not assigned(o) then
+ lua_pushnil(LState)
+ else
+ InternalDeclareTable(Value.AsObject);
+ end
+ else
+ begin
+ if Value.Kind = tkEnumeration then
+ begin
+ Value := prop.GetValue(AObject).AsOrdinal;
+ end;
+ TLuaUtils.PushTValue(LState, Value)
+ end;
+ lua_settable(LState, -3);
+ end;
+ finally
+ ctx.Free;
+ end;
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString; AObject: TObject)
+ : TLuaEngine;
+begin
+ InternalDeclareTable(AObject);
+ lua_setglobal(LState, PAnsiChar(ATableName));
+end;
+
+function TLuaEngine.DeclareTable(const ATableName: AnsiString; __self: Pointer;
+ AFunctions: TDictionary;
+ AData: TDictionary): TLuaEngine;
+var
+ key: string;
+begin
+ lua_newtable(LState);
+ TLuaUtils.PushTValue(LState, '__self');
+ lua_pushlightuserdata(LState, __self);
+ lua_settable(LState, -3);
+ for key in AFunctions.Keys do
+ begin
+ TLuaUtils.PushTValue(LState, key);
+ lua_pushcfunction(LState, AFunctions[key]);
+ lua_settable(LState, -3);
+ end;
+
+ if Assigned(AData) then
+ begin
+ for key in AData.Keys do
+ begin
+ TLuaUtils.PushTValue(LState, key);
+ TLuaUtils.PushTValue(LState, AData[key]);
+ lua_settable(LState, -3);
+ end;
+ end;
+
+ lua_setglobal(LState, PAnsiChar(ATableName));
+end;
+
+{ TLuaValue }
+
+class function TLuaValue.GetTValueFromLuaValueType(LuaValueType: TLuaValueType;
+ LuaState: Plua_State; StackIndex: Integer): TValue;
+var
+ a: AnsiString;
+begin
+ case LuaValueType of
+ lvtNil:
+ Result := nil;
+
+ lvtNumber:
+ Result := lua_tonumber(LuaState, StackIndex);
+
+ lvtInteger:
+ Result := lua_tointeger(LuaState, StackIndex);
+
+ lvtString:
+ begin
+ a := lua_tostring(LuaState, StackIndex);
+ Result := a;
+ end;
+
+ lvtBoolean:
+ Result := lua_toboolean(LuaState, StackIndex) = 1;
+
+ lvtLightUserData:
+ Result := TObject(lua_topointer(LuaState, StackIndex));
+
+ lvtTable:
+ begin
+ Result := GetAsLuaTable(LuaState, StackIndex);
+ end;
+
+ lvtFunction:
+ begin
+ raise ELuaException.Create('Not implemented');
+ // _lua_CFunction := lua_tocfunction(LuaState, StackIndex);
+ Result := nil; { todo }
+ end;
+
+ lvtUserData:
+ raise ELuaException.Create('UserData not allowed here');
+
+ lvtThread:
+ begin
+ raise ELuaException.Create('Not implemented');
+ // _pluastate := lua_tothread(LuaState, StackIndex);
+ Result := nil; { todo }
+ end;
+ end;
+end;
+
+constructor TLuaValue.Create(LuaState: Plua_State; StackIndex: Integer);
+begin
+ inherited Create;
+ FLuaValueType := GetLuaValueType(LuaState, StackIndex);
+ FValue := GetTValueFromLuaValueType(FLuaValueType, LuaState, StackIndex);
+end;
+
+class function TLuaValue.GetLuaValueType(LuaState: Plua_State;
+ StackIndex: Integer): TLuaValueType;
+begin
+ Result := lvtNil;
+ case lua_type(LuaState, StackIndex) of
+ lua_tnil:
+ Result := lvtNil;
+ LUA_TNUMBER:
+ Result := lvtNumber;
+ LUA_TBOOLEAN:
+ Result := lvtBoolean;
+ LUA_TSTRING:
+ Result := lvtString;
+ LUA_TTABLE:
+ Result := lvtTable;
+ LUA_TFUNCTION:
+ Result := lvtFunction;
+ LUA_TUSERDATA:
+ Result := lvtUserData;
+ LUA_TTHREAD:
+ Result := lvtThread;
+ LUA_TLIGHTUSERDATA:
+ Result := lvtLightUserData;
+ LUA_TNONE:
+ raise ELuaException.Create('Invalid stack index location');
+ end;
+end;
+
+procedure TLuaValue.CheckType(LuaValueType: TLuaValueType);
+begin
+ if FLuaValueType <> LuaValueType then
+ raise ELuaException.Create('Cannot access value as ' +
+ GetEnumName(TypeInfo(TLuaValueType), Ord(LuaValueType)) + ' while it is '
+ + GetEnumName(TypeInfo(TLuaValueType), Ord(FLuaValueType)));
+end;
+
+function TLuaValue.GetAsBoolean: boolean;
+begin
+ CheckType(lvtBoolean);
+ Result := FValue.AsBoolean;
+end;
+
+function TLuaValue.GetAsInteger: Integer;
+begin
+ Result := 0;
+ if Self.FLuaValueType = lvtNumber then
+ begin
+ if GetAsNumber = Trunc(GetAsNumber) then
+ Result := Trunc(GetAsNumber)
+ else
+ CheckType(lvtInteger);
+ end
+ else
+ begin
+ CheckType(lvtInteger);
+ Result := FValue.AsInteger;
+ end;
+end;
+
+function TLuaValue.GetAsLightUserData: Pointer;
+begin
+ CheckType(lvtLightUserData);
+ Result := Pointer(FValue.AsObject);
+end;
+
+class function TLuaValue.GetAsLuaTable(LuaState: Plua_State;
+ StackIndex: Integer): TValue;
+begin
+ raise ELuaException.Create('Not implemented');
+end;
+
+function TLuaValue.GetAsNumber: Double;
+begin
+ CheckType(lvtNumber);
+ Result := FValue.AsExtended;
+end;
+
+function TLuaValue.GetAsString: AnsiString;
+begin
+ CheckType(lvtString);
+ Result := FValue.AsString;
+end;
+
+function TLuaValue.IsBoolean: boolean;
+begin
+ Result := FLuaValueType = lvtBoolean;
+end;
+
+function TLuaValue.IsInteger: boolean;
+begin
+ Result := FLuaValueType = lvtInteger;
+end;
+
+function TLuaValue.IsLightUserData: boolean;
+begin
+ Result := FLuaValueType = lvtLightUserData;
+end;
+
+function TLuaValue.IsNil: boolean;
+begin
+ Result := FLuaValueType = lvtNil;
+end;
+
+function TLuaValue.IsNumber: boolean;
+begin
+ Result := FLuaValueType = lvtNumber;
+end;
+
+function TLuaValue.IsString: boolean;
+begin
+ Result := FLuaValueType = lvtString;
+end;
+
+class function TLuaValue.PopTValueFromStack(LuaState: Plua_State): TValue;
+var
+ lvt: TLuaValueType;
+begin
+ lvt := TLuaValue.GetLuaValueType(LuaState, -1);
+ Result := TLuaValue.GetTValueFromLuaValueType(lvt, LuaState, -1);
+ lua_pop(LuaState, 1);
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/README.md b/samples/serversideviews_lua/lua4delphi/README.md
new file mode 100644
index 00000000..fa0a1c27
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/README.md
@@ -0,0 +1,4 @@
+# lua4delphi
+Delphi binding for Lua 5.1 language
+
+This project was initially part of [DelphiMVCFramework](https://github.com/danieleteti/delphimvcframework) but now it is an indipendent project.
diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr
new file mode 100644
index 00000000..2ceabe90
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr
@@ -0,0 +1,27 @@
+program LuaEmbedded;
+
+{$APPTYPE CONSOLE}
+
+{$R *.res}
+
+
+uses
+ LuaBind.Filters.Text,
+ System.IOUtils;
+
+var
+ eLuaFilter: TLuaEmbeddedTextFilter;
+
+begin
+ eLuaFilter := TLuaEmbeddedTextFilter.Create;
+ try
+ eLuaFilter.OutputFunction := 'io.write';
+ eLuaFilter.TemplateCode := TFile.ReadAllText(ParamStr(1));
+ eLuaFilter.Execute;
+
+ TFile.WriteAllText(TPath.ChangeExtension(ParamStr(1), '.lua'), eLuaFilter.LuaCode);
+ finally
+ eLuaFilter.Free;
+ end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj
new file mode 100644
index 00000000..deb7d810
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj
@@ -0,0 +1,954 @@
+
+
+ {D2CDB6BD-1AC1-49D5-87D9-23DAE45069D0}
+ 19.3
+ None
+ LuaEmbedded.dpr
+ True
+ Debug
+ Win32
+ 1
+ Console
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ LuaEmbedded
+ $(BDS)\bin\delphi_PROJECTICNS.icns
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
+ fmx;IndySystem;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;DBXOracleDriver;CustomIPTransport;AureliusXE2;dsnap;IndyCore;fmxase;inetdbxpress;IPIndyImpl;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;DBXInformixDriver;DBXFirebirdDriver;inet;fmxobj;LKSL;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;$(DCC_UsePackage)
+ .\$(Platform)\$(Config)
+ .\$(Platform)\$(Config)
+
+
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ Debug
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ Debug
+ true
+ Base
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ JvGlobus;JvMM;JvDlgs;JvCrypt;TeeDB;Rave100VCL;vclib;inetdbbde;DBXSybaseASEDriver;vclimg;DataBindingsVCL160;fmi;vcldb;vcldsnap;dac160;unidacvcl160;DBXDb2Driver;Intraweb_120_160;dwsLibRuntime;JvCore;vclribbon;frxe16;vcl;CloudService;DBXMSSQLDriver;CodeSiteExpressPkg;unidac160;FmxTeeUI;JvAppFrm;JvRuntimeDesign;webdsnap;JclDeveloperTools;adortl;JvWizards;SimpleGraphPackage;NewAC;OpenWirePkgD16;vcldbx;frx16;DotNet4Delphi_XE2;crcontrols160;JclContainers;Tee;DataBindings;DBXOdbcDriver;JvCmp;JvSystem;svnui;adgrmxe2;JvControls;frxDB16;intrawebdb_120_160;fs16;vclactnband;FMXTee;TeeUI;bindcompvcl;JvStdCtrls;JvCustom;Jcl;vclie;vcltouch;dacvcl160;websnap;VclSmp;fsDB16;DataSnapConnectors;RlxPackage;dsnapcon;JclVcl;JvPascalInterpreter;vclx;Lua4Delphi;svn;bdertl;$(DCC_UsePackage)
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ 1033
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+
+
+ TeeDB;vclib;DBXSybaseASEDriver;vclimg;vcldb;vcldsnap;DBXDb2Driver;vcl;DBXMSSQLDriver;webdsnap;adortl;Tee;DBXOdbcDriver;adgrmxe2;vclactnband;TeeUI;bindcompvcl;vclie;vcltouch;websnap;VclSmp;DataSnapConnectors;dsnapcon;vclx;$(DCC_UsePackage)
+
+
+ DEBUG;$(DCC_Define)
+ false
+ true
+ true
+ true
+
+
+ test01.elua
+ ..\..\;$(DCC_UnitSearchPath)
+ None
+ 1033
+ false
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+
+ MainSource
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1040
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ (untitled)
+ (untitled)
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ 1
+
+
+ 0
+
+
+
+
+ classes
+ 64
+
+
+ classes
+ 64
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ False
+ False
+ True
+ False
+
+
+ 12
+
+
+
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua b/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua
new file mode 100644
index 00000000..2f96a931
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua
@@ -0,0 +1,13 @@
+This is a normal text file
+but now I'm start a Lua tag
+
+And now back to the simple text mode
+Expressions are supported too.
+Do you know what is the result of 5*5?
+5*5 =
+bye bye
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr
new file mode 100644
index 00000000..365a57e3
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr
@@ -0,0 +1,39 @@
+program LuaConsole;
+
+{$APPTYPE CONSOLE}
+{$R *.res}
+
+uses
+ LuaBind,
+ System.SysUtils,
+ LuaBind.Intf in '..\..\LuaBind.Intf.pas';
+
+var
+ LuaEngine: TLuaEngine;
+ ScriptDir, PackagePathToAppend: string;
+
+begin
+ try
+ LuaEngine := TLuaEngine.Create;
+ try
+ ScriptDir := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(1)));
+ PackagePathToAppend := ScriptDir + '?.lua';
+ LuaEngine.ExecuteScript('package.path = package.path .. ";' +
+ PackagePathToAppend.Replace('\', '\\') + '"' + sLineBreak +
+ '__SCRIPTFILE__ = "' + ParamStr(1).Replace('\', '\\') + '"' +
+ sLineBreak +
+ '__SCRIPTDIR__ = "' + ScriptDir.Replace('\', '\\') + '"' +
+ sLineBreak);
+ LuaEngine.LoadFromFile(ParamStr(1));
+ LuaEngine.Execute;
+ finally
+ LuaEngine.Free;
+ end;
+ except
+ on E: Exception do
+ Writeln(E.ClassName, ': ', E.Message);
+ end;
+ if DebugHook <> 0 then
+ readln;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj
new file mode 100644
index 00000000..ded31c90
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj
@@ -0,0 +1,994 @@
+
+
+ {F33CC2C0-360B-4A50-8D01-0DFBCF12DFD3}
+ 19.3
+ None
+ LuaConsole.dpr
+ True
+ Debug
+ Win32
+ 1
+ Console
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ LuaConsole
+ $(BDS)\bin\delphi_PROJECTICNS.icns
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
+ .\$(Platform)\$(Config)
+ .\$(Platform)\$(Config)
+ false
+ false
+ false
+ false
+ false
+
+
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ Debug
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ Debug
+ true
+ Base
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ true
+ Base
+ true
+ true
+ IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;DBXSqliteDriver;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;fmx;IndySystem;AnyDAC_PhysIB_D18;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;AnyDAC_PhysMSAcc_D18;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;IndyCore;IndyIPCommon;CloudService;FmxTeeUI;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;AnyDAC_PhysMySQL_D18;AnyDAC_Phys_D18;AnyDAC_Comp_D18;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;bindcompdbx;FMXTee;AnyDAC_PhysASA_D18;DBXInformixDriver;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;fmxobj;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage);$(DCC_UsePackage)
+
+
+ None
+ true
+ ..\..\;$(DCC_UnitSearchPath)
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ D:\DEV\bitPresenze30\servers\bpserver\data\e.lua
+ IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;NxGridDsgn_dxe3;DBXSqliteDriver;frxDB18;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;tmswizdXE4;fmx;IndySystem;TeeDB;frx18;AnyDAC_PhysIB_D18;inetdbbde;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;sample01adapters;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;NxDBGridDsgn_dxe3;vcldb;vcldsnap;AnyDAC_PhysMSAcc_D18;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;NxDBGridRun_dxe3;vclribbon;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;CodeSiteExpressPkg;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;webdsnap;AnyDAC_PhysMySQL_D18;NxCollectionRun_dxe3;adortl;CustomAdaptersMDPackage;AnyDAC_Phys_D18;NxCollectionDsgn_dxe3;NxGridRun_dxe3;NxCommonDsgn_dxe3;AnyDAC_Comp_D18;NxCommonRun_dxe3;bindcompfmx;tmsdXE4;BPAdapters;vcldbx;TextPkg;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;Tee;DBXOdbcDriver;NxAddonsRun_dxe3;dorm_runtime_xe4;xmlrtl;svnui;ibxpress;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;frxe18;vclactnband;bindengine;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;vcltouch;AnyDAC_PhysASA_D18;tmsexdXE4;VclSmp;DBXInformixDriver;Intraweb;DataSnapConnectors;NxInspectorRun_dxe3;dsnapcon;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;tmsxlsdXE4;fmxobj;vclx;svn;DBXSybaseASADriver;fmxdae;NxInspectorDsgn_dxe3;bdertl;VirtualTreesR;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage)
+ 1033
+
+
+ true
+ IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;NxGridDsgn_dxe3;DBXSqliteDriver;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;fmx;IndySystem;TeeDB;AnyDAC_PhysIB_D18;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;NxDBGridDsgn_dxe3;vcldb;vcldsnap;AnyDAC_PhysMSAcc_D18;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;NxDBGridRun_dxe3;vclribbon;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;webdsnap;AnyDAC_PhysMySQL_D18;NxCollectionRun_dxe3;adortl;AnyDAC_Phys_D18;NxCollectionDsgn_dxe3;NxGridRun_dxe3;NxCommonDsgn_dxe3;AnyDAC_Comp_D18;NxCommonRun_dxe3;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;Tee;DBXOdbcDriver;NxAddonsRun_dxe3;xmlrtl;ibxpress;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;vclactnband;bindengine;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;vcltouch;AnyDAC_PhysASA_D18;VclSmp;DBXInformixDriver;Intraweb;DataSnapConnectors;NxInspectorRun_dxe3;dsnapcon;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;fmxobj;vclx;DBXSybaseASADriver;fmxdae;NxInspectorDsgn_dxe3;VirtualTreesR;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage)
+
+
+ DEBUG;$(DCC_Define)
+ true
+ false
+ true
+ true
+ true
+
+
+ None
+ 1033
+ false
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+
+ MainSource
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ LuaConsole.dpr
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1040
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+ LuaConsole.exe
+ true
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ 1
+
+
+ 0
+
+
+
+
+ classes
+ 64
+
+
+ classes
+ 64
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ False
+ False
+ False
+ True
+ False
+
+
+ 12
+
+
+
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua b/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua
new file mode 100644
index 00000000..df0587bc
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua
@@ -0,0 +1,13 @@
+--print(package.path)
+
+--[[
+require'lfs'
+
+print(lfs.currentdir ())
+
+--table.foreach(_G, print)
+]]
+
+for i= 0,9 do
+ print(i)
+end
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua
new file mode 100644
index 00000000..f504b5a9
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua
@@ -0,0 +1,20 @@
+-- configuration file for program `pp'
+-- define window size
+
+theform = {
+ f = form,
+ setcaption = function (value)
+ _setcaption(theform.f, value)
+ end
+}
+
+width = 200
+height = x1+x2+x3;
+stringa = 'UPPERCASE='..delphiuppercase('daniele teti')..
+ 'Nome: '..daniele.nome..
+ 'Cognome: '..daniele.cognome..
+ 'Età: '..daniele.eta..
+ 'Il nome completo è: '..daniele:fullname()
+
+--theform:setcaption("Hello World")
+_setcaption( form, "ciao mondo" )
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua
new file mode 100644
index 00000000..e60cdc90
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua
@@ -0,0 +1,229 @@
+--[[ DataDumper.lua
+Copyright (c) 2007 Olivetti-Engineering SA
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+]]
+
+local dumplua_closure = [[
+local closures = {}
+local function closure(t)
+ closures[#closures+1] = t
+ t[1] = assert(loadstring(t[1]))
+ return t[1]
+end
+
+for _,t in pairs(closures) do
+ for i = 2,#t do
+ debug.setupvalue(t[1], i-1, t[i])
+ end
+end
+]]
+
+local lua_reserved_keywords = {
+ 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',
+ 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
+ 'return', 'then', 'true', 'until', 'while' }
+
+local function keys(t)
+ local res = {}
+ local oktypes = { stringstring = true, numbernumber = true }
+ local function cmpfct(a,b)
+ if oktypes[type(a)..type(b)] then
+ return a < b
+ else
+ return type(a) < type(b)
+ end
+ end
+ for k in pairs(t) do
+ res[#res+1] = k
+ end
+ table.sort(res, cmpfct)
+ return res
+end
+
+local c_functions = {}
+for _,lib in pairs{'_G', 'string', 'table', 'math',
+ 'io', 'os', 'coroutine', 'package', 'debug'} do
+ local t = _G[lib] or {}
+ lib = lib .. "."
+ if lib == "_G." then lib = "" end
+ for k,v in pairs(t) do
+ if type(v) == 'function' and not pcall(string.dump, v) then
+ c_functions[v] = lib..k
+ end
+ end
+end
+
+function DataDumper(value, varname, fastmode, ident)
+ local defined, dumplua = {}
+ -- Local variables for speed optimization
+ local string_format, type, string_dump, string_rep =
+ string.format, type, string.dump, string.rep
+ local tostring, pairs, table_concat =
+ tostring, pairs, table.concat
+ local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0
+ setmetatable(strvalcache, {__index = function(t,value)
+ local res = string_format('%q', value)
+ t[value] = res
+ return res
+ end})
+ local fcts = {
+ string = function(value) return strvalcache[value] end,
+ number = function(value) return value end,
+ boolean = function(value) return tostring(value) end,
+ ['nil'] = function(value) return 'nil' end,
+ ['function'] = function(value)
+ return string_format("loadstring(%q)", string_dump(value))
+ end,
+ userdata = function() error("Cannot dump userdata") end,
+ thread = function() error("Cannot dump threads") end,
+ }
+ local function test_defined(value, path)
+ if defined[value] then
+ if path:match("^getmetatable.*%)$") then
+ out[#out+1] = string_format("s%s, %s)\n", path:sub(2,-2), defined[value])
+ else
+ out[#out+1] = path .. " = " .. defined[value] .. "\n"
+ end
+ return true
+ end
+ defined[value] = path
+ end
+ local function make_key(t, key)
+ local s
+ if type(key) == 'string' and key:match('^[_%a][_%w]*$') then
+ s = key .. "="
+ else
+ s = "[" .. dumplua(key, 0) .. "]="
+ end
+ t[key] = s
+ return s
+ end
+ for _,k in ipairs(lua_reserved_keywords) do
+ keycache[k] = '["'..k..'"] = '
+ end
+ if fastmode then
+ fcts.table = function (value)
+ -- Table value
+ local numidx = 1
+ out[#out+1] = "{"
+ for key,val in pairs(value) do
+ if key == numidx then
+ numidx = numidx + 1
+ else
+ out[#out+1] = keycache[key]
+ end
+ local str = dumplua(val)
+ out[#out+1] = str..","
+ end
+ if string.sub(out[#out], -1) == "," then
+ out[#out] = string.sub(out[#out], 1, -2);
+ end
+ out[#out+1] = "}"
+ return ""
+ end
+ else
+ fcts.table = function (value, ident, path)
+ if test_defined(value, path) then return "nil" end
+ -- Table value
+ local sep, str, numidx, totallen = " ", {}, 1, 0
+ local meta, metastr = (debug or getfenv()).getmetatable(value)
+ if meta then
+ ident = ident + 1
+ metastr = dumplua(meta, ident, "getmetatable("..path..")")
+ totallen = totallen + #metastr + 16
+ end
+ for _,key in pairs(keys(value)) do
+ local val = value[key]
+ local s = ""
+ local subpath = path
+ if key == numidx then
+ subpath = subpath .. "[" .. numidx .. "]"
+ numidx = numidx + 1
+ else
+ s = keycache[key]
+ if not s:match "^%[" then subpath = subpath .. "." end
+ subpath = subpath .. s:gsub("%s*=%s*$","")
+ end
+ s = s .. dumplua(val, ident+1, subpath)
+ str[#str+1] = s
+ totallen = totallen + #s + 2
+ end
+ if totallen > 80 then
+ sep = "\n" .. string_rep(" ", ident+1)
+ end
+ str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-3).."}"
+ if meta then
+ sep = sep:sub(1,-3)
+ return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")"
+ end
+ return str
+ end
+ fcts['function'] = function (value, ident, path)
+ if test_defined(value, path) then return "nil" end
+ if c_functions[value] then
+ return c_functions[value]
+ elseif debug == nil or debug.getupvalue(value, 1) == nil then
+ return string_format("loadstring(%q)", string_dump(value))
+ end
+ closure_cnt = closure_cnt + 1
+ local res = {string.dump(value)}
+ for i = 1,math.huge do
+ local name, v = debug.getupvalue(value,i)
+ if name == nil then break end
+ res[i+1] = v
+ end
+ return "closure " .. dumplua(res, ident, "closures["..closure_cnt.."]")
+ end
+ end
+ function dumplua(value, ident, path)
+ return fcts[type(value)](value, ident, path)
+ end
+ if varname == nil then
+ varname = "return "
+ elseif varname:match("^[%a_][%w_]*$") then
+ varname = varname .. " = "
+ end
+ if fastmode then
+ setmetatable(keycache, {__index = make_key })
+ out[1] = varname
+ table.insert(out,dumplua(value, 0))
+ return table.concat(out)
+ else
+ setmetatable(keycache, {__index = make_key })
+ local items = {}
+ for i=1,10 do items[i] = '' end
+ items[3] = dumplua(value, ident or 0, "t")
+ if closure_cnt > 0 then
+ items[1], items[6] = dumplua_closure:match("(.*\n)\n(.*)")
+ out[#out+1] = ""
+ end
+ if #out > 0 then
+ items[2], items[4] = "local t = ", "\n"
+ items[5] = table.concat(out)
+ items[7] = varname .. "t"
+ else
+ items[2] = varname
+ end
+ return table.concat(items)
+ end
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua
new file mode 100644
index 00000000..f8871933
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua
@@ -0,0 +1,5 @@
+Ciao
+
+mondo
+
+close
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua
new file mode 100644
index 00000000..1bf01ea4
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua
@@ -0,0 +1,10 @@
+io.write [[
+Ciao
+]] io.write("hello")
+io.write [[
+
+mondo
+]] io.write("world")
+io.write [[
+
+close]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua
new file mode 100644
index 00000000..51044dd1
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua
@@ -0,0 +1,6 @@
+Ciao
+
+mondo
+
+Hi, my name is . What's your name?
+close
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua
new file mode 100644
index 00000000..a49379a9
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua
@@ -0,0 +1,13 @@
+io.write [[
+Ciao
+]] io.write("hello")
+io.write [[
+
+mondo
+]] io.write("world")
+io.write [[
+
+Hi, my name is ]]io.write( "Daniele Teti" )
+io.write [[
+. What's your name?
+close]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua
new file mode 100644
index 00000000..2fe3f521
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua
@@ -0,0 +1,26 @@
+
+
+Hello DWS
+
+
+Hello DWS
+This page was generated at .
+Some test links
+Some facts:
');
+ print_facts(i);
+ print('');
+end
+?>
+
+
+
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua
new file mode 100644
index 00000000..4e279a3a
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua
@@ -0,0 +1,29 @@
+io.write [[
+
+
+Hello DWS
+
+
+Hello DWS
+This page was generated at .
+Some test links
+Some facts:
]]
+
+function print_facts(i)
+ print(tostring(i) .. ' + ' .. tostring(i) .. ' = ' .. tostring(i+i))
+end
+
+for i = 1,5 do
+ print('- ');
+ print_facts(i);
+ print('
');
+end
+
+io.write [[
+
+
+
+]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.elua
new file mode 100644
index 00000000..e69de29b
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.lua
new file mode 100644
index 00000000..e69de29b
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua
new file mode 100644
index 00000000..9e21ae5a
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua
@@ -0,0 +1,2 @@
+
+Hello World
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua
new file mode 100644
index 00000000..2cd0861f
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua
@@ -0,0 +1,6 @@
+ local x = 1
+io.write [[
+
+Hello World ]]io.write( x)
+io.write [[
+]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua
new file mode 100644
index 00000000..0cae4c2a
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua
@@ -0,0 +1,9 @@
+Hello There
+
+
+"
+?>
+
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua
new file mode 100644
index 00000000..4018596e
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua
@@ -0,0 +1,18 @@
+io.write [[
+Hello There
+]]
+local x = "This is an open tag "
+
+io.write [[
+
+]]io.write(y)
+io.write [[
+]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua
new file mode 100644
index 00000000..28da7872
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua
@@ -0,0 +1,9 @@
+Hello There
+
+
+
+
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua
new file mode 100644
index 00000000..07c8a56e
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua
@@ -0,0 +1,18 @@
+io.write [[
+Hello There
+]]
+local x = "Here there is an \" escaped double quote\""
+
+io.write [[
+
+]]io.write(x)
+io.write [[
+
+]]
+local y = "Here there is only one \" escaped double quote"
+
+io.write [[
+
+]]io.write(y)
+io.write [[
+]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat
new file mode 100644
index 00000000..531fed66
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat
@@ -0,0 +1 @@
+lua %1 > "%1.txt"
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua
new file mode 100644
index 00000000..04a86cb6
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua
@@ -0,0 +1,189 @@
+-------------------------------------------------------------------------------
+-- includes a new tostring function that handles tables recursively
+--
+-- @author Danilo Tuler (tuler@ideais.com.br)
+-- @author Andre Carregal (info@keplerproject.org)
+-- @author Thiago Costa Ponte (thiago@ideais.com.br)
+--
+-- @copyright 2004-2011 Kepler Project
+-------------------------------------------------------------------------------
+
+local type, table, string, _tostring, tonumber = type, table, string, tostring, tonumber
+local select = select
+local error = error
+local format = string.format
+
+module("logging")
+
+-- Meta information
+_COPYRIGHT = "Copyright (C) 2004-2011 Kepler Project"
+_DESCRIPTION = "A simple API to use logging features in Lua"
+_VERSION = "LuaLogging 1.1.4"
+
+-- The DEBUG Level designates fine-grained instring.formational events that are most
+-- useful to debug an application
+DEBUG = "DEBUG"
+
+-- The INFO level designates instring.formational messages that highlight the
+-- progress of the application at coarse-grained level
+INFO = "INFO"
+
+-- The WARN level designates potentially harmful situations
+WARN = "WARN"
+
+-- The ERROR level designates error events that might still allow the
+-- application to continue running
+ERROR = "ERROR"
+
+-- The FATAL level designates very severe error events that will presumably
+-- lead the application to abort
+FATAL = "FATAL"
+
+local LEVEL = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
+local MAX_LEVELS = #LEVEL
+-- make level names to order
+for i=1,MAX_LEVELS do
+ LEVEL[LEVEL[i]] = i
+end
+
+-- private log function, with support for formating a complex log message.
+local function LOG_MSG(self, level, fmt, ...)
+ local f_type = type(fmt)
+ if f_type == 'string' then
+ if select('#', ...) > 0 then
+ return self:append(level, format(fmt, ...))
+ else
+ -- only a single string, no formating needed.
+ return self:append(level, fmt)
+ end
+ elseif f_type == 'function' then
+ -- fmt should be a callable function which returns the message to log
+ return self:append(level, fmt(...))
+ end
+ -- fmt is not a string and not a function, just call tostring() on it.
+ return self:append(level, tostring(fmt))
+end
+
+-- create the proxy functions for each log level.
+local LEVEL_FUNCS = {}
+for i=1,MAX_LEVELS do
+ local level = LEVEL[i]
+ LEVEL_FUNCS[i] = function(self, ...)
+ -- no level checking needed here, this function will only be called if it's level is active.
+ return LOG_MSG(self, level, ...)
+ end
+end
+
+-- do nothing function for disabled levels.
+local function disable_level() end
+
+-- improved assertion funciton.
+local function assert(exp, ...)
+ -- if exp is true, we are finished so don't do any processing of the parameters
+ if exp then return exp, ... end
+ -- assertion failed, raise error
+ error(format(...), 2)
+end
+
+-------------------------------------------------------------------------------
+-- Creates a new logger object
+-- @param append Function used by the logger to append a message with a
+-- log-level to the log stream.
+-- @return Table representing the new logger object.
+-------------------------------------------------------------------------------
+function new(append)
+
+ if type(append) ~= "function" then
+ return nil, "Appender must be a function."
+ end
+
+ local logger = {}
+ logger.append = append
+
+ logger.setLevel = function (self, level)
+ local order = LEVEL[level]
+ assert(order, "undefined level `%s'", _tostring(level))
+ self.level = level
+ self.level_order = order
+ -- enable/disable levels
+ for i=1,MAX_LEVELS do
+ local name = LEVEL[i]:lower()
+ if i >= order then
+ self[name] = LEVEL_FUNCS[i]
+ else
+ self[name] = disable_level
+ end
+ end
+ end
+
+ -- generic log function.
+ logger.log = function (self, level, ...)
+ local order = LEVEL[level]
+ assert(order, "undefined level `%s'", _tostring(level))
+ if order < self.level_order then
+ return
+ end
+ return LOG_MSG(self, level, ...)
+ end
+
+ -- initialize log level.
+ logger:setLevel(DEBUG)
+ return logger
+end
+
+
+-------------------------------------------------------------------------------
+-- Prepares the log message
+-------------------------------------------------------------------------------
+function prepareLogMsg(pattern, dt, level, message)
+
+ local logMsg = pattern or "%date %level %message\n"
+ message = string.gsub(message, "%%", "%%%%")
+ logMsg = string.gsub(logMsg, "%%date", dt)
+ logMsg = string.gsub(logMsg, "%%level", level)
+ logMsg = string.gsub(logMsg, "%%message", message)
+ return logMsg
+end
+
+
+-------------------------------------------------------------------------------
+-- Converts a Lua value to a string
+--
+-- Converts Table fields in alphabetical order
+-------------------------------------------------------------------------------
+function tostring(value)
+ local str = ''
+
+ if (type(value) ~= 'table') then
+ if (type(value) == 'string') then
+ str = string.format("%q", value)
+ else
+ str = _tostring(value)
+ end
+ else
+ local auxTable = {}
+ table.foreach(value, function(i, v)
+ if (tonumber(i) ~= i) then
+ table.insert(auxTable, i)
+ else
+ table.insert(auxTable, tostring(i))
+ end
+ end)
+ table.sort(auxTable)
+
+ str = str..'{'
+ local separator = ""
+ local entry = ""
+ table.foreachi (auxTable, function (i, fieldName)
+ if ((tonumber(fieldName)) and (tonumber(fieldName) > 0)) then
+ entry = tostring(value[tonumber(fieldName)])
+ else
+ entry = fieldName.." = "..tostring(value[fieldName])
+ end
+ str = str..separator..entry
+ separator = ", "
+ end)
+ str = str..'}'
+ end
+ return str
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua
new file mode 100644
index 00000000..69ef7ea7
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua
@@ -0,0 +1,27 @@
+sample = {}
+
+local function getvalue (self, key, args)
+ print ("retrieving", key)
+ if (key == 'pippo') then
+ return function (p1,p2,p3,p4,p5,p6) return p2 end
+ end
+ return "__newindex "..key
+end
+
+local function setvalue(self,key,value)
+ print ("setting",key,"to",value)
+ -- ... do some here with key / values
+end
+
+local function oncall(self, key, args)
+ print("function calling...")
+ print(key)
+end
+
+setmetatable(sample,{__index = getvalue, __newindex = setvalue, __call = oncall})
+
+--sample['hello'] = 'world';
+--print(sample['hello']);
+--print(sample(123))
+
+print(sample:pippo(23))
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua
new file mode 100644
index 00000000..261ae37c
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua
@@ -0,0 +1,18 @@
+io.write [[
+This is a normal text file
+but now I'm start a Lua tag
+]]
+ --here I can write simple Lua code
+ for i = 1,5 do
+ print("i = " .. tostring(i));
+ end
+
+io.write [[
+
+And now back to the simple text mode
+Expressions are supported too.
+Do you know what is the result of 5*5?
+5*5 = ]]io.write( 5*5 )
+io.write [[
+
+bye bye]]
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua
new file mode 100644
index 00000000..f1dca35d
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua
@@ -0,0 +1,9 @@
+a = {
+ nome = "Daniele",
+ cognome = "Teti",
+ eta = 32
+ }
+
+for k,v in pairs(a) do
+ print(k..'='..v)
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua
new file mode 100644
index 00000000..687eec44
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua
@@ -0,0 +1,2 @@
+days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
+print(days[3]);
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua
new file mode 100644
index 00000000..a86f71c7
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua
@@ -0,0 +1,9 @@
+require"logging.console"
+
+local logger = logging.console()
+
+logger:info("logging.console test")
+logger:debug("debugging...")
+logger:error("error!")
+logger:debug("string with %4")
+print("Console Logging OK")
\ No newline at end of file
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua
new file mode 100644
index 00000000..1a2b111c
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua
@@ -0,0 +1,6 @@
+require "logging.file"
+local logger = logging.file("__TEST%s.log", "%Y-%m-%d")
+logger:info("logging.file test")
+logger:debug("debugging...")
+logger:error("error!")
+logger:info({id = "1"})
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua
new file mode 100644
index 00000000..3b24fa28
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua
@@ -0,0 +1,5 @@
+local x = 1+2+3;
+local s = "Hello World";
+if (x > 2) then
+ print(s);
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua
new file mode 100644
index 00000000..7917c789
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua
@@ -0,0 +1,23 @@
+require "lua_taival.datasets"
+
+local s = open_dataset(people);
+s.first();
+local f = io.open("test_02.txt", "w")
+while not s.eof() do
+ f:write(s.get('first_name').." "..s.get('last_name').." "..s.get('born_date').." "..s.get("is_male").."\n")
+ s.movenext()
+end;
+s.close()
+
+f:write(tostring(s.is_open()))
+s.open()
+f:write(tostring(s.is_open()))
+s.movenext()
+f:write(tostring(s.is_open()))
+s.first()
+f:write(tostring(s.is_open()))
+s.movenext()
+f:write(tostring(s.is_open()))
+s.close()
+f:write(tostring(s.is_open()))
+f:close()
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua
new file mode 100644
index 00000000..464727b8
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua
@@ -0,0 +1,26 @@
+require "lua_taival.delphiobjects"
+require "logging.file"
+
+logger = logging.file("test_03_TEST.log")
+
+local s = connect_to_delphi_object(person);
+s.FirstName = "Daniele";
+s.LastName = "Teti";
+s.Age = 30;
+
+
+
+s.BecomeOlder(2);
+first_name = s.FirstName;
+last_name = s.LastName;
+full_name = s.GetFullName('Mr.');
+age = s.Age;
+
+
+--reading property
+local name = s.LastName
+
+--writing a property
+s.LastName = "Teti" --you can write to a property in this way
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua
new file mode 100644
index 00000000..59babc91
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua
@@ -0,0 +1,10 @@
+require "lua_taival.delphiobjects"
+require "logging.file"
+logger = logging.file("test_04_TEST_%s.log", "%Y-%m-%d")
+
+local sl = connect_to_delphi_object(stringlist);
+
+sl.Add("two");
+sl.Add("three");
+sl.Add("four");
+logger:debug(sl.Text);
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua
new file mode 100644
index 00000000..2379d39e
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua
@@ -0,0 +1,7 @@
+require "lua_taival.delphiobjects"
+require "logging.file"
+logger = logging.file("test_05_TEST_%s.log", "%Y-%m-%d")
+
+local sl = connect_to_delphi_object(stringlist);
+sl.Text = "Daniele Teti"
+logger:debug(sl.Text);
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua
new file mode 100644
index 00000000..91bf2816
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua
@@ -0,0 +1,8 @@
+require "lua_taival.delphiobjects"
+require "logging.file"
+logger = logging.file("test_06_TEST.log")
+
+local sl = create_delphi_object('System.Classes.TStringList')
+sl.Text = "Daniele Teti"
+logger:debug('Ecco il contenuto della TStringList: '..sl.Text);
+sl.Free();
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua
new file mode 100644
index 00000000..bf524b1e
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua
@@ -0,0 +1,6 @@
+require "lua_taival.delphiobjects"
+require "logging.file"
+logger = logging.file("test_07_TEST_%s.log", "%Y-%m-%d")
+
+--this should raise an exception
+local fs = create_delphi_object('System.Classes.TFileStream');
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua
new file mode 100644
index 00000000..591ea320
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua
@@ -0,0 +1,3 @@
+function myfunc(a,b,c)
+ return a..b..c
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua
new file mode 100644
index 00000000..2ad020c8
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua
@@ -0,0 +1,5 @@
+local sl = TStringList.new()
+sl:add('Hello World')
+--sl.add('Hello World2')
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr
new file mode 100644
index 00000000..0316deab
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr
@@ -0,0 +1,21 @@
+program LuaPlayground;
+
+uses
+ Vcl.Forms,
+ Unit11 in 'Unit11.pas' {MainForm},
+ LuaBind.Intf in '..\..\LuaBind.Intf.pas',
+ LuaBind in '..\..\LuaBind.pas',
+ LuaBind.CustomType.DataSet in '..\..\LuaBind.CustomType.DataSet.pas',
+ LuaBind.DelphiObjects in '..\..\LuaBind.DelphiObjects.pas';
+
+{$R *.res}
+
+
+begin
+ ReportMemoryLeaksOnShutdown := True;
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.CreateForm(TMainForm, MainForm);
+ Application.Run;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj
new file mode 100644
index 00000000..6a2d1e47
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj
@@ -0,0 +1,989 @@
+
+
+ {F2D71A9C-D7E4-4B13-9AB9-F8ED3349D646}
+ 19.3
+ VCL
+ LuaPlayground.dpr
+ True
+ Debug
+ Win32
+ 1
+ Application
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage)
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
+ .\$(Platform)\$(Config)
+ .\$(Platform)\$(Config)
+ false
+ false
+ false
+ false
+ false
+ LuaPlayground
+
+
+ OpenWirePkgD16;vcldbx;frx16;TeeDB;Rave100VCL;vclib;Tee;inetdbbde;DBXOdbcDriver;DBXSybaseASEDriver;ibxpress;svnui;vclimg;OpenWireLabPkgD16;intrawebdb_120_160;fmi;frxDB16;fs16;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;SynEdit_RXE2;vclie;vcltouch;Intraweb_120_160;DBXDb2Driver;websnap;dwsLibRuntime;vclribbon;VclSmp;fsDB16;frxe16;vcl;DataSnapConnectors;UIBD16Win32R;CodeSiteExpressPkg;CloudService;DBXMSSQLDriver;FmxTeeUI;dsnapcon;RlxPackage;DataSnapServerConnectionMonitoring;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage)
+ true
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ 1033
+ $(BDS)\bin\default_app.manifest
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ true
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ DBXOdbcDriver;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;SynEdit_RXE2;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DataSnapConnectors;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;$(DCC_UsePackage)
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
+ $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
+
+
+ DEBUG;$(DCC_Define)
+ false
+ true
+ true
+ true
+
+
+ false
+ Debug
+ ..\bin
+ true
+ 1033
+ true
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+
+ MainSource
+
+
+
+ dfm
+
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1040
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ LuaPlayground.dpr
+
+
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+
+
+
+ LuaPlayground.exe
+ true
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ classes
+ 64
+
+
+ classes
+ 64
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ Contents\MacOS
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ Contents\MacOS
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ Contents\Resources\StartUp\
+ 0
+
+
+ 0
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+
+
+ C:\Users\Daniele\Desktop\luawrapper\unittests\LuaTestTests.dproj
+
+
+ 12
+
+
+
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas
new file mode 100644
index 00000000..afa885f3
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas
@@ -0,0 +1,401 @@
+unit LuaWrapper;
+
+interface
+
+uses dorLua,
+ System.Classes,
+ System.SysUtils,
+ System.Rtti;
+
+type
+ ELuaException = class(Exception)
+
+ end;
+
+ ILuaValue = interface
+ ['{8621BAD3-B847-4176-937F-2CD016BBE13E}']
+ /// ///
+ function IsNil: boolean;
+ function IsNumber: boolean;
+ function IsInteger: boolean;
+ function IsString: boolean;
+ function IsBoolean: boolean;
+ function IsLightUserData: boolean;
+ /// ///
+ function GetAsNumber: Double;
+ function GetAsInteger: Integer;
+ function GetAsString: AnsiString;
+ function GetAsBoolean: boolean;
+ function GetAsLightUserData: Pointer;
+ end;
+
+ TLuaValueType = (lvtNil, lvtNumber, lvtInteger, lvtString, lvtBoolean, lvtLightUserData,
+ lvtTable, lvtFunction, lvtUserData, lvtThread);
+
+ TLuaValue = class(TInterfacedObject, ILuaValue)
+ strict private
+ FLuaValueType: TLuaValueType;
+ strict
+ private
+
+ protected
+ /// ///
+ function IsNil: boolean;
+ function IsNumber: boolean;
+ function IsInteger: boolean;
+ function IsString: boolean;
+ function IsBoolean: boolean;
+ function IsLightUserData: boolean;
+ /// ///
+ function GetAsNumber: Double;
+ function GetAsInteger: Integer;
+ function GetAsString: AnsiString;
+ function GetAsBoolean: boolean;
+ function GetAsLightUserData: Pointer;
+ private
+ procedure CheckType(LuaValueType: TLuaValueType);
+ protected
+ FValue: TValue;
+ constructor Create(LuaState: Plua_State; StackIndex: Integer);
+ { todo }
+ function GetAsLuaTable(LuaState: Plua_State; StackIndex: Integer): TValue;
+ public
+ class function GetLuaValueType(LuaState: Plua_State; StackIndex: Integer): TLuaValueType;
+ end;
+
+ TLuaEngine = class
+ strict protected
+ LState: Plua_State;
+ public
+ constructor Create; overload; virtual;
+ constructor Create(const AScript: String); overload; virtual;
+ destructor Destroy; override;
+ procedure LoadScript(const AScript: AnsiString); overload;
+ procedure LoadScript(const AStream: TStream; AOwnStream: boolean = true); overload;
+ procedure LoadFromFile(const AFileName: String);
+ procedure Execute;
+
+ // PUSH methods for simple types
+ function DeclareGlobalNil(AName: AnsiString): TLuaEngine;
+ function DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine;
+ function DeclareGlobalInteger(AName: AnsiString; AValue: Integer): TLuaEngine;
+ function DeclareGlobalString(AName: AnsiString; AValue: AnsiString): TLuaEngine;
+ function DeclareGlobalBoolean(AName: AnsiString; AValue: boolean): TLuaEngine;
+ function DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer): TLuaEngine;
+
+ // GET methods for simple types
+ function GetGlobal(AName: AnsiString): ILuaValue;
+ end;
+
+implementation
+
+{ TLuaEngine }
+
+constructor TLuaEngine.Create;
+begin
+ inherited Create;
+ LState := lua_open;
+ if not assigned(LState) then
+ raise ELuaException.Create('Cannot initialize Lua');
+ luaL_openlibs(LState);
+end;
+
+constructor TLuaEngine.Create(const AScript: String);
+begin
+ Create;
+ LoadScript(AScript);
+end;
+
+function TLuaEngine.DeclareGlobalBoolean(AName: AnsiString; AValue: boolean): TLuaEngine;
+var
+ b: Integer;
+begin
+ if AValue then
+ b := 1
+ else
+ b := 0;
+ lua_pushboolean(LState, b);
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+function TLuaEngine.DeclareGlobalInteger(AName: AnsiString; AValue: Integer): TLuaEngine;
+begin
+ lua_pushinteger(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+function TLuaEngine.DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer): TLuaEngine;
+begin
+ lua_pushlightuserdata(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+function TLuaEngine.DeclareGlobalNil(AName: AnsiString): TLuaEngine;
+begin
+ lua_pushnil(LState);
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+function TLuaEngine.DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine;
+begin
+ lua_pushnumber(LState, AValue);
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+function TLuaEngine.DeclareGlobalString(AName: AnsiString; AValue: AnsiString): TLuaEngine;
+begin
+ lua_pushstring(LState, PAnsiChar(AValue));
+ lua_setglobal(LState, PAnsiChar(AName));
+end;
+
+destructor TLuaEngine.Destroy;
+begin
+ lua_close(LState);
+ inherited;
+end;
+
+procedure TLuaEngine.Execute;
+var
+ err: PAnsiChar;
+ r: Integer;
+begin
+ r := lua_pcall(LState, 0, 0, 0);
+ case r of
+ // success
+ 0:
+ begin
+ lua_pop(LState, lua_gettop(LState));
+ end;
+ // a runtime error.
+ LUA_ERRRUN:
+ begin
+ err := lua_tostring(LState, -1);
+ raise ELuaException.CreateFmt('Runtime error [%s]', [err]);
+ lua_pop(LState, 1);
+ end;
+ // memory allocation error. For such errors, Lua does not call the error handler function.
+ LUA_ERRMEM:
+ begin
+ err := lua_tostring(LState, -1);
+ raise ELuaException.CreateFmt('Memory allocation error [%s]', [err]);
+ lua_pop(LState, 1);
+ end;
+ // error while running the error handler function.
+ LUA_ERRERR:
+ begin
+ err := lua_tostring(LState, -1);
+ raise ELuaException.CreateFmt('Error while running the error handler function [%s]', [err]);
+ lua_pop(LState, 1);
+ end;
+ else
+ begin
+ err := lua_tostring(LState, -1);
+ raise ELuaException.CreateFmt('Unknown Error [%s]', [err]);
+ lua_pop(LState, 1);
+ end;
+ end;
+end;
+
+function TLuaEngine.GetGlobal(AName: AnsiString): ILuaValue;
+begin
+ lua_getglobal(LState, PAnsiChar(AName));
+ Result := TLuaValue.Create(LState, -1);
+end;
+
+procedure TLuaEngine.LoadFromFile(const AFileName: String);
+var
+ err: PAnsiChar;
+begin
+ if luaL_loadfile(LState, PAnsiChar(AFileName)) <> 0 then
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.Create(err);
+ end;
+end;
+
+procedure TLuaEngine.LoadScript(const AStream: TStream; AOwnStream: boolean);
+var
+ sr: TStreamReader;
+ s: string;
+begin
+ sr := TStreamReader.Create(AStream);
+ try
+ if AOwnStream then
+ sr.OwnStream;
+ s := sr.ReadToEnd;
+ LoadScript(s);
+ finally
+ sr.Free;
+ end;
+end;
+
+procedure TLuaEngine.LoadScript(const AScript: AnsiString);
+var
+ err: PAnsiChar;
+begin
+ if luaL_loadstring(LState,
+ PAnsiChar(AScript)) <> 0 then
+ begin
+ err := lua_tostring(LState, -1);
+ lua_pop(LState, 1);
+ raise ELuaException.Create(err);
+ end;
+end;
+
+{ TLuaValue }
+
+constructor TLuaValue.Create(LuaState: Plua_State; StackIndex: Integer);
+var
+ a: AnsiString;
+ _lua_CFunction: lua_CFunction;
+ _pluastate: Plua_State;
+begin
+ inherited Create;
+ FLuaValueType := GetLuaValueType(LuaState, StackIndex);
+
+ case FLuaValueType of
+ lvtNil:
+ FValue := nil;
+
+ lvtNumber:
+ FValue := lua_tonumber(LuaState, StackIndex);
+
+ lvtInteger:
+ FValue := lua_tointeger(LuaState, StackIndex);
+
+ lvtString:
+ begin
+ a := lua_tostring(LuaState, StackIndex);
+ FValue := a;
+ end;
+
+ lvtBoolean:
+ FValue := lua_toboolean(LuaState, StackIndex) = 1;
+
+ lvtLightUserData:
+ FValue := lua_topointer(LuaState, StackIndex);
+
+ lvtTable:
+ begin
+ FValue := GetAsLuaTable(LuaState, StackIndex);
+ end;
+
+ lvtFunction:
+ begin
+ _lua_CFunction := lua_tocfunction(LuaState, StackIndex);
+ FValue := nil; { todo }
+ end;
+
+ lvtUserData:
+ FValue := lua_touserdata(LuaState, StackIndex);
+
+ lvtThread:
+ begin
+ _pluastate := lua_tothread(LuaState, StackIndex);
+ FValue := nil; { todo }
+ end;
+ end;
+
+end;
+
+class function TLuaValue.GetLuaValueType(LuaState: Plua_State; StackIndex: Integer):
+ TLuaValueType;
+begin
+ case lua_type(LuaState, StackIndex) of
+ LUA_TNIL:
+ Result := lvtNil;
+ LUA_TNUMBER:
+ Result := lvtNumber;
+ LUA_TBOOLEAN:
+ Result := lvtBoolean;
+ LUA_TSTRING:
+ Result := lvtString;
+ LUA_TTABLE:
+ Result := lvtTable;
+ LUA_TFUNCTION:
+ Result := lvtFunction;
+ LUA_TUSERDATA:
+ Result := lvtUserData;
+ LUA_TTHREAD:
+ Result := lvtThread;
+ LUA_TLIGHTUSERDATA:
+ Result := lvtLightUserData;
+ LUA_TNONE:
+ raise ELuaException.Create('Invalid stack index location');
+ end;
+end;
+
+procedure TLuaValue.CheckType(LuaValueType: TLuaValueType);
+begin
+ if FLuaValueType <> LuaValueType then
+ raise ELuaException.Create('Cannot access value as ' + inttostr(Integer(LuaValueType)));
+end;
+
+function TLuaValue.GetAsBoolean:
+ boolean;
+begin
+ CheckType(lvtBoolean);
+ Result := FValue.AsBoolean;
+end;
+
+function TLuaValue.GetAsInteger: Integer;
+begin
+ CheckType(lvtInteger);
+ Result := FValue.AsInteger;
+end;
+
+function TLuaValue.GetAsLightUserData: Pointer;
+begin
+ CheckType(lvtLightUserData);
+ Result := FValue.AsType;
+end;
+
+function TLuaValue.GetAsLuaTable(LuaState: Plua_State; StackIndex: Integer): TValue;
+begin
+ { todo }
+end;
+
+function TLuaValue.GetAsNumber: Double;
+begin
+ CheckType(lvtNumber);
+ Result := FValue.AsExtended;
+end;
+
+function TLuaValue.GetAsString: AnsiString;
+begin
+ CheckType(lvtString);
+ Result := FValue.AsString;
+end;
+
+function TLuaValue.IsBoolean: boolean;
+begin
+ Result := FLuaValueType = lvtBoolean;
+end;
+
+function TLuaValue.IsInteger: boolean;
+begin
+ Result := FLuaValueType = lvtInteger;
+end;
+
+function TLuaValue.IsLightUserData: boolean;
+begin
+ Result := FLuaValueType = lvtLightUserData;
+end;
+
+function TLuaValue.IsNil: boolean;
+begin
+ Result := FLuaValueType = lvtNil;
+end;
+
+function TLuaValue.IsNumber: boolean;
+begin
+ Result := FLuaValueType = lvtNumber;
+end;
+
+function TLuaValue.IsString: boolean;
+begin
+ Result := FLuaValueType = lvtString;
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm
new file mode 100644
index 00000000..1ed60482
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm
@@ -0,0 +1,52 @@
+object MainForm: TMainForm
+ Left = 0
+ Top = 0
+ Caption = 'PlaygroundForm'
+ ClientHeight = 404
+ ClientWidth = 533
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+ object Button1: TButton
+ Left = 8
+ Top = 8
+ Width = 145
+ Height = 49
+ Caption = 'lua_pcall'
+ TabOrder = 0
+ OnClick = Button1Click
+ end
+ object Button2: TButton
+ Left = 159
+ Top = 8
+ Width = 179
+ Height = 49
+ Caption = 'Load Config File'
+ TabOrder = 1
+ OnClick = Button2Click
+ end
+ object Button3: TButton
+ Left = 8
+ Top = 63
+ Width = 515
+ Height = 50
+ Caption = 'push_object_properties'
+ TabOrder = 2
+ OnClick = Button3Click
+ end
+ object Button4: TButton
+ Left = 344
+ Top = 8
+ Width = 179
+ Height = 49
+ Caption = 'GetGlobal'
+ TabOrder = 3
+ OnClick = Button4Click
+ end
+end
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas
new file mode 100644
index 00000000..90d14cd0
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas
@@ -0,0 +1,495 @@
+unit MainFormU;
+
+interface
+
+uses
+ Winapi.Windows,
+ Winapi.Messages,
+ System.SysUtils,
+ System.Variants,
+ System.Classes,
+ Vcl.Graphics,
+ Vcl.Controls,
+ Vcl.Forms,
+ Vcl.Dialogs,
+ Vcl.StdCtrls,
+ Data.DB,
+ Datasnap.DBClient,
+ Vcl.ExtCtrls,
+ Vcl.DBCtrls,
+ Vcl.Grids,
+ Vcl.DBGrids;
+
+type
+ TMainForm = class(TForm)
+ Button1: TButton;
+ Button2: TButton;
+ Button3: TButton;
+ Button4: TButton;
+ procedure Button1Click(Sender: TObject);
+ procedure Button2Click(Sender: TObject);
+ procedure Button3Click(Sender: TObject);
+ procedure Button4Click(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ procedure Button5Click(Sender: TObject);
+
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ end;
+
+ TPersona = class
+ private
+ FAge : Integer;
+ FLastName : string;
+ FFirstName: string;
+ FBornDate : TDateTime;
+ FChild : TPersona;
+ procedure SetAge(const Value: Integer);
+ procedure SetFirstName(const Value: string);
+ procedure SetLastName(const Value: string);
+ procedure SetBornDate(const Value: TDateTime);
+ procedure SetChild(const Value: TPersona);
+
+ public
+ class function NewPersona: TPersona;
+ property FirstName: string read FFirstName write SetFirstName;
+ property LastName: string read FLastName write SetLastName;
+ property Age: Integer read FAge write SetAge;
+ property BornDate: TDateTime read FBornDate write SetBornDate;
+ property Child: TPersona read FChild write SetChild;
+ end;
+
+var
+ MainForm: TMainForm;
+
+implementation
+
+uses
+ rtti,
+ System.TypInfo,
+ LuaBind.Intf,
+ LuaBind;
+
+{$R *.dfm}
+
+
+procedure TMainForm.Button1Click(Sender: TObject);
+var
+ state: Plua_State;
+begin
+ state := lua_open;
+ if not assigned(state) then
+ raise Exception.Create('Cannot initialize Lua');
+ try
+ luaL_openlibs(state);
+ if luaL_loadstring(state,
+ 'days = {"Sunday", "Monday", "Tuesday", "Wednesday"}; ' +
+ 'print(days[2]);') = 0 then
+ begin
+ if lua_pcall(state, 0, 1, 0) <> 0 then
+ begin
+ ShowMessage(lua_tostring(state, - 1));
+ lua_pop(state, 1);
+ end
+ else
+ begin
+ lua_pop(state, lua_gettop(state));
+ end;
+ end
+ else
+ begin
+ ShowMessage(lua_tostring(state, - 1));
+ lua_pop(state, 1);
+ end;
+ finally
+ lua_close(state);
+ end;
+end;
+
+function MyFunctionForLua(L: Plua_State): Integer; cdecl;
+var
+ v: pansichar;
+ s: ansistring;
+begin
+ s := uppercase(lua_tostring(L, 1));
+ lua_pushstring(L, pansichar(s));
+ Result := 1; // * number of results * /
+end;
+
+function myfullname(L: Plua_State): Integer; cdecl;
+var
+ v: pansichar;
+ s: ansistring;
+begin
+ assert(lua_istable(L, - 1));
+ lua_getfield(L, - 1, pansichar('nome'));
+ s := lua_tostring(L, - 1);
+ lua_pushstring(L, pansichar(s));
+ Result := 1; // * number of results * /
+end;
+
+function _setcaption(L: Plua_State): Integer; cdecl;
+var
+ form : TForm;
+ newcaption: ansistring;
+begin
+ assert(lua_type(L, - 1) = LUA_TSTRING);
+ assert(lua_type(L, - 2) = LUA_TLIGHTUSERDATA);
+
+ newcaption := lua_tostring(L, - 1);
+ lua_pop(L, 1);
+
+ form := TForm(lua_topointer(L, - 1));
+ lua_pop(L, 1);
+
+ form.Caption := newcaption;
+ Result := 0;
+end;
+
+function doSomethingOnDelphiObject(L: Plua_State): Integer; cdecl;
+var
+ v : pansichar;
+ s : ansistring;
+ p : Pointer;
+ form: TMainForm;
+begin
+
+ // TFileStream.Create('', fmCreate);
+
+ assert(lua_islightuserdata(L, - 1));
+ // lua_pop(L, );
+ p := lua_topointer(L, - 1);
+ lua_pop(L, 1);
+ form := TMainForm(p);
+ form.Caption := 'Cambiato da Lua';
+
+ // lua_getfield(L, -1, pansichar('nome'));
+ // s := lua_tostring(L, -1);
+ // lua_pushstring(L, pansichar(s));
+ //
+ Result := 0; // * number of results * /
+end;
+
+procedure SetSomeTables(L: Plua_State);
+begin
+ lua_newtable(L);
+ lua_pushstring(L, 'nome');
+ lua_pushstring(L, 'Daniele');
+ lua_settable(L, - 3);
+
+ lua_pushstring(L, 'cognome');
+ lua_pushstring(L, 'Teti');
+ lua_settable(L, - 3);
+
+ lua_pushstring(L, 'eta');
+ lua_pushnumber(L, 3);
+ lua_settable(L, - 3);
+
+ lua_pushstring(L, 'fullname');
+ lua_pushcfunction(L, @myfullname);
+ lua_settable(L, - 3);
+
+ lua_setglobal(L, 'daniele');
+end;
+
+// procedure SetSomeTables(L: Plua_State);
+// begin
+// lua_newtable(L);
+// lua_pushstring(L, 'nome');
+// lua_pushstring(L, 'Daniele');
+// lua_pushstring(L, 'cognome');
+// lua_pushnumber(L, 2);
+// lua_pushstring(L, 'eta');
+// lua_pushnumber(L, 3);
+// lua_pushstring(L, 'fullname');
+// lua_pushcfunction(L, @myfullname);
+// lua_settable(L, -9);
+// lua_settable(L, -7);
+// lua_settable(L, -5);
+// lua_settable(L, -3);
+// lua_setglobal(L, 'daniele');
+// end;
+
+procedure SetSomeVariables(L: Plua_State);
+begin
+ lua_pushnumber(L, 11);
+ lua_pushnumber(L, 22);
+ lua_pushnumber(L, 33);
+ lua_setglobal(L, 'x3');
+ lua_setglobal(L, 'x2');
+ lua_setglobal(L, 'x1');
+end;
+
+function Load(filename: ansistring; out AWidth: Integer;
+ out AHeight: Integer): string;
+var
+ L : Plua_State;
+ AStringa: string;
+begin
+ L := lua_open();
+ luaL_openlibs(L);
+ // luaopen_base(L);
+ // luaopen_io(L);
+ // luaopen_string(L);
+ // luaopen_math(L);
+
+ if (luaL_loadfile(L, pansichar(filename)) > 0) then
+ begin
+ Exit('Cannot run configuration file ' + lua_tostring(L, - 1));
+ end;
+
+ SetSomeVariables(L);
+ SetSomeTables(L);
+
+ lua_pushcfunction(L, @MyFunctionForLua);
+ lua_setglobal(L, 'delphiuppercase');
+
+ lua_pushcfunction(L, @doSomethingOnDelphiObject);
+ lua_setglobal(L, 'dosomething');
+
+ lua_pushcfunction(L, @_setcaption);
+ lua_setglobal(L, '_setcaption');
+
+ lua_pushlightuserdata(L, MainForm);
+ lua_setglobal(L, 'form');
+
+ if lua_pcall(L, 0, 0, 0) > 0 then
+ begin
+ Exit('Cannot exec configuration file ' + lua_tostring(L, - 1));
+ end;
+
+ lua_getglobal(L, 'width');
+ lua_getglobal(L, 'height');
+ lua_getglobal(L, 'stringa');
+
+ if (lua_isnumber(L, - 3) = 0) then
+ Exit('Width should be a number');
+
+ if (lua_isnumber(L, - 2) = 0) then
+ Exit('Height should be a number');
+
+ if (lua_isstring(L, - 1) = 0) then
+ Exit('stringa should be a string');
+
+ AWidth := lua_tointeger(L, - 3);
+ AHeight := lua_tointeger(L, - 2);
+ AStringa := lua_tostring(L, - 1);
+ lua_close(L);
+ Result := Format('Width: %d, Height: %d, Stringa: %s',
+ [AWidth, AHeight, AStringa]);
+end;
+
+procedure TMainForm.Button2Click(Sender: TObject);
+var
+ w: Integer;
+ h: Integer;
+begin
+ ShowMessage(Load('config.lua', w, h));
+end;
+
+procedure push_object_properties(L: Plua_State; AObject: TObject;
+ AName: string);
+var
+ prop : TRttiProperty;
+ ctx : TRttiContext;
+ properties: TArray;
+ k : ansistring;
+ Value : TValue;
+ v : ansistring;
+begin
+ ctx := TRttiContext.Create;
+ try
+ lua_newtable(L);
+ properties := ctx.GetType(AObject.ClassType).GetProperties;
+ for prop in properties do
+ begin
+ k := prop.Name;
+ lua_pushstring(L, pansichar(k));
+ Value := prop.GetValue(AObject);
+ if Value.TypeInfo^.Kind in [tkString, tkUString] then
+ begin
+ v := Value.AsString;
+ lua_pushstring(L, pansichar(v));
+ end
+ else if Value.TypeInfo^.Kind = tkInteger then
+ begin
+ lua_pushnumber(L, Value.AsInteger);
+ end
+ else if Value.TypeInfo^.Kind = tkFloat then
+ begin
+ lua_pushnumber(L, Value.AsExtended);
+ end
+ else if Value.TypeInfo^.Kind = tkClass then
+ begin
+ if Value.IsEmpty then
+ lua_pushnil(L)
+ else
+ push_object_properties(L, Value.AsObject, '');
+ end;
+
+ lua_settable(L, - 3);
+ end;
+ finally
+ ctx.Free;
+ end;
+end;
+
+procedure push_table(L: Plua_State; Keys: array of ansistring;
+ Values: array of ansistring);
+var
+ key : TObject;
+ I : Integer;
+ k : ansistring;
+ v : ansistring;
+ pvalue, pkey: pansichar;
+ le : Cardinal;
+begin
+ // lua_newtable(L);
+ // pkey := GetMemory(Length('firstname') + 1);
+ // pkey := StrCopy(pkey, pansichar('firstname'));
+ // lua_pushstring(L, pkey);
+ // //lua_pushstring(L, 'firstname');
+ // lua_pushstring(L, 'Daniele');
+ // lua_settable(L, -3);
+ // lua_pushstring(L, 'lastname');
+ // lua_pushstring(L, 'Teti');
+ // lua_settable(L, -3);
+
+ lua_newtable(L);
+ for I := 0 to high(Keys) do
+ begin
+ k := Keys[I];
+ v := Values[I];
+ lua_pushstring(L, pansichar(k));
+ lua_pushstring(L, pansichar(v));
+ lua_settable(L, - 3);
+ end;
+
+
+ // k := Keys[I];
+ // pkey := GetMemory(Length(k) + 1);
+ // ZeroMemory(pkey, Length(k) + 1);
+ // MoveMemory(pkey, pansichar(k), Length(k));
+ /// / pkey := StrPCopy(pkey, pansichar(k));
+ //
+ // v := Values[I];
+ // pvalue := GetMemory(Length(v) + 1);
+ // pvalue := StrCopy(pvalue, pansichar(v));
+ //
+ // lua_pushstring(L, pkey);
+ // lua_pushstring(L, pvalue);
+ // lua_settable(L, -3);
+
+end;
+
+procedure TMainForm.Button3Click(Sender: TObject);
+var
+ L : Plua_State;
+ persona: TPersona;
+begin
+ persona := TPersona.Create;
+ try
+ persona.FirstName := 'Daniele';
+ persona.LastName := 'Teti';
+ persona.Age := 32;
+ persona.BornDate := date;
+ persona.Child := TPersona.NewPersona;
+
+ L := lua_open;
+ try
+ luaL_openlibs(L);
+ if luaL_loadfile(L, 'test01.html') > 0 then
+ raise Exception.Create('Cannot run configuration file ' +
+ lua_tostring(L, - 1));
+
+ // push_table(L, ['firstname', 'lastname'], ['Daniele', 'Teti']);
+ push_object_properties(L, persona, 'persona');
+ lua_setglobal(L, 'persona');
+ if lua_pcall(L, 0, 0, 0) > 0 then
+ begin
+ raise Exception.Create('Cannot exec configuration file ' +
+ lua_tostring(L, - 1));
+ end;
+ lua_getglobal(L, 'p');
+ ShowMessage(lua_tostring(L, - 1));
+ finally
+ lua_close(L);
+ end;
+ finally
+ persona.Child.Free;
+ persona.Free;
+ end;
+end;
+
+procedure TMainForm.Button4Click(Sender: TObject);
+var
+ lua: TLuaEngine;
+ v : ILuaValue;
+begin
+ lua := TLuaEngine.Create;
+ try
+ lua.LoadScript(
+ 'local z = y + 2;' + sLineBreak +
+ 'x = y + 1 + z;');
+ lua.DeclareGlobalInteger('y', 4);
+ lua.Execute;
+ v := lua.GetGlobal('x');
+ if v.IsNumber then
+ ShowMessage(FloatToStr(v.GetAsNumber));
+ finally
+ lua.Free;
+ end;
+end;
+
+procedure TMainForm.Button5Click(Sender: TObject);
+begin
+ // ClientDataSet1.SaveToFile(ClientDataSet1.filename);
+ // ClientDataSet1.Close;
+end;
+
+procedure TMainForm.FormCreate(Sender: TObject);
+begin
+ // ClientDataSet1.Close;
+ // ClientDataSet1.filename := '..\..\..\unittests\win32\debug\samplecds.xml';
+ // ClientDataSet1.Open;
+end;
+
+{ TPersona }
+
+class function TPersona.NewPersona: TPersona;
+begin
+ Result := TPersona.Create;
+ Result.FirstName := 'Mattia';
+ Result.LastName := 'Teti';
+ Result.Age := 1;
+ Result.BornDate := EncodeDate(2011, 11, 17);
+end;
+
+procedure TPersona.SetAge(const Value: Integer);
+begin
+ FAge := Value;
+end;
+
+procedure TPersona.SetBornDate(const Value: TDateTime);
+begin
+ FBornDate := Value;
+end;
+
+procedure TPersona.SetChild(const Value: TPersona);
+begin
+ FChild := Value;
+end;
+
+procedure TPersona.SetFirstName(const Value: string);
+begin
+ FFirstName := Value;
+end;
+
+procedure TPersona.SetLastName(const Value: string);
+begin
+ FLastName := Value;
+end;
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr
new file mode 100644
index 00000000..9185bf10
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr
@@ -0,0 +1,27 @@
+program LuaBindingUnitTests;
+
+{$IFDEF CONSOLE_TESTRUNNER}
+{$APPTYPE CONSOLE}
+{$ENDIF}
+
+
+uses
+ DUnitTestRunner,
+ TestLuaWrapper in 'TestLuaWrapper.pas',
+ TestObjects in 'TestObjects.pas',
+ TestLuaEmbeddedTextFilter in 'TestLuaEmbeddedTextFilter.pas',
+ LuaBind.Filters.Text in '..\LuaBind.Filters.Text.pas',
+ LuaBind.Intf in '..\LuaBind.Intf.pas',
+ LuaBind.CustomType.DataSet in '..\LuaBind.CustomType.DataSet.pas',
+ LuaBind.CustomType.PODO in '..\LuaBind.CustomType.PODO.pas',
+ LuaBind.CustomType.UserType in '..\LuaBind.CustomType.UserType.pas',
+ LuaBind in '..\LuaBind.pas',
+ LuaBind.DelphiObjects in '..\LuaBind.DelphiObjects.pas';
+
+{$R *.RES}
+
+
+begin
+ ReportMemoryLeaksOnShutdown := True;
+ DUnitTestRunner.RunRegisteredTests;
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj
new file mode 100644
index 00000000..e5eceb33
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj
@@ -0,0 +1,971 @@
+
+
+ {617B701F-53AB-42BC-8140-9BEC89FB3469}
+ 19.3
+ None
+ True
+ Debug
+ Win32
+ 1
+ Console
+ LuaBindingUnitTests.dpr
+
+
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Base
+ true
+
+
+ true
+ Cfg_1
+ true
+ true
+
+
+ true
+ Base
+ true
+
+
+ LuaBindingUnitTests
+ $(BDS)\bin\delphi_PROJECTICNS.icns
+ $(BDS)\bin\delphi_PROJECTICON.ico
+ $(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath)
+ _CONSOLE_TESTRUNNER;$(DCC_Define)
+ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)
+ fmx;IndySystem;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;DBXOracleDriver;CustomIPTransport;AureliusXE2;dsnap;IndyCore;fmxase;inetdbxpress;IPIndyImpl;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;DBXInformixDriver;DBXFirebirdDriver;inet;fmxobj;LKSL;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;$(DCC_UsePackage)
+ .
+ .\$(Platform)\$(Config)
+
+
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ Debug
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=
+ Debug
+ true
+ Base
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
+ true
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
+ true
+ $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
+ true
+ true
+ android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
+ true
+ true
+ true
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
+ $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
+
+
+ JvGlobus;JvMM;JvDlgs;JvCrypt;TeeDB;Rave100VCL;vclib;inetdbbde;DBXSybaseASEDriver;vclimg;DataBindingsVCL160;fmi;vcldb;vcldsnap;dac160;unidacvcl160;DBXDb2Driver;Intraweb_120_160;dwsLibRuntime;JvCore;vclribbon;frxe16;vcl;CloudService;DBXMSSQLDriver;CodeSiteExpressPkg;unidac160;FmxTeeUI;JvAppFrm;JvRuntimeDesign;webdsnap;JclDeveloperTools;adortl;JvWizards;SimpleGraphPackage;NewAC;OpenWirePkgD16;vcldbx;frx16;DotNet4Delphi_XE2;crcontrols160;JclContainers;Tee;DataBindings;DBXOdbcDriver;JvCmp;JvSystem;svnui;adgrmxe2;JvControls;frxDB16;intrawebdb_120_160;fs16;vclactnband;FMXTee;TeeUI;bindcompvcl;JvStdCtrls;JvCustom;Jcl;vclie;vcltouch;dacvcl160;websnap;VclSmp;fsDB16;DataSnapConnectors;RlxPackage;dsnapcon;JclVcl;JvPascalInterpreter;vclx;Lua4Delphi;svn;bdertl;$(DCC_UsePackage)
+ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
+ 1033
+ CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
+ ..\samples\bin
+ (None)
+
+
+ vclib;DBXSybaseASEDriver;vclimg;vcldb;vcldsnap;DBXDb2Driver;vcl;DBXMSSQLDriver;webdsnap;adortl;DBXOdbcDriver;adgrmxe2;vclactnband;bindcompvcl;vclie;vcltouch;websnap;VclSmp;DataSnapConnectors;dsnapcon;vclx;$(DCC_UsePackage)
+
+
+ DEBUG;$(DCC_Define)
+ false
+ true
+ true
+ true
+
+
+ 3
+ None
+ 1033
+ false
+
+
+ false
+ RELEASE;$(DCC_Define)
+ 0
+ 0
+
+
+
+ MainSource
+
+
+
+
+
+
+
+
+
+
+
+
+ Base
+
+
+ Cfg_1
+ Base
+
+
+ Cfg_2
+ Base
+
+
+
+ Delphi.Personality.12
+
+
+
+
+ False
+ False
+ 1
+ 0
+ 0
+ 0
+ False
+ False
+ False
+ False
+ False
+ 1040
+ 1252
+
+
+
+
+ 1.0.0.0
+
+
+
+
+
+ 1.0.0.0
+
+
+
+ Embarcadero C++Builder Office 2000 Servers Package
+ Embarcadero C++Builder Office XP Servers Package
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
+
+ LuaBindingUnitTests.dpr
+
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ 1
+
+
+ 0
+
+
+
+
+ classes
+ 64
+
+
+ classes
+ 64
+
+
+
+
+ res\xml
+ 1
+
+
+ res\xml
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\armeabi
+ 1
+
+
+ library\lib\armeabi
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ library\lib\mips
+ 1
+
+
+ library\lib\mips
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\values-v21
+ 1
+
+
+ res\values-v21
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ res\drawable
+ 1
+
+
+ res\drawable
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-ldpi
+ 1
+
+
+ res\drawable-ldpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-mdpi
+ 1
+
+
+ res\drawable-mdpi
+ 1
+
+
+
+
+ res\drawable-hdpi
+ 1
+
+
+ res\drawable-hdpi
+ 1
+
+
+
+
+ res\drawable-xhdpi
+ 1
+
+
+ res\drawable-xhdpi
+ 1
+
+
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+ res\drawable-xxhdpi
+ 1
+
+
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+ res\drawable-xxxhdpi
+ 1
+
+
+
+
+ res\drawable-small
+ 1
+
+
+ res\drawable-small
+ 1
+
+
+
+
+ res\drawable-normal
+ 1
+
+
+ res\drawable-normal
+ 1
+
+
+
+
+ res\drawable-large
+ 1
+
+
+ res\drawable-large
+ 1
+
+
+
+
+ res\drawable-xlarge
+ 1
+
+
+ res\drawable-xlarge
+ 1
+
+
+
+
+ res\values
+ 1
+
+
+ res\values
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 1
+ .framework
+
+
+ 0
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .dll;.bpl
+
+
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 1
+ .dylib
+
+
+ 0
+ .bpl
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ False
+ False
+ True
+ False
+
+
+ DUnit / Delphi Win32
+ GUI
+ C:\Users\Daniele\Desktop\luawrapper\mytest\LuaTest.dproj
+
+
+
+ 12
+
+
+
+
+
diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas
new file mode 100644
index 00000000..686b897a
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas
@@ -0,0 +1,168 @@
+unit TestLuaEmbeddedTextFilter;
+{
+
+ Delphi DUnit Test Case
+ ----------------------
+ This unit contains a skeleton test case class generated by the Test Case Wizard.
+ Modify the generated code to correctly setup and call the methods from the unit
+ being tested.
+
+}
+
+interface
+
+uses
+ TestFramework,
+ System.Classes,
+ TestLuaWrapper,
+ System.SysUtils,
+ LuaBind,
+ LuaBind.Intf,
+ System.Rtti;
+
+type
+ TTestEmbeddedTextFilter = class(TTestCase)
+ strict private
+ FLuaEngine: TLuaEngine;
+
+ public
+ procedure SetUp; override;
+ procedure TearDown; override;
+
+ published
+ procedure TestDoAllTests;
+ procedure TestHelperExecAndGet01;
+ procedure TestHelperExecAndGetMultiThread;
+ end;
+
+implementation
+
+uses
+ System.IOUtils,
+ LuaBind.Filters.Text,
+ System.Generics.collections,
+ System.Types;
+
+{ TTestEmbeddedTextFilter }
+
+procedure TTestEmbeddedTextFilter.SetUp;
+begin
+ inherited;
+ FLuaEngine := TLuaEngine.Create;
+end;
+
+procedure TTestEmbeddedTextFilter.TearDown;
+begin
+ FLuaEngine.Free;
+ inherited;
+end;
+
+procedure TTestEmbeddedTextFilter.TestDoAllTests;
+var
+ luafiles: TStringDynArray;
+ f : string;
+ Filter : TLuaEmbeddedTextFilter;
+begin
+ luafiles := TDirectory.GetFiles('embeddedtextfiltertests', '*.elua');
+ TArray.Sort(luafiles);
+ for f in luafiles do
+ begin
+ Filter := TLuaEmbeddedTextFilter.Create;
+ try
+ Filter.OutputFunction := 'io.write';
+ Filter.TemplateCode := TFile.ReadAllText(f);
+ Filter.Execute;
+ TFile.WriteAllText(ChangeFileExt(f, '.lua'), Filter.LuaCode);
+ try
+ FLuaEngine.LoadScript(Filter.LuaCode);
+ FLuaEngine.Execute; // only check if is ok the syntax
+ except
+ on E: Exception do
+ begin
+ Fail('File ' + f + ' - ' + E.Message);
+ end;
+ end;
+ finally
+ Filter.Free;
+ end;
+ end;
+end;
+
+procedure TTestEmbeddedTextFilter.TestHelperExecAndGet01;
+var
+ r: string;
+begin
+ r := TLuaEmbeddedTextFilter.ExecuteWithResult('hello',
+ ['nome', 'cognome'],
+ ['Daniele', 'Teti']);
+ CheckEquals('hello', r);
+
+ r := TLuaEmbeddedTextFilter.ExecuteWithResult('Hello ,, how are you?',
+ ['nome', 'cognome'],
+ ['Daniele', 'Teti']);
+ CheckEquals('Hello Daniele,Teti, how are you?', r);
+
+ r := TLuaEmbeddedTextFilter.ExecuteWithResult
+ ('Hello ,, how are you?',
+ ['nome', 'cognome'],
+ ['Daniele', 'Teti']);
+ CheckEquals('Hello Daniele,Teti, ' +
+ StringOfChar('*', 100)
+ + ' how are you?', r)
+end;
+
+procedure TTestEmbeddedTextFilter.TestHelperExecAndGetMultiThread;
+var
+ p : TProc;
+ t1 : TThread;
+ I : Integer;
+ ThreadList: TList;
+ ooo : string;
+begin
+ p :=
+ procedure
+ var
+ r: string;
+ begin
+ r := TLuaEmbeddedTextFilter.ExecuteWithResult
+ ('Hello ,, how are you?',
+ ['nome', 'cognome'],
+ ['Daniele', 'Teti']);
+ TThread.Synchronize(nil,
+ procedure
+ begin
+ ooo := ooo +
+ BoolToStr('Hello Daniele,Teti, ' +
+ StringOfChar('*', 100)
+ + ' how are you?' = r)[1];
+ end);
+ end;
+ ooo := '';
+ ThreadList := TList.Create;
+ try
+ for I := 1 to 50 do
+ begin
+ t1 := TThread.CreateAnonymousThread(p);
+ t1.FreeOnTerminate := false;
+ t1.Start;
+ ThreadList.Add(t1);
+ end;
+
+ while ThreadList.Count > 0 do
+ begin
+ ThreadList[0].WaitFor;
+ ThreadList[0].Free;
+ ThreadList.Delete(0);
+ end;
+ CheckEquals(StringOfChar('T', 50), ooo);
+ finally
+ ThreadList.Free;
+ end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+RegisterTest(TTestEmbeddedTextFilter.Suite);
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas
new file mode 100644
index 00000000..b8ce6f1c
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas
@@ -0,0 +1,579 @@
+unit TestLuaWrapper;
+{
+
+ Delphi DUnit Test Case
+ ----------------------
+ This unit contains a skeleton test case class generated by the Test Case Wizard.
+ Modify the generated code to correctly setup and call the methods from the unit
+ being tested.
+
+}
+{ .$RTTI EXPLICIT METHODS([vcPublished, vcPublic]) }
+
+interface
+
+uses
+ TestFramework,
+ System.Classes,
+ LuaBind.Intf,
+ LuaBind,
+ System.Rtti,
+ System.SysUtils;
+
+type
+ // Test methods for class TLuaEngine
+
+ TestTLuaEngine = class(TTestCase)
+ strict private
+ FLuaEngine: TLuaEngine;
+
+ private
+
+ public
+ procedure SetUp; override;
+ procedure TearDown; override;
+
+ published
+ procedure TestLoadScript;
+ procedure TestLoadScript1;
+ procedure TestLoadFromFile;
+ procedure TestDeclareGlobalNil;
+ procedure TestDeclareGlobalNumber;
+ procedure TestDeclareGlobalInteger;
+ procedure TestDeclareGlobalString;
+ procedure TestDeclareGlobalBoolean;
+ procedure TestDeclareGlobalLightUserData;
+ procedure TestDeclareGlobalUserData;
+ /// /////
+ procedure TestDeclareGlobalFunction;
+ procedure TestGetGlobal;
+
+ /// ///test core extensions
+ procedure TestExposeDataSet;
+ procedure TestExposeDelphiObject;
+ procedure TestExposeDelphiObjectNoDeps;
+ procedure TestExposeVCLDelphiObject;
+ procedure TestExposeVCLDelphiObjectSetProperty;
+ procedure TestCreateDelphiObject;
+ procedure TestCreateDelphiObjectWithWringConstructor;
+
+ /// ///// test helper pusher
+ procedure TestPushTableWithIntegerKeys;
+ procedure TestPushTableWithStringKeys;
+ procedure TestPushTableWithTValueValues;
+ procedure TestPushTableFromCompoundObject;
+
+ /// ////
+ procedure TestExecuteFunction;
+
+ procedure TestMyDirtyTests;
+
+ end;
+
+implementation
+
+uses
+ System.IOUtils,
+ LuaBind.CustomType.DataSet,
+ Datasnap.DBClient,
+ LuaBind.CustomType.PODO,
+ LuaBind.CustomType.UserType,
+ System.Generics.Collections,
+ TestObjects;
+
+procedure TestTLuaEngine.SetUp;
+begin
+ FLuaEngine := TLuaEngine.Create;
+end;
+
+procedure TestTLuaEngine.TearDown;
+begin
+ FLuaEngine.Free;
+ FLuaEngine := nil;
+end;
+
+procedure TestTLuaEngine.TestLoadScript;
+var
+ AScript: AnsiString;
+begin
+ FLuaEngine.LoadScript(AScript);
+ FLuaEngine.Execute;
+
+ FLuaEngine.LoadScript('local x = 1+2+3;');
+ FLuaEngine.Execute;
+
+ ExpectedException := ELuaRuntimeException;
+ FLuaEngine.LoadScript('local x = pippo.makeBooom();');
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestLoadScript1;
+var
+ AStream: TStream;
+begin
+ AStream := TFile.OpenRead('test_01.lua');
+ FLuaEngine.LoadScript(AStream, true);
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestMyDirtyTests;
+begin
+ FLuaEngine.LoadExternalLibraries(TLuaMyTest.Create);
+ FLuaEngine.LoadFromFile('test_mydirtytest.lua');
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestPushTableFromCompoundObject;
+var
+ father, Child: TPerson;
+begin
+ father := TPerson.Create;
+ try
+ father.Child := TPerson.Create;
+ try
+ father.FirstName := 'Daniele';
+ father.LastName := 'Teti';
+ father.Age := 32;
+ father.Child.FirstName := 'Daniele Son';
+ father.Child.LastName := 'Teti';
+ father.Child.Age := 2;
+ father.Child.Child := nil;
+ FLuaEngine.DeclareTable('person', father);
+ FLuaEngine.LoadScript
+ ('s = person.FirstName .. person.LastName .. tostring(person.Age) .. person.Child.FirstName .. person.Child.LastName .. person.Child.Age');
+ FLuaEngine.Execute;
+ CheckEquals('DanieleTeti32Daniele SonTeti2', FLuaEngine.GetGlobal('s').GetAsString);
+ finally
+ father.Child.Free;
+ end;
+ finally
+ father.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestPushTableWithIntegerKeys;
+begin
+ FLuaEngine.DeclareTable('mytable', [1, 2, 3, 4], ['daniele', 'teti', 'peter', 'parker']);
+ FLuaEngine.LoadScript('s = mytable[1]..mytable[2]..mytable[3]..mytable[4]');
+ FLuaEngine.Execute;
+ CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s').GetAsString)
+end;
+
+procedure TestTLuaEngine.TestPushTableWithStringKeys;
+begin
+ FLuaEngine.DeclareTable('mytable', ['a', 'b', 'c', 'd'], ['daniele', 'teti', 'peter', 'parker']);
+ FLuaEngine.LoadScript(
+ 's1 = mytable["a"] .. mytable["b"] .. mytable["c"] .. mytable["d"];' +
+ 's2 = mytable.a .. mytable.b .. mytable.c .. mytable.d');
+ FLuaEngine.Execute;
+ CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s1').GetAsString);
+ CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s2').GetAsString)
+end;
+
+procedure TestTLuaEngine.TestPushTableWithTValueValues;
+var
+ dict: TDictionary;
+begin
+ dict := TDictionary.Create;
+ try
+ dict.AddOrSetValue('hello', 'world');
+ dict.AddOrSetValue(1234, 'onetwothree');
+ dict.AddOrSetValue('yes', true);
+ dict.AddOrSetValue('no', false);
+ FLuaEngine.DeclareTable('mytable', dict);
+ FLuaEngine.LoadScript
+ ('s = mytable.hello .. mytable[1234] .. tostring(mytable.yes) .. tostring(mytable["no"])');
+ FLuaEngine.Execute;
+ CheckEquals('worldonetwothreetruefalse', FLuaEngine.GetGlobal('s').GetAsString)
+ finally
+ dict.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestLoadFromFile;
+begin
+ FLuaEngine.LoadFromFile('test_01.lua');
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalNil;
+begin
+ FLuaEngine.DeclareGlobalNil('_nil');
+ FLuaEngine.LoadScript('');
+ FLuaEngine.Execute;
+ CheckTrue(FLuaEngine.GetGlobal('_nil').IsNil);
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalNumber;
+var
+ Value : ILuaValue;
+ _tot, _number1, _number2, _number3, _number4: Double;
+begin
+ _number1 := 1;
+ _number2 := 1.1234;
+ _number3 := 1234.5678;
+ _number4 := 12345678;
+ FLuaEngine.DeclareGlobalNumber('_number1', _number1);
+ FLuaEngine.DeclareGlobalNumber('_number2', _number2);
+ FLuaEngine.DeclareGlobalNumber('_number3', _number3);
+ FLuaEngine.DeclareGlobalNumber('_number4', _number4);
+
+ FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('_tot');
+
+ CheckTrue(Value.IsNumber);
+ CheckFalse(Value.IsInteger);
+ CheckFalse(Value.IsString);
+ CheckFalse(Value.IsNil);
+ CheckFalse(Value.IsBoolean);
+ CheckFalse(Value.IsLightUserData);
+
+ _tot := _number1 + _number2 + _number3 + _number4;
+ CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001);
+
+ ExpectedException := ELuaException;
+ Value.GetAsString;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalInteger;
+var
+ Value : ILuaValue;
+ _tot, _number1, _number2, _number3, _number4: Integer;
+begin
+ _number1 := 1;
+ _number2 := 1234;
+ _number3 := 12345678;
+ _number4 := 12345678;
+ FLuaEngine.DeclareGlobalInteger('_number1', _number1);
+ FLuaEngine.DeclareGlobalInteger('_number2', _number2);
+ FLuaEngine.DeclareGlobalInteger('_number3', _number3);
+ FLuaEngine.DeclareGlobalInteger('_number4', _number4);
+
+ FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('_tot');
+
+ CheckTrue(Value.IsNumber);
+ /// a sum of integers returns a NUMBER result type.. :-(
+ CheckFalse(Value.IsInteger);
+ CheckFalse(Value.IsString);
+ CheckFalse(Value.IsNil);
+ CheckFalse(Value.IsBoolean);
+ CheckFalse(Value.IsLightUserData);
+
+ _tot := _number1 + _number2 + _number3 + _number4;
+ CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001);
+
+ ExpectedException := ELuaException;
+ Value.GetAsString;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalString;
+var
+ Value : ILuaValue;
+ _tot, _string1, _string2, _string3, _string4: AnsiString;
+begin
+ _string1 := '';
+ _string2 := 'hello';
+ _string3 := 'Lua';
+ _string4 := 'world àèéùòìçò§£$%';
+ FLuaEngine.DeclareGlobalString('_string1', _string1);
+ FLuaEngine.DeclareGlobalString('_string2', _string2);
+ FLuaEngine.DeclareGlobalString('_string3', _string3);
+ FLuaEngine.DeclareGlobalString('_string4', _string4);
+
+ FLuaEngine.LoadScript('_tot = _string1 .. _string2 .. _string3 .. _string4;');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('_tot');
+
+ CheckFalse(Value.IsNumber);
+ CheckFalse(Value.IsInteger);
+ CheckTrue(Value.IsString);
+ CheckFalse(Value.IsNil);
+ CheckFalse(Value.IsBoolean);
+ CheckFalse(Value.IsLightUserData);
+
+ _tot := _string1 + _string2 + _string3 + _string4;
+ CheckEquals('helloLuaworld àèéùòìçò§£$%', _tot);
+
+ ExpectedException := ELuaException;
+ Value.GetAsInteger;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalUserData;
+begin
+ // FLuaEngine.DeclareGlobalUserData('pippo', nil);
+ // FLuaEngine.LoadScript('');
+ // FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestExecuteFunction;
+var
+ r: AnsiString;
+begin
+ FLuaEngine.LoadScript('function myfunc(a,b,c) return a..b..c end');
+ FLuaEngine.Execute;
+ r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString;
+ CheckEquals('helloLuaworld', r);
+ FLuaEngine.Reset;
+ FLuaEngine.LoadFromFile('test_08.lua');
+ FLuaEngine.Execute;
+ r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString;
+ CheckEquals('helloLuaworld', r);
+end;
+
+procedure TestTLuaEngine.TestExposeDataSet;
+var
+ ds: TClientDataSet;
+ _1: string;
+ _2: string;
+begin
+ ds := TClientDataSet.Create(nil);
+ try
+ ds.LoadFromFile('samplecds.xml');
+ ds.Open;
+ FLuaEngine.LoadExternalLibraries(TLuaDataSetExposerLibraries.Create);
+ ExposeDataSet(FLuaEngine, ds, 'people');
+ FLuaEngine.LoadFromFile('test_02.lua');
+ FLuaEngine.Execute;
+ finally
+ ds.Free;
+ end;
+ _1 := TFile.ReadAllText('test_02_expected.txt');
+ _2 := TFile.ReadAllText('test_02.txt');
+ CheckEquals(_1, _2);
+end;
+
+procedure TestTLuaEngine.TestExposeDelphiObject;
+var
+ person: TPerson;
+begin
+ person := TPerson.Create;
+ try
+ FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
+ ExposeDelphiObject(FLuaEngine, person, 'person');
+ FLuaEngine.LoadFromFile('test_03.lua');
+ FLuaEngine.Execute;
+ CheckEquals('Teti', FLuaEngine.GetGlobal('last_name').GetAsString);
+ CheckEquals('Daniele', FLuaEngine.GetGlobal('first_name').GetAsString);
+ CheckEquals('Mr. Daniele Teti', FLuaEngine.GetGlobal('full_name').GetAsString);
+ CheckEquals(32, FLuaEngine.GetGlobal('age').GetAsInteger);
+ CheckEquals('Teti', person.LastName);
+ CheckEquals('Daniele', person.FirstName);
+ CheckEquals(32, person.Age);
+ finally
+ person.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestExposeDelphiObjectNoDeps;
+var
+ person: TPerson;
+begin
+ person := TPerson.Create;
+ try
+ person.FirstName := 'Daniele';
+ person.LastName := 'Teti';
+ person.Age := 33;
+ FLuaEngine.DeclareGlobalDelphiObjectAsTable(person, 'person');
+ // FLuaEngine.ExecuteScript('r = person.FirstName .. person.LastName .. tostring(person.Age)');
+ // CheckEquals('DanieleTeti33', FLuaEngine.GetGlobal('r').GetAsString);
+
+ FLuaEngine.LoadScript('x = person:hello("parametro1", "parametro2")');
+ FLuaEngine.Execute;
+ // FLuaEngine.ExecuteScript('person:BecomeOlder(1)');
+ CheckEquals('DanieleTeti34', FLuaEngine.GetGlobal('x').GetAsString);
+ finally
+ person.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestExposeVCLDelphiObject;
+var
+ sl: TStringList;
+begin
+ sl := TStringList.Create;
+ try
+ sl.Add('first');
+ FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
+ ExposeDelphiObject(FLuaEngine, sl, 'stringlist');
+ FLuaEngine.LoadFromFile('test_04.lua');
+ FLuaEngine.Execute;
+ CheckEquals(4, sl.Count);
+ finally
+ sl.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestExposeVCLDelphiObjectSetProperty;
+var
+ sl: TStringList;
+begin
+ sl := TStringList.Create;
+ try
+ sl.Add('first');
+ sl.Add('two');
+ sl.Add('three');
+ FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
+ ExposeDelphiObject(FLuaEngine, sl, 'stringlist');
+ FLuaEngine.LoadFromFile('test_05.lua');
+ FLuaEngine.Execute;
+ CheckEquals(1, sl.Count);
+ CheckEquals('Daniele Teti', sl[0]);
+ finally
+ sl.Free;
+ end;
+end;
+
+procedure TestTLuaEngine.TestCreateDelphiObject;
+begin
+ FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
+ FLuaEngine.LoadFromFile('test_06.lua');
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestCreateDelphiObjectWithWringConstructor;
+begin
+ FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
+ FLuaEngine.LoadFromFile('test_07.lua');
+ ExpectedException := ELuaRuntimeException;
+ FLuaEngine.Execute;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalBoolean;
+var
+ Value : ILuaValue;
+ _tot, _boolean1, _boolean2, _boolean3, _boolean4: boolean;
+begin
+ _boolean1 := true;
+ _boolean2 := false;
+ _boolean3 := true;
+ _boolean4 := false;
+ FLuaEngine.DeclareGlobalBoolean('_boolean1', _boolean1);
+ FLuaEngine.DeclareGlobalBoolean('_boolean2', _boolean2);
+ FLuaEngine.DeclareGlobalBoolean('_boolean3', _boolean3);
+ FLuaEngine.DeclareGlobalBoolean('_boolean4', _boolean4);
+
+ FLuaEngine.LoadScript('_tot = _boolean1 or _boolean2 and _boolean3 or _boolean4;');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('_tot');
+
+ CheckFalse(Value.IsNumber);
+ CheckFalse(Value.IsInteger);
+ CheckFalse(Value.IsString);
+ CheckFalse(Value.IsNil);
+ CheckTrue(Value.IsBoolean);
+ CheckFalse(Value.IsLightUserData);
+
+ _tot := _boolean1 or _boolean2 and _boolean3 or _boolean4;
+ CheckEquals(_tot, Value.GetAsBoolean);
+
+ ExpectedException := ELuaException;
+ Value.GetAsString;
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalFunction;
+ function SayHello(L: Plua_State): Integer; cdecl;
+ var
+ s: AnsiString;
+ begin
+ s := lua_tostring(L, - 1);
+ s := 'before ' + s + ' after';
+ lua_pop(L, 1);
+ lua_pushstring(L, PAnsiChar(s));
+ Result := 1;
+ end;
+
+var
+ Value: ILuaValue;
+begin
+ FLuaEngine.DeclareGlobalFunction('sayhello', @SayHello);
+ FLuaEngine.LoadScript('x = sayhello("hello world")');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('x');
+ CheckEquals('before hello world after', Value.GetAsString);
+end;
+
+procedure TestTLuaEngine.TestDeclareGlobalLightUserData;
+var
+ Value: ILuaValue;
+ _ptr : Pointer;
+ Obj : TStringList;
+ Obj2 : TStringList;
+
+ function AddToTStringList(L: Plua_State): Integer; cdecl;
+ var
+ sl: TStringList;
+ s : AnsiString;
+ begin
+ s := lua_tostring(L, - 1);
+ lua_pop(L, 1);
+ sl := TStringList(lua_topointer(L, - 1));
+ lua_pop(L, 1);
+ sl.Add(s);
+ Result := 0;
+ end;
+
+begin
+ _ptr := nil;
+ FLuaEngine.DeclareGlobalLightUserData('_ptr', _ptr);
+ FLuaEngine.LoadScript('x = _ptr');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('x');
+ CheckTrue(Value.IsLightUserData);
+ CheckTrue(Value.GetAsLightUserData = nil);
+
+ // Now try to pass a tstringlist
+ Obj := TStringList.Create;
+ try
+ Obj.Add('Hello World');
+ _ptr := Pointer(Obj);
+ FLuaEngine.DeclareGlobalLightUserData('_ptr1', _ptr);
+
+ FLuaEngine.DeclareGlobalFunction('additem', @AddToTStringList);
+
+ FLuaEngine.LoadScript('x = _ptr1; additem(x,"added from Lua")');
+ FLuaEngine.Execute;
+ Value := FLuaEngine.GetGlobal('x');
+
+ CheckFalse(Value.IsNumber);
+ CheckFalse(Value.IsInteger);
+ CheckFalse(Value.IsString);
+ CheckFalse(Value.IsNil);
+ CheckFalse(Value.IsBoolean);
+ CheckTrue(Value.IsLightUserData);
+
+ CheckNotNull(Value.GetAsLightUserData);
+ _ptr := Value.GetAsLightUserData;
+
+ Obj2 := TStringList(_ptr);
+ CheckEquals(2, Obj2.Count);
+ CheckEquals('Hello World', Obj2[0]);
+ CheckEquals('added from Lua', Obj2[1]);
+ finally
+ Obj.Free;
+ end;
+
+ ExpectedException := ELuaException;
+ Value.GetAsString;
+end;
+
+procedure TestTLuaEngine.TestGetGlobal;
+var
+ ReturnValue: ILuaValue;
+ AName : AnsiString;
+begin
+ // TODO: Setup method call parameters
+ ReturnValue := FLuaEngine.GetGlobal(AName);
+ // TODO: Validate method results
+end;
+
+{ TPerson }
+
+initialization
+
+// Register any test cases with the test runner
+RegisterTest(TestTLuaEngine.Suite);
+
+end.
diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas
new file mode 100644
index 00000000..40680cd4
--- /dev/null
+++ b/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas
@@ -0,0 +1,63 @@
+unit TestObjects;
+
+interface
+
+type
+ TPerson = class(TObject)
+ private
+ FLastName: String;
+ FFirstName: String;
+ FAge: Integer;
+ FChild: TPerson;
+ procedure SetLastName(const Value: String);
+ procedure SetFirstName(const Value: String);
+ procedure SetAge(const Value: Integer);
+ procedure SetChild(const Value: TPerson);
+ public
+ constructor Create;
+ function GetFullName(ASalutation: String): String;
+ procedure BecomeOlder(HowManyYear: Integer);
+ property Child: TPerson read FChild write SetChild;
+ property LastName: String read FLastName write SetLastName;
+ property FirstName: String read FFirstName write SetFirstName;
+ property Age: Integer read FAge write SetAge;
+ end;
+
+implementation
+
+procedure TPerson.BecomeOlder(HowManyYear: Integer);
+begin
+ FAge := FAge + HowManyYear;
+end;
+
+constructor TPerson.Create;
+begin
+ inherited;
+end;
+
+function TPerson.GetFullName(ASalutation: String): String;
+begin
+ Result := ASalutation + ' ' + FFirstName + ' ' + FLastName;
+end;
+
+procedure TPerson.SetAge(const Value: Integer);
+begin
+ FAge := Value;
+end;
+
+procedure TPerson.SetChild(const Value: TPerson);
+begin
+ FChild := Value;
+end;
+
+procedure TPerson.SetFirstName(const Value: String);
+begin
+ FFirstName := Value;
+end;
+
+procedure TPerson.SetLastName(const Value: String);
+begin
+ FLastName := Value;
+end;
+
+end.