From 983bf658a65fe1becae6c4a4c69ba5b088b30f2b Mon Sep 17 00:00:00 2001 From: msojocs Date: Sun, 23 Jul 2023 08:50:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/night.h | 35 +++++--- src/night/night.cpp | 3 + src/night/ns_stream.cpp | 48 ++++++++--- src/night/ns_token.cpp | 172 +++++++++++++++++++++++++++++++++++++-- test/wcc.disassembly.cpp | 7 +- 5 files changed, 230 insertions(+), 35 deletions(-) diff --git a/src/include/night.h b/src/include/night.h index c882a02..d1fde72 100644 --- a/src/include/night.h +++ b/src/include/night.h @@ -45,6 +45,11 @@ namespace night extern std::string nst_; extern std::string NS_BUILTIN_SPACE; + extern std::string NS_BUILTIN_PUNC; + extern std::string NS_BUILTIN_OP; + extern std::string NS_BUILTIN_ALL_OP; + extern std::string NS_BUILTIN_TYPE; + extern std::string NS_BUILTIN_KW; int compile_ns(std::string const&,std::string const&,std::string const&,uint,std::string&,bool); void compile_ns_with_sourcemap(std::string const&,std::string const&,std::string const&,std::string const&,uint,std::string&,std::string&); @@ -58,6 +63,8 @@ namespace night public: std::string offset_0; std::string offset_24; + int offset_48; + int offset_52; std::string offset_60; std::string offset_84; std::string offset_108; @@ -97,6 +104,13 @@ namespace night night::ns_node* gen_son(std::string); void hamlet(void); }; + + struct PeekData + { + char data; + int offset_4; + int offset_8; + }; class NSStream { @@ -114,9 +128,9 @@ namespace night bool eof(void); bool eof_2(void); void err(std::string const&,int,int,bool); - char next(void); - char peek(void); - char peek_2(void); + PeekData next(void); + PeekData peek(void); + PeekData peek_2(void); }; class NSToken @@ -128,6 +142,7 @@ namespace night NSStream offset_4; // 不是int night::ns_node* offset_8 = nullptr; std::vector offset_12; + std::map offset_24; NSToken(/* args */); ~NSToken(); @@ -140,18 +155,18 @@ namespace night void push(night::ns_node *); void read_comment_method_1(void); void read_comment_method_2(void); - night::ns_node* read_next(void); - void read_number(std::string const&); + night::ns_node * read_next(void); + night::ns_node * read_number(std::string const&); night::ns_node * read_string(char, std::string const&); - void read_var(std::string const&); + night::ns_node * read_var(std::string const&); std::string read_while(bool (*)(char,void *),void *); - void rw_cb_number(char,void *); + static bool rw_cb_number(char,void *); void skip_comment(std::string &); static bool tk_is_comment2(char,void *); static bool tk_is_not_line_break(char,void *); - bool tk_is_valid_op_str(char,void *); - bool tk_is_var(char,void *); - void tk_is_var_start(char,void *); + static bool tk_is_valid_op_str(char,void *); + static bool tk_is_var(char,void *); + static bool tk_is_var_start(char,void *); static bool tk_is_whitespace(char,void *); }; diff --git a/src/night/night.cpp b/src/night/night.cpp index 1171e20..d7bbf43 100644 --- a/src/night/night.cpp +++ b/src/night/night.cpp @@ -38,6 +38,9 @@ namespace night std::string NS_BUILTIN_ALL_OP = " = ? + - * / % ++ -- + - ~ ! << >> >>> & ^ | < > <= >= == != === !== *= /= %= += -= <<= >>= >>>= &= ^= |= && || "; std::string NS_BUILTIN_PUNC = ".,;(){}[]:"; std::string NS_BUILTIN_SPACE = " \t\r\n"; + std::string NS_BUILTIN_TYPE = " Number Math Date "; + // keywords + std::string NS_BUILTIN_KW = " delete void typeof null undefined NaN Infinity var if else true false require this function arguments return for while do break continue switch case default "; std::string std_v_n = "new std::vector"; std::string std_v_v_n = "new std::vector*>"; diff --git a/src/night/ns_stream.cpp b/src/night/ns_stream.cpp index b952518..44826c4 100644 --- a/src/night/ns_stream.cpp +++ b/src/night/ns_stream.cpp @@ -14,53 +14,70 @@ namespace night { } - char NSStream::peek(void) + PeekData NSStream::peek(void) { + PeekData ret; if (this->offset_48 < this->offset_24.length()) { char v3 = this->offset_24.at(this->offset_48); - return v3; + ret.data = v3; + ret.offset_4 = this->offset_52; + ret.offset_8 = this->offset_56; } else { - return 0; + ret.data = 0; + ret.offset_4 = 0; + ret.offset_8 = 0; } + return ret; } bool NSStream::eof(void) { - return this->peek() == 0; + return this->peek().data == 0; } - char NSStream::peek_2(void) + PeekData NSStream::peek_2(void) { + PeekData ret; if (this->offset_48 + 1 < this->offset_24.length()) { char v3 = this->offset_24.at(this->offset_48 + 1); + int v4 = this->offset_52; + int v5 = this->offset_56 + 1; if (v3 == '\n') { - this->offset_52++; - this->offset_56 = 1; + v4++; + v5 = 1; } - return v3; + ret.data = v3; + ret.offset_4 = v4; + ret.offset_8 = v5; } else { - return 0; + ret.data = 0; + ret.offset_4 = 0; + ret.offset_8 = 0; } + return ret; } bool NSStream::eof_2(void) { - return this->peek_2() == 0; + return this->peek_2().data == 0; } - char NSStream::next(void) + PeekData NSStream::next(void) { + PeekData ret; if (this->offset_48 < this->offset_24.length()) { char v7 = this->offset_24.at(this->offset_48); this->offset_48++; + int v5 = this->offset_52; + int v6 = this->offset_56; if (v7 == 10) // \n { this->offset_56 = 1; @@ -70,12 +87,17 @@ namespace night { this->offset_56++; } - return v7; + ret.data = v7; + ret.offset_4 = v5; + ret.offset_8 = v6; } else { - return 0; + ret.data = 0; + ret.offset_4 = 0; + ret.offset_8 = 0; } + return ret; } void NSStream::err(std::string const& a2, int a3, int a4, bool a5) diff --git a/src/night/ns_token.cpp b/src/night/ns_token.cpp index da517eb..414dd96 100644 --- a/src/night/ns_token.cpp +++ b/src/night/ns_token.cpp @@ -42,8 +42,48 @@ namespace night else { auto v13 = this->offset_4.peek(); - this->read_string(v13, v14); - // TODO... + if (v13.data == '"' || v13.data == '\'') + { + v7 = this->read_string(v13.data, v14); + } + else if (v13.data - '0' > 9) + { + if (!night::NSToken::tk_is_var_start(v13.data, 0)) + { + int pos = night::NS_BUILTIN_PUNC.find(v13.data, 0); + if (pos == -1) + { + int pos2 = night::NS_BUILTIN_OP.find(v13.data, 0); + if (pos2 == -1) + { + std::string msg = "Unexpected token `"; + msg.append(std::string(1, v13.data)); + msg.append("`"); + this->offset_4.err(msg, 0, 0, false); + } + std::string v15; + auto v17 = this->read_while(night::NSToken::tk_is_valid_op_str, (void *)&v15); + auto v7 = this->offset_0.gen_son(night::NS_TYPE_OP); + + } + else + { + auto v7 = this->offset_0.gen_son(night::NS_TYPE_PUNC); + auto v19 = this->offset_4.next(); + std::string v15(1, v19.data); + v7->offset_60 = v15; + } + // goto LABEL_19; + } + else + { + v7 = this->read_var(v14); + } + } + else + { + v7 = this->read_number(v14); + } } return v7; @@ -101,7 +141,7 @@ namespace night break; } auto v5 = this->offset_4.peek(); - if (v5 != '/') + if (v5.data != '/') { break; } @@ -110,7 +150,7 @@ namespace night break; } v5 = this->offset_4.peek_2(); - if (v5 == '/') + if (v5.data == '/') { v5 = this->offset_4.next(); v5 = this->offset_4.next(); @@ -119,7 +159,7 @@ namespace night else { v5 = this->offset_4.peek_2(); - if (v5 == '*') + if (v5.data == '*') return; v5 = this->offset_4.next(); v5 = this->offset_4.next(); @@ -179,26 +219,102 @@ namespace night } + night::ns_node * NSToken::read_number(std::string const& a2) + { + int v8; + auto v9 = this->read_while(night::NSToken::rw_cb_number, &v8); + auto v13 = this->offset_4.peek(); + if (night::NSToken::tk_is_var_start(v13.data, nullptr)) + { + std::string msg = "Unexpected token `"; + msg.append(std::string(1, v13.data)); + msg.append("`"); + this->offset_4.err(msg, 0, 0, false); + } + auto son = this->offset_0.gen_son(night::NS_TYPE_NUM); + son->offset_60 = v9; + son->offset_84 = a2; + return son; + } + std::string NSToken::read_while(bool (*a3)(char,void *), void *a4) { std::string result = ""; while (!this->offset_4.eof()) { auto v6 = this->offset_4.peek(); - if (!a3(v6, a4)) + if (!a3(v6.data, a4)) { break; } v6 = this->offset_4.next(); - result.push_back(v6); + result.push_back(v6.data); } return result; } + night::ns_node *NSToken::read_var(std::string const & a2) + { + auto v12 = this->offset_4.peek(); + auto v13 = this->read_while(night::NSToken::tk_is_var, 0); + std::string v16 = " " + v13 + " "; + int pos = night::NS_BUILTIN_TYPE.find(v16, 0); + night::ns_node *son = nullptr; + if (pos == -1) + { + int v6 = night::NS_BUILTIN_KW.find(v16, 0); + auto v4 = night::NS_TYPE_KW; + if (v6 == -1) + { + v4 = night::NS_TYPE_VAR; + } + son = this->offset_0.gen_son(v4); + if (v6 == -1) + { + v16 = night::nsv_ + v13; + } + else + { + v16 = v13; + } + son->offset_60 = v16; + son->offset_24.assign(v13); + son->offset_84 = a2; + son->offset_48 = v12.offset_4; + son->offset_52 = v12.offset_8; + if (!this->offset_24[v13]) + { + this->offset_24[v13] = this->offset_24.size(); + } + } + else + { + son = this->offset_0.gen_son(night::NS_TYPE_B_TYPE); + son->offset_60 = v13; + son->offset_84 = a2; + } + return son; + } + void NSToken::err(std::string const& a2, int a3, int a4, bool a5) { this->offset_4.err(a2, a3, a4, a5); } + bool NSToken::rw_cb_number(char ch, void *t) + { + int *a2 = (int *)t; + if(ch != '.') + { + return ch - '0' <= 9u; + } + bool result = false; + if (!*a2) + { + *a2 = 1; + return true; + } + return result; + } bool NSToken::tk_is_whitespace(char ch, void *) { @@ -209,20 +325,58 @@ namespace night { return ch != 10; } + bool NSToken::tk_is_valid_op_str(char ch, void *t) + { + std::string * a2 = (std::string *)t; + std::string v6; + v6.assign(*a2); + v6.replace(v6.length(), 0, 1, ch); + bool result = false; + if ( + night::NS_BUILTIN_OP.find(ch, 0) == -1 + || ( + night::NS_BUILTIN_ALL_OP.find(v6, 0) == -1 + ) + ) + { + result = false; + } + else + { + a2->assign(v6); + result = true; + } + return result; + } bool NSToken::tk_is_comment2(char ch, void * t) { night::NSStream *a2 = (night::NSStream *)t; auto v3 = a2->peek(); - if (v3 != '*') + if (v3.data != '*') { return 1; } v3 = a2->peek_2(); - if (v3 != '/') + if (v3.data != '/') { return 1; } a2->next(); return 0; } + bool NSToken::tk_is_var(char ch, void * t) + { + bool result = night::NSToken::tk_is_var_start(ch, t); + if (!result) + { + uint8_t v4 = ch - '0'; + return (ch == '_') | (v4 <= 9u); + } + return result; + } + bool NSToken::tk_is_var_start(char ch, void * t) + { + uint8_t v1 = ch - 'A'; + return (v1 <= 0x19u) | (ch == '_'); + } } \ No newline at end of file diff --git a/test/wcc.disassembly.cpp b/test/wcc.disassembly.cpp index d9c36e4..0e86a78 100644 --- a/test/wcc.disassembly.cpp +++ b/test/wcc.disassembly.cpp @@ -15482,8 +15482,8 @@ _DWORD *__thiscall night::NSStream::next(_DWORD *ecx0, night::NSStream *this) ++*((_DWORD *)this + 14); } *(_BYTE *)ecx0 = v7; - ecx0[2] = v6; ecx0[1] = v5; + ecx0[2] = v6; } else { @@ -16165,6 +16165,7 @@ struct _Unwind_Exception *__thiscall night::NSToken::read_var(int this, int a2) std::operator+((char *)v16, (int)&night::nsv_, (int)v13); else std::string::basic_string((char *)v16, (int)v13); + std::string::operator=((unsigned __int8 **)lpuexcpt + 15, (int)v16); std::string::_M_dispose(v16); std::string::_M_assign((int)lpuexcpt + 24, (int)v13); @@ -16257,7 +16258,7 @@ unsigned __int8 **__fastcall night::NSToken::read_next(int a1) std::string::basic_string(v19, v3); night::NSStream::err(lpuexcptb, (int)v19, 0, 0, 0); } - v15[0] = (int)v16; + v15[0] = (int)v16; // STD::STRING v15[1] = 0; v16[0] = 0; night::NSToken::read_while[abi:cxx11]( @@ -53926,7 +53927,7 @@ bool __cdecl night::NSToken::rw_cb_number(night::NSToken *this, _BYTE *a2) { bool result; // al - if ( (_BYTE)this != 46 ) + if ( (_BYTE)this != '.'/*46*/ ) return (unsigned __int8)((_BYTE)this - 48) <= 9u; result = 0; if ( !*a2 )