yanghuan / csharp.lua Goto Github PK
View Code? Open in Web Editor NEWThe C# to Lua compiler
License: Other
The C# to Lua compiler
License: Other
I mean methods like load
, require
, etc
dynamic script = G.Get("script");
script.A("test");
causes
1> System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitInvocationExpression(InvocationExpressionSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 1202
1> в Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitExpressionStatement(ExpressionStatementSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 912
1> в Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionStatementSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxNodeTransfor.BlockCommonNode.Visit(LuaSyntaxNodeTransfor transfor, LuaBlockSyntax block, Int32& lastLine) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 832
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitBlock(BlockSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 877
1> в Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitMethodDeclaration(MethodDeclarationSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 446
1> в Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxNodeTransfor.BuildTypeMembers(LuaTypeDeclarationSyntax typeDeclaration, TypeDeclarationSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 167
1> в CSharpLua.LuaSyntaxNodeTransfor.BuildTypeDeclaration(INamedTypeSymbol typeSymbol, TypeDeclarationSyntax node, LuaTypeDeclarationSyntax typeDeclaration) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 217
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitTypeDeclaration(TypeDeclarationSyntax node, LuaTypeDeclarationSyntax typeDeclaration) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 253
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitClassDeclaration(ClassDeclarationSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 337
1> в Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxNodeTransfor.VisitCompilationUnit(CompilationUnitSyntax node) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:строка 144
1> в Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
1> в CSharpLua.LuaSyntaxGenerator.Create() в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:строка 120
1> в CSharpLua.LuaSyntaxGenerator.Generate(String baseFolder, String outFolder) в D:\Project\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:строка 140
1> в CSharpLua.Worker.Compiler() в D:\Project\CSharp.lua\CSharp.lua\Worker.cs:строка 111
1> в CSharpLua.Program.Main(String[] args) в D:\Project\CSharp.lua\CSharp.lua\Program.cs:строка 67
I use
<?xml version="1.0" encoding="utf-8" ?>
<meta>
<assembly>
<namespace name="NativeApi">
<class name="G" Name="_G">
<method name="Get" ArgCount="1" Template="_G[{0}]" />
<method name="Set" ArgCount="2" Template="_G[{0}] = {1}" />
</class>
</namespace>
</assembly>
</meta>
public class G
{
public static dynamic Get(dynamic n)
{
throw new NotImplementedException();
}
public static dynamic Set(dynamic n, dynamic v)
{
throw new NotImplementedException();
}
}
When you use Func<> to store a function that returns something, for example as a parameter that takes a lambda expression, the function is invoked incorrectly.
namespace Test
{
class Program
{
static void Main(string[] args)
{
var a = Test(() => true);
}
static bool Test(Func<bool> selector)
{
return selector.Invoke();
}
}
}
Compiles to:
-- Generated by CSharp.lua Compiler 1.1.0
local System = System
System.namespace("Test", function (namespace)
namespace.class("Program", function (namespace)
local Main, Test
Main = function (args)
local a = Test(function ()
return true
end)
end
Test = function (selector)
return selector:Invoke() -- Notice :Invoke() is called, while the selector should just simply be invoked
end
return {
Main = Main
}
end)
end)
On the Func<> parameter, the :Invoke method is called, which doesn't exists.
This should compile to something like selector()
:
Test = function (selector)
return selector()
end
**Version: ** Master commit: 6621be8
Hi, first - thank you for your work!
What's exactly with nullable support? You mentioned in FAQ that it doesn't work, I don't see why it's hard to implement.
Structs - do they work? I mean copying with assignment and passing argument "by value".
What class is directly translated to lua's hashtable class?
Are generic collections supported?
Are custom generic classes supported?
测试代码
var a = typeof(IEnumerable<>);
报错:
1> }" ---> System.Exception: Compiler has a bug, thanks to commit issue at https://github.com/yanghuan/CSharp.lua/issue, SourceLocation(D:\OWM_Client3\GameScript\/CSLua\Frameworks\MicroResolver\Internal\CompilationContext.cs@23:13)"var a = typeof(IEnumerable<>);" ---> System.NullReferenceException: Object reference not set to an instance of an object. 1> at CSharpLua.Utility.GetTypeShortName(INamedTypeSymbol typeSymbol, Func
3 funcOfNamespace, Func2 funcOfTypeName) in D:\src\CSharp.lua\CSharp.lua\Utils.cs:line 718 1> at CSharpLua.LuaSyntaxGenerator.GetTypeShortName(ISymbol symbol, LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 1368 1> at CSharpLua.LuaSyntaxGenerator.GetTypeName(ISymbol symbol, LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 1324 1> at CSharpLua.LuaSyntaxGenerator.FillTypeArguments(List
1 typeArguments, INamedTypeSymbol typeSymbol, LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 1352
1> at CSharpLua.LuaSyntaxGenerator.GetTypeArguments(INamedTypeSymbol typeSymbol, LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 1338
1> at CSharpLua.LuaSyntaxGenerator.GetTypeName(ISymbol symbol, LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 1325
1> at CSharpLua.LuaSyntaxNodeTransform.GetTypeName(ISymbol symbol) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.Helper.cs:line 572
1> at CSharpLua.LuaSyntaxNodeTransform.VisitGenericName(GenericNameSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.Object.cs:line 168
1> at CSharpLua.LuaSyntaxNodeTransform.VisitTypeOfExpression(TypeOfExpressionSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.Object.cs:line 428
1> at CSharpLua.LuaSyntaxNodeTransform.VisitEqualsValueClause(EqualsValueClauseSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 2110
1> at CSharpLua.LuaSyntaxNodeTransform.VisitVariableDeclarator(VariableDeclaratorSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 2104
1> at CSharpLua.LuaSyntaxNodeTransform.VisitVariableDeclaration(VariableDeclarationSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 2082
1> at CSharpLua.LuaSyntaxNodeTransform.VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 2058
1> at CSharpLua.LuaSyntaxNodeTransform.BlockCommonNode.Visit(LuaSyntaxNodeTransform transfor) in D:\src\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 940
`
using System;
namespace UnitTest
{
public class StaticClassA
{
public static StaticClassA field1 = new StaticClassA();
}
public class StaticClassB
{
StaticClassA field2 = StaticClassA.field1;
static StaticClassA field3 = StaticClassA.field1;
StaticClassB()
{
StaticClassA field4 = StaticClassA.field1;
}
}
}
用这个测试用例,转换时会报错,望修复。
var assetPath = "UI/Login.prefab";
var lastDot = assetPath.LastIndexOf('.');
预期lastDot应该等于8,结果不正确
Having a method with params like so:
C#: [...] public void Log(object thing, params object[] args)
And calling it like:
C#: [...] Log("Testing something {0}:", 1234);
Generates:
Lua: [...] Log("Testing something {0}:", 1234)
When it should generate:
Lua: [...] Log("Testing something {0}:", System.Array(System.Object)(1234))
The syntactic sugar normally applied by the compiler (turning params arguments into an array) is missing and therefor valid C# code will compile to incorrect Lua code.
Workaround is to not use params or just pass an array yourself.
Window.cs
`namespace CSLua
{
public class Window
{
}
public class Window<T> : Window
{
}
}
`
LoginResource.cs
`
namespace CSLua
{
public class LoginResource
{
}
}
`
TestHelloWorld.cs
`using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace CSLua
{
public class LoginPage : Window
{
}
}
namespace Sample
{
public sealed class TestHelloWord : MonoBehaviour
{
public void Awake()
{
new CSLua.LoginPage();
}
}
}
`
根据这个的代码编译成lua运行,即可会导致运行报错
`LuaException: D:/src/CSharpLuaForUnity/Assets/Lua/CompiledScripts/Sample/TestHelloWord.lua:12: attempt to index upvalue 'CSLua' (a nil value)
stack traceback:
D:/src/CSharpLuaForUnity/Assets/Lua/CompiledScripts/Sample/TestHelloWord.lua:12: in function 'extends'
D:/src/CSharpLuaForUnity/Assets/Lua/CoreSystemLua/CoreSystem/Core.lua:168: in function 'setBase'
D:/src/CSharpLuaForUnity/Assets/Lua/CoreSystemLua/CoreSystem/Core.lua:264: in function 'def'
D:/src/CSharpLuaForUnity/Assets/Lua/CoreSystemLua/CoreSystem/Core.lua:1093: in function <D:/src/CSharpLuaForUnity/Assets/Lua/CoreSystemLua/CoreSystem/Core.lua:1092>
D:/src/CSharpLuaForUnity/Assets/Lua/CoreSystemLua/CoreSystem/Core.lua:858: in function 'init'
D:/src/CSharpLuaForUnity/Assets/Lua/CompiledScripts/manifest.lua:13: in function <D:/src/CSharpLuaForUnity/Assets/Lua/CompiledScripts/manifest.lua:2>
D:/src/CSharpLuaForUnity/Assets/Lua/Classloader.lua:13: in main chunk
[C]: in function 'require'
D:/src/CSharpLuaForUnity/Assets/Lua/Main.lua:1: in main chunk
LuaInterface.LuaState:LuaLoadBuffer(Byte[], String) (at Assets/BaseScripts/ToLua/Core/LuaState.cs:2158)
LuaInterface.LuaState:DoFile(String) (at Assets/BaseScripts/ToLua/Core/LuaState.cs:624)
LuaClient:StartMain() (at Assets/BaseScripts/ToLua/Misc/LuaClient.cs:141)
CSharpLua.CSharpLuaClient:StartMain() (at Assets/BaseScripts/CSharpLua/CSharpLuaClient.cs:137)
LuaClient:OnLoadFinished() (at Assets/BaseScripts/ToLua/Misc/LuaClient.cs:183)
LuaClient:LoadLuaFiles() (at Assets/BaseScripts/ToLua/Misc/LuaClient.cs:54)
LuaClient:Init() (at Assets/BaseScripts/ToLua/Misc/LuaClient.cs:166)
LuaClient:Awake() (at Assets/BaseScripts/ToLua/Misc/LuaClient.cs:172)
`
When there are spaces in an input or output directory the path should be passed like
-s "D:\Sources Folder" -d "D:\My Documents\Path"
我想在第三方一个支持lua脚本的程序里用csharp.lua 我看了下你的core里小于 5.3 require(bit) 但 有的5.2是没有bit的 实际我可能也用不到bit操作 有法子绕过这个报错吗 或者 怎么给他加个bit包呢?
When I use this minimal test case to reproduce the issue:
using System.Collections.Generic;
namespace Test
{
public enum Test {
a,
b
}
public class TestClass {
public Dictionary<Test, bool> test = new Dictionary<Test, bool>() {
{Test.a, true},
{Test.b, false}
};
}
}
I get this as the output when trying to build:
Assertion failed.
Description: Assertion failed.
Stack Trace:
at CSharpLua.LuaSyntaxNodeTransfor.VisitInitializerExpression(InitializerExpressionSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.Object.cs:line 142
at CSharpLua.LuaSyntaxNodeTransfor.BuildObjectInitializerExpression(InitializerExpressionSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.Object.cs:line 112
at CSharpLua.LuaSyntaxNodeTransfor.VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.Object.cs:line 80
at CSharpLua.LuaSyntaxNodeTransfor.GetFieldValueExpression(TypeSyntax type, ITypeSymbol typeSymbol, ExpressionSyntax expression, Boolean& valueIsLiteral) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 636
at CSharpLua.LuaSyntaxNodeTransfor.AddField(LuaIdentifierNameSyntax name, ITypeSymbol typeSymbol, TypeSyntax type, ExpressionSyntax expression, Boolean isImmutable, Boolean isStatic, Boolean isPrivate, Boolean isReadOnly, SyntaxList`1 attributeLists) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 659
at CSharpLua.LuaSyntaxNodeTransfor.VisitBaseFieldDeclarationSyntax(BaseFieldDeclarationSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 608
at CSharpLua.LuaSyntaxNodeTransfor.VisitFieldDeclaration(FieldDeclarationSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 628
at Microsoft.CodeAnalysis.CSharp.Syntax.FieldDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at CSharpLua.LuaSyntaxNodeTransfor.BuildTypeMembers(LuaTypeDeclarationSyntax typeDeclaration, TypeDeclarationSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 175
at CSharpLua.LuaSyntaxNodeTransfor.BuildTypeDeclaration(INamedTypeSymbol typeSymbol, TypeDeclarationSyntax node, LuaTypeDeclarationSyntax typeDeclaration) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 239
at CSharpLua.LuaSyntaxNodeTransfor.VisitTypeDeclaration(INamedTypeSymbol typeSymbol, TypeDeclarationSyntax node, LuaTypeDeclarationSyntax typeDeclaration) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 286
at CSharpLua.LuaSyntaxNodeTransfor.VisitClassDeclaration(ClassDeclarationSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 367
at Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at CSharpLua.LuaSyntaxNodeTransfor.BlockCommonNode.Visit(LuaSyntaxNodeTransfor transfor) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 922
at CSharpLua.LuaSyntaxNodeTransfor.<VisitTriviaAndNode>d__71.MoveNext() in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 977
at System.Linq.Enumerable.<CastIterator>d__34`1.MoveNext()
at CSharpLua.LuaAst.LuaSyntaxList`1.AddRange(IEnumerable`1 collection) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaAst\LuaSyntaxNode.cs:line 158
at CSharpLua.LuaAst.LuaWrapFunctionStatementSynatx.AddStatements(IEnumerable`1 statements) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaAst\LuaWrapFunctionStatementSynatx.cs:line 50
at CSharpLua.LuaSyntaxNodeTransfor.VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 168
at Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at CSharpLua.LuaSyntaxNodeTransfor.BlockCommonNode.Visit(LuaSyntaxNodeTransfor transfor) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 922
at CSharpLua.LuaSyntaxNodeTransfor.<VisitTriviaAndNode>d__71.MoveNext() in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 977
at CSharpLua.LuaSyntaxNodeTransfor.VisitCompilationUnit(CompilationUnitSyntax node) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransfor.cs:line 148
at Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
at CSharpLua.LuaSyntaxGenerator.Create() in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 120
at CSharpLua.LuaSyntaxGenerator.Generate(String outFolder) in F:\Misc\code\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 138
at CSharpLua.Worker.Compiler() in F:\Misc\code\CSharp.lua\CSharp.lua\Worker.cs:line 126
at CSharpLua.Worker.Do() in F:\Misc\code\CSharp.lua\CSharp.lua\Worker.cs:line 111
at CSharpLua.Program.Main(String[] args) in F:\Misc\code\CSharp.lua\CSharp.lua\Program.cs:line 64
Any potential fixes/workarounds? For now, I'm thinking of just using the int values of the enum values as keys, but I'm wondering if there's a better solution.
Edit: Just tested that, it didn't work.
string a = "a, b";
string[] aa = a.Split(',');
转换成
local a = "a, b"
local aa = a:Split(44 --[[',']])
在CoreSystem/String.lua的函数String.Split中会使用到这个传入的44
然后调用44:gsub("([%%%^%.])", "%%%1")
应该直接转换为
local a = "a, b"
local aa = a:Split(',')
就对了
重现代码:
`using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Sample
{
public class Value
{
T _value = default(T);
public T value
{
get
{
return _value;
}
set
{
_value = value;
}
}
}
public sealed class TestHelloWord : MonoBehaviour
{
Value<int> _intValue = new Value<int>();
public void Awake()
{
_intValue.value++;
}
}
}
`
_intValue.value++;的代码,会编译成
default:setvalue() = default:getvalue() + 1
导致运行时报错
I know CSharp.lua produces readable Lua code from Roslyn, what keeps...
But, some cons:
This is table-indexing.
t['x']
t.x
rawget(t, 'x')
(Raw access and dot or brackets access.)
There's no reason to reuse things of the output (e.g., namespaces and names) from Lua. You could rather re-use the csc assemblies, for avoiding re-compilation.
With -reusable flag, table indices aren't avoided.
A name like MyStaticDef.StaticMethod
or NsQual.Member
is rather expressed by using mangled locals.
This means the output names will be something like (except _ENV
or _G
)
A B C
a b c
_A
_0
__
___A
rather than
Class.StatixMethod
OriginClass.Peek
Nsx.Ver
Mx.CoreClass.Go
-- etc...
... A minimum combination of every allowed Lua id char.
Structs variables are stored as locals in Lua code. If contained in a class or object, they're stored as array fields instead.
Normal variables are stored in contiguous arrays and accessed by indices.
These arrays are class instances theirselves. Since some classes extend another, it may be necessary to reserve the first array field for helping virtual methods or the is
operator.
Here an example...
-- first variable, named x
uint x = 10
compiles to...
-- in class constructor
this[1]=10
or may be even removed from the output or expanded to a local.
Things like table.remove or print aren't accessed directly, as they can conflict with mangled names. You rather put
local _ENV = _ENV or _G
_ENV.table.something
And more, add something like Lua namespace for allowing to access the environment table from C#. Do that w/o overhead, e.g.:
namespace Lua
{
public struct LuaValue
{
...
public LuaValue rawget(LuaValue key);
publuc LuaValue index(LuaValue key);
}
}
// later on
LuaValue.Env.index(new LuaValue("print")).call()
This must be optimized such that LuaValue does have no overhead. This means, LuaValue will simply be stored as the expected value. Table, anything...
E.g.:
_ENV.print() -- output
A pull request wouldn't be so hard, err.
Line numbers and columns can be kept in various ways, optionally. Errors will carry them, be caught and display them along w/ the message.
namespace Game
{
public class KLASS{
public static string ASTATIC = "im fox"; //error
public KLASS(){}
public void on(){}
}
public class KLASS2 : KLASS{
public KLASS2()
{
on();
}
}
public class Start
{
public static void Main()
{
new KLASS2();
}
}
}
↑ this will be wrong!
↓ no wrong , but can't init this static menber
namespace Game
{
public class KLASS{
public static string ASTATIC;
public KLASS(){ ASTATIC = "im fox"; }
public void on(){}
}
public class KLASS2 : KLASS{
public KLASS2()
{
on();
}
}
public class Start
{
public static void Main()
{
new KLASS2();
}
}
}
Unhandled Exception: System.IO.FileNotFoundException: could not load file or assembly 'Microsoft.CodeAnalysis, Version=1.3.1.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35' or one of its dependencies.系统找不到指定文件。
at CSharpLua.Program.Main<string[] args>
`
using System;
using UnityEngine;
namespace CSLua
{
public class TestBase
{
public static Func<string, string> delegateSyncLoadUI = null;
}
public class TestClass : TestBase
{
}
public class Test1 : CSLua.LuaPage
{
}
public sealed class GameMain : MonoBehaviour {
public void Awake()
{
new TestClass();
}
}
}
`
当使用以上代码运行时,发现new TestClass()会失败。
编译后代码:
`
-- Generated by CSharp.lua Compiler 1.1.0
local System = System
local CSLua
System.usingDeclare(function (global)
CSLua = global.CSLua
end)
System.namespace("CSLua", function (namespace)
namespace.class("TestBase", function (namespace)
local staticCtor
staticCtor = function (this)
this.delegateSyncLoadUI = nil
end
return {
staticCtor = staticCtor
}
end)
namespace.class("TestClass", function (namespace)
local ctor
ctor = function (this)
this.base.ctor(this)
end
return {
inherits = function (global)
return {
global.CSLua.TestBase
}
end,
ctor = ctor
}
end)
namespace.class("Test1", function (namespace)
local ctor
ctor = function (this)
this.base.ctor(this)
end
return {
inherits = function (global)
return {
global.CSLua.LuaPage
}
end,
ctor = ctor
}
end)
namespace.class("GameMain", function (namespace)
local Awake
Awake = function (this)
CSLua.TestClass()
end
return {
inherits = function (global)
return {
global.UnityEngine.MonoBehaviour
}
end,
Awake = Awake
}
end)
end)
`
报错信息:
LuaException: D:/OWM_Client3/Assets/CSharpLua/Lua/CompiledScripts/CSLua/GameMain.lua:50: attempt to call field 'TestClass' (a table value)
stack traceback:
D:/OWM_Client3/Assets/CSharpLua/Lua/CompiledScripts/CSLua/GameMain.lua:50: in function 'Awake'
D:/OWM_Client3/Assets/CSharpLua/Lua/UnityAdapter.lua:240: in function 'ctor'
D:/OWM_Client3/Assets/CSharpLua/Lua/CoreSystemLua/CoreSystem/Core.lua:48: in function <D:/OWM_Client3/Assets/CSharpLua/Lua/CoreSystemLua/CoreSystem/Core.lua:46>
I'm having trouble understanding how I can call C-functions that were bound to Lua when it is being used to script another program. For instance, Class Foo
, writing in C, has method Foo.Do()
which returns a Bar
. It binds Foo.Do()
to Lua, exposing it as you.do().
So then, in Lua, I can do something like this, even though you.do()
is never declare in the Lua files:
Function Work()
local result = you.do()
end
In C#, though, you.do() is not defined. I could write some mocks with interfaces and statics, where the body just throws an exception. I'm not sure if that will cause problems with your library though?
Just FYI, I have no control over the application declaring Foo.Do()
.
What's the best way to achieve this?
Thank you.
c#
void func(int a, params int[] args) {
if (Array.IndexOf(args, 1) > -1) {
a = 2;
}
}
lua
func = function (a, args)
if System.Array.IndexOf(args, 1) > - 1 then
a = 2
end
end
转换完的结果应该是不对的 变长参数应该放到{...}里面
ps:感谢你的项目,现在手头的一个unity3d客户端游戏在转c#逻辑到lua代码,大量用了这个项目的自动转换代码,你修复的真快!再次感谢。
When assigning variable inline with an if-statement, the compiler creates an error in the Lua code:
namespace Test
{
class Program
{
static void Main(string[] args)
{
string test;
if ((test = "test") != null)
{
}
}
}
}
Compiles to:
-- Generated by CSharp.lua Compiler 1.1.0
local System = System
System.namespace("Test", function (namespace)
namespace.class("Program", function (namespace)
local Main
Main = function (args)
local test
if (test = "test") ~= nil then -- Syntax error.
end
end
return {
Main = Main
}
end)
end)
Note that if (test = "test") ~= nil then
is a syntax error.
**Version: ** Master commit: 6621be8
LUA 5.3版本的math.pow是nil 直接使用x^y
Math.lua使用了math.pow
CSharpLua.CompilationErrorException: SourceLocation(GeneralAlgorithm.cs@2215:29)"CheckSameCard(nowCards, 3, out threeList)": Your code is startling,17 temporary variables is not enough, please refactor your code.
private LuaIdentifierNameSyntax GetTempIdentifier(SyntaxNode node) {
int index = CurFunction.TempIndex++;
string name = LuaSyntaxNode.TempIdentifiers.GetOrDefault(index % LuaSyntaxNode.TempIdentifiers.Length);
//对index取余这样改对不对?
if (name == null) {
throw new CompilationErrorException(node, $"Your code is startling,{LuaSyntaxNode.TempIdentifiers.Length} temporary variables is not enough");
}
return new LuaIdentifierNameSyntax(name);
}
I discovered that you are using pretty outdated nuget dependencies, please consider updating.
var arr = new[] { 1, 2, 3, 4 };
这种语法不支持
VisitImplicitArrayCreationExpression
这个没实现
I just finished the first major part of a project I'm writing that uses this, and I was wondering if there was any place to share what people have made using CSharp.Lua. I have two projects currently for it:
Future project I'm looking at making: something like LuaRocks or NPM for managing dependencies for projects and managing launching projects... would there be any demand for this? Thinking it may build a larger community around this (although it is a relatively unknown project)
Like
// normal code
#if lua
--load() and other lua stuff
#endif
// C# again
or better a syntax that can return a value
Writing:
C#: public int SomeProp { get; set; }
Will not compile to anything in Lua, whilst the compiler normally makes fields for this purpose.
Workaround is manually making the fields:
C#:
private int someProp;
public int SomeProp { get => someProp; set => someProp = value; }
Currently, the self compilation is just high level integration test, but is of no use, because the output cannot be executed (Correct me if I'm wrong).
For it to be called self-compiling, which I think is a really good target, all of the compilers dependencies need to compile to lua too, which are currently Microsoft.CodeAnalysis.dll and Microsoft.CodeAnalysis.CSharp.dll.
They do however have more dependencies, but if lucky, the parts to build the syntax tree do not require that many more CLR features.
逻辑代码如下:
Vector3 vec3 = instance.vec2
这行代码被翻译成了:
local vec3 = instance.UnityEngine.ToVector3(vec2)
应该翻译成这样才对:
local vec3 = UnityEngine.ToVector3(instance.vec2)
如果把逻辑代码改成
Vector3 vec3 = (Vector3)instance.vec2;
则会自动生成正确的代码
local vec3 = UnityEngine.ToVector3(instance.vec2)
重现代码:
`using UnityEngine;
namespace CSLua
{
public class TestClass
{
public Vector2 vec2;
}
public sealed class GameMain : MonoBehaviour
{
public void Awake()
{
var instance = new TestClass();
Vector3 vec3 = instance.vec2;
}
}
}
`
生成后代码
`-- Generated by CSharp.lua Compiler 1.1.0
local System = System
local UnityEngine = UnityEngine
local CSLua
System.usingDeclare(function (global)
CSLua = global.CSLua
end)
System.namespace("CSLua", function (namespace)
namespace.class("TestClass", function (namespace)
local ctor
ctor = function (this)
this.vec2 = System.default(UnityEngine.Vector2)
end
return {
ctor = ctor
}
end)
namespace.class("GameMain", function (namespace)
local Awake
Awake = function (this)
local instance = CSLua.TestClass()
local vec3 = instance.UnityEngine.ToVector3(vec2)
end
return {
inherits = function (global)
return {
global.UnityEngine.MonoBehaviour
}
end,
Awake = Awake
}
end)
end)
`
float a=1.1f; 转换到lua : local a = 1.1f, 也加了f,所以报错
The following code writes a bool variable to the console which is concatenated with a string:
bool isActive = true;
System.Console.WriteLine("isActive: " + isActive);
It compiles to:
local isActive = true
System.Console.WriteLine("isActive: " .. isActive)
which causes an error in lua that the boolean value isActive cannot be concatenated. isActive should be wrapped with tostring() or System.toString(). Currently I am using boxing in C# as a workaround (Console.WriteLine("isActive: " + (object)isActive)
) that compiles with System.toString() around isActive. I would prefer a solution without having to change the C# code.
Is there any tool or possibility to generate C# wrapper API for existing lua library? They could return dynamic but at least I have IntelliSense for class names, method and parameter names.
希望可以在打了Attribute标签的元素上,有限的生成对应的Reflect元信息,能通过GetType().GetMember等方式把这些元信息取回来,如果没有打Attribute的元素,则可以不生成。要不然怕生成的元信息量太大了。
Attribute,可以用在很多地方,例如:
protobuf
dataconfig读取
数据绑定
UI绑定
等等很多可以大幅度精简逻辑代码的地方。
C#代码
ALog.Info("GameMain Init Start !{0} {1}", iIndex, fIndex);
模板
<method name="Info" GenericArgCount="0" Template="ALog.Info5({0}, {*1})"> <arg type="System.String"/> <arg type="System.Object[]"/> </method>
编译成lua后:
ALog.Info5("GameMain Init Start !{0} {1}", iIndexfIndex)
变参之间缺少逗号。
Like _G["name"] - how it can be done?
using System;
namespace Game
{
public static class Test
{
public static string name = "fox";
public static void change()
{
Test.name = "not fox"; // error
// name = "not fox"; // right
}
}
public class DNF_Mobile
{
public static void Main() {
Test.name = "im fox2";
Test.change();
System.Console.WriteLine(Test.name);
}
}
}
This is the wrong usage?
不能这样用吗?
I am interested in using and also contributing to CSharp.lua
It would be very helpful to have a Contributions.md for you to state, whether you welcome contributions, and if you do, then how to get started and some direction as to what parts need the most work.
Also, it would be very useful to provide English documentation, as there is no chance (for me) to read the chinese documentation ;D
Thanks for your work
Would it be possible to use the same tools to compile F# -> F# AST -> Lua AST ?
string s = "123";
var sb = new StringBuilder();
sb.Append(s[0]);
int x = int.Parse(sb.ToString()); // here x is not 1 but 31(ASCII)
when sb.Append(s[0]); s[0] is cast to byte by string:byte(), then int.Parse will consider it as a number type and get 31.
the problem is when c# call sb.Append(char c) and sb.Append(int x), c is just append at end of buffer but x will convert to string. but in lua, s[0] always return a number, and lua can not distinguish char and int here.
solution:
during transfor ast, type info can retrieve from roslyn in sb.Apppend(TYPE t), here type cast may needed when c# call ToString automatically.
After pulling this commit (git checkout af9850a), I receive an error every time I try to compile:
System.InvalidOperationException: Stack empty.
at System.Collections.Generic.Stack`1.ThrowForEmptyStack()
at System.Collections.Generic.Stack`1.Peek()
at CSharpLua.LuaSyntaxNodeTransform.get_CurBlock() in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 139
at CSharpLua.LuaSyntaxNodeTransform.VisitAssignmentExpression(AssignmentExpressionSyntax node) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 1296
at CSharpLua.LuaSyntaxNodeTransform.VisitArrowExpressionClause(ArrowExpressionClauseSyntax node) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.Object.cs:line 954
at CSharpLua.LuaSyntaxNodeTransform.VisitPropertyDeclaration(PropertyDeclarationSyntax node) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 693
at CSharpLua.LuaSyntaxNodeTransform.BuildTypeMembers(LuaTypeDeclarationSyntax typeDeclaration, TypeDeclarationSyntax node) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 181
at CSharpLua.LuaSyntaxNodeTransform.AcceptPartialType(PartialTypeDeclaration major, List`1 typeDeclarations) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxNodeTransform.cs:line 354
at CSharpLua.LuaSyntaxGenerator.CheckPartialTypes() in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 237
at CSharpLua.LuaSyntaxGenerator.Create() in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 133
at CSharpLua.LuaSyntaxGenerator.Generate(String outFolder) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\LuaSyntaxGenerator.cs:line 147
at CSharpLua.Compiler.Compile() in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\Compiler.cs:line 122
at CSharpLua.Compiler.Do() in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua\Compiler.cs:line 107
at CSharpLua.Program.Main(String[] args) in C:\Users\Joas\Desktop\CSharp.lua\CSharp.lua.Launcher\Program.cs:line 64
I do not know what causes it, but if I revert to the commit before this one (git checkout d9174b1), the compiler runs fine.
I debugged the compiler and found that the exception is thrown on this peace of code:
public bool IsDead { get; set; }
public bool IsAlive
{
get => !this.IsDead;
set => this.IsDead = !value; -- Exception thrown here
}
I appreciate the effort you put into this repository.
when compile throw exception
int[,] array = { {0, 1 }, {2, 3} };
当使用静态变量 + 成员变量 + 派生类时,基类成员函数无法识别。
重现代码:
`using System;
using UnityEngine;
namespace CSLua
{
public class BaseClass
{
public string memberValue = string.Empty;
public static bool staticValue = false;
public void Show()
{
}
}
public class TestClass : BaseClass
{
}
public sealed class GameMain : MonoBehaviour
{
public void Awake()
{
var ins = new TestClass();
ins.Show();
}
}
}
`
编译后代码:
`-- Generated by CSharp.lua Compiler 1.1.0
local System = System
local CSLua
System.usingDeclare(function (global)
CSLua = global.CSLua
end)
System.namespace("CSLua", function (namespace)
namespace.class("BaseClass", function (namespace)
local Show, staticCtor, ctor
staticCtor = function (this)
this.staticValue = false
end
ctor = function (this)
this.memberValue = ""
end
Show = function (this)
end
return {
Show = Show,
staticCtor = staticCtor,
ctor = ctor
}
end)
namespace.class("TestClass", function (namespace)
local ctor
ctor = function (this)
this.base.ctor(this)
end
return {
inherits = function (global)
return {
global.CSLua.BaseClass
}
end,
ctor = ctor
}
end)
namespace.class("GameMain", function (namespace)
local Awake
Awake = function (this)
local ins = CSLua.TestClass()
ins:Show()
end
return {
inherits = function (global)
return {
global.UnityEngine.MonoBehaviour
}
end,
Awake = Awake
}
end)
end)
`
报错堆栈:
LuaException: D:/OWM_Client3/Assets/CSharpLua/Lua/CompiledScripts/CSLua/GameMain.lua:43: attempt to call method 'Show' (a nil value) stack traceback: D:/OWM_Client3/Assets/CSharpLua/Lua/CompiledScripts/CSLua/GameMain.lua:43: in function 'Awake' D:/OWM_Client3/Assets/CSharpLua/Lua/UnityAdapter.lua:240: in function '__ctor__' D:/OWM_Client3/Assets/CSharpLua/Lua/CoreSystemLua/CoreSystem/Core.lua:48: in function <D:/OWM_Client3/Assets/CSharpLua/Lua/CoreSystemLua/CoreSystem/Core.lua:46> LuaInterface.LuaState:PCall(Int32, Int32) (at Assets/CSharpLua/BaseScripts/ToLua/Core/LuaState.cs:738) LuaInterface.LuaFunction:PCall() (at Assets/CSharpLua/BaseScripts/ToLua/Core/LuaFunction.cs:96) LuaInterface.LuaFunction:Call(GameObject, String) (at Assets/CSharpLua/BaseScripts/ToLua/Core/LuaFunction.cs:137) CSharpLua.CSharpLuaClient:StartMain() (at Assets/CSharpLua/BaseScripts/CSharpLua/CSharpLuaClient.cs:97) LuaClient:OnLoadFinished() (at Assets/CSharpLua/BaseScripts/ToLua/Misc/LuaClient.cs:183) LuaClient:LoadLuaFiles() (at Assets/CSharpLua/BaseScripts/ToLua/Misc/LuaClient.cs:54) LuaClient:Init() (at Assets/CSharpLua/BaseScripts/ToLua/Misc/LuaClient.cs:166) LuaClient:Awake() (at Assets/CSharpLua/BaseScripts/ToLua/Misc/LuaClient.cs:172)
C#中这样写:
var iOSGen = UnityEngine.iOS.Device.generation;
编译成lua,是这样:
local iOSGen = UnityEngine.UnityEngine.iOS.Device.getgeneration()
编译后多了一层UnityEngine的命名空间。
如果改成
C#中这样写:
using UnityEngine.iOS;
var iOSGen = Device.generation;
编译成lua,是这样:
local iOSGen = UnityEngineiOS.Device.getgeneration()
Hey, I wrote a Cake addin for CSharp.Lua to allow building projects with it. One of the modifications I had to make to allow this though was rebuilding the project with .NET Standard 2.0 instead of as a .net core application. Would it be possible to split the actual compiler off into a library and have the console application separate? I could probably submit a PR for this if needed, but I wanted to know if I was the only one who needed that.
Btw, if anyone wants access to it, I have an example project using my Cake module here: https://git.nofla.me/cgit/rtech/cake-csharp.lua-example (I don't use Github anymore for my personal projects)
Could you use csproj data instead of "input directory" and references list?
LuaSyntaxNodeTransfor.Object:50 when processing new Action<dynamic>
argument.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NativeApi;
public class Program
{
public static void Main()
{
var script = G.Get("script");
script.on_init(new Action<dynamic>(EventHandler));
}
static void EventHandler(dynamic eve)
{
}
}
namespace NativeApi
{
public class G
{
public static dynamic Get(dynamic n)
{
throw new NotImplementedException();
}
public static dynamic Set(dynamic n, dynamic v)
{
throw new NotImplementedException();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<meta>
<assembly>
<namespace name="NativeApi">
<class name="G" Name="_G">
<method name="Get" ArgCount="1" Template="_G[{0}]" />
<method name="Set" ArgCount="2" Template="_G[{0}] = {1}" />
</class>
</namespace>
</assembly>
</meta>
public enum SIDE_TYPE {
Self = 0,
Partner = 1,
Self_Team = 2,
Enemy_Team = 3,
All = 4
}
When the redundant class qualifier is used to access a static property, the converter thinks it has to find the property somewhere else.
Example
using System;
namespace TestApp
{
class Program
{
public static string Test { get; set; }
static void Main(string[] args)
{
Console.WriteLine(Program.Test);
Console.WriteLine(Test);
}
}
}
Converts to:
-- Generated by CSharp.lua Compiler 1.1.0
local System = System
local TestApp
System.usingDeclare(function (global)
TestApp = global.TestApp
end)
System.namespace("TestApp", function (namespace)
namespace.class("Program", function (namespace)
local Main
Main = function (args)
System.Console.WriteLine(Test) -- note the converter tries to access something that doesn't exists in this context
System.Console.WriteLine(TestApp.Program.Test)
end
return {
Main = Main
}
end)
end)
Command I executed: >dotnet "CSharp.lua.Launcher.dll" -s "C:\Users\Joas\source\repos\TestApp\TestApp" -d "C:\Users\Joas\Desktop\Test"
Version: 1.1.3
I've tried debugging the issue, but I find it a lot of work since there's no technical documentation in the solution.
SIDE NOTE: Please consider at least adding ///<summary>
's for classes properties and methods.
如果我想包含UnityEngine.dll,用这个里面的结构怎么把c# To lua。
Error exception: The type of namespace name 'UnityEngine' could not be found <are you missing a using directive or assembly reference ?>
尝试把UnityEngine.dll import到了CSharp.lua的sln里面,然并卵。求解?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.