diff --git a/langutils.d b/langutils.d index 6a292b0..42018b4 100644 --- a/langutils.d +++ b/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 { TokenType type; diff --git a/parser.d b/parser.d index 500d195..82bcd77 100644 --- a/parser.d +++ b/parser.d @@ -226,6 +226,10 @@ string parseTypeDeclaration(const Token[] tokens, ref size_t index) case TokenType.BitAnd: type ~= tokens[index++].value; break; + case TokenType.Function: + type ~= " " ~ tokens[index++].value; + type ~= parenContent(tokens, index); + break; default: break buildingType; } @@ -510,35 +514,76 @@ body ++index; Enum e = new Enum; 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) { - ++index; - e.type = tokens[index++].value; + index++; + if (!isIdentifierOrType(tokens[index])) + skipBlockStatement(tokens, index); + else + enumType = tokens[index++].value; } - else - e.type = "uint"; - if (tokens[index] != TokenType.LBrace) - { - tokens.skipBlockStatement(index); - return e; - } +enumBody: auto r = betweenBalancedBraces(tokens, index); 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; - member.line = r[i].lineNumber; - member.name = r[i].value; - e.members ~= member; - r.skipPastNext(TokenType.Comma, i); + m.line = r[i + 1].lineNumber; + m.name = r[i + 1].value; + m.type = r[i].value; + } + 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 - ++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; } @@ -641,6 +686,7 @@ body { switch(r[i].type) { + case TokenType.Alias: case TokenType.In: case TokenType.Out: case TokenType.Ref: diff --git a/schema/dscanner-schema.json b/schema/dscanner-schema.json new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/schema/dscanner-schema.json @@ -0,0 +1 @@ + diff --git a/types.d b/types.d index d069864..f70dc50 100644 --- a/types.d +++ b/types.d @@ -88,7 +88,7 @@ protected: void printMembers(File f, uint indent = 0) const { - writeJSONString(f, "name", name, indent); + writeJSONString(f, "name", name == null ? "<>" : name, indent); f.writeln(","); f.write(std.array.replicate(" ", indent), "\"line\" : ", line); f.writeln(","); @@ -326,6 +326,7 @@ struct EnumMember { uint line; string name; + string type; } /** @@ -335,8 +336,9 @@ class Enum : Base { public: - /// Base type for this enum - string type; + /// True in the case of "enum a {b, c}" or + /// False in the case of "enum x = 5" or "enum :double {x = 12.9, y = 8.3}" + bool hasMembers; /// Enum members; may be empty EnumMember[] members; @@ -345,9 +347,12 @@ public: { auto app = appender!(string[])(); 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; } @@ -357,14 +362,14 @@ protected: override void printMembers(File f, uint indent = 0) const { super.printMembers(f, indent); - f.writeln(","); - writeJSONString(f, "type", type, indent); f.writeln(",\n", std.array.replicate(" ", indent), "\"members\" : ["); foreach(i, member; members) { f.writeln(std.array.replicate(" ", indent + 1), "{"); writeJSONString(f, "name", member.name, indent + 2); f.writeln(","); + writeJSONString(f, "type", member.type, indent + 2); + f.writeln(","); f.writeln(std.array.replicate(" ", indent + 2), "\"line\" : ", member.line); f.write(std.array.replicate(" ", indent + 1), "}"); if (i + 1 < members.length) @@ -663,7 +668,7 @@ public: continue; Tuple!(string, string)[string] typeMap; foreach (member; e.members) - typeMap[member.name] = Tuple!(string, string)(e.type, "e"); + typeMap[member.name] = Tuple!(string, string)(member.type, "e"); return typeMap; } }