version 0.2
try, throw implemented help screen updates some code reorganisation readme and doc updates
This commit is contained in:
145
ml.cpp
145
ml.cpp
@@ -1351,6 +1351,11 @@ namespace builtin {
|
||||
|
||||
if (args.size() != 2)
|
||||
throw MlError(MlValue("/", divide), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
if ((args[1].get_type_name() == "int" && args[1] == 0l) ||
|
||||
(args[1].get_type_name() == "float" && args[1] == 0.0))
|
||||
throw std::invalid_argument("divide by zero.");
|
||||
|
||||
return args[0] / args[1];
|
||||
}
|
||||
|
||||
@@ -1846,17 +1851,6 @@ namespace builtin {
|
||||
return acc;
|
||||
}
|
||||
|
||||
MlValue threads_join(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() != 0)
|
||||
throw MlError(MlValue("threads_join", threads_join), env, TOO_MANY_ARGS);
|
||||
|
||||
std::lock_guard<std::mutex> lockGuard(register_mutex);
|
||||
for (auto &th : threads_register)
|
||||
if (th.joinable()) th.join();
|
||||
|
||||
return MlValue::nil();
|
||||
}
|
||||
|
||||
MlValue thread_sleep(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
eval_args(args, env);
|
||||
|
||||
@@ -1866,48 +1860,51 @@ namespace builtin {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(args[0].as_int()));
|
||||
return args[0];
|
||||
}
|
||||
}
|
||||
|
||||
void repl(MlEnvironment &env) {
|
||||
std::string code;
|
||||
std::string input;
|
||||
MlValue tmp;
|
||||
std::vector<MlValue> parsed;
|
||||
MlValue threads_join(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() != 0)
|
||||
throw MlError(MlValue("threads-join", threads_join), env, TOO_MANY_ARGS);
|
||||
|
||||
setup_linenoise(env);
|
||||
|
||||
while (true) {
|
||||
char *line = linenoise(">>> ");
|
||||
if (line == nullptr) break;
|
||||
|
||||
linenoise_line_read(line);
|
||||
|
||||
input = std::string(line);
|
||||
|
||||
if (input == "!quit" || input == "!q")
|
||||
break;
|
||||
else if (input == "!env" || input == "!e")
|
||||
std::cout << env << std::endl;
|
||||
else if (input == "!export" || input == "!x") {
|
||||
std::cout << "File to export to: ";
|
||||
std::getline(std::cin, input);
|
||||
|
||||
write_file_contents(input, code);
|
||||
} else if (input != "") {
|
||||
try {
|
||||
tmp = run(input, env);
|
||||
std::cout << " => " << tmp.debug() << std::endl;
|
||||
code += input + "\n";
|
||||
} catch (MlError &e) {
|
||||
std::cerr << e.description() << std::endl;
|
||||
MlPerfMon::instance().clear_callstack();
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
std::lock_guard<std::mutex> lockGuard(register_mutex);
|
||||
for (auto &th : threads_register)
|
||||
if (th.joinable()) th.join();
|
||||
|
||||
return MlValue::nil();
|
||||
}
|
||||
|
||||
|
||||
MlValue try_block(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() < 2 || args.size() > 3)
|
||||
throw MlError(MlValue("try", try_block), env, args.size() > 3 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
MlValue value;
|
||||
size_t cs_posisition; // unroll stack position to state when try begun to prevent "forgotten" entries in case of exception
|
||||
|
||||
// try block
|
||||
try {
|
||||
cs_posisition = MlPerfMon::instance().get_callstack_position();
|
||||
value = args[0].eval(env);
|
||||
// catch block
|
||||
} catch (std::exception &e) {
|
||||
MlPerfMon::instance().restore_callstack_position(cs_posisition);
|
||||
env.set("ml-exception", MlValue::string(e.what()));
|
||||
value = args[1].eval(env);
|
||||
}
|
||||
// finally block
|
||||
if (args.size() == 3) {
|
||||
args[2].eval(env);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
MlValue throw_exception(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() != 1)
|
||||
throw MlError(MlValue("throw", throw_exception), env, args.size() > 1 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
throw std::runtime_error(args[0].as_string());
|
||||
}
|
||||
|
||||
close_linenoise();
|
||||
}
|
||||
|
||||
void load_std_lib(MlEnvironment &env) {
|
||||
@@ -2037,6 +2034,10 @@ MlValue MlEnvironment::get(const std::string &name) const {
|
||||
if (name == "thread-sleep") return MlValue("thread-sleep", builtin::thread_sleep);
|
||||
if (name == "threads-join") return MlValue("threads-join", builtin::threads_join);
|
||||
|
||||
// Exceptions
|
||||
if (name == "try") return MlValue("try", builtin::try_block);
|
||||
if (name == "throw") return MlValue("throw", builtin::throw_exception);
|
||||
|
||||
std::map<std::string, MlValue>::const_iterator itr = defs.find(name);
|
||||
if (itr != defs.end()) return itr->second;
|
||||
else if (parent_scope != nullptr) {
|
||||
@@ -2061,6 +2062,50 @@ std::vector<std::string> MlEnvironment::get_lambdas_list() const {
|
||||
return lambdas;
|
||||
}
|
||||
|
||||
|
||||
void repl(MlEnvironment &env) {
|
||||
std::string code;
|
||||
std::string input;
|
||||
MlValue tmp;
|
||||
std::vector<MlValue> parsed;
|
||||
|
||||
setup_linenoise(env);
|
||||
|
||||
while (true) {
|
||||
char *line = linenoise(">>> ");
|
||||
if (line == nullptr) break;
|
||||
|
||||
linenoise_line_read(line);
|
||||
|
||||
input = std::string(line);
|
||||
|
||||
if (input == "!quit" || input == "!q")
|
||||
break;
|
||||
else if (input == "!env" || input == "!e")
|
||||
std::cout << env << std::endl;
|
||||
else if (input == "!export" || input == "!x") {
|
||||
std::cout << "File to export to: ";
|
||||
std::getline(std::cin, input);
|
||||
|
||||
write_file_contents(input, code);
|
||||
} else if (input != "") {
|
||||
try {
|
||||
tmp = run(input, env);
|
||||
std::cout << " => " << tmp.debug() << std::endl;
|
||||
code += input + "\n";
|
||||
} catch (MlError &e) {
|
||||
std::cerr << e.description() << std::endl;
|
||||
MlPerfMon::instance().clear_callstack();
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close_linenoise();
|
||||
}
|
||||
|
||||
|
||||
bool cmdOptionExists(char **begin, char **end, const std::string &option) { return std::find(begin, end, option) != end; }
|
||||
|
||||
std::vector<std::string> getCmdOption(char *argv[], int argc, const std::string &option) {
|
||||
@@ -2092,7 +2137,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
// help
|
||||
if (cmdOptionExists(argv, argv + argc, "-h")) {
|
||||
std::cout << "Usage:\n\t-h print this help\n\t-f source_file - executes code in file\n\t-c code - runs passed code\n\t-i runs repl\n\t-b skip stdlib loading\n\t-p prints profile info at the end\n\t-v prints version string\n\n";
|
||||
std::cout << "Usage:\n\t-h print this help\n\t-b skip stdlib loading\n\t-c code - runs code passed on command line\n\t-f source_file - executes code in file\n\t-i runs repl\n\t-p prints profile info at the end\n\t-v prints version string\n\n";
|
||||
return 0;
|
||||
}
|
||||
// version
|
||||
|
||||
Reference in New Issue
Block a user