Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion src/MoonSharp.Interpreter/IAnnotationPolicy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
namespace MoonSharp.Interpreter
{
public enum AnnotationValueParsingPolicy
{
/// <summary>
/// Annotations are parsed as string @MyAnnotation("strValue") or as a table @MyAnnotation({"key1", "key2"})
/// </summary>
StringOrTable,
/// <summary>
/// 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"})
/// </summary>
ForceTable
}

public enum AnnotationAction
{
Allow,
Expand All @@ -11,16 +24,37 @@ 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();

public static IAnnotationPolicy Ignore { get; } = new IgnorePolicy();

public static IAnnotationPolicy Error { get; } = new ErrorPolicy();

class AllowPolicy : IAnnotationPolicy
{
public AnnotationAction OnChunkAnnotation(string name, DynValue value)
Expand All @@ -32,6 +66,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value)
{
return AnnotationAction.Allow;
}

public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable;
}

class IgnorePolicy : IAnnotationPolicy
Expand All @@ -45,6 +81,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value)
{
return AnnotationAction.Ignore;
}

public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable;
}

class ErrorPolicy : IAnnotationPolicy
Expand All @@ -58,6 +96,8 @@ public AnnotationAction OnFunctionAnnotation(string name, DynValue value)
{
return AnnotationAction.Error;
}

public AnnotationValueParsingPolicy AnnotationParsingPolicy { get; set; } = AnnotationValueParsingPolicy.StringOrTable;
}
}
}
1 change: 1 addition & 0 deletions src/MoonSharp.Interpreter/ScriptOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ internal ScriptOptions(ScriptOptions defaults)

/// <summary>
/// Gets or sets the annotation policy for the script compiler (C-Like mode only)
/// <see cref="AnnotationValueParsingPolicy" />
/// </summary>
public IAnnotationPolicy AnnotationPolicy { get; set; } = AnnotationPolicies.Allow;

Expand Down
46 changes: 41 additions & 5 deletions src/MoonSharp.Interpreter/Tree/Statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@bind("html-name", "cool")
function f() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@bind("html-name")
function f() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@bind
function f() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@bind("tbl1")
@bind2({"tbl2", "tbl3"})
@bind3("tbl4", "tbl6")
function f() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@bind2({"tbl2", "tbl3"})
function f() {

}
9 changes: 8 additions & 1 deletion src/MoonSharp.Tests/EndToEnd/CLikeTestRunner.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -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"))
{
Expand All @@ -49,7 +51,12 @@ public async Task Run(string path)

try
{
await script.DoStringAsync(code);
DynValue dv = script.LoadString(code);
IReadOnlyList<Annotation> 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"))
Expand Down