Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qualify pegged/peg.d as @safe and when possible pure nothrow @nogc #311

Merged
merged 3 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 5 additions & 3 deletions pegged/dynamic/grammar.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import pegged.peg;
import pegged.parser;
import pegged.dynamic.peg;

@safe:

struct ParameterizedRule
{
size_t numArgs;
Dynamic delegate(Dynamic[]) code;
Dynamic delegate(Dynamic[]) @safe code;

Dynamic opCall(D...)(D rules)
{
Expand Down Expand Up @@ -64,7 +66,7 @@ struct ParameterizedRule
}
}

ParameterizedRule parameterizedRule(size_t n, Dynamic delegate(Dynamic[] d) code)
ParameterizedRule parameterizedRule(size_t n, Dynamic delegate(Dynamic[] d) @safe code)
{
ParameterizedRule pr;
pr.numArgs = n;
Expand Down Expand Up @@ -182,7 +184,7 @@ Dynamic makeRule(ParseTree def, Dynamic[string] context)
throw new Exception("Unknown name: " ~ name);
}

Dynamic ruleFromTree(ParseTree p)
Dynamic ruleFromTree(ParseTree p) @safe
{
//writeln("rfT: ", p.name, " ", p.matches);
//Dynamic result;
Expand Down
16 changes: 9 additions & 7 deletions pegged/dynamic/peg.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import std.stdio;

import pegged.peg;

alias ParseTree delegate(ParseTree) Dynamic;
alias ParseTree delegate(ParseTree) @safe Dynamic;

@safe:

string getName(D)(D rule)
{
Expand All @@ -17,9 +19,9 @@ string getName(D)(D rule)

ParseTree callDynamic(D)(D d, string s)
{
static if (is(typeof(d) : ParseTree delegate(ParseTree)) || is(typeof(d) : ParseTree function(ParseTree)))
static if (is(typeof(d) : ParseTree delegate(ParseTree) @safe) || is(typeof(d) : ParseTree function(ParseTree) @safe))
return d(ParseTree("",false,[], s));
else static if (is(typeof(d) : ParseTree delegate(ParseTree) delegate()) || is(typeof(d) : ParseTree function(ParseTree) delegate()))
else static if (is(typeof(d) : ParseTree delegate(ParseTree) @safe delegate()) || is(typeof(d) : ParseTree function(ParseTree) @safe delegate()))
return d()(ParseTree("",false,[], s));
else static if (is(typeof(d) : ParseTree delegate(string)) || is(typeof(d) : ParseTree function(string)))
return d(s);
Expand All @@ -31,9 +33,9 @@ ParseTree callDynamic(D)(D d, string s)

ParseTree callDynamic(D)(D d, ParseTree p)
{
static if (is(typeof(d) : ParseTree delegate(ParseTree)) || is(typeof(d) : ParseTree function(ParseTree)))
static if (is(typeof(d) : ParseTree delegate(ParseTree) @safe) || is(typeof(d) : ParseTree function(ParseTree) @safe))
return d(p);
else static if (is(typeof(d) : ParseTree delegate(ParseTree) delegate()) || is(typeof(d) : ParseTree function(ParseTree) delegate()))
else static if (is(typeof(d) : ParseTree delegate(ParseTree) @safe delegate()) || is(typeof(d) : ParseTree function(ParseTree) @safe delegate()))
return d()(p);
else static if (is(typeof(d) : ParseTree delegate(string)) || is(typeof(d) : ParseTree function(string)))
return d(p.input[p.end..$]);
Expand Down Expand Up @@ -245,7 +247,7 @@ Dynamic and(T...)(T rules) if (T.length)

Dynamic or(T...)(T rules)
{
return (ParseTree p)
return (ParseTree p) @safe
{
// error-management
ParseTree longestFail = ParseTree("or", false, [], p.input, p.end, 0);
Expand Down Expand Up @@ -309,7 +311,7 @@ Dynamic or(T...)(T rules)
start += len + names[i].length + 4;
}
}
orErrorString = cast(string)(errString[0..$-4]);
() @trusted { orErrorString = cast(string)(errString[0..$-4]); } ();

veelo marked this conversation as resolved.
Show resolved Hide resolved
longestFail.matches = longestFail.matches[0..$-1] // discarding longestFail error message
~ [orErrorString]; // and replacing it by the new, concatenated one.
Expand Down
26 changes: 13 additions & 13 deletions pegged/grammar.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import std.stdio;
public import pegged.peg;
import pegged.parser;


@safe:

/**
Option enum to get internal memoization (parse results storing).
Expand Down Expand Up @@ -204,16 +204,16 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)
string firstRuleName = generateCode(p.children[1].children[0]);

result =
"struct Generic" ~ shortGrammarName ~ "(TParseTree)
"@safe struct Generic" ~ shortGrammarName ~ "(TParseTree)
{
import std.functional : toDelegate;
import pegged.dynamic.grammar;
static import pegged.peg;
struct " ~ grammarName ~ "\n {
enum name = \"" ~ shortGrammarName ~ "\";
static ParseTree delegate(ParseTree)[string] before;
static ParseTree delegate(ParseTree)[string] after;
static ParseTree delegate(ParseTree)[string] rules;";
static ParseTree delegate(ParseTree) @safe [string] before;
static ParseTree delegate(ParseTree) @safe [string] after;
static ParseTree delegate(ParseTree) @safe [string] rules;";

if (withMemo == Memoization.yes) {
result ~= "
Expand All @@ -226,7 +226,7 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)
}

result ~= "
static this()\n {\n";
static this() @trusted\n {\n";

ParseTree[] definitions = p.children[1 .. $];
bool userDefinedSpacing;
Expand All @@ -248,7 +248,7 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)

template hooked(alias r, string name)
{
static ParseTree hooked(ParseTree p)
static ParseTree hooked(ParseTree p) @safe
{
ParseTree result;

Expand All @@ -267,13 +267,13 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)
return result;
}

static ParseTree hooked(string input)
static ParseTree hooked(string input) @safe
{
return hooked!(r, name)(ParseTree(\"\",false,[],input));
}
}

static void addRuleBefore(string parentRule, string ruleSyntax)
static void addRuleBefore(string parentRule, string ruleSyntax) @safe
{
// enum name is the current grammar name
DynamicGrammar dg = pegged.dynamic.grammar.grammar(name ~ \": \" ~ ruleSyntax, rules);
Expand All @@ -283,7 +283,7 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)
before[parentRule] = rules[dg.startingRule];
}

static void addRuleAfter(string parentRule, string ruleSyntax)
static void addRuleAfter(string parentRule, string ruleSyntax) @safe
{
// enum name is the current grammar named
DynamicGrammar dg = pegged.dynamic.grammar.grammar(name ~ \": \" ~ ruleSyntax, rules);
Expand All @@ -295,7 +295,7 @@ string grammar(Memoization withMemo = Memoization.yes)(ParseTree defAsParseTree)
after[parentRule] = rules[dg.startingRule];
}

static bool isRule(string s)
static bool isRule(string s) pure nothrow @nogc
{
import std.algorithm : startsWith;
return s.startsWith(\"" ~ shortGrammarName ~ ".\");
Expand Down Expand Up @@ -2437,12 +2437,12 @@ version(unittest)
{
P foo(P)(P p) { return p;} // for testing actions

void badGrammar(string s)()
void badGrammar(string s)() @safe
{
assert(!__traits(compiles, {mixin(grammar(s));}), "This should fail: " ~ s);
}

void goodGrammar(string s)()
void goodGrammar(string s)() @safe
{
assert(__traits(compiles, {mixin(grammar(s));}), "This should work: " ~ s);
}
Expand Down
16 changes: 9 additions & 7 deletions pegged/introspection.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import std.typecons;

import pegged.parser;

@safe:

/**
The different kinds of recursion for a rule.
'direct' means the rule name appears in its own definition. 'indirect' means the rule calls itself through another rule (the call chain can be long).
Expand Down Expand Up @@ -109,9 +111,9 @@ pure GrammarInfo grammarInfo(ParseTree p)
also appear in the call graph when the rule has a name: hence, calls to predefined rules like 'identifier' or
'digit' will appear, but not a call to '[0-9]+', considered here as an anonymous rule.
*/
bool[string][string] callGraph(ParseTree p)
bool[string][string] callGraph(ParseTree p) @safe
{
bool[string] findIdentifiers(ParseTree p)
bool[string] findIdentifiers(ParseTree p) @safe
{
bool[string] idList;
if (p.name == "Pegged.Identifier")
Expand Down Expand Up @@ -144,7 +146,7 @@ pure GrammarInfo grammarInfo(ParseTree p)
It will propagate the calls to find all rules called by a given rule,
directly (already in the call graph) or indirectly (through another rule).
*/
bool[string][string] closure(bool[string][string] graph)
bool[string][string] closure(bool[string][string] graph) @safe
{
bool[string][string] path;
foreach(rule, children; graph) // deep-dupping, to avoid children aliasing
Expand All @@ -169,7 +171,7 @@ pure GrammarInfo grammarInfo(ParseTree p)
return path;
}

Recursive[string] recursions(bool[string][string] graph)
Recursive[string] recursions(bool[string][string] graph) @safe
{
bool[string][string] path = closure(graph);

Expand All @@ -189,7 +191,7 @@ pure GrammarInfo grammarInfo(ParseTree p)
return result;
}

NullMatch nullMatching(ParseTree p)
NullMatch nullMatching(ParseTree p) @safe
{
switch (p.name)
{
Expand Down Expand Up @@ -250,7 +252,7 @@ pure GrammarInfo grammarInfo(ParseTree p)
}
}

InfiniteLoop infiniteLooping(ParseTree p)
InfiniteLoop infiniteLooping(ParseTree p) @safe
{
switch (p.name)
{
Expand Down Expand Up @@ -292,7 +294,7 @@ pure GrammarInfo grammarInfo(ParseTree p)
}
}

LeftRecursive leftRecursion(ParseTree p, ref string[] cycle)
LeftRecursive leftRecursion(ParseTree p, ref string[] cycle) @safe
{
import std.algorithm.searching: countUntil;
switch (p.name)
Expand Down
12 changes: 7 additions & 5 deletions pegged/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,20 @@ public import pegged.peg;
import std.algorithm: startsWith;
import std.functional: toDelegate;

@safe:

struct GenericPegged(TParseTree)
{
import std.functional : toDelegate;
import pegged.dynamic.grammar;
static import pegged.peg;
struct Pegged
@safe struct Pegged
{
enum name = "Pegged";
static ParseTree delegate(ParseTree)[string] before;
static ParseTree delegate(ParseTree)[string] after;
static ParseTree delegate(ParseTree)[string] rules;
static this()
static ParseTree delegate(ParseTree) @safe [string] before;
static ParseTree delegate(ParseTree) @safe [string] after;
static ParseTree delegate(ParseTree) @safe [string] rules;
static this() @trusted
{
veelo marked this conversation as resolved.
Show resolved Hide resolved
rules["Grammar"] = toDelegate(&Grammar);
rules["Definition"] = toDelegate(&Definition);
Expand Down
Loading