Git Product home page Git Product logo

neolua's Introduction

NeoLua

A Lua implementation for the Dynamic Language Runtime (DLR).

Introduction

NeoLua is an implementation of the Lua language. Currently, the implementation is on the level of Lua_5.3 (http://www.lua.org/manual/5.3/manual.html). The goal is to follow the reference of the C-Lua implementation and combine this with full .NET Framework support. That means, it should be easy to call .NET functions from Lua and it should be easy access variables and functions from a .net language (e.g. C#, VB.NET, ...).

NeoLua is implemented in C# and uses the Dynamic Language Runtime. It therefore integrates very well with the .NET Framework.

Quickstart

You can play and test the language with the tool NeoCmd.

NeoCmd

Or there are two easy ways to use NeoLua in your project.

  • Download the Neo.Lua.dll and add the reference. For full desktop support also a reference to Neo.Lua.Desktop.dll is useful.
  • Install the NuGet package of NeoLua.

Simple example:

using (Lua lua = new Lua()) // Create the Lua script engine
{
    dynamic env = lua.CreateEnvironment(); // Create a environment
    env.dochunk("a = 'Hallo World!';", "test.lua"); // Create a variable in Lua
    Console.WriteLine(env.a); // Access a variable in C#
    env.dochunk("function add(b) return b + 3; end;", "test.lua"); // Create a function in Lua
    Console.WriteLine("Add(3) = {0}", env.add(3)); // Call the function in C#
}
Using lua As Lua = New Lua ' Create the Lua script engine
    Dim env As Object = lua.CreateEnvironment(Of LuaGlobal)() ' Create a environment
    env.dochunk("a = 'Hallo World!';", "test.lua") ' Create a variable in Lua
    Console.WriteLine(env.a) ' Access a variable in VB
    env.dochunk("function add(b) return b + 3; end;", "test.lua") ' Create a function in Lua
    Console.WriteLine("Add(3) = {0}", (New LuaResult(env.add(3)))(0)) ' Call the function in VB
End Using

A more "complex" script, that shows the interaction between lua and .net:

local t = clr.System.Int32[](6, 8, 9, 19);",
return t:Sum(), t:Where(function(c : int) : bool return c < 10 end):Sum()

NeoLua is a .NET portable assembly (IL) for

  • .NET Framework 4.5.1
  • Windows Phone 8.1
  • Windows Store Apps 8.1
  • Xamarin.Android

There will be no support for .NET Frameworks lower than 4.5.

It does not work with

  • Xamarin.iOS. or any .NET runtime that does not support code generation.

What NeoLua is useful for

  • Outsource the logic of your application into scripts
  • Structuring of logic
  • Build a dynamic configuration system, with functions and variables
  • As a formula parser
  • ...

So, this could be reliable partner for your compiled .NET application or engine (e.g. game engines).

What I did not have in mind

  • Compiling libraries
  • Standalone applications

Advantages of NeoLua

  • Dynamic access between Lua script and and the host application/.NET Framework and vice-versa.
  • NeoLua is based on the DLR. So you get compiled code that is collectable and well-optimized.
  • It is compatible with the .NET world (e.g. C#, VB.NET, IronPython, ...).
  • Full and easy access to the .NET Framework or your own libraries (with no stub code).
  • A rich implementation of the Lua table, for a got integration in the .NET world e.g. binding, enumeration, ...
  • A .NET Framework garbage collector that is well-tested and very fast.
  • Pure IL (x86, x64 support)

Drawbacks of NeoLua

  • It is not 100% compatible to Lua. But I will try very hard.
  • No deployment of precompiled scripts.

Drawbacks of bridges to c-lua, that are solved with NeoLua

  • You have two memory managers and so you have to marshal every data between these two worlds. That takes time and there are a lot pitfalls to get memory leaks.
  • C-Lua interprets its own bytecode. The code is not compiled to machine code.

Documentation

This documention has the same structure like the official reference (Lua 5.3), so it should be easy to compare the two worlds.

  1. Introduction
  2. Basic concepts
  3. Language
  4. Application Program Interface
    1. Getting started
    2. Script engine
    3. Chunks
    4. Table's
  5. The Auxiliary Library
    1. clr library
    2. Extent lua table
    3. Debugging
  6. Standard libraries
  7. NeoCmd

If there is something unclear, wrong or misunderstanding please use the discussions.

Projects that use this library

Links

You want pay for your request, contact us under https://tecware-gmbh.de/kontakt.html (only for members of the european union).

Or you want todo something good for other people. Donate to https://angelman.de/unser-verein/spenden/ (only in german)

neolua's People

Contributors

10se1ucgo avatar andrew-boyarshin avatar aspennn avatar c0bra5 avatar chi-lambda avatar dlamkins avatar halex2005 avatar hdkeeper avatar neolithos avatar ojb500 avatar orthographic-pedant avatar patrickkursawe avatar powercode avatar rkblackfire avatar systemkeeper avatar thoj avatar tmkls avatar vanillajonathan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neolua's Issues

Support for .NET Core

Hello,

Are there any plans for the neolua to support the new .NET Core version?

Tks

Github version of NeoLua fails to detect function's overload.

Example:

local DirectoryInfo = clr.System.IO.DirectoryInfo;
local di = DirectoryInfo("Scripts");
local fi = di:GetFiles();

Returns an ArgumentNullException:

Value cannot be null.
Parameter name: searchPattern

at Neo.IronLua.LuaChunk.Run(LuaTable env, Object[] callArgs) in C:\neolua-master\NeoLua\LuaChunk.cs:line 64
at Neo.IronLua.LuaGlobalPortable.DoChunk(LuaChunk chunk, Object[] callArgs) in C:\neolua-master\NeoLua\LuaGlobalPortable.cs:line 167
at Neo.IronLua.LuaGlobalPortable.DoChunk(TextReader tr, String sName, KeyValuePair`2[] args) in C:\neolua-master\NeoLua\LuaGlobalPortable.cs:line 149
at Neo.IronLua.LuaGlobal.DoChunk(String sFileName, KeyValuePair`2[] args) in C:\neolua-master\NeoLuaD\LuaGlobal.cs:line 39
at ExternalXaml.Engine.LuaWindow.LuaCompile(String luaName) in C:\ExternalXaml\ExternalXaml\Engine\LuaWindow.vb:line 59

Note:

  • It was working on the NuGet version of NeoLua
  • Reproducable with my CodeProject's NeoLua implementation.

ConcatString

local b = "b" local c = "a" .. b
to access method 'Neo.IronLua.Lua.RtConcatString(System.Object[])' failed.

Dynamic accessor

In my library, I have a class with a dictionary, and I want scripts to be able to directly access them, e.g myobject.ChildObject.DeeperChildObject.

I made the base class inherit from DynamicObject, and overrode "TryGetMember", but the method does not get invoked when accessing an object in the LuaGlobalTable. I was going to try inherit from LuaTable, but this causes issues with protobuf-net/serialization.

How could I achieve this with NeoLua?

Reload script at runtime

Hi

I'm writing a scripting engine for an internal tool. One thing I would like to implement is on the fly reloading when the script file changes on disk. The tool is long running and calls a member function loaded from a Lua script continuously. I need to be able to reload this script while the tool is still running. This is what i have tried:

Please excuse the Pesudo-code

if (scripts_changed) {
                try
                {                    
                    lua = new Lua();
                    chunk = lua.CompileChunk(script_file, new LuaCompileOptions() { DebugEngine = LuaStackTraceDebugger.Default });
                }
                catch (LuaParseException e)
                {
//... Parse error. just return and try again.
                }
                try
                {
                    global = lua.CreateEnvironment<LuaGlobal>();
                    global.DoChunk(chunk);
                }
                catch (Exception e)
                {
// ... just return and try again
                }
}

try
{
   global.CallMember("Something"); //This fails after fixed runtime error.
}
catch (Exception e)
{
//... oof
}

The script_changed is just set when a *.lua file changes via FileSystemWatcher and when starting up.

  1. Start up. Script runs OK.
  2. Introduce change. Script runs OK
  3. Introduce parse error. Fails with parse exception.
  4. Fix Parse error. Script runs OK.
  5. Introduce runtime error. Script Fails with runtime exception.
  6. Fix runtime error. Script fails with cant find member function exception.

Only way to fix this is to restart the whole program. I've tried lua.Clear(),global.Clear(),lua = null, global = null and creating new instances. But it seems the program keeps old script data around and can't be cleared and still fails on reload even if the error is fixed.

I'm probably missing something fundamental here. And tips on how to do this properly?

I'm Using v1.2.8. But i could find any relevant commits that my have fixed this.

Thanks for you help :)

Here are the exceptions i'm getting in the runtime error case:
** Runtime Error Introduced **
Script changed... Reloading.
Exception: Can not call nil value.
Exception: -- internal --
at [L] main8(LuaTable _G) line main.lua:22:1

Runtime Error: Value cannot be null.
Parameter name: 'table:Scan' not found.
Runtime Error: at [C] Neo.IronLua.LuaTable.CallMemberDirect(String memberName,Object[] args,Boolean ignoreCase,Boolean rawGet,Boolean throwExceptions) line C:\Projects\NeoLua\NeoLua\LuaTable.cs:2824:8
at [C] Neo.IronLua.LuaTable.CallMember(String memberName) line C:\Projects\NeoLua\NeoLua\LuaTable.cs:2771:7
at [C] MyProgram.LuaScript.ScriptTask() line c:\bla\bla.cs

** Runtime Error Fixed **
Script changed... Reloading.
Runtime Error: Failed to call 'Scan'.
Runtime Error: at [C] Neo.IronLua.LuaTable.CallMemberDirect(String memberName,Object[] args,Boolean ignoreCase,Boolean rawGet,Boolean throwExceptions) line C:\Projects\NeoLua\NeoLua\LuaTable.cs:2869:6
at [C] Neo.IronLua.LuaTable.CallMember(String memberName) line C:\Projects\NeoLua\NeoLua\LuaTable.cs:2771:7
at [C] MyProgram.LuaScript.ScriptTask() line c:\bla\bla.cs

TranslateRegularExpression function corrections

Hi,

Using the new improved gmatch, I have noticed a couple of issues with the TranslateRegularExpression. There were a couple of typos and some of the translations looked incorrect.
I have gone through and changed them to what I believe to be correct. I has also added the uppercase variations that do the opposite of the lower case chars.
From http://www.lua.org/manual/5.3/manual.html "For all classes represented by single letters (%a, %c, etc.), the corresponding uppercase letter represents the complement of the class. For instance, %S represents all non-space characters."

Hope this helps.

case 'a': // all letters
    sb.Append("\\p{L}");
    break;
case 'A': // all Non letters
    sb.Append("\\P{L}");
    break;                              
case 's': // all space characters
    sb.Append("\\s");
    break;
case 'S': // all NON space characters
    sb.Append("\\S");
    break;  
case 'd': // all digits
    sb.Append("\\d");
    break;
case 'D': // all NON digits
    sb.Append("\\D");
    break;                              
case 'w': // all alphanumeric characters
    sb.Append("\\w");
    break;
case 'W': // all NON alphanumeric characters
    sb.Append("\\W");
    break;                              
case 'c': // all control characters
    sb.Append("\\p{C}");
    break;
case 'C': // all NON control characters
    sb.Append("\\P{C}");
    break;                              
case 'g': // all printable characters except space
    sb.Append("\\S");
    break;
case 'G': // all NON printable characters including space
    sb.Append("\\s");
    break;                              
case 'p': // all punctuation characters
    sb.Append("\\p{P}");
    break;
case 'P': // all NON punctuation characters
    sb.Append("\\P{P}");
    break;                              
case 'l': // all lowercase letters
    sb.Append("\\p{Ll}");
    break;
case 'L': // all NON lowercase letters
    sb.Append("\\P{Ll}");
    break;                              
case 'u': // all uppercase letters
    sb.Append("\\p{Lu}");
    break;
case 'U': // all NON uppercase letters
    sb.Append("\\P{Lu}");
    break;                              
case 'x': // all hexadecimal digits
    sb.Append("\\[0-9A-Fa-f]");
    break;
case 'X': // all NON hexadecimal digits
    sb.Append("\\[^0-9A-Fa-f]");
    break;

Simon

LuaType.LookupReferencedAssemblies setter always sets the member to true

A problem with the setter: You set the variable to "true" instead of "value".
The bad thing is also that this value is already used by the static constructor, so you can't change it before it is used for the first time.
My application has 170+ assemblies loaded, and initializing Lua takes more than 20 seconds. Looks like the type resolution machanism could be a bit optimized... trying to work around this with a seperate application domain for now.

Something strange with String.Format

I've run into somewhat strange with String.Format().

local s = 'aaa';
clr.System.Windows.Forms.MessageBox:Show('{0}':Format(s));
-- Works fine
clr.System.Windows.Forms.MessageBox:Show('{0}':Format('aaa'));
-- Throwa exception

Const typeof Generic does not work properly.

Const example:

const OCS typeof System.Collections.ObjectModel.ObservableCollection[System.String]

Right now, this is my workaround for this:

VB.NET:

DirectCast(g, LuaGlobal).RegisterPackage("OCS", GetType(ObservableCollection(Of String)))

C#:

g.RegisterPackage("OCS", typeof(ObservableCollection<string>));

Compile Message:

Scripts\Content1.lua : Type 'System.Collections.ObjectModel.ObservableCollection' not found. (6, 1)

at [C] Neo.IronLua.Parser.ParseType(Scope scope,LuaLexer code,Boolean lNeedType) line c:\PathToProject\NeoLua\NeoLua\Parser.cs:1624:4
at [C] Neo.IronLua.Parser.ParseConst(Scope scope,LuaLexer code) line c:\PathToProject\NeoLua\NeoLua\Parser.cs:983:5
at [C] Neo.IronLua.Parser.ParseStatement(Scope scope,LuaLexer code) line c:\PathToProject\NeoLua\NeoLua\Parser.cs:756:6
at [C] Neo.IronLua.Parser.ParseBlock(Scope scope,LuaLexer code) line c:\PathToProject\NeoLua\NeoLua\Parser.cs:592:7
at [C] Neo.IronLua.Parser.ParseChunk(Lua runtime,LuaCompileOptions options,Boolean lHasEnvironment,LuaLexer code,Type typeDelegate,Type returnType,IEnumerable`1 args) line c:\PathToProject\NeoLua\NeoLua\Parser.cs:519:4
at [C] Neo.IronLua.Lua.CompileChunk(String sChunkName,LuaCompileOptions options,TextReader tr,IEnumerable`1 args) line c:\PathToProject\NeoLua\NeoLua\Lua.cs:224:6
at [C] Neo.IronLua.LuaGlobalPortable.DoChunk(TextReader tr,String sName,KeyValuePair`2[] args) line c:\PathToProject\NeoLua\NeoLua\LuaGlobalPortable.cs:149:5
at [C] Neo.IronLua.LuaGlobal.DoChunk(String sFileName,KeyValuePair`2[] args) line c:\PathToProject\NeoLua\NeoLuaD\LuaGlobal.cs:39:5
at [C] ExternalXaml.Engine.LuaContent.LuaCompile(String luaName) line C:\PathToProject\ExternalXaml\ExternalXaml\Engine\LuaContent.vb:69:17

Tested using:
http://www.codeproject.com/Tips/1043831/VB-NET-NeoLua-and-External-XAML-Implementation

I might be wrong about this. Perhaps my knowledge of lua is limited. Do correct me in any way. ๐Ÿ˜†

Overload resolution issue on NeoLua 1.1.1

NeoLua Interactive Command
Version NeoLua 5.3 (1.1.1.0) by neolithos

  source code at http://neolua.codeplex.com
  supported from http://tecware-gmbh.de

  Write ':h' for help.

> utf8 = clr.System.Text.Encoding.UTF8
> utf8:GetBytes('hi')
>
ArgumentNullException: Array cannot be null.
Parameter name: bytes
 at line(LuaTable _G) line line:2:1

It seems (from the stack trace in my actual application) it tries to call the UTF8Encoding.GetBytes(String, Int32, Int32, Byte[], Int32) overload, rather than GetBytes(String) as requested.

About "break"

I found two problems when I use it.

repeat
	break
	if true then end
until true

In NeoLua 5.3 (1.2.21.0) it told me "Unexpected token 'if'. 'until' expected.", In Lua 5.3 it can be use well.

And another:

local l = {}
l[1] = {v = 26}
l[2] = {v = 20}
table.sort(l, function(a, b) return a.v < b.v end)

print(l[1].v)
print(l[2].v)

In lua 5.3 is:

20
26

But NeoLua no sort them.

Can't write into file

have some problems with writing to file, so this code

local file = io.open('file.txt', 'a+')
io.output(file)
io.write('hey')
io.close(file)

doesn't write anithing and gives an exception on io.close(file):

[16:11:48] ERROR: Error creating script environment for resource admin: ะ”ะพัั‚ัƒะฟ ะบ ะทะฐะบั€ั‹ั‚ะพะผัƒ ั„ะฐะนะปัƒ ะฝะตะฒะพะทะผะพะถะตะฝ.
[16:11:51] ERROR: at [U] System.IO.__Error.FileNotOpen()
[16:11:51] ERROR: at [U] System.IO.FileStream.Write(Byte[] array,Int32 offset,Int32 count)
[16:11:51] ERROR: at [U] System.IO.StreamWriter.Flush(Boolean flushStream,Boolean flushEncoder)
[16:11:51] ERROR: at [U] System.IO.StreamWriter.Flush()
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFile.flush() line C:\Projects\NeoLua\NeoLua\LuaFile.cs:128:6
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFileStream.flush() line C:\Projects\NeoLua\NeoLuaD\LuaFile.cs:38:4
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFile.Dispose(Boolean disposing) line C:\Projects\NeoLua\NeoLua\LuaFile.cs:106:4
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFileStream.Dispose(Boolean disposing) line C:\Projects\NeoLua\NeoLuaD\LuaFile.cs:33:4
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFile.close() line C:\Projects\NeoLua\NeoLua\LuaFile.cs:118:4
[16:11:51] ERROR: at [C] Neo.IronLua.LuaFilePackage.close(LuaFile file) line C:\Projects\NeoLua\NeoLuaD\LuaFile.cs:242:9
[16:11:51] ERROR: at [U] CallSite.Target(CallSite,Object,Object)
[16:11:51] ERROR: at [U] System.Dynamic.UpdateDelegates.UpdateAndExecute2(CallSite site,T0 arg0,T1 arg1)
[16:11:51] ERROR: at [U] CallSite.Target(CallSite,Object,Object)
[16:11:51] ERROR: at [L] server(LuaTable _G) line server.lua:4:1

find with multiple returns

string testst = "fsdfsdF/R/1/EP";
string chunkbody = "function getOrig(z) _,_,o = string.find(z, '.*/.*/.*/(.*)'); return o; end;";
using (Lua le = new Lua()) {
    dynamic g = le.CreateEnvironment();
    g.dochunk(chunkbody, "test.lua");
    Console.WriteLine((string)g.getOrig(testst));
}

displays

fsdfsdF/R/1/EP

when according to http://www.lua.org/cgi-bin/demo, it should display

EP

[documentation request] Xamarin.iOS support

Hey there! Just saw NeoLua and I'm very interested in exploring it further. I'm currently without access to a working Xamarin.iOS environment, otherwise I'd check this myself, but I noticed that NeoLua uses the DLR but advertises support for iOS. I wasn't aware that this is possible; could you perhaps explain that a little bit? (My understanding is that the DLR is wholly incompatible with Xamarin.iOS; maybe a line in the README to explain the NeoLua support for it would clear things up?)

Thanks very much! NeoLua looks really cool and I can't wait to play with it.

Using Constants

What is the best approach to using constants declared in C# in the lua script.

FYI: When I try calling the EntityStates.RESTING without passing the reference it throws an exception.

C#:
_inputs.Add("target", this);
_inputs.Add("constants", typeof(EntityStates));

Lua Script:
local EntityStates = inputs["constants"];

    `if (entity.StateManager.HasState(EntityStates.RESTING) == true) then
        hpRegen = (((entity.GetValue("level") + 20) *1) / 750);`

Nuget Error

I am not sure if this goes here or not....
image

About table.sort with function

When I sort a table like this:

	local tbl = {{1,2}, {2,3}, {2,0}}

	table.sort(tbl , function(a , b)
			return false
		end)

In NeoLua 5.3 (1.2.21.0) it told me "INNER EXCEPTION", but in Lua 5.3 it can be use.

Cast nil to string returns String.Empty

NeoLua Version: >1.2.23

Example to reproduce:

return cast(string, nil) -- returns String.Empty

This code has an unexpected result:

local s : string = nil;
return not s; -- returns false instead of true

see also test: TestLogic13a

I changed the cast/convert, that the result is nil now. (breaking change)

Are there arguments against this change?

Please updated the basic documentation

Hi,
Please update the basic documentation otherwise its difficult to even get started. The below line from "Getting started" documentation doesn't works

using (LuaChunk chunk = l.CompileChunk(c, Lua.DefaultDebugEngine))

string.find not behaving as expected

This snippet prints "Found direction" in normal Lua and "Found me" in neoLua

netDebug = print

local strPrefix = "/x-name/other/v1.0"

local path_map = {base=strPrefix .. "/",me=strPrefix .. "/me",energy=strPrefix .. "/energy",direction=strPrefix .. "/direction",devices=strPrefix .. "/devices",items=strPrefix .. "/items",collections=strPrefix .. "/collections"}

path = "/x-name/other/v1.0/direction"

if string.find(path, path_map.me,1,true) then
  netDebug("Found me")
elseif string.find(path, path_map.energy,1,true) then
  netDebug("Found energy")
elseif string.find(path, path_map.direction,1,true) then
  netDebug("Found direction")
end

Local function declaration bug

This declaration works fine.

local summaryPanel_Resize = function (sender, args): void
-- Do something
end;

While this one throws an exception:

local function summaryPanel_Resize(sender, args): void
-- Do something
end;

LuaAssert method should call LuaError

The LuaAssert method in LuaGlobal.cs uses the Debug.Assert function. This causes problems because that assert will terminate the application in Debug mode and do nothing in Release mode..

We use assert for unit testing and expect a LuaRuntimeException to be thrown with the message supplied to the assert function and check for it in the tests. A test suite can have many tests, each able to fail.

In Lua 5.2, the assert function calls the error function, so this behavior is consistent with how the language works. The patch below illustrate the suggested change.

--- a/NeoLua/LuaGlobal.cs
+++ b/NeoLua/LuaGlobal.cs
@@ -267,7 +267,8 @@ namespace Neo.IronLua
        [LuaMember("assert")]
        private static object LuaAssert(object value, string sMessage)
        {
-           Debug.Assert(IsTrue(value), sMessage);
+           if (!IsTrue(value))
+               LuaError(sMessage ?? "assertion failed!", 1);
            return value;
        } // func LuaAssert

Get chunk name from method?

I have an event system where scripts can add functions as listeners. I want to disconnect the listener if a flag in the script is set, but I don't know how to access the script/chunk name from the MethodInfo.

Range character classes in regexp work incorrectly

Character classes with range in regexp work incorrectly in NeoLua.

C Lua sample:

local r = string.gsub("192.168.33.15", '[0-9]+', "x");
print(r);
-- prints x.x.x.x -> ok

NeoLua sample

form.testBox.Text = string.gsub("192.168.33.15", '[0-9]+', "x");
-- prints 1x2.168.33.15 -> ERROR

Although if you set string.__TranslateRegEx = true, it works fine again.
Is there a bug in regexp translator?

about "..."

Hi, I found two problems when I used it.

function test1(...)
	print(...[1]) -- print 2 ???
end

test1(1,2,3,4,5)
  
function test2(...)
	local t={...}	-- error in CompileChunk
	print(t[1])
end

test2(1,2,3,4,5)
  

Thanks for you help :)

