Skip to content

Commit

Permalink
Stop signature binding swamping the profile. At least one lesson to t…
Browse files Browse the repository at this point in the history
…each Rakudo's from this experience.
  • Loading branch information
jnthn committed Aug 21, 2010
1 parent d9c8bf3 commit 7608b1b
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
10 changes: 6 additions & 4 deletions dotnet/compiler/PAST2DNSTCompiler.pm
Expand Up @@ -365,10 +365,12 @@ sub compile_signature(@params) {

# Flags.
$param.push(
$_.viviself ?? 'Parameter.OPTIONAL_FLAG' !!
$_.slurpy && $_.named ?? 'Parameter.NAMED_SLURPY_FLAG' !!
$_.slurpy ?? 'Parameter.POS_SLURPY_FLAG' !!
'0');
$_.viviself && $_.named ?? 'Parameter.OPTIONAL_FLAG | Parameter.NAMED_FLAG' !!
$_.viviself ?? 'Parameter.OPTIONAL_FLAG' !!
$_.slurpy && $_.named ?? 'Parameter.NAMED_SLURPY_FLAG' !!
$_.slurpy ?? 'Parameter.POS_SLURPY_FLAG' !!
$_.named ?? 'Parameter.NAMED_FLAG' !!
'Parameter.POS_FLAG');

$params.push($param);
}
Expand Down
10 changes: 10 additions & 0 deletions dotnet/runtime/Runtime/Signatures/Parameter.cs
Expand Up @@ -46,6 +46,11 @@ public Parameter(RakudoObject Type, string VariableName, string Name, int Flags)
/// </summary>
public int Flags;

/// <summary>
/// (Un-)flag for positional parameters.
/// </summary>
public const int POS_FLAG = 0;

/// <summary>
/// Flag for optional parameters.
/// </summary>
Expand All @@ -60,5 +65,10 @@ public Parameter(RakudoObject Type, string VariableName, string Name, int Flags)
/// Flag for named slurpy parameters.
/// </summary>
public const int NAMED_SLURPY_FLAG = 4;

/// <summary>
/// Flag for named parameters.
/// </summary>
public const int NAMED_FLAG = 8;
}
}
87 changes: 60 additions & 27 deletions dotnet/runtime/Runtime/Signatures/SignatureBinder.cs
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using Rakudo.Metamodel;
using Rakudo.Metamodel.Representations;

namespace Rakudo.Runtime
{
Expand All @@ -11,6 +12,16 @@ namespace Rakudo.Runtime
/// </summary>
public static class SignatureBinder
{
/// <summary>
/// Singleton empty positionals array.
/// </summary>
private static RakudoObject[] EmptyPos = new RakudoObject[0];

/// <summary>
/// Single empty nameds hash.
/// </summary>
private static Dictionary<string, RakudoObject> EmptyNamed = new Dictionary<string, RakudoObject>();

/// <summary>
/// Binds the capture against the given signature and stores the
/// bound values into variables in the lexpad.
Expand All @@ -30,15 +41,59 @@ public static void Bind(Context C, RakudoObject Capture)
// The lexpad we'll bind into.
var Target = C.LexPad;

// Make sure the object is really a low level capture (don't handle
// otherwise yet) and grab the pieces.
var NativeCapture = Capture as P6capture.Instance;
if (NativeCapture == null)
throw new NotImplementedException("Can only deal with native captures at the moment");
var Positionals = NativeCapture.Positionals ?? EmptyPos;
var Nameds = NativeCapture.Nameds ?? EmptyNamed;

// Current positional.
var CurPositional = 0;

// Iterate over the parameters.
var Params = C.StaticCodeObject.Sig.Parameters;
foreach (var Param in Params)
{
// Positional required?
if (Param.Flags == Parameter.POS_FLAG)
{
if (CurPositional < Positionals.Length)
{
// We have an argument, just bind it.
Target[Param.VariableName] = Positionals[CurPositional];
}
else
{
throw new Exception("Not enough positional parameters; got " +
CurPositional.ToString() + " but needed " +
NumRequiredPositionals(C.StaticCodeObject.Sig).ToString());
}

// Increment positional counter.
CurPositional++;
}

// Positonal optional?
else if (Param.Flags == Parameter.OPTIONAL_FLAG)
{
if (CurPositional < Positionals.Length)
{
// We have an argument, just bind it.
Target[Param.VariableName] = Positionals[CurPositional];
}
else
{
// XXX Default value, vivification.
}

// Increment positional counter.
CurPositional++;
}

// Named slurpy?
if ((Param.Flags & Parameter.NAMED_SLURPY_FLAG) != 0)
else if ((Param.Flags & Parameter.NAMED_SLURPY_FLAG) != 0)
{
throw new Exception("Named slurpy parameters are not yet implemented.");
}
Expand All @@ -53,8 +108,8 @@ public static void Bind(Context C, RakudoObject Capture)
else if (Param.Name != null)
{
// Yes, try and get argument.
var Value = CaptureHelper.GetNamed(Capture, Param.Name);
if (Value != null)
RakudoObject Value;
if (Nameds.TryGetValue(Param.Name, out Value))
{
// We have an argument, just bind it.
Target[Param.VariableName] = Value;
Expand All @@ -73,37 +128,15 @@ public static void Bind(Context C, RakudoObject Capture)
}
}

// Otherwise, it's a positional.
// Otherwise, WTF?
else
{
var Value = CaptureHelper.GetPositional(Capture, CurPositional);
if (Value != null)
{
// We have an argument, just bind it.
Target[Param.VariableName] = Value;
}
else
{
// Optional?
if ((Param.Flags & Parameter.OPTIONAL_FLAG) == 0)
{
throw new Exception("Not enough positional parameters; got " +
CurPositional.ToString() + " but needed " +
NumRequiredPositionals(C.StaticCodeObject.Sig).ToString());
}
else
{
// XXX Default value, vivification.
}
}

// Increment positional counter.
CurPositional++;
}
}

// Ensure we had enough positionals.
var PossiesInCapture = CaptureHelper.NumPositionals(Capture);
var PossiesInCapture = Positionals.Length;
if (CurPositional != PossiesInCapture)
throw new Exception("Too many positional arguments passed; expected " +
NumRequiredPositionals(C.StaticCodeObject.Sig).ToString() +
Expand Down

0 comments on commit 7608b1b

Please sign in to comment.