aboutsummaryrefslogtreecommitdiff
path: root/include/lexer/ast.h
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-09-05 16:34:38 +0000
committer_ov4 <ov4@ov4.org>2026-09-05 16:34:38 +0000
commite4818de45bea799629b288c30514a52fc22abfb2 (patch)
tree9420517986acd2f2f4f19841399da5b202679623 /include/lexer/ast.h
parent0e756a669f05a569faf0d1c90d66b5ddff5c7e78 (diff)
rename
Diffstat (limited to 'include/lexer/ast.h')
-rw-r--r--include/lexer/ast.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/include/lexer/ast.h b/include/lexer/ast.h
new file mode 100644
index 0000000..05ba553
--- /dev/null
+++ b/include/lexer/ast.h
@@ -0,0 +1,139 @@
+#pragma once
+
+#include <string>
+
+#include "parser/enum_type.h"
+#include "parser/token.h"
+#include "parser/shared.h"
+
+using namespace std; // remove this
+
+namespace ov4
+{
+
+class T_token;
+
+class T_ast
+{
+public:
+ T_ast() = default;
+
+ enum_token_type token_type;
+ string command_text;
+ size_t left = string::npos;
+ size_t right = string::npos;
+};
+
+string final_trim(size_t _begin, size_t _end)
+{
+ string s;
+ for (size_t i = _begin; i < _end; i++)
+ {
+ if (token[i].token_type != TEXT)
+ continue;
+ s += token[i].text + " ";
+ }
+ s = s.substr(0, s.size()-1); // eat final space
+ return s;
+}
+
+size_t alloc_ast()
+{
+ ast.emplace_back();
+ return ast_index++;
+}
+
+int get_pivot_order(enum_token_type x)
+{
+ switch(x)
+ {
+ case ASYNC:
+ case SEMICOLON:
+ return 1000;
+
+ case LOGIC_AND:
+ case LOGIC_OR:
+ return 500;
+
+ case PIPE:
+ return 100;
+
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+bool is_operator(enum_token_type x)
+{
+ switch(x)
+ {
+ case LOGIC_AND:
+ case LOGIC_OR:
+ case PIPE:
+ case ASYNC:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// region [begin, end)
+void parse(size_t cmd_begin, size_t cmd_end, size_t ast_vec)
+{
+ int current_depth = 0;
+ int current_order = -1;
+ int max_depth = -1;
+ size_t found_pos = string::npos;
+
+ for (size_t i = cmd_begin; i < cmd_end; i++)
+ {
+ if (token[i].bracket_depth > max_depth)
+ max_depth = token[i].bracket_depth;
+ }
+
+
+ while (found_pos == string::npos)
+ {
+ // scan from right to left
+ for (size_t i = cmd_end - 1; i >= cmd_begin && i < cmd_end; i--)
+ {
+ // if same depth
+ // and higher order number
+ if (token[i].bracket_depth == current_depth
+ && is_operator(token[i].token_type)
+ && get_pivot_order(token[i].token_type) > current_order)
+ {
+ current_order = get_pivot_order(token[i].token_type);
+ found_pos = i;
+ println("Found pos: {} order: {} depth: {}", i, current_order, current_depth);
+ }
+ }
+ current_depth++;
+ if (current_depth > max_depth)
+ {
+ break;
+ }
+ }
+
+ if (found_pos == string::npos)
+ {
+ println("Smallest unit");
+ ast[ast_vec].token_type = TEXT;
+ ast[ast_vec].command_text = final_trim(cmd_begin, cmd_end);
+ return;
+ }
+
+ size_t l = alloc_ast();
+ size_t r = alloc_ast();
+ ast[ast_vec].left = l;
+ ast[ast_vec].right = r;
+ ast[ast_vec].token_type = token[found_pos].token_type;
+
+ println("Parse sub: {}, {}, {}", cmd_begin, found_pos, cmd_end);
+
+ parse(cmd_begin, found_pos, l);
+ parse(found_pos+1, cmd_end, r);
+}
+
+}