Attempt to use wrong overload.

I believe I've commented about this issue before, but I can't seem to find the original post.

I have two constructors: one takes 3 floats and the other takes 2 Vector3 objects.
When calling the constructor with 2 Vector3s, it tries to use the 3-float operator, resulting in a No conversion defined from Vector3 to Single. exception. I have trouble understanding why it would ever want/need to pick an overload that doesn't even have the same number of arguments.

I don't plan on using any BCL/clr code from Lua, and compatibility with existing scripts is more important in my project, so if this behaviour can't be fixed without affecting clr-compatibility, it would be nice to have it as a compile option.

This was tested with both 1.2.5 and the latest commit.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Neo.IronLua;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Lua l = new Lua())
            {
                var t = new LuaGlobalPortable(l);
                t.RegisterPackage("CFrame", typeof(CFrame));
                t.RegisterPackage("Vector3", typeof(Vector3));
                var c = l.CompileChunk(
                    @"
local v = Vector3(1, 2, 3)
local test1 = CFrame(v, v) -- no error

local test2 = CFrame(v, Vector3(1, 2, 3)) -- error

return test3
", "test", null);
                var r = c.Run(t);
            }
        }

        class Vector3
        {
            public float x;
            public float y;
            public float z;

            public Vector3(float x, float y, float z)
            {
                this.x = x;
                this.y = y;
                this.z = z;
            }
        }

        class CFrame
        {
            public float x;
            public float y;
            public float z;

            public CFrame(float x, float y, float z)
            {
                x = x;
                y = y;
                z = z;
            }

            public CFrame(Vector3 v0, Vector3 v1)
            {
                x = v0.x + v1.x;
                y = v0.y + v1.y;
                z = v0.z + v1.z;
            }
        }
    }
}

