aboutsummaryrefslogtreecommitdiff
path: root/src/eval.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.cc')
-rw-r--r--src/eval.cc88
1 files changed, 69 insertions, 19 deletions
diff --git a/src/eval.cc b/src/eval.cc
index f25f6cd..82bd09c 100644
--- a/src/eval.cc
+++ b/src/eval.cc
@@ -13,37 +13,36 @@
#include <vector>
#include <string>
+#include "magic_enum/magic_enum.hpp"
+
+#include "error.h"
+#include "lexer/lexer_class.h"
+#include "lexer/ast.h"
+#include "lexer/token.h"
+#include "lexer/enum_type.h"
+#include "lexer/symbol_property.h"
+
using namespace std;
extern char **environ;
namespace ov4
{
-
-/*
- * eval - Evaluate the command line that the user has just typed in
- *
- * If the user has requested a built-in command (quit, jobs, bg or fg)
- * then execute it immediately. Otherwise, fork a child process and
- * run the job in the context of the child. If the job is running in
- * the foreground, wait for it to terminate and then return. Note:
- * each child process must have a unique process group ID so that our
- * background children don't receive SIGINT (SIGTSTP) from the kernel
- * when we type ctrl-c (ctrl-z) at the keyboard.
-*/
-void eval(char *cmdline)
+
+int eval_exe(string s, bool is_aync)
{
+ char cmdline[MAXLINE];
+ strcpy(cmdline, s.c_str());
char arg[MAXARGS][MAXLINE];
char *argv[MAXARGS];
for (int i = 0 ; i < MAXARGS; i++)
{
argv[i] = &arg[i][0];
}
- int ground = parseline(cmdline, argv);
+ parseline(cmdline, argv);
+
+ if (exe_bultin_command(argv)) return 0;
- if (argv[0] == nullptr) return;
- if (exe_bultin_command(argv)) return;
-
// block_io signals can stop shell
// when child is at foreground, parent shell is at background
sigprocmask(SIG_BLOCK, &block_io, nullptr);
@@ -60,7 +59,7 @@ void eval(char *cmdline)
if (pid == 0) // child
{
setpgid(0, 0);
- if (!ground) // foreground
+ if (!is_aync) // foreground
tcsetpgrp(tty_fd, getpgrp());
sigprocmask(SIG_SETMASK, &prev, nullptr);
@@ -101,7 +100,7 @@ void eval(char *cmdline)
// parent
- if (!ground) // foreground
+ if (!is_aync) // foreground
{
addjob(pid, FG, cmdline);
sigset_t prev_with_sigchld_blocked = prev;
@@ -119,6 +118,57 @@ void eval(char *cmdline)
+ return 0;
+}
+
+void eval_tree_cd(size_t i, const T_lexer &lexer_instance)
+{
+ // TODO: async
+ if (lexer_instance.ast[i].token_type == TEXT)
+ {
+ eval_exe(lexer_instance.ast[i].command_text, false);
+ return;
+ }
+ if (lexer_instance.ast[i].left != string::npos)
+ {
+ eval_tree_cd(lexer_instance.ast[i].left, lexer_instance);
+ }
+
+ if (lexer_instance.ast[i].right != string::npos)
+ {
+ eval_tree_cd(lexer_instance.ast[i].right, lexer_instance);
+ }
+}
+
+/*
+ * eval - Evaluate the command line that the user has just typed in
+ *
+ * If the user has requested a built-in command (quit, jobs, bg or fg)
+ * then execute it immediately. Otherwise, fork a child process and
+ * run the job in the context of the child. If the job is running in
+ * the foreground, wait for it to terminate and then return. Note:
+ * each child process must have a unique process group ID so that our
+ * background children don't receive SIGINT (SIGTSTP) from the kernel
+ * when we type ctrl-c (ctrl-z) at the keyboard.
+*/
+void eval(char *cmdline)
+{
+ string s = cmdline;
+ T_lexer lexer_instance;
+
+ try
+ {
+ lexer_instance.tokenizer(s);
+ lexer_instance.parse(0, lexer_instance.token.size(), lexer_instance.alloc_ast());
+ }
+ catch(const T_error &e)
+ {
+ cerr << "Error: " << magic_enum::enum_name(e.code) << endl;
+ cerr << "what: " << e.what() << endl;
+ return;
+ }
+
+ eval_tree_cd(0, lexer_instance);
return;
}