From 94d0ce9c2d2c06def54ab5071a66711b4da4b342 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 26 Dec 2024 00:45:53 +0800 Subject: [PATCH 1/3] :memo: format --- std/csv.nas | 10 +++++----- std/file.nas | 24 +++++++++++------------- std/queue.nas | 24 ++++++++++++------------ std/stack.nas | 4 ++-- std/string.nas | 6 ++++-- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/std/csv.nas b/std/csv.nas index c2d843d..d6edac4 100644 --- a/std/csv.nas +++ b/std/csv.nas @@ -2,14 +2,14 @@ # ValKmjolnir 2022/10/15 use std.io; -var read = func(path, delimeter=",", endline="\n") { +var read = func(path, delimeter = ",", endline = "\n") { var context = io.readfile(path); context = split(endline, context); - forindex(var i;context) { - context[i] = split(delimeter,context[i]); + forindex(var i; context) { + context[i] = split(delimeter, context[i]); } - if (size(context)<=1) { - die("incorrect csv file <"~path~">: "~size(context)~" line(s)."); + if (size(context) <= 1) { + die("incorrect csv file <" ~ path ~ ">: " ~ size(context) ~ " line(s)."); } return { property: context[0], diff --git a/std/file.nas b/std/file.nas index 1138a54..d7bf765 100644 --- a/std/file.nas +++ b/std/file.nas @@ -4,12 +4,10 @@ use std.io; use std.unix; var SEEK_SET = io.SEEK_SET; - var SEEK_CUR = io.SEEK_CUR; - var SEEK_END = io.SEEK_END; -var new = func(filename, mode="r") { +var new = func(filename, mode = "r") { if (!io.exists(filename)) { return nil; } @@ -56,7 +54,7 @@ var find_all_files = func(path) { var dd = unix.opendir(path); var res = []; while(var n = unix.readdir(dd)) { - if (unix.isfile(path~"/"~n)) { + if (unix.isfile(path ~ "/" ~ n)) { append(res, n); } } @@ -74,11 +72,11 @@ var recursive_find_files = func(path) { files: [] }; while(var n = unix.readdir(dd)) { - if (unix.isfile(path~"/"~n)) { + if (unix.isfile(path ~ "/" ~ n)) { append(res.files, n); - } elsif (unix.isdir(path~"/"~n) and n!="." and n!="..") { - var tmp = recursive_find_files(path~"/"~n); - if (tmp!=nil) { + } elsif (unix.isdir(path ~ "/" ~ n) and n != "." and n != "..") { + var tmp = recursive_find_files(path ~ "/" ~ n); + if (tmp != nil) { append(res.files, tmp); } } @@ -89,19 +87,19 @@ var recursive_find_files = func(path) { var recursive_find_files_flat = func(path) { var tree_files = recursive_find_files(path); - if (tree_files==nil) { + if (tree_files == nil) { return []; } var flat = []; var bfs = [tree_files]; - while(size(bfs)!=0) { + while(size(bfs) != 0) { var first = pop(bfs); foreach(var file_record; first.files) { if (ishash(file_record)) { append(bfs, file_record); continue; } - append(flat, first.dir~"/"~file_record); + append(flat, first.dir ~ "/" ~ file_record); } } return flat; @@ -110,7 +108,7 @@ var recursive_find_files_flat = func(path) { var recursive_find_files_with_extension = func(path, extensions...) { var in_vec = func(ext) { foreach(var i; extensions) { - if (ext==i) { + if (ext == i) { return 1; } } @@ -121,7 +119,7 @@ var recursive_find_files_with_extension = func(path, extensions...) { var res = []; foreach(var filename; files) { var tmp = split('.', filename); - if (size(tmp)>1 and in_vec(tmp[-1])) { + if (size(tmp) > 1 and in_vec(tmp[-1])) { append(res, filename); } } diff --git a/std/queue.nas b/std/queue.nas index d662e77..392600a 100644 --- a/std/queue.nas +++ b/std/queue.nas @@ -4,32 +4,32 @@ var new = func() { var (begin, end) = (nil, nil); return{ push: func(elem) { - var new_node={ + var new_node = { elem:elem, next:nil }; - if (begin==nil) - begin=end=new_node; + if (begin == nil) + begin = end = new_node; else { - end.next=new_node; - end=new_node; + end.next = new_node; + end = new_node; } }, pop: func() { - if (begin!=nil) - begin=begin.next; - if (begin==nil) - end=nil; + if (begin != nil) + begin = begin.next; + if (begin == nil) + end = nil; }, front: func() { - if (begin!=nil) + if (begin != nil) return begin.elem; }, clear: func() { - begin=end=nil; + begin = end = nil; }, empty: func() { - return begin==nil; + return begin == nil; } }; } diff --git a/std/stack.nas b/std/stack.nas index 596a603..6fc8544 100644 --- a/std/stack.nas +++ b/std/stack.nas @@ -10,7 +10,7 @@ var stack = func() { return pop(vec); }, top: func() { - if (size(vec)!=0) { + if (size(vec) != 0) { return vec[-1]; } }, @@ -18,7 +18,7 @@ var stack = func() { vec = []; }, empty: func() { - return size(vec)==0; + return size(vec) == 0; } }; } diff --git a/std/string.nas b/std/string.nas index b14d2ce..f2ab3b5 100644 --- a/std/string.nas +++ b/std/string.nas @@ -33,11 +33,13 @@ func() { }(); var to_char = func(number) { - return 0<=number and number<256? __num_to_char[number]:""; + return 0 <= number and number < 256? __num_to_char[number] : ""; } var to_num = func(character) { - return __temp_contains(__char_to_num, character)? __char_to_num[character]:-1; + return __temp_contains(__char_to_num, character) + ? __char_to_num[character] + : -1; } var __string_split_with_empty_substr = func(separator, str) { From 985dee800169fa81a6ac6939a9e7e95dc25af9b6 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 26 Dec 2024 21:02:35 +0800 Subject: [PATCH 2/3] :memo: format --- src/nasal_type.cpp | 37 --------------- src/nasal_type.h | 98 +++++++++++++++++++++++--------------- src/nasal_vm.cpp | 10 ++-- src/nasal_vm.h | 40 ++++++++-------- test/coroutine.nas | 116 +++++++++++++++++++++++---------------------- 5 files changed, 144 insertions(+), 157 deletions(-) diff --git a/src/nasal_type.cpp b/src/nasal_type.cpp index 588fbc2..8a38b11 100644 --- a/src/nasal_type.cpp +++ b/src/nasal_type.cpp @@ -317,41 +317,4 @@ std::ostream& operator<<(std::ostream& out, var& ref) { return out; } -bool var::object_check(const std::string& name) const { - return is_ghost() && ghost().type_name == name && ghost().pointer; -} - -var var::none() { - return {vm_type::vm_none, static_cast(0)}; -} - -var var::nil() { - return {vm_type::vm_nil, static_cast(0)}; -} - -var var::ret(u64 pc) { - return {vm_type::vm_ret, pc}; -} - -var var::cnt(i64 n) { - return {vm_type::vm_cnt, n}; -} - -var var::num(f64 n) { - return {vm_type::vm_num, n}; -} - -var var::gcobj(nas_val* p) { - return {p->type, p}; -} - -var var::addr(var* p) { - return {vm_type::vm_addr, p}; -} - -var nas_err(const std::string& error_function_name, const std::string& info) { - std::cerr << "[vm] " << error_function_name << ": " << info << "\n"; - return var::none(); -} - } \ No newline at end of file diff --git a/src/nasal_type.h b/src/nasal_type.h index 029f9da..3c240d5 100644 --- a/src/nasal_type.h +++ b/src/nasal_type.h @@ -86,31 +86,45 @@ public: } val; private: - var(vm_type t, u64 pc) {type = t; val.ret = pc;} - var(vm_type t, i64 ct) {type = t; val.cnt = ct;} - var(vm_type t, f64 n) {type = t; val.num = n;} - var(vm_type t, var* p) {type = t; val.addr = p;} - var(vm_type t, nas_val* p) {type = t; val.gcobj = p;} + var(vm_type t, u64 pc) { type = t; val.ret = pc; } + var(vm_type t, i64 ct) { type = t; val.cnt = ct; } + var(vm_type t, f64 n) { type = t; val.num = n; } + var(vm_type t, var* p) { type = t; val.addr = p; } + var(vm_type t, nas_val* p) { type = t; val.gcobj = p; } public: var() = default; var(const var&) = default; bool operator==(const var& nr) const { - return type==nr.type && val.gcobj==nr.val.gcobj; + return type == nr.type && val.gcobj == nr.val.gcobj; } bool operator!=(const var& nr) const { - return type!=nr.type || val.gcobj!=nr.val.gcobj; + return type != nr.type || val.gcobj != nr.val.gcobj; } public: // create new var object - static var none(); - static var nil(); - static var ret(u64); - static var cnt(i64); - static var num(f64); - static var gcobj(nas_val*); - static var addr(var*); + static var none() { + return var(vm_type::vm_none, static_cast(0)); + } + static var nil() { + return var(vm_type::vm_nil, static_cast(0)); + } + static var ret(u64 pc) { + return var(vm_type::vm_ret, pc); + } + static var cnt(i64 n) { + return var(vm_type::vm_cnt, n); + } + static var num(f64 n) { + return var(vm_type::vm_num, n); + } + static var gcobj(nas_val* p) { + return var(p->type, p); + } + static var addr(var* p) { + return var(vm_type::vm_addr, p); + } public: // get value @@ -143,26 +157,27 @@ public: const nas_map& map() const { return *val.gcobj->ptr.map; } public: - bool is_none() const { return type==vm_type::vm_none; } - bool is_cnt() const { return type==vm_type::vm_cnt; } - bool is_addr() const { return type==vm_type::vm_addr; } - bool is_ret() const { return type==vm_type::vm_ret; } - bool is_nil() const { return type==vm_type::vm_nil; } - bool is_num() const { return type==vm_type::vm_num; } - bool is_str() const { return type==vm_type::vm_str; } - bool is_vec() const { return type==vm_type::vm_vec; } - bool is_hash() const { return type==vm_type::vm_hash; } - bool is_func() const { return type==vm_type::vm_func; } - bool is_upval() const { return type==vm_type::vm_upval; } - bool is_ghost() const { return type==vm_type::vm_ghost; } - bool is_coroutine() const { return type==vm_type::vm_co; } - bool is_map() const { return type==vm_type::vm_map; } + bool is_none() const { return type == vm_type::vm_none; } + bool is_cnt() const { return type == vm_type::vm_cnt; } + bool is_addr() const { return type == vm_type::vm_addr; } + bool is_ret() const { return type == vm_type::vm_ret; } + bool is_nil() const { return type == vm_type::vm_nil; } + bool is_num() const { return type == vm_type::vm_num; } + bool is_str() const { return type == vm_type::vm_str; } + bool is_vec() const { return type == vm_type::vm_vec; } + bool is_hash() const { return type == vm_type::vm_hash; } + bool is_func() const { return type == vm_type::vm_func; } + bool is_upval() const { return type == vm_type::vm_upval; } + bool is_ghost() const { return type == vm_type::vm_ghost; } + bool is_coroutine() const { return type == vm_type::vm_co; } + bool is_map() const { return type == vm_type::vm_map; } public: // number and string can be translated to each other f64 to_num() const; std::string to_str(); - bool object_check(const std::string&) const; + inline bool object_check(const std::string&) const; + friend std::ostream& operator<<(std::ostream&, var&); }; struct nas_vec { @@ -174,6 +189,7 @@ struct nas_vec { auto size() const { return elems.size(); } var get_value(const i32); var* get_memory(const i32); + friend std::ostream& operator<<(std::ostream&, nas_vec&); }; struct nas_hash { @@ -185,6 +201,7 @@ struct nas_hash { auto size() const { return elems.size(); } var get_value(const std::string&); var* get_memory(const std::string&); + friend std::ostream& operator<<(std::ostream&, nas_hash&); }; struct nas_func { @@ -206,6 +223,7 @@ struct nas_func { parameter_size(0), local_size(0), dynamic_parameter_name("") {} void clear(); + friend std::ostream& operator<<(std::ostream&, nas_func&); }; struct nas_upval { @@ -222,7 +240,7 @@ public: nas_upval(): on_stack(true), size(0), stack_frame_offset(nullptr) {} var& operator[](usize n) { - return on_stack? stack_frame_offset[n]:elems[n]; + return on_stack? stack_frame_offset[n] : elems[n]; } void clear() { @@ -250,6 +268,7 @@ public: ~nas_ghost() { clear(); } void set(const std::string&, destructor, marker, void*); void clear(); + friend std::ostream& operator<<(std::ostream&, const nas_ghost&); public: const auto& get_ghost_name() const { return type_name; } @@ -290,6 +309,7 @@ struct nas_co { delete[] ctx.stack; } void clear(); + friend std::ostream& operator<<(std::ostream&, const nas_co&); }; struct nas_map { @@ -304,21 +324,21 @@ public: var get_value(const std::string&); var* get_memory(const std::string&); + friend std::ostream& operator<<(std::ostream&, nas_map&); }; -std::ostream& operator<<(std::ostream&, nas_vec&); -std::ostream& operator<<(std::ostream&, nas_hash&); -std::ostream& operator<<(std::ostream&, nas_func&); -std::ostream& operator<<(std::ostream&, nas_map&); -std::ostream& operator<<(std::ostream&, const nas_ghost&); -std::ostream& operator<<(std::ostream&, const nas_co&); -std::ostream& operator<<(std::ostream&, var&); - const var zero = var::num(0); const var one = var::num(1); const var nil = var::nil(); +inline bool var::object_check(const std::string& name) const { + return is_ghost() && ghost().type_name == name && ghost().pointer; +} + // use to print error log and return error value -var nas_err(const std::string&, const std::string&); +static var nas_err(const std::string& func, const std::string& info) { + std::cerr << "[vm] " << func << ": " << info << "\n"; + return var::none(); +} } \ No newline at end of file diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index 70bc2cc..3a57ec4 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -536,12 +536,12 @@ void vm::die(const std::string& str) { if (!ngc.cort) { // in main context, exit directly std::exit(1); - } else { - // in coroutine, shut down the coroutine and return to main context - ctx.pc = 0; // mark coroutine 'dead' - ngc.context_reserve(); // switch context to main - ctx.top[0] = nil; // generate return value 'nil' } + + // in coroutine, shut down the coroutine and return to main context + ctx.pc = 0; // mark coroutine 'dead' + ngc.context_reserve(); // switch context to main + ctx.top[0] = nil; // generate return value 'nil' } void vm::run(const codegen& gen, diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 0829bce..6221208 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -359,8 +359,8 @@ inline void vm::o_loadl() { } inline void vm::o_loadu() { - ctx.funcr.func().upval[(imm[ctx.pc]>>16)&0xffff] - .upval()[imm[ctx.pc]&0xffff] = (ctx.top--)[0]; + ctx.funcr.func().upval[(imm[ctx.pc]>>16) & 0xffff] + .upval()[imm[ctx.pc] & 0xffff] = (ctx.top--)[0]; } inline void vm::o_dup() { @@ -452,7 +452,7 @@ inline void vm::o_lnot() { var val = ctx.top[0]; switch(val.type) { case vm_type::vm_nil: ctx.top[0] = one; break; - case vm_type::vm_num: ctx.top[0] = val.num()? zero:one; break; + case vm_type::vm_num: ctx.top[0] = val.num()? zero : one; break; case vm_type::vm_str: { const f64 num = util::str_to_num(val.str().c_str()); if (std::isnan(num)) { @@ -462,7 +462,7 @@ inline void vm::o_lnot() { } } break; default: - die("cannot do not-operation on "+type_name_string(val)); + die("cannot do not-operation on " + type_name_string(val)); return; } } @@ -477,7 +477,7 @@ inline void vm::o_bnot() { inline void vm::o_btor() { ctx.top[-1] = var::num( - static_cast(ctx.top[-1].to_num())| + static_cast(ctx.top[-1].to_num()) | static_cast(ctx.top[0].to_num()) ); --ctx.top; @@ -485,7 +485,7 @@ inline void vm::o_btor() { inline void vm::o_btxor() { ctx.top[-1] = var::num( - static_cast(ctx.top[-1].to_num())^ + static_cast(ctx.top[-1].to_num()) ^ static_cast(ctx.top[0].to_num()) ); --ctx.top; @@ -493,7 +493,7 @@ inline void vm::o_btxor() { inline void vm::o_btand() { ctx.top[-1] = var::num( - static_cast(ctx.top[-1].to_num())& + static_cast(ctx.top[-1].to_num()) & static_cast(ctx.top[0].to_num()) ); --ctx.top; @@ -503,10 +503,10 @@ inline void vm::o_btand() { ctx.top[-1] = var::num(ctx.top[-1].to_num() type ctx.top[0].to_num());\ --ctx.top; -inline void vm::o_add() {op_calc(+);} -inline void vm::o_sub() {op_calc(-);} -inline void vm::o_mul() {op_calc(*);} -inline void vm::o_div() {op_calc(/);} +inline void vm::o_add() { op_calc(+); } +inline void vm::o_sub() { op_calc(-); } +inline void vm::o_mul() { op_calc(*); } +inline void vm::o_div() { op_calc(/); } inline void vm::o_lnk() { // concat two vectors into one if (ctx.top[-1].is_vec() && ctx.top[0].is_vec()) { @@ -535,7 +535,7 @@ inline void vm::o_subc() {op_calc_const(-);} inline void vm::o_mulc() {op_calc_const(*);} inline void vm::o_divc() {op_calc_const(/);} inline void vm::o_lnkc() { - ctx.top[0] = ngc.newstr(ctx.top[0].to_str()+const_string[imm[ctx.pc]]); + ctx.top[0] = ngc.newstr(ctx.top[0].to_str() + const_string[imm[ctx.pc]]); } // top[0] stores the value of memr[0], to avoid being garbage-collected @@ -575,7 +575,7 @@ inline void vm::o_lnkeq() { ctx.memr[0].to_str()+ctx.top[-1].to_str() ); ctx.memr = nullptr; - ctx.top -= imm[ctx.pc]+1; + ctx.top -= imm[ctx.pc] + 1; } inline void vm::o_bandeq() { @@ -598,11 +598,11 @@ inline void vm::o_boreq() { inline void vm::o_bxoreq() { ctx.top[-1] = ctx.memr[0] = var::num( - static_cast(ctx.memr[0].to_num())^ + static_cast(ctx.memr[0].to_num()) ^ static_cast(ctx.top[-1].to_num()) ); ctx.memr = nullptr; - ctx.top -= imm[ctx.pc]+1; + ctx.top -= imm[ctx.pc] + 1; } // top[0] stores the value of memr[0], to avoid being garbage-collected @@ -1083,8 +1083,8 @@ inline void vm::o_mcalll() { inline void vm::o_mupval() { ctx.memr = &( ctx.funcr.func() - .upval[(imm[ctx.pc]>>16)&0xffff] - .upval()[imm[ctx.pc]&0xffff] + .upval[(imm[ctx.pc]>>16) & 0xffff] + .upval()[imm[ctx.pc] & 0xffff] ); (++ctx.top)[0] = ctx.memr[0]; // push value in this memory space on stack @@ -1102,7 +1102,7 @@ inline void vm::o_mcallv() { } } else if (vec.is_hash()) { // do mcallh but use the mcallv way if (!val.is_str()) { - die("must use string as the key but get "+type_name_string(val)); + die("must use string as the key but get " + type_name_string(val)); return; } auto& ref = vec.hash(); @@ -1114,7 +1114,7 @@ inline void vm::o_mcallv() { } } else if (vec.is_map()) { if (!val.is_str()) { - die("must use string as the key but get "+type_name_string(val)); + die("must use string as the key but get " + type_name_string(val)); return; } auto& ref = vec.map(); @@ -1192,7 +1192,7 @@ inline void vm::o_ret() { auto size = func.func().local_size; upval.on_stack = false; upval.elems.resize(size); - for(u64 i = 0; i Date: Thu, 26 Dec 2024 23:19:34 +0800 Subject: [PATCH 3/3] :memo: add doc about how to build on windows --- .gitignore | 3 ++- CMakeLists.txt | 29 +++++++++++++++++------------ README.md | 2 +- doc/README_zh.md | 1 + doc/windows-build.md | 27 +++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 doc/windows-build.md diff --git a/.gitignore b/.gitignore index 7ccf091..76f7285 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ build/ out/ dist/ -cmake-build-*/ +cmake-build-* +cmake-windows-* # IDE and editor files .vscode/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 69c03f8..40d3f42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wshadow -Wall") add_compile_options(-fPIC) # MSVC needs this command option to really enable utf-8 output -if(MSVC) +if (MSVC) add_compile_options(/utf-8) endif() @@ -103,16 +103,21 @@ target_link_libraries(mat module-used-object) add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp) target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}/src) +if (WIN32) + target_link_libraries(nasock ws2_32) +endif() target_link_libraries(nasock module-used-object) -# Add web library -add_library(nasal-web SHARED - src/nasal_web.cpp - ${NASAL_OBJECT_SOURCE_FILE} -) -target_include_directories(nasal-web PRIVATE ${CMAKE_SOURCE_DIR}/src) -set_target_properties(nasal-web PROPERTIES - C_VISIBILITY_PRESET hidden - CXX_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN ON -) +# Add web library, not for MSVC now +if (NOT MSVC) + add_library(nasal-web SHARED + src/nasal_web.cpp + ${NASAL_OBJECT_SOURCE_FILE} + ) + target_include_directories(nasal-web PRIVATE ${CMAKE_SOURCE_DIR}/src) + set_target_properties(nasal-web PROPERTIES + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + ) +endif() \ No newline at end of file diff --git a/README.md b/README.md index 119dbf4..bf26763 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Make sure thread model is `posix thread model`, otherwise no thread library exis ### __Windows (Visual Studio)__ -There is a [__CMakelists.txt__](./CMakeLists.txt) to create project. +There is a [__CMakelists.txt__](./CMakeLists.txt) to create project. Recently we find how to build it with command line tools: [__Build Nasal-Interpreter on Windows]__(./doc/windows-build.md). ### __Linux / macOS / Unix__ diff --git a/doc/README_zh.md b/doc/README_zh.md index b750837..ccefecb 100644 --- a/doc/README_zh.md +++ b/doc/README_zh.md @@ -81,6 +81,7 @@ Windows 平台的预览版解释器现在还没配置相关流水线, ### __Windows 平台 (Vistual Studio)__ 项目提供了 [__CMakeLists.txt__](../CMakeLists.txt) 用于在`Visual Studio`中创建项目。 +最近我们总结了命令行编译的方法 [__如何在 Windows 平台编译 Nasal-Interpreter__](./windows-build.md)。 ### __Linux / macOS / Unix 平台__ diff --git a/doc/windows-build.md b/doc/windows-build.md new file mode 100644 index 0000000..665ba49 --- /dev/null +++ b/doc/windows-build.md @@ -0,0 +1,27 @@ +# Build Nasal-Interpreter on Windows + +## MSVC / Visual Studio + +Need CMake and Visual Studio 2022. Remember to add MSBuild.exe to Path. + +Valid on powershell: + +```sh +mkdir cmake-windows-msvc +cd cmake-windows-msvc +cmake .. -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" +MSbuild.exe nasal.sln /p:Configuration=Release /p:Platform=x64 +``` + +## MingW-W64 + +Need CMake and MingW-W64. Remember to add MingW-W64 bin to Path. + +Valid on powershell: + +```sh +mkdir cmake-windows-mingw +cd cmake-windows-mingw +cmake .. -DCMAKE_BUILD_TYPE=Release -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ +mingw32-make.exe -j6 +```