22#include < fstream>
33#include < iostream>
44#include < lbd/repl.h>
5+ #include < lbd/term.h>
56#include < lbd/fe/lexer.h>
67#include < lbd/fe/parser.h>
78#include < lbd/intp/interpreter.h>
89
9- namespace repl {
10- static bool force_on_env_dump = false ;
11- static bool debug_enabled = false ;
12-
13- static std::optional<std::string> read_file (const std::string &filepath) {
14- std::ifstream file (filepath);
15- if (!file) {
16- // Could not open file
17- return std::nullopt ;
18- }
19- return std::string ((std::istreambuf_iterator<char >(file)), std::istreambuf_iterator<char >());
20- }
10+ // TODO: Add support for clicking enter during lambda expression definition
2111
12+ namespace repl {
2213 static void process_load_command (const std::string &arg,
2314 std::optional<std::shared_ptr<intp::interp::Env> > &shared_env) {
2415 try {
25- const std::string filepath = arg;
16+ const std::string & filepath = arg;
2617 if (!std::filesystem::exists (filepath)) {
27- std::cerr << " error: filepath "
28- << filepath << " does not exist"
29- << std::endl;
18+ std::cerr << colors::RED << " error: filepath " << filepath << " does not exist"
19+ << colors::RESET << std::endl;
3020 return ;
3121 }
3222 fe::lexer::Lexer lexer (filepath, fe::lexer::FromFile{});
@@ -46,45 +36,29 @@ namespace repl {
4636 }
4737 }
4838 }
49- std::cout << " info: file loaded: " << filepath << std::endl;
39+ std::cout << colors:: BLUE << " info: file loaded: " << filepath << colors:: RESET << std::endl;
5040 } catch (const std::exception &ex) {
51- std::cerr << " error: could not load file: " << ex.what () << std::endl;
41+ std::cerr << colors:: RED << " error: could not load file: " << ex.what () << colors:: RESET << std::endl;
5242 }
5343 }
5444
55- static void help () {
56- std::cout
57- << " available REPL commands:\n "
58- << " general:\n "
59- << " :q, :quit, :exit Exit the REPL\n "
60- << " :c, :clear, :cls Clear the screen\n "
61- << " :h, :help, :? Show this help message\n "
62- << " :l <filepath>, :load <filepath> Load file into REPL\n "
63- << " :r, :reload Reset environment (forget all bindings)\n "
64- << " :d, :debug Toggle debug mode\n "
65- << " inspection:\n "
66- << " :e, :env Show all variables in current environment\n "
67- << " :force Toggle forcing evaluation when dumping env\n "
68- << " current options:\n "
69- << " debug [" << (debug_enabled ? " on " : " off" ) <<
70- " ] (use :debug to toggle)\n "
71- << " force-on-env-dump [" << (force_on_env_dump ? " on " : " off" ) <<
72- " ] (use :force to toggle)"
73- << std::endl;
74- }
45+ #define on_off (val ) ((val) ? " on " : " off" )
7546
7647 void loop (const bool debug) {
77- debug_enabled = debug;
78- std::cout << " lambda-discipline REPL.\n type :quit to exit." << std::endl;
48+ enable_virtual_terminal ();
49+ static bool force_on_env_dump = false ;
50+ static bool debug_enabled = false ;
51+ std::cout << colors::BLUE << " Welcome to lambda-discipline REPL.\n Type :quit to exit."
52+ << colors::RESET << std::endl;
7953 std::string line;
8054 std::optional<std::shared_ptr<intp::interp::Env> > shared_global_env = std::nullopt ;
8155 while (true ) {
82- std::cout << " lbd> " ;
56+ std::cout << colors:: CYAN << " \n >> " << colors:: RESET ;
8357 if (!std::getline (std::cin, line)) {
8458 break ; // EOF (C-d / C-z)
8559 }
8660 if (line == " :q" || line == " :quit" || line == " :exit" ) {
87- std::cout << " exiting REPL" << std::endl;
61+ std::cout << colors:: BLUE << " exiting REPL" << colors:: RESET << std::endl;
8862 break ;
8963 }
9064 if (line == " :c" || line == " :clear" || line == " :cls" ) {
@@ -96,24 +70,41 @@ namespace repl {
9670 continue ;
9771 }
9872 if (line == " :h" || line == " :help" || line == " :?" ) {
99- help ();
73+ std::cout << std::endl;
74+ print_table ({" General Commands" , " Argument" , " Description" }, {
75+ {" :q, :quit, :exit" , " " , " Clear the screen" },
76+ {" :c, :clear, :cls" , " " , " Exit the REPL" },
77+ {" :h, :help, :?" , " " , " Display this help message" },
78+ {" :l, :load" , " <filepath>" , " Load file into REPL" },
79+ {" :r, :reset" , " " , " Reset environment" },
80+ {" :d, :debug" , " " , " Toogle debug mode" }
81+ }, colors::GREEN );
82+ std::cout << std::endl;
83+ print_table ({" Inspection Commands" , " Argument" , " Description" }, {
84+ {" :e, :env" , " " , " Dump environment bindings" },
85+ {" :force" , " " , " Force thunk evaluation on dump" }
86+ }, colors::GREEN );
87+ std::cout << std::endl;
88+ print_table ({" Options" , " State" , " Help" }, {
89+ {" debug" , on_off (debug_enabled), " use :debug to toggle" },
90+ {" force-on-env-dump" , on_off (force_on_env_dump), " use :force to toggle" }
91+ }, colors::GREEN );
10092 continue ;
10193 }
10294 if (line == " :env" || line == " :e" ) {
95+ std::cout << std::endl;
10396 if (shared_global_env) {
104- std::cout << " info: environment bindings:" << std::endl;
105- (*shared_global_env)->dump (std::cout, force_on_env_dump);
97+ print_table ({" Symbol" , " Thunk" }, (*shared_global_env)->to_vector (force_on_env_dump), colors::GREEN );
10698 } else {
107- std::cout << " info: environment is empty " << std::endl ;
99+ print_table ({ " Symbol " , " Thunk " }, {{ " Empty " }}, colors:: GREEN ) ;
108100 }
109101 continue ;
110102 }
111- if (line == " :reload " || line == " :r" ) {
103+ if (line == " :reset " || line == " :r" ) {
112104 shared_global_env.reset ();
113- std::cout << " info: environment reloaded" << std::endl;
114105 continue ;
115106 }
116- if (line == " :debug" ) {
107+ if (line == " :debug" || line == " :d " ) {
117108 debug_enabled = !debug_enabled;
118109 continue ;
119110 }
@@ -139,21 +130,22 @@ namespace repl {
139130 const std::vector<fe::token::Token> tokens = lexer.lex_all ();
140131 if (debug) {
141132 for (const auto &tok: tokens) {
142- std::cout << tok << " \n " ;
133+ std::cout << colors:: YELLOW << tok << colors:: RESET << std::endl ;
143134 }
144135 }
145136 // Parse
146137 fe::parser::Parser parser (tokens);
147138 if (debug) {
148- std::cout << parser.program << " \n " ;
139+ std::cout << colors:: YELLOW << parser.program << colors:: RESET << std::endl ;
149140 }
150141 // Interpret
142+ // TODO: Add flag to disable printing in REPL (disabled by default)
151143 const auto [global_env, value] = intp::interp::interpret (
152144 parser.program , shared_global_env, {.own_expr = true });
153- std::cout << " === > " << value << " \n " ;
145+ std::cout << colors:: GREEN << " = > " << value << colors:: RESET << std::endl ;
154146 shared_global_env = global_env;
155147 } catch (const std::exception &ex) {
156- std::cerr << " error: " << ex.what () << " \n " ;
148+ std::cerr << colors:: RED << " error: " << ex.what () << colors:: RESET << std::endl ;
157149 }
158150 }
159151 }
0 commit comments