From 08fc70a984cf3aed52052926f2c86dad93c89275 Mon Sep 17 00:00:00 2001 From: Darren Horrocks Date: Sat, 12 Sep 2020 00:16:25 +0100 Subject: [PATCH] refactor and move around --- .gitignore | 8 + DScript.csproj | 76 -- DScript.sln | 25 + DScript/DScript.csproj | 18 + .../ConsoleFunctionProvider.cs | 104 +-- .../ConvertFunctionProvider.cs | 134 ++- .../EngineFunctionProvider.cs | 90 +- .../MathFunctionProvider.cs | 374 ++++----- .../FunctionProviders}/RNGFunctionProvider.cs | 90 +- .../ScriptClassAttribute.cs | 108 +-- DScript/ScriptEngine.Base.cs | 85 ++ .../ScriptEngine.Block.cs | 120 +-- DScript/ScriptEngine.Condition.cs | 63 ++ DScript/ScriptEngine.Expression.cs | 96 +++ DScript/ScriptEngine.Factor.cs | 285 +++++++ DScript/ScriptEngine.FunctionCall.cs | 136 +++ DScript/ScriptEngine.Logic.cs | 101 +++ DScript/ScriptEngine.Shift.cs | 65 ++ DScript/ScriptEngine.Statement.cs | 305 +++++++ .../ScriptEngine.Term.cs | 114 +-- DScript/ScriptEngine.Ternary.cs | 65 ++ .../ScriptEngine.Unary.cs | 114 +-- DScript/ScriptEngine.cs | 555 +++++++++++++ .../ScriptException.cs | 84 +- DScript/ScriptLex.cs | 567 +++++++++++++ DScript/ScriptVar.cs | 783 ++++++++++++++++++ DScript/ScriptVarLink.cs | 100 +++ DScript/Utils.cs | 119 +++ LICENSE | 2 +- NuGet/spec.nuspec | 24 +- Properties/AssemblyInfo.cs | 57 -- ScriptEngine.Base.cs | 84 -- ScriptEngine.Condition.cs | 63 -- ScriptEngine.Expression.cs | 96 --- ScriptEngine.Factor.cs | 285 ------- ScriptEngine.FunctionCall.cs | 143 ---- ScriptEngine.Logic.cs | 101 --- ScriptEngine.Shift.cs | 65 -- ScriptEngine.Statement.cs | 305 ------- ScriptEngine.Ternary.cs | 65 -- ScriptEngine.cs | 546 ------------ ScriptLex.cs | 567 ------------- ScriptVar.cs | 783 ------------------ ScriptVarLink.cs | 100 --- Utils.cs | 119 --- 45 files changed, 4054 insertions(+), 4135 deletions(-) create mode 100644 .gitignore delete mode 100644 DScript.csproj create mode 100644 DScript.sln create mode 100644 DScript/DScript.csproj rename {FunctionProviders => DScript/FunctionProviders}/ConsoleFunctionProvider.cs (78%) rename {FunctionProviders => DScript/FunctionProviders}/ConvertFunctionProvider.cs (62%) rename {FunctionProviders => DScript/FunctionProviders}/EngineFunctionProvider.cs (77%) rename {FunctionProviders => DScript/FunctionProviders}/MathFunctionProvider.cs (94%) rename {FunctionProviders => DScript/FunctionProviders}/RNGFunctionProvider.cs (83%) rename ScriptClassAttribute.cs => DScript/ScriptClassAttribute.cs (84%) create mode 100644 DScript/ScriptEngine.Base.cs rename ScriptEngine.Block.cs => DScript/ScriptEngine.Block.cs (50%) create mode 100644 DScript/ScriptEngine.Condition.cs create mode 100644 DScript/ScriptEngine.Expression.cs create mode 100644 DScript/ScriptEngine.Factor.cs create mode 100644 DScript/ScriptEngine.FunctionCall.cs create mode 100644 DScript/ScriptEngine.Logic.cs create mode 100644 DScript/ScriptEngine.Shift.cs create mode 100644 DScript/ScriptEngine.Statement.cs rename ScriptEngine.Term.cs => DScript/ScriptEngine.Term.cs (51%) create mode 100644 DScript/ScriptEngine.Ternary.cs rename ScriptEngine.Unary.cs => DScript/ScriptEngine.Unary.cs (52%) create mode 100644 DScript/ScriptEngine.cs rename ScriptException.cs => DScript/ScriptException.cs (80%) create mode 100644 DScript/ScriptLex.cs create mode 100644 DScript/ScriptVar.cs create mode 100644 DScript/ScriptVarLink.cs create mode 100644 DScript/Utils.cs delete mode 100644 Properties/AssemblyInfo.cs delete mode 100644 ScriptEngine.Base.cs delete mode 100644 ScriptEngine.Condition.cs delete mode 100644 ScriptEngine.Expression.cs delete mode 100644 ScriptEngine.Factor.cs delete mode 100644 ScriptEngine.FunctionCall.cs delete mode 100644 ScriptEngine.Logic.cs delete mode 100644 ScriptEngine.Shift.cs delete mode 100644 ScriptEngine.Statement.cs delete mode 100644 ScriptEngine.Ternary.cs delete mode 100644 ScriptEngine.cs delete mode 100644 ScriptLex.cs delete mode 100644 ScriptVar.cs delete mode 100644 ScriptVarLink.cs delete mode 100644 Utils.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79e01ce --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs +/obj +/bin +/DScript/obj diff --git a/DScript.csproj b/DScript.csproj deleted file mode 100644 index bdca82a..0000000 --- a/DScript.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - - - Debug - AnyCPU - {FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE} - Library - Properties - DScript - DScript - v4.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/DScript.sln b/DScript.sln new file mode 100644 index 0000000..1a6b70c --- /dev/null +++ b/DScript.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30330.147 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DScript", "DScript/DScript.csproj", "{FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC4BD1FC-B545-4EEA-AD76-A2ECE21EEDFE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2F9335D2-D60B-4F1D-926A-16CB06673EE6} + EndGlobalSection +EndGlobal diff --git a/DScript/DScript.csproj b/DScript/DScript.csproj new file mode 100644 index 0000000..2b0b2b6 --- /dev/null +++ b/DScript/DScript.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.1 + LICENSE + https://github.com/bizzehdee/DScript + https://github.com/bizzehdee/DScript + + + + + + True + + + + + diff --git a/FunctionProviders/ConsoleFunctionProvider.cs b/DScript/FunctionProviders/ConsoleFunctionProvider.cs similarity index 78% rename from FunctionProviders/ConsoleFunctionProvider.cs rename to DScript/FunctionProviders/ConsoleFunctionProvider.cs index a18947b..bdf5e03 100644 --- a/FunctionProviders/ConsoleFunctionProvider.cs +++ b/DScript/FunctionProviders/ConsoleFunctionProvider.cs @@ -1,52 +1,52 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript.FunctionProviders -{ - [ScriptClass("Console")] - public class ConsoleFunctionProvider - { - public void WriteLine(String text, object userData) - { - Console.WriteLine(text); - } - - public String ReadLine(object userData) - { - String retVal = Console.ReadLine(); - return retVal; - } - - public void Write(String text, object userData) - { - Console.Write(text); - } - - public Int32 ReadChar(object userData) - { - Int32 retVal = Console.Read(); - return retVal; - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript.FunctionProviders +{ + [ScriptClass("Console")] + public class ConsoleFunctionProvider + { + public void WriteLine(string text, object userData) + { + Console.WriteLine(text); + } + + public string ReadLine(object userData) + { + var retVal = Console.ReadLine(); + return retVal; + } + + public void Write(string text, object userData) + { + Console.Write(text); + } + + public int ReadChar(object userData) + { + int retVal = Console.Read(); + return retVal; + } + } +} diff --git a/FunctionProviders/ConvertFunctionProvider.cs b/DScript/FunctionProviders/ConvertFunctionProvider.cs similarity index 62% rename from FunctionProviders/ConvertFunctionProvider.cs rename to DScript/FunctionProviders/ConvertFunctionProvider.cs index 2c9ce35..170df59 100644 --- a/FunctionProviders/ConvertFunctionProvider.cs +++ b/DScript/FunctionProviders/ConvertFunctionProvider.cs @@ -1,68 +1,66 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript.FunctionProviders -{ - [ScriptClass("Convert")] - public class ConvertFunctionProvider - { - public static String IntToString(Int32 val, object userData) - { - return String.Format("{0}", val); - } - - public static double IntToFloat(Int32 val, object userData) - { - return val; - } - - public static String FloatToString(double val, object userData) - { - return String.Format("{0}", val); - } - - public static Int32 FloatToInt(double val, object userData) - { - return (Int32)val; - } - - public static double StringToFloat(String val, object userData) - { - double returnVal; - - double.TryParse(val, out returnVal); - - return returnVal; - } - - public static Int32 StringToInt(String val, object userData) - { - Int32 returnVal; - - Int32.TryParse(val, out returnVal); - - return returnVal; - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript.FunctionProviders +{ + [ScriptClass("Convert")] + public class ConvertFunctionProvider + { + public static String IntToString(int val, object userData) + { + return string.Format("{0}", val); + } + + public static double IntToFloat(int val, object userData) + { + return val; + } + + public static string FloatToString(double val, object userData) + { + return string.Format("{0}", val); + } + + public static int FloatToInt(double val, object userData) + { + return (int)val; + } + + public static double StringToFloat(string val, object userData) + { + + double.TryParse(val, out double returnVal); + + return returnVal; + } + + public static int StringToInt(string val, object userData) + { + + int.TryParse(val, out int returnVal); + + return returnVal; + } + } +} diff --git a/FunctionProviders/EngineFunctionProvider.cs b/DScript/FunctionProviders/EngineFunctionProvider.cs similarity index 77% rename from FunctionProviders/EngineFunctionProvider.cs rename to DScript/FunctionProviders/EngineFunctionProvider.cs index 5e81039..78492b2 100644 --- a/FunctionProviders/EngineFunctionProvider.cs +++ b/DScript/FunctionProviders/EngineFunctionProvider.cs @@ -1,45 +1,45 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript.FunctionProviders -{ - [ScriptClass] - public class EngineFunctionProvider - { - public static void Exec(String code, object userdata) - { - ScriptEngine engine = (ScriptEngine)userdata; - engine.Execute(code); - } - - public static String Eval(String code, object userdata) - { - ScriptEngine engine = (ScriptEngine)userdata; - - ScriptVarLink returnLink = engine.EvalComplex(code); - - return returnLink.Var.GetString(); - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript.FunctionProviders +{ + [ScriptClass] + public class EngineFunctionProvider + { + public static void Exec(string code, object userdata) + { + var engine = (ScriptEngine)userdata; + engine.Execute(code); + } + + public static string Eval(string code, object userdata) + { + var engine = (ScriptEngine)userdata; + + var returnLink = engine.EvalComplex(code); + + return returnLink.Var.GetString(); + } + } +} diff --git a/FunctionProviders/MathFunctionProvider.cs b/DScript/FunctionProviders/MathFunctionProvider.cs similarity index 94% rename from FunctionProviders/MathFunctionProvider.cs rename to DScript/FunctionProviders/MathFunctionProvider.cs index c756a42..28b163f 100644 --- a/FunctionProviders/MathFunctionProvider.cs +++ b/DScript/FunctionProviders/MathFunctionProvider.cs @@ -1,187 +1,187 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript.FunctionProviders -{ - [ScriptClass("Math", PropertiesAsObjects = true)] - public class MathFunctionProvider - { - public static double Pi - { - get { return Math.PI; } - } - - public static double E() - { - return Math.E; - } - - public static double Abs(double v, object userdata) - { - return Math.Abs(v); - } - - public static double Round(double val, int digits, object userdata) - { - return Math.Round(val, digits); - } - - public static double Ceil(double val, object userdata) - { - return Math.Ceiling(val); - } - - public static double Floor(double val, object userdata) - { - return Math.Floor(val); - } - - public static double Min(double a, double b, object userdata) - { - return Math.Min(a, b); - } - - public static double Max(double a, double b, object userdata) - { - return Math.Max(a, b); - } - - public static double Range(double a, double b, double x, object userdata) - { - return (x < a ? a : (x > b ? b : a)); - } - - public static double Sign(double val, object userdata) - { - return Math.Sign(val); - } - - public static double Sin(double val, object userdata) - { - return Math.Sin(val); - } - - public static double Cos(double val, object userdata) - { - return Math.Cos(val); - } - - public static double Tan(double val, object userdata) - { - return Math.Tan(val); - } - - public static double Sinh(double val, object userdata) - { - return Math.Sinh(val); - } - - public static double Cosh(double val, object userdata) - { - return Math.Cosh(val); - } - - public static double Tanh(double val, object userdata) - { - return Math.Tanh(val); - } - - public static double ASin(double val, object userdata) - { - return Math.Asin(val); - } - - public static double ACos(double val, object userdata) - { - return Math.Acos(val); - } - - public static double ATan(double val, object userdata) - { - return Math.Atan(val); - } - - public static double ASinh(double val, object userdata) - { - double returnVal; - - if (val > 0) - { - returnVal = Math.Log(val + Math.Sqrt(val * val + 1)); - } - else - { - returnVal = -Math.Log(-val + Math.Sqrt(val * val + 1)); - } - - return returnVal; - } - - public static double ACosh(double val, object userdata) - { - double returnVal; - - if (val > 0) - { - returnVal = Math.Log(val + Math.Sqrt(val * val - 1)); - } - else - { - returnVal = -Math.Log(-val + Math.Sqrt(val * val - 1)); - } - - return returnVal; - } - - public static double ATan2(double a, double b, object userdata) - { - return Math.Atan2(a, b); - } - - public static double Pow(double a, double b, object userdata) - { - return Math.Pow(a, b); - } - - public static double Sqrt(double val, object userdata) - { - return Math.Sqrt(val); - } - - public static double Log(double val, object userdata) - { - return Math.Log(val); - } - - public static double Log10(double val, object userdata) - { - return Math.Log10(val); - } - - public static double Exp(double val, object userdata) - { - return Math.Exp(val); - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript.FunctionProviders +{ + [ScriptClass("Math", PropertiesAsObjects = true)] + public class MathFunctionProvider + { + public static double Pi + { + get { return Math.PI; } + } + + public static double E() + { + return Math.E; + } + + public static double Abs(double v, object userdata) + { + return Math.Abs(v); + } + + public static double Round(double val, int digits, object userdata) + { + return Math.Round(val, digits); + } + + public static double Ceil(double val, object userdata) + { + return Math.Ceiling(val); + } + + public static double Floor(double val, object userdata) + { + return Math.Floor(val); + } + + public static double Min(double a, double b, object userdata) + { + return Math.Min(a, b); + } + + public static double Max(double a, double b, object userdata) + { + return Math.Max(a, b); + } + + public static double Range(double a, double b, double x, object userdata) + { + return (x < a ? a : (x > b ? b : a)); + } + + public static double Sign(double val, object userdata) + { + return Math.Sign(val); + } + + public static double Sin(double val, object userdata) + { + return Math.Sin(val); + } + + public static double Cos(double val, object userdata) + { + return Math.Cos(val); + } + + public static double Tan(double val, object userdata) + { + return Math.Tan(val); + } + + public static double Sinh(double val, object userdata) + { + return Math.Sinh(val); + } + + public static double Cosh(double val, object userdata) + { + return Math.Cosh(val); + } + + public static double Tanh(double val, object userdata) + { + return Math.Tanh(val); + } + + public static double ASin(double val, object userdata) + { + return Math.Asin(val); + } + + public static double ACos(double val, object userdata) + { + return Math.Acos(val); + } + + public static double ATan(double val, object userdata) + { + return Math.Atan(val); + } + + public static double ASinh(double val, object userdata) + { + double returnVal; + + if (val > 0) + { + returnVal = Math.Log(val + Math.Sqrt(val * val + 1)); + } + else + { + returnVal = -Math.Log(-val + Math.Sqrt(val * val + 1)); + } + + return returnVal; + } + + public static double ACosh(double val, object userdata) + { + double returnVal; + + if (val > 0) + { + returnVal = Math.Log(val + Math.Sqrt(val * val - 1)); + } + else + { + returnVal = -Math.Log(-val + Math.Sqrt(val * val - 1)); + } + + return returnVal; + } + + public static double ATan2(double a, double b, object userdata) + { + return Math.Atan2(a, b); + } + + public static double Pow(double a, double b, object userdata) + { + return Math.Pow(a, b); + } + + public static double Sqrt(double val, object userdata) + { + return Math.Sqrt(val); + } + + public static double Log(double val, object userdata) + { + return Math.Log(val); + } + + public static double Log10(double val, object userdata) + { + return Math.Log10(val); + } + + public static double Exp(double val, object userdata) + { + return Math.Exp(val); + } + } +} diff --git a/FunctionProviders/RNGFunctionProvider.cs b/DScript/FunctionProviders/RNGFunctionProvider.cs similarity index 83% rename from FunctionProviders/RNGFunctionProvider.cs rename to DScript/FunctionProviders/RNGFunctionProvider.cs index 9005a9b..2fd380d 100644 --- a/FunctionProviders/RNGFunctionProvider.cs +++ b/DScript/FunctionProviders/RNGFunctionProvider.cs @@ -1,45 +1,45 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript.FunctionProviders -{ - [ScriptClass("Random")] - public class RNGFunctionProvider - { - public static Int32 Next(object userdata) - { - return (new Random()).Next(); - } - - public static Int32 NextMax(Int32 max, object userdata) - { - return (new Random()).Next(max); - } - - public static Int32 NextMinMax(Int32 min, Int32 max, object userdata) - { - return (new Random()).Next(min, max); - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript.FunctionProviders +{ + [ScriptClass("Random")] + public class RNGFunctionProvider + { + public static int Next(object userdata) + { + return (new Random()).Next(); + } + + public static int NextMax(Int32 max, object userdata) + { + return (new Random()).Next(max); + } + + public static int NextMinMax(Int32 min, Int32 max, object userdata) + { + return (new Random()).Next(min, max); + } + } +} diff --git a/ScriptClassAttribute.cs b/DScript/ScriptClassAttribute.cs similarity index 84% rename from ScriptClassAttribute.cs rename to DScript/ScriptClassAttribute.cs index b2884f4..c1bae55 100644 --- a/ScriptClassAttribute.cs +++ b/DScript/ScriptClassAttribute.cs @@ -1,54 +1,54 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - //Not currently used - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] - public class ScriptClassAttribute : Attribute - { - public String[] Namespace { get; set; } - public String ClassName { get; set; } - public bool PropertiesAsObjects { get; set; } - public bool IsObject { get; set; } - - public ScriptClassAttribute() - { - ClassName = null; - Namespace = null; - } - - public ScriptClassAttribute(String name) - { - ClassName = name; - Namespace = null; - } - - public ScriptClassAttribute(String name, String[] ns) - { - ClassName = name; - Namespace = ns; - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + //Not currently used + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public class ScriptClassAttribute : Attribute + { + public string[] Namespace { get; set; } + public string ClassName { get; set; } + public bool PropertiesAsObjects { get; set; } + public bool IsObject { get; set; } + + public ScriptClassAttribute() + { + ClassName = null; + Namespace = null; + } + + public ScriptClassAttribute(string name) + { + ClassName = name; + Namespace = null; + } + + public ScriptClassAttribute(string name, string[] ns) + { + ClassName = name; + Namespace = ns; + } + } +} diff --git a/DScript/ScriptEngine.Base.cs b/DScript/ScriptEngine.Base.cs new file mode 100644 index 0000000..9f37300 --- /dev/null +++ b/DScript/ScriptEngine.Base.cs @@ -0,0 +1,85 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Base(ref bool execute) + { + ScriptVarLink a = Ternary(ref execute); + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'=' || + currentLexer.TokenType == ScriptLex.LexTypes.PlusEqual || + currentLexer.TokenType == ScriptLex.LexTypes.MinusEqual) + { + if (execute && a.Owned) + { + if (a.Name.Length > 0) + { + var aReal = Root.AddChildNoDup(a.Name, a.Var); + a = aReal; + } + else + { + //?wtf? + System.Diagnostics.Trace.TraceWarning("Trying to assign to an unnamed type..."); + } + } + + var op = currentLexer.TokenType; + currentLexer.Match(op); + + var b = Base(ref execute); + + if (execute) + { + switch (op) + { + case (ScriptLex.LexTypes)'=': + { + a.ReplaceWith(b); + } + break; + case ScriptLex.LexTypes.PlusEqual: + { + var res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes)'+'); + a.ReplaceWith(res); + } + break; + case ScriptLex.LexTypes.MinusEqual: + { + var res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes)'-'); + a.ReplaceWith(res); + } + break; + default: + throw new ScriptException("Base broke"); + } + } + + } + + return a; + } + } +} diff --git a/ScriptEngine.Block.cs b/DScript/ScriptEngine.Block.cs similarity index 50% rename from ScriptEngine.Block.cs rename to DScript/ScriptEngine.Block.cs index 2a41f7e..5f39478 100644 --- a/ScriptEngine.Block.cs +++ b/DScript/ScriptEngine.Block.cs @@ -1,60 +1,60 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public partial class ScriptEngine - { - private void Block(ref bool execute) - { - _currentLexer.Match((ScriptLex.LexTypes)'{'); - if (execute) - { - while (_currentLexer.TokenType != 0 && _currentLexer.TokenType != (ScriptLex.LexTypes)'}') - { - Statement(ref execute); - } - - _currentLexer.Match((ScriptLex.LexTypes)'}'); - } - else - { - Int32 brackets = 1; - while (_currentLexer.TokenType != 0 && brackets > 0) - { - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'{') - { - brackets++; - } - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'}') - { - brackets--; - } - - _currentLexer.Match(_currentLexer.TokenType); - } - } - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public partial class ScriptEngine + { + private void Block(ref bool execute) + { + currentLexer.Match((ScriptLex.LexTypes)'{'); + if (execute) + { + while (currentLexer.TokenType != 0 && currentLexer.TokenType != (ScriptLex.LexTypes)'}') + { + Statement(ref execute); + } + + currentLexer.Match((ScriptLex.LexTypes)'}'); + } + else + { + int brackets = 1; + while (currentLexer.TokenType != 0 && brackets > 0) + { + if (currentLexer.TokenType == (ScriptLex.LexTypes)'{') + { + brackets++; + } + if (currentLexer.TokenType == (ScriptLex.LexTypes)'}') + { + brackets--; + } + + currentLexer.Match(currentLexer.TokenType); + } + } + } + } +} diff --git a/DScript/ScriptEngine.Condition.cs b/DScript/ScriptEngine.Condition.cs new file mode 100644 index 0000000..cedbee0 --- /dev/null +++ b/DScript/ScriptEngine.Condition.cs @@ -0,0 +1,63 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Condition(ref bool execute) + { + var a = Shift(ref execute); + + while (currentLexer.TokenType == ScriptLex.LexTypes.Equal || + currentLexer.TokenType == ScriptLex.LexTypes.NEqual || + currentLexer.TokenType == ScriptLex.LexTypes.TypeEqual || + currentLexer.TokenType == ScriptLex.LexTypes.NTypeEqual || + currentLexer.TokenType == ScriptLex.LexTypes.LEqual || + currentLexer.TokenType == ScriptLex.LexTypes.GEqual || + currentLexer.TokenType == (ScriptLex.LexTypes)'>' || + currentLexer.TokenType == (ScriptLex.LexTypes)'<' + ) + { + var op = currentLexer.TokenType; + currentLexer.Match(op); + var b = Shift(ref execute); + + if (execute) + { + var res = a.Var.MathsOp(b.Var, op); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + } + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.Expression.cs b/DScript/ScriptEngine.Expression.cs new file mode 100644 index 0000000..7d5e675 --- /dev/null +++ b/DScript/ScriptEngine.Expression.cs @@ -0,0 +1,96 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Expression(ref bool execute) + { + var negate = false; + if (currentLexer.TokenType == (ScriptLex.LexTypes)'-') + { + currentLexer.Match((ScriptLex.LexTypes)'-'); + negate = true; + } + + var a = Term(ref execute); + + if (negate) + { + var zero = new ScriptVar(0); + var res = zero.MathsOp(a.Var, (ScriptLex.LexTypes)'-'); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + } + + while (currentLexer.TokenType == (ScriptLex.LexTypes)'+' || + currentLexer.TokenType == (ScriptLex.LexTypes)'-' || + currentLexer.TokenType == ScriptLex.LexTypes.PlusPlus || + currentLexer.TokenType == ScriptLex.LexTypes.MinusMinus) + { + var op = currentLexer.TokenType; + currentLexer.Match(op); + + if (op == ScriptLex.LexTypes.PlusPlus || op == ScriptLex.LexTypes.MinusMinus) + { + if (execute) + { + var one = new ScriptVar(1); + var res = a.Var.MathsOp(one, (ScriptLex.LexTypes)(op == ScriptLex.LexTypes.PlusPlus ? '+' : '-')); + var oldVal = new ScriptVarLink(a.Var, null); + + a.ReplaceWith(res); + a = oldVal; + } + } + else + { + ScriptVarLink b = Term(ref execute); + if (execute) + { + var res = a.Var.MathsOp(b.Var, op); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + + } + } + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.Factor.cs b/DScript/ScriptEngine.Factor.cs new file mode 100644 index 0000000..306ae4f --- /dev/null +++ b/DScript/ScriptEngine.Factor.cs @@ -0,0 +1,285 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Factor(ref bool execute) + { + if (currentLexer.TokenType == (ScriptLex.LexTypes)'(') + { + currentLexer.Match((ScriptLex.LexTypes)'('); + var a = Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)')'); + return a; + } + if (currentLexer.TokenType == ScriptLex.LexTypes.RTrue) + { + currentLexer.Match(ScriptLex.LexTypes.RTrue); + return new ScriptVarLink(new ScriptVar(1), null); + } + if (currentLexer.TokenType == ScriptLex.LexTypes.RFalse) + { + currentLexer.Match(ScriptLex.LexTypes.RTrue); + return new ScriptVarLink(new ScriptVar(0), null); + } + if (currentLexer.TokenType == ScriptLex.LexTypes.RNull) + { + currentLexer.Match(ScriptLex.LexTypes.RUndefined); + return new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Null), null); + } + if (currentLexer.TokenType == ScriptLex.LexTypes.RUndefined) + { + currentLexer.Match(ScriptLex.LexTypes.RUndefined); + return new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Undefined), null); + } + if (currentLexer.TokenType == ScriptLex.LexTypes.Id) + { + var a = execute ? FindInScopes(currentLexer.TokenString) : new ScriptVarLink(new ScriptVar(), null); + + ScriptVar parent = null; + + if (execute && a == null) + { + a = new ScriptVarLink(new ScriptVar(), currentLexer.TokenString); + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + + while (currentLexer.TokenType == (ScriptLex.LexTypes)'(' || currentLexer.TokenType == (ScriptLex.LexTypes)'.' || currentLexer.TokenType == (ScriptLex.LexTypes)'[') + { + if (currentLexer.TokenType == (ScriptLex.LexTypes)'(') // function call + { + a = FunctionCall(ref execute, a, parent); + } + else if (currentLexer.TokenType == (ScriptLex.LexTypes)'.') // child access + { + currentLexer.Match((ScriptLex.LexTypes)'.'); + if (execute) + { + if (!a.Var.IsObject) + { + throw new ScriptException("Trying to call object member on non object type"); + } + + var name = currentLexer.TokenString; + var child = a.Var.FindChild(name); + + if (child == null) + { + child = FindInParentClasses(a.Var, name); + } + + if (child == null) + { + if (a.Var.IsArray && name == "length") + { + var length = a.Var.GetArrayLength(); + child = new ScriptVarLink(new ScriptVar(length), null); + } + else if (a.Var.IsString && name == "length") + { + var length = a.Var.GetString().Length; + child = new ScriptVarLink(new ScriptVar(length), null); + } + else + { + child = a.Var.AddChild(name, null); + } + } + + parent = a.Var; + a = child; + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + } + else if (currentLexer.TokenType == (ScriptLex.LexTypes)'[') // array access + { + currentLexer.Match((ScriptLex.LexTypes)'['); + var index = Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)']'); + + if (execute) + { + ScriptVarLink child = a.Var.FindChildOrCreate(index.Var.GetString()); + parent = a.Var; + a = child; + } + } + else + { + throw new ScriptException("WTF?"); + } + } + + return a; + } + + if (currentLexer.TokenType == ScriptLex.LexTypes.Int || currentLexer.TokenType == ScriptLex.LexTypes.Float) + { + var a = new ScriptVar(currentLexer.TokenString, currentLexer.TokenType == ScriptLex.LexTypes.Int ? ScriptVar.Flags.Integer : ScriptVar.Flags.Double); + currentLexer.Match(currentLexer.TokenType); + return new ScriptVarLink(a, null); + } + + if (currentLexer.TokenType == ScriptLex.LexTypes.Str) + { + var a = new ScriptVar(currentLexer.TokenString, ScriptVar.Flags.String); + currentLexer.Match(currentLexer.TokenType); + return new ScriptVarLink(a, null); + } + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'{') + { + var contents = new ScriptVar(null, ScriptVar.Flags.Object); + //looking for JSON like objects + currentLexer.Match((ScriptLex.LexTypes)'{'); + while (currentLexer.TokenType != (ScriptLex.LexTypes)'}') + { + var id = currentLexer.TokenString; + + if (currentLexer.TokenType == ScriptLex.LexTypes.Str) + { + currentLexer.Match(ScriptLex.LexTypes.Str); + } + else + { + currentLexer.Match(ScriptLex.LexTypes.Id); + } + + currentLexer.Match((ScriptLex.LexTypes)':'); + + if (execute) + { + ScriptVarLink a = Base(ref execute); + contents.AddChild(id, a.Var); + } + + if (currentLexer.TokenType != (ScriptLex.LexTypes)'}') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + } + currentLexer.Match((ScriptLex.LexTypes)'}'); + + return new ScriptVarLink(contents, null); + } + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'[') + { + int idx = 0; + var contents = new ScriptVar(null, ScriptVar.Flags.Array); + //looking for JSON like arrays + currentLexer.Match((ScriptLex.LexTypes)'['); + while (currentLexer.TokenType != (ScriptLex.LexTypes)']') + { + if (execute) + { + var id = String.Format("{0}", idx); + + var a = Base(ref execute); + contents.AddChild(id, a.Var); + } + + if (currentLexer.TokenType != (ScriptLex.LexTypes)']') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + + idx++; + } + currentLexer.Match((ScriptLex.LexTypes)']'); + + return new ScriptVarLink(contents, null); + } + + if (currentLexer.TokenType == ScriptLex.LexTypes.RFunction) + { + var funcVar = ParseFunctionDefinition(); + if (funcVar.Name != String.Empty) + { + System.Diagnostics.Trace.TraceWarning("Functions not defined at statement level are not supposed to have a name"); + } + return funcVar; + } + + if (currentLexer.TokenType == ScriptLex.LexTypes.RNew) // new + { + currentLexer.Match(ScriptLex.LexTypes.RNew); + + var className = currentLexer.TokenString; + if (execute) + { + var classOrFuncObject = FindInScopes(className); + if (classOrFuncObject == null) + { + System.Diagnostics.Trace.TraceWarning("{0} is not a valid class name", className); + return new ScriptVarLink(new ScriptVar(), null); + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + + var obj = new ScriptVar(null, ScriptVar.Flags.Object); + var objLink = new ScriptVarLink(obj, null); + + if (classOrFuncObject.Var.IsFunction) + { + FunctionCall(ref execute, classOrFuncObject, obj); + } + else + { + //creating new instance of a class + if (classOrFuncObject.Var.ClassType != null) + { + obj.ClassInstance = Activator.CreateInstance(classOrFuncObject.Var.ClassType); + } + + obj.AddChild(ScriptVar.PrototypeClassName, classOrFuncObject.Var); + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'(') + { + currentLexer.Match((ScriptLex.LexTypes)'('); + currentLexer.Match((ScriptLex.LexTypes)')'); + } + } + + return objLink; + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + if (currentLexer.TokenType == (ScriptLex.LexTypes)'(') + { + currentLexer.Match((ScriptLex.LexTypes)'('); + currentLexer.Match((ScriptLex.LexTypes)')'); + } + } + + currentLexer.Match(ScriptLex.LexTypes.Eof); + + return null; + } + } +} diff --git a/DScript/ScriptEngine.FunctionCall.cs b/DScript/ScriptEngine.FunctionCall.cs new file mode 100644 index 0000000..4897fc1 --- /dev/null +++ b/DScript/ScriptEngine.FunctionCall.cs @@ -0,0 +1,136 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink FunctionCall(ref bool execute, ScriptVarLink function, ScriptVar parent) + { + if (execute) + { + if (!function.Var.IsFunction) + { + throw new ScriptException(String.Format("{0} is not a function", function.Name)); + } + + currentLexer.Match((ScriptLex.LexTypes)'('); + var functionRoot = new ScriptVar(null, ScriptVar.Flags.Function); + + if (parent != null) + { + functionRoot.AddChildNoDup("this", parent); + } + + var v = function.Var.FirstChild; + while (v != null) + { + var value = Base(ref execute); + if (value.Var.IsBasic) + { + //pass by val + functionRoot.AddChild(v.Name, value.Var.DeepCopy()); + } + else + { + //pass by ref + functionRoot.AddChild(v.Name, value.Var); + } + + if (currentLexer.TokenType != (ScriptLex.LexTypes)')') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + + v = v.Next; + } + + currentLexer.Match((ScriptLex.LexTypes)')'); + + var returnVarLink = functionRoot.AddChild(ScriptVar.ReturnVarName, null); + + scopes.Push(functionRoot); + + callStack.Push(string.Format("{0} from line {1}", function.Name, currentLexer.LineNumber)); + + if (function.Var.IsNative) + { + var func = function.Var.GetCallback(); + func?.Invoke(functionRoot, function.Var.GetCallbackUserData(), parent); + } + else + { + var oldLex = currentLexer; + var newLex = new ScriptLex(function.Var.GetString()); + currentLexer = newLex; + + try + { + Block(ref execute); + + execute = true; + } + catch + { + throw; + } + finally + { + currentLexer = oldLex; + } + } + + callStack.Pop(); + scopes.Pop(); + + var returnVar = new ScriptVarLink(returnVarLink.Var, null); + functionRoot.RemoveLink(returnVarLink); + + return returnVar; + } + + //not executing the function, just parsing it out + currentLexer.Match((ScriptLex.LexTypes)'('); + + while (currentLexer.TokenType != (ScriptLex.LexTypes)')') + { + Base(ref execute); + + if (currentLexer.TokenType != (ScriptLex.LexTypes)')') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + } + + currentLexer.Match((ScriptLex.LexTypes)')'); + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'{') //WTF? + { + Block(ref execute); + } + + return function; + } + } +} diff --git a/DScript/ScriptEngine.Logic.cs b/DScript/ScriptEngine.Logic.cs new file mode 100644 index 0000000..e15a3da --- /dev/null +++ b/DScript/ScriptEngine.Logic.cs @@ -0,0 +1,101 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Logic(ref bool execute) + { + var a = Condition(ref execute); + + while (currentLexer.TokenType == (ScriptLex.LexTypes)'&' || + currentLexer.TokenType == (ScriptLex.LexTypes)'|' || + currentLexer.TokenType == (ScriptLex.LexTypes)'^' || + currentLexer.TokenType == ScriptLex.LexTypes.AndAnd || + currentLexer.TokenType == ScriptLex.LexTypes.OrOr) + { + var op = currentLexer.TokenType; + currentLexer.Match(op); + + var shortcut = false; + var isBool = false; + + if (op == ScriptLex.LexTypes.AndAnd) + { + op = (ScriptLex.LexTypes)'&'; + shortcut = !a.Var.GetBool(); + isBool = true; + } + else if (op == ScriptLex.LexTypes.OrOr) + { + op = (ScriptLex.LexTypes)'|'; + shortcut = a.Var.GetBool(); + isBool = true; + } + + var condition = !shortcut && execute; + var b = Condition(ref condition); + + if (execute && !shortcut) + { + if (isBool) + { + var newA = new ScriptVar(a.Var.GetBool()); + var newB = new ScriptVar(b.Var.GetBool()); + + if (a.Owned) + { + a = new ScriptVarLink(newA, null); + } + else + { + a.ReplaceWith(newA); + } + + if (b.Owned) + { + b = new ScriptVarLink(newB, null); + } + else + { + b.ReplaceWith(newA); + } + } + + var res = a.Var.MathsOp(b.Var, op); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + } + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.Shift.cs b/DScript/ScriptEngine.Shift.cs new file mode 100644 index 0000000..a7a0502 --- /dev/null +++ b/DScript/ScriptEngine.Shift.cs @@ -0,0 +1,65 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Shift(ref bool execute) + { + var a = Expression(ref execute); + + if (currentLexer.TokenType == ScriptLex.LexTypes.LShift || + currentLexer.TokenType == ScriptLex.LexTypes.RShift || + currentLexer.TokenType == ScriptLex.LexTypes.RShiftUnsigned) + { + var op = currentLexer.TokenType; + currentLexer.Match(op); + var b = Base(ref execute); + + var shift = execute ? b.Var.GetInt() : 0; + + if (execute) + { + if (op == ScriptLex.LexTypes.LShift) + { + a.Var.SetInt(a.Var.GetInt() << shift); + } + + if (op == ScriptLex.LexTypes.RShift) + { + a.Var.SetInt(a.Var.GetInt() >> shift); + } + + if (op == ScriptLex.LexTypes.RShiftUnsigned) + { + a.Var.SetInt((int)(((uint)a.Var.GetInt()) >> shift)); + } + } + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.Statement.cs b/DScript/ScriptEngine.Statement.cs new file mode 100644 index 0000000..9da6fb9 --- /dev/null +++ b/DScript/ScriptEngine.Statement.cs @@ -0,0 +1,305 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public partial class ScriptEngine + { + private void Statement(ref bool execute) + { + if (currentLexer.TokenType == ScriptLex.LexTypes.Id || + currentLexer.TokenType == ScriptLex.LexTypes.Int || + currentLexer.TokenType == ScriptLex.LexTypes.Float || + currentLexer.TokenType == ScriptLex.LexTypes.Str || + currentLexer.TokenType == (ScriptLex.LexTypes)'-') + { + //execite a basic statement + Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)';'); + } + else if (currentLexer.TokenType == (ScriptLex.LexTypes)'{') + { + //code block + Block(ref execute); + } + else if (currentLexer.TokenType == (ScriptLex.LexTypes)';') + { + //allow for multiple semi colon such as ;;; + currentLexer.Match((ScriptLex.LexTypes)';'); + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RVar) + { + //creating variables + //TODO: make this less shit + + currentLexer.Match(ScriptLex.LexTypes.RVar); + + while (currentLexer.TokenType != (ScriptLex.LexTypes)';') + { + ScriptVarLink a = null; + if (execute) + { + a = scopes.Peek().FindChildOrCreate(currentLexer.TokenString); + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + + //get through the dots + while (currentLexer.TokenType == (ScriptLex.LexTypes)'.') + { + currentLexer.Match((ScriptLex.LexTypes)'.'); + if (execute) + { + var aLast = a; + if (aLast != null) + { + a = aLast.Var.FindChildOrCreate(currentLexer.TokenString); + } + } + + currentLexer.Match(ScriptLex.LexTypes.Id); + } + + //initialiser + if (currentLexer.TokenType == (ScriptLex.LexTypes)'=') + { + currentLexer.Match((ScriptLex.LexTypes)'='); + var varLink = Base(ref execute); + if (execute) + { + if (a != null) + { + a.ReplaceWith(varLink); + } + } + } + + if (currentLexer.TokenType != (ScriptLex.LexTypes)';') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + } + + currentLexer.Match((ScriptLex.LexTypes)';'); + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RIf) + { + //if condition + currentLexer.Match(ScriptLex.LexTypes.RIf); + currentLexer.Match((ScriptLex.LexTypes)'('); + var varLink = Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)')'); + + bool condition = execute && varLink.Var.GetBool(); + bool noExecute = false; + if (condition) + { + Statement(ref execute); + } + else + { + Statement(ref noExecute); + } + + if (currentLexer.TokenType == ScriptLex.LexTypes.RElse) + { + //else part of an if + currentLexer.Match(ScriptLex.LexTypes.RElse); + + if (condition) + { + Statement(ref noExecute); + } + else + { + Statement(ref execute); + } + } + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RWhile) + { + //while loop + currentLexer.Match(ScriptLex.LexTypes.RWhile); + currentLexer.Match((ScriptLex.LexTypes)'('); + + var whileConditionStart = currentLexer.TokenStart; + var condition = Base(ref execute); + var loopCondition = execute && condition.Var.GetBool(); + + var whileCond = currentLexer.GetSubLex(whileConditionStart); + currentLexer.Match((ScriptLex.LexTypes)')'); + + var whileBodyStart = currentLexer.TokenStart; + + Statement(ref loopCondition); + + var whileBody = currentLexer.GetSubLex(whileBodyStart); + var oldLex = currentLexer; + + //TODO: possible maximum itteration limit? + while (loopCondition) + { + whileCond.Reset(); + + currentLexer = whileCond; + + condition = Base(ref execute); + + loopCondition = condition.Var.GetBool(); + + if (loopCondition) + { + whileBody.Reset(); + currentLexer = whileBody; + Statement(ref execute); + } + } + + currentLexer = oldLex; + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RFor) + { + //for loop + currentLexer.Match(ScriptLex.LexTypes.RFor); + currentLexer.Match((ScriptLex.LexTypes)'('); + + Statement(ref execute); //init + + var forConditionStart = currentLexer.TokenStart; + var condition = Base(ref execute); + var noExecute = false; + var loopCondition = execute && condition.Var.GetBool(); + + var forCondition = currentLexer.GetSubLex(forConditionStart); + + currentLexer.Match((ScriptLex.LexTypes)';'); + + var forIterStart = currentLexer.TokenStart; + + Base(ref noExecute); + + var forIter = currentLexer.GetSubLex(forIterStart); + + currentLexer.Match((ScriptLex.LexTypes)')'); + + var forBodyStart = currentLexer.TokenStart; + + if (loopCondition) + { + Statement(ref execute); + } + else + { + Statement(ref noExecute); + } + + var forBody = currentLexer.GetSubLex(forBodyStart); + var oldLex = currentLexer; + if (loopCondition) + { + forIter.Reset(); + currentLexer = forIter; + + Base(ref execute); + } + + //TODO: limit number of iterations? + while (execute && loopCondition) + { + forCondition.Reset(); + currentLexer = forCondition; + + condition = Base(ref execute); + + loopCondition = condition.Var.GetBool(); + + if (execute && loopCondition) + { + forBody.Reset(); + currentLexer = forBody; + + Statement(ref execute); + } + + if (execute && loopCondition) + { + forIter.Reset(); + currentLexer = forIter; + + Base(ref execute); + } + } + + currentLexer = oldLex; + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RReturn) + { + currentLexer.Match(ScriptLex.LexTypes.RReturn); + + ScriptVarLink res = null; + if (currentLexer.TokenType != (ScriptLex.LexTypes)';') + { + res = Base(ref execute); + } + if (execute) + { + var resultVar = scopes.Peek().FindChild(ScriptVar.ReturnVarName); + if (resultVar != null) + { + resultVar.ReplaceWith(res); + } + else + { + //return statement outside of function??? + System.Diagnostics.Trace.TraceWarning("Return statement outside of a function, what is going on?"); + } + } + + execute = false; + currentLexer.Match((ScriptLex.LexTypes)';'); + } + else if (currentLexer.TokenType == ScriptLex.LexTypes.RFunction) + { + //function + var funcVar = ParseFunctionDefinition(); + if (execute) + { + if (funcVar.Name == string.Empty) + { + //functions must have a name at statement level + } + else + { + var v = scopes.Peek(); + v.AddChildNoDup(funcVar.Name, funcVar.Var); + } + } + } + else + { + currentLexer.Match(ScriptLex.LexTypes.Eof); + } + } + } +} diff --git a/ScriptEngine.Term.cs b/DScript/ScriptEngine.Term.cs similarity index 51% rename from ScriptEngine.Term.cs rename to DScript/ScriptEngine.Term.cs index 65792e5..1c3e40e 100644 --- a/ScriptEngine.Term.cs +++ b/DScript/ScriptEngine.Term.cs @@ -1,57 +1,57 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Term(ref bool execute) - { - ScriptVarLink a = Unary(ref execute); - - while (_currentLexer.TokenType == (ScriptLex.LexTypes) '*' || - _currentLexer.TokenType == (ScriptLex.LexTypes) '/' || - _currentLexer.TokenType == (ScriptLex.LexTypes) '%') - { - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(_currentLexer.TokenType); - - ScriptVarLink b = Unary(ref execute); - if (execute) - { - ScriptVar res = a.Var.MathsOp(b.Var, op); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - } - } - - return a; - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Term(ref bool execute) + { + var a = Unary(ref execute); + + while (currentLexer.TokenType == (ScriptLex.LexTypes)'*' || + currentLexer.TokenType == (ScriptLex.LexTypes)'/' || + currentLexer.TokenType == (ScriptLex.LexTypes)'%') + { + var op = currentLexer.TokenType; + currentLexer.Match(currentLexer.TokenType); + + var b = Unary(ref execute); + if (execute) + { + var res = a.Var.MathsOp(b.Var, op); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + } + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.Ternary.cs b/DScript/ScriptEngine.Ternary.cs new file mode 100644 index 0000000..3435b34 --- /dev/null +++ b/DScript/ScriptEngine.Ternary.cs @@ -0,0 +1,65 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Ternary(ref bool execute) + { + var a = Logic(ref execute); + + if (currentLexer.TokenType == (ScriptLex.LexTypes)'?') + { + currentLexer.Match((ScriptLex.LexTypes)'?'); + + if (!execute) + { + Base(ref execute); + + currentLexer.Match((ScriptLex.LexTypes)':'); + + Base(ref execute); + } + else + { + bool first = a.Var.GetBool(); + + if (first) + { + a = Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)':'); + Base(ref execute); + } + else + { + Base(ref execute); + currentLexer.Match((ScriptLex.LexTypes)':'); + a = Base(ref execute); + } + } + } + + return a; + } + } +} diff --git a/ScriptEngine.Unary.cs b/DScript/ScriptEngine.Unary.cs similarity index 52% rename from ScriptEngine.Unary.cs rename to DScript/ScriptEngine.Unary.cs index 34b2b9b..decee45 100644 --- a/ScriptEngine.Unary.cs +++ b/DScript/ScriptEngine.Unary.cs @@ -1,57 +1,57 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Unary(ref bool execute) - { - ScriptVarLink a; - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'!') - { - _currentLexer.Match((ScriptLex.LexTypes)'!'); - a = Factor(ref execute); - if (execute) - { - ScriptVar zero = new ScriptVar(0); - ScriptVar res = a.Var.MathsOp(zero, ScriptLex.LexTypes.Equal); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - } - } - else - { - a = Factor(ref execute); - } - - return a; - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +namespace DScript +{ + public partial class ScriptEngine + { + private ScriptVarLink Unary(ref bool execute) + { + ScriptVarLink a; + if (currentLexer.TokenType == (ScriptLex.LexTypes)'!') + { + currentLexer.Match((ScriptLex.LexTypes)'!'); + a = Factor(ref execute); + if (execute) + { + var zero = new ScriptVar(0); + var res = a.Var.MathsOp(zero, ScriptLex.LexTypes.Equal); + + if (a.Owned) + { + a = new ScriptVarLink(res, null); + } + else + { + a.ReplaceWith(res); + } + } + } + else + { + a = Factor(ref execute); + } + + return a; + } + } +} diff --git a/DScript/ScriptEngine.cs b/DScript/ScriptEngine.cs new file mode 100644 index 0000000..9c2f168 --- /dev/null +++ b/DScript/ScriptEngine.cs @@ -0,0 +1,555 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace DScript +{ + public partial class ScriptEngine : IDisposable + { + #region IDisposable + private bool _disposed; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + stringClass.UnRef(); + arrayClass.UnRef(); + objectClass.UnRef(); + Root.UnRef(); + + if (currentLexer != null) + { + currentLexer.Dispose(); + } + } + + // Indicate that the instance has been disposed. + _disposed = true; + } + } + #endregion + + private readonly ScriptVar stringClass; + private readonly ScriptVar objectClass; + private readonly ScriptVar arrayClass; + private Stack scopes; + private readonly Stack callStack; + + private ScriptLex currentLexer; + + public delegate void ScriptCallbackCB(ScriptVar var, object userdata, ScriptVar parent = null); + + public ScriptVar Root { get; private set; } + + public ScriptEngine(bool loadProviders = true) + { + currentLexer = null; + + scopes = new Stack(); + callStack = new Stack(); + + Root = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); + + stringClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); + objectClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); + arrayClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); + + Root.AddChild("String", stringClass); + Root.AddChild("Object", objectClass); + Root.AddChild("Array", arrayClass); + + if (loadProviders) + { + LoadAllFunctionProviders(); + } + } + + public void Trace() + { + Root.Trace(0, null); + } + + public void Execute(String code) + { + var oldLex = currentLexer; + var oldScopes = scopes; + + using (currentLexer = new ScriptLex(code)) + { + scopes.Clear(); + scopes.Push(Root); + callStack.Clear(); + + try + { + while (currentLexer.TokenType != 0) + { + bool execute = true; + Statement(ref execute); + } + } + catch (ScriptException ex) + { + string errorMessage = string.Format("ERROR on line {0} column {1} [{2}]", currentLexer.LineNumber, currentLexer.ColumnNumber, ex.Message); + + int i = 0; + foreach (ScriptVar scriptVar in scopes) + { + errorMessage += "\n" + i++ + ": " + scriptVar; + } + + Console.Error.WriteLine(errorMessage); + } + } + + currentLexer = oldLex; + scopes = oldScopes; + } + + public ScriptVarLink EvalComplex(string code) + { + var oldLex = currentLexer; + var oldScopes = scopes; + + currentLexer = new ScriptLex(code); + + callStack.Clear(); + scopes.Clear(); + scopes.Push(Root); + + ScriptVarLink v = null; + + try + { + bool execute = true; + do + { + v = Base(ref execute); + if (currentLexer.TokenType != ScriptLex.LexTypes.Eof) + { + currentLexer.Match((ScriptLex.LexTypes)';'); + } + } while (currentLexer.TokenType != ScriptLex.LexTypes.Eof); + } + catch (ScriptException ex) + { + var errorMessage = ex.Message; + int i = 0; + foreach (ScriptVar scriptVar in scopes) + { + errorMessage += "\n" + i++ + ": " + scriptVar; + } + + Console.Error.WriteLine(errorMessage); + } + + currentLexer = oldLex; + scopes = oldScopes; + + if (v != null) + { + return v; + } + + return new ScriptVarLink(new ScriptVar(null), null); + } + + public void AddObject(String[] ns, String objectName, ScriptVar val) + { + var baseVar = Root; + + if (ns != null) + { + int x = 0; + for (; x < ns.Length; x++) + { + var link = baseVar.FindChild(ns[x]); + + if (link == null) + { + link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); + } + + baseVar = link.Var; + } + } + + baseVar.AddChild(objectName, val); + } + + public void AddMethod(string[] ns, string funcName, string[] args, ScriptCallbackCB callback, object userdata) + { + var fName = funcName; + var baseVar = Root; + + if (ns != null) + { + int x = 0; + for (; x < ns.Length; x++) + { + var link = baseVar.FindChild(ns[x]); + + if (link == null) + { + link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); + } + + baseVar = link.Var; + } + } + + + var funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); + funcVar.SetCallback(callback, userdata); + + //do we have any arguments to create? + if (args != null) + { + foreach (string arg in args) + { + funcVar.AddChildNoDup(arg, null); + } + } + + baseVar.AddChild(fName, funcVar); + } + + public void AddMethod(string funcName, string[] args, ScriptCallbackCB callback, object userdata) + { + var funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); + funcVar.SetCallback(callback, userdata); + + //do we have any arguments to create? + if (args != null) + { + foreach (string arg in args) + { + funcVar.AddChildNoDup(arg, null); + } + } + + Root.AddChild(funcName, funcVar); + } + + public void LoadAllFunctionProviders() + { + var execAssembly = Assembly.GetExecutingAssembly(); + + TestForAttribute(execAssembly); + + AssemblyName[] referencedAssemblies = execAssembly.GetReferencedAssemblies(); + foreach (AssemblyName assembly in referencedAssemblies) + { + Assembly asm = Assembly.Load(assembly); + + TestForAttribute(asm); + } + } + + private void TestForAttribute(Assembly asm) + { + Type[] types = asm.GetTypes(); + foreach (Type type in types) + { + object[] scObjects = type.GetCustomAttributes(typeof(ScriptClassAttribute), false); + if (scObjects.Length > 0) + { + ProcessType(type, scObjects[0] as ScriptClassAttribute); + } + } + } + + private void ProcessType(Type type, ScriptClassAttribute attr) + { + AddObject(attr.Namespace ?? new string[0], attr.ClassName ?? type.Name, new ScriptVar(null, ScriptVar.Flags.Object | ScriptVar.Flags.Native) { ClassType = type }); + + MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); + ProcessMethods(methods, attr); + + methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); + ProcessMethods(methods, attr); + + PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static); + ProcessProperties(properties, attr, null); + } + + private void ProcessMethods(MethodInfo[] methods, ScriptClassAttribute attr) + { + foreach (MethodInfo method in methods) + { + if (method.IsSpecialName) continue; + + ParameterInfo[] parameters = method.GetParameters(); + if (parameters.Length < 1) continue; + + String[] argNames = new string[parameters.Length - 1]; + for (int i = 0; i < parameters.Length - 1; i++) + { + argNames[i] = parameters[i].Name; + } + + MethodInfo methodCopy = method; + String[] ns = attr.Namespace ?? new string[0]; + + if (attr.ClassName == null && ns.Length == 0) + { + ns = null; + } + else + { + Array.Resize(ref ns, ns.Length + 1); + ns[ns.Length - 1] = attr.ClassName; + } + + AddMethod(ns, method.Name, argNames, CreateScriptFunction(methodCopy, parameters), this); + } + } + + private void ProcessProperties(PropertyInfo[] properties, ScriptClassAttribute attr, object instance) + { + foreach (PropertyInfo property in properties) + { + if (property.IsSpecialName) continue; + + PropertyInfo propertyCopy = property; + String[] ns = attr.Namespace ?? new string[0]; + + if (attr.ClassName == null && ns.Length == 0) + { + ns = null; + } + else + { + Array.Resize(ref ns, ns.Length + 1); + ns[ns.Length - 1] = attr.ClassName; + } + + if (property.PropertyType == typeof(bool)) + { + AddObject(ns, property.Name, new ScriptVar((bool)property.GetValue(instance, null))); + } + else if (property.PropertyType == typeof(string)) + { + AddObject(ns, property.Name, new ScriptVar((string)property.GetValue(instance, null))); + } + else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(float) || property.PropertyType == typeof(double)) + { + AddObject(ns, property.Name, new ScriptVar((double)property.GetValue(instance, null))); + } + else if (property.PropertyType == typeof(Int32)) + { + AddObject(ns, property.Name, new ScriptVar((Int32)property.GetValue(instance, null))); + } + } + } + + private ScriptCallbackCB CreateScriptFunction(MethodInfo method, ParameterInfo[] parameters) + { + return delegate (ScriptVar var, object userdata, ScriptVar parent) + { + object[] args = new object[parameters.Length]; + + int i = 0; + for (; i < parameters.Length - 1; i++) + { + args[i] = var.GetParameter(parameters[i].Name).GetData(); + } + + args[i] = userdata; + + object returnVal; + + if (method.IsStatic) + { + returnVal = method.Invoke(null, args); + } + else + { + returnVal = method.Invoke(parent.ClassInstance, args); + } + + if (method.ReturnType == typeof(Int32)) + { + var.SetReturnVar(new ScriptVar(Convert.ToInt32(returnVal), ScriptVar.Flags.Integer)); + } + else if (method.ReturnType == typeof(bool)) + { + var.SetReturnVar(new ScriptVar(Convert.ToBoolean(returnVal) ? 1 : 0, ScriptVar.Flags.Integer)); + } + else if (method.ReturnType == typeof(double) || method.ReturnType == typeof(float)) + { + var.SetReturnVar(new ScriptVar(Convert.ToDouble(returnVal), ScriptVar.Flags.Double)); + } + else if (method.ReturnType == typeof(String)) + { + var.SetReturnVar(new ScriptVar(Convert.ToString(returnVal), ScriptVar.Flags.String)); + } + }; + } + + [Obsolete("Do not use, this is the old way of binding native methods to language functions")] + public void AddMethod(String funcProto, ScriptCallbackCB callback, Object userdata) + { + ScriptLex oldLex = currentLexer; + + using (currentLexer = new ScriptLex(funcProto)) + { + ScriptVar baseVar = Root; + + currentLexer.Match(ScriptLex.LexTypes.RFunction); + String funcName = currentLexer.TokenString; + currentLexer.Match(ScriptLex.LexTypes.Id); + + while (currentLexer.TokenType == (ScriptLex.LexTypes)'.') + { + currentLexer.Match((ScriptLex.LexTypes)'.'); + ScriptVarLink link = baseVar.FindChild(funcName); + + if (link == null) + { + link = baseVar.AddChild(funcName, new ScriptVar(null, ScriptVar.Flags.Object)); + } + + baseVar = link.Var; + funcName = currentLexer.TokenString; + currentLexer.Match(ScriptLex.LexTypes.Id); + } + + ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); + funcVar.SetCallback(callback, userdata); + + ParseFunctionArguments(funcVar); + + baseVar.AddChild(funcName, funcVar); + } + + currentLexer = oldLex; + } + + private ScriptVarLink FindInScopes(String name) + { + foreach (ScriptVar scriptVar in scopes) + { + ScriptVarLink a = scriptVar.FindChild(name); + if (a != null) + { + return a; + } + } + + return null; + } + + private ScriptVarLink FindInParentClasses(ScriptVar obj, String name) + { + ScriptVarLink implementation; + var parentClass = obj.FindChild(ScriptVar.PrototypeClassName); + + while (parentClass != null) + { + implementation = parentClass.Var.FindChild(name); + if (implementation != null) + { + return implementation; + } + parentClass = parentClass.Var.FindChild(ScriptVar.PrototypeClassName); + } + + if (obj.IsString) + { + implementation = stringClass.FindChild(name); + if (implementation != null) + { + return implementation; + } + } + + if (obj.IsArray) + { + implementation = arrayClass.FindChild(name); + if (implementation != null) + { + return implementation; + } + } + + implementation = objectClass.FindChild(name); + if (implementation != null) + { + return implementation; + } + + return null; + } + + private ScriptVarLink ParseFunctionDefinition() + { + currentLexer.Match(ScriptLex.LexTypes.RFunction); + var funcName = String.Empty; + + //named function + if (currentLexer.TokenType == ScriptLex.LexTypes.Id) + { + funcName = currentLexer.TokenString; + currentLexer.Match(ScriptLex.LexTypes.Id); + } + + var funcVar = new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Function), funcName); + ParseFunctionArguments(funcVar.Var); + + var funcBegin = currentLexer.TokenStart; + bool execute = false; + Block(ref execute); + funcVar.Var.SetData(currentLexer.GetSubString(funcBegin)); + + return funcVar; + } + + private void ParseFunctionArguments(ScriptVar funcVar) + { + currentLexer.Match((ScriptLex.LexTypes)'('); + while (currentLexer.TokenType != (ScriptLex.LexTypes)')') + { + funcVar.AddChildNoDup(currentLexer.TokenString, null); + currentLexer.Match(ScriptLex.LexTypes.Id); + + if (currentLexer.TokenType != (ScriptLex.LexTypes)')') + { + currentLexer.Match((ScriptLex.LexTypes)','); + } + } + + currentLexer.Match((ScriptLex.LexTypes)')'); + } + } +} diff --git a/ScriptException.cs b/DScript/ScriptException.cs similarity index 80% rename from ScriptException.cs rename to DScript/ScriptException.cs index a319a5d..22f5ae3 100644 --- a/ScriptException.cs +++ b/DScript/ScriptException.cs @@ -1,42 +1,42 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - [Serializable] - public class ScriptException : Exception - { - public ScriptException(String msg) - : base(msg) - { - - } - - public ScriptException(String msg, Exception innerException) - : base(msg, innerException) - { - - } - } -} +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + [Serializable] + public class ScriptException : Exception + { + public ScriptException(string msg) + : base(msg) + { + + } + + public ScriptException(string msg, Exception innerException) + : base(msg, innerException) + { + + } + } +} diff --git a/DScript/ScriptLex.cs b/DScript/ScriptLex.cs new file mode 100644 index 0000000..475dcc7 --- /dev/null +++ b/DScript/ScriptLex.cs @@ -0,0 +1,567 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public class ScriptLex : IDisposable + { + #region IDisposable + private bool _disposed; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + if (dataOwned) + { + data = string.Empty; + } + } + + // Indicate that the instance has been disposed. + _disposed = true; + } + } + #endregion + + private string data; + private readonly bool dataOwned; + private readonly int dataStart; + private readonly int dataEnd; + private int dataPos; + private int currColumnNumber; + + public char CurrentChar { get; private set; } + public char NextChar { get; private set; } + public LexTypes TokenType { get; private set; } + public int TokenStart { get; private set; } + public int TokenEnd { get; private set; } + public int TokenLastEnd { get; private set; } + public int LineNumber { get; private set; } + public int ColumnNumber { get; private set; } + public string TokenString { get; private set; } + + public enum LexTypes + { + Eof = 0, + Id = 256, + Int, + Float, + Str, + Equal, + TypeEqual, + NEqual, + NTypeEqual, + LEqual, + LShift, + LShiftEqual, + GEqual, + RShift, + RShiftUnsigned, + RShiftEqual, + PlusEqual, + MinusEqual, + PlusPlus, + MinusMinus, + AndEqual, + AndAnd, + OrEqual, + OrOr, + XorEqual, + RListStart, + RIf = RListStart, + RElse, + RDo, + RWhile, + RFor, + RBreak, + RContinue, + RFunction, + RReturn, + RVar, + RTrue, + RFalse, + RNull, + RUndefined, + RNew, + RListEnd + } + + public ScriptLex(string input) + { + data = input; + dataOwned = true; + dataStart = 0; + dataEnd = data.Length; + + Reset(); + } + + public ScriptLex(ScriptLex owner, int start, int end) + { + data = owner.data; + dataOwned = false; + dataStart = start; + dataEnd = end; + + Reset(); + } + + public void Reset() + { + dataPos = dataStart; + TokenStart = 0; + TokenEnd = 0; + TokenLastEnd = 0; + TokenType = 0; + TokenString = ""; + + GetNextChar(); + GetNextChar(); + GetNextToken(); + } + + public void GetNextChar() + { + CurrentChar = NextChar; + + if (dataPos < dataEnd) + { + NextChar = data[dataPos]; + } + else + { + NextChar = (char)0; + } + + dataPos++; + + currColumnNumber++; + + if (CurrentChar == '\n') + { + LineNumber++; + currColumnNumber = 0; + } + } + + public void GetNextToken() + { + ColumnNumber = currColumnNumber; + + TokenType = LexTypes.Eof; + TokenString = string.Empty; + + while (CurrentChar != (char)0 && CurrentChar.IsWhitespace()) + { + GetNextChar(); + } + + //single line comment + if (CurrentChar == '/' && NextChar == '/') + { + while (CurrentChar != 0 && CurrentChar != '\n') GetNextChar(); + GetNextChar(); + GetNextToken(); + return; + } + + //multi line comment + if (CurrentChar == '/' && NextChar == '*') + { + while (CurrentChar != '*' && CurrentChar != '/') GetNextChar(); + GetNextChar(); + GetNextChar(); + GetNextToken(); + return; + } + + TokenStart = dataPos - 2; + + if (CurrentChar.IsAlpha()) //IDs + { + while (CurrentChar.IsAlpha() || CurrentChar.IsNumeric()) + { + TokenString += CurrentChar; + GetNextChar(); + } + + TokenType = LexTypes.Id; + switch (TokenString) + { + case "if": TokenType = LexTypes.RIf; break; + case "else": TokenType = LexTypes.RElse; break; + case "do": TokenType = LexTypes.RDo; break; + case "while": TokenType = LexTypes.RWhile; break; + case "for": TokenType = LexTypes.RFor; break; + case "break": TokenType = LexTypes.RBreak; break; + case "continue": TokenType = LexTypes.RContinue; break; + case "function": TokenType = LexTypes.RFunction; break; + case "return": TokenType = LexTypes.RReturn; break; + case "var": TokenType = LexTypes.RVar; break; + case "true": TokenType = LexTypes.RTrue; break; + case "false": TokenType = LexTypes.RFalse; break; + case "null": TokenType = LexTypes.RFalse; break; + case "undefined": TokenType = LexTypes.RNull; break; + case "new": TokenType = LexTypes.RNew; break; + + } + } + else if (CurrentChar.IsNumeric()) //Numbers + { + var isHex = false; + if (CurrentChar == '0') + { + TokenString += CurrentChar; + GetNextChar(); + } + + if (CurrentChar == 'x') + { + isHex = true; + TokenString += CurrentChar; + GetNextChar(); + } + + TokenType = LexTypes.Int; + + while (CurrentChar.IsNumeric() || (isHex && CurrentChar.IsHexadecimal())) + { + TokenString += CurrentChar; + GetNextChar(); + } + + if (!isHex && CurrentChar == '.') + { + TokenType = LexTypes.Float; + TokenString += '.'; + GetNextChar(); + while (CurrentChar.IsNumeric()) + { + TokenString += CurrentChar; + GetNextChar(); + } + } + + if (!isHex && (CurrentChar == 'e' || CurrentChar == 'E')) + { + TokenType = LexTypes.Float; + TokenString += CurrentChar; + GetNextChar(); + if (CurrentChar == '-') + { + TokenString += CurrentChar; + GetNextChar(); + } + while (CurrentChar.IsNumeric()) + { + TokenString += CurrentChar; + GetNextChar(); + } + } + } + else if (CurrentChar == '"') //Strings + { + GetNextChar(); + while (CurrentChar != (char)0 && CurrentChar != '"') + { + if (CurrentChar == '\\') + { + GetNextChar(); + switch (CurrentChar) + { + case 'n': + TokenString += '\n'; + break; + case '"': + TokenString += '"'; + break; + case '\\': + TokenString += '\\'; + break; + default: + TokenString += CurrentChar; + break; + } + } + else + { + TokenString += CurrentChar; + } + + GetNextChar(); + } + + GetNextChar(); + + TokenType = LexTypes.Str; + } + else if (CurrentChar == '\'') //Strings again + { + GetNextChar(); + + while (CurrentChar != (char)0 && CurrentChar != '\'') + { + if (CurrentChar == '\\') + { + GetNextChar(); + + switch (CurrentChar) + { + case 'n': + TokenString += '\n'; + break; + case 'a': + TokenString += '\a'; + break; + case 'r': + TokenString += '\r'; + break; + case 't': + TokenString += '\t'; + break; + case '\'': + TokenString += '\''; + break; + case '\\': + TokenString += '\\'; + break; + case 'x': + { + var str = ""; + GetNextChar(); + str += CurrentChar; + GetNextChar(); + str += CurrentChar; + TokenString += (char)Convert.ToInt64(str); + } + break; + default: + if (CurrentChar >= '0' && CurrentChar <= '7') + { + var str = ""; + str += CurrentChar; + GetNextChar(); + str += CurrentChar; + GetNextChar(); + str += CurrentChar; + TokenString += (char)Convert.ToInt64(str); + } + else + { + TokenString += CurrentChar; + } + break; + } + } + else + { + TokenString += CurrentChar; + } + + GetNextChar(); + } + + GetNextChar(); + + TokenType = LexTypes.Str; + } + else //Single character + { + TokenType = (LexTypes)CurrentChar; + + if (CurrentChar != (char)0) + { + GetNextChar(); + } + + if (TokenType == (LexTypes)'=' && CurrentChar == '=') // == + { + TokenType = LexTypes.Equal; + GetNextChar(); + + if (CurrentChar == '=') //=== + { + TokenType = LexTypes.TypeEqual; + GetNextChar(); + } + } + else if (TokenType == (LexTypes)'!' && CurrentChar == '=') // != + { + TokenType = LexTypes.NEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'<' && CurrentChar == '=') // <= + { + TokenType = LexTypes.LEqual; + GetNextChar(); + + if (CurrentChar == '=') //!== + { + TokenType = LexTypes.NTypeEqual; + GetNextChar(); + } + } + else if (TokenType == (LexTypes)'<' && CurrentChar == '<') // << + { + TokenType = LexTypes.LShift; + GetNextChar(); + if (CurrentChar == '=') //<<= + { + TokenType = LexTypes.LShiftEqual; + GetNextChar(); + } + } + else if (TokenType == (LexTypes)'>' && CurrentChar == '=') // >= + { + TokenType = LexTypes.GEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'>' && CurrentChar == '>') // >> + { + TokenType = LexTypes.RShift; + GetNextChar(); + + if (CurrentChar == '=') // >>= + { + TokenType = LexTypes.RShiftEqual; + GetNextChar(); + } + else if (CurrentChar == '>') // >>> + { + TokenType = LexTypes.RShiftUnsigned; + GetNextChar(); + } + } + else if (TokenType == (LexTypes)'+' && CurrentChar == '=') // += + { + TokenType = LexTypes.PlusEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'-' && CurrentChar == '=') // -= + { + TokenType = LexTypes.MinusEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'+' && CurrentChar == '+') // ++ + { + TokenType = LexTypes.PlusPlus; + GetNextChar(); + } + else if (TokenType == (LexTypes)'-' && CurrentChar == '-') // -- + { + TokenType = LexTypes.MinusMinus; + GetNextChar(); + } + else if (TokenType == (LexTypes)'&' && CurrentChar == '=') // &= + { + TokenType = LexTypes.AndEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'&' && CurrentChar == '&') // && + { + TokenType = LexTypes.AndAnd; + GetNextChar(); + } + else if (TokenType == (LexTypes)'|' && CurrentChar == '=') // |= + { + TokenType = LexTypes.OrEqual; + GetNextChar(); + } + else if (TokenType == (LexTypes)'|' && CurrentChar == '|') // || + { + TokenType = LexTypes.OrOr; + GetNextChar(); + } + else if (TokenType == (LexTypes)'^' && CurrentChar == '=') // ^= + { + TokenType = LexTypes.XorEqual; + GetNextChar(); + } + } + + /* Something broke... */ + TokenLastEnd = TokenEnd; + TokenEnd = dataPos - 3; + } + + public ScriptLex GetSubLex(int lastPosition) + { + int lastCharIdx = TokenLastEnd + 1; + + if (lastCharIdx < dataEnd) + { + return new ScriptLex(this, lastPosition, lastCharIdx); + } + + return new ScriptLex(this, lastPosition, dataEnd); + } + + public string GetPosition(int pos) + { + return string.Format("{0}", pos); + } + + public string GetSubString(int pos) + { + int lastCharIndex = TokenLastEnd + 1; + + if (lastCharIndex < dataEnd) + { + return data.Substring(pos, lastCharIndex - pos); + } + + return data.Substring(pos); + } + + public void Match(LexTypes type) + { + if (TokenType != type) + { + var expectedName = Enum.GetName(typeof(LexTypes), type); + if (string.IsNullOrEmpty(expectedName)) + { + expectedName = string.Format("{0}", ((char)type)); + } + + var foundName = Enum.GetName(typeof(LexTypes), TokenType); + if (string.IsNullOrEmpty(foundName)) + { + foundName = string.Format("{0}", (char)TokenType); + } + + throw new ScriptException(string.Format("Unexpected token type. Expected {0}, found {1}", expectedName, foundName)); + } + + GetNextToken(); + } + } +} diff --git a/DScript/ScriptVar.cs b/DScript/ScriptVar.cs new file mode 100644 index 0000000..7f35087 --- /dev/null +++ b/DScript/ScriptVar.cs @@ -0,0 +1,783 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public class ScriptVar : IDisposable + { + #region IDisposable + private bool _disposed; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + RemoveAllChildren(); + } + + // Indicate that the instance has been disposed. + _disposed = true; + } + } + #endregion + + private int refs; + private Flags flags; + private object data; + private int intData; + private double doubleData; + private ScriptEngine.ScriptCallbackCB callback; + private object callbackUserData; + + public const string ReturnVarName = "return"; + public const string PrototypeClassName = "prototype"; + + [Flags] + public enum Flags + { + Undefined = 1, + Function = 2, + Object = 4, + Array = 8, + Double = 16, + Integer = 32, + String = 64, + Null = 128, + Native = 256, + Class = 512, + NumericMask = Null | Double | Integer, + VarTypeMask = Double | Integer | String | Function | Object | Array | Null + } + + public ScriptVarLink FirstChild { get; set; } + public ScriptVarLink LastChild { get; set; } + + public ScriptVar() + { + refs = 0; + flags = Flags.Undefined; + Init(); + } + + public ScriptVar(int val) + { + refs = 0; + flags = Flags.Integer; + Init(); + intData = val; + } + + public ScriptVar(double val) + { + refs = 0; + flags = Flags.Double; + Init(); + doubleData = val; + } + + public ScriptVar(string val) + { + refs = 0; + flags = Flags.String; + Init(); + data = val; + } + + public ScriptVar(bool val) + { + refs = 0; + flags = Flags.Integer; + Init(); + intData = val ? 1 : 0; + } + + public ScriptVar(object val, Flags flags) + { + refs = 0; + this.flags = flags; + Init(); + data = val; + } + + private void Init() + { + FirstChild = null; + LastChild = null; + callback = null; + callbackUserData = null; + data = null; + intData = 0; + doubleData = 0; + } + + public bool IsInt + { + get { return (flags & Flags.Integer) != 0; } + } + + public bool IsDouble + { + get { return (flags & Flags.Double) != 0; } + } + + public bool IsString + { + get { return (flags & Flags.String) != 0; } + } + + public bool IsNumeric + { + get { return (flags & Flags.NumericMask) != 0; } + } + + public bool IsFunction + { + get { return (flags & Flags.Function) != 0; } + } + + public bool IsObject + { + get { return (flags & Flags.Object) != 0; } + } + + public bool IsArray + { + get { return (flags & Flags.Array) != 0; } + } + + public bool IsNative + { + get { return (flags & Flags.Native) != 0; } + } + + public bool IsUndefined + { + get { return (flags & Flags.VarTypeMask) == Flags.Undefined; } + } + + public bool IsNull + { + get { return (flags & Flags.Null) != 0; } + } + + public bool IsBasic + { + get { return FirstChild == null; } + } + + public bool IsClass + { + get { return (flags & Flags.Class) != 0; } + } + + public ScriptVar this[string index] + { + get { return GetParameter(index); } + } + + public int GetInt() + { + if (IsInt && data == null) return intData; + if (IsInt && data != null) return Convert.ToInt32(data); + if (IsNull) return 0; + if (IsUndefined) return 0; + if (IsDouble) return (int)doubleData; + return 0; + } + + public bool GetBool() + { + return GetInt() != 0; + } + + public double GetDouble() + { + if (IsDouble && data == null) return doubleData; + if (IsDouble && data != null) return Convert.ToDouble(data); + if (IsInt) return intData; + if (IsNull) return 0; + if (IsUndefined) return 0; + return 0; + } + + public string GetString() + { + if (IsInt) + { + return string.Format("{0:D}", intData); + } + if (IsDouble) + { + return string.Format("{0}", doubleData); + } + if (IsNull) return "null"; + if (IsUndefined) return "undefined"; + + return (string)data; + } + + public object GetData() + { + if (IsNull) return null; + if (IsUndefined) return null; + if (IsInt && data == null) return intData; + if (IsInt && data != null) return Convert.ToInt32(data); + if (IsDouble && data == null) return doubleData; + if (IsDouble && data != null) return Convert.ToDouble(data); + + return data; + } + + public void SetInt(int num) + { + flags = (flags & ~Flags.VarTypeMask) | Flags.Integer; + intData = num; + doubleData = 0; + data = null; + } + + public void SetDouble(double num) + { + flags = (flags & ~Flags.VarTypeMask) | Flags.Double; + intData = 0; + doubleData = num; + data = null; + } + + public void SetString(string str) + { + flags = (flags & ~Flags.VarTypeMask) | Flags.String; + intData = 0; + doubleData = 0; + data = str; + } + + public void SetUndefined() + { + flags = (flags & ~Flags.VarTypeMask) | Flags.Undefined; + intData = 0; + doubleData = 0; + data = null; + RemoveAllChildren(); + } + + public void SetArray() + { + flags = (flags & ~Flags.VarTypeMask) | Flags.Array; + intData = 0; + doubleData = 0; + data = null; + RemoveAllChildren(); + } + + public ScriptVar Ref() + { + refs++; + return this; + } + + public void UnRef() + { + if (refs <= 0) throw new ScriptException("No refs to unref"); + + if ((--refs) == 0) + { + Dispose(true); + } + } + + public int GetRefs() + { + return refs; + } + + public ScriptVarLink FindChild(string childName) + { + var v = FirstChild; + + while (v != null) + { + if (v.Name == childName) + { + return v; + } + + v = v.Next; + } + + return null; + } + + public ScriptVarLink FindChildOrCreate(string childName, Flags varFlags = Flags.Undefined) + { + var l = FindChild(childName); + if (l != null) return l; + + return AddChild(childName, new ScriptVar(null, varFlags)); + } + + public ScriptVarLink FindChildOrCreateByPath(string path) + { + var p = path.IndexOf('.'); + if (p < 0) return FindChildOrCreate(path); + + var parts = path.Split('.'); + + return FindChildOrCreate(parts[0], Flags.Object).Var.FindChildOrCreateByPath(parts[1]); + } + + public ScriptVarLink AddChild(String childName, ScriptVar child) + { + if (IsUndefined) + { + flags = Flags.Object; + } + + var c = child ?? new ScriptVar(); + + var link = new ScriptVarLink(c, childName) + { + Owned = true + }; + + if (LastChild != null) + { + LastChild.Next = link; + link.Prev = LastChild; + LastChild = link; + } + else + { + FirstChild = link; + LastChild = link; + } + + return link; + } + + public ScriptVarLink AddChildNoDup(String childName, ScriptVar child) + { + var c = child ?? new ScriptVar(); + + var v = FindChild(childName); + if (v != null) + { + v.ReplaceWith(c); + } + else + { + v = AddChild(childName, c); + } + + return v; + } + + public void RemoveChild(ScriptVar child) + { + var link = FirstChild; + + while (link != null) + { + if (link.Var == child) break; + + link = link.Next; + } + + RemoveLink(link); + } + + public void RemoveLink(ScriptVarLink link) + { + if (link == null) return; + + if (link.Next != null) + { + link.Next.Prev = link.Prev; + } + if (link.Prev != null) + { + link.Prev.Next = link.Next; + } + if (LastChild == link) + { + LastChild = link.Prev; + } + if (FirstChild == link) + { + FirstChild = link.Next; + } + } + + public void RemoveAllChildren() + { + var c = FirstChild; + + while (c != null) + { + var t = c.Next; + c = t; + } + + FirstChild = null; + LastChild = null; + } + + public ScriptVar ReturnVar + { + get + { + return GetReturnVar(); + } + set + { + SetReturnVar(value); + } + } + + public ScriptVar GetReturnVar() + { + return GetParameter(ReturnVarName); + } + + public void SetReturnVar(ScriptVar var) + { + FindChildOrCreate(ReturnVarName).ReplaceWith(var); + } + + public ScriptVar GetParameter(string name) + { + return FindChildOrCreate(name).Var; + } + + public ScriptVar GetArrayIndex(int idx) + { + var link = FindChild(string.Format("{0}", idx)); + if (link != null) return link.Var; + + return new ScriptVar(null, Flags.Null); + } + + public void SetArrayIndex(int idx, ScriptVar value) + { + var link = FindChild(string.Format("{0}", idx)); + + if (link != null) + { + if (value.IsUndefined) + { + RemoveLink(link); + } + else + { + link.ReplaceWith(value); + } + } + else + { + if (!value.IsUndefined) + { + AddChild(string.Format("{0}", idx), value); + } + } + } + + public int GetArrayLength() + { + var highest = -1; + + if (!IsArray) return 0; + + ScriptVarLink link = FirstChild; + + while (link != null) + { + int outputVal; + if (int.TryParse(link.Name, out outputVal)) + { + if (outputVal > highest) highest = outputVal; + } + + link = link.Next; + } + + return highest + 1; + } + + public int GettChildren() + { + var n = 0; + var link = FirstChild; + while (link != null) + { + n++; + link = link.Next; + } + return n; + } + + public bool Equal(ScriptVar v) + { + bool res; + + using (ScriptVar resV = MathsOp(v, ScriptLex.LexTypes.Equal)) + { + res = resV.GetBool(); + } + + return res; + } + + public ScriptVar MathsOp(ScriptVar b, ScriptLex.LexTypes op) + { + var a = this; + + char opc = (char)op; + + if (op == ScriptLex.LexTypes.TypeEqual || op == ScriptLex.LexTypes.NTypeEqual) + { + bool equal = ((a.flags & Flags.VarTypeMask) == (b.flags & Flags.VarTypeMask)); + + if (equal) + { + ScriptVar contents = a.MathsOp(b, ScriptLex.LexTypes.Equal); + if (!contents.GetBool()) equal = false; + } + + if (op == ScriptLex.LexTypes.TypeEqual) + { + return new ScriptVar(equal); + } + + return new ScriptVar(!equal); + } + + if (a.IsUndefined && b.IsUndefined) + { + if (op == ScriptLex.LexTypes.Equal) + { + return new ScriptVar(true); + } + if (op == ScriptLex.LexTypes.NEqual) + { + return new ScriptVar(false); + } + + return new ScriptVar(); + } + + if ((a.IsNumeric || a.IsUndefined) && (b.IsNumeric || b.IsUndefined)) + { + if (!a.IsDouble && !b.IsDouble) + { + //ints + int da = a.GetInt(); + int db = b.GetInt(); + + switch (opc) + { + case '+': return new ScriptVar(da + db); + case '-': return new ScriptVar(da - db); + case '*': return new ScriptVar(da * db); + case '/': return new ScriptVar(da / db); + case '&': return new ScriptVar(da & db); + case '|': return new ScriptVar(da | db); + case '^': return new ScriptVar(da ^ db); + case '%': return new ScriptVar(da % db); + case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(da == db); + case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(da != db); + case '<': return new ScriptVar(da < db); + case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar(da <= db); + case '>': return new ScriptVar(da > db); + case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar(da >= db); + + default: throw new ScriptException("Operation not supported on the Int datatype"); + } + } + else + { + //doubles + double da = a.GetDouble(); + double db = b.GetDouble(); + + switch (opc) + { + case '+': return new ScriptVar(da + db); + case '-': return new ScriptVar(da - db); + case '*': return new ScriptVar(da * db); + case '/': return new ScriptVar(da / db); + case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(da == db); + case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(da != db); + case '<': return new ScriptVar(da < db); + case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar(da <= db); + case '>': return new ScriptVar(da > db); + case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar(da >= db); + + default: throw new ScriptException("Operation not supported on the Int datatype"); + } + } + } + + if (a.IsArray) + { + switch (op) + { + case ScriptLex.LexTypes.Equal: return new ScriptVar(a == b); + case ScriptLex.LexTypes.NEqual: return new ScriptVar(a != b); + + default: throw new ScriptException("Operation not supported on the Array datatype"); + } + } + + if (a.IsObject) + { + switch (op) + { + case ScriptLex.LexTypes.Equal: return new ScriptVar(a == b); + case ScriptLex.LexTypes.NEqual: return new ScriptVar(a != b); + + default: throw new ScriptException("Operation not supported on the Object datatype"); + } + } + + string sda = a.GetString(); + string sdb = b.GetString(); + + switch (opc) + { + case '+': return new ScriptVar(sda + sdb, Flags.String); + case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(sda == sdb); + case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(sda != sdb); + case '<': return new ScriptVar(String.CompareOrdinal(sda, sdb) < 0); + case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar((String.CompareOrdinal(sda, sdb) < 0) || sda == sdb); + case '>': return new ScriptVar(String.CompareOrdinal(sda, sdb) > 0); + case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar((String.CompareOrdinal(sda, sdb) > 0) || sda == sdb); + default: throw new ScriptException("Operation not supported on the String datatype"); + } + } + + protected void CopySimpleData(ScriptVar val) + { + data = val.data; + intData = val.intData; + doubleData = val.doubleData; + flags = (flags & ~Flags.VarTypeMask) | (val.flags & Flags.VarTypeMask); + } + + public void CopyValue(ScriptVar val) + { + if (val != null) + { + CopySimpleData(val); + RemoveAllChildren(); + + var link = val.FirstChild; + + while (link != null) + { + ScriptVar copied = link.Name != PrototypeClassName ? link.Var.DeepCopy() : link.Var; + + AddChild(link.Name, copied); + + link = link.Next; + } + } + else + { + SetUndefined(); + } + } + + public ScriptVar DeepCopy() + { + var newVar = new ScriptVar(); + newVar.CopySimpleData(this); + + var link = FirstChild; + while (link != null) + { + var copied = link.Name != PrototypeClassName ? link.Var.DeepCopy() : link.Var; + + newVar.AddChild(link.Name, copied); + + link = link.Next; + } + + return newVar; + } + + public void SetCallback(ScriptEngine.ScriptCallbackCB callback, object userdata) + { + this.callback = callback; + callbackUserData = userdata; + } + + public void Trace(int indent, string name) + { + System.Diagnostics.Trace.TraceInformation("{0}{1} = '{2}' ({3})", new string(' ', indent), name ?? "ROOT", GetString(), flags); + + var link = FirstChild; + while (link != null) + { + link.Var.Trace(indent + 2, link.Name); + link = link.Next; + } + } + + public static implicit operator string(ScriptVar d) + { + return d.GetString(); + } + + public override string ToString() + { + return string.Format("{0}", GetHashCode()); + } + + internal void SetData(object data) + { + this.data = data; + } + + internal ScriptEngine.ScriptCallbackCB GetCallback() + { + return callback; + } + + internal object GetCallbackUserData() + { + return callbackUserData; + } + + internal Type ClassType { get; set; } + internal object ClassInstance { get; set; } + + } +} diff --git a/DScript/ScriptVarLink.cs b/DScript/ScriptVarLink.cs new file mode 100644 index 0000000..732c6ee --- /dev/null +++ b/DScript/ScriptVarLink.cs @@ -0,0 +1,100 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + public class ScriptVarLink : IDisposable + { + #region IDisposable + private bool _disposed; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + Var.UnRef(); + } + + // Indicate that the instance has been disposed. + _disposed = true; + } + } + #endregion + + public string Name { get; private set; } + public ScriptVarLink Next { get; internal set; } + public ScriptVarLink Prev { get; internal set; } + public ScriptVar Var { get; internal set; } + public bool Owned { get; internal set; } + + public ScriptVarLink(ScriptVar var, String name) + { + Name = name; + Var = var.Ref(); + Next = null; + Prev = null; + Owned = false; + } + + public ScriptVarLink(ScriptVarLink toCopy) + { + Name = toCopy.Name; + Var = toCopy.Var.Ref(); + Next = toCopy.Next; + Prev = toCopy.Prev; + Owned = toCopy.Owned; + } + + public void ReplaceWith(ScriptVar newVar) + { + var oldVar = Var; + Var = newVar.Ref(); + oldVar.UnRef(); + } + + public void ReplaceWith(ScriptVarLink newVar) + { + ReplaceWith(newVar != null ? newVar.Var : new ScriptVar()); + } + + public int GetIntName() + { + int retVal = Convert.ToInt32(Name); + + return retVal; + } + + public void SetIntName(int n) + { + Name = string.Format("{0}", n); + } + } +} diff --git a/DScript/Utils.cs b/DScript/Utils.cs new file mode 100644 index 0000000..c8a270a --- /dev/null +++ b/DScript/Utils.cs @@ -0,0 +1,119 @@ +/* +Copyright (c) 2014 - 2020 Darren Horrocks + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +using System; + +namespace DScript +{ + internal static class Utils + { + public static bool IsWhitespace(this char ch) + { + return (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r'); + } + + public static bool IsNumeric(this char ch) + { + return (ch >= '0') && (ch <= '9'); + } + + public static bool IsNumber(this String str) + { + var c = str.Length; + for (var i = 0; i < c; i++) + { + if (!IsNumeric(str[i])) return false; + } + return true; + } + + public static bool IsHexadecimal(this char ch) + { + return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F')); + } + + public static bool IsAlpha(this char ch) + { + return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ch == '_'; + } + + public static bool IsIDString(this string str) + { + var c = str.Length; + for (var i = 0; i < c; i++) + { + if (IsNumeric(str[i]) || !IsAlpha(str[i])) return false; + } + return true; + } + + public static string GetJSString(this string str) + { + var oStr = str; + + for (var x = 0; x < oStr.Length; x++) + { + var replaceWith = ""; + bool replace = true; + switch (oStr[x]) + { + case '\\': + replaceWith = "\\\\"; + break; + case '\n': + replaceWith = "\\n"; + break; + case '\r': + replaceWith = "\\r"; + break; + case '\a': + replaceWith = "\\a"; + break; + case '"': + replaceWith = "\\\""; + break; + default: + { + var nCh = ((int)oStr[x]) & 0xFF; + if (nCh < 32 || nCh > 127) + { + replaceWith = string.Format("\\x{0:x2}", nCh); + } + else + { + replace = false; + } + } + break; + } + + if (replace) + { + oStr = oStr.Substring(0, x) + replaceWith + oStr.Substring(x + 1); + x += replaceWith.Length - 1; + } + } + + return string.Format("\"{0}\"", oStr); + } + } +} diff --git a/LICENSE b/LICENSE index a583e0d..eb0e672 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Darren Horrocks +Copyright (c) 2014 - 2020 Darren Horrocks Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/NuGet/spec.nuspec b/NuGet/spec.nuspec index b44f925..28a2786 100644 --- a/NuGet/spec.nuspec +++ b/NuGet/spec.nuspec @@ -1,17 +1,17 @@ - DScript - DScript Javascript based script engine - - Darren Horrocks - Darren Horrocks - https://github.com/bizzehdee/DScript/blob/master/LICENSE - https://github.com/bizzehdee/DScript - true - Open sourced object oriented JavaScript syntax based scripting language implemented in C# - - Copyright Darren Horrocks 2014 - scriptengine script engine language javascript + DScript + DScript Javascript based script engine + + Darren Horrocks + Darren Horrocks + https://github.com/bizzehdee/DScript/blob/master/LICENSE + https://github.com/bizzehdee/DScript + true + Open sourced object oriented JavaScript syntax based scripting language implemented in C# + + Copyright Darren Horrocks 2014 + scriptengine script engine language javascript \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs deleted file mode 100644 index a9a19ec..0000000 --- a/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DScript")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("DScript")] -[assembly: AssemblyCopyright("Copyright © Darren Horrocks 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("13291375-e3bc-4edf-921b-c76aba91f62b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ScriptEngine.Base.cs b/ScriptEngine.Base.cs deleted file mode 100644 index 67c5fc0..0000000 --- a/ScriptEngine.Base.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Base(ref bool execute) - { - ScriptVarLink a = Ternary(ref execute); - - if (_currentLexer.TokenType == (ScriptLex.LexTypes) '=' || - _currentLexer.TokenType == ScriptLex.LexTypes.PlusEqual || - _currentLexer.TokenType == ScriptLex.LexTypes.MinusEqual) - { - if (execute && a.Owned) - { - if (a.Name.Length > 0) - { - ScriptVarLink aReal = Root.AddChildNoDup(a.Name, a.Var); - a = aReal; - } - else - { - //?wtf? - System.Diagnostics.Trace.TraceWarning("Trying to assign to an unnamed type..."); - } - } - - - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(op); - - ScriptVarLink b = Base(ref execute); - - if (execute) - { - switch (op) - { - case (ScriptLex.LexTypes) '=': - a.ReplaceWith(b); - break; - case ScriptLex.LexTypes.PlusEqual: - { - ScriptVar res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes) '+'); - a.ReplaceWith(res); - } - break; - case ScriptLex.LexTypes.MinusEqual: - { - ScriptVar res = a.Var.MathsOp(b.Var, (ScriptLex.LexTypes) '-'); - a.ReplaceWith(res); - } - break; - default: - throw new ScriptException("Base broke"); - } - } - - } - - return a; - } - } -} diff --git a/ScriptEngine.Condition.cs b/ScriptEngine.Condition.cs deleted file mode 100644 index c8debb9..0000000 --- a/ScriptEngine.Condition.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Condition(ref bool execute) - { - ScriptVarLink a = Shift(ref execute); - - while (_currentLexer.TokenType == ScriptLex.LexTypes.Equal || - _currentLexer.TokenType == ScriptLex.LexTypes.NEqual || - _currentLexer.TokenType == ScriptLex.LexTypes.TypeEqual || - _currentLexer.TokenType == ScriptLex.LexTypes.NTypeEqual || - _currentLexer.TokenType == ScriptLex.LexTypes.LEqual || - _currentLexer.TokenType == ScriptLex.LexTypes.GEqual || - _currentLexer.TokenType == (ScriptLex.LexTypes)'>' || - _currentLexer.TokenType == (ScriptLex.LexTypes)'<' - ) - { - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(op); - ScriptVarLink b = Shift(ref execute); - - if (execute) - { - ScriptVar res = a.Var.MathsOp(b.Var, op); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - } - } - - return a; - } - } -} diff --git a/ScriptEngine.Expression.cs b/ScriptEngine.Expression.cs deleted file mode 100644 index 73e9f97..0000000 --- a/ScriptEngine.Expression.cs +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Expression(ref bool execute) - { - bool negate = false; - if (_currentLexer.TokenType == (ScriptLex.LexTypes) '-') - { - _currentLexer.Match((ScriptLex.LexTypes)'-'); - negate = true; - } - - ScriptVarLink a = Term(ref execute); - - if (negate) - { - ScriptVar zero = new ScriptVar(0); - ScriptVar res = zero.MathsOp(a.Var, (ScriptLex.LexTypes) '-'); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - } - - while (_currentLexer.TokenType == (ScriptLex.LexTypes) '+' || - _currentLexer.TokenType == (ScriptLex.LexTypes) '-' || - _currentLexer.TokenType == ScriptLex.LexTypes.PlusPlus || - _currentLexer.TokenType == ScriptLex.LexTypes.MinusMinus) - { - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(op); - - if (op == ScriptLex.LexTypes.PlusPlus || op == ScriptLex.LexTypes.MinusMinus) - { - if (execute) - { - ScriptVar one = new ScriptVar(1); - ScriptVar res = a.Var.MathsOp(one, (ScriptLex.LexTypes) (op == ScriptLex.LexTypes.PlusPlus ? '+' : '-')); - ScriptVarLink oldVal = new ScriptVarLink(a.Var, null); - - a.ReplaceWith(res); - a = oldVal; - } - } - else - { - ScriptVarLink b = Term(ref execute); - if (execute) - { - ScriptVar res = a.Var.MathsOp(b.Var, op); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - - } - } - } - - return a; - } - } -} diff --git a/ScriptEngine.Factor.cs b/ScriptEngine.Factor.cs deleted file mode 100644 index 796a4ef..0000000 --- a/ScriptEngine.Factor.cs +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Factor(ref bool execute) - { - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'(') - { - _currentLexer.Match((ScriptLex.LexTypes)'('); - ScriptVarLink a = Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)')'); - return a; - } - if (_currentLexer.TokenType == ScriptLex.LexTypes.RTrue) - { - _currentLexer.Match(ScriptLex.LexTypes.RTrue); - return new ScriptVarLink(new ScriptVar(1), null); - } - if (_currentLexer.TokenType == ScriptLex.LexTypes.RFalse) - { - _currentLexer.Match(ScriptLex.LexTypes.RTrue); - return new ScriptVarLink(new ScriptVar(0), null); - } - if (_currentLexer.TokenType == ScriptLex.LexTypes.RNull) - { - _currentLexer.Match(ScriptLex.LexTypes.RUndefined); - return new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Null), null); - } - if (_currentLexer.TokenType == ScriptLex.LexTypes.RUndefined) - { - _currentLexer.Match(ScriptLex.LexTypes.RUndefined); - return new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Undefined), null); - } - if (_currentLexer.TokenType == ScriptLex.LexTypes.Id) - { - ScriptVarLink a = execute ? FindInScopes(_currentLexer.TokenString) : new ScriptVarLink(new ScriptVar(), null); - - ScriptVar parent = null; - - if (execute && a == null) - { - a = new ScriptVarLink(new ScriptVar(), _currentLexer.TokenString); - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - - while (_currentLexer.TokenType == (ScriptLex.LexTypes)'(' || _currentLexer.TokenType == (ScriptLex.LexTypes)'.' || _currentLexer.TokenType == (ScriptLex.LexTypes)'[') - { - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'(') // function call - { - a = FunctionCall(ref execute, a, parent); - } - else if (_currentLexer.TokenType == (ScriptLex.LexTypes)'.') // child access - { - _currentLexer.Match((ScriptLex.LexTypes)'.'); - if (execute) - { - if (!a.Var.IsObject) - { - throw new ScriptException("Trying to call object member on non object type"); - } - - String name = _currentLexer.TokenString; - ScriptVarLink child = a.Var.FindChild(name); - - if (child == null) - { - child = FindInParentClasses(a.Var, name); - } - - if (child == null) - { - if (a.Var.IsArray && name == "length") - { - Int32 length = a.Var.GetArrayLength(); - child = new ScriptVarLink(new ScriptVar(length), null); - } - else if (a.Var.IsString && name == "length") - { - Int32 length = a.Var.GetString().Length; - child = new ScriptVarLink(new ScriptVar(length), null); - } - else - { - child = a.Var.AddChild(name, null); - } - } - - parent = a.Var; - a = child; - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - } - else if (_currentLexer.TokenType == (ScriptLex.LexTypes)'[') // array access - { - _currentLexer.Match((ScriptLex.LexTypes)'['); - ScriptVarLink index = Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)']'); - - if (execute) - { - ScriptVarLink child = a.Var.FindChildOrCreate(index.Var.GetString()); - parent = a.Var; - a = child; - } - } - else - { - throw new ScriptException("WTF?"); - } - } - - return a; - } - - if (_currentLexer.TokenType == ScriptLex.LexTypes.Int || _currentLexer.TokenType == ScriptLex.LexTypes.Float) - { - ScriptVar a = new ScriptVar(_currentLexer.TokenString, _currentLexer.TokenType == ScriptLex.LexTypes.Int ? ScriptVar.Flags.Integer : ScriptVar.Flags.Double); - _currentLexer.Match(_currentLexer.TokenType); - return new ScriptVarLink(a, null); - } - - if (_currentLexer.TokenType == ScriptLex.LexTypes.Str) - { - ScriptVar a = new ScriptVar(_currentLexer.TokenString, ScriptVar.Flags.String); - _currentLexer.Match(_currentLexer.TokenType); - return new ScriptVarLink(a, null); - } - - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'{') - { - ScriptVar contents = new ScriptVar(null, ScriptVar.Flags.Object); - //looking for JSON like objects - _currentLexer.Match((ScriptLex.LexTypes)'{'); - while (_currentLexer.TokenType != (ScriptLex.LexTypes)'}') - { - String id = _currentLexer.TokenString; - - if (_currentLexer.TokenType == ScriptLex.LexTypes.Str) - { - _currentLexer.Match(ScriptLex.LexTypes.Str); - } - else - { - _currentLexer.Match(ScriptLex.LexTypes.Id); - } - - _currentLexer.Match((ScriptLex.LexTypes)':'); - - if (execute) - { - ScriptVarLink a = Base(ref execute); - contents.AddChild(id, a.Var); - } - - if (_currentLexer.TokenType != (ScriptLex.LexTypes)'}') - { - _currentLexer.Match((ScriptLex.LexTypes)','); - } - } - _currentLexer.Match((ScriptLex.LexTypes)'}'); - - return new ScriptVarLink(contents, null); - } - - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'[') - { - Int32 idx = 0; - ScriptVar contents = new ScriptVar(null, ScriptVar.Flags.Array); - //looking for JSON like arrays - _currentLexer.Match((ScriptLex.LexTypes)'['); - while (_currentLexer.TokenType != (ScriptLex.LexTypes)']') - { - if (execute) - { - String id = String.Format("{0}", idx); - - ScriptVarLink a = Base(ref execute); - contents.AddChild(id, a.Var); - } - - if (_currentLexer.TokenType != (ScriptLex.LexTypes)']') - { - _currentLexer.Match((ScriptLex.LexTypes)','); - } - - idx++; - } - _currentLexer.Match((ScriptLex.LexTypes)']'); - - return new ScriptVarLink(contents, null); - } - - if (_currentLexer.TokenType == ScriptLex.LexTypes.RFunction) - { - ScriptVarLink funcVar = ParseFunctionDefinition(); - if (funcVar.Name != String.Empty) - { - System.Diagnostics.Trace.TraceWarning("Functions not defined at statement level are not supposed to have a name"); - } - return funcVar; - } - - if (_currentLexer.TokenType == ScriptLex.LexTypes.RNew) // new - { - _currentLexer.Match(ScriptLex.LexTypes.RNew); - - String className = _currentLexer.TokenString; - if (execute) - { - ScriptVarLink classOrFuncObject = FindInScopes(className); - if (classOrFuncObject == null) - { - System.Diagnostics.Trace.TraceWarning("{0} is not a valid class name", className); - return new ScriptVarLink(new ScriptVar(), null); - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - - ScriptVar obj = new ScriptVar(null, ScriptVar.Flags.Object); - ScriptVarLink objLink = new ScriptVarLink(obj, null); - - if (classOrFuncObject.Var.IsFunction) - { - FunctionCall(ref execute, classOrFuncObject, obj); - } - else - { - //creating new instance of a class - if (classOrFuncObject.Var.ClassType != null) - { - obj.ClassInstance = Activator.CreateInstance(classOrFuncObject.Var.ClassType); - } - - obj.AddChild(ScriptVar.PrototypeClassName, classOrFuncObject.Var); - - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'(') - { - _currentLexer.Match((ScriptLex.LexTypes)'('); - _currentLexer.Match((ScriptLex.LexTypes)')'); - } - } - - return objLink; - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'(') - { - _currentLexer.Match((ScriptLex.LexTypes)'('); - _currentLexer.Match((ScriptLex.LexTypes)')'); - } - } - - _currentLexer.Match(ScriptLex.LexTypes.Eof); - - return null; - } - } -} diff --git a/ScriptEngine.FunctionCall.cs b/ScriptEngine.FunctionCall.cs deleted file mode 100644 index 466b66f..0000000 --- a/ScriptEngine.FunctionCall.cs +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink FunctionCall(ref bool execute, ScriptVarLink function, ScriptVar parent) - { - if (execute) - { - if (!function.Var.IsFunction) - { - throw new ScriptException(String.Format("{0} is not a function", function.Name)); - } - - _currentLexer.Match((ScriptLex.LexTypes) '('); - ScriptVar functionRoot = new ScriptVar(null, ScriptVar.Flags.Function); - - if (parent != null) - { - functionRoot.AddChildNoDup("this", parent); - } - - ScriptVarLink v = function.Var.FirstChild; - while (v != null) - { - ScriptVarLink value = Base(ref execute); - if (value.Var.IsBasic) - { - //pass by val - functionRoot.AddChild(v.Name, value.Var.DeepCopy()); - } - else - { - //pass by ref - functionRoot.AddChild(v.Name, value.Var); - } - - if (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') - { - _currentLexer.Match((ScriptLex.LexTypes) ','); - } - - v = v.Next; - } - - _currentLexer.Match((ScriptLex.LexTypes) ')'); - - ScriptVarLink returnVarLink = functionRoot.AddChild(ScriptVar.ReturnVarName, null); - - _scopes.Push(functionRoot); - - _callStack.Push(String.Format("{0} from line {1}", function.Name, _currentLexer.LineNumber)); - - if (function.Var.IsNative) - { - ScriptCallbackCB func = function.Var.GetCallback(); - if (func != null) - { - func(functionRoot, function.Var.GetCallbackUserData(), parent); - } - } - else - { - ScriptException ex = null; - ScriptLex oldLex = _currentLexer; - ScriptLex newLex = new ScriptLex(function.Var.GetString()); - _currentLexer = newLex; - - try - { - Block(ref execute); - - execute = true; - } - catch (ScriptException e) - { - ex = e; - } - - _currentLexer = oldLex; - - if (ex != null) - { - throw ex; - } - } - - _callStack.Pop(); - _scopes.Pop(); - - ScriptVarLink returnVar = new ScriptVarLink(returnVarLink.Var, null); - functionRoot.RemoveLink(returnVarLink); - - return returnVar; - } - - //not executing the function, just parsing it out - _currentLexer.Match((ScriptLex.LexTypes)'('); - - while (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') - { - Base(ref execute); - - if (_currentLexer.TokenType != (ScriptLex.LexTypes) ')') - { - _currentLexer.Match((ScriptLex.LexTypes)','); - } - } - - _currentLexer.Match((ScriptLex.LexTypes)')'); - - if (_currentLexer.TokenType == (ScriptLex.LexTypes) '{') //WTF? - { - Block(ref execute); - } - - return function; - } - } -} diff --git a/ScriptEngine.Logic.cs b/ScriptEngine.Logic.cs deleted file mode 100644 index ab34c39..0000000 --- a/ScriptEngine.Logic.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Logic(ref bool execute) - { - ScriptVarLink a = Condition(ref execute); - - while (_currentLexer.TokenType == (ScriptLex.LexTypes) '&' || - _currentLexer.TokenType == (ScriptLex.LexTypes) '|' || - _currentLexer.TokenType == (ScriptLex.LexTypes) '^' || - _currentLexer.TokenType == ScriptLex.LexTypes.AndAnd || - _currentLexer.TokenType == ScriptLex.LexTypes.OrOr) - { - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(op); - - bool shortcut = false; - bool isBool = false; - - if (op == ScriptLex.LexTypes.AndAnd) - { - op = (ScriptLex.LexTypes)'&'; - shortcut = !a.Var.GetBool(); - isBool = true; - } - else if (op == ScriptLex.LexTypes.OrOr) - { - op = (ScriptLex.LexTypes)'|'; - shortcut = a.Var.GetBool(); - isBool = true; - } - - bool condition = !shortcut && execute; - ScriptVarLink b = Condition(ref condition); - - if (execute && !shortcut) - { - if (isBool) - { - ScriptVar newA = new ScriptVar(a.Var.GetBool()); - ScriptVar newB = new ScriptVar(b.Var.GetBool()); - - if (a.Owned) - { - a = new ScriptVarLink(newA, null); - } - else - { - a.ReplaceWith(newA); - } - - if (b.Owned) - { - b = new ScriptVarLink(newB, null); - } - else - { - b.ReplaceWith(newA); - } - } - - ScriptVar res = a.Var.MathsOp(b.Var, op); - - if (a.Owned) - { - a = new ScriptVarLink(res, null); - } - else - { - a.ReplaceWith(res); - } - } - } - - return a; - } - } -} diff --git a/ScriptEngine.Shift.cs b/ScriptEngine.Shift.cs deleted file mode 100644 index da5d2ac..0000000 --- a/ScriptEngine.Shift.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Shift(ref bool execute) - { - ScriptVarLink a = Expression(ref execute); - - if (_currentLexer.TokenType == ScriptLex.LexTypes.LShift || - _currentLexer.TokenType == ScriptLex.LexTypes.RShift || - _currentLexer.TokenType == ScriptLex.LexTypes.RShiftUnsigned) - { - ScriptLex.LexTypes op = _currentLexer.TokenType; - _currentLexer.Match(op); - ScriptVarLink b = Base(ref execute); - - Int32 shift = execute ? b.Var.GetInt() : 0; - - if (execute) - { - if (op == ScriptLex.LexTypes.LShift) - { - a.Var.SetInt(a.Var.GetInt() << shift); - } - - if (op == ScriptLex.LexTypes.RShift) - { - a.Var.SetInt(a.Var.GetInt() >> shift); - } - - if (op == ScriptLex.LexTypes.RShiftUnsigned) - { - a.Var.SetInt((int)(((uint)a.Var.GetInt()) >> shift)); - } - } - } - - return a; - } - } -} diff --git a/ScriptEngine.Statement.cs b/ScriptEngine.Statement.cs deleted file mode 100644 index 6e99bc3..0000000 --- a/ScriptEngine.Statement.cs +++ /dev/null @@ -1,305 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public partial class ScriptEngine - { - private void Statement(ref bool execute) - { - if (_currentLexer.TokenType == ScriptLex.LexTypes.Id || - _currentLexer.TokenType == ScriptLex.LexTypes.Int || - _currentLexer.TokenType == ScriptLex.LexTypes.Float || - _currentLexer.TokenType == ScriptLex.LexTypes.Str || - _currentLexer.TokenType == (ScriptLex.LexTypes) '-') - { - //execite a basic statement - Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)';'); - } - else if (_currentLexer.TokenType == (ScriptLex.LexTypes)'{') - { - //code block - Block(ref execute); - } - else if (_currentLexer.TokenType == (ScriptLex.LexTypes)';') - { - //allow for multiple semi colon such as ;;; - _currentLexer.Match((ScriptLex.LexTypes)';'); - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RVar) - { - //creating variables - //TODO: make this less shit - - _currentLexer.Match(ScriptLex.LexTypes.RVar); - - while (_currentLexer.TokenType != (ScriptLex.LexTypes) ';') - { - ScriptVarLink a = null; - if (execute) - { - a = _scopes.Peek().FindChildOrCreate(_currentLexer.TokenString); - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - - //get through the dots - while (_currentLexer.TokenType == (ScriptLex.LexTypes)'.') - { - _currentLexer.Match((ScriptLex.LexTypes)'.'); - if (execute) - { - ScriptVarLink aLast = a; - if (aLast != null) - { - a = aLast.Var.FindChildOrCreate(_currentLexer.TokenString); - } - } - - _currentLexer.Match(ScriptLex.LexTypes.Id); - } - - //initialiser - if (_currentLexer.TokenType == (ScriptLex.LexTypes)'=') - { - _currentLexer.Match((ScriptLex.LexTypes)'='); - ScriptVarLink varLink = Base(ref execute); - if (execute) - { - if (a != null) - { - a.ReplaceWith(varLink); - } - } - } - - if (_currentLexer.TokenType != (ScriptLex.LexTypes)';') - { - _currentLexer.Match((ScriptLex.LexTypes)','); - } - } - - _currentLexer.Match((ScriptLex.LexTypes)';'); - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RIf) - { - //if condition - _currentLexer.Match(ScriptLex.LexTypes.RIf); - _currentLexer.Match((ScriptLex.LexTypes)'('); - ScriptVarLink varLink = Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)')'); - - bool condition = execute && varLink.Var.GetBool(); - bool noExecute = false; - if (condition) - { - Statement(ref execute); - } - else - { - Statement(ref noExecute); - } - - if (_currentLexer.TokenType == ScriptLex.LexTypes.RElse) - { - //else part of an if - _currentLexer.Match(ScriptLex.LexTypes.RElse); - - if (condition) - { - Statement(ref noExecute); - } - else - { - Statement(ref execute); - } - } - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RWhile) - { - //while loop - _currentLexer.Match(ScriptLex.LexTypes.RWhile); - _currentLexer.Match((ScriptLex.LexTypes)'('); - - Int32 whileConditionStart = _currentLexer.TokenStart; - ScriptVarLink condition = Base(ref execute); - bool loopCondition = execute && condition.Var.GetBool(); - - ScriptLex whileCond = _currentLexer.GetSubLex(whileConditionStart); - _currentLexer.Match((ScriptLex.LexTypes)')'); - - Int32 whileBodyStart = _currentLexer.TokenStart; - - Statement(ref loopCondition); - - ScriptLex whileBody = _currentLexer.GetSubLex(whileBodyStart); - ScriptLex oldLex = _currentLexer; - - //TODO: possible maximum itteration limit? - while (loopCondition) - { - whileCond.Reset(); - - _currentLexer = whileCond; - - condition = Base(ref execute); - - loopCondition = condition.Var.GetBool(); - - if (loopCondition) - { - whileBody.Reset(); - _currentLexer = whileBody; - Statement(ref execute); - } - } - - _currentLexer = oldLex; - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFor) - { - //for loop - _currentLexer.Match(ScriptLex.LexTypes.RFor); - _currentLexer.Match((ScriptLex.LexTypes)'('); - - Statement(ref execute); //init - - int forConditionStart = _currentLexer.TokenStart; - ScriptVarLink condition = Base(ref execute); - bool noExecute = false; - bool loopCondition = execute && condition.Var.GetBool(); - - ScriptLex forCondition = _currentLexer.GetSubLex(forConditionStart); - - _currentLexer.Match((ScriptLex.LexTypes)';'); - - int forIterStart = _currentLexer.TokenStart; - - Base(ref noExecute); - - ScriptLex forIter = _currentLexer.GetSubLex(forIterStart); - - _currentLexer.Match((ScriptLex.LexTypes)')'); - - int forBodyStart = _currentLexer.TokenStart; - - if (loopCondition) - { - Statement(ref execute); - } - else - { - Statement(ref noExecute); - } - - ScriptLex forBody = _currentLexer.GetSubLex(forBodyStart); - ScriptLex oldLex = _currentLexer; - if (loopCondition) - { - forIter.Reset(); - _currentLexer = forIter; - - Base(ref execute); - } - - //TODO: limit number of iterations? - while (execute && loopCondition) - { - forCondition.Reset(); - _currentLexer = forCondition; - - condition = Base(ref execute); - - loopCondition = condition.Var.GetBool(); - - if (execute && loopCondition) - { - forBody.Reset(); - _currentLexer = forBody; - - Statement(ref execute); - } - - if (execute && loopCondition) - { - forIter.Reset(); - _currentLexer = forIter; - - Base(ref execute); - } - } - - _currentLexer = oldLex; - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RReturn) - { - _currentLexer.Match(ScriptLex.LexTypes.RReturn); - - ScriptVarLink res = null; - if (_currentLexer.TokenType != (ScriptLex.LexTypes)';') - { - res = Base(ref execute); - } - if (execute) - { - ScriptVarLink resultVar = _scopes.Peek().FindChild(ScriptVar.ReturnVarName); - if (resultVar != null) - { - resultVar.ReplaceWith(res); - } - else - { - //return statement outside of function??? - System.Diagnostics.Trace.TraceWarning("Return statement outside of a function, what is going on?"); - } - } - - execute = false; - _currentLexer.Match((ScriptLex.LexTypes)';'); - } - else if (_currentLexer.TokenType == ScriptLex.LexTypes.RFunction) - { - //function - ScriptVarLink funcVar = ParseFunctionDefinition(); - if (execute) - { - if (funcVar.Name == String.Empty) - { - //functions must have a name at statement level - } - else - { - ScriptVar v = _scopes.Peek(); - v.AddChildNoDup(funcVar.Name, funcVar.Var); - } - } - } - else - { - _currentLexer.Match(ScriptLex.LexTypes.Eof); - } - } - } -} diff --git a/ScriptEngine.Ternary.cs b/ScriptEngine.Ternary.cs deleted file mode 100644 index 404e045..0000000 --- a/ScriptEngine.Ternary.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace DScript -{ - public partial class ScriptEngine - { - private ScriptVarLink Ternary(ref bool execute) - { - ScriptVarLink a = Logic(ref execute); - - if (_currentLexer.TokenType == (ScriptLex.LexTypes) '?') - { - _currentLexer.Match((ScriptLex.LexTypes)'?'); - - if (!execute) - { - Base(ref execute); - - _currentLexer.Match((ScriptLex.LexTypes)':'); - - Base(ref execute); - } - else - { - bool first = a.Var.GetBool(); - - if (first) - { - a = Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)':'); - Base(ref execute); - } - else - { - Base(ref execute); - _currentLexer.Match((ScriptLex.LexTypes)':'); - a = Base(ref execute); - } - } - } - - return a; - } - } -} diff --git a/ScriptEngine.cs b/ScriptEngine.cs deleted file mode 100644 index 0bae20a..0000000 --- a/ScriptEngine.cs +++ /dev/null @@ -1,546 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace DScript -{ - public partial class ScriptEngine : IDisposable - { - #region IDisposable - private bool _disposed; - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - _stringClass.UnRef(); - _arrayClass.UnRef(); - _objectClass.UnRef(); - Root.UnRef(); - - if (_currentLexer != null) - { - _currentLexer.Dispose(); - } - } - - // Indicate that the instance has been disposed. - _disposed = true; - } - } - #endregion - - private readonly ScriptVar _stringClass; - private readonly ScriptVar _objectClass; - private readonly ScriptVar _arrayClass; - private Stack _scopes; - private readonly Stack _callStack; - - private ScriptLex _currentLexer; - - public delegate void ScriptCallbackCB(ScriptVar var, object userdata, ScriptVar parent = null); - - public ScriptVar Root { get; private set; } - - public ScriptEngine(bool loadProviders = true) - { - _currentLexer = null; - - _scopes = new Stack(); - _callStack = new Stack(); - - Root = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); - - _stringClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); - _objectClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); - _arrayClass = (new ScriptVar(null, ScriptVar.Flags.Object)).Ref(); - - Root.AddChild("String", _stringClass); - Root.AddChild("Object", _objectClass); - Root.AddChild("Array", _arrayClass); - - if (loadProviders) - { - LoadAllFunctionProviders(); - } - } - - public void Trace() - { - Root.Trace(0, null); - } - - public void Execute(String code) - { - ScriptLex oldLex = _currentLexer; - Stack oldScopes = _scopes; - - using (_currentLexer = new ScriptLex(code)) - { - _scopes.Clear(); - _scopes.Push(Root); - _callStack.Clear(); - - try - { - while (_currentLexer.TokenType != 0) - { - bool execute = true; - Statement(ref execute); - } - } - catch (ScriptException ex) - { - String errorMessage = String.Format("ERROR on line {0} column {1} [{2}]", _currentLexer.LineNumber, _currentLexer.ColumnNumber, ex.Message); - - int i = 0; - foreach (ScriptVar scriptVar in _scopes) - { - errorMessage += "\n" + i++ + ": " + scriptVar; - } - - Console.Write(errorMessage); - } - } - - _currentLexer = oldLex; - _scopes = oldScopes; - } - - public ScriptVarLink EvalComplex(String code) - { - ScriptLex oldLex = _currentLexer; - Stack oldScopes = _scopes; - - _currentLexer = new ScriptLex(code); - - _callStack.Clear(); - _scopes.Clear(); - _scopes.Push(Root); - - ScriptVarLink v = null; - - try - { - bool execute = true; - do - { - v = Base(ref execute); - if (_currentLexer.TokenType != ScriptLex.LexTypes.Eof) - { - _currentLexer.Match((ScriptLex.LexTypes) ';'); - } - } while (_currentLexer.TokenType != ScriptLex.LexTypes.Eof); - } - catch (ScriptException ex) - { - String errorMessage = ex.Message; - int i = 0; - foreach (ScriptVar scriptVar in _scopes) - { - errorMessage += "\n" + i++ + ": " + scriptVar; - } - - Console.Write(errorMessage); - } - - _currentLexer = oldLex; - _scopes = oldScopes; - - if (v != null) - { - return v; - } - - return new ScriptVarLink(new ScriptVar(null), null); - } - - public void AddObject(String[] ns, String objectName, ScriptVar val) - { - ScriptVar baseVar = Root; - - if (ns != null) - { - int x = 0; - for (; x < ns.Length; x++) - { - ScriptVarLink link = baseVar.FindChild(ns[x]); - - if (link == null) - { - link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); - } - - baseVar = link.Var; - } - } - - baseVar.AddChild(objectName, val); - } - - public void AddMethod(String[] ns, String funcName, String[] args, ScriptCallbackCB callback, Object userdata) - { - String fName = funcName; - ScriptVar baseVar = Root; - - if (ns != null) - { - int x = 0; - for (; x < ns.Length; x++) - { - ScriptVarLink link = baseVar.FindChild(ns[x]); - - if (link == null) - { - link = baseVar.AddChild(ns[x], new ScriptVar(null, ScriptVar.Flags.Object)); - } - - baseVar = link.Var; - } - } - - - ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); - funcVar.SetCallback(callback, userdata); - - //do we have any arguments to create? - if (args != null) - { - foreach (string arg in args) - { - funcVar.AddChildNoDup(arg, null); - } - } - - baseVar.AddChild(fName, funcVar); - } - - public void AddMethod(String funcName, String[] args, ScriptCallbackCB callback, Object userdata) - { - ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); - funcVar.SetCallback(callback, userdata); - - //do we have any arguments to create? - if (args != null) - { - foreach (string arg in args) - { - funcVar.AddChildNoDup(arg, null); - } - } - - Root.AddChild(funcName, funcVar); - } - - public void LoadAllFunctionProviders() - { - Assembly execAssembly = Assembly.GetExecutingAssembly(); - - TestForAttribute(execAssembly); - - AssemblyName[] referencedAssemblies = execAssembly.GetReferencedAssemblies(); - foreach (AssemblyName assembly in referencedAssemblies) - { - Assembly asm = Assembly.Load(assembly); - - TestForAttribute(asm); - } - } - - private void TestForAttribute(Assembly asm) - { - Type[] types = asm.GetTypes(); - foreach (Type type in types) - { - object[] scObjects = type.GetCustomAttributes(typeof(ScriptClassAttribute), false); - if (scObjects.Length > 0) - { - ProcessType(type, scObjects[0] as ScriptClassAttribute); - } - } - } - - private void ProcessType(Type type, ScriptClassAttribute attr) - { - AddObject(attr.Namespace ?? new string[0], attr.ClassName ?? type.Name, new ScriptVar(null, ScriptVar.Flags.Object | ScriptVar.Flags.Native) { ClassType = type }); - - MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); - ProcessMethods(methods, attr); - - methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); - ProcessMethods(methods, attr); - - PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); - //ProcessProperties(properties, attr, Activator.CreateInstance(type)); - - properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static); - ProcessProperties(properties, attr, null); - } - - private void ProcessMethods(MethodInfo[] methods, ScriptClassAttribute attr) - { - foreach (MethodInfo method in methods) - { - if (method.IsSpecialName) continue; - - ParameterInfo[] parameters = method.GetParameters(); - if (parameters.Length < 1) continue; - - String[] argNames = new string[parameters.Length - 1]; - for (int i = 0; i < parameters.Length - 1; i++) - { - argNames[i] = parameters[i].Name; - } - - MethodInfo methodCopy = method; - String[] ns = attr.Namespace ?? new string[0]; - - if (attr.ClassName == null && ns.Length == 0) - { - ns = null; - } - else - { - Array.Resize(ref ns, ns.Length + 1); - ns[ns.Length - 1] = attr.ClassName; - } - - AddMethod(ns, method.Name, argNames, CreateScriptFunction(methodCopy, parameters), this); - } - } - - private void ProcessProperties(PropertyInfo[] properties, ScriptClassAttribute attr, object instance) - { - foreach (PropertyInfo property in properties) - { - if (property.IsSpecialName) continue; - - PropertyInfo propertyCopy = property; - String[] ns = attr.Namespace ?? new string[0]; - - if (attr.ClassName == null && ns.Length == 0) - { - ns = null; - } - else - { - Array.Resize(ref ns, ns.Length + 1); - ns[ns.Length - 1] = attr.ClassName; - } - - if (property.PropertyType == typeof(bool)) - { - AddObject(ns, property.Name, new ScriptVar((bool)property.GetValue(instance, null))); - } - else if (property.PropertyType == typeof(string)) - { - AddObject(ns, property.Name, new ScriptVar((string)property.GetValue(instance, null))); - } - else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(float) || property.PropertyType == typeof(double)) - { - AddObject(ns, property.Name, new ScriptVar((double)property.GetValue(instance, null))); - } - else if (property.PropertyType == typeof(Int32)) - { - AddObject(ns, property.Name, new ScriptVar((Int32)property.GetValue(instance, null))); - } - } - } - - private ScriptCallbackCB CreateScriptFunction(MethodInfo method, ParameterInfo[] parameters) - { - return delegate(ScriptVar var, object userdata, ScriptVar parent) - { - object[] args = new object[parameters.Length]; - - int i = 0; - for (; i < parameters.Length - 1; i++) - { - args[i] = var.GetParameter(parameters[i].Name).GetData(); - } - - args[i] = userdata; - - object returnVal; - - if (method.IsStatic) - { - returnVal = method.Invoke(null, args); - } - else - { - returnVal = method.Invoke(parent.ClassInstance, args); - } - - if (method.ReturnType == typeof (Int32)) - { - var.SetReturnVar(new ScriptVar(Convert.ToInt32(returnVal), ScriptVar.Flags.Integer)); - } - else if (method.ReturnType == typeof (bool)) - { - var.SetReturnVar(new ScriptVar(Convert.ToBoolean(returnVal) ? 1 : 0, ScriptVar.Flags.Integer)); - } - else if (method.ReturnType == typeof (double) || method.ReturnType == typeof(float)) - { - var.SetReturnVar(new ScriptVar(Convert.ToDouble(returnVal), ScriptVar.Flags.Double)); - } - else if (method.ReturnType == typeof (String)) - { - var.SetReturnVar(new ScriptVar(Convert.ToString(returnVal), ScriptVar.Flags.String)); - } - }; - } - - [Obsolete("Do not use, this is the old way of binding native methods to language functions")] - public void AddMethod(String funcProto, ScriptCallbackCB callback, Object userdata) - { - ScriptLex oldLex = _currentLexer; - - using (_currentLexer = new ScriptLex(funcProto)) - { - ScriptVar baseVar = Root; - - _currentLexer.Match(ScriptLex.LexTypes.RFunction); - String funcName = _currentLexer.TokenString; - _currentLexer.Match(ScriptLex.LexTypes.Id); - - while (_currentLexer.TokenType == (ScriptLex.LexTypes) '.') - { - _currentLexer.Match((ScriptLex.LexTypes) '.'); - ScriptVarLink link = baseVar.FindChild(funcName); - - if (link == null) - { - link = baseVar.AddChild(funcName, new ScriptVar(null, ScriptVar.Flags.Object)); - } - - baseVar = link.Var; - funcName = _currentLexer.TokenString; - _currentLexer.Match(ScriptLex.LexTypes.Id); - } - - ScriptVar funcVar = new ScriptVar(null, ScriptVar.Flags.Function | ScriptVar.Flags.Native); - funcVar.SetCallback(callback, userdata); - - ParseFunctionArguments(funcVar); - - baseVar.AddChild(funcName, funcVar); - } - - _currentLexer = oldLex; - } - - private ScriptVarLink FindInScopes(String name) - { - foreach (ScriptVar scriptVar in _scopes) - { - ScriptVarLink a = scriptVar.FindChild(name); - if (a != null) - { - return a; - } - } - - return null; - } - - private ScriptVarLink FindInParentClasses(ScriptVar obj, String name) - { - ScriptVarLink implementation; - ScriptVarLink parentClass = obj.FindChild(ScriptVar.PrototypeClassName); - - while (parentClass != null) - { - implementation = parentClass.Var.FindChild(name); - if (implementation != null) return implementation; - parentClass = parentClass.Var.FindChild(ScriptVar.PrototypeClassName); - } - - if (obj.IsString) - { - implementation = _stringClass.FindChild(name); - if (implementation != null) return implementation; - } - - if (obj.IsArray) - { - implementation = _arrayClass.FindChild(name); - if (implementation != null) return implementation; - } - - implementation = _objectClass.FindChild(name); - if (implementation != null) return implementation; - - return null; - } - - private ScriptVarLink ParseFunctionDefinition() - { - _currentLexer.Match(ScriptLex.LexTypes.RFunction); - String funcName = String.Empty; - - //named function - if (_currentLexer.TokenType == ScriptLex.LexTypes.Id) - { - funcName = _currentLexer.TokenString; - _currentLexer.Match(ScriptLex.LexTypes.Id); - } - - ScriptVarLink funcVar = new ScriptVarLink(new ScriptVar(null, ScriptVar.Flags.Function), funcName); - ParseFunctionArguments(funcVar.Var); - - Int32 funcBegin = _currentLexer.TokenStart; - bool execute = false; - Block(ref execute); - funcVar.Var.SetData(_currentLexer.GetSubString(funcBegin)); - - return funcVar; - } - - private void ParseFunctionArguments(ScriptVar funcVar) - { - _currentLexer.Match((ScriptLex.LexTypes)'('); - while (_currentLexer.TokenType != (ScriptLex.LexTypes)')') - { - funcVar.AddChildNoDup(_currentLexer.TokenString, null); - _currentLexer.Match(ScriptLex.LexTypes.Id); - - if (_currentLexer.TokenType != (ScriptLex.LexTypes)')') - { - _currentLexer.Match((ScriptLex.LexTypes)','); - } - } - - _currentLexer.Match((ScriptLex.LexTypes)')'); - } - } -} diff --git a/ScriptLex.cs b/ScriptLex.cs deleted file mode 100644 index 485e40d..0000000 --- a/ScriptLex.cs +++ /dev/null @@ -1,567 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public class ScriptLex : IDisposable - { - #region IDisposable - private bool _disposed; - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - if (_dataOwned) - { - _data = string.Empty; - } - } - - // Indicate that the instance has been disposed. - _disposed = true; - } - } - #endregion - - private String _data; - private readonly bool _dataOwned; - private readonly Int32 _dataStart; - private readonly Int32 _dataEnd; - private Int32 _dataPos; - private Int32 _currColumnNumber; - - public char CurrentChar { get; set; } - public char NextChar { get; set; } - public LexTypes TokenType { get; set; } - public Int32 TokenStart { get; set; } - public Int32 TokenEnd { get; set; } - public Int32 TokenLastEnd { get; set; } - public Int32 LineNumber { get; private set; } - public int ColumnNumber { get; private set; } - public String TokenString { get; set; } - - public enum LexTypes - { - Eof = 0, - Id = 256, - Int, - Float, - Str, - Equal, - TypeEqual, - NEqual, - NTypeEqual, - LEqual, - LShift, - LShiftEqual, - GEqual, - RShift, - RShiftUnsigned, - RShiftEqual, - PlusEqual, - MinusEqual, - PlusPlus, - MinusMinus, - AndEqual, - AndAnd, - OrEqual, - OrOr, - XorEqual, - RListStart, - RIf = RListStart, - RElse, - RDo, - RWhile, - RFor, - RBreak, - RContinue, - RFunction, - RReturn, - RVar, - RTrue, - RFalse, - RNull, - RUndefined, - RNew, - RListEnd - } - - public ScriptLex(String input) - { - _data = input; - _dataOwned = true; - _dataStart = 0; - _dataEnd = _data.Length; - - Reset(); - } - - public ScriptLex(ScriptLex owner, Int32 start, Int32 end) - { - _data = owner._data; - _dataOwned = false; - _dataStart = start; - _dataEnd = end; - - Reset(); - } - - public void Reset() - { - _dataPos = _dataStart; - TokenStart = 0; - TokenEnd = 0; - TokenLastEnd = 0; - TokenType = 0; - TokenString = ""; - - GetNextChar(); - GetNextChar(); - GetNextToken(); - } - - public void GetNextChar() - { - CurrentChar = NextChar; - - if (_dataPos < _dataEnd) - { - NextChar = _data[_dataPos]; - } - else - { - NextChar = (char)0; - } - - _dataPos++; - - _currColumnNumber++; - - if(CurrentChar == '\n') - { - LineNumber++; - _currColumnNumber = 0; - } - } - - public void GetNextToken() - { - ColumnNumber = _currColumnNumber; - - TokenType = LexTypes.Eof; - TokenString = String.Empty; - - while (CurrentChar != (char)0 && CurrentChar.IsWhitespace()) - { - GetNextChar(); - } - - //single line comment - if (CurrentChar == '/' && NextChar == '/') - { - while (CurrentChar != 0 && CurrentChar != '\n') GetNextChar(); - GetNextChar(); - GetNextToken(); - return; - } - - //multi line comment - if (CurrentChar == '/' && NextChar == '*') - { - while (CurrentChar != '*' && CurrentChar != '/') GetNextChar(); - GetNextChar(); - GetNextChar(); - GetNextToken(); - return; - } - - TokenStart = _dataPos - 2; - - if (CurrentChar.IsAlpha()) //IDs - { - while (CurrentChar.IsAlpha() || CurrentChar.IsNumeric()) - { - TokenString += CurrentChar; - GetNextChar(); - } - - TokenType = LexTypes.Id; - switch (TokenString) - { - case "if": TokenType = LexTypes.RIf; break; - case "else": TokenType = LexTypes.RElse; break; - case "do": TokenType = LexTypes.RDo; break; - case "while": TokenType = LexTypes.RWhile; break; - case "for": TokenType = LexTypes.RFor; break; - case "break": TokenType = LexTypes.RBreak; break; - case "continue": TokenType = LexTypes.RContinue; break; - case "function": TokenType = LexTypes.RFunction; break; - case "return": TokenType = LexTypes.RReturn; break; - case "var": TokenType = LexTypes.RVar; break; - case "true": TokenType = LexTypes.RTrue; break; - case "false": TokenType = LexTypes.RFalse; break; - case "null": TokenType = LexTypes.RFalse; break; - case "undefined": TokenType = LexTypes.RNull; break; - case "new": TokenType = LexTypes.RNew; break; - - } - } - else if (CurrentChar.IsNumeric()) //Numbers - { - bool isHex = false; - if (CurrentChar == '0') - { - TokenString += CurrentChar; - GetNextChar(); - } - - if (CurrentChar == 'x') - { - isHex = true; - TokenString += CurrentChar; - GetNextChar(); - } - - TokenType = LexTypes.Int; - - while (CurrentChar.IsNumeric() || (isHex && CurrentChar.IsHexadecimal())) - { - TokenString += CurrentChar; - GetNextChar(); - } - - if (!isHex && CurrentChar == '.') - { - TokenType = LexTypes.Float; - TokenString += '.'; - GetNextChar(); - while (CurrentChar.IsNumeric()) - { - TokenString += CurrentChar; - GetNextChar(); - } - } - - if (!isHex && (CurrentChar == 'e' || CurrentChar == 'E')) - { - TokenType = LexTypes.Float; - TokenString += CurrentChar; - GetNextChar(); - if (CurrentChar == '-') - { - TokenString += CurrentChar; - GetNextChar(); - } - while (CurrentChar.IsNumeric()) - { - TokenString += CurrentChar; - GetNextChar(); - } - } - } - else if (CurrentChar == '"') //Strings - { - GetNextChar(); - while (CurrentChar != (char) 0 && CurrentChar != '"') - { - if (CurrentChar == '\\') - { - GetNextChar(); - switch (CurrentChar) - { - case 'n': - TokenString += '\n'; - break; - case '"': - TokenString += '"'; - break; - case '\\': - TokenString += '\\'; - break; - default: - TokenString += CurrentChar; - break; - } - } - else - { - TokenString += CurrentChar; - } - - GetNextChar(); - } - - GetNextChar(); - - TokenType = LexTypes.Str; - } - else if (CurrentChar == '\'') //Strings again - { - GetNextChar(); - - while (CurrentChar != (char) 0 && CurrentChar != '\'') - { - if (CurrentChar == '\\') - { - GetNextChar(); - - switch (CurrentChar) - { - case 'n': - TokenString += '\n'; - break; - case 'a': - TokenString += '\a'; - break; - case 'r': - TokenString += '\r'; - break; - case 't': - TokenString += '\t'; - break; - case '\'': - TokenString += '\''; - break; - case '\\': - TokenString += '\\'; - break; - case 'x': - { - String str = ""; - GetNextChar(); - str += CurrentChar; - GetNextChar(); - str += CurrentChar; - TokenString += (char) Convert.ToInt64(str); - } - break; - default: - if (CurrentChar >= '0' && CurrentChar <= '7') - { - String str = ""; - str += CurrentChar; - GetNextChar(); - str += CurrentChar; - GetNextChar(); - str += CurrentChar; - TokenString += (char) Convert.ToInt64(str); - } - else - { - TokenString += CurrentChar; - } - break; - } - } - else - { - TokenString += CurrentChar; - } - - GetNextChar(); - } - - GetNextChar(); - - TokenType = LexTypes.Str; - } - else //Single character - { - TokenType = (LexTypes) CurrentChar; - - if (CurrentChar != (char) 0) - { - GetNextChar(); - } - - if (TokenType == (LexTypes)'=' && CurrentChar == '=') // == - { - TokenType = LexTypes.Equal; - GetNextChar(); - - if (CurrentChar == '=') //=== - { - TokenType = LexTypes.TypeEqual; - GetNextChar(); - } - } - else if (TokenType == (LexTypes)'!' && CurrentChar == '=') // != - { - TokenType = LexTypes.NEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'<' && CurrentChar == '=') // <= - { - TokenType = LexTypes.LEqual; - GetNextChar(); - - if (CurrentChar == '=') //!== - { - TokenType = LexTypes.NTypeEqual; - GetNextChar(); - } - } - else if (TokenType == (LexTypes)'<' && CurrentChar == '<') // << - { - TokenType = LexTypes.LShift; - GetNextChar(); - if (CurrentChar == '=') //<<= - { - TokenType = LexTypes.LShiftEqual; - GetNextChar(); - } - } - else if (TokenType == (LexTypes)'>' && CurrentChar == '=') // >= - { - TokenType = LexTypes.GEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'>' && CurrentChar == '>') // >> - { - TokenType = LexTypes.RShift; - GetNextChar(); - - if (CurrentChar == '=') // >>= - { - TokenType = LexTypes.RShiftEqual; - GetNextChar(); - } - else if (CurrentChar == '>') // >>> - { - TokenType = LexTypes.RShiftUnsigned; - GetNextChar(); - } - } - else if (TokenType == (LexTypes)'+' && CurrentChar == '=') // += - { - TokenType = LexTypes.PlusEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'-' && CurrentChar == '=') // -= - { - TokenType = LexTypes.MinusEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'+' && CurrentChar == '+') // ++ - { - TokenType = LexTypes.PlusPlus; - GetNextChar(); - } - else if (TokenType == (LexTypes)'-' && CurrentChar == '-') // -- - { - TokenType = LexTypes.MinusMinus; - GetNextChar(); - } - else if (TokenType == (LexTypes)'&' && CurrentChar == '=') // &= - { - TokenType = LexTypes.AndEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'&' && CurrentChar == '&') // && - { - TokenType = LexTypes.AndAnd; - GetNextChar(); - } - else if (TokenType == (LexTypes)'|' && CurrentChar == '=') // |= - { - TokenType = LexTypes.OrEqual; - GetNextChar(); - } - else if (TokenType == (LexTypes)'|' && CurrentChar == '|') // || - { - TokenType = LexTypes.OrOr; - GetNextChar(); - } - else if (TokenType == (LexTypes)'^' && CurrentChar == '=') // ^= - { - TokenType = LexTypes.XorEqual; - GetNextChar(); - } - } - - /* Something broke... */ - TokenLastEnd = TokenEnd; - TokenEnd = _dataPos - 3; - } - - public ScriptLex GetSubLex(Int32 lastPosition) - { - int lastCharIdx = TokenLastEnd + 1; - - if (lastCharIdx < _dataEnd) - { - return new ScriptLex(this, lastPosition, lastCharIdx); - } - - return new ScriptLex(this, lastPosition, _dataEnd); - } - - public String GetPosition(Int32 pos) - { - return String.Format("{0}", pos); - } - - public String GetSubString(Int32 pos) - { - Int32 lastCharIndex = TokenLastEnd + 1; - - if (lastCharIndex < _dataEnd) - { - return _data.Substring(pos, lastCharIndex - pos); - } - - return (_data.Substring(pos)); - } - - public void Match(LexTypes type) - { - if(TokenType != type) - { - String expectedName = Enum.GetName(typeof(LexTypes), type); - if(String.IsNullOrEmpty(expectedName)) - { - expectedName = String.Format("{0}", ((char)type)); - } - - String foundName = Enum.GetName(typeof(LexTypes), TokenType); - if(String.IsNullOrEmpty(foundName)) - { - foundName = String.Format("{0}", ((char)TokenType)); - } - - throw new ScriptException(String.Format("Unexpected token type. Expected {0}, found {1}", expectedName, foundName)); - } - - GetNextToken(); - } - } -} diff --git a/ScriptVar.cs b/ScriptVar.cs deleted file mode 100644 index 880f3ee..0000000 --- a/ScriptVar.cs +++ /dev/null @@ -1,783 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public class ScriptVar : IDisposable - { - #region IDisposable - private bool _disposed; - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - RemoveAllChildren(); - } - - // Indicate that the instance has been disposed. - _disposed = true; - } - } - #endregion - - private int _refs; - private Flags _flags; - private object _data; - private int _intData; - private double _doubleData; - private ScriptEngine.ScriptCallbackCB _callback; - private object _callbackUserData; - - public const String ReturnVarName = "return"; - public const String PrototypeClassName = "prototype"; - - [Flags] - public enum Flags - { - Undefined = 1, - Function = 2, - Object = 4, - Array = 8, - Double = 16, - Integer = 32, - String = 64, - Null = 128, - Native = 256, - Class = 512, - NumericMask = Null | Double | Integer, - VarTypeMask = Double | Integer | String | Function | Object | Array | Null - } - - public ScriptVarLink FirstChild { get; set; } - public ScriptVarLink LastChild { get; set; } - - public ScriptVar() - { - _refs = 0; - _flags = Flags.Undefined; - Init(); - } - - public ScriptVar(int val) - { - _refs = 0; - _flags = Flags.Integer; - Init(); - _intData = val; - } - - public ScriptVar(double val) - { - _refs = 0; - _flags = Flags.Double; - Init(); - _doubleData = val; - } - - public ScriptVar(string val) - { - _refs = 0; - _flags = Flags.String; - Init(); - _data = val; - } - - public ScriptVar(bool val) - { - _refs = 0; - _flags = Flags.Integer; - Init(); - _intData = val ? 1 : 0; - } - - public ScriptVar(object val, Flags flags) - { - _refs = 0; - _flags = flags; - Init(); - _data = val; - } - - private void Init() - { - FirstChild = null; - LastChild = null; - _callback = null; - _callbackUserData = null; - _data = null; - _intData = 0; - _doubleData = 0; - } - - public bool IsInt - { - get { return (_flags & Flags.Integer) != 0; } - } - - public bool IsDouble - { - get { return (_flags & Flags.Double) != 0; } - } - - public bool IsString - { - get { return (_flags & Flags.String) != 0; } - } - - public bool IsNumeric - { - get { return (_flags & Flags.NumericMask) != 0; } - } - - public bool IsFunction - { - get { return (_flags & Flags.Function) != 0; } - } - - public bool IsObject - { - get { return (_flags & Flags.Object) != 0; } - } - - public bool IsArray - { - get { return (_flags & Flags.Array) != 0; } - } - - public bool IsNative - { - get { return (_flags & Flags.Native) != 0; } - } - - public bool IsUndefined - { - get { return (_flags & Flags.VarTypeMask) == Flags.Undefined; } - } - - public bool IsNull - { - get { return (_flags & Flags.Null) != 0; } - } - - public bool IsBasic - { - get { return FirstChild == null; } - } - - public bool IsClass - { - get { return (_flags & Flags.Class) != 0; } - } - - public ScriptVar this[String index] - { - get { return GetParameter(index); } - } - - public int GetInt() - { - if (IsInt && _data == null) return _intData; - if (IsInt && _data != null) return Convert.ToInt32(_data); - if (IsNull) return 0; - if (IsUndefined) return 0; - if (IsDouble) return (int)_doubleData; - return 0; - } - - public bool GetBool() - { - return GetInt() != 0; - } - - public double GetDouble() - { - if (IsDouble && _data == null) return _doubleData; - if (IsDouble && _data != null) return Convert.ToDouble(_data); - if (IsInt) return _intData; - if (IsNull) return 0; - if (IsUndefined) return 0; - return 0; - } - - public String GetString() - { - if (IsInt) - { - return String.Format("{0:D}", _intData); - } - if (IsDouble) - { - return String.Format("{0}", _doubleData); - } - if (IsNull) return "null"; - if (IsUndefined) return "undefined"; - - return (String)_data; - } - - public object GetData() - { - if (IsNull) return null; - if (IsUndefined) return null; - if (IsInt && _data == null) return _intData; - if (IsInt && _data != null) return Convert.ToInt32(_data); - if (IsDouble && _data == null) return _doubleData; - if (IsDouble && _data != null) return Convert.ToDouble(_data); - - return _data; - } - - public void SetInt(int num) - { - _flags = (_flags & ~Flags.VarTypeMask) | Flags.Integer; - _intData = num; - _doubleData = 0; - _data = null; - } - - public void SetDouble(double num) - { - _flags = (_flags & ~Flags.VarTypeMask) | Flags.Double; - _intData = 0; - _doubleData = num; - _data = null; - } - - public void SetString(string str) - { - _flags = (_flags & ~Flags.VarTypeMask) | Flags.String; - _intData = 0; - _doubleData = 0; - _data = str; - } - - public void SetUndefined() - { - _flags = (_flags & ~Flags.VarTypeMask) | Flags.Undefined; - _intData = 0; - _doubleData = 0; - _data = null; - RemoveAllChildren(); - } - - public void SetArray() - { - _flags = (_flags & ~Flags.VarTypeMask) | Flags.Array; - _intData = 0; - _doubleData = 0; - _data = null; - RemoveAllChildren(); - } - - public ScriptVar Ref() - { - _refs++; - return this; - } - - public void UnRef() - { - if (_refs <= 0) throw new ScriptException("No refs to unref"); - - if ((--_refs) == 0) - { - Dispose(true); - } - } - - public int GetRefs() - { - return _refs; - } - - public ScriptVarLink FindChild(String childName) - { - ScriptVarLink v = FirstChild; - - while (v != null) - { - if (v.Name == childName) - { - return v; - } - - v = v.Next; - } - - return null; - } - - public ScriptVarLink FindChildOrCreate(String childName, Flags varFlags = Flags.Undefined) - { - ScriptVarLink l = FindChild(childName); - if (l != null) return l; - - return AddChild(childName, new ScriptVar(null, varFlags)); - } - - public ScriptVarLink FindChildOrCreateByPath(String path) - { - Int32 p = path.IndexOf('.'); - if (p < 0) return FindChildOrCreate(path); - - String[] parts = path.Split('.'); - - return FindChildOrCreate(parts[0], Flags.Object).Var.FindChildOrCreateByPath(parts[1]); - } - - public ScriptVarLink AddChild(String childName, ScriptVar child) - { - if (IsUndefined) - { - _flags = Flags.Object; - } - - ScriptVar c = child ?? new ScriptVar(); - - ScriptVarLink link = new ScriptVarLink(c, childName) - { - Owned = true - }; - - if (LastChild != null) - { - LastChild.Next = link; - link.Prev = LastChild; - LastChild = link; - } - else - { - FirstChild = link; - LastChild = link; - } - - return link; - } - - public ScriptVarLink AddChildNoDup(String childName, ScriptVar child) - { - ScriptVar c = child ?? new ScriptVar(); - - ScriptVarLink v = FindChild(childName); - if (v != null) - { - v.ReplaceWith(c); - } - else - { - v = AddChild(childName, c); - } - - return v; - } - - public void RemoveChild(ScriptVar child) - { - ScriptVarLink link = FirstChild; - - while (link != null) - { - if(link.Var == child) break; - - link = link.Next; - } - - RemoveLink(link); - } - - public void RemoveLink(ScriptVarLink link) - { - if (link == null) return; - - if (link.Next != null) - { - link.Next.Prev = link.Prev; - } - if (link.Prev != null) - { - link.Prev.Next = link.Next; - } - if (LastChild == link) - { - LastChild = link.Prev; - } - if (FirstChild == link) - { - FirstChild = link.Next; - } - } - - public void RemoveAllChildren() - { - ScriptVarLink c = FirstChild; - - while (c != null) - { - ScriptVarLink t = c.Next; - c = t; - } - - FirstChild = null; - LastChild = null; - } - - public ScriptVar ReturnVar - { - get - { - return GetReturnVar(); - } - set - { - SetReturnVar(value); - } - } - - public ScriptVar GetReturnVar() - { - return GetParameter(ReturnVarName); - } - - public void SetReturnVar(ScriptVar var) - { - FindChildOrCreate(ReturnVarName).ReplaceWith(var); - } - - public ScriptVar GetParameter(String name) - { - return FindChildOrCreate(name).Var; - } - - public ScriptVar GetArrayIndex(Int32 idx) - { - ScriptVarLink link = FindChild(String.Format("{0}", idx)); - if (link != null) return link.Var; - - return new ScriptVar(null, Flags.Null); - } - - public void SetArrayIndex(Int32 idx, ScriptVar value) - { - ScriptVarLink link = FindChild(String.Format("{0}", idx)); - - if (link != null) - { - if (value.IsUndefined) - { - RemoveLink(link); - } - else - { - link.ReplaceWith(value); - } - } - else - { - if (!value.IsUndefined) - { - AddChild(String.Format("{0}", idx), value); - } - } - } - - public Int32 GetArrayLength() - { - Int32 highest = -1; - - if (!IsArray) return 0; - - ScriptVarLink link = FirstChild; - - while (link != null) - { - Int32 outputVal; - if (Int32.TryParse(link.Name, out outputVal)) - { - if (outputVal > highest) highest = outputVal; - } - - link = link.Next; - } - - return highest + 1; - } - - public Int32 GettChildren() - { - Int32 n = 0; - ScriptVarLink link = FirstChild; - while (link != null) - { - n++; - link = link.Next; - } - return n; - } - - public bool Equal(ScriptVar v) - { - bool res; - - using (ScriptVar resV = MathsOp(v, ScriptLex.LexTypes.Equal)) - { - res = resV.GetBool(); - } - - return res; - } - - public ScriptVar MathsOp(ScriptVar b, ScriptLex.LexTypes op) - { - ScriptVar a = this; - - char opc = (char)op; - - if (op == ScriptLex.LexTypes.TypeEqual || op == ScriptLex.LexTypes.NTypeEqual) - { - bool equal = ((a._flags & Flags.VarTypeMask) == (b._flags & Flags.VarTypeMask)); - - if (equal) - { - ScriptVar contents = a.MathsOp(b, ScriptLex.LexTypes.Equal); - if (!contents.GetBool()) equal = false; - } - - if (op == ScriptLex.LexTypes.TypeEqual) - { - return new ScriptVar(equal); - } - - return new ScriptVar(!equal); - } - - if (a.IsUndefined && b.IsUndefined) - { - if (op == ScriptLex.LexTypes.Equal) - { - return new ScriptVar(true); - } - if (op == ScriptLex.LexTypes.NEqual) - { - return new ScriptVar(false); - } - - return new ScriptVar(); - } - - if ((a.IsNumeric || a.IsUndefined) && (b.IsNumeric || b.IsUndefined)) - { - if (!a.IsDouble && !b.IsDouble) - { - //ints - int da = a.GetInt(); - int db = b.GetInt(); - - switch (opc) - { - case '+': return new ScriptVar(da + db); - case '-': return new ScriptVar(da - db); - case '*': return new ScriptVar(da * db); - case '/': return new ScriptVar(da / db); - case '&': return new ScriptVar(da & db); - case '|': return new ScriptVar(da | db); - case '^': return new ScriptVar(da ^ db); - case '%': return new ScriptVar(da % db); - case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(da == db); - case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(da != db); - case '<': return new ScriptVar(da < db); - case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar(da <= db); - case '>': return new ScriptVar(da > db); - case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar(da >= db); - - default: throw new ScriptException("Operation not supported on the Int datatype"); - } - } - else - { - //doubles - double da = a.GetDouble(); - double db = b.GetDouble(); - - switch (opc) - { - case '+': return new ScriptVar(da + db); - case '-': return new ScriptVar(da - db); - case '*': return new ScriptVar(da * db); - case '/': return new ScriptVar(da / db); - case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(da == db); - case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(da != db); - case '<': return new ScriptVar(da < db); - case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar(da <= db); - case '>': return new ScriptVar(da > db); - case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar(da >= db); - - default: throw new ScriptException("Operation not supported on the Int datatype"); - } - } - } - - if (a.IsArray) - { - switch (op) - { - case ScriptLex.LexTypes.Equal: return new ScriptVar(a == b); - case ScriptLex.LexTypes.NEqual: return new ScriptVar(a != b); - - default: throw new ScriptException("Operation not supported on the Array datatype"); - } - } - - if (a.IsObject) - { - switch (op) - { - case ScriptLex.LexTypes.Equal: return new ScriptVar(a == b); - case ScriptLex.LexTypes.NEqual: return new ScriptVar(a != b); - - default: throw new ScriptException("Operation not supported on the Object datatype"); - } - } - - string sda = a.GetString(); - string sdb = b.GetString(); - - switch (opc) - { - case '+': return new ScriptVar(sda + sdb, Flags.String); - case (char)ScriptLex.LexTypes.Equal: return new ScriptVar(sda == sdb); - case (char)ScriptLex.LexTypes.NEqual: return new ScriptVar(sda != sdb); - case '<': return new ScriptVar(String.CompareOrdinal(sda, sdb) < 0); - case (char)ScriptLex.LexTypes.LEqual: return new ScriptVar((String.CompareOrdinal(sda, sdb) < 0) || sda == sdb); - case '>': return new ScriptVar(String.CompareOrdinal(sda, sdb) > 0); - case (char)ScriptLex.LexTypes.GEqual: return new ScriptVar((String.CompareOrdinal(sda, sdb) > 0) || sda == sdb); - default: throw new ScriptException("Operation not supported on the String datatype"); - } - } - - protected void CopySimpleData(ScriptVar val) - { - _data = val._data; - _intData = val._intData; - _doubleData = val._doubleData; - _flags = (_flags & ~Flags.VarTypeMask) | (val._flags & Flags.VarTypeMask); - } - - public void CopyValue(ScriptVar val) - { - if (val != null) - { - CopySimpleData(val); - RemoveAllChildren(); - - ScriptVarLink link = val.FirstChild; - - while (link != null) - { - ScriptVar copied = link.Name != PrototypeClassName ? link.Var.DeepCopy() : link.Var; - - AddChild(link.Name, copied); - - link = link.Next; - } - } - else - { - SetUndefined(); - } - } - - public ScriptVar DeepCopy() - { - ScriptVar newVar = new ScriptVar(); - newVar.CopySimpleData(this); - - ScriptVarLink link = FirstChild; - while (link != null) - { - ScriptVar copied = link.Name != PrototypeClassName ? link.Var.DeepCopy() : link.Var; - - newVar.AddChild(link.Name, copied); - - link = link.Next; - } - - return newVar; - } - - public void SetCallback(ScriptEngine.ScriptCallbackCB callback, object userdata) - { - _callback = callback; - _callbackUserData = userdata; - } - - public void Trace(Int32 indent, String name) - { - System.Diagnostics.Trace.TraceInformation("{0}{1} = '{2}' ({3})", new String(' ', indent), name ?? "ROOT", GetString(), _flags); - - ScriptVarLink link = FirstChild; - while(link != null) - { - link.Var.Trace(indent + 2, link.Name); - link = link.Next; - } - } - - public static implicit operator String(ScriptVar d) - { - return d.GetString(); - } - - public override string ToString() - { - return String.Format("{0}", GetHashCode()); - } - - internal void SetData(object data) - { - _data = data; - } - - internal ScriptEngine.ScriptCallbackCB GetCallback() - { - return _callback; - } - - internal object GetCallbackUserData() - { - return _callbackUserData; - } - - internal Type ClassType { get; set; } - internal Object ClassInstance { get; set; } - - } -} diff --git a/ScriptVarLink.cs b/ScriptVarLink.cs deleted file mode 100644 index fc57301..0000000 --- a/ScriptVarLink.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - public class ScriptVarLink : IDisposable - { - #region IDisposable - private bool _disposed; - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - Var.UnRef(); - } - - // Indicate that the instance has been disposed. - _disposed = true; - } - } - #endregion - - public String Name { get; set; } - public ScriptVarLink Next { get; set; } - public ScriptVarLink Prev { get; set; } - public ScriptVar Var { get; set; } - public bool Owned { get; set; } - - public ScriptVarLink(ScriptVar var, String name) - { - Name = name; - Var = var.Ref(); - Next = null; - Prev = null; - Owned = false; - } - - public ScriptVarLink(ScriptVarLink toCopy) - { - Name = toCopy.Name; - Var = toCopy.Var.Ref(); - Next = toCopy.Next; - Prev = toCopy.Prev; - Owned = toCopy.Owned; - } - - public void ReplaceWith(ScriptVar newVar) - { - ScriptVar oldVar = Var; - Var = newVar.Ref(); - oldVar.UnRef(); - } - - public void ReplaceWith(ScriptVarLink newVar) - { - ReplaceWith(newVar != null ? newVar.Var : new ScriptVar()); - } - - public Int32 GetIntName() - { - int retVal = Convert.ToInt32(Name); - - return retVal; - } - - public void SetIntName(Int32 n) - { - Name = String.Format("{0}", n); - } - } -} diff --git a/Utils.cs b/Utils.cs deleted file mode 100644 index 65c38b9..0000000 --- a/Utils.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright (c) 2014 Darren Horrocks - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -using System; - -namespace DScript -{ - internal static class Utils - { - public static bool IsWhitespace(this char ch) - { - return (ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r'); - } - - public static bool IsNumeric(this char ch) - { - return (ch >= '0') && (ch <= '9'); - } - - public static bool IsNumber(this String str) - { - Int32 c = str.Length; - for (Int32 i = 0; i < c; i++) - { - if (!IsNumeric(str[i])) return false; - } - return true; - } - - public static bool IsHexadecimal(this char ch) - { - return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F')); - } - - public static bool IsAlpha(this char ch) - { - return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || ch == '_'; - } - - public static bool IsIDString(this String str) - { - Int32 c = str.Length; - for (Int32 i = 0; i < c; i++) - { - if (IsNumeric(str[i]) || !IsAlpha(str[i])) return false; - } - return true; - } - - public static String GetJSString(this String str) - { - String oStr = str; - - for (int x = 0; x < oStr.Length; x++) - { - String replaceWith = ""; - bool replace = true; - switch (oStr[x]) - { - case '\\': - replaceWith = "\\\\"; - break; - case '\n': - replaceWith = "\\n"; - break; - case '\r': - replaceWith = "\\r"; - break; - case '\a': - replaceWith = "\\a"; - break; - case '"': - replaceWith = "\\\""; - break; - default: - { - Int32 nCh = ((Int32) oStr[x]) & 0xFF; - if (nCh < 32 || nCh > 127) - { - replaceWith = String.Format("\\x{0:x2}", nCh); - } - else - { - replace = false; - } - } - break; - } - - if (replace) - { - oStr = oStr.Substring(0, x) + replaceWith + oStr.Substring(x + 1); - x += replaceWith.Length - 1; - } - } - - return String.Format("\"{0}\"", oStr); - } - } -}