semver.lua (https://github.com/kikito/semver.lua) crashes.

An exception of type 'System.ArgumentException' occurred in System.dll but was not handled in user code
parsing "^(+?[^+]+)(+.+)$" - Quantifier {x,y} following nothing.

And:

"^(%d+)%.?(%d_)%.?(%d_)(.-)$" incorrectly matches the 3rd group as a the 4th group, so
1.2.0 becomes "1". "2", "", "0".

Code Customization Options

Is there a way to add custom expressions to the language? The ability to extend the language in anyway?

I would like to add custom keywords like

world myVar = 9000 -- this variable would be available to the world not just local scope
-- or
thread myFunc(args)
-- execute code on separate thread
end

Is there anyway to open up the api to allow that?

Cannot write file without close

NeoLua Version: NeoCmd 5.3 (1.2.23.0)

I use it to output some text. but the output file is empty.

file = io.open("test.txt", "w")
file:write("test")
-- no file:close()

Handling of require doesn't work if StandardPackagesPath is changed

In NeoLuaD / Lua.Libraries.cs there is a return from the loop as soon as LuaRequireCheckFile is called. This means only the first path in paths is checked, so scripts in a path added to StandardPackagesPath will never be found (see line 130 below).

123             foreach (string c in paths) 
124             { 
125                 if (String.IsNullOrEmpty(c)) 
126                     continue; 
127                 else 
128                 { 
129                     sFileName = System.IO.Path.Combine(c, sModName + ".lua"); 
130                     return LuaRequireCheckFile(ref sFileName, ref dtStamp); 
131                 } 
132             } 

string.find vs s:find

hello in the following code:

var v = new {
    F1Article = "HON",
    CArticle = "TRADUCTION",
    IsCpi = "X",
    HT = 10
};
using (Lua le = new Lua()) {
    LuaGlobal lg = le.CreateEnvironment();                                

    try {
        Func<Object, Boolean> f0 = lg.Lua.CreateLambda<Func<Object, Boolean>>(String.Format("f0"), "return l.CArticle:find(\"^TRAD\")", "l");
        Console.WriteLine("f0: {0}", f0(v));
    } catch (Exception ex) { 
        Console.WriteLine(ex.Message); 
    }

    try {
        Func<Object, Boolean> f1 = lg.Lua.CreateLambda<Func<Object, Boolean>>(String.Format("f1"), "return string.find(l.CArticle, \"^TRAD\")", "l");
        Console.WriteLine("f1: {0}", f1(v));
    } catch (Exception ex) {
        Console.WriteLine(ex.Message);
    }
}

the first try runs, but the second crashes.

Changes to the api and target version

Hi at all,

currently, I thing about to change the Neo.Lua.dll to a portable version for .net framework 4.5.1, Windows Phone 8.1, Windows Store Apps 8.1, Xamarin.Android, Xamarin.iOS.

Changes needed:

  • LuaResult will not implement IConvertible anymore
  • LuaTable will not implement ITypedList anymore
  • LuaGlobal and StackTrace Debugger will be moved to library Neo.Lua.Desktop.dll (.net framework 4.5.1)
  • Assembly loader loads assemblies (ReflectionOnlyLoad is missing)

I need a little bit feedback or suggestions. Are you with this changes comfortable?

Regex for %b

Another Addition. I think this is the correct regex for the %b

                                if (i < sRegEx.Length - 2)
                                {
                                    char c1 = sRegEx[i + 1];
                                    char c2 = sRegEx[i + 2];
                                    //Example for %b()
                                    //(\((?>(?<n>\()|(?<-n>\))|(?:[^\(\)]*))*\)(?(n)(?!)))
                                    //Example for %bab
                                    //(a(?>(?<n>a)|(?<-n>b)|(?:[^ab]*))*b(?(n)(?!)))
                                    sb.Append("(");
                                    sb.Append(Regex.Escape(c1.ToString()));
                                    sb.Append("(?>(?<n>");
                                    sb.Append(Regex.Escape(c1.ToString()));
                                    sb.Append(")|(?<-n>");
                                    sb.Append(Regex.Escape(c2.ToString()));
                                    sb.Append(")|(?:[^");
                                    sb.Append(Regex.Escape(c1.ToString()));
                                    sb.Append(Regex.Escape(c2.ToString()));
                                    sb.Append("]*))*");
                                    sb.Append(Regex.Escape(c2.ToString()));
                                    sb.Append("(?(n)(?!)))");
                                    i += 2;
                                }
                                else
                                    throw new ArgumentOutOfRangeException();
                                break;

I have tested against this

s = [[
(Standard)
(() Double Brackets ())
( Across Lines
)
(()  Double Brackets Across Lines
())
(2 in) (A Line)
Before(Inside)After
MissMatch (found))
)Not Matched(
MissMatch2 ((found2)
]]

for k in string.gmatch(s,"%b()") do
  print(k)
end

--[[ Expected Results
(Standard)
(() Double Brackets ())
( Across Lines
)
(()  Double Brackets Across Lines
())
(2 in)
(A Line)
(Inside)
(found)
(found2)
]]--

And the results for both c# and lua are the same.

I need to learn how to use git!

Overload finder picks the wrong one

Picks wrong override:

line = clr.System.String[]("Hallo", "Welt", "!!!");
return clr.System.String:Join(" ", line)

Same on String.Format.

Syntax parser bug?

Possibly I've run into a bug in the syntax parser.

clr.System.Windows.Forms.MessageBox.Show( "Hello":ToUpper() );
-- Raises execption

Let's add extra parentheses.

clr.System.Windows.Forms.MessageBox.Show( ("Hello":ToUpper()) );
-- Works fine

Sandboxing Lua code.

I want to run Lua code in a mostly empty environment, so my scripts do not have access to IO, for example.

My first attempt was to clear the members of the default LuaGlobal, but I got:

Can't load file LuaTable.cs under c:\Projects\NeoLua\NeoLua.
Check the file permission and the existence of that file.

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Neo.IronLua.LuaTable.RemoveValue(Int32 iIndex) in c:\Projects\NeoLua\NeoLua\LuaTable.cs:line 1581
   at Neo.IronLua.LuaTable.System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.Clear()

It looks like two problems at the very least: you have debug info in the NuGet version of the library, so SharpDevelop tried to open the source, and second, you can't run LuaGlobal.Members.Clear() despite .IsReadOnly being set to false.

The third problem is that the environment doesn't contain the "clr" member, but I am still able to use it:
assert: System.Object LuaAssert(System.Object, System.String)
collectgarbage: Neo.IronLua.LuaResult LuaCollectgarbage(System.String, System.Object)
dofile: Neo.IronLua.LuaResult LuaDoFile(System.Object[])
dochunk: Neo.IronLua.LuaResult LuaDoChunk(System.Object[])
error: Void LuaError(System.String, Int32)
getmetatable: Neo.IronLua.LuaTable LuaGetMetaTable(System.Object)
ipairs: Neo.IronLua.LuaResult LuaIPairs(Neo.IronLua.LuaTable)
pairs: Neo.IronLua.LuaResult LuaPairs(Neo.IronLua.LuaTable)
load: System.Object LuaLoad(System.Object, System.String, System.String, Neo.IronLua.LuaTable)
loadfile: System.Object LuaLoadFile(System.String, System.String, Neo.IronLua.LuaTable)
next: System.Object LuaNext(Neo.IronLua.LuaTable, System.Object)
pcall: Neo.IronLua.LuaResult LuaPCall(System.Object, System.Object[])
print: Void LuaPrint(System.Object[])
rawequal: Boolean LuaRawEqual(System.Object, System.Object)
rawget: System.Object LuaRawGet(Neo.IronLua.LuaTable, System.Object)
rawlen: Int32 LuaRawLen(System.Object)
rawset: Neo.IronLua.LuaTable LuaRawSet(Neo.IronLua.LuaTable, System.Object, System.Object)
require: Neo.IronLua.LuaResult LuaRequire(System.Object)
select: Neo.IronLua.LuaResult LuaSelect(System.String, System.Object[])
setmetatable: Neo.IronLua.LuaTable LuaSetMetaTable(Neo.IronLua.LuaTable, Neo.IronLua.LuaTable)
tonumber: System.Object LuaToNumber(System.Object, System.Nullable`1[System.Int32])
tostring: System.String LuaToString(System.Object)
type: System.String LuaTypeTest(System.Object, Boolean)
xpcall: Neo.IronLua.LuaResult LuaXPCall(System.Object, System.Object, System.Object[])
_VERSION: NeoLua 5.3
table: Neo.IronLua.LuaTable
coroutine: Neo.IronLua.LuaThread
io: Neo.IronLua.LuaFilePackage
package: Neo.IronLua.LuaGlobal+LuaLibraryPackage
bit32: Neo.IronLua.LuaLibraryBit32
math: Neo.IronLua.LuaLibraryMath
os: Neo.IronLua.LuaLibraryOS
string: Neo.IronLua.LuaLibraryString
debug: Neo.IronLua.LuaLibraryDebug

Even a lambda that is created without an environment still has access to everything in "clr". Is there a way to run NeoLua code in a tighly sandboxed environment? Creating a sandbox within a chunk doesn't help either:

//this doesn't work...
g.DoChunk("do\r\n" +
          "local chunk = \""+ chunk +"\"\r\n" + //ouch, injection risk in sample code!
          "load(chunk,chunk,'t',{})()\r\n" +
          "end", "test3");
//nor this...
g.DoChunk("_ENV = {}\r\n" + chunk, "test4");

creating lambda with non existing property is possible when it should not be.

please consider the following code:

using Neo.IronLua;
using System;

namespace ztests {
    class Program {
        static void Main(string[] args) {
            Folder fd = new Folder { SomeId = 1 };
            File fl = new File { Folder = fd};

            using (Lua le = new Lua()) {
                Func<File, Boolean> f0 = le.CreateLambda<Func<File, Boolean>>("f0", "return fl.Folder.SomeId == 1", "fl");
                Console.WriteLine("f0: {0}", f0(fl));
                Func<File, Boolean> f1 = le.CreateLambda<Func<File, Boolean>>("f1", "return fl.Folder.SomeId == 0", "fl");
                Console.WriteLine("f1: {0}", f1(fl));
                Func<File, Boolean> f2 = le.CreateLambda<Func<File, Boolean>>("f2", "return fl.Folder.FakeId == 1", "fl");
                Console.WriteLine("f2: {0}", f2(fl));
            }
        }
    }

    public class Folder {
        public int SomeId { get; set; }
    }

    public class File {
        public Folder Folder { get; set; }
    }
}

it outputs:

f0: True
f1: False
f2: False

which, from a certain point of view, is correct.

But fl.Folder.FakeId does not exist. Is it possible to have NeoLua raise an exception or any kind of flag in such case ?

Can avoid return multiple values?

I have a simple script(local ret;ret=request; return ret;).when I make the request argument a Array value,the script return multiple values.When I make the request argument a List Value,the Script return a single value.How Can I make the return of the first case as well as the second case?

Unexpected result for char vs string

n = "_Typ"
if n[0] ~= '_' then
  print("TRUE") 
else
  print("FALSE")
end

Results in true???

n = "_Typ"
if n[0]:ToString() ~= '_' then
  print("TRUE") 
else
  print("FALSE")
end

Has the correct result.

string.gmatch Match Multiple

Hi,

Neolua is brilliant, but I have hit a problem with gmatch.

I think there is an issue when gmatch is supposed to return multiple results.
You have a script here "NeoLua.Test/Lua/Runtime12.lua", which should show the issue.

("This is the code in the script")

local s = "from=world, to=Lua"
local i = 0;
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
    print(k .. "=" .. v);
    i = i + 1;
end;
return i;

The Printed value is incorrect, it prints
from=world=
to=Lua=

Instead of
from=world
to=Lua

It seems the first result is the only result ever returned, and this returns the who match instead of the value in brackets.

Is this a know issue?
Thanks
Simon

can this support mult threads?

NeoLua Version:
my server has many threads, the manager will scheluder those threads, some times task A will call the lua function, some times schedule task B call functions.
is this possible.
Example to reproduce:

Incorrect CLR namespace resolving

I'm trying to use MySQL .NET connector. It seems like namespaces are resolved incorrectly.

clr.System.Windows.Forms.MessageBox:Show('{0}':Format(clr.MySql.Data));
-- Outputs MySql.Data - correct

clr.System.Windows.Forms.MessageBox:Show('{0}':Format(clr.System.Data));
-- Outputs MySql.Data again - incorrect!

Because of this, I cannot create an instance of System.Data.DataTable.

local eventTable = clr.System.Data.DataTable();
-- Raises "Object is null" exception

Assigning to LuaMember bool or int

Hi

I am having an issue assigning to bool and int from a lua script, I am not sure what the best solution is.

I have a c# class that inherits from LuaTable, so it can be treated like any other table in the Lua code.
This class has a few pre existing properties, which are defined in the class.

Such as

[LuaMember("DebugOn")]
public bool DebugOn
{
    get;
    set;
}

Getting the properties from bool and int work fine in the lua code.

debugValue = object.DebugOn

But if I try to set a boolean or Int I get a dynamic binding exception

object.DebugOn = false

"The result type 'System.Boolean' of the dynamic binding produced by the object with type 'Model.Protocols' for the binder 'Neo.IronLua.Lua+LuaSetMemberBinder' is not compatible with the result type 'System.Object' expected by the call site."

If I change to type to an object it works fine. But then I have to cast the value to what it should be. Like so:

private bool debugOn;
[LuaMember("DebugOn")]
public bool DebugOn
{
    get { return debugOn;}
    set { debugOn = (bool)value; }
}

Is there a better way of doing this? Am I doing something wrong.

Thanks
Simon

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.