Skip to content
This repository was archived by the owner on Oct 12, 2026. It is now read-only.

Commit 0bf0048

Browse files
committed
Add info and debug to Logger
1 parent 0bb165f commit 0bf0048

6 files changed

Lines changed: 141 additions & 107 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ if_then: Any = \condition: Any.
4343
```
4444

4545
```console
46-
$ ./cmake-build-debug/lbd.exe -f ./examples/if_then.lbd
46+
$ ./cmake-build-debug/lbd -f ./examples/if_then.lbd
4747
True
4848
False
4949
```

‎include/lbd/logs.h‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
#include <lbd/exceptions.h>
77

88
namespace logs {
9-
class Logger {
9+
struct Logger {
1010
bool exit_on_error = true;
1111
bool use_color = false;
1212
bool show_loc = true;
1313

14-
public:
1514
Logger() = default;
1615

1716
Logger(const bool exit_on_error, const bool use_color, const bool show_loc) : exit_on_error(exit_on_error),
@@ -39,5 +38,28 @@ namespace logs {
3938
}
4039
throw ControlledExit{};
4140
}
41+
42+
template<typename... Args>
43+
void info(Args &&... args) const {
44+
log_impl(colors::BLUE, std::cout, std::forward<Args>(args)...);
45+
}
46+
47+
template<typename... Args>
48+
void debug(Args &&... args) const {
49+
log_impl(colors::YELLOW, std::cout, std::forward<Args>(args)...);
50+
}
51+
52+
private:
53+
template<typename... Args>
54+
void log_impl(const std::string &color, std::ostream &os, Args &&... args) const {
55+
if (use_color) {
56+
os << color;
57+
}
58+
(os << ... << std::forward<Args>(args));
59+
if (use_color) {
60+
os << colors::RESET;
61+
}
62+
os << std::endl;
63+
}
4264
};
4365
}

‎include/lbd/options.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace options {
55
struct Options {
66
bool own_expr = false; /// Owning Expression inside Thunk. Turned on for REPL
7+
bool force_on_env_dump = false;
78
bool debug = false;
89
logs::Logger logger;
910
};

‎scripts/dump_todo.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
with open(GITIGNORE_PATH, "r", encoding="utf-8") as f:
2424
spec = pathspec.PathSpec.from_lines("gitwildmatch", f)
2525

26+
pending = 0
27+
2628
root: str
2729
for root, _, files in os.walk(BASE_DIR):
2830
filename: str
@@ -40,6 +42,9 @@
4042
todo_index = line.index("TODO:")
4143
todo_text = line[todo_index:].strip()
4244
print(f"{rel_path}:{lineno}: {todo_text}")
45+
pending += 1
4346
except (UnicodeDecodeError, PermissionError):
4447
# Skip files that can’t be read as text
4548
continue
49+
50+
print("\nPending: ", pending)

‎src/fe/parser.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ namespace fe::parser {
151151
loaded_files.insert(abs_path);
152152
auto lexer_v = lexer::Lexer(filepath, lexer::FromFile{}, options_v);
153153
const auto tokens = lexer_v.lex_all();
154-
// TODO: Accept Options and Add a debug flag for printing Lexed Tokens
154+
if (options_v.debug) {
155+
for (const auto &tok: tokens) {
156+
options_v.logger.debug(tok);
157+
}
158+
}
155159
for (Parser parser(tokens, options_v); auto &node: parser.program.nodes) {
156160
nodes.emplace_back(std::move(node));
157161
}

‎src/repl.cpp‎

Lines changed: 105 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -13,144 +13,146 @@
1313
#define on_off(val) ((val) ? "on " : "off")
1414

1515
namespace repl {
16+
static options::Options options_v;
17+
1618
static void process_load_command(const std::string &arg,
1719
std::optional<std::shared_ptr<intp::interp::Env> > &shared_env) {
18-
try {
19-
const std::string &filepath = arg;
20-
if (!std::filesystem::exists(filepath)) {
21-
std::cerr << colors::RED << "error: filepath " << filepath << " does not exist"
22-
<< colors::RESET << std::endl;
23-
return;
20+
const std::string &filepath = arg;
21+
if (!std::filesystem::exists(filepath)) {
22+
options_v.logger.error({}, "IO error: filepath ", filepath, "does not exists");
23+
}
24+
fe::lexer::Lexer lexer(filepath, fe::lexer::FromFile{});
25+
const auto tokens = lexer.lex_all();
26+
if (options_v.debug) {
27+
for (const auto &tok: tokens) {
28+
options_v.logger.debug(tok);
2429
}
25-
fe::lexer::Lexer lexer(filepath, fe::lexer::FromFile{});
26-
const auto tokens = lexer.lex_all();
27-
// TODO: Accept Options and Add a debug flag for printing Lexed Tokens
28-
fe::parser::Parser parser(tokens);
29-
const std::optional<std::shared_ptr<intp::interp::Env> > temp_env = shared_env;
30-
// Merge loaded_env into shared_env
31-
if (const auto [loaded_env, _] = intp::interp::interpret(parser.program, temp_env, {.own_expr = true});
32-
loaded_env) {
33-
if (!shared_env) {
34-
shared_env = loaded_env;
35-
} else {
36-
// Merge all Bindings from loaded_env into shared_env
37-
for (const auto &[fst, snd]: loaded_env->table) {
38-
(*shared_env)->bind(fst, snd);
39-
}
30+
}
31+
fe::parser::Parser parser(tokens);
32+
const std::optional<std::shared_ptr<intp::interp::Env> > temp_env = shared_env;
33+
// Merge loaded_env into shared_env
34+
if (const auto [loaded_env, _] = intp::interp::interpret(parser.program, temp_env, {.own_expr = true});
35+
loaded_env) {
36+
if (!shared_env) {
37+
shared_env = loaded_env;
38+
} else {
39+
// Merge all Bindings from loaded_env into shared_env
40+
for (const auto &[fst, snd]: loaded_env->table) {
41+
(*shared_env)->bind(fst, snd);
4042
}
4143
}
42-
std::cout << colors::BLUE << "info: file loaded: " << filepath << colors::RESET << std::endl;
43-
} catch (const std::exception &ex) {
44-
std::cerr << colors::RED << "error: could not load file: " << ex.what() << colors::RESET << std::endl;
4544
}
45+
options_v.logger.info("info: file loaded ", filepath);
4646
}
4747

48+
4849
void loop(const bool debug) {
4950
enable_virtual_terminal();
5051

51-
static bool force_on_env_dump = false;
5252
static logs::Logger logger(false, true, false);
53-
static options::Options options = {.own_expr = true, .debug = debug, .logger = logger};
53+
options_v = {.own_expr = true, .force_on_env_dump = false, .debug = debug, .logger = logger};
5454

55-
std::cout << colors::BLUE << "Welcome to lambda-discipline REPL.\nType :quit to exit."
56-
<< colors::RESET << std::endl;
5755
std::string line;
5856
std::optional<std::shared_ptr<intp::interp::Env> > shared_global_env = std::nullopt;
57+
58+
options_v.logger.info("Welcome to lambda-discipline REPL.\nType :quit to exit.");
59+
5960
while (true) {
60-
std::cout << colors::CYAN << "\n>> " << colors::RESET;
61-
if (!std::getline(std::cin, line)) {
62-
break; // EOF (C-d / C-z)
63-
}
64-
if (line == ":q" || line == ":quit" || line == ":exit") {
65-
std::cout << "\n" << colors::BLUE << "exiting REPL" << colors::RESET << std::endl;
66-
break;
67-
}
68-
if (line == ":c" || line == ":clear" || line == ":cls") {
61+
try {
62+
std::cout << colors::CYAN << "\n>> " << colors::RESET;
63+
if (!std::getline(std::cin, line)) {
64+
break; // EOF (C-d / C-z)
65+
}
66+
if (line == ":q" || line == ":quit" || line == ":exit") {
67+
options_v.logger.info("\nexiting REPL.");
68+
break;
69+
}
70+
if (line == ":c" || line == ":clear" || line == ":cls") {
6971
#ifdef _WIN32
70-
std::system("cls");
72+
std::system("cls");
7173
#else
72-
std::system("clear");
74+
std::system("clear");
7375
#endif
74-
continue;
75-
}
76-
if (line == ":h" || line == ":help" || line == ":?") {
77-
std::cout << std::endl;
78-
print_table({"General Commands", "Argument", "Description"}, {
79-
{":q, :quit, :exit", "", "Clear the screen"},
80-
{":c, :clear, :cls", "", "Exit the REPL"},
81-
{":h, :help, :?", "", "Display this help message"},
82-
{":l, :load", "<filepath>", "Load file into REPL"},
83-
{":r, :reset", "", "Reset environment"},
84-
{":d, :debug", "", "Toggle debug mode"}
85-
}, colors::GREEN);
86-
std::cout << std::endl;
87-
print_table({"Inspection Commands", "Argument", "Description"}, {
88-
{":e, :env", "", "Dump environment bindings"},
89-
{":force", "", "Force thunk evaluation on dump"}
90-
}, colors::GREEN);
91-
std::cout << std::endl;
92-
print_table({"Options", "State", "Help"}, {
93-
{"debug", on_off(options.debug), "use :debug to toggle"},
94-
{"force-on-env-dump", on_off(force_on_env_dump), "use :force to toggle"}
95-
}, colors::GREEN);
96-
continue;
97-
}
98-
if (line == ":env" || line == ":e") {
99-
std::cout << std::endl;
100-
if (shared_global_env) {
101-
print_table({"Symbol", "Thunk"}, (*shared_global_env)->to_vector(force_on_env_dump), colors::GREEN);
102-
} else {
103-
print_table({"Symbol", "Thunk"}, {{"Empty"}}, colors::GREEN);
76+
continue;
77+
}
78+
if (line == ":h" || line == ":help" || line == ":?") {
79+
std::cout << std::endl;
80+
print_table({"General Commands", "Argument", "Description"}, {
81+
{":q, :quit, :exit", "", "Clear the screen"},
82+
{":c, :clear, :cls", "", "Exit the REPL"},
83+
{":h, :help, :?", "", "Display this help message"},
84+
{":l, :load", "<filepath>", "Load file into REPL"},
85+
{":r, :reset", "", "Reset environment"},
86+
{":d, :debug", "", "Toggle debug mode"}
87+
}, colors::GREEN);
88+
std::cout << std::endl;
89+
print_table({"Inspection Commands", "Argument", "Description"}, {
90+
{":e, :env", "", "Dump environment bindings"},
91+
{":force", "", "Force thunk evaluation on dump"}
92+
}, colors::GREEN);
93+
std::cout << std::endl;
94+
print_table({"Options", "State", "Help"}, {
95+
{"debug", on_off(options_v.debug), "use :debug to toggle"},
96+
{"force-on-env-dump", on_off(options_v.force_on_env_dump), "use :force to toggle"}
97+
}, colors::GREEN);
98+
continue;
99+
}
100+
if (line == ":env" || line == ":e") {
101+
std::cout << std::endl;
102+
if (shared_global_env) {
103+
print_table({"Symbol", "Thunk"}, (*shared_global_env)->to_vector(options_v.force_on_env_dump),
104+
colors::GREEN);
105+
} else {
106+
print_table({"Symbol", "Thunk"}, {{"Empty"}}, colors::GREEN);
107+
}
108+
continue;
109+
}
110+
if (line == ":reset" || line == ":r") {
111+
shared_global_env.reset();
112+
continue;
113+
}
114+
if (line == ":debug" || line == ":d") {
115+
options_v.debug = !options_v.debug;
116+
continue;
117+
}
118+
if (line == ":force") {
119+
options_v.force_on_env_dump = !options_v.force_on_env_dump;
120+
continue;
121+
}
122+
if (line.rfind(":load ", 0) == 0) {
123+
process_load_command(line.substr(6), shared_global_env);
124+
continue;
125+
}
126+
if (line.rfind(":l ", 0) == 0) {
127+
process_load_command(line.substr(3), shared_global_env);
128+
continue;
129+
}
130+
if (line.empty()) {
131+
continue;
104132
}
105-
continue;
106-
}
107-
if (line == ":reset" || line == ":r") {
108-
shared_global_env.reset();
109-
continue;
110-
}
111-
if (line == ":debug" || line == ":d") {
112-
options.debug = !options.debug;
113-
continue;
114-
}
115-
if (line == ":force") {
116-
force_on_env_dump = !force_on_env_dump;
117-
continue;
118-
}
119-
if (line.rfind(":load ", 0) == 0) {
120-
process_load_command(line.substr(6), shared_global_env);
121-
continue;
122-
}
123-
if (line.rfind(":l ", 0) == 0) {
124-
process_load_command(line.substr(3), shared_global_env);
125-
continue;
126-
}
127-
if (line.empty()) {
128-
continue;
129-
}
130-
try {
131133
// Lex
132-
fe::lexer::Lexer lexer_v(line, fe::lexer::FromRepl{}, options);
134+
fe::lexer::Lexer lexer_v(line, fe::lexer::FromRepl{}, options_v);
133135
const std::vector<fe::token::Token> tokens = lexer_v.lex_all();
134-
if (options.debug) {
136+
if (options_v.debug) {
135137
for (const auto &tok: tokens) {
136-
std::cout << colors::YELLOW << tok << colors::RESET << std::endl;
138+
options_v.logger.debug(tok);
137139
}
138140
}
139141

140142
// Parse
141-
fe::parser::Parser parser_v(tokens, options);
142-
if (options.debug) {
143-
std::cout << colors::YELLOW << parser_v.program << colors::RESET << std::endl;
143+
fe::parser::Parser parser_v(tokens, options_v);
144+
if (options_v.debug) {
145+
options_v.logger.debug(parser_v.program);
144146
}
145147

146148
// Interpret
147149
const auto [global_env, value] = intp::interp::interpret(
148-
parser_v.program, shared_global_env, options);
150+
parser_v.program, shared_global_env, options_v);
149151
std::cout << colors::GREEN << "=> " << value << colors::RESET << std::endl;
150152
shared_global_env = global_env;
151153
} catch (const ControlledExit &) {
152154
} catch (const std::exception &ex) {
153-
std::cerr << colors::RED << "error: " << ex.what() << colors::RESET << std::endl;
155+
options_v.logger.error({}, "error: ", ex.what());;
154156
}
155157
}
156158
}

0 commit comments

Comments
 (0)