Skip to content

Instantly share code, notes, and snippets.

@DanielKeep
Created December 26, 2009 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielKeep/263832 to your computer and use it in GitHub Desktop.
Save DanielKeep/263832 to your computer and use it in GitHub Desktop.
/// Parses the storage class for function arguments.
/// Authors: Daniel Keep
/// Copyright: Copyright © 2009 Daniel Keep
/// License: BSD v2 <http://www.opensource.org/licenses/bsd-license.php>
module argparse;
enum ParamSemantics
{
None = 0b0000,
In = 0b0001,
Out = 0b0010,
Ref = 0b0011,
Scope = 0b0100,
}
private:
bool startsWith(in string s, in string match)
{
if( s.length >= match.length )
return s[0..match.length] == match;
else
return false;
}
enum ParseMode
{
Normal,
StripWS
}
string classifyType(in string type)
{
// Classify
if( startsWith(type, "in ") )
return "ParamSemantics.In";
else if( startsWith(type, "out ") )
return "ParamSemantics.Out";
else if( startsWith(type, "ref ") )
return "ParamSemantics.Ref";
else if( startsWith(type, "scope ") )
return "ParamSemantics.Scope";
else
return "ParamSemantics.None";
}
string parseParamSemanticsImpl(string args)
{
// First, chop off the first and last chars (should be parens)
assert( args[0] == '(' && args[$-1] == ')' );
args = args[1..$-1];
// If the string is empty, that means no args.
if( args.length == 0 )
return "null /+ no arguments +/";
// Start parsing
string result = "[";
auto mode = ParseMode.Normal;
size_t i = 0;
int level = 0;
foreach( j, c ; args )
{
if( c == ',' && level == 0 )
{
// End of argument
auto type = args[i..j];
result ~= classifyType(type) ~ "/+"~type~"+/" ~ ", ";
mode = ParseMode.StripWS;
}
else if( c == '(' || c == '[' )
++level;
else if( c == ')' || c == ']' )
--level;
else if( mode == ParseMode.StripWS )
{
if( c != ' ' )
{
mode = ParseMode.Normal;
i = j;
}
}
else
{
// no-op
}
}
// Classify last argument
auto type = args[i..$];
result ~= classifyType(type) ~ "/+"~type~"+/";
// Done
result ~= "]";
return result ~ `/+ `~args~` +/`;
}
public template ParameterSemantics(alias Function)
{
const ParameterSemantics =
ParameterSemantics!(typeof(Function));
}
import std.traits : ParameterTypeTuple;
public template ParameterSemantics(FnT)
{
const ParameterSemantics =
mixin(parseParamSemanticsImpl(
ParameterTypeTuple!(FnT).stringof));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment