Fix issue #20
This commit is contained in:
parent
fcf6578232
commit
3054914e2f
36
langutils.d
36
langutils.d
|
@ -584,6 +584,42 @@ static this()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure string getTypeFromToken(ref const Token t)
|
||||||
|
{
|
||||||
|
switch (t.type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case TokenType.DoubleLiteral:
|
||||||
|
return "double";
|
||||||
|
case TokenType.FloatLiteral:
|
||||||
|
return "float";
|
||||||
|
case TokenType.IntLiteral:
|
||||||
|
return "int";
|
||||||
|
case TokenType.RealLiteral:
|
||||||
|
return "real";
|
||||||
|
case TokenType.UnsignedIntLiteral:
|
||||||
|
return "uint";
|
||||||
|
case TokenType.UnsignedLongLiteral:
|
||||||
|
return "ulong";
|
||||||
|
case TokenType.LongLiteral:
|
||||||
|
return "long";
|
||||||
|
case TokenType.DStringLiteral:
|
||||||
|
return "dstring";
|
||||||
|
case TokenType.StringLiteral:
|
||||||
|
return "string";
|
||||||
|
case TokenType.WStringLiteral:
|
||||||
|
return "wstring";
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pure bool isIdentifierOrType(ref const Token t)
|
||||||
|
{
|
||||||
|
return t.type == TokenType.Identifier || (t.type > TokenType.TYPES_BEGIN
|
||||||
|
&& TokenType.TYPES_END);
|
||||||
|
}
|
||||||
|
|
||||||
struct Token
|
struct Token
|
||||||
{
|
{
|
||||||
TokenType type;
|
TokenType type;
|
||||||
|
|
80
parser.d
80
parser.d
|
@ -226,6 +226,10 @@ string parseTypeDeclaration(const Token[] tokens, ref size_t index)
|
||||||
case TokenType.BitAnd:
|
case TokenType.BitAnd:
|
||||||
type ~= tokens[index++].value;
|
type ~= tokens[index++].value;
|
||||||
break;
|
break;
|
||||||
|
case TokenType.Function:
|
||||||
|
type ~= " " ~ tokens[index++].value;
|
||||||
|
type ~= parenContent(tokens, index);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break buildingType;
|
break buildingType;
|
||||||
}
|
}
|
||||||
|
@ -510,35 +514,76 @@ body
|
||||||
++index;
|
++index;
|
||||||
Enum e = new Enum;
|
Enum e = new Enum;
|
||||||
e.line = tokens[index].lineNumber;
|
e.line = tokens[index].lineNumber;
|
||||||
e.name = tokens[index++].value;
|
string enumType;
|
||||||
|
|
||||||
|
if (tokens[index] == TokenType.LBrace)
|
||||||
|
goto enumBody;
|
||||||
|
|
||||||
|
if (isIdentifierOrType(tokens[index]))
|
||||||
|
{
|
||||||
|
if (index + 1 < tokens.length && tokens[index + 1] == TokenType.Identifier)
|
||||||
|
{
|
||||||
|
// enum long l = 4;
|
||||||
|
EnumMember m;
|
||||||
|
m.type = tokens[index++].value;
|
||||||
|
m.line = tokens[index].lineNumber;
|
||||||
|
e.name = m.name = tokens[index].value;
|
||||||
|
e.members ~= m;
|
||||||
|
skipBlockStatement(tokens, index);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// enum m = "abcd";
|
||||||
|
e.name = tokens[index].value;
|
||||||
|
EnumMember m;
|
||||||
|
m.name = e.name;
|
||||||
|
m.line = tokens[index].lineNumber;
|
||||||
|
m.type = getTypeFromToken(tokens[index + 2]);
|
||||||
|
e.members ~= m;
|
||||||
|
skipBlockStatement(tokens, index);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tokens[index] == TokenType.Colon)
|
if (tokens[index] == TokenType.Colon)
|
||||||
{
|
{
|
||||||
++index;
|
index++;
|
||||||
e.type = tokens[index++].value;
|
if (!isIdentifierOrType(tokens[index]))
|
||||||
|
skipBlockStatement(tokens, index);
|
||||||
|
else
|
||||||
|
enumType = tokens[index++].value;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
e.type = "uint";
|
|
||||||
|
|
||||||
if (tokens[index] != TokenType.LBrace)
|
enumBody:
|
||||||
{
|
|
||||||
tokens.skipBlockStatement(index);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto r = betweenBalancedBraces(tokens, index);
|
auto r = betweenBalancedBraces(tokens, index);
|
||||||
for (size_t i = 0; i < r.length;)
|
for (size_t i = 0; i < r.length;)
|
||||||
{
|
{
|
||||||
if (r[i].type == TokenType.Identifier)
|
EnumMember m;
|
||||||
|
if (isIdentifierOrType(r[i]) && i + 1 < r.length && isIdentifierOrType(r[i + 1]))
|
||||||
{
|
{
|
||||||
EnumMember member;
|
m.line = r[i + 1].lineNumber;
|
||||||
member.line = r[i].lineNumber;
|
m.name = r[i + 1].value;
|
||||||
member.name = r[i].value;
|
m.type = r[i].value;
|
||||||
e.members ~= member;
|
}
|
||||||
r.skipPastNext(TokenType.Comma, i);
|
else if (isIdentifierOrType(r[i]) && i + 1 < r.length && r[i + 1] == TokenType.Assign)
|
||||||
|
{
|
||||||
|
if (enumType == null && i + 2 < r.length)
|
||||||
|
m.type = getTypeFromToken(r[i + 2]);
|
||||||
|
else
|
||||||
|
m.type = enumType;
|
||||||
|
m.line = r[i].lineNumber;
|
||||||
|
m.name = r[i].value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++i;
|
{
|
||||||
|
m.line = r[i].lineNumber;
|
||||||
|
m.name = r[i].value;
|
||||||
|
m.type = enumType == null ? "int" : enumType;
|
||||||
|
}
|
||||||
|
e.members ~= m;
|
||||||
|
skipPastNext(r, TokenType.Comma, i);
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -641,6 +686,7 @@ body
|
||||||
{
|
{
|
||||||
switch(r[i].type)
|
switch(r[i].type)
|
||||||
{
|
{
|
||||||
|
case TokenType.Alias:
|
||||||
case TokenType.In:
|
case TokenType.In:
|
||||||
case TokenType.Out:
|
case TokenType.Out:
|
||||||
case TokenType.Ref:
|
case TokenType.Ref:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
21
types.d
21
types.d
|
@ -88,7 +88,7 @@ protected:
|
||||||
|
|
||||||
void printMembers(File f, uint indent = 0) const
|
void printMembers(File f, uint indent = 0) const
|
||||||
{
|
{
|
||||||
writeJSONString(f, "name", name, indent);
|
writeJSONString(f, "name", name == null ? "<<anonymous>>" : name, indent);
|
||||||
f.writeln(",");
|
f.writeln(",");
|
||||||
f.write(std.array.replicate(" ", indent), "\"line\" : ", line);
|
f.write(std.array.replicate(" ", indent), "\"line\" : ", line);
|
||||||
f.writeln(",");
|
f.writeln(",");
|
||||||
|
@ -326,6 +326,7 @@ struct EnumMember
|
||||||
{
|
{
|
||||||
uint line;
|
uint line;
|
||||||
string name;
|
string name;
|
||||||
|
string type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -335,8 +336,9 @@ class Enum : Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Base type for this enum
|
/// True in the case of "enum a {b, c}" or
|
||||||
string type;
|
/// False in the case of "enum x = 5" or "enum :double {x = 12.9, y = 8.3}"
|
||||||
|
bool hasMembers;
|
||||||
|
|
||||||
/// Enum members; may be empty
|
/// Enum members; may be empty
|
||||||
EnumMember[] members;
|
EnumMember[] members;
|
||||||
|
@ -345,9 +347,12 @@ public:
|
||||||
{
|
{
|
||||||
auto app = appender!(string[])();
|
auto app = appender!(string[])();
|
||||||
app.put(format("%s\t%s\t%d;\"\tg", name, fileName, line));
|
app.put(format("%s\t%s\t%d;\"\tg", name, fileName, line));
|
||||||
foreach (EnumMember member; members)
|
if (hasMembers)
|
||||||
{
|
{
|
||||||
app.put(format("%s\t%s\t%d;\"\te\tenum:%s", member.name, fileName, member.line, name));
|
foreach (EnumMember member; members)
|
||||||
|
{
|
||||||
|
app.put(format("%s\t%s\t%d;\"\te\tenum:%s", member.name, fileName, member.line, name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return app.data;
|
return app.data;
|
||||||
}
|
}
|
||||||
|
@ -357,14 +362,14 @@ protected:
|
||||||
override void printMembers(File f, uint indent = 0) const
|
override void printMembers(File f, uint indent = 0) const
|
||||||
{
|
{
|
||||||
super.printMembers(f, indent);
|
super.printMembers(f, indent);
|
||||||
f.writeln(",");
|
|
||||||
writeJSONString(f, "type", type, indent);
|
|
||||||
f.writeln(",\n", std.array.replicate(" ", indent), "\"members\" : [");
|
f.writeln(",\n", std.array.replicate(" ", indent), "\"members\" : [");
|
||||||
foreach(i, member; members)
|
foreach(i, member; members)
|
||||||
{
|
{
|
||||||
f.writeln(std.array.replicate(" ", indent + 1), "{");
|
f.writeln(std.array.replicate(" ", indent + 1), "{");
|
||||||
writeJSONString(f, "name", member.name, indent + 2);
|
writeJSONString(f, "name", member.name, indent + 2);
|
||||||
f.writeln(",");
|
f.writeln(",");
|
||||||
|
writeJSONString(f, "type", member.type, indent + 2);
|
||||||
|
f.writeln(",");
|
||||||
f.writeln(std.array.replicate(" ", indent + 2), "\"line\" : ", member.line);
|
f.writeln(std.array.replicate(" ", indent + 2), "\"line\" : ", member.line);
|
||||||
f.write(std.array.replicate(" ", indent + 1), "}");
|
f.write(std.array.replicate(" ", indent + 1), "}");
|
||||||
if (i + 1 < members.length)
|
if (i + 1 < members.length)
|
||||||
|
@ -663,7 +668,7 @@ public:
|
||||||
continue;
|
continue;
|
||||||
Tuple!(string, string)[string] typeMap;
|
Tuple!(string, string)[string] typeMap;
|
||||||
foreach (member; e.members)
|
foreach (member; e.members)
|
||||||
typeMap[member.name] = Tuple!(string, string)(e.type, "e");
|
typeMap[member.name] = Tuple!(string, string)(member.type, "e");
|
||||||
return typeMap;
|
return typeMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue