Skip to content

Commit

Permalink
libnixf: generate diagnostic declarations from python (#548)
Browse files Browse the repository at this point in the history
  • Loading branch information
inclyc authored Jul 21, 2024
1 parent 963dd36 commit 87135e0
Show file tree
Hide file tree
Showing 12 changed files with 421 additions and 147 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/build/

/html/

__pycache__
27 changes: 15 additions & 12 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{ lib
, stdenv
, boost182
, gtest
, lit
, llvmPackages
, meson
, ninja
, nix
, nixpkgs-fmt
, pkg-config
, nlohmann_json
{
lib,
stdenv,
boost182,
gtest,
lit,
llvmPackages,
meson,
ninja,
nix,
nixpkgs-fmt,
pkg-config,
nlohmann_json,
python312,
}:

stdenv.mkDerivation {
Expand All @@ -23,6 +25,7 @@ stdenv.mkDerivation {
nativeBuildInputs = [
meson
ninja
python312
pkg-config
];

Expand Down
30 changes: 18 additions & 12 deletions libnixf/default.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{ lib
, stdenv
, meson
, ninja
, pkg-config
, lit
, nixpkgs-fmt
, gtest
, boost182
, nlohmann_json
{
lib,
stdenv,
meson,
ninja,
pkg-config,
lit,
nixpkgs-fmt,
gtest,
boost182,
nlohmann_json,
python312,
}:

stdenv.mkDerivation {
Expand All @@ -16,7 +18,11 @@ stdenv.mkDerivation {

src = ../.;

outputs = [ "out" "bin" "dev" ];
outputs = [
"out"
"bin"
"dev"
];

mesonBuildType = "release";

Expand All @@ -28,6 +34,7 @@ stdenv.mkDerivation {
meson
ninja
pkg-config
python312
];

nativeCheckInputs = [
Expand All @@ -41,7 +48,6 @@ stdenv.mkDerivation {
nlohmann_json
];


meta = {
mainProgram = "nixf";
description = "Nix language frontend, parser & semantic analysis";
Expand Down
11 changes: 6 additions & 5 deletions libnixf/include/nixf/Basic/Diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Range.h"

#include <cassert>
#include <optional>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -167,11 +168,7 @@ class Diagnostic : public PartialDiagnostic {
};

/// Internal kind
enum DiagnosticKind {
#define DIAG(SNAME, CNAME, SEVERITY, MESSAGE) DK_##CNAME,
#include "DiagnosticKinds.inc"
#undef DIAG
};
#include "DiagnosticEnum.h"

Diagnostic(DiagnosticKind Kind, LexerCursorRange Range)
: PartialDiagnostic(Range), Kind(Kind) {}
Expand All @@ -191,6 +188,10 @@ class Diagnostic : public PartialDiagnostic {
/// have the sname "bison"
[[nodiscard]] static const char *sname(DiagnosticKind Kind);

/// \brief Parse diagnostic "cname" to diagnostic id
[[nodiscard]] static std::optional<Diagnostic::DiagnosticKind>
parseKind(std::string_view SName);

[[nodiscard]] virtual const char *sname() const { return sname(kind()); }

Note &note(Note::NoteKind Kind, LexerCursorRange Range) {
Expand Down
68 changes: 0 additions & 68 deletions libnixf/include/nixf/Basic/DiagnosticKinds.inc

This file was deleted.

33 changes: 0 additions & 33 deletions libnixf/src/Basic/Diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,39 +36,6 @@ const char *nixf::Note::sname(NoteKind Kind) {
__builtin_unreachable();
}

nixf::Diagnostic::Severity nixf::Diagnostic::severity(DiagnosticKind Kind) {
switch (Kind) {
#define DIAG(SNAME, CNAME, SEVERITY, MESSAGE) \
case DK_##CNAME: \
return DS_##SEVERITY;
#include "nixf/Basic/DiagnosticKinds.inc"
#undef DIAG
}
assert(false && "Invalid diagnostic kind");
__builtin_unreachable();
}
const char *nixf::Diagnostic::message(DiagnosticKind Kind) {
switch (Kind) {
#define DIAG(SNAME, CNAME, SEVERITY, MESSAGE) \
case DK_##CNAME: \
return MESSAGE;
#include "nixf/Basic/DiagnosticKinds.inc"
#undef DIAG
}
assert(false && "Invalid diagnostic kind");
__builtin_unreachable();
}
const char *nixf::Diagnostic::sname(DiagnosticKind Kind) {
switch (Kind) {
#define DIAG(SNAME, CNAME, SEVERITY, MESSAGE) \
case DK_##CNAME: \
return SNAME;
#include "nixf/Basic/DiagnosticKinds.inc"
#undef DIAG
}
assert(false && "Invalid diagnostic kind");
__builtin_unreachable();
}
const char *nixf::Note::message(NoteKind Kind) {
switch (Kind) {
#define DIAG_NOTE(SNAME, CNAME, MESSAGE) \
Expand Down
120 changes: 120 additions & 0 deletions libnixf/src/Basic/Diagnostic.cpp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Generate "DiagnosticEnum.h"
from functools import reduce
from operator import add
import sys

from diagnostic import Diagnostic, diagnostics
from support import lines, indent


def gen_parse_id() -> list[str]:
def gen_case(d: Diagnostic) -> list[str]:
return [
"{" f'"{d["sname"]}", Diagnostic::DK_{d["cname"]}' "},",
]

return [
"std::optional<Diagnostic::DiagnosticKind> Diagnostic::parseKind(std::string_view SName) {",
*map(
indent,
[
"static std::unordered_map<std::string_view, nixf::Diagnostic::DiagnosticKind> DKMap {",
*map(indent, reduce(add, map(gen_case, diagnostics))),
"};",
"",
"auto It = DKMap.find(SName);",
"if (It != DKMap.end())",
" return It->second;",
"return std::nullopt;",
],
),
"}",
]


def gen_message() -> list[str]:
"Generate nixf::Diagnostic::message implementation"

def gen_case(d: Diagnostic) -> list[str]:
return [
f'case DK_{d["cname"]}:',
indent(f'return "{d["message"]}";'),
]

return [
"const char *Diagnostic::message(DiagnosticKind Kind) {",
*map(
indent,
[
"switch(Kind) {",
*reduce(add, map(gen_case, diagnostics)),
"}",
"__builtin_unreachable();",
],
),
"}",
]


def gen_serverity() -> list[str]:
"Generate nixf::Diagnostic::severity implementation"

def gen_case(d: Diagnostic) -> list[str]:
return [
f'case DK_{d["cname"]}:',
indent(f'return DS_{d["severity"]};'),
]

return [
"Diagnostic::Severity Diagnostic::severity(DiagnosticKind Kind) {",
*map(
indent,
[
"switch(Kind) {",
*reduce(add, map(gen_case, diagnostics)),
"}",
"__builtin_unreachable();",
],
),
"}",
]


def gen_sname() -> list[str]:
"Generate nixf::Diagnostic::sname implementation"

def gen_case(d: Diagnostic) -> list[str]:
return [
f'case DK_{d["cname"]}:',
indent(f'return "{d["sname"]}";'),
]

return [
"const char *Diagnostic::sname(DiagnosticKind Kind) {",
*map(
indent,
[
"switch(Kind) {",
*reduce(add, map(gen_case, diagnostics)),
"}",
"__builtin_unreachable();",
],
),
"}",
]


output = open(sys.argv[1], "w")
_ = output.write(
lines(
[
'#include "nixf/Basic/Diagnostic.h"',
"#include <unordered_map>",
"using namespace nixf;",
*gen_sname(),
*gen_serverity(),
*gen_message(),
*gen_parse_id(),
]
)
)
17 changes: 17 additions & 0 deletions libnixf/src/Basic/DiagnosticEnum.h.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generate "DiagnosticEnum.h"
import sys

from support import lines
from diagnostic import diagnostics


output = open(sys.argv[1], "w")
_ = output.write(
lines(
[
"enum DiagnosticKind {",
*map(lambda x: f" DK_{x['cname']},", diagnostics),
"};",
]
)
)
Loading

0 comments on commit 87135e0

Please sign in to comment.