beautiful unicode output info

This commit is contained in:
ValKmjolnir 2024-06-02 23:56:49 +08:00
parent 0f61f8e18e
commit 5a165d3255
8 changed files with 186 additions and 143 deletions

View File

@ -112,7 +112,12 @@ build/nasal_type.o:\
src/nasal_type.h src/nasal_type.cpp | build src/nasal_type.h src/nasal_type.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_type.cpp -o build/nasal_type.o $(CXX) $(CXXFLAGS) src/nasal_type.cpp -o build/nasal_type.o
build/nasal_gc.o: src/nasal.h src/nasal_type.h src/nasal_gc.h src/nasal_gc.cpp | build build/nasal_gc.o:\
src/nasal.h\
src/util/util.h\
src/nasal_type.h\
src/nasal_gc.h\
src/nasal_gc.cpp | build
$(CXX) $(CXXFLAGS) src/nasal_gc.cpp -o build/nasal_gc.o $(CXX) $(CXXFLAGS) src/nasal_gc.cpp -o build/nasal_gc.o
build/nasal_import.o: \ build/nasal_import.o: \

View File

@ -45,7 +45,7 @@ private:
std::string format_location(expr* node) { std::string format_location(expr* node) {
std::stringstream ss; std::stringstream ss;
ss << " ["; ss << " [";
node->get_location().dump_begin(ss); node->get_location().dump_begin(ss);
ss << "]\n"; ss << "]\n";
return ss.str(); return ss.str();
@ -90,10 +90,10 @@ public:
public: public:
void dump(code_block* root) { void dump(code_block* root) {
util::windows_code_page_manager wcpm; util::windows_code_page_manager wm;
wcpm.set_utf8_output(); wm.set_utf8_output();
root->accept(this); root->accept(this);
wcpm.restore_code_page(); wm.restore_code_page();
} }
}; };

View File

@ -23,4 +23,40 @@ cli_config parse(const std::vector<std::string>& args) {
return result; return result;
} }
std::ostream& help(std::ostream& out) {
out
<< "\n"
<< " ,--#-,\n"
<< "<3 / \\____\\ <3\n"
<< " |_|__A_|\n"
<< "\nnasal <option>\n"
<< "option:\n"
<< " -h, --help | get help.\n"
<< " -v, --version | get version.\n"
<< " -r, --repl | use repl interpreter.\n"
<< "\nnasal [option] <file> [argv]\n"
<< "option:\n"
<< " -a, --ast | view ast after link/optimize process.\n"
<< " --raw-ast | view ast without after-processing.\n"
<< " -c, --code | view generated bytecode.\n"
<< " -s, --symbol | show analysed symbol info.\n"
<< " -e, --exec | execute directly.\n"
<< " -t, --time | show execute time.\n"
<< " -d, --detail | get detail info.\n"
<< " -f, --ref-file | get referenced files.\n"
<< " -dbg, --debug | debug mode.\n"
<< " --prof | show profiling result, "
<< "available under debug mode.\n"
<< " --prof-all | show profiling result of all files, "
<< "available under debug mode.\n"
<< " --limit | use limited execution mode "
<< "(readonly api enabled).\n"
<< "file:\n"
<< " <filename> | execute file.\n"
<< "argv:\n"
<< " <args> | cmd arguments used in program.\n"
<< "\n";
return out;
}
} }

View File

