Skip to content

Commit

Permalink
Added lambda declarations parsing including signatures
Browse files Browse the repository at this point in the history
Outcomes
   847 Passed
   392 Failed
   372 Skipped
  • Loading branch information
mikhail-barg committed Oct 25, 2021
1 parent 7a47624 commit 01bdb94
Show file tree
Hide file tree
Showing 6 changed files with 3,543 additions and 3,273 deletions.
6,218 changes: 3,143 additions & 3,075 deletions src/Jsonata.Net.Native.TestSuite/TestReport/Jsonata.Net.Native.TestSuite.xml

Large diffs are not rendered by default.

Binary file modified src/Jsonata.Net.Native.TestSuite/TestReport/extract.txt
Binary file not shown.
184 changes: 183 additions & 1 deletion src/Jsonata.Net.Native/Parsing/Nodes.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Jsonata.Net.Native.Parsing
{
Expand Down Expand Up @@ -654,6 +656,186 @@ public override string ToString()
}
}


// A LambdaNode represents a user-defined JSONata function.
internal sealed record LambdaNode(bool isShorthand, List<string> paramNames, LambdaNode.Signature? signature, Node body) : Node
{
internal override LambdaNode optimize()
{
Node body = this.body.optimize();
if (body != this.body)
{
return new LambdaNode(this.isShorthand, this.paramNames, this.signature, body);
}
else
{
return this;
}
}

public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.Append(this.isShorthand ? "λ" : "function");
builder.Append('(');
for (int i = 0; i < this.paramNames.Count; ++i)
{
if (i != 0)
{
builder.Append(",");
};
builder.Append('$');
builder.Append(this.paramNames[i]);
}
builder.Append(')');
if (this.signature != null)
{
this.signature.ToString(builder);
};
builder.Append('{');
builder.Append(this.body.ToString());
builder.Append('}');
return builder.ToString();
}

internal enum ParamOpt
{
None,

// ParamOptional denotes an optional parameter.
Optional,

// ParamVariadic denotes a variadic parameter.
Variadic,

// ParamContextable denotes a parameter that can be
// replaced by the evaluation context if no value is
// provided by the caller.
Contextable
};

[Flags]
internal enum ParamType
{
Bool = 0x01,
Number = 0x02,
String = 0x04,
Null = 0x08,

Array = 0x10,
Object = 0x20,

Func = 0x40,

Simple = Bool | Number | String | Null,
Json = Simple | Array | Object,
Any = Json | Func,
None = 0x0
}

internal static readonly Tuple<ParamType, char>[] s_paramTypePriorityLetters = {
Tuple.Create(ParamType.Any, 'x'),
Tuple.Create(ParamType.Json, 'j'),
Tuple.Create(ParamType.Simple, 'u'),

Tuple.Create(ParamType.Bool, 'b'),
Tuple.Create(ParamType.Number, 'n'),
Tuple.Create(ParamType.String, 's'),
Tuple.Create(ParamType.Null, 'l'),

Tuple.Create(ParamType.Array, 'a'),
Tuple.Create(ParamType.Object, 'o'),

Tuple.Create(ParamType.Func, 'f'),
};

internal sealed record Param(ParamType type, ParamOpt option, Signature? subSignature)
{
public static string ParamOptToString(ParamOpt opt)
{
switch (opt)
{
case ParamOpt.None:
return "";
case ParamOpt.Optional:
return "?";
case ParamOpt.Variadic:
return "+";
case ParamOpt.Contextable:
return "-";
default:
throw new Exception("Unexpected param opt " + opt);
}
}

public static string ParamTypeToString(ParamType type)
{
foreach (Tuple<ParamType, char> t in s_paramTypePriorityLetters)
{
if (type == t.Item1)
{
return t.Item2.ToString();
}
}

StringBuilder builder = new StringBuilder();
builder.Append('(');
foreach (Tuple<ParamType, char> t in s_paramTypePriorityLetters)
{
if ((type & t.Item1) == t.Item1)
{
builder.Append(t.Item2);
type = type & ~t.Item1;
}
}
builder.Append(')');
return builder.ToString();
}

public override string ToString()
{
StringBuilder builder = new StringBuilder();
this.ToString(builder);
return builder.ToString();
}

internal void ToString(StringBuilder builder)
{
builder.Append(ParamTypeToString(this.type));
if (this.subSignature != null)
{
this.subSignature.ToString(builder);
};
builder.Append(ParamOptToString(this.option));
}
}

internal sealed record Signature(List<Param> args, Param? result)
{
public override string ToString()
{
StringBuilder builder = new StringBuilder();
this.ToString(builder);
return builder.ToString();
}

internal void ToString(StringBuilder builder)
{
builder.Append('<');
foreach (Param arg in args)
{
arg.ToString(builder);
};
if (result != null)
{
builder.Append(':');
result.ToString(builder);
};
builder.Append('>');
}
}
}

// A PartialNode represents a partially applied function.
internal sealed record PartialNode(Node func, List<Node> args) : Node
{
Expand Down
196 changes: 0 additions & 196 deletions src/Jsonata.Net.Native/Parsing/Params.cs

This file was deleted.

Loading

0 comments on commit 01bdb94

Please sign in to comment.