From 597c0388cb2dab46b43282da896b8095f5bb799b Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sat, 1 Jul 2023 23:21:52 +0800 Subject: [PATCH] :rocket: update --- ast/nasal_new_vm.h | 160 -- makefile | 98 +- {ast => src}/ast_dumper.cpp | 0 {ast => src}/ast_dumper.h | 0 {ast => src}/ast_visitor.cpp | 0 {ast => src}/ast_visitor.h | 0 {ast => src}/nasal_new_ast.cpp | 0 {ast => src}/nasal_new_ast.h | 0 {ast => src}/nasal_new_builtin.cpp | 0 {ast => src}/nasal_new_builtin.h | 0 {ast => src}/nasal_new_codegen.cpp | 0 {ast => src}/nasal_new_codegen.h | 0 {ast => src}/nasal_new_dbg.cpp | 0 {ast => src}/nasal_new_dbg.h | 1 + {ast => src}/nasal_new_err.cpp | 9 + {ast => src}/nasal_new_err.h | 10 - {ast => src}/nasal_new_gc.cpp | 78 +- {ast => src}/nasal_new_gc.h | 11 +- {ast => src}/nasal_new_header.h | 0 {ast => src}/nasal_new_import.cpp | 0 {ast => src}/nasal_new_import.h | 0 {ast => src}/nasal_new_lexer.cpp | 0 {ast => src}/nasal_new_lexer.h | 0 {ast => src}/nasal_new_main.cpp | 49 +- {ast => src}/nasal_new_misc.cpp | 0 {ast => src}/nasal_new_opcode.cpp | 0 {ast => src}/nasal_new_opcode.h | 0 {ast => src}/nasal_new_parse.cpp | 0 {ast => src}/nasal_new_parse.h | 0 src/nasal_new_vm.cpp | 412 ++++ ast/nasal_new_vm.cpp => src/nasal_new_vm.h | 2010 +++++++++----------- {ast => src}/optimizer.cpp | 0 {ast => src}/optimizer.h | 0 {ast => src}/symbol_finder.cpp | 1 + {ast => src}/symbol_finder.h | 0 35 files changed, 1436 insertions(+), 1403 deletions(-) delete mode 100644 ast/nasal_new_vm.h rename {ast => src}/ast_dumper.cpp (100%) rename {ast => src}/ast_dumper.h (100%) rename {ast => src}/ast_visitor.cpp (100%) rename {ast => src}/ast_visitor.h (100%) rename {ast => src}/nasal_new_ast.cpp (100%) rename {ast => src}/nasal_new_ast.h (100%) rename {ast => src}/nasal_new_builtin.cpp (100%) rename {ast => src}/nasal_new_builtin.h (100%) rename {ast => src}/nasal_new_codegen.cpp (100%) rename {ast => src}/nasal_new_codegen.h (100%) rename {ast => src}/nasal_new_dbg.cpp (100%) rename {ast => src}/nasal_new_dbg.h (96%) rename {ast => src}/nasal_new_err.cpp (91%) rename {ast => src}/nasal_new_err.h (85%) rename {ast => src}/nasal_new_gc.cpp (81%) rename {ast => src}/nasal_new_gc.h (97%) rename {ast => src}/nasal_new_header.h (100%) rename {ast => src}/nasal_new_import.cpp (100%) rename {ast => src}/nasal_new_import.h (100%) rename {ast => src}/nasal_new_lexer.cpp (100%) rename {ast => src}/nasal_new_lexer.h (100%) rename {ast => src}/nasal_new_main.cpp (81%) rename {ast => src}/nasal_new_misc.cpp (100%) rename {ast => src}/nasal_new_opcode.cpp (100%) rename {ast => src}/nasal_new_opcode.h (100%) rename {ast => src}/nasal_new_parse.cpp (100%) rename {ast => src}/nasal_new_parse.h (100%) create mode 100644 src/nasal_new_vm.cpp rename ast/nasal_new_vm.cpp => src/nasal_new_vm.h (50%) rename {ast => src}/optimizer.cpp (100%) rename {ast => src}/optimizer.h (100%) rename {ast => src}/symbol_finder.cpp (94%) rename {ast => src}/symbol_finder.h (100%) diff --git a/ast/nasal_new_vm.h b/ast/nasal_new_vm.h deleted file mode 100644 index 9bfe4c9..0000000 --- a/ast/nasal_new_vm.h +++ /dev/null @@ -1,160 +0,0 @@ -#pragma once - -#include -#include - -#include "nasal_new_import.h" -#include "nasal_new_gc.h" -#include "nasal_new_codegen.h" - -#ifdef _MSC_VER -#pragma warning (disable:4244) -#pragma warning (disable:4267) -#pragma warning (disable:4102) -#endif - -class vm { -protected: - - /* registers and constants of vm */ - context ctx; - - /* constants */ - const f64* cnum=nullptr; // constant numbers - const std::string* cstr=nullptr; // constant symbols and strings - std::vector imm; // immediate number table - - /* garbage collector */ - gc ngc; - - /* main stack */ - var stack[STACK_DEPTH]; - - /* values used for debugger */ - const std::string* files=nullptr; // file name list - const opcode* bytecode=nullptr; // bytecode buffer address - - /* vm initializing function */ - void init( - const std::vector&, - const std::vector&, - const std::vector&, - const std::vector&, - const std::vector&); - - /* debug functions */ - bool verbose; - void valinfo(var&); - void traceback(); - void stackinfo(const u32); - void reginfo(); - void gstate(); - void lstate(); - void ustate(); - void detail(); - void die(const std::string&); - - /* vm calculation functions*/ - bool cond(var&); - - /* vm operands */ - void o_intg(); - void o_intl(); - void o_loadg(); - void o_loadl(); - void o_loadu(); - void o_pnum(); - void o_pnil(); - void o_pstr(); - void o_newv(); - void o_newh(); - void o_newf(); - void o_happ(); - void o_para(); - void o_deft(); - void o_dyn(); - void o_lnot(); - void o_usub(); - void o_bnot(); - void o_btor(); - void o_btxor(); - void o_btand(); - void o_add(); - void o_sub(); - void o_mul(); - void o_div(); - void o_lnk(); - void o_addc(); - void o_subc(); - void o_mulc(); - void o_divc(); - void o_lnkc(); - void o_addeq(); - void o_subeq(); - void o_muleq(); - void o_diveq(); - void o_lnkeq(); - void o_bandeq(); - void o_boreq(); - void o_bxoreq(); - void o_addeqc(); - void o_subeqc(); - void o_muleqc(); - void o_diveqc(); - void o_lnkeqc(); - void o_addecp(); - void o_subecp(); - void o_mulecp(); - void o_divecp(); - void o_lnkecp(); - void o_meq(); - void o_eq(); - void o_neq(); - void o_less(); - void o_leq(); - void o_grt(); - void o_geq(); - void o_lessc(); - void o_leqc(); - void o_grtc(); - void o_geqc(); - void o_pop(); - void o_jmp(); - void o_jt(); - void o_jf(); - void o_cnt(); - void o_findex(); - void o_feach(); - void o_callg(); - void o_calll(); - void o_upval(); - void o_callv(); - void o_callvi(); - void o_callh(); - void o_callfv(); - void o_callfh(); - void o_callb(); - void o_slcbeg(); - void o_slcend(); - void o_slc(); - void o_slc2(); - void o_mcallg(); - void o_mcalll(); - void o_mupval(); - void o_mcallv(); - void o_mcallh(); - void o_ret(); - -public: - - /* constructor of vm instance */ - vm(): ngc(&ctx), verbose(false) {} - - /* execution entry */ - void run( - const codegen&, - const linker&, - const std::vector&, - const bool - ); -}; diff --git a/makefile b/makefile index c6c5715..08c5a68 100644 --- a/makefile +++ b/makefile @@ -74,79 +74,81 @@ test:nasal @ ./nasal -t -d test/ycombinator.nas NASAL_NEW_AST=\ - nasal_new_misc.o\ nasal_new_err.o\ - nasal_new_gc.o\ - nasal_new_import.o\ - nasal_new_lexer.o\ nasal_new_ast.o\ - nasal_new_builtin.o\ - nasal_new_codegen.o\ - nasal_new_opcode.o\ - nasal_new_parse.o\ - nasal_new_vm.o\ - nasal_new_dbg.o\ - optimizer.o\ - symbol_finder.o\ ast_visitor.o\ ast_dumper.o\ + nasal_new_lexer.o\ + nasal_new_parse.o\ + nasal_new_import.o\ + optimizer.o\ + nasal_new_opcode.o\ + symbol_finder.o\ + nasal_new_codegen.o\ + nasal_new_misc.o\ + nasal_new_gc.o\ + nasal_new_builtin.o\ + nasal_new_vm.o\ + nasal_new_dbg.o\ nasal_new_main.o # for test nnew: $(NASAL_NEW_AST) - $(CXX) $(NASAL_NEW_AST) -o nnew -ldl - @ echo "build done" + $(CXX) $(NASAL_NEW_AST) -O3 -o nnew -ldl -nasal_new_main.o: ast/nasal_new_main.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_main.cpp -fno-exceptions -fPIC -o nasal_new_main.o -I . +nnew.exe: $(NASAL_NEW_AST) + $(CXX) $(NASAL_NEW_AST) -O3 -o nnew.exe -nasal_new_misc.o: ast/nasal_new_header.h ast/nasal_new_misc.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_misc.cpp -fno-exceptions -fPIC -o nasal_new_misc.o -I . +nasal_new_main.o: src/nasal_new_main.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_main.cpp -fno-exceptions -fPIC -o nasal_new_main.o -I . -nasal_new_err.o: ast/nasal_new_err.h ast/nasal_new_err.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_err.cpp -fno-exceptions -fPIC -o nasal_new_err.o -I . +nasal_new_misc.o: src/nasal_new_header.h src/nasal_new_misc.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_misc.cpp -fno-exceptions -fPIC -o nasal_new_misc.o -I . -nasal_new_gc.o: ast/nasal_new_gc.h ast/nasal_new_gc.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_gc.cpp -fno-exceptions -fPIC -o nasal_new_gc.o -I . +nasal_new_err.o: src/nasal_new_err.h src/nasal_new_err.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_err.cpp -fno-exceptions -fPIC -o nasal_new_err.o -I . -nasal_new_import.o: ast/nasal_new_import.h ast/nasal_new_import.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_import.cpp -fno-exceptions -fPIC -o nasal_new_import.o -I . +nasal_new_gc.o: src/nasal_new_gc.h src/nasal_new_gc.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_gc.cpp -fno-exceptions -fPIC -o nasal_new_gc.o -I . -nasal_new_lexer.o: ast/nasal_new_lexer.h ast/nasal_new_lexer.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_lexer.cpp -fno-exceptions -fPIC -o nasal_new_lexer.o -I . +nasal_new_import.o: src/nasal_new_import.h src/nasal_new_import.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_import.cpp -fno-exceptions -fPIC -o nasal_new_import.o -I . -nasal_new_ast.o: ast/nasal_new_ast.h ast/nasal_new_ast.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_ast.cpp -fno-exceptions -fPIC -o nasal_new_ast.o -I . +nasal_new_lexer.o: src/nasal_new_lexer.h src/nasal_new_lexer.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_lexer.cpp -fno-exceptions -fPIC -o nasal_new_lexer.o -I . -nasal_new_builtin.o: ast/nasal_new_builtin.h ast/nasal_new_builtin.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_builtin.cpp -fno-exceptions -fPIC -o nasal_new_builtin.o -I . +nasal_new_ast.o: src/nasal_new_ast.h src/nasal_new_ast.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_ast.cpp -fno-exceptions -fPIC -o nasal_new_ast.o -I . -nasal_new_codegen.o: ast/nasal_new_codegen.h ast/nasal_new_codegen.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_codegen.cpp -fno-exceptions -fPIC -o nasal_new_codegen.o -I . +nasal_new_builtin.o: src/nasal_new_builtin.h src/nasal_new_builtin.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_builtin.cpp -fno-exceptions -fPIC -o nasal_new_builtin.o -I . -nasal_new_opcode.o: ast/nasal_new_opcode.h ast/nasal_new_opcode.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_opcode.cpp -fno-exceptions -fPIC -o nasal_new_opcode.o -I . +nasal_new_codegen.o: src/nasal_new_codegen.h src/nasal_new_codegen.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_codegen.cpp -fno-exceptions -fPIC -o nasal_new_codegen.o -I . -nasal_new_parse.o: ast/nasal_new_parse.h ast/nasal_new_parse.cpp ast/nasal_new_ast.h - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_parse.cpp -fno-exceptions -fPIC -o nasal_new_parse.o -I . +nasal_new_opcode.o: src/nasal_new_opcode.h src/nasal_new_opcode.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_opcode.cpp -fno-exceptions -fPIC -o nasal_new_opcode.o -I . -optimizer.o: ast/optimizer.h ast/optimizer.cpp ast/nasal_new_ast.h - $(CXX) -std=$(STD) -c -O3 ast/optimizer.cpp -fno-exceptions -fPIC -o optimizer.o -I . +nasal_new_parse.o: src/nasal_new_parse.h src/nasal_new_parse.cpp src/nasal_new_ast.h + $(CXX) -std=$(STD) -c -O3 src/nasal_new_parse.cpp -fno-exceptions -fPIC -o nasal_new_parse.o -I . -symbol_finder.o: ast/symbol_finder.h ast/symbol_finder.cpp ast/nasal_new_ast.h - $(CXX) -std=$(STD) -c -O3 ast/symbol_finder.cpp -fno-exceptions -fPIC -o symbol_finder.o -I . +optimizer.o: src/optimizer.h src/optimizer.cpp src/nasal_new_ast.h + $(CXX) -std=$(STD) -c -O3 src/optimizer.cpp -fno-exceptions -fPIC -o optimizer.o -I . -ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp - $(CXX) -std=$(STD) -c -O3 ast/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I . +symbol_finder.o: src/symbol_finder.h src/symbol_finder.cpp src/nasal_new_ast.h + $(CXX) -std=$(STD) -c -O3 src/symbol_finder.cpp -fno-exceptions -fPIC -o symbol_finder.o -I . -ast_dumper.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_dumper.h ast/ast_dumper.cpp - $(CXX) -std=$(STD) -c -O3 ast/ast_dumper.cpp -fno-exceptions -fPIC -o ast_dumper.o -I . +ast_visitor.o: src/nasal_new_ast.h src/ast_visitor.h src/ast_visitor.cpp + $(CXX) -std=$(STD) -c -O3 src/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I . -nasal_new_vm.o: ast/nasal_new_vm.h ast/nasal_new_vm.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_vm.cpp -fno-exceptions -fPIC -o nasal_new_vm.o -I . +ast_dumper.o: src/nasal_new_ast.h src/ast_visitor.h src/ast_dumper.h src/ast_dumper.cpp + $(CXX) -std=$(STD) -c -O3 src/ast_dumper.cpp -fno-exceptions -fPIC -o ast_dumper.o -I . -nasal_new_dbg.o: ast/nasal_new_dbg.h ast/nasal_new_dbg.cpp - $(CXX) -std=$(STD) -c -O3 ast/nasal_new_dbg.cpp -fno-exceptions -fPIC -o nasal_new_dbg.o -I . +nasal_new_vm.o: src/nasal_new_vm.h src/nasal_new_vm.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_vm.cpp -fno-exceptions -fPIC -o nasal_new_vm.o -I . + +nasal_new_dbg.o: src/nasal_new_dbg.h src/nasal_new_dbg.cpp + $(CXX) -std=$(STD) -c -O3 src/nasal_new_dbg.cpp -fno-exceptions -fPIC -o nasal_new_dbg.o -I . .PHONY: nasal_new_clean nasal_new_clean: diff --git a/ast/ast_dumper.cpp b/src/ast_dumper.cpp similarity index 100% rename from ast/ast_dumper.cpp rename to src/ast_dumper.cpp diff --git a/ast/ast_dumper.h b/src/ast_dumper.h similarity index 100% rename from ast/ast_dumper.h rename to src/ast_dumper.h diff --git a/ast/ast_visitor.cpp b/src/ast_visitor.cpp similarity index 100% rename from ast/ast_visitor.cpp rename to src/ast_visitor.cpp diff --git a/ast/ast_visitor.h b/src/ast_visitor.h similarity index 100% rename from ast/ast_visitor.h rename to src/ast_visitor.h diff --git a/ast/nasal_new_ast.cpp b/src/nasal_new_ast.cpp similarity index 100% rename from ast/nasal_new_ast.cpp rename to src/nasal_new_ast.cpp diff --git a/ast/nasal_new_ast.h b/src/nasal_new_ast.h similarity index 100% rename from ast/nasal_new_ast.h rename to src/nasal_new_ast.h diff --git a/ast/nasal_new_builtin.cpp b/src/nasal_new_builtin.cpp similarity index 100% rename from ast/nasal_new_builtin.cpp rename to src/nasal_new_builtin.cpp diff --git a/ast/nasal_new_builtin.h b/src/nasal_new_builtin.h similarity index 100% rename from ast/nasal_new_builtin.h rename to src/nasal_new_builtin.h diff --git a/ast/nasal_new_codegen.cpp b/src/nasal_new_codegen.cpp similarity index 100% rename from ast/nasal_new_codegen.cpp rename to src/nasal_new_codegen.cpp diff --git a/ast/nasal_new_codegen.h b/src/nasal_new_codegen.h similarity index 100% rename from ast/nasal_new_codegen.h rename to src/nasal_new_codegen.h diff --git a/ast/nasal_new_dbg.cpp b/src/nasal_new_dbg.cpp similarity index 100% rename from ast/nasal_new_dbg.cpp rename to src/nasal_new_dbg.cpp diff --git a/ast/nasal_new_dbg.h b/src/nasal_new_dbg.h similarity index 96% rename from ast/nasal_new_dbg.h rename to src/nasal_new_dbg.h index d05bc25..9d0fcdf 100644 --- a/ast/nasal_new_dbg.h +++ b/src/nasal_new_dbg.h @@ -74,6 +74,7 @@ private: void call_sort(const u64*) const; void step_info(); void interact(); + public: dbg(error& err): next(false), fsize(0), diff --git a/ast/nasal_new_err.cpp b/src/nasal_new_err.cpp similarity index 91% rename from ast/nasal_new_err.cpp rename to src/nasal_new_err.cpp index 7cf657d..8e7f7ec 100644 --- a/ast/nasal_new_err.cpp +++ b/src/nasal_new_err.cpp @@ -1,4 +1,13 @@ #include "nasal_new_err.h" +#ifdef _WIN32 +#include // use SetConsoleTextAttribute +struct for_reset { + CONSOLE_SCREEN_BUFFER_INFO scr; + for_reset() { + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr); + } +} reset_ter_color; +#endif std::ostream& back_white(std::ostream& s) { #ifdef _WIN32 diff --git a/ast/nasal_new_err.h b/src/nasal_new_err.h similarity index 85% rename from ast/nasal_new_err.h rename to src/nasal_new_err.h index 192300b..5f73b05 100644 --- a/ast/nasal_new_err.h +++ b/src/nasal_new_err.h @@ -16,16 +16,6 @@ struct span { std::string file; }; -#ifdef _WIN32 -#include // use SetConsoleTextAttribute -struct for_reset { - CONSOLE_SCREEN_BUFFER_INFO scr; - for_reset() { - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr); - } -} reset_ter_color; -#endif - std::ostream& back_white(std::ostream&); std::ostream& red(std::ostream&); std::ostream& cyan(std::ostream&); diff --git a/ast/nasal_new_gc.cpp b/src/nasal_new_gc.cpp similarity index 81% rename from ast/nasal_new_gc.cpp rename to src/nasal_new_gc.cpp index ecd7ab2..8747397 100644 --- a/ast/nasal_new_gc.cpp +++ b/src/nasal_new_gc.cpp @@ -466,57 +466,71 @@ void gc::info() { using std::left; using std::setw; using std::setfill; - const char* name[]={"str ","vec ","hash ","func ","upval","obj ","co "}; - std::clog<<"\ngc info (gc count|alloc count|memory size)\n"; + const char* name[] = { + "string ", + "vector ", + "hashmap ", + "function ", + "upvalue ", + "object ", + "coroutine" + }; - usize ident=0; + usize indent=0; for(u8 i=0;i unused[gc_type_size]; // gc free list /* heap increase size */ - u32 incr[gc_type_size]={ + u32 incr[gc_type_size] = { 128, // vm_str 128, // vm_vec 64, // vm_hash @@ -354,7 +354,10 @@ struct gc { u64 size[gc_type_size]; u64 gcnt[gc_type_size]; u64 acnt[gc_type_size]; - i64 worktime=0; + i64 worktime = 0; + i64 max_time = 0; + i64 max_mark_time = 0; + i64 max_sweep_time = 0; gc(context* _ctx): rctx(_ctx) {} diff --git a/ast/nasal_new_header.h b/src/nasal_new_header.h similarity index 100% rename from ast/nasal_new_header.h rename to src/nasal_new_header.h diff --git a/ast/nasal_new_import.cpp b/src/nasal_new_import.cpp similarity index 100% rename from ast/nasal_new_import.cpp rename to src/nasal_new_import.cpp diff --git a/ast/nasal_new_import.h b/src/nasal_new_import.h similarity index 100% rename from ast/nasal_new_import.h rename to src/nasal_new_import.h diff --git a/ast/nasal_new_lexer.cpp b/src/nasal_new_lexer.cpp similarity index 100% rename from ast/nasal_new_lexer.cpp rename to src/nasal_new_lexer.cpp diff --git a/ast/nasal_new_lexer.h b/src/nasal_new_lexer.h similarity index 100% rename from ast/nasal_new_lexer.h rename to src/nasal_new_lexer.h diff --git a/ast/nasal_new_main.cpp b/src/nasal_new_main.cpp similarity index 81% rename from ast/nasal_new_main.cpp rename to src/nasal_new_main.cpp index 94196ad..d397166 100644 --- a/ast/nasal_new_main.cpp +++ b/src/nasal_new_main.cpp @@ -15,12 +15,13 @@ #include #include -const u32 VM_AST =0x01; -const u32 VM_CODE =0x02; -const u32 VM_TIME =0x04; -const u32 VM_EXEC =0x08; -const u32 VM_DETAIL=0x10; -const u32 VM_DEBUG =0x20; +const u32 VM_RAW_AST = 1; +const u32 VM_AST = 1<<1; +const u32 VM_CODE = 1<<2; +const u32 VM_TIME = 1<<3; +const u32 VM_EXEC = 1<<4; +const u32 VM_DETAIL = 1<<5; +const u32 VM_DEBUG = 1<<6; std::ostream& help(std::ostream& out) { out @@ -32,19 +33,20 @@ std::ostream& help(std::ostream& out) { #endif <<"\nnasal