基于AScript的Lua脚本语言发布啦
AScript是一个开源的C#动态脚本解析执行引擎,支持扩展多种脚本语言,2026年8月12日正式发布了lua脚本语言AScript.Lang.Lua,快来试试吧!
一、介绍
支持 Lua 基础语法和数据类型,以及表、元表、面向对象、模块等功能。
二、安装
1 install-package AScript 2 install-package AScript.Lang.Lua
三、使用说明
- 命名空间:using AScript.Lang.Lua;
- 常用数据类型:
nil: 空值boolean: 布尔值 (true,false)number: 数值 (整数和浮点数)string: 字符串table: 表 (数组)- 运算符
- 算术运算符:
+,-,*,/,%,^(幂),//(整数除法) - 关系运算符:
<,>,<=,>=,==,~= - 逻辑运算符:
and,or,not - 连接运算符:
..(字符串连接),#(长度) - 赋值运算符:
=,+=,-=,*=,/=,%=,^=,..= - 控制结构
- 条件语句:
if ... then ... elseif ... then ... else ... end - while循环:
while ... do ... end - repeat循环:
repeat ... until ... - 数值for循环:
for i = start, end, step do ... end - 泛型for循环:
for v in expr do ... end - 泛型for循环:
for i,v in expr do ... end - 函数定义:
function name(args) ... end - 匿名函数:
local f = function(args) ... end - 局部变量:
local var = value - 表构造器
- 数组风格:
{ value1, value2, value3 } - 字典风格:
{ key1 = value1, key2 = value2 } - 混合风格:
{ 1, 2, name = "test" }
1、注册语言
1 Script.Langs.Set("lua", LuaLang.Instance); 2 // 可全局设置为默认语言 3 // Script.Langs.Set("lua", LuaLang.Instance, setDefault: true);
2、字符串连接
两个字符串连接使用..操作符而不是+操作符。
1 var script = new Script(); 2 script.Context.Langs = new[] { "lua" }; 3 Assert.AreEqual("hello123", script.Eval("'hello'..123"));
3、数据打包/解包
1 // 打包 2 string s = @" 3 local format='<i4i4fc10' 4 local hp=12500 5 local mp=8700 6 local atk=156.5 7 local name='john' 8 local data = string.pack(format, hp, mp, atk, name) 9 print(#data) -- 控制台输出data长度 10 "; 11 var script = new Script(); 12 script.Context.Langs = new[] { "lua" }; 13 script.Eval(s); 14 // 解包 15 script.Eval("local a,b,c,d=string.unpack(format, data)"); 16 Assert.AreEqual(12500, script.Eval("a")); 17 Assert.AreEqual(8700, script.Eval("b")); 18 Assert.AreEqual(156.5, script.Eval("c")); 19 Assert.AreEqual("john", script.Eval("d"));
4、条件语句
1 string code = @" 2 local x = 10 3 if x >= 10 and x < 50 then 4 local a = 5 5 local b = 15 6 x = a + b + 80 7 elseif x >= 50 and x < 100 then 8 x = 200 9 else 10 x = 300 11 end 12 x 13 "; 14 var script = new Script(); 15 script.Context.Langs = new[] { "lua" }; 16 Assert.AreEqual(100L, script.Eval(code));
5、while循环
1 string code = @" 2 local i = 0 3 local sum = 0 4 while i < 5 do 5 i = i + 1 6 sum = sum + i 7 end 8 sum 9 "; 10 var script = new Script(); 11 script.Context.Langs = new[] { "lua" }; 12 Assert.AreEqual(15L, script.Eval(code));
6、数值for循环
- 语法:
for i=start,end[,step] do ... end,其中step默认为1 - 注:循环体内部改变循环变量i的值,不影响循环次数
1 string code = @" 2 local sum = 0 3 for i = 1, 5 do 4 i = i + 10 5 sum = sum + i 6 end 7 sum 8 "; 9 var script = new Script(); 10 script.Context.Langs = new[] { "lua" }; 11 Assert.AreEqual(65L, script.Eval(code));
7、泛型for循环
1 string code = @" 2 local sum = 0 3 -- for v in ipairs({1, 2, 3, 4, 5}) do 4 for i, v in ipairs({1, 2, 3, 4, 5}) do 5 sum = sum + v 6 end 7 sum 8 "; 9 var script = new Script(); 10 script.Context.Langs = new[] { "lua" }; 11 Assert.AreEqual(15L, script.Eval(code));
8、函数
1 string code = @" 2 function factorial(n) 3 if n <= 1 then 4 return 1 5 end 6 return n * factorial(n - 1) 7 end 8 factorial(5) 9 "; 10 var script = new Script(); 11 script.Context.Langs = new[] { "lua" }; 12 Assert.AreEqual(120L, script.Eval(code));
9、表(数组)
1 string code = @" 2 local arr = {10, 20, 30} 3 arr[1] + arr[2] + arr[3] 4 "; 5 var script = new Script(); 6 script.Context.Langs = new[] { "lua" }; 7 Assert.AreEqual(60L, script.Eval(code));
10、表(字典)
1 string code = @" 2 local t = { x = 3, y = 5 } 3 t.sum = function(a,b) 4 print(a,b) 5 return a+b 6 end 7 t.sum(t.x,t.y) 8 "; 9 var script = new Script(); 10 script.Context.Langs = new[] { "lua" }; 11 Assert.AreEqual(8L, script.Eval(code));
11、元表
1 string code = @" 2 local t = {} 3 local metatable = { __index = { name = 'tom' } } 4 setmetatable(t, metatable) 5 t.name 6 "; 7 var script = new Script(); 8 script.Context.Langs = new[] { "lua" }; 9 Assert.AreEqual("tom", script.Eval(code));
12、面向对象(OOP)
1 string code = @" 2 -- 定义动物类(Animal) 3 Animal = {name = 'Unknown'} 4 5 -- Animal 类的构造函数 6 function Animal:new(name) 7 local o = {} 8 setmetatable(o, self) -- 设置元表,使其继承 Animal 的方法 9 self.__index = self -- 让对象可以访问 Animal 的方法 10 o.name = name or 'Unknown' -- 设置名称,默认为 'Unknown' 11 return o 12 end 13 14 -- Animal 类的方法:叫声 15 function Animal:speak() 16 return self.name .. ' makes a sound.' 17 end 18 19 -- 定义狗类(Dog),继承自 Animal 20 Dog = Animal:new() -- Dog 继承 Animal 类 21 22 -- 重写狗类的构造函数 23 function Dog:new(name, breed) 24 local o = {} 25 setmetatable(o, self) -- 设置元表,使其继承 Dog 和 Animal 的方法 26 self.__index = self -- 让对象可以访问 Dog 的方法 27 o.name = name or 'Unknown' 28 o.breed = breed or 'Unknown' 29 return o 30 end 31 32 -- 重写狗类的叫声方法(重写 Animal 的 speak 方法) 33 function Dog:speak() 34 return self.name .. ' barks.' 35 end 36 37 -- 创建 Animal 对象 38 local animal = Animal:new('Generic Animal') 39 local s1 = animal:speak() -- 输出 'Generic Animal makes a sound.' 40 41 -- 创建 Dog 对象 42 local dog = Dog:new('Buddy', 'Golden Retriever') 43 local s2 = dog:speak() -- 输出 'Buddy barks.' 44 s1 .. ';' .. s2 45 "; 46 var script = new Script(); 47 script.Context.Langs = new[] { "lua" }; 48 Assert.AreEqual("Generic Animal makes a sound.;Buddy barks.", script.Eval(code));
13、模块
使用require引入模块,优先查找IScriptModule模块,再查找模块目录中的模块文件。
1)添加模块目录
1 LuaLang.Instance.Modules.AddDir("./lua/modules");
2)模块目录中添加Person.lua文件
1 Person = {name = '', age = 0} 2 3 function Person:new(name, age) 4 local obj = {} -- 创建一个新的表作为对象 5 setmetatable(obj, self) -- 设置元表,使其成为 Person 的实例 6 self.__index = self -- 设置索引元方法,指向 Person 7 obj.name = name 8 obj.age = age 9 return obj 10 end 11 12 function Person:introduce() 13 return 'My name is ' .. self.name .. ' and I am ' .. self.age .. ' years old.' 14 end 15 16 return Person
3)引入并使用模块
1 string code = @" 2 require 'Person' 3 local person1 = Person:new('Alice', 30) 4 person1:introduce() 5 "; 6 var script = new Script(); 7 script.Context.Langs = new[] { "lua" }; 8 Assert.AreEqual("My name is Alice and I am 30 years old.", script.Eval(code));
14、io模块
文件操作,服务端请谨慎使用,避免脚本恶意修改、删除文件。
1)安装模块
1 install-package AScript.Lang.Lua.io
2)注册io模块
1 LuaLang.Instance.Modules.Add("io", new AScript.Lang.Lua.io.LuaIOModule());
3)使用io
1 string code = @" 2 require 'io' 3 local f = io.open(file, 'w') 4 f:write('hello') 5 f:close() 6 local f = io.open(file, 'r') 7 local content = f:read() 8 f:close() 9 content 10 "; 11 var script = new Script(); 12 script.Context.Langs = new[] { "lua" }; 13 script.Context.SetVar("file", "./test.txt"); 14 Assert.AreEqual("hello", script.Eval(code));
四、与宿主程序交互
1、脚本调用C#函数
1 var code = @" 2 local a = 10 3 local b = 20 4 sum(a, b) 5 "; 6 var script = new Script(); 7 script.Context.Langs = new[] { "lua" }; 8 // 注入函数 9 script.Context.AddFunc<long, long, long>("sum", (x, y) => x + y); 10 Assert.AreEqual(30L, script.Eval(code));
2、C#调用脚本中的函数
1 var code = @" 2 function sum(x,y) 3 return x+y 4 end 5 local a = 10 6 local b = 20 7 sum(a, b) 8 "; 9 var script = new Script(); 10 script.Context.Langs = new[] { "lua" }; 11 Assert.AreEqual(30L, script.Eval(code)); 12 // 获取脚本中的函数 13 var sum = script.Context.GetFunc<long, long, long>("sum"); 14 Assert.AreEqual(80L, sum(30, 50));
五、结束语
更多语法、功能请参考Lua 教程 | 菜鸟教程。
AScript开源地址:https://gitee.com/rockey627/AScript

浙公网安备 33010602011771号