nixd
Loading...
Searching...
No Matches
Basic.h
Go to the documentation of this file.
1#pragma once
2
3#include "nixf/Basic/Range.h"
4
5#include <boost/container/small_vector.hpp>
6
7#include <cassert>
8#include <string>
9
10namespace nixf {
11
12class Node {
13public:
14 enum NodeKind {
15#define NODE(NAME) NK_##NAME,
17#undef NODE
19#define EXPR(NAME) NK_##NAME,
21#undef EXPR
23 };
24
25private:
26 NodeKind Kind;
27 LexerCursorRange Range;
28
29protected:
30 explicit Node(NodeKind Kind, LexerCursorRange Range)
31 : Kind(Kind), Range(Range) {}
32
33public:
34 [[nodiscard]] NodeKind kind() const { return Kind; }
35 [[nodiscard]] LexerCursorRange range() const { return Range; }
36 [[nodiscard]] PositionRange positionRange() const { return Range.range(); }
37 [[nodiscard]] LexerCursor lCur() const { return Range.lCur(); }
38 [[nodiscard]] LexerCursor rCur() const { return Range.rCur(); }
39 [[nodiscard]] static const char *name(NodeKind Kind);
40 [[nodiscard]] const char *name() const { return name(Kind); }
41
42 using ChildVector = boost::container::small_vector<Node *, 8>;
43
44 [[nodiscard]] virtual ChildVector children() const = 0;
45
46 virtual ~Node() = default;
47
48 /// \brief Descendant node that contains the given range.
49 [[nodiscard]] const Node *descend(PositionRange Range) const {
50 if (!positionRange().contains(Range)) {
51 return nullptr;
52 }
53 for (const auto &Child : children()) {
54 if (!Child)
55 continue;
56 if (Child->positionRange().contains(Range)) {
57 return Child->descend(Range);
58 }
59 }
60 return this;
61 }
62
63 [[nodiscard]] std::string_view src(std::string_view Src) const {
64 auto Begin = lCur().offset();
65 auto Length = rCur().offset() - Begin;
66 return Src.substr(Begin, Length);
67 }
68};
69
70class Expr : public Node {
71protected:
72 explicit Expr(NodeKind Kind, LexerCursorRange Range) : Node(Kind, Range) {
73 assert(NK_BeginExpr <= Kind && Kind <= NK_EndExpr);
74 }
75
76public:
77 static bool classof(const Node *N) { return isExpr(N->kind()); }
78
79 static bool isExpr(NodeKind Kind) {
80 return NK_BeginExpr <= Kind && Kind <= NK_EndExpr;
81 }
82
83 /// \returns true if the expression might be evaluated to lambda.
84 static bool maybeLambda(NodeKind Kind) {
85 if (!isExpr(Kind))
86 return false;
87 switch (Kind) {
88 case Node::NK_ExprInt:
89 case Node::NK_ExprFloat:
90 case Node::NK_ExprAttrs:
91 case Node::NK_ExprString:
92 case Node::NK_ExprPath:
93 return false;
94 default:
95 return true;
96 }
97 }
98
99 [[nodiscard]] bool maybeLambda() const { return maybeLambda(kind()); }
100};
101
102/// \brief Misc node, used for parentheses, keywords, etc.
103///
104/// This is used for representing nodes that only location matters.
105/// Might be useful for linting.
106class Misc : public Node {
107public:
108 Misc(LexerCursorRange Range) : Node(NK_Misc, Range) {}
109
110 [[nodiscard]] ChildVector children() const override { return {}; }
111};
112
113/// \brief Identifier. Variable names, attribute names, etc.
114class Identifier : public Node {
115 const std::string Name;
116
117public:
118 Identifier(LexerCursorRange Range, std::string Name)
119 : Node(NK_Identifier, Range), Name(std::move(Name)) {}
120 [[nodiscard]] const std::string &name() const { return Name; }
121
122 [[nodiscard]] ChildVector children() const override { return {}; }
123};
124
125/// \brief Holds a "." in the language.
126class Dot : public Node {
127 const Node *Prev;
128 const Node *Next;
129
130public:
131 Dot(LexerCursorRange Range, const Node *Prev, const Node *Next)
132 : Node(NK_Dot, Range), Prev(Prev), Next(Next) {
133 assert(Prev);
134 }
135
136 [[nodiscard]] ChildVector children() const override { return {}; }
137
138 [[nodiscard]] const Node &prev() const {
139 assert(Prev);
140 return *Prev;
141 }
142 [[nodiscard]] const Node *next() const { return Next; }
143};
144
145} // namespace nixf
Holds a "." in the language.
Definition Basic.h:126
ChildVector children() const override
Definition Basic.h:136
const Node & prev() const
Definition Basic.h:138
Dot(LexerCursorRange Range, const Node *Prev, const Node *Next)
Definition Basic.h:131
const Node * next() const
Definition Basic.h:142
Expr(NodeKind Kind, LexerCursorRange Range)
Definition Basic.h:72
static bool classof(const Node *N)
Definition Basic.h:77
bool maybeLambda() const
Definition Basic.h:99
static bool isExpr(NodeKind Kind)
Definition Basic.h:79
static bool maybeLambda(NodeKind Kind)
Definition Basic.h:84
Identifier. Variable names, attribute names, etc.
Definition Basic.h:114
const std::string & name() const
Definition Basic.h:120
Identifier(LexerCursorRange Range, std::string Name)
Definition Basic.h:118
ChildVector children() const override
Definition Basic.h:122
PositionRange range() const
Definition Range.h:123
LexerCursor lCur() const
Definition Range.h:116
LexerCursor rCur() const
Definition Range.h:117
A point in the source file.
Definition Range.h:57
std::size_t offset() const
Offset in the source file, starting from 0.
Definition Range.h:102
Misc node, used for parentheses, keywords, etc.
Definition Basic.h:106
Misc(LexerCursorRange Range)
Definition Basic.h:108
ChildVector children() const override
Definition Basic.h:110
const Node * descend(PositionRange Range) const
Descendant node that contains the given range.
Definition Basic.h:49
const char * name() const
Definition Basic.h:40
LexerCursor lCur() const
Definition Basic.h:37
@ NK_EndExpr
Definition Basic.h:22
@ NK_BeginExpr
Definition Basic.h:18
NodeKind kind() const
Definition Basic.h:34
std::string_view src(std::string_view Src) const
Definition Basic.h:63
boost::container::small_vector< Node *, 8 > ChildVector
Definition Basic.h:42
LexerCursor rCur() const
Definition Basic.h:38
virtual ~Node()=default
PositionRange positionRange() const
Definition Basic.h:36
LexerCursorRange range() const
Definition Basic.h:35
Node(NodeKind Kind, LexerCursorRange Range)
Definition Basic.h:30
virtual ChildVector children() const =0