input2 added

This commit is contained in:
vaclavt
2022-05-19 18:38:52 +02:00
parent aec06b5f52
commit 6506494750
5 changed files with 72 additions and 24 deletions

View File

@@ -0,0 +1,18 @@
(defmacro until (cnd body)
(list 'while '(not (eval cnd))
body
))
(def stop nil)
(until stop
(do
(def line (input2 "=> "))
(if (= line "!q")
(set! stop #t)
(print line))
))

View File

@@ -83,6 +83,7 @@
|`(random low high)`|Get a random number between two numbers inclusively|`>>> (random 1 6) => 5`|System| |`(random low high)`|Get a random number between two numbers inclusively|`>>> (random 1 6) => 5`|System|
|`(include file)`|Read a file and execute its code||IO| |`(include file)`|Read a file and execute its code||IO|
|`(input [prompt])`|Get user input with an optional prompt||IO| |`(input [prompt])`|Get user input with an optional prompt||IO|
|`(input2 [prompt])`|Get user input using libnoise with an optional prompt||IO|
|`(read)`|Reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object||IO| |`(read)`|Reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object||IO|
|`(read-file filename)`|Get the contents of a file|`>>> (read-file "/tmp/a.txt") => "test"`|IO| |`(read-file filename)`|Get the contents of a file|`>>> (read-file "/tmp/a.txt") => "test"`|IO|
|`(read-file-lines filename lambda)`|Reads file and for each line call lambda with passing the line as a parameter|`(read-file-lines "/tmp/f.txt" (lambda (ln) (print ln))`|IO| |`(read-file-lines filename lambda)`|Reads file and for each line call lambda with passing the line as a parameter|`(read-file-lines "/tmp/f.txt" (lambda (ln) (print ln))`|IO|

37
ml.cpp
View File

@@ -1135,6 +1135,24 @@ MlValue input(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue::string(s); return MlValue::string(s);
} }
// Get user input with an optional prompt using line noise
MlValue input2(std::vector<MlValue> args, MlEnvironment &env) {
// TODO add setup etc
eval_args(args, env);
if (args.size() > 1)
throw MlError(MlValue("input2", input2), env, TOO_MANY_ARGS);
char *line = linenoise(args.empty() ? ">>> " : args[0].as_string().c_str());
if (line == nullptr) throw std::runtime_error("date_to_string, cannot initialise linenoise");
std::string input{line};
linenoise_add_to_history(input);
return MlValue::string(input);
}
// Get a random number between two numbers inclusively // Get a random number between two numbers inclusively
MlValue random(std::vector<MlValue> args, MlEnvironment &env) { MlValue random(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@@ -2252,6 +2270,7 @@ std::map<const std::string, Builtin> builtin_funcs
std::make_pair("random", builtin::random), std::make_pair("random", builtin::random),
std::make_pair("include", builtin::include), std::make_pair("include", builtin::include),
std::make_pair("input", builtin::input), std::make_pair("input", builtin::input),
std::make_pair("input2", builtin::input2),
std::make_pair("read", builtin::read), std::make_pair("read", builtin::read),
std::make_pair("read-file", builtin::read_file), std::make_pair("read-file", builtin::read_file),
std::make_pair("read-file-lines", builtin::read_file_lines), std::make_pair("read-file-lines", builtin::read_file_lines),
@@ -2361,15 +2380,14 @@ void repl(MlEnvironment &env) {
MlValue tmp; MlValue tmp;
std::vector<MlValue> parsed; std::vector<MlValue> parsed;
setup_linenoise(env, builtin_funcs); setup_linenoise_repl(env, builtin_funcs);
while (true) { while (true) {
char *line = linenoise(">>> "); char *line = linenoise(">>> ");
if (line == nullptr) break; if (line == nullptr) break;
linenoise_line_read(line);
input = std::string(line); input = std::string(line);
linenoise_add_to_history(input);
if (input == "!quit" || input == "!q") if (input == "!quit" || input == "!q")
break; break;
@@ -2393,8 +2411,6 @@ void repl(MlEnvironment &env) {
} }
} }
} }
close_linenoise();
} }
@@ -2425,11 +2441,13 @@ int main(int argc, char *argv[]) {
srand(time(NULL)); srand(time(NULL));
try { try {
// performance monitor on // performance monitor on
if (cmdOptionExists(argv, argv + argc, "-p")) if (cmdOptionExists(argv, argv + argc, "-p")) {
MlPerfMon::instance().turnOn(); MlPerfMon::instance().turnOn();
}
// better stacktrace // better stacktrace
if (cmdOptionExists(argv, argv + argc, "-d")) if (cmdOptionExists(argv, argv + argc, "-d")) {
MlPerfMon::instance().debugOn(); MlPerfMon::instance().debugOn();
}
// skip loading std lib // skip loading std lib
if (!cmdOptionExists(argv, argv + argc, "-b")) { if (!cmdOptionExists(argv, argv + argc, "-b")) {
load_std_lib(env); load_std_lib(env);
@@ -2444,6 +2462,9 @@ int main(int argc, char *argv[]) {
std::cout << VERSION << std::endl; std::cout << VERSION << std::endl;
return 0; return 0;
} }
setup_linenoise();
// passed code // passed code
if (cmdOptionExists(argv, argv + argc, "-c")) { if (cmdOptionExists(argv, argv + argc, "-c")) {
std::vector<std::string> codes = getCmdOption(argv, argc, "-c"); std::vector<std::string> codes = getCmdOption(argv, argc, "-c");
@@ -2467,6 +2488,8 @@ int main(int argc, char *argv[]) {
repl(env); repl(env);
} }
close_linenoise();
MlPerfMon::instance().print_results(); MlPerfMon::instance().print_results();
return 0; return 0;

View File

@@ -1,13 +1,14 @@
#include "ml_util.h" #include "ml_util.h"
#include "string.h"
#include <string>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
// #include <filesystem> // #include <filesystem>
std::vector<std::string> commands {}; std::vector<std::string> commands {};
std::string history_file;
// kryplove z applu a jejich problemy s filesystemem // kryplove z applu a jejich problemy s filesystemem
/* /*
@@ -20,8 +21,7 @@ std::string get_history_file_dir() {
} }
*/ */
std::string get_history_file_dir() { std::string get_history_filepath(const std::string &file) {
std::string file{"/.ml_history.txt"};
const char *t = std::getenv("HOME"); const char *t = std::getenv("HOME");
if (t == nullptr) return "/tmp/" + file; if (t == nullptr) return "/tmp/" + file;
@@ -30,33 +30,37 @@ std::string get_history_file_dir() {
MlEnvironment * repl_env = nullptr; MlEnvironment * repl_env = nullptr;
void setup_linenoise(const MlEnvironment &env, const std::map<const std::string, Builtin> &builtins) { void setup_linenoise() {
repl_env = (MlEnvironment*) &env; history_file = get_history_filepath("/.ml_history.txt");
linenoiseHistoryLoad(history_file.c_str());
std::string history_file = get_history_file_dir();
linenoiseHistorySetMaxLen(500); linenoiseHistorySetMaxLen(500);
linenoiseSetMultiLine(1);
}
void setup_linenoise_repl(const MlEnvironment &env, const std::map<const std::string, Builtin> &builtins) {
// basic linenoise setup must be already set
repl_env = (MlEnvironment*) &env;
linenoiseSetCompletionCallback(completion); linenoiseSetCompletionCallback(completion);
linenoiseSetHintsCallback(hints); linenoiseSetHintsCallback(hints);
linenoiseSetMultiLine(1);
linenoiseHistoryLoad(history_file.c_str());
commands.reserve(builtins.size()); commands.reserve(builtins.size());
for(auto it = builtins.begin(); it != builtins.end(); ++it) for(auto it = builtins.begin(); it != builtins.end(); ++it)
commands.push_back(it->first); commands.push_back(it->first);
} }
void linenoise_line_read(char *line) { void linenoise_add_to_history(const std::string &line) {
linenoiseHistoryAdd(line); if (!line.empty())
linenoiseHistoryAdd(line.c_str());
} }
void close_linenoise() { void close_linenoise() {
std::string history_file = get_history_file_dir();
linenoiseHistorySave(history_file.c_str()); linenoiseHistorySave(history_file.c_str());
} }
size_t last_token_index( std::string str ) { size_t last_token_index(std::string str) {
// remove trailing white space // remove trailing white space
while( !str.empty() && std::isspace( str.back() ) ) str.pop_back() ; while( !str.empty() && std::isspace( str.back() ) ) str.pop_back() ;

View File

@@ -1,11 +1,13 @@
#pragma once #pragma once
#include "ml.h" #include "ml.h"
#include "linenoise.h" #include "linenoise.h"
void setup_linenoise(const MlEnvironment &env, const std::map<const std::string, Builtin> &builtins); #include <string>
void linenoise_line_read(char *line);
void setup_linenoise();
void setup_linenoise_repl(const MlEnvironment &env, const std::map<const std::string, Builtin> &builtins);
void linenoise_add_to_history(const std::string &line);
void close_linenoise(); void close_linenoise();