Skip to content
Open
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
9 changes: 9 additions & 0 deletions dstep/translator/MacroDefinition.d
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ string translate(CallExpr expression, ExpressionContext context)
expression.args.map!fmap.join(", "));
}

string translate(BracedExpr expr, ExpressionContext context)
{
return "null /* FIXME: " ~ expr.expr ~ " */";
}

string translate(Expression expression, ExpressionContext context)
{
import std.format : format;
Expand Down Expand Up @@ -350,6 +355,10 @@ string translate(Expression expression, ExpressionContext context)
condExpr.expr.translate(context),
condExpr.left.translate(context),
condExpr.right.translate(context));
},
delegate string(BracedExpr expr)
{
return expr.translate(context);
});
}

Expand Down
60 changes: 58 additions & 2 deletions dstep/translator/MacroParser.d
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,23 @@ class CondExpr
}
}

struct BracedExpr
{
string expr;

this (string expr)
{
this.expr = expr;
}

string toString()
{
import std.format : format;

return format("BracedExpr(expr = %s)", expr);
}
}

alias Expression = Algebraic!(
Identifier,
TypeIdentifier,
Expand Down Expand Up @@ -530,7 +547,8 @@ alias Expression = Algebraic!(
OrExpr,
LogicalAndExpr,
LogicalOrExpr,
CondExpr);
CondExpr,
BracedExpr);

Expression debraced(Expression expression)
{
Expand Down Expand Up @@ -1032,6 +1050,40 @@ Expression parseCondExpr(ref Token[] tokens, Cursor[string] table, bool defined)
return expr;
}

Expression parseBracedExpr(ref Token[] tokens)
{
if (tokens.empty)
return Expression.init;

auto local = tokens;

while (local.length >= 2 &&
acceptPunctuation!("(")(local) &&
local[$ - 1].kind == TokenKind.punctuation &&
local[$ - 1].spelling == ")")
{
local = local[0 .. $ - 1];
}

if (!local.empty &&
local.front.kind == TokenKind.punctuation &&
local.front.spelling == "{" &&
local.back.kind == TokenKind.punctuation &&
local.back.spelling == "}")
{
auto buffer = appender!string();
foreach (token; tokens)
{
buffer.put(token.spelling);
}
auto expr = Expression(BracedExpr(buffer.data));
tokens = [];
return expr;
}

return Expression.init;
}

bool parseBasicSpecifier(ref Token[] tokens, ref string spelling, Cursor[string] table)
{
import std.meta : AliasSeq;
Expand Down Expand Up @@ -1430,14 +1482,18 @@ Expression parseExpr(ref Token[] tokens, Cursor[string] table, bool defined)
if (condExpr.hasValue)
return condExpr;

auto bracedExpr = parseBracedExpr(tokens);
if (bracedExpr.hasValue)
return bracedExpr;

return Expression.init;
}

Expression parseExpr(ref Token[] tokens, bool defined)
{
Cursor[string] table;

return parseCondExpr(tokens, table, defined);
return parseExpr(tokens, table, defined);
}

Expression parseEnumMember(Token[] tokens, Cursor[string] table)
Expand Down
4 changes: 4 additions & 0 deletions dstep/translator/TypeInference.d
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ InferredType inferExpressionType(Expression expression)
return commonType(
condExpr.left.inferExpressionType(),
condExpr.right.inferExpressionType());
},
delegate InferredType(BracedExpr objectExpr)
{
return InferredType(Generic.init);
});
}

Expand Down
31 changes: 31 additions & 0 deletions tests/unit/MacroParsingTests.d
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,37 @@ unittest
assert(d !is null && d.expr.hasValue && d.expr.peek!CallExpr !is null);
}

unittest
{
auto a = parse(`#define NESTED { .inner = { 1, 2 } }`);
assert(a !is null);
assert(a.expr.hasValue);
assert(a.expr.peek!BracedExpr !is null);
auto braced1 = a.expr.get!BracedExpr;
assert(braced1.expr == `{.inner={1,2}}`);

auto b = parse(`#define MAKE(a) { .data = (a) }`);
assert(b !is null);
assert(b.expr.hasValue);
assert(b.expr.peek!BracedExpr !is null);
auto braced2 = b.expr.get!BracedExpr;
assert(braced2.expr == `{.data=(a)}`);

auto c = parse(`#define UUID { 0x5ae69b6a, 0xd191, 0x4609, {0xb7, 0xdc, 0x24, 0x80, 0x8e, 0xf9, 0x97, 0xb5 } }`);
assert(c !is null);
assert(c.expr.hasValue);
assert(c.expr.peek!BracedExpr !is null);
auto braced3 = c.expr.get!BracedExpr;
assert(braced3.expr == `{0x5ae69b6a,0xd191,0x4609,{0xb7,0xdc,0x24,0x80,0x8e,0xf9,0x97,0xb5}}`);

auto d = parse(`#define D (({ {1, 2}, {3, 4} }))`);
assert(d !is null);
assert(d.expr.hasValue);
assert(d.expr.peek!BracedExpr !is null);
auto braced4 = d.expr.get!BracedExpr;
assert(braced4.expr == `(({{1,2},{3,4}}))`);
}

// Test collection of type names.
unittest
{
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/MacroTranslTests.d
Original file line number Diff line number Diff line change
Expand Up @@ -841,3 +841,33 @@ extern (D) auto fun(T)(auto ref T a)
}
D");
}

unittest
{
assertTMD(q"C
#define NESTED { .inner = { 1, 2 } }
C", q"D
enum NESTED = null /* FIXME: {.inner={1,2}} */;
D");

assertTMD(q"C
#define INIT(val) { .data = (val), .len = sizeof(val) }
C", q"D
extern (D) auto INIT(T)(auto ref T val)
{
return null /* FIXME: {.data=(val),.len=sizeof(val)} */;
}
D");

assertTMD(q"C
#define UUID { 0x5ae69b6a, 0xd191, 0x4609, {0xb7, 0xdc, 0x24, 0x80, 0x8e, 0xf9, 0x97, 0xb5 } }
C", q"D
enum UUID = null /* FIXME: {0x5ae69b6a,0xd191,0x4609,{0xb7,0xdc,0x24,0x80,0x8e,0xf9,0x97,0xb5}} */;
D");

assertTMD(q"C
#define D (({ {1, 2}, {3, 4} }))
C", q"D
enum D = null /* FIXME: (({{1,2},{3,4}})) */;
D");
}