From e6f988125cb91ac2a2f8461c95cd1c7eb7c307b8 Mon Sep 17 00:00:00 2001 From: lofcz Date: Sat, 9 Apr 2022 18:57:03 +0200 Subject: [PATCH] Relax brks around annotations --- .../IAnnotationPolicy.cs | 42 ++++++++++++++++- src/MoonSharp.Interpreter/ScriptOptions.cs | 1 + src/MoonSharp.Interpreter/Tree/Statement.cs | 46 +++++++++++++++++-- .../SyntaxCLike/Annotations/1-annotation.lua | 4 ++ .../SyntaxCLike/Annotations/1-annotation.txt | 0 .../SyntaxCLike/Annotations/2-annotation.lua | 4 ++ .../SyntaxCLike/Annotations/2-annotation.txt | 0 .../SyntaxCLike/Annotations/3-annotation.lua | 4 ++ .../SyntaxCLike/Annotations/3-annotation.txt | 0 .../SyntaxCLike/Annotations/4-annotation.lua | 6 +++ .../SyntaxCLike/Annotations/4-annotation.txt | 0 .../SyntaxCLike/Annotations/5-annotation.lua | 4 ++ .../SyntaxCLike/Annotations/5-annotation.txt | 0 .../EndToEnd/CLikeTestRunner.cs | 9 +++- 14 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.lua create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.txt create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.lua create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.txt create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.lua create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.txt create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.lua create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.txt create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.lua create mode 100644 src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.txt diff --git a/src/MoonSharp.Interpreter/IAnnotationPolicy.cs b/src/MoonSharp.Interpreter/IAnnotationPolicy.cs index 9dd9af33..d01fddbb 100644 --- a/src/MoonSharp.Interpreter/IAnnotationPolicy.cs +++ b/src/MoonSharp.Interpreter/IAnnotationPolicy.cs @@ -1,5 +1,18 @@ namespace MoonSharp.Interpreter { + public enum AnnotationValueParsingPolicy + { + /// + /// Annotations are parsed as string @MyAnnotation("strValue") or as a table @MyAnnotation({"key1", "key2"}) + /// + StringOrTable, + /// + /// Annotations are always parsed as a table and curly brackes enclosing the table are relaxed. + /// In this mode @MyAnnotation("key1", "key2") is equivalent to @MyAnnotation({"key1", "key2"}) + /// + ForceTable + } + public enum AnnotationAction { Allow, @@ -11,8 +24,29 @@ public interface IAnnotationPolicy { AnnotationAction OnChunkAnnotation(string name, DynValue value); AnnotationAction OnFunctionAnnotation(string name, DynValue value); + AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } } + public class CustomPolicy : IAnnotationPolicy + { + public CustomPolicy(AnnotationValueParsingPolicy parsingPolicy) + { + AnnotationParsingPolicy = parsingPolicy; + } + + public AnnotationAction OnChunkAnnotation(string name, DynValue value) + { + return AnnotationAction.Allow; + } + + public AnnotationAction OnFunctionAnnotation(string name, DynValue value) + { + return AnnotationAction.Allow; + } + + public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } + } + public static class AnnotationPolicies { public static IAnnotationPolicy Allow { get; } = new AllowPolicy(); @@ -20,7 +54,7 @@ public static class AnnotationPolicies public static IAnnotationPolicy Ignore { get; } = new IgnorePolicy(); public static IAnnotationPolicy Error { get; } = new ErrorPolicy(); - + class AllowPolicy : IAnnotationPolicy { public AnnotationAction OnChunkAnnotation(string name, DynValue value) @@ -32,6 +66,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value) { return AnnotationAction.Allow; } + + public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable; } class IgnorePolicy : IAnnotationPolicy @@ -45,6 +81,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value) { return AnnotationAction.Ignore; } + + public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable; } class ErrorPolicy : IAnnotationPolicy @@ -58,6 +96,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value) { return AnnotationAction.Error; } + + public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable; } } } \ No newline at end of file diff --git a/src/MoonSharp.Interpreter/ScriptOptions.cs b/src/MoonSharp.Interpreter/ScriptOptions.cs index 901d3c4b..16f83640 100644 --- a/src/MoonSharp.Interpreter/ScriptOptions.cs +++ b/src/MoonSharp.Interpreter/ScriptOptions.cs @@ -119,6 +119,7 @@ internal ScriptOptions(ScriptOptions defaults) /// /// Gets or sets the annotation policy for the script compiler (C-Like mode only) + /// /// public IAnnotationPolicy AnnotationPolicy { get; set; } = AnnotationPolicies.Allow; diff --git a/src/MoonSharp.Interpreter/Tree/Statement.cs b/src/MoonSharp.Interpreter/Tree/Statement.cs index cd8dc5a1..93931779 100644 --- a/src/MoonSharp.Interpreter/Tree/Statement.cs +++ b/src/MoonSharp.Interpreter/Tree/Statement.cs @@ -51,26 +51,62 @@ static Annotation ParseAnnotation(ScriptLoadingContext lcontext) lcontext.Lexer.Next(); //Skip annotation marker var nameToken = CheckTokenType(lcontext, TokenType.Name); //name DynValue value = DynValue.Nil; - //value - if (lcontext.Lexer.Current.Type == TokenType.Brk_Open_Round) + + DynValue NextPart(bool next) { - lcontext.Lexer.Next(); + DynValue _value = DynValue.Nil; if (lcontext.Lexer.Current.Type != TokenType.Brk_Close_Round) { + if (next) + { + lcontext.Lexer.Next(); + } + var exprToken = lcontext.Lexer.Current; var expr = Expression.Expr(lcontext); if (expr is TableConstructor tbl) { - if(!tbl.TryGetLiteral(out value)) + if(!tbl.TryGetLiteral(out _value)) throw new SyntaxErrorException(exprToken, "annotation value must be literal or prime table"); } - else if (!expr.EvalLiteral(out value)) + else if (!expr.EvalLiteral(out _value)) { throw new SyntaxErrorException(exprToken, "annotation value must be literal or prime table"); } } + + return _value; + } + + if (lcontext.Lexer.Current.Type == TokenType.Brk_Open_Round) + { + value = NextPart(true); + + if (lcontext.Script.Options.AnnotationPolicy.AnnotationParsingPolicy == AnnotationValueParsingPolicy.StringOrTable || value.Type == DataType.Table) + { + CheckTokenType(lcontext, TokenType.Brk_Close_Round); + return new Annotation(nameToken.Text, value); + } + + DynValue table = DynValue.NewTable(lcontext.Script); + table.Table.Append(value); + + while (true) + { + if (lcontext.Lexer.Current.Type == TokenType.Brk_Close_Round) + { + break; + } + + CheckTokenType(lcontext, TokenType.Comma); + value = NextPart(false); + table.Table.Append(value); + } + CheckTokenType(lcontext, TokenType.Brk_Close_Round); + return new Annotation(nameToken.Text, table); } + return new Annotation(nameToken.Text, value); } diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.lua b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.lua new file mode 100644 index 00000000..b5aa39f4 --- /dev/null +++ b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.lua @@ -0,0 +1,4 @@ +@bind("html-name", "cool") +function f() { + +} \ No newline at end of file diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.txt b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/1-annotation.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.lua b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.lua new file mode 100644 index 00000000..50b5497a --- /dev/null +++ b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.lua @@ -0,0 +1,4 @@ +@bind("html-name") +function f() { + +} \ No newline at end of file diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.txt b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/2-annotation.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.lua b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.lua new file mode 100644 index 00000000..1b50d7c1 --- /dev/null +++ b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.lua @@ -0,0 +1,4 @@ +@bind +function f() { + +} \ No newline at end of file diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.txt b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/3-annotation.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.lua b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.lua new file mode 100644 index 00000000..377832fe --- /dev/null +++ b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.lua @@ -0,0 +1,6 @@ +@bind("tbl1") +@bind2({"tbl2", "tbl3"}) +@bind3("tbl4", "tbl6") +function f() { + +} \ No newline at end of file diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.txt b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/4-annotation.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.lua b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.lua new file mode 100644 index 00000000..1ec81f9c --- /dev/null +++ b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.lua @@ -0,0 +1,4 @@ +@bind2({"tbl2", "tbl3"}) +function f() { + +} \ No newline at end of file diff --git a/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.txt b/src/MoonSharp.Tests/EndToEnd/CLike/SyntaxCLike/Annotations/5-annotation.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/MoonSharp.Tests/EndToEnd/CLikeTestRunner.cs b/src/MoonSharp.Tests/EndToEnd/CLikeTestRunner.cs index 988ca721..ad98a6b7 100644 --- a/src/MoonSharp.Tests/EndToEnd/CLikeTestRunner.cs +++ b/src/MoonSharp.Tests/EndToEnd/CLikeTestRunner.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; @@ -35,6 +36,7 @@ public async Task Run(string path) Script script = new Script(CoreModules.Preset_HardSandbox); script.Options.DebugPrint = s => stdOut.AppendLine(s); script.Options.IndexTablesFrom = 0; + script.Options.AnnotationPolicy = new CustomPolicy(AnnotationValueParsingPolicy.ForceTable); if (path.Contains("SyntaxCLike")) { @@ -49,7 +51,12 @@ public async Task Run(string path) try { - await script.DoStringAsync(code); + DynValue dv = script.LoadString(code); + IReadOnlyList annots = dv.Function.Annotations; + await script.CallAsync(dv); + + DynValue dv2 = script.Globals.Get("f"); + Assert.AreEqual(output.Trim(), stdOut.ToString().Trim(), $"Test {path} did not pass."); if (path.Contains("invalid"))