nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
ast.hpp
1// include/ast.hpp
2#pragma once
3#include <memory>
4#include <string>
5#include <utility>
6#include <vector>
7
8namespace nk {
9
10enum class NodeType {
11 NUMBER_LITERAL,
12 IMAG_LITERAL,
13 STRING_LITERAL,
14 BOOL_LITERAL,
15 IDENTIFIER,
16 BINARY_OP,
17 UNARY_OP,
18 ASSIGN,
19 MULTI_ASSIGN,
20 INDEX,
21 CELL_INDEX,
22 FIELD_ACCESS,
23 DYNAMIC_FIELD_ACCESS, // s.(expr) — field name from expression
24 MATRIX_LITERAL,
25 CELL_LITERAL,
26 CALL,
27 COLON_EXPR,
28 IF_STMT,
29 FOR_STMT,
30 WHILE_STMT,
31 BREAK_STMT,
32 CONTINUE_STMT,
33 RETURN_STMT,
34 SWITCH_STMT,
35 FUNCTION_DEF,
36 // classdef. CLASSDEF_DEF: strValue = class name; paramNames =
37 // superclass names (`< Base & ...`); children = a mix of
38 // CLASSDEF_PROPERTY and FUNCTION_DEF (methods incl. the constructor).
39 // CLASSDEF_PROPERTY: strValue = property name; children[0] = default
40 // expression (absent → default []). See object_model.md.
41 CLASSDEF_DEF,
42 CLASSDEF_PROPERTY,
43 // One `enumeration` member: strValue = member name; children = constructor
44 // argument expressions (empty for a plain `Red`, present for `Monday(1)`).
45 CLASSDEF_ENUM_MEMBER,
46 // Superclass-qualified reference `lhs@Base`: children[0] = lhs (the
47 // object var in a constructor, or a method-name identifier in a method),
48 // strValue = Base class name. Wrapped in a CALL for `lhs@Base(args)`.
49 SUPERCLASS_REF,
50 BLOCK,
51 EXPR_STMT,
52 END_VAL,
53 ANON_FUNC,
54 TRY_STMT,
55 GLOBAL_STMT,
56 PERSISTENT_STMT,
57 DELETE_ASSIGN,
58 COMMAND_CALL,
59 DQSTRING_LITERAL,
60};
61
62struct ASTNode;
63using ASTNodePtr = std::unique_ptr<ASTNode>;
64
65struct ASTNode
66{
67 NodeType type;
68 int line = 0;
69 int col = 0;
70 int endLine = 0; // line of closing 'end' keyword (for loops, if, switch, etc.)
71 // Position one past the last character of the statement's TEXTUAL
72 // form (so e.g. for `a = 1;` endCol points to col after `;`).
73 // Populated by the parser for simple statements via
74 // consumeStmtTerminator() right when the trailing ';' / ',' token
75 // is consumed. Stays 0 when no terminator was present — callers
76 // (graph view) treat 0 as "slice to end of line".
77 int endCol = 0;
78
79 std::string strValue;
80 double numValue = 0;
81 bool boolValue = false;
82 bool suppressOutput = false;
83
84 std::vector<ASTNodePtr> children;
85 std::vector<std::string> paramNames;
86 std::vector<std::string> returnNames;
87 // classdef only: attributes of the enclosing properties/methods block,
88 // stored as flat tokens (e.g. {"Static"}, {"Constant"},
89 // {"Access","private"}) on each CLASSDEF_PROPERTY / method FUNCTION_DEF.
90 std::vector<std::string> classAttrs;
91
92 // MULTI_ASSIGN only: one lvalue expression per output target when at
93 // least one target is a complex lvalue (`s.f`, `a(i)`, `c{i}`, ...).
94 // Empty when every target is a bare identifier or `~` (the common
95 // case stays on the fast returnNames-only path). A nullptr entry
96 // denotes an ignored `~` output. When non-empty, the size matches
97 // returnNames and this is the authoritative target list.
98 std::vector<ASTNodePtr> lhsTargets;
99
100 std::vector<std::pair<ASTNodePtr, ASTNodePtr>> branches;
101 ASTNodePtr elseBranch;
102
103 // Cached operator function pointer (set on first eval, avoids hash lookup)
104 mutable const void *cachedOp = nullptr;
105 // Cached builtin ID for inline scalar evaluation (0 = not resolved, -1 = not a builtin)
106 mutable int8_t cachedBuiltinId = 0;
107 // Cached pointer to UserFunction (for user-defined function calls)
108 mutable const void *cachedUserFunc = nullptr;
109
110 ASTNode()
111 : type(NodeType::NUMBER_LITERAL)
112 {}
113 explicit ASTNode(NodeType t)
114 : type(t)
115 {}
116};
117
118ASTNodePtr makeNode(NodeType t);
119ASTNodePtr makeNode(NodeType t, int line, int col);
120ASTNodePtr cloneNode(const ASTNode *src);
121
122// Walk a chain of FIELD_ACCESS nodes rooted at an IDENTIFIER and produce
123// the dotted name (`pkg.sub.foo` for `pkg.sub.foo` or its enclosing CALL
124// node's funcNode). Returns the empty string when the chain doesn't fit
125// the qualified-name shape — caller falls through to other paths.
126//
127// On success, *rootIdent is set to the IDENTIFIER node at the chain root
128// (callers need it for variable-shadow checks).
129std::string tryBuildQualifiedName(const ASTNode *node,
130 const ASTNode **rootIdent = nullptr);
131
132} // namespace nk