callstack added
This commit is contained in:
parent
5afa7dd69f
commit
9ab0a2c98d
39
Readme.md
39
Readme.md
|
|
@ -7,19 +7,28 @@
|
|||
|
||||
|
||||
### TODO
|
||||
- replace to_string macro in ml.cpp
|
||||
- add debug support, at least call stack
|
||||
- documentation
|
||||
- add url of source/inspiration to clib/*.cpp
|
||||
- add stdtest - to test every functionality
|
||||
- add instrumentation (time, nr of evals, num of atoms, debug info, debug environment etc)
|
||||
- add parenthesis coloring into linenoise
|
||||
- multiline editing (kilo editor)
|
||||
- execute system command should capture stderr
|
||||
- add some mem stats to benchmark
|
||||
- create pastebin like web using ml
|
||||
#### Code
|
||||
- documentation
|
||||
- rename constants in ml_profiler.h
|
||||
- replace to_string macro in ml.cpp
|
||||
- add url of source/inspiration to clib/*.cpp
|
||||
- add instrumentation (time, nr of evals, num of atoms, debug info, debug environment etc)
|
||||
#### Language
|
||||
- support for (), nil, t, in lsp code replace 0 by nil in logicals
|
||||
- file functions
|
||||
- name it here
|
||||
- open file
|
||||
- read line
|
||||
- write line
|
||||
- close file
|
||||
- string functions
|
||||
- itok - integer to char, chartoint (better names) - mini printf can be useed for it (%d)
|
||||
- compare - needed for sorting, cmp ignore case
|
||||
- regexp functions
|
||||
- date support
|
||||
|
|
@ -31,7 +40,6 @@
|
|||
- mapcar (funcall, apply)
|
||||
- syntax highlighting do VS Code
|
||||
- add hash datatype
|
||||
- create pastebin like web using ml
|
||||
|
||||
#### Performance
|
||||
- define is one of most frequent callee, when in scope with very few vars, lookup sequentially
|
||||
|
|
@ -40,24 +48,25 @@
|
|||
- mini_sprintf - unnecesary copying between vector and list
|
||||
- (do, scope ..) repeatedly assign to acc
|
||||
|
||||
#### Compile
|
||||
```
|
||||
mkdir -p build
|
||||
gcc -std=c99 -c -O2 -o linenoise.o clib/linenoise.c
|
||||
c++ -c -O2 -I/usr/local/opt/openssl/include -Iclib --std=c++17 ml.cpp ml_io.cpp ml_date.cpp ml_string.cpp ml_util.cpp ml_profiler.cpp clib/json11.cpp clib/csvparser.cpp clib/sslclient.cpp clib/printf.cpp
|
||||
// on linux c++ -o build/ml -O2 -L/usr/local/lib -L/usr/local/opt/openssl/lib -lm -lstdc++ -lcrypto -lssl *.o
|
||||
c++ -o build/ml -O2 -L/usr/local/lib -L/usr/local/opt/openssl/lib -lm -lstdc++ -lcrypto -lssl -Wl,-stack_size -Wl,0x1000000 *.o
|
||||
```
|
||||
// or cmake
|
||||
|
||||
#### Install
|
||||
```
|
||||
cp build/ml /usr/local/bin/ml
|
||||
cp stdlib/*.lsp /usr/local/var/mlisp/
|
||||
```
|
||||
|
||||
#### Compile
|
||||
```
|
||||
gcc -std=c99 -c -O2 -o linenoise.o clib/linenoise.c
|
||||
c++ -c -O2 -I/usr/local/opt/openssl/include -Iclib --std=c++17 ml.cpp ml_io.cpp ml_date.cpp ml_string.cpp ml_util.cpp ml_profiler.cpp clib/json11.cpp clib/csvparser.cpp clib/sslclient.cpp clib/printf.cpp
|
||||
c++ -o ml -O2 -L/usr/local/lib -L/usr/local/opt/openssl/lib -lm -lstdc++ -lcrypto -lssl -Wl,-stack_size -Wl,0x1000000 *.o
|
||||
```
|
||||
or
|
||||
cmake
|
||||
|
||||
### Example of use
|
||||
```
|
||||
time ./build/ml -c '(include "../example.lisp") (print (fact 1000))'
|
||||
./build/ml -f debug.lisp
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -46,4 +46,12 @@
|
|||
|
||||
(print (and (print "xx") (= 1 0) (print "yy")))
|
||||
|
||||
(defun aa () (do
|
||||
(print "prvni")
|
||||
(+ 1 xx)
|
||||
(print "druhy")
|
||||
))
|
||||
|
||||
(aa)
|
||||
|
||||
; (sleep 1.5)
|
||||
23
ml.cpp
23
ml.cpp
|
|
@ -51,10 +51,10 @@
|
|||
|
||||
|
||||
// Convert an object to a string using a string stream conveniently
|
||||
#if __APPLE_
|
||||
#define to_string(x) static_cast<std::ostringstream>((std::ostringstream() << std::dec << x )).str()
|
||||
#elif __linux
|
||||
#if __linux
|
||||
#define to_string(x) static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x )).str()
|
||||
#else
|
||||
#define to_string(x) static_cast<std::ostringstream>((std::ostringstream() << std::dec << x )).str()
|
||||
#endif
|
||||
|
||||
// Is this character a valid lisp symbol character
|
||||
|
|
@ -624,7 +624,8 @@ MlError::~MlError() {
|
|||
|
||||
std::string MlError::description() {
|
||||
// return "error: the expression `" + cause->debug() + "` failed in scope " + to_string(env) + " with message \"" + msg + "\"";
|
||||
return "error: the expression `" + cause->debug() + "` with message \"" + msg + "\"";
|
||||
return MlPerfMon::instance().callstack() +
|
||||
"error: the expression `" + cause->debug() + "` with message \"" + msg + "\"";
|
||||
}
|
||||
|
||||
void MlEnvironment::combine(MlEnvironment const &other) {
|
||||
|
|
@ -693,6 +694,7 @@ MlValue MlValue::apply(std::vector<MlValue> args, MlEnvironment &env) {
|
|||
MlValue MlValue::eval(MlEnvironment &env) {
|
||||
std::vector<MlValue> args;
|
||||
MlValue function;
|
||||
MlValue res;
|
||||
MlEnvironment e;
|
||||
switch (type) {
|
||||
case QUOTE:
|
||||
|
|
@ -715,11 +717,10 @@ MlValue MlValue::eval(MlEnvironment &env) {
|
|||
args[i] = args[i].eval(env);
|
||||
|
||||
MlPerfMon::instance().add_method_call(function.type == LAMBDA ? "lambda" : function.str);
|
||||
res = function.apply( args, env );
|
||||
MlPerfMon::instance().end_method_call();
|
||||
|
||||
return function.apply(
|
||||
args,
|
||||
env
|
||||
);
|
||||
return res;
|
||||
|
||||
default:
|
||||
return *this;
|
||||
|
|
@ -1015,7 +1016,7 @@ namespace builtin {
|
|||
eval_args(args, env);
|
||||
|
||||
std::exit(args.size() < 1 ? 0 : args[0].cast_to_int().as_int());
|
||||
return MlValue();
|
||||
return MlValue(); // will not be called :-)
|
||||
}
|
||||
|
||||
// Print several values and return the last one
|
||||
|
|
@ -1557,7 +1558,7 @@ namespace builtin {
|
|||
if (args.size() != 2)
|
||||
throw MlError(MlValue("string-split", string_split), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
// TODO more efficient
|
||||
// TODO do it more efficient
|
||||
std::vector<std::string> elements = regexp_strsplit(args[0].as_string(), args[1].as_string());
|
||||
std::vector<MlValue> result{};
|
||||
|
||||
|
|
@ -1970,7 +1971,7 @@ int main(int argc, char *argv[]) {
|
|||
} catch (MlError &e) {
|
||||
std::cerr << e.description() << std::endl;
|
||||
} catch (std::runtime_error &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << MlPerfMon::instance().callstack() << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
#include "ml_profiler.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
// for linux gcc
|
||||
#include <iomanip>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using namespace std::chrono;
|
||||
|
|
@ -15,6 +16,8 @@ void MlPerfMon::turnOn() {
|
|||
}
|
||||
|
||||
void MlPerfMon::add_method_call(const std::string &method) {
|
||||
call_stack.push_back(method);
|
||||
|
||||
if (perfOn) {
|
||||
auto search = calls_counter.find(method);
|
||||
if (search != calls_counter.end()) {
|
||||
|
|
@ -25,6 +28,25 @@ void MlPerfMon::add_method_call(const std::string &method) {
|
|||
}
|
||||
}
|
||||
|
||||
void MlPerfMon::end_method_call() {
|
||||
if (!call_stack.empty()){
|
||||
call_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
std::string MlPerfMon::callstack() const {
|
||||
std::string cs {"call stack:\n"};
|
||||
|
||||
int cnt = 0;
|
||||
for (auto it = call_stack.rbegin(); it != call_stack.rend() && cnt < call_stack_max_methods; ++it, ++cnt)
|
||||
cs.append( std::string(*it) + "\n"); // << std::endl;
|
||||
|
||||
if (call_stack.size() > call_stack_max_methods)
|
||||
cs.append("next " + std::to_string(call_stack.size() - call_stack_max_methods) + " entries skipped..\n");
|
||||
|
||||
return cs.append("\n");
|
||||
}
|
||||
|
||||
void MlPerfMon::print_results() {
|
||||
if (perfOn) {
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> end_time = std::chrono::high_resolution_clock::now();
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
#include "ml.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <deque>
|
||||
#include <chrono>
|
||||
|
||||
static const int method_name_print_len = 15;
|
||||
static const int print_top_methods = 15;
|
||||
static const int call_stack_max_methods = 10;
|
||||
|
||||
class MlPerfMon {
|
||||
|
||||
|
|
@ -24,10 +26,13 @@ public:
|
|||
void turnOn();
|
||||
|
||||
void add_method_call(const std::string &method);
|
||||
void end_method_call();
|
||||
std::string callstack() const;
|
||||
void print_results();
|
||||
|
||||
private:
|
||||
bool perfOn;
|
||||
std::unordered_map<std::string, long> calls_counter;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
|
||||
std::deque<std::string> call_stack;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue