diff --git a/src/WattleScript.Interpreter/CoreLib/PrototypeModule.cs b/src/WattleScript.Interpreter/CoreLib/PrototypeModule.cs index 9f4d6072..2138ac38 100644 --- a/src/WattleScript.Interpreter/CoreLib/PrototypeModule.cs +++ b/src/WattleScript.Interpreter/CoreLib/PrototypeModule.cs @@ -7,9 +7,9 @@ namespace WattleScript.Interpreter.CoreLib [WattleScriptModule(Namespace = "prototype")] public class PrototypeModule { - private const string NUMBER_PROTOTABLE = "681bf104-NUMBER-PROTO"; - private const string BOOLEAN_PROTOTABLE = "77813cb0-BOOLEAN-PROTO"; - private const string RANGE_PROTOTABLE = "88c45cc7-RANGE-PROTO"; + internal const string NUMBER_PROTOTABLE = "681bf104-NUMBER-PROTO"; + internal const string BOOLEAN_PROTOTABLE = "77813cb0-BOOLEAN-PROTO"; + internal const string RANGE_PROTOTABLE = "88c45cc7-RANGE-PROTO"; public static void WattleScriptInit(Table globalTable, Table proto) { @@ -30,8 +30,10 @@ public static void EnablePrototypes(Table globalTable) void Register(string prototableIdent, DataType protoType) { //register - var tab = new Table(sc); - var funcs = new Table(sc); + Table tab = new Table(sc); + DynValue mFuncs = sc.Registry.Get(prototableIdent); + Table funcs = mFuncs.IsNil() ? new Table(sc) : mFuncs.Table; + tab.Set("__index", DynValue.NewTable(funcs)); sc.SetTypeMetatable(protoType, tab); sc.Registry.Set(prototableIdent, DynValue.NewTable(funcs)); diff --git a/src/WattleScript.Interpreter/CoreLib/RangesModule.cs b/src/WattleScript.Interpreter/CoreLib/RangesModule.cs new file mode 100644 index 00000000..a26d5ea4 --- /dev/null +++ b/src/WattleScript.Interpreter/CoreLib/RangesModule.cs @@ -0,0 +1,106 @@ +using System; + +namespace WattleScript.Interpreter.CoreLib +{ + /// + /// Class implementing string Wattle & Lua functions + /// + [WattleScriptModule(Namespace = "range")] + public class RangesModule + { + public static void WattleScriptInit(Table globalTable, Table rangesTable) + { + globalTable.OwnerScript.Registry.Set(PrototypeModule.RANGE_PROTOTABLE, DynValue.NewTable(rangesTable)); + + Table stringMetatable = new Table(globalTable.OwnerScript); + stringMetatable.Set("__index", DynValue.NewTable(rangesTable)); + globalTable.OwnerScript.SetTypeMetatable(DataType.Range, stringMetatable); + } + + [WattleScriptModuleMethod] + public static DynValue totable(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + Table table = new Table(executionContext.OwnerScript); + + if (range.From < range.To) + { + for (int i = range.From; i <= range.To; i++) + { + table.Append(DynValue.NewNumber(i)); + } + } + else if (range.From > range.To) + { + for (int i = range.To; i >= range.From; i--) + { + table.Append(DynValue.NewNumber(i)); + } + } + + return DynValue.NewTable(table); + } + + [WattleScriptModuleMethod] + public static DynValue sort(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + if (range.From > range.To) + { + (range.To, range.From) = (range.From, range.To); + } + + return rangeDv; + } + + [WattleScriptModuleMethod] + public static DynValue sum(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + return DynValue.NewNumber(range.From + range.To); + } + + [WattleScriptModuleMethod] + public static DynValue swap(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + (range.To, range.From) = (range.From, range.To); + + return rangeDv; + } + + [WattleScriptModuleMethod] + public static DynValue issorted(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + return DynValue.NewBoolean(range.From <= range.To); + } + + [WattleScriptModuleMethod] + public static DynValue max(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + return DynValue.NewNumber(Math.Max(range.From, range.To)); + } + + [WattleScriptModuleMethod] + public static DynValue min(ScriptExecutionContext executionContext, CallbackArguments args) + { + DynValue rangeDv = args.AsType(0, "table", DataType.Range); + Range range = rangeDv.Range; + + return DynValue.NewNumber(Math.Min(range.From, range.To)); + } + } +} \ No newline at end of file diff --git a/src/WattleScript.Interpreter/DataTypes/DynValue.cs b/src/WattleScript.Interpreter/DataTypes/DynValue.cs index e95e7799..1a48d634 100644 --- a/src/WattleScript.Interpreter/DataTypes/DynValue.cs +++ b/src/WattleScript.Interpreter/DataTypes/DynValue.cs @@ -459,11 +459,17 @@ public string ToPrintString() string typeString = this.Type.ToLuaTypeString(); - if (m_Object is UserData ud) + switch (m_Object) { - string str = ud.Descriptor.AsString(ud.Object); - if (str != null) - return str; + case UserData ud: + { + string str = ud.Descriptor.AsString(ud.Object); + if (str != null) + return str; + break; + } + case Range range: + return $"{range.From}..{range.To}"; } return refid.FormatTypeString(typeString); diff --git a/src/WattleScript.Interpreter/Modules/CoreModules.cs b/src/WattleScript.Interpreter/Modules/CoreModules.cs index a75931ff..b29fdec4 100755 --- a/src/WattleScript.Interpreter/Modules/CoreModules.cs +++ b/src/WattleScript.Interpreter/Modules/CoreModules.cs @@ -89,6 +89,10 @@ public enum CoreModules /// Prototype table for changing types. PrototypeMethods must also be set. /// PrototypeTable = 0x40000, + /// + /// The "ranges" package (introduced by WattleScript). + /// + Ranges = 0x80000, /// /// A sort of "hard" sandbox preset, including string, math, table, bit32 packages, constants and table iterators. @@ -105,17 +109,21 @@ public enum CoreModules /// /// A softer sandbox preset + prototypes, adding metatables support, error handling, coroutine, time functions, json parsing and dynamic evaluations. /// - Preset_SoftSandboxWattle = Preset_SoftSandbox | PrototypeMethods | PrototypeTable, + Preset_SoftSandboxWattle = Preset_SoftSandbox | PrototypeMethods | PrototypeTable | Ranges, + /// + /// Shared base of and + /// + Preset_DefaultShared = LoadMethods | OS_System | IO, /// /// The default preset. Includes everything except "debug" as now. /// Beware that using this preset allows scripts unlimited access to the system. /// - Preset_Default = Preset_SoftSandbox | LoadMethods | OS_System | IO, + Preset_Default = Preset_SoftSandbox | Preset_DefaultShared, /// /// The default preset + prototypes. Includes everything except "debug" as now. /// Beware that using this preset allows scripts unlimited access to the system. /// - Preset_DefaultWattle = Preset_Default | PrototypeMethods | PrototypeTable, + Preset_DefaultWattle = Preset_SoftSandboxWattle | Preset_DefaultShared | PrototypeMethods | PrototypeTable, /// /// The complete package. /// Beware that using this preset allows scripts unlimited access to the system. diff --git a/src/WattleScript.Interpreter/Modules/ModuleRegister.cs b/src/WattleScript.Interpreter/Modules/ModuleRegister.cs index f1e2bc4d..ee251c54 100755 --- a/src/WattleScript.Interpreter/Modules/ModuleRegister.cs +++ b/src/WattleScript.Interpreter/Modules/ModuleRegister.cs @@ -40,6 +40,7 @@ public static Table RegisterCoreModules(this Table table, CoreModules modules) if (modules.Has(CoreModules.IO)) RegisterModuleType(table); if (modules.Has(CoreModules.Debug)) RegisterModuleType(table); if (modules.Has(CoreModules.Json)) RegisterModuleType(table); + if (modules.Has(CoreModules.Ranges)) RegisterModuleType(table); if (modules.Has(CoreModules.PrototypeMethods)) { PrototypeModule.EnablePrototypes(table); if (modules.Has(CoreModules.PrototypeTable)) @@ -47,6 +48,7 @@ public static Table RegisterCoreModules(this Table table, CoreModules modules) RegisterModuleType(table); } } + return table; } diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.lua new file mode 100644 index 00000000..a3745020 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.lua @@ -0,0 +1,3 @@ +tbl = range.totable(1>..5) +print(tbl[0]); +print(tbl[1]); \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.txt new file mode 100644 index 00000000..1234e84b --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/1-table.txt @@ -0,0 +1,2 @@ +2 +3 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.lua new file mode 100644 index 00000000..230daeeb --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.lua @@ -0,0 +1,2 @@ +x = 2>..<5 +print(x.totable()[1]) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.txt new file mode 100644 index 00000000..bf0d87ab --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/2-table-proto.txt @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.lua new file mode 100644 index 00000000..f7441400 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.lua @@ -0,0 +1,6 @@ +a = 10 +b = 2 + +x = (a..b).sort() +print(x.from) +print(x.to) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.txt new file mode 100644 index 00000000..97cba313 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/3-sort.txt @@ -0,0 +1,2 @@ +2 +10 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.lua new file mode 100644 index 00000000..694fbc19 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.lua @@ -0,0 +1,3 @@ +x = (10..2).sort() +print(x.from) +print(x.to) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.txt new file mode 100644 index 00000000..97cba313 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/4-arit.txt @@ -0,0 +1,2 @@ +2 +10 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.lua new file mode 100644 index 00000000..d777c307 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.lua @@ -0,0 +1,3 @@ +x = (4..8).swap() +print(x.from) +print(x.to) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.txt new file mode 100644 index 00000000..cbe2e875 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/5-swap.txt @@ -0,0 +1,2 @@ +8 +4 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.lua new file mode 100644 index 00000000..e13aff72 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.lua @@ -0,0 +1,2 @@ +x = (10..20).sum() +print(x) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.txt new file mode 100644 index 00000000..8580e7b6 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/6-sum.txt @@ -0,0 +1 @@ +30 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.lua new file mode 100644 index 00000000..2f8c3eb8 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.lua @@ -0,0 +1,6 @@ +x = (10..20).issorted() +y = (2..1).issorted() +z = (1..1).issorted() +print(x) +print(y) +print(z) \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.txt new file mode 100644 index 00000000..5879b866 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/7-issorted.txt @@ -0,0 +1,3 @@ +true +false +true \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.lua new file mode 100644 index 00000000..60b5120e --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.lua @@ -0,0 +1,2 @@ +x = (4..2).max() +print(x) diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.txt new file mode 100644 index 00000000..bf0d87ab --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/8-max.txt @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.lua b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.lua new file mode 100644 index 00000000..b683ecc1 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.lua @@ -0,0 +1,2 @@ +x = (4..2).min() +print(x) diff --git a/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.txt b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.txt new file mode 100644 index 00000000..d8263ee9 --- /dev/null +++ b/src/WattleScript.Tests/EndToEnd/CLike/SyntaxCLike/Ranges/StdModule/9-min.txt @@ -0,0 +1 @@ +2 \ No newline at end of file