@ -5,6 +5,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include <iostream>
namespace nasal::cli { namespace nasal::cli {
@ -67,4 +68,6 @@ const std::unordered_map<std::string, option> cli_options = {
cli_config parse(const std::vector<std::string>&); cli_config parse(const std::vector<std::string>&);
std::ostream& help(std::ostream&);
} }

View File

@ -18,45 +18,9 @@
#include "repl/repl.h" #include "repl/repl.h"
#include "cli/cli.h" #include "cli/cli.h"
#include <unordered_map>
#include <thread> #include <thread>
#include <cstdlib> #include <cstdlib>
std::ostream& help(std::ostream& out) {
out
<< "\n"
<< " ,--#-,\n"
<< "<3 / \\____\\ <3\n"
<< " |_|__A_|\n"
<< "\nnasal <option>\n"
<< "option:\n"
<< " -h, --help | get help.\n"
<< " -v, --version | get version.\n"
<< " -r, --repl | use repl interpreter.\n"
<< "\nnasal [option] <file> [argv]\n"
<< "option:\n"
<< " -a, --ast | view ast after link/optimize process.\n"
<< " --raw-ast | view ast without after-processing.\n"
<< " -c, --code | view generated bytecode.\n"
<< " -s, --symbol | show analysed symbol info.\n"
<< " -e, --exec | execute directly.\n"
<< " -t, --time | show execute time.\n"
<< " -d, --detail | get detail info.\n"
<< " -f, --ref-file | get referenced files.\n"
<< " -dbg, --debug | debug mode.\n"
<< " --prof | show profiling result, available in debug mode.\n"
<< " --prof-all | show profiling result of all files, "
<< "available under debug mode.\n"
<< " --limit | use limited execution mode "
<< "(readonly api enabled).\n"
<< "file:\n"
<< " <filename> | execute file.\n"
<< "argv:\n"
<< " <args> | cmd arguments used in program.\n"
<< "\n";
return out;
}
std::ostream& logo(std::ostream& out) { std::ostream& logo(std::ostream& out) {
out out
<< "\n" << "\n"
@ -67,7 +31,8 @@ std::ostream& logo(std::ostream& out) {
<< " \\_\\ \\/ \\__,_|___/\\__,_|_|\n" << " \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<< "\n" << "\n"
<< "ver : " << __nasver__ << "ver : " << __nasver__
<< " " << nasal::util::get_platform() << " " << nasal::util::get_arch() << " " << nasal::util::get_platform()
<< " " << nasal::util::get_arch()
<< " (" << __DATE__ << " " << __TIME__ << ")\n" << " (" << __DATE__ << " " << __TIME__ << ")\n"
<< "std : c++ " << __cplusplus << "\n" << "std : c++ " << __cplusplus << "\n"
<< "core : " << std::thread::hardware_concurrency() << " core(s)\n" << "core : " << std::thread::hardware_concurrency() << " core(s)\n"
@ -75,9 +40,9 @@ std::ostream& logo(std::ostream& out) {
<< "repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n" << "repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<< "wiki : https://wiki.flightgear.org/Nasal_scripting_language\n" << "wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
<< "\n" << "\n"
<< "presented by fgprc members\n" << "presented by fgprc members:\n"
<< " - http://fgprc.org\n" << " - http://fgprc.org\n"
<< " - http://fgprc.org.cn\n" << " - http://fgprc.org.cn\n"
<< "\n" << "\n"
<< "input <nasal -h> to get help .\n\n"; << "input <nasal -h> to get help .\n\n";
return out; return out;
@ -96,7 +61,8 @@ std::ostream& version(std::ostream& out) {
} }
out << "nasal version " << __nasver__; out << "nasal version " << __nasver__;
out << " " << nasal::util::get_platform() << " " << nasal::util::get_arch(); out << " " << nasal::util::get_platform();
out << " " << nasal::util::get_arch();
out << " (" << __DATE__ << " " << __TIME__ << ")\n"; out << " (" << __DATE__ << " " << __TIME__ << ")\n";
return out; return out;
} }
@ -195,7 +161,7 @@ i32 main(i32 argc, const char* argv[]) {
// run directly or show help // run directly or show help
if (argc==2) { if (argc==2) {
if (config.has(nasal::cli::option::cli_help)) { if (config.has(nasal::cli::option::cli_help)) {
std::clog << help; std::clog << nasal::cli::help;
} else if (config.has(nasal::cli::option::cli_version)) { } else if (config.has(nasal::cli::option::cli_version)) {
std::clog << version; std::clog << version;
} else if (config.has(nasal::cli::option::cli_repl_mode)) { } else if (config.has(nasal::cli::option::cli_repl_mode)) {

View File

@ -1,4 +1,5 @@
#include "nasal_gc.h" #include "nasal_gc.h"
#include "util/util.h"
namespace nasal { namespace nasal {
@ -258,15 +259,27 @@ void gc::clear() {
} }
void gc::info() const { void gc::info() const {
util::windows_code_page_manager wm;
wm.set_utf8_output();
using std::left; using std::left;
using std::setw; using std::setw;
using std::setfill; using std::setfill;
using std::setprecision;
const char* used_table_name[] = { const char* used_table_name[] = {
"object type", "gc count", "alloc count", "memory size", "object type",
"detail", "time spend", "gc time", "avg time", "max gc", "gc count",
"max mark", "max sweep", nullptr "alloc count",
"memory size",
"detail",
"time spend",
"gc time",
"avg time",
"max gc",
"max mark",
"max sweep",
nullptr
}; };
const char* name[] = { const char* name[] = {
"string", "string",
@ -297,21 +310,33 @@ void gc::info() const {
len = std::to_string(size[i]).length(); len = std::to_string(size[i]).length();
indent = indent<len? len:indent; indent = indent<len? len:indent;
} }
auto indent_string = std::string("--"); auto indent_string = std::string("──");
for(usize i = 0; i<indent; ++i) { for(usize i = 0; i<indent; ++i) {
indent_string += "-"; indent_string += "";
} }
const auto last_line = "+" + indent_string + "+" + const auto first_line = "" + indent_string + "" +
indent_string + "-" + indent_string + "-" + indent_string + "+"; indent_string + "" +
indent_string = indent_string + "+" + indent_string + "" +
indent_string + "+" + indent_string + "+" + indent_string; indent_string + "";
const auto mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto another_mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto last_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
std::clog << "\n+" << indent_string << "+\n"; std::clog << "\n" << first_line << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "object type"; std::clog << " " << left << setw(indent) << setfill(' ') << "object type";
std::clog << " | " << left << setw(indent) << setfill(' ') << "gc count"; std::clog << " " << left << setw(indent) << setfill(' ') << "gc count";
std::clog << " | " << left << setw(indent) << setfill(' ') << "alloc count"; std::clog << " " << left << setw(indent) << setfill(' ') << "alloc count";
std::clog << " | " << left << setw(indent) << setfill(' ') << "memory size"; std::clog << " " << left << setw(indent) << setfill(' ') << "memory size";
std::clog << " |\n+" << indent_string << "+\n"; std::clog << " \n" << mid_line << "\n";
double total = 0; double total = 0;
for(u8 i = 0; i<gc_type_size; ++i) { for(u8 i = 0; i<gc_type_size; ++i) {
@ -319,46 +344,54 @@ void gc::info() const {
continue; continue;
} }
total += static_cast<f64>(gcnt[i]); total += static_cast<f64>(gcnt[i]);
std::clog << "| " << left << setw(indent) << setfill(' ') << name[i]; std::clog << " " << left << setw(indent) << setfill(' ') << name[i];
std::clog << " | " << left << setw(indent) << setfill(' ') << gcnt[i]; std::clog << " " << left << setw(indent) << setfill(' ') << gcnt[i];
std::clog << " | " << left << setw(indent) << setfill(' ') << acnt[i]; std::clog << " " << left << setw(indent) << setfill(' ') << acnt[i];
std::clog << " | " << left << setw(indent) << setfill(' ') << size[i]; std::clog << " " << left << setw(indent) << setfill(' ') << size[i];
std::clog << " |\n"; std::clog << " \n";
} }
std::clog << "+" << indent_string << "+\n"; std::clog << mid_line << "\n";
auto den = std::chrono::high_resolution_clock::duration::period::den; const auto den = std::chrono::high_resolution_clock::duration::period::den;
std::clog << "| " << left << setw(indent) << setfill(' ') << "detail"; std::clog << " " << left << setw(indent) << setfill(' ') << "detail";
std::clog << " | " << left << setw(indent) << setfill(' ') << "time spend"; std::clog << " " << left << setw(indent) << setfill(' ') << "time spend";
std::clog << " | " << left << setw(indent) << setfill('x') << "x"; std::clog << " " << left << setw(indent) << setfill('x') << "x";
std::clog << " | " << left << setw(indent) << setfill('x') << "x"; std::clog << " " << left << setw(indent) << setfill('x') << "x";
std::clog << " |\n+" << indent_string << "+\n"; std::clog << " \n" << another_mid_line << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "gc time"; const auto gc_time = worktime*1.0/den*1000;
std::clog << " | " << setw(indent-3) << std::setprecision(4) << worktime*1.0/den*1000 << " ms"; std::clog << "" << left << setw(indent) << setfill(' ') << "gc time";
std::clog << setw(indent*2+7) << " " << "|\n"; std::clog << "" << setw(indent-3) << setprecision(4) << gc_time << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "avg time"; const auto avg_time = worktime*1.0/den*1000/total;
std::clog << " | " << setw(indent-3) << std::setprecision(4) << worktime*1.0/den*1000/total << " ms"; std::clog << "" << left << setw(indent) << setfill(' ') << "avg time";
std::clog << setw(indent*2+7) << " " << "|\n"; std::clog << "" << setw(indent-3) << setprecision(4) << avg_time << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "max gc"; const auto max_gc = max_time*1.0/den*1000;
std::clog << " | " << setw(indent-3) << std::setprecision(4) << max_time*1.0/den*1000 << " ms"; std::clog << "" << left << setw(indent) << setfill(' ') << "max gc";
std::clog << setw(indent*2+7) << " " << "|\n"; std::clog << "" << setw(indent-3) << setprecision(4) << max_gc << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "max mark"; const auto max_mark = max_mark_time*1.0/den*1000;
std::clog << " | " << setw(indent-3) << std::setprecision(4) << max_mark_time*1.0/den*1000 << " ms"; std::clog << "" << left << setw(indent) << setfill(' ') << "max mark";
std::clog << setw(indent*2+7) << " " << "|\n"; std::clog << "" << setw(indent-3) << setprecision(4) << max_mark << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "max sweep"; const auto max_sweep = max_sweep_time*1.0/den*1000;
std::clog << " | " << setw(indent-3) << std::setprecision(4) << max_sweep_time*1.0/den*1000 << " ms"; std::clog << "" << left << setw(indent) << setfill(' ') << "max sweep";
std::clog << setw(indent*2+7) << " " << "|\n"; std::clog << "" << setw(indent-3) << setprecision(4) << max_sweep << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << "| " << left << setw(indent) << setfill(' ') << "concurrent"; std::clog << "" << left << setw(indent) << setfill(' ') << "concurrent";
std::clog << " | " << setw(indent) << (flag_concurrent_mark_triggered? "true":"false"); std::clog << "" << setw(indent)
std::clog << setw(indent*2+7) << " " << "|\n"; << (flag_concurrent_mark_triggered? "true":"false");
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << last_line << "\n"; std::clog << last_line << "\n";
wm.restore_code_page();
} }
var gc::alloc(const vm_type type) { var gc::alloc(const vm_type type) {

View File

@ -18,7 +18,7 @@ var table_character_set = [
"┷", "┳", "⊥", "﹃", "﹄", "╮", "╭", "╯", "╰", "" "┷", "┳", "⊥", "﹃", "﹄", "╮", "╭", "╯", "╰", ""
]; ];
var selection_box = ["○", "◉", "☐", "▣"]; var selection_box = ["○", "◉", "☐", "▣", "☑", "☒"];
var char_ttf=[ var char_ttf=[
[" "," "," "," "," "," "], [" "," "," "," "," "," "],

View File

@ -7,8 +7,8 @@ use std.io;
use std.unix; use std.unix;
use std.math; use std.math;
var is_windows_platform=os.platform()=="windows"; var is_windows_platform = os.platform()=="windows";
var is_macos_platform=os.platform()=="macOS"; var is_macos_platform = os.platform()=="macOS";
if (is_windows_platform) { if (is_windows_platform) {
runtime.windows.set_utf8_output(); runtime.windows.set_utf8_output();
@ -17,72 +17,72 @@ if (is_windows_platform) {
var cpu_stat = func() { var cpu_stat = func() {
if (is_windows_platform or is_macos_platform) if (is_windows_platform or is_macos_platform)
return nil; return nil;
var cpu=split("\n",io.readfile("/proc/stat"))[0]; var cpu = split("\n", io.readfile("/proc/stat"))[0];
cpu=split(" ",cpu); cpu = split(" ", cpu);
cpu={ cpu = {
name:cpu[0], name: cpu[0],
user:cpu[1], user: cpu[1],
nice:cpu[2], nice: cpu[2],
system:cpu[3], system: cpu[3],
idle:cpu[4], idle: cpu[4],
iowait:cpu[5], iowait: cpu[5],
irq:cpu[6], irq: cpu[6],
softirq:cpu[7], softirq: cpu[7],
}; };
return cpu; return cpu;
} }
var cpu_occupation = func() { var cpu_occupation = func() {
var first_in=1; var first_in = 1;
while(1) { while(1) {
var cpu0=cpu_stat(); var cpu0 = cpu_stat();
if (first_in) { if (first_in) {
unix.sleep(0.1); unix.sleep(0.1);
first_in=0; first_in = 0;
} else { } else {
for(var i=0;i<10;i+=1) { for(var i = 0; i < 10; i += 1) {
unix.sleep(0.1); unix.sleep(0.1);
coroutine.yield(nil); coroutine.yield(nil);
} }
} }
var cpu1=cpu_stat(); var cpu1 = cpu_stat();
if (is_windows_platform or is_macos_platform) { if (is_windows_platform or is_macos_platform) {
coroutine.yield(0); coroutine.yield(0);
continue; continue;
} }
var t0=cpu0.user+cpu0.nice+cpu0.system+cpu0.idle+cpu0.iowait+cpu0.irq+cpu0.softirq; var t0 = cpu0.user+cpu0.nice+cpu0.system+cpu0.idle+cpu0.iowait+cpu0.irq+cpu0.softirq;
var t1=cpu1.user+cpu1.nice+cpu1.system+cpu1.idle+cpu1.iowait+cpu1.irq+cpu1.softirq; var t1 = cpu1.user+cpu1.nice+cpu1.system+cpu1.idle+cpu1.iowait+cpu1.irq+cpu1.softirq;
var interval=cpu1.idle-cpu0.idle; var interval = cpu1.idle-cpu0.idle;
coroutine.yield(t0==t1?0:(1-interval/(t1-t0))*100); coroutine.yield(t0==t1? 0:(1-interval/(t1-t0))*100);
} }
} }
var mem_occupation = func() { var mem_occupation = func() {
if (is_windows_platform or is_macos_platform) if (is_windows_platform or is_macos_platform)
return {MemTotal:math.inf,MemFree:math.inf}; return {MemTotal:math.inf,MemFree:math.inf};
var meminfo=split("\n",io.readfile("/proc/meminfo")); var meminfo = split("\n",io.readfile("/proc/meminfo"));
var mem_res={}; var mem_res = {};
forindex(var i;meminfo) { forindex(var i; meminfo) {
var tmp=split(" ",meminfo[i])[0:1]; var tmp = split(" ", meminfo[i])[0:1];
tmp[0]=substr(tmp[0],0,size(tmp[0])-1); tmp[0] = substr(tmp[0], 0, size(tmp[0])-1);
mem_res[tmp[0]]=num(tmp[1]); mem_res[tmp[0]] = num(tmp[1]);
} }
return mem_res; return mem_res;
} }
var random_generator = func() { var random_generator = func() {
var rise=[" ","▁","▂","▃","▄","▅","▆","▇","█"]; var rise = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
var total=0; var total = 0;
var statistics=[]; var statistics = [];
setsize(statistics,70); setsize(statistics, 70);
while(1) { while(1) {
for(var i=0;i<10;i+=1) { for(var i=0;i<10;i+=1) {
total+=1; total+=1;
var u=rand()*rand()*(rand()>0.5?-1:1); var u=rand()*rand()*(rand()>0.5?-1:1);
statistics[int(size(statistics)/2+u*size(statistics)/2)]+=1; statistics[int(size(statistics)/2+u*size(statistics)/2)]+=1;
} }
var s=["","",""]; var s = ["", "", ""];
foreach(var st;statistics) { foreach(var st; statistics) {
var max_rate=100/size(statistics); var max_rate=100/size(statistics);
var rate=st/total*100; var rate=st/total*100;
for(var i=size(s)-1;i>=0;i-=1) { for(var i=size(s)-1;i>=0;i-=1) {
@ -97,12 +97,12 @@ var random_generator = func() {
} }
var tmp=""; var tmp="";
for(var i=0;i<size(statistics);i+=1) { for(var i=0;i<size(statistics);i+=1) {
tmp~="-"; tmp~="";
} }
println("\e[16;1H \e[32m|",s[0],"|\e[0m"); println("\e[16;1H \e[32m│", s[0], "│\e[0m");
println("\e[17;1H \e[32m|",s[1],"|\e[0m"); println("\e[17;1H \e[32m│", s[1], "│\e[0m");
println("\e[18;1H \e[32m|",s[2],"|\e[0m"); println("\e[18;1H \e[32m│", s[2], "│\e[0m");
println("\e[19;1H \e[32m+"~tmp~"+\e[0m"); println("\e[19;1H \e[32m╰", tmp, "╯\e[0m");
coroutine.yield(); coroutine.yield();
} }
} }
@ -164,7 +164,7 @@ func() {
var tmp=""; var tmp="";
for(var i=0;i<70;i+=1) { for(var i=0;i<70;i+=1) {
tmp~="-"; tmp~="";
} }
var s=["","",""]; var s=["","",""];
@ -181,11 +181,11 @@ func() {
} }
} }
} }
println("\e[7;1H \e[32m+"~tmp~"+\e[0m"); println("\e[7;1H \e[32m╭"~tmp~"╮\e[0m");
println("\e[8;1H \e[32m|",s[0],"|\e[0m"); println("\e[8;1H \e[32m│",s[0],"│\e[0m");
println("\e[9;1H \e[32m|",s[1],"|\e[0m"); println("\e[9;1H \e[32m│",s[1],"│\e[0m");
println("\e[10;1H \e[32m|",s[2],"|\e[0m"); println("\e[10;1H \e[32m│",s[2],"│\e[0m");
println("\e[11;1H \e[32m+"~tmp~"+\e[0m"); println("\e[11;1H \e[32m├"~tmp~"┤\e[0m");
var s=["","",""]; var s=["","",""];
foreach(var occ;mem_occupation_log) { foreach(var occ;mem_occupation_log) {
@ -201,10 +201,10 @@ func() {
} }
} }
} }
println("\e[12;1H \e[32m|",s[0],"|\e[0m"); println("\e[12;1H \e[32m│",s[0],"│\e[0m");
println("\e[13;1H \e[32m|",s[1],"|\e[0m"); println("\e[13;1H \e[32m│",s[1],"│\e[0m");
println("\e[14;1H \e[32m|",s[2],"|\e[0m"); println("\e[14;1H \e[32m│",s[2],"│\e[0m");
println("\e[15;1H \e[32m+"~tmp~"+\e[0m"); println("\e[15;1H \e[32m├"~tmp~"┤\e[0m");
println("\e[20;1H Press 'q' to quit."); println("\e[20;1H Press 'q' to quit.");
} }