Compare commits
27 Commits
dev
...
feature/t6
Author | SHA1 | Date | |
---|---|---|---|
|
30352b21a7 | ||
|
0da3653f26 | ||
|
628749631b | ||
|
18db7e071a | ||
|
15f76542b1 | ||
|
73ed709fed | ||
|
4fec6cda20 | ||
|
66b5c82840 | ||
|
a16c70bd54 | ||
|
328961ee83 | ||
|
8e5cea1af7 | ||
|
4d6d9916bf | ||
|
1a5e39fa0e | ||
|
de254a1293 | ||
|
dcff855efb | ||
|
bbce74f47a | ||
|
2c0a5dce18 | ||
|
89e34cd3a1 | ||
|
7eed6f45f8 | ||
|
5eb63e3284 | ||
|
05fc8a7421 | ||
|
ec91109cc3 | ||
|
0ec0b4d6f5 | ||
|
6a0419b5bf | ||
|
f53fb4fe47 | ||
|
b6777295a1 | ||
|
b1ad170030 |
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -149,6 +149,11 @@ user*.bat
|
||||
# VScode
|
||||
.vscode/
|
||||
|
||||
compiled/
|
||||
decompiled/
|
||||
assembled/
|
||||
disassembled/
|
||||
|
||||
data/iw5/
|
||||
data/iw6/
|
||||
data/iw7/
|
||||
|
14
README.md
14
README.md
@ -2,8 +2,10 @@
|
||||
![license](https://img.shields.io/github/license/xensik/gsc-tool.svg)
|
||||
[![GitHub issues](https://img.shields.io/github/issues/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/issues)
|
||||
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/releases)
|
||||
|
||||
# GSC Tool
|
||||
A utility to compile & decompile IW engine game scripts.
|
||||
|
||||
## Supported Games
|
||||
- **IW5** *(Call of Duty: Modern Warfare 3)*
|
||||
- **IW6** *(Call of Duty: Ghosts)*
|
||||
@ -18,6 +20,7 @@ A utility to compile & decompile IW engine game scripts.
|
||||
- **T5** *(Call of Duty: Black Ops)* ***\*WIP\****
|
||||
- **T6** *(Call of Duty: Black Ops II)*
|
||||
- **T7** *(Call of Duty: Black Ops III)* ***\*WIP\****
|
||||
|
||||
## Usage
|
||||
``./gsc-tool.exe <mode> <game> <path>``
|
||||
|
||||
@ -29,6 +32,8 @@ A utility to compile & decompile IW engine game scripts.
|
||||
|
||||
for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zdecomp` modes
|
||||
|
||||
Example: ``./gsc-tool.exe comp iw5 ./data/iw5/my_fancy_script.gsc``
|
||||
|
||||
| Mode |Description | Output |
|
||||
|:---------|:--------------------------|:------------|
|
||||
|`asm` |assemble a `file.gscasm` |`file.gscbin`|
|
||||
@ -39,7 +44,13 @@ for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zd
|
||||
## File Format
|
||||
If you need to extract scripts from fastfiles or game memory, use [Zonetool](https://github.com/ZoneTool/zonetool) or [Jekyll](https://github.com/EthanC/Jekyll).
|
||||
|
||||
- gsc-tool ``.gscbin`` format is a serialized ScriptFile struct: ***name***: null-term string, ***compressedLen***: 4 byte uint, ***len***: 4 byte uint, ***bytecodeLen***: 4 byte uint, ***buffer***: byte array[compressedLen], ***bytecode***: byte array[bytecodeLen].
|
||||
- gsc-tool ``.gscbin`` format is a serialized ScriptFile struct: <br/>
|
||||
***name***: null-terminated string <br/>
|
||||
***compressedLen***: 4 byte uint <br/>
|
||||
***len***: 4 byte uint <br/>
|
||||
***bytecodeLen***: 4 byte uint <br/>
|
||||
***buffer***: byte array[compressedLen] <br/>
|
||||
***bytecode***: byte array[bytecodeLen] <br/>
|
||||
|
||||
- zonetool (IW5) format made of bytecode file ``.cgsc`` and decompressed stack buffer ``.cgsc.stack``.
|
||||
|
||||
@ -47,5 +58,6 @@ If you need to extract scripts from fastfiles or game memory, use [Zonetool](htt
|
||||
|
||||
## Credits
|
||||
This project is based on [*RektInator's* gsc-asm](https://github.com/ZoneTool/gsc-asm). Special thanks to **RektInator**, **JTAG** & **Dasfonia**.
|
||||
|
||||
## Disclaimer
|
||||
This software has been created purely for the purposes of academic research. Project maintainers are not responsible or liable for misuse of the software. Use responsibly.
|
||||
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
||||
Subproject commit 53ce2713117ef2a8ed682d77b944df991c499252
|
||||
Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389
|
@ -190,6 +190,7 @@ xsk::gsc::h1::parser::symbol_type H1lex(xsk::gsc::h1::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -611,6 +612,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -644,6 +646,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -190,6 +190,7 @@ xsk::gsc::h2::parser::symbol_type H2lex(xsk::gsc::h2::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -611,6 +612,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -644,6 +646,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -188,6 +188,7 @@ xsk::gsc::iw5::parser::symbol_type IW5lex(xsk::gsc::iw5::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -601,6 +602,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -634,6 +636,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -188,6 +188,7 @@ xsk::gsc::iw6::parser::symbol_type IW6lex(xsk::gsc::iw6::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -601,6 +602,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -634,6 +636,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -188,6 +188,7 @@ xsk::gsc::iw7::parser::symbol_type IW7lex(xsk::gsc::iw7::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -601,6 +602,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -634,6 +636,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -192,6 +192,7 @@ xsk::gsc::iw8::parser::symbol_type IW8lex(xsk::gsc::iw8::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -615,6 +616,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -650,6 +652,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -190,6 +190,7 @@ xsk::gsc::s1::parser::symbol_type S1lex(xsk::gsc::s1::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -611,6 +612,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -644,6 +646,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -190,6 +190,7 @@ xsk::gsc::s2::parser::symbol_type S2lex(xsk::gsc::s2::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -611,6 +612,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -644,6 +646,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -192,6 +192,7 @@ xsk::gsc::s4::parser::symbol_type S4lex(xsk::gsc::s4::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -615,6 +616,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -650,6 +652,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -202,6 +202,7 @@ xsk::arc::t6::parser::symbol_type T6lex(xsk::arc::t6::lexer& lexer);
|
||||
%type <ast::expr> expr_binary
|
||||
%type <ast::expr> expr_primitive
|
||||
%type <ast::expr_complement::ptr> expr_complement
|
||||
%type <ast::expr_negate::ptr> expr_negate
|
||||
%type <ast::expr_not::ptr> expr_not
|
||||
%type <ast::expr_call::ptr> expr_call
|
||||
%type <ast::expr_method::ptr> expr_method
|
||||
@ -625,6 +626,7 @@ expr_binary
|
||||
|
||||
expr_primitive
|
||||
: expr_complement { $$.as_node = std::move($1); }
|
||||
| expr_negate { $$.as_node = std::move($1); }
|
||||
| expr_not { $$.as_node = std::move($1); }
|
||||
| expr_call { $$.as_node = std::move($1); }
|
||||
| expr_method { $$.as_node = std::move($1); }
|
||||
@ -675,6 +677,17 @@ expr_complement
|
||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
||||
;
|
||||
|
||||
expr_negate
|
||||
: SUB expr_identifier %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_paren %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_array %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
| SUB expr_field %prec NEG
|
||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
||||
;
|
||||
|
||||
expr_not
|
||||
: NOT expr
|
||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
||||
|
@ -429,7 +429,7 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[2])));
|
||||
}
|
||||
|
||||
const auto file_id = resolver::file_id(inst->data[0]);
|
||||
const auto file_id = resolver::token_id(inst->data[0]);
|
||||
const auto func_id = resolver::token_id(inst->data[1]);
|
||||
|
||||
stack_->write<std::uint16_t>(file_id);
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1796,17 +1792,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1866,28 +1877,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1946,6 +2007,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2158,7 +2284,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2168,7 +2294,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2413,7 +2539,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3033,17 +3166,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3272,18 +3408,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
@ -338,7 +338,7 @@ void disassembler::disassemble_far_call(const instruction::ptr& inst, bool threa
|
||||
}
|
||||
|
||||
const auto file_id = stack_->read<std::uint16_t>();
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::file_name(file_id);
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::token_name(file_id);
|
||||
const auto func_id = stack_->read<std::uint16_t>();
|
||||
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace h1 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy62[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace h1 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy67[sizeof (std::string)];
|
||||
char dummy68[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -983,40 +986,41 @@ namespace xsk { namespace gsc { namespace h1 {
|
||||
S_expr_binary = 159, // expr_binary
|
||||
S_expr_primitive = 160, // expr_primitive
|
||||
S_expr_complement = 161, // expr_complement
|
||||
S_expr_not = 162, // expr_not
|
||||
S_expr_call = 163, // expr_call
|
||||
S_expr_method = 164, // expr_method
|
||||
S_expr_function = 165, // expr_function
|
||||
S_expr_pointer = 166, // expr_pointer
|
||||
S_expr_add_array = 167, // expr_add_array
|
||||
S_expr_parameters = 168, // expr_parameters
|
||||
S_expr_arguments = 169, // expr_arguments
|
||||
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty
|
||||
S_expr_reference = 171, // expr_reference
|
||||
S_expr_array = 172, // expr_array
|
||||
S_expr_field = 173, // expr_field
|
||||
S_expr_size = 174, // expr_size
|
||||
S_expr_paren = 175, // expr_paren
|
||||
S_expr_object = 176, // expr_object
|
||||
S_expr_thisthread = 177, // expr_thisthread
|
||||
S_expr_empty_array = 178, // expr_empty_array
|
||||
S_expr_undefined = 179, // expr_undefined
|
||||
S_expr_game = 180, // expr_game
|
||||
S_expr_self = 181, // expr_self
|
||||
S_expr_anim = 182, // expr_anim
|
||||
S_expr_level = 183, // expr_level
|
||||
S_expr_animation = 184, // expr_animation
|
||||
S_expr_animtree = 185, // expr_animtree
|
||||
S_expr_identifier_nosize = 186, // expr_identifier_nosize
|
||||
S_expr_identifier = 187, // expr_identifier
|
||||
S_expr_path = 188, // expr_path
|
||||
S_expr_istring = 189, // expr_istring
|
||||
S_expr_string = 190, // expr_string
|
||||
S_expr_vector = 191, // expr_vector
|
||||
S_expr_float = 192, // expr_float
|
||||
S_expr_integer = 193, // expr_integer
|
||||
S_expr_false = 194, // expr_false
|
||||
S_expr_true = 195 // expr_true
|
||||
S_expr_negate = 162, // expr_negate
|
||||
S_expr_not = 163, // expr_not
|
||||
S_expr_call = 164, // expr_call
|
||||
S_expr_method = 165, // expr_method
|
||||
S_expr_function = 166, // expr_function
|
||||
S_expr_pointer = 167, // expr_pointer
|
||||
S_expr_add_array = 168, // expr_add_array
|
||||
S_expr_parameters = 169, // expr_parameters
|
||||
S_expr_arguments = 170, // expr_arguments
|
||||
S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
|
||||
S_expr_reference = 172, // expr_reference
|
||||
S_expr_array = 173, // expr_array
|
||||
S_expr_field = 174, // expr_field
|
||||
S_expr_size = 175, // expr_size
|
||||
S_expr_paren = 176, // expr_paren
|
||||
S_expr_object = 177, // expr_object
|
||||
S_expr_thisthread = 178, // expr_thisthread
|
||||
S_expr_empty_array = 179, // expr_empty_array
|
||||
S_expr_undefined = 180, // expr_undefined
|
||||
S_expr_game = 181, // expr_game
|
||||
S_expr_self = 182, // expr_self
|
||||
S_expr_anim = 183, // expr_anim
|
||||
S_expr_level = 184, // expr_level
|
||||
S_expr_animation = 185, // expr_animation
|
||||
S_expr_animtree = 186, // expr_animtree
|
||||
S_expr_identifier_nosize = 187, // expr_identifier_nosize
|
||||
S_expr_identifier = 188, // expr_identifier
|
||||
S_expr_path = 189, // expr_path
|
||||
S_expr_istring = 190, // expr_istring
|
||||
S_expr_string = 191, // expr_string
|
||||
S_expr_vector = 192, // expr_vector
|
||||
S_expr_float = 193, // expr_float
|
||||
S_expr_integer = 194, // expr_integer
|
||||
S_expr_false = 195, // expr_false
|
||||
S_expr_true = 196 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1160,6 +1164,10 @@ namespace xsk { namespace gsc { namespace h1 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace h1 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2432,6 +2454,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4813,8 +4839,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2251, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2419, ///< Last index in yytable_.
|
||||
yynnts_ = 84, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4948,6 +4974,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5266,6 +5296,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5513,7 +5547,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::h1
|
||||
#line 5517 "parser.hpp"
|
||||
#line 5551 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,9 +23,6 @@ public:
|
||||
static auto method_id(const std::string& name) -> std::uint16_t;
|
||||
static auto method_name(std::uint16_t id) -> std::string;
|
||||
|
||||
static auto file_id(const std::string& name) -> std::uint16_t;
|
||||
static auto file_name(std::uint16_t id) -> std::string;
|
||||
|
||||
static auto token_id(const std::string& name) -> std::uint16_t;
|
||||
static auto token_name(std::uint16_t id) -> std::string;
|
||||
|
||||
|
@ -429,7 +429,7 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[2])));
|
||||
}
|
||||
|
||||
const auto file_id = resolver::file_id(inst->data[0]);
|
||||
const auto file_id = resolver::token_id(inst->data[0]);
|
||||
const auto func_id = resolver::token_id(inst->data[1]);
|
||||
|
||||
stack_->write<std::uint16_t>(file_id);
|
||||
@ -536,7 +536,7 @@ void assembler::assemble_offset(std::int32_t offset)
|
||||
{
|
||||
std::array<std::uint8_t, 4> bytes = {};
|
||||
|
||||
offset = (offset << 10) >> 8;
|
||||
offset = (offset << 8) >> 8;
|
||||
|
||||
*reinterpret_cast<std::int32_t*>(bytes.data()) = offset;
|
||||
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1796,17 +1792,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1866,28 +1877,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1946,6 +2007,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2158,7 +2284,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2168,7 +2294,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2413,7 +2539,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3033,17 +3166,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3272,18 +3408,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
@ -338,7 +338,7 @@ void disassembler::disassemble_far_call(const instruction::ptr& inst, bool threa
|
||||
}
|
||||
|
||||
const auto file_id = stack_->read<std::uint16_t>();
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::file_name(file_id);
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::token_name(file_id);
|
||||
const auto func_id = stack_->read<std::uint16_t>();
|
||||
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id);
|
||||
|
||||
@ -450,7 +450,7 @@ auto disassembler::disassemble_offset() -> std::int32_t
|
||||
|
||||
auto offset = *reinterpret_cast<std::int32_t*>(bytes.data());
|
||||
|
||||
offset = (offset << 8) >> 10;
|
||||
offset = (offset << 8) >> 8;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace h2 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy62[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace h2 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy67[sizeof (std::string)];
|
||||
char dummy68[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -983,40 +986,41 @@ namespace xsk { namespace gsc { namespace h2 {
|
||||
S_expr_binary = 159, // expr_binary
|
||||
S_expr_primitive = 160, // expr_primitive
|
||||
S_expr_complement = 161, // expr_complement
|
||||
S_expr_not = 162, // expr_not
|
||||
S_expr_call = 163, // expr_call
|
||||
S_expr_method = 164, // expr_method
|
||||
S_expr_function = 165, // expr_function
|
||||
S_expr_pointer = 166, // expr_pointer
|
||||
S_expr_add_array = 167, // expr_add_array
|
||||
S_expr_parameters = 168, // expr_parameters
|
||||
S_expr_arguments = 169, // expr_arguments
|
||||
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty
|
||||
S_expr_reference = 171, // expr_reference
|
||||
S_expr_array = 172, // expr_array
|
||||
S_expr_field = 173, // expr_field
|
||||
S_expr_size = 174, // expr_size
|
||||
S_expr_paren = 175, // expr_paren
|
||||
S_expr_object = 176, // expr_object
|
||||
S_expr_thisthread = 177, // expr_thisthread
|
||||
S_expr_empty_array = 178, // expr_empty_array
|
||||
S_expr_undefined = 179, // expr_undefined
|
||||
S_expr_game = 180, // expr_game
|
||||
S_expr_self = 181, // expr_self
|
||||
S_expr_anim = 182, // expr_anim
|
||||
S_expr_level = 183, // expr_level
|
||||
S_expr_animation = 184, // expr_animation
|
||||
S_expr_animtree = 185, // expr_animtree
|
||||
S_expr_identifier_nosize = 186, // expr_identifier_nosize
|
||||
S_expr_identifier = 187, // expr_identifier
|
||||
S_expr_path = 188, // expr_path
|
||||
S_expr_istring = 189, // expr_istring
|
||||
S_expr_string = 190, // expr_string
|
||||
S_expr_vector = 191, // expr_vector
|
||||
S_expr_float = 192, // expr_float
|
||||
S_expr_integer = 193, // expr_integer
|
||||
S_expr_false = 194, // expr_false
|
||||
S_expr_true = 195 // expr_true
|
||||
S_expr_negate = 162, // expr_negate
|
||||
S_expr_not = 163, // expr_not
|
||||
S_expr_call = 164, // expr_call
|
||||
S_expr_method = 165, // expr_method
|
||||
S_expr_function = 166, // expr_function
|
||||
S_expr_pointer = 167, // expr_pointer
|
||||
S_expr_add_array = 168, // expr_add_array
|
||||
S_expr_parameters = 169, // expr_parameters
|
||||
S_expr_arguments = 170, // expr_arguments
|
||||
S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
|
||||
S_expr_reference = 172, // expr_reference
|
||||
S_expr_array = 173, // expr_array
|
||||
S_expr_field = 174, // expr_field
|
||||
S_expr_size = 175, // expr_size
|
||||
S_expr_paren = 176, // expr_paren
|
||||
S_expr_object = 177, // expr_object
|
||||
S_expr_thisthread = 178, // expr_thisthread
|
||||
S_expr_empty_array = 179, // expr_empty_array
|
||||
S_expr_undefined = 180, // expr_undefined
|
||||
S_expr_game = 181, // expr_game
|
||||
S_expr_self = 182, // expr_self
|
||||
S_expr_anim = 183, // expr_anim
|
||||
S_expr_level = 184, // expr_level
|
||||
S_expr_animation = 185, // expr_animation
|
||||
S_expr_animtree = 186, // expr_animtree
|
||||
S_expr_identifier_nosize = 187, // expr_identifier_nosize
|
||||
S_expr_identifier = 188, // expr_identifier
|
||||
S_expr_path = 189, // expr_path
|
||||
S_expr_istring = 190, // expr_istring
|
||||
S_expr_string = 191, // expr_string
|
||||
S_expr_vector = 192, // expr_vector
|
||||
S_expr_float = 193, // expr_float
|
||||
S_expr_integer = 194, // expr_integer
|
||||
S_expr_false = 195, // expr_false
|
||||
S_expr_true = 196 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1160,6 +1164,10 @@ namespace xsk { namespace gsc { namespace h2 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace h2 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2432,6 +2454,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4813,8 +4839,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2251, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2419, ///< Last index in yytable_.
|
||||
yynnts_ = 84, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4948,6 +4974,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5266,6 +5296,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5513,7 +5547,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::h2
|
||||
#line 5517 "parser.hpp"
|
||||
#line 5551 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -17,12 +17,10 @@ namespace xsk::gsc::h2
|
||||
std::unordered_map<std::uint8_t, std::string_view> opcode_map;
|
||||
std::unordered_map<std::uint16_t, std::string_view> function_map;
|
||||
std::unordered_map<std::uint16_t, std::string_view> method_map;
|
||||
std::unordered_map<std::uint16_t, std::string_view> file_map;
|
||||
std::unordered_map<std::uint16_t, std::string_view> token_map;
|
||||
std::unordered_map<std::string_view, std::uint8_t> opcode_map_rev;
|
||||
std::unordered_map<std::string_view, std::uint16_t> function_map_rev;
|
||||
std::unordered_map<std::string_view, std::uint16_t> method_map_rev;
|
||||
std::unordered_map<std::string_view, std::uint16_t> file_map_rev;
|
||||
std::unordered_map<std::string_view, std::uint16_t> token_map_rev;
|
||||
std::unordered_map<std::string, std::vector<std::uint8_t>> files;
|
||||
read_cb_type read_callback = nullptr;
|
||||
@ -120,35 +118,6 @@ auto resolver::method_name(std::uint16_t id) -> std::string
|
||||
return utils::string::va("_meth_%04X", id);
|
||||
}
|
||||
|
||||
auto resolver::file_id(const std::string& name) -> std::uint16_t
|
||||
{
|
||||
if (name.starts_with("_id_"))
|
||||
{
|
||||
return static_cast<std::uint16_t>(std::stoul(name.substr(4), nullptr, 16));
|
||||
}
|
||||
|
||||
const auto itr = file_map_rev.find(name);
|
||||
|
||||
if (itr != file_map_rev.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto resolver::file_name(std::uint16_t id) -> std::string
|
||||
{
|
||||
const auto itr = file_map.find(id);
|
||||
|
||||
if (itr != file_map.end())
|
||||
{
|
||||
return std::string(itr->second);
|
||||
}
|
||||
|
||||
return utils::string::va("_id_%04X", id);
|
||||
}
|
||||
|
||||
auto resolver::token_id(const std::string& name) -> std::uint16_t
|
||||
{
|
||||
if (name.starts_with("_id_"))
|
||||
@ -476,7 +445,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 800> function_list
|
||||
{ 0x02C, "_func_02C" },
|
||||
{ 0x02D, "_func_02D" },
|
||||
{ 0x02E, "_func_02E" },
|
||||
{ 0x02F, "_func_02F" },
|
||||
{ 0x02F, "isdefined" },
|
||||
{ 0x030, "_func_030" },
|
||||
{ 0x031, "_func_031" },
|
||||
{ 0x032, "_func_032" },
|
||||
@ -876,7 +845,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 800> function_list
|
||||
{ 0x1BC, "_func_1BC" },
|
||||
{ 0x1BD, "_func_1BD" },
|
||||
{ 0x1BE, "_func_1BE" },
|
||||
{ 0x1BF, "_func_1BF" },
|
||||
{ 0x1BF, "getnextarraykey" },
|
||||
{ 0x1C0, "_func_1C0" },
|
||||
{ 0x1C1, "_func_1C1" },
|
||||
{ 0x1C2, "_func_1C2" },
|
||||
@ -903,7 +872,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 800> function_list
|
||||
{ 0x1D7, "_func_1D7" },
|
||||
{ 0x1D8, "_func_1D8" },
|
||||
{ 0x1D9, "_func_1D9" },
|
||||
{ 0x1DA, "_func_1DA" },
|
||||
{ 0x1DA, "getfirstarraykey" },
|
||||
{ 0x1DB, "_func_1DB" },
|
||||
{ 0x1DC, "_func_1DC" },
|
||||
{ 0x1DD, "_func_1DD" },
|
||||
@ -2727,11 +2696,6 @@ const std::array<std::pair<std::uint16_t, const char*>, 1491> method_list
|
||||
{ 0x85D2, "_meth_85D2" },
|
||||
}};
|
||||
|
||||
const std::array<std::pair<std::uint16_t, const char*>, 1> file_list
|
||||
{{
|
||||
{ 0, "null" },
|
||||
}};
|
||||
|
||||
const std::array<std::pair<std::uint16_t, const char*>, 5> token_list
|
||||
{{
|
||||
{ 0x0000, "" },
|
||||
@ -2755,8 +2719,6 @@ struct __init__
|
||||
function_map_rev.reserve(function_list.size());
|
||||
method_map.reserve(method_list.size());
|
||||
method_map_rev.reserve(method_list.size());
|
||||
file_map.reserve(file_list.size());
|
||||
file_map_rev.reserve(file_list.size());
|
||||
token_map.reserve(token_list.size());
|
||||
token_map_rev.reserve(token_list.size());
|
||||
|
||||
@ -2778,12 +2740,6 @@ struct __init__
|
||||
method_map_rev.insert({ entry.second, entry.first });
|
||||
}
|
||||
|
||||
for (const auto& entry : file_list)
|
||||
{
|
||||
file_map.insert({ entry.first, entry.second });
|
||||
file_map_rev.insert({ entry.second, entry.first });
|
||||
}
|
||||
|
||||
for (const auto& entry : token_list)
|
||||
{
|
||||
token_map.insert({ entry.first, entry.second });
|
||||
|
@ -129,7 +129,6 @@ void assembler::assemble(const std::string& file, std::vector<function::ptr>& fu
|
||||
functions_ = std::move(funcs);
|
||||
|
||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(opcode::OP_End));
|
||||
stack_->write<std::uint32_t>(0x62727568);
|
||||
|
||||
for (const auto& func : functions_)
|
||||
{
|
||||
@ -428,7 +427,7 @@ void assembler::assemble_far_call(const instruction::ptr& inst, bool thread)
|
||||
script_->write<std::uint8_t>(static_cast<std::uint8_t>(std::stoi(inst->data[2])));
|
||||
}
|
||||
|
||||
const auto file_id = resolver::file_id(inst->data[0]);
|
||||
const auto file_id = resolver::token_id(inst->data[0]);
|
||||
const auto func_id = resolver::token_id(inst->data[1]);
|
||||
|
||||
stack_->write<std::uint16_t>(file_id);
|
||||
|
@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -82,6 +82,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1272,7 +1265,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1332,7 +1325,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1790,17 +1786,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1860,28 +1871,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1940,6 +2001,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2152,17 +2278,17 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
// continue is at jumpback, not post-expr
|
||||
// jump is referenced, not post-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2407,7 +2533,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3027,17 +3160,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3266,18 +3402,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
@ -337,7 +337,7 @@ void disassembler::disassemble_far_call(const instruction::ptr& inst, bool threa
|
||||
}
|
||||
|
||||
const auto file_id = stack_->read<std::uint16_t>();
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::file_name(file_id);
|
||||
const auto file_name = file_id == 0 ? stack_->read_c_string() : resolver::token_name(file_id);
|
||||
const auto func_id = stack_->read<std::uint16_t>();
|
||||
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw5 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy62[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy65[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw5 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy66[sizeof (std::string)];
|
||||
char dummy67[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -977,40 +980,41 @@ namespace xsk { namespace gsc { namespace iw5 {
|
||||
S_expr_binary = 157, // expr_binary
|
||||
S_expr_primitive = 158, // expr_primitive
|
||||
S_expr_complement = 159, // expr_complement
|
||||
S_expr_not = 160, // expr_not
|
||||
S_expr_call = 161, // expr_call
|
||||
S_expr_method = 162, // expr_method
|
||||
S_expr_function = 163, // expr_function
|
||||
S_expr_pointer = 164, // expr_pointer
|
||||
S_expr_add_array = 165, // expr_add_array
|
||||
S_expr_parameters = 166, // expr_parameters
|
||||
S_expr_arguments = 167, // expr_arguments
|
||||
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty
|
||||
S_expr_reference = 169, // expr_reference
|
||||
S_expr_array = 170, // expr_array
|
||||
S_expr_field = 171, // expr_field
|
||||
S_expr_size = 172, // expr_size
|
||||
S_expr_paren = 173, // expr_paren
|
||||
S_expr_object = 174, // expr_object
|
||||
S_expr_thisthread = 175, // expr_thisthread
|
||||
S_expr_empty_array = 176, // expr_empty_array
|
||||
S_expr_undefined = 177, // expr_undefined
|
||||
S_expr_game = 178, // expr_game
|
||||
S_expr_self = 179, // expr_self
|
||||
S_expr_anim = 180, // expr_anim
|
||||
S_expr_level = 181, // expr_level
|
||||
S_expr_animation = 182, // expr_animation
|
||||
S_expr_animtree = 183, // expr_animtree
|
||||
S_expr_identifier_nosize = 184, // expr_identifier_nosize
|
||||
S_expr_identifier = 185, // expr_identifier
|
||||
S_expr_path = 186, // expr_path
|
||||
S_expr_istring = 187, // expr_istring
|
||||
S_expr_string = 188, // expr_string
|
||||
S_expr_vector = 189, // expr_vector
|
||||
S_expr_float = 190, // expr_float
|
||||
S_expr_integer = 191, // expr_integer
|
||||
S_expr_false = 192, // expr_false
|
||||
S_expr_true = 193 // expr_true
|
||||
S_expr_negate = 160, // expr_negate
|
||||
S_expr_not = 161, // expr_not
|
||||
S_expr_call = 162, // expr_call
|
||||
S_expr_method = 163, // expr_method
|
||||
S_expr_function = 164, // expr_function
|
||||
S_expr_pointer = 165, // expr_pointer
|
||||
S_expr_add_array = 166, // expr_add_array
|
||||
S_expr_parameters = 167, // expr_parameters
|
||||
S_expr_arguments = 168, // expr_arguments
|
||||
S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
|
||||
S_expr_reference = 170, // expr_reference
|
||||
S_expr_array = 171, // expr_array
|
||||
S_expr_field = 172, // expr_field
|
||||
S_expr_size = 173, // expr_size
|
||||
S_expr_paren = 174, // expr_paren
|
||||
S_expr_object = 175, // expr_object
|
||||
S_expr_thisthread = 176, // expr_thisthread
|
||||
S_expr_empty_array = 177, // expr_empty_array
|
||||
S_expr_undefined = 178, // expr_undefined
|
||||
S_expr_game = 179, // expr_game
|
||||
S_expr_self = 180, // expr_self
|
||||
S_expr_anim = 181, // expr_anim
|
||||
S_expr_level = 182, // expr_level
|
||||
S_expr_animation = 183, // expr_animation
|
||||
S_expr_animtree = 184, // expr_animtree
|
||||
S_expr_identifier_nosize = 185, // expr_identifier_nosize
|
||||
S_expr_identifier = 186, // expr_identifier
|
||||
S_expr_path = 187, // expr_path
|
||||
S_expr_istring = 188, // expr_istring
|
||||
S_expr_string = 189, // expr_string
|
||||
S_expr_vector = 190, // expr_vector
|
||||
S_expr_float = 191, // expr_float
|
||||
S_expr_integer = 192, // expr_integer
|
||||
S_expr_false = 193, // expr_false
|
||||
S_expr_true = 194 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1154,6 +1158,10 @@ namespace xsk { namespace gsc { namespace iw5 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw5 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2408,6 +2430,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4770,8 +4796,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2303, ///< Last index in yytable_.
|
||||
yynnts_ = 82, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2363, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4905,6 +4931,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5219,6 +5249,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5462,7 +5496,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::iw5
|
||||
#line 5466 "parser.hpp"
|
||||
#line 5500 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
39658
src/iw5/xsk/resolver.cpp
39658
src/iw5/xsk/resolver.cpp
File diff suppressed because it is too large
Load Diff
@ -23,9 +23,6 @@ public:
|
||||
static auto method_id(const std::string& name) -> std::uint16_t;
|
||||
static auto method_name(std::uint16_t id) -> std::string;
|
||||
|
||||
static auto file_id(const std::string& name) -> std::uint16_t;
|
||||
static auto file_name(std::uint16_t id) -> std::string;
|
||||
|
||||
static auto token_id(const std::string& name) -> std::uint16_t;
|
||||
static auto token_name(std::uint16_t id) -> std::string;
|
||||
|
||||
|
@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -82,6 +82,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1272,7 +1265,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1332,7 +1325,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1790,17 +1786,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1860,28 +1871,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1940,6 +2001,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2152,7 +2278,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2162,7 +2288,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2407,7 +2533,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3027,17 +3160,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3266,18 +3402,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw6 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy62[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy65[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw6 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy66[sizeof (std::string)];
|
||||
char dummy67[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -977,40 +980,41 @@ namespace xsk { namespace gsc { namespace iw6 {
|
||||
S_expr_binary = 157, // expr_binary
|
||||
S_expr_primitive = 158, // expr_primitive
|
||||
S_expr_complement = 159, // expr_complement
|
||||
S_expr_not = 160, // expr_not
|
||||
S_expr_call = 161, // expr_call
|
||||
S_expr_method = 162, // expr_method
|
||||
S_expr_function = 163, // expr_function
|
||||
S_expr_pointer = 164, // expr_pointer
|
||||
S_expr_add_array = 165, // expr_add_array
|
||||
S_expr_parameters = 166, // expr_parameters
|
||||
S_expr_arguments = 167, // expr_arguments
|
||||
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty
|
||||
S_expr_reference = 169, // expr_reference
|
||||
S_expr_array = 170, // expr_array
|
||||
S_expr_field = 171, // expr_field
|
||||
S_expr_size = 172, // expr_size
|
||||
S_expr_paren = 173, // expr_paren
|
||||
S_expr_object = 174, // expr_object
|
||||
S_expr_thisthread = 175, // expr_thisthread
|
||||
S_expr_empty_array = 176, // expr_empty_array
|
||||
S_expr_undefined = 177, // expr_undefined
|
||||
S_expr_game = 178, // expr_game
|
||||
S_expr_self = 179, // expr_self
|
||||
S_expr_anim = 180, // expr_anim
|
||||
S_expr_level = 181, // expr_level
|
||||
S_expr_animation = 182, // expr_animation
|
||||
S_expr_animtree = 183, // expr_animtree
|
||||
S_expr_identifier_nosize = 184, // expr_identifier_nosize
|
||||
S_expr_identifier = 185, // expr_identifier
|
||||
S_expr_path = 186, // expr_path
|
||||
S_expr_istring = 187, // expr_istring
|
||||
S_expr_string = 188, // expr_string
|
||||
S_expr_vector = 189, // expr_vector
|
||||
S_expr_float = 190, // expr_float
|
||||
S_expr_integer = 191, // expr_integer
|
||||
S_expr_false = 192, // expr_false
|
||||
S_expr_true = 193 // expr_true
|
||||
S_expr_negate = 160, // expr_negate
|
||||
S_expr_not = 161, // expr_not
|
||||
S_expr_call = 162, // expr_call
|
||||
S_expr_method = 163, // expr_method
|
||||
S_expr_function = 164, // expr_function
|
||||
S_expr_pointer = 165, // expr_pointer
|
||||
S_expr_add_array = 166, // expr_add_array
|
||||
S_expr_parameters = 167, // expr_parameters
|
||||
S_expr_arguments = 168, // expr_arguments
|
||||
S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
|
||||
S_expr_reference = 170, // expr_reference
|
||||
S_expr_array = 171, // expr_array
|
||||
S_expr_field = 172, // expr_field
|
||||
S_expr_size = 173, // expr_size
|
||||
S_expr_paren = 174, // expr_paren
|
||||
S_expr_object = 175, // expr_object
|
||||
S_expr_thisthread = 176, // expr_thisthread
|
||||
S_expr_empty_array = 177, // expr_empty_array
|
||||
S_expr_undefined = 178, // expr_undefined
|
||||
S_expr_game = 179, // expr_game
|
||||
S_expr_self = 180, // expr_self
|
||||
S_expr_anim = 181, // expr_anim
|
||||
S_expr_level = 182, // expr_level
|
||||
S_expr_animation = 183, // expr_animation
|
||||
S_expr_animtree = 184, // expr_animtree
|
||||
S_expr_identifier_nosize = 185, // expr_identifier_nosize
|
||||
S_expr_identifier = 186, // expr_identifier
|
||||
S_expr_path = 187, // expr_path
|
||||
S_expr_istring = 188, // expr_istring
|
||||
S_expr_string = 189, // expr_string
|
||||
S_expr_vector = 190, // expr_vector
|
||||
S_expr_float = 191, // expr_float
|
||||
S_expr_integer = 192, // expr_integer
|
||||
S_expr_false = 193, // expr_false
|
||||
S_expr_true = 194 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1154,6 +1158,10 @@ namespace xsk { namespace gsc { namespace iw6 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw6 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2408,6 +2430,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4770,8 +4796,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2303, ///< Last index in yytable_.
|
||||
yynnts_ = 82, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2363, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4905,6 +4931,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5219,6 +5249,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5462,7 +5496,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::iw6
|
||||
#line 5466 "parser.hpp"
|
||||
#line 5500 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -82,6 +82,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1272,7 +1265,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1332,7 +1325,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1790,17 +1786,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1860,28 +1871,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1940,6 +2001,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2152,7 +2278,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2162,7 +2288,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2407,7 +2533,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3027,17 +3160,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3266,18 +3402,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw7 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy62[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy65[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw7 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy66[sizeof (std::string)];
|
||||
char dummy67[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -977,40 +980,41 @@ namespace xsk { namespace gsc { namespace iw7 {
|
||||
S_expr_binary = 157, // expr_binary
|
||||
S_expr_primitive = 158, // expr_primitive
|
||||
S_expr_complement = 159, // expr_complement
|
||||
S_expr_not = 160, // expr_not
|
||||
S_expr_call = 161, // expr_call
|
||||
S_expr_method = 162, // expr_method
|
||||
S_expr_function = 163, // expr_function
|
||||
S_expr_pointer = 164, // expr_pointer
|
||||
S_expr_add_array = 165, // expr_add_array
|
||||
S_expr_parameters = 166, // expr_parameters
|
||||
S_expr_arguments = 167, // expr_arguments
|
||||
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty
|
||||
S_expr_reference = 169, // expr_reference
|
||||
S_expr_array = 170, // expr_array
|
||||
S_expr_field = 171, // expr_field
|
||||
S_expr_size = 172, // expr_size
|
||||
S_expr_paren = 173, // expr_paren
|
||||
S_expr_object = 174, // expr_object
|
||||
S_expr_thisthread = 175, // expr_thisthread
|
||||
S_expr_empty_array = 176, // expr_empty_array
|
||||
S_expr_undefined = 177, // expr_undefined
|
||||
S_expr_game = 178, // expr_game
|
||||
S_expr_self = 179, // expr_self
|
||||
S_expr_anim = 180, // expr_anim
|
||||
S_expr_level = 181, // expr_level
|
||||
S_expr_animation = 182, // expr_animation
|
||||
S_expr_animtree = 183, // expr_animtree
|
||||
S_expr_identifier_nosize = 184, // expr_identifier_nosize
|
||||
S_expr_identifier = 185, // expr_identifier
|
||||
S_expr_path = 186, // expr_path
|
||||
S_expr_istring = 187, // expr_istring
|
||||
S_expr_string = 188, // expr_string
|
||||
S_expr_vector = 189, // expr_vector
|
||||
S_expr_float = 190, // expr_float
|
||||
S_expr_integer = 191, // expr_integer
|
||||
S_expr_false = 192, // expr_false
|
||||
S_expr_true = 193 // expr_true
|
||||
S_expr_negate = 160, // expr_negate
|
||||
S_expr_not = 161, // expr_not
|
||||
S_expr_call = 162, // expr_call
|
||||
S_expr_method = 163, // expr_method
|
||||
S_expr_function = 164, // expr_function
|
||||
S_expr_pointer = 165, // expr_pointer
|
||||
S_expr_add_array = 166, // expr_add_array
|
||||
S_expr_parameters = 167, // expr_parameters
|
||||
S_expr_arguments = 168, // expr_arguments
|
||||
S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
|
||||
S_expr_reference = 170, // expr_reference
|
||||
S_expr_array = 171, // expr_array
|
||||
S_expr_field = 172, // expr_field
|
||||
S_expr_size = 173, // expr_size
|
||||
S_expr_paren = 174, // expr_paren
|
||||
S_expr_object = 175, // expr_object
|
||||
S_expr_thisthread = 176, // expr_thisthread
|
||||
S_expr_empty_array = 177, // expr_empty_array
|
||||
S_expr_undefined = 178, // expr_undefined
|
||||
S_expr_game = 179, // expr_game
|
||||
S_expr_self = 180, // expr_self
|
||||
S_expr_anim = 181, // expr_anim
|
||||
S_expr_level = 182, // expr_level
|
||||
S_expr_animation = 183, // expr_animation
|
||||
S_expr_animtree = 184, // expr_animtree
|
||||
S_expr_identifier_nosize = 185, // expr_identifier_nosize
|
||||
S_expr_identifier = 186, // expr_identifier
|
||||
S_expr_path = 187, // expr_path
|
||||
S_expr_istring = 188, // expr_istring
|
||||
S_expr_string = 189, // expr_string
|
||||
S_expr_vector = 190, // expr_vector
|
||||
S_expr_float = 191, // expr_float
|
||||
S_expr_integer = 192, // expr_integer
|
||||
S_expr_false = 193, // expr_false
|
||||
S_expr_true = 194 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1154,6 +1158,10 @@ namespace xsk { namespace gsc { namespace iw7 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw7 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2408,6 +2430,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4770,8 +4796,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2303, ///< Last index in yytable_.
|
||||
yynnts_ = 82, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2363, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4905,6 +4931,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5219,6 +5249,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5462,7 +5496,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::iw7
|
||||
#line 5466 "parser.hpp"
|
||||
#line 5500 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1283,6 +1286,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1814,11 +1807,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1827,17 +1823,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1897,28 +1908,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1977,6 +2038,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2189,7 +2315,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2199,7 +2325,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2444,7 +2570,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3070,17 +3203,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3309,18 +3445,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -511,134 +511,137 @@ namespace xsk { namespace gsc { namespace iw8 {
|
||||
// expr_method
|
||||
char dummy26[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy27[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy27[sizeof (ast::expr_not::ptr)];
|
||||
char dummy28[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy28[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy29[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy29[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy30[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy30[sizeof (ast::expr_path::ptr)];
|
||||
char dummy31[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy31[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy32[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy32[sizeof (ast::expr_self::ptr)];
|
||||
char dummy33[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy33[sizeof (ast::expr_size::ptr)];
|
||||
char dummy34[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy34[sizeof (ast::expr_string::ptr)];
|
||||
char dummy35[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy35[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy36[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy36[sizeof (ast::expr_true::ptr)];
|
||||
char dummy37[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy37[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy38[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy38[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy39[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy39[sizeof (ast::include::ptr)];
|
||||
char dummy40[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy40[sizeof (ast::program::ptr)];
|
||||
char dummy41[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy41[sizeof (ast::stmt)];
|
||||
char dummy42[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy42[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy43[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy44[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy45[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy46[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy47[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy48[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy49[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy50[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy51[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy52[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy53[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy54[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy55[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy56[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy57[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy58[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy59[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy60[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy61[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy62[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy63[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy64[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy65[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy66[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy67[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy68[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy68[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy69[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -646,7 +649,7 @@ namespace xsk { namespace gsc { namespace iw8 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy69[sizeof (std::string)];
|
||||
char dummy70[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -993,42 +996,43 @@ namespace xsk { namespace gsc { namespace iw8 {
|
||||
S_expr_binary = 161, // expr_binary
|
||||
S_expr_primitive = 162, // expr_primitive
|
||||
S_expr_complement = 163, // expr_complement
|
||||
S_expr_not = 164, // expr_not
|
||||
S_expr_call = 165, // expr_call
|
||||
S_expr_method = 166, // expr_method
|
||||
S_expr_function = 167, // expr_function
|
||||
S_expr_pointer = 168, // expr_pointer
|
||||
S_expr_add_array = 169, // expr_add_array
|
||||
S_expr_parameters = 170, // expr_parameters
|
||||
S_expr_arguments = 171, // expr_arguments
|
||||
S_expr_arguments_no_empty = 172, // expr_arguments_no_empty
|
||||
S_expr_isdefined = 173, // expr_isdefined
|
||||
S_expr_istrue = 174, // expr_istrue
|
||||
S_expr_reference = 175, // expr_reference
|
||||
S_expr_array = 176, // expr_array
|
||||
S_expr_field = 177, // expr_field
|
||||
S_expr_size = 178, // expr_size
|
||||
S_expr_paren = 179, // expr_paren
|
||||
S_expr_object = 180, // expr_object
|
||||
S_expr_thisthread = 181, // expr_thisthread
|
||||
S_expr_empty_array = 182, // expr_empty_array
|
||||
S_expr_undefined = 183, // expr_undefined
|
||||
S_expr_game = 184, // expr_game
|
||||
S_expr_self = 185, // expr_self
|
||||
S_expr_anim = 186, // expr_anim
|
||||
S_expr_level = 187, // expr_level
|
||||
S_expr_animation = 188, // expr_animation
|
||||
S_expr_animtree = 189, // expr_animtree
|
||||
S_expr_identifier_nosize = 190, // expr_identifier_nosize
|
||||
S_expr_identifier = 191, // expr_identifier
|
||||
S_expr_path = 192, // expr_path
|
||||
S_expr_istring = 193, // expr_istring
|
||||
S_expr_string = 194, // expr_string
|
||||
S_expr_vector = 195, // expr_vector
|
||||
S_expr_float = 196, // expr_float
|
||||
S_expr_integer = 197, // expr_integer
|
||||
S_expr_false = 198, // expr_false
|
||||
S_expr_true = 199 // expr_true
|
||||
S_expr_negate = 164, // expr_negate
|
||||
S_expr_not = 165, // expr_not
|
||||
S_expr_call = 166, // expr_call
|
||||
S_expr_method = 167, // expr_method
|
||||
S_expr_function = 168, // expr_function
|
||||
S_expr_pointer = 169, // expr_pointer
|
||||
S_expr_add_array = 170, // expr_add_array
|
||||
S_expr_parameters = 171, // expr_parameters
|
||||
S_expr_arguments = 172, // expr_arguments
|
||||
S_expr_arguments_no_empty = 173, // expr_arguments_no_empty
|
||||
S_expr_isdefined = 174, // expr_isdefined
|
||||
S_expr_istrue = 175, // expr_istrue
|
||||
S_expr_reference = 176, // expr_reference
|
||||
S_expr_array = 177, // expr_array
|
||||
S_expr_field = 178, // expr_field
|
||||
S_expr_size = 179, // expr_size
|
||||
S_expr_paren = 180, // expr_paren
|
||||
S_expr_object = 181, // expr_object
|
||||
S_expr_thisthread = 182, // expr_thisthread
|
||||
S_expr_empty_array = 183, // expr_empty_array
|
||||
S_expr_undefined = 184, // expr_undefined
|
||||
S_expr_game = 185, // expr_game
|
||||
S_expr_self = 186, // expr_self
|
||||
S_expr_anim = 187, // expr_anim
|
||||
S_expr_level = 188, // expr_level
|
||||
S_expr_animation = 189, // expr_animation
|
||||
S_expr_animtree = 190, // expr_animtree
|
||||
S_expr_identifier_nosize = 191, // expr_identifier_nosize
|
||||
S_expr_identifier = 192, // expr_identifier
|
||||
S_expr_path = 193, // expr_path
|
||||
S_expr_istring = 194, // expr_istring
|
||||
S_expr_string = 195, // expr_string
|
||||
S_expr_vector = 196, // expr_vector
|
||||
S_expr_float = 197, // expr_float
|
||||
S_expr_integer = 198, // expr_integer
|
||||
S_expr_false = 199, // expr_false
|
||||
S_expr_true = 200 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1180,6 +1184,10 @@ namespace xsk { namespace gsc { namespace iw8 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1747,6 +1755,20 @@ namespace xsk { namespace gsc { namespace iw8 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2488,6 +2510,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4899,8 +4925,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2278, ///< Last index in yytable_.
|
||||
yynnts_ = 85, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2481, ///< Last index in yytable_.
|
||||
yynnts_ = 86, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -5042,6 +5068,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5368,6 +5398,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5615,7 +5649,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::iw8
|
||||
#line 5619 "parser.hpp"
|
||||
#line 5653 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1796,17 +1792,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1866,28 +1877,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1946,6 +2007,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2158,7 +2284,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2168,7 +2294,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2413,7 +2539,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3033,17 +3166,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3272,18 +3408,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace s1 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy62[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace s1 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy67[sizeof (std::string)];
|
||||
char dummy68[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -983,40 +986,41 @@ namespace xsk { namespace gsc { namespace s1 {
|
||||
S_expr_binary = 159, // expr_binary
|
||||
S_expr_primitive = 160, // expr_primitive
|
||||
S_expr_complement = 161, // expr_complement
|
||||
S_expr_not = 162, // expr_not
|
||||
S_expr_call = 163, // expr_call
|
||||
S_expr_method = 164, // expr_method
|
||||
S_expr_function = 165, // expr_function
|
||||
S_expr_pointer = 166, // expr_pointer
|
||||
S_expr_add_array = 167, // expr_add_array
|
||||
S_expr_parameters = 168, // expr_parameters
|
||||
S_expr_arguments = 169, // expr_arguments
|
||||
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty
|
||||
S_expr_reference = 171, // expr_reference
|
||||
S_expr_array = 172, // expr_array
|
||||
S_expr_field = 173, // expr_field
|
||||
S_expr_size = 174, // expr_size
|
||||
S_expr_paren = 175, // expr_paren
|
||||
S_expr_object = 176, // expr_object
|
||||
S_expr_thisthread = 177, // expr_thisthread
|
||||
S_expr_empty_array = 178, // expr_empty_array
|
||||
S_expr_undefined = 179, // expr_undefined
|
||||
S_expr_game = 180, // expr_game
|
||||
S_expr_self = 181, // expr_self
|
||||
S_expr_anim = 182, // expr_anim
|
||||
S_expr_level = 183, // expr_level
|
||||
S_expr_animation = 184, // expr_animation
|
||||
S_expr_animtree = 185, // expr_animtree
|
||||
S_expr_identifier_nosize = 186, // expr_identifier_nosize
|
||||
S_expr_identifier = 187, // expr_identifier
|
||||
S_expr_path = 188, // expr_path
|
||||
S_expr_istring = 189, // expr_istring
|
||||
S_expr_string = 190, // expr_string
|
||||
S_expr_vector = 191, // expr_vector
|
||||
S_expr_float = 192, // expr_float
|
||||
S_expr_integer = 193, // expr_integer
|
||||
S_expr_false = 194, // expr_false
|
||||
S_expr_true = 195 // expr_true
|
||||
S_expr_negate = 162, // expr_negate
|
||||
S_expr_not = 163, // expr_not
|
||||
S_expr_call = 164, // expr_call
|
||||
S_expr_method = 165, // expr_method
|
||||
S_expr_function = 166, // expr_function
|
||||
S_expr_pointer = 167, // expr_pointer
|
||||
S_expr_add_array = 168, // expr_add_array
|
||||
S_expr_parameters = 169, // expr_parameters
|
||||
S_expr_arguments = 170, // expr_arguments
|
||||
S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
|
||||
S_expr_reference = 172, // expr_reference
|
||||
S_expr_array = 173, // expr_array
|
||||
S_expr_field = 174, // expr_field
|
||||
S_expr_size = 175, // expr_size
|
||||
S_expr_paren = 176, // expr_paren
|
||||
S_expr_object = 177, // expr_object
|
||||
S_expr_thisthread = 178, // expr_thisthread
|
||||
S_expr_empty_array = 179, // expr_empty_array
|
||||
S_expr_undefined = 180, // expr_undefined
|
||||
S_expr_game = 181, // expr_game
|
||||
S_expr_self = 182, // expr_self
|
||||
S_expr_anim = 183, // expr_anim
|
||||
S_expr_level = 184, // expr_level
|
||||
S_expr_animation = 185, // expr_animation
|
||||
S_expr_animtree = 186, // expr_animtree
|
||||
S_expr_identifier_nosize = 187, // expr_identifier_nosize
|
||||
S_expr_identifier = 188, // expr_identifier
|
||||
S_expr_path = 189, // expr_path
|
||||
S_expr_istring = 190, // expr_istring
|
||||
S_expr_string = 191, // expr_string
|
||||
S_expr_vector = 192, // expr_vector
|
||||
S_expr_float = 193, // expr_float
|
||||
S_expr_integer = 194, // expr_integer
|
||||
S_expr_false = 195, // expr_false
|
||||
S_expr_true = 196 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1160,6 +1164,10 @@ namespace xsk { namespace gsc { namespace s1 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace s1 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2432,6 +2454,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4813,8 +4839,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2251, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2419, ///< Last index in yytable_.
|
||||
yynnts_ = 84, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4948,6 +4974,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5266,6 +5296,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5513,7 +5547,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::s1
|
||||
#line 5517 "parser.hpp"
|
||||
#line 5551 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -464,10 +464,10 @@ const std::array<std::pair<std::uint16_t, const char*>, 735> function_list
|
||||
{ 0x020, "badplace_cylinder" },
|
||||
{ 0x021, "badplace_arc" },
|
||||
{ 0x022, "badplace_brush" },
|
||||
{ 0x023, "_func_023" }, // SP 0x140261020
|
||||
{ 0x024, "_func_024" }, // SP 0x14027EA80
|
||||
{ 0x025, "_func_025" }, // SP 0x14027EB20
|
||||
{ 0x026, "_func_026" }, // SP 0x14027E9B0
|
||||
{ 0x023, "clearallcorpses" }, // SP 0x140261020
|
||||
{ 0x024, "setturretnode" }, // SP 0x14027EA80
|
||||
{ 0x025, "unsetturretnode" }, // SP 0x14027EB20
|
||||
{ 0x026, "setnodepriority" }, // SP 0x14027E9B0
|
||||
{ 0x027, "_func_027" }, // SP 0x14027E870
|
||||
{ 0x028, "_func_028" }, // empty
|
||||
{ 0x029, "_func_029" }, // empty
|
||||
@ -492,7 +492,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 735> function_list
|
||||
{ 0x03C, "getdvarvector" },
|
||||
{ 0x03D, "gettime" },
|
||||
{ 0x03E, "gettimeutc" },
|
||||
{ 0x03F, "_func_03F" }, // SP 0x14024B9C0, MP 0x1403156A0
|
||||
{ 0x03F, "getradiometricunit" },
|
||||
{ 0x040, "getentbynum" },
|
||||
{ 0x041, "getweaponmodel" },
|
||||
{ 0x042, "getculldist" },
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1790,11 +1783,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1803,17 +1799,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1873,28 +1884,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1953,6 +2014,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2165,7 +2291,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2175,7 +2301,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2420,7 +2546,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3040,17 +3173,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3279,18 +3415,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace s2 {
|
||||
// expr_method
|
||||
char dummy24[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy25[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy25[sizeof (ast::expr_not::ptr)];
|
||||
char dummy26[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy26[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy27[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy27[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy28[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy28[sizeof (ast::expr_path::ptr)];
|
||||
char dummy29[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy29[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy30[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy30[sizeof (ast::expr_self::ptr)];
|
||||
char dummy31[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy31[sizeof (ast::expr_size::ptr)];
|
||||
char dummy32[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy32[sizeof (ast::expr_string::ptr)];
|
||||
char dummy33[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy33[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy34[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy34[sizeof (ast::expr_true::ptr)];
|
||||
char dummy35[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy35[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy36[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy36[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy37[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy37[sizeof (ast::include::ptr)];
|
||||
char dummy38[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy38[sizeof (ast::program::ptr)];
|
||||
char dummy39[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy39[sizeof (ast::stmt)];
|
||||
char dummy40[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy40[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy41[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy41[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy42[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy42[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy43[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy44[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy45[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy46[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy47[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy48[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy49[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy50[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy51[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy52[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy53[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy54[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy55[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy56[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy57[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy58[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy59[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy60[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy61[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy62[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy63[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy66[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace s2 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy67[sizeof (std::string)];
|
||||
char dummy68[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -983,40 +986,41 @@ namespace xsk { namespace gsc { namespace s2 {
|
||||
S_expr_binary = 159, // expr_binary
|
||||
S_expr_primitive = 160, // expr_primitive
|
||||
S_expr_complement = 161, // expr_complement
|
||||
S_expr_not = 162, // expr_not
|
||||
S_expr_call = 163, // expr_call
|
||||
S_expr_method = 164, // expr_method
|
||||
S_expr_function = 165, // expr_function
|
||||
S_expr_pointer = 166, // expr_pointer
|
||||
S_expr_add_array = 167, // expr_add_array
|
||||
S_expr_parameters = 168, // expr_parameters
|
||||
S_expr_arguments = 169, // expr_arguments
|
||||
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty
|
||||
S_expr_reference = 171, // expr_reference
|
||||
S_expr_array = 172, // expr_array
|
||||
S_expr_field = 173, // expr_field
|
||||
S_expr_size = 174, // expr_size
|
||||
S_expr_paren = 175, // expr_paren
|
||||
S_expr_object = 176, // expr_object
|
||||
S_expr_thisthread = 177, // expr_thisthread
|
||||
S_expr_empty_array = 178, // expr_empty_array
|
||||
S_expr_undefined = 179, // expr_undefined
|
||||
S_expr_game = 180, // expr_game
|
||||
S_expr_self = 181, // expr_self
|
||||
S_expr_anim = 182, // expr_anim
|
||||
S_expr_level = 183, // expr_level
|
||||
S_expr_animation = 184, // expr_animation
|
||||
S_expr_animtree = 185, // expr_animtree
|
||||
S_expr_identifier_nosize = 186, // expr_identifier_nosize
|
||||
S_expr_identifier = 187, // expr_identifier
|
||||
S_expr_path = 188, // expr_path
|
||||
S_expr_istring = 189, // expr_istring
|
||||
S_expr_string = 190, // expr_string
|
||||
S_expr_vector = 191, // expr_vector
|
||||
S_expr_float = 192, // expr_float
|
||||
S_expr_integer = 193, // expr_integer
|
||||
S_expr_false = 194, // expr_false
|
||||
S_expr_true = 195 // expr_true
|
||||
S_expr_negate = 162, // expr_negate
|
||||
S_expr_not = 163, // expr_not
|
||||
S_expr_call = 164, // expr_call
|
||||
S_expr_method = 165, // expr_method
|
||||
S_expr_function = 166, // expr_function
|
||||
S_expr_pointer = 167, // expr_pointer
|
||||
S_expr_add_array = 168, // expr_add_array
|
||||
S_expr_parameters = 169, // expr_parameters
|
||||
S_expr_arguments = 170, // expr_arguments
|
||||
S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
|
||||
S_expr_reference = 172, // expr_reference
|
||||
S_expr_array = 173, // expr_array
|
||||
S_expr_field = 174, // expr_field
|
||||
S_expr_size = 175, // expr_size
|
||||
S_expr_paren = 176, // expr_paren
|
||||
S_expr_object = 177, // expr_object
|
||||
S_expr_thisthread = 178, // expr_thisthread
|
||||
S_expr_empty_array = 179, // expr_empty_array
|
||||
S_expr_undefined = 180, // expr_undefined
|
||||
S_expr_game = 181, // expr_game
|
||||
S_expr_self = 182, // expr_self
|
||||
S_expr_anim = 183, // expr_anim
|
||||
S_expr_level = 184, // expr_level
|
||||
S_expr_animation = 185, // expr_animation
|
||||
S_expr_animtree = 186, // expr_animtree
|
||||
S_expr_identifier_nosize = 187, // expr_identifier_nosize
|
||||
S_expr_identifier = 188, // expr_identifier
|
||||
S_expr_path = 189, // expr_path
|
||||
S_expr_istring = 190, // expr_istring
|
||||
S_expr_string = 191, // expr_string
|
||||
S_expr_vector = 192, // expr_vector
|
||||
S_expr_float = 193, // expr_float
|
||||
S_expr_integer = 194, // expr_integer
|
||||
S_expr_false = 195, // expr_false
|
||||
S_expr_true = 196 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1160,6 +1164,10 @@ namespace xsk { namespace gsc { namespace s2 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace s2 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2432,6 +2454,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4813,8 +4839,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2251, ///< Last index in yytable_.
|
||||
yynnts_ = 83, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2419, ///< Last index in yytable_.
|
||||
yynnts_ = 84, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -4948,6 +4974,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5266,6 +5296,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5513,7 +5547,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::s2
|
||||
#line 5517 "parser.hpp"
|
||||
#line 5551 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement, blk);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate, blk);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not, blk);
|
||||
break;
|
||||
@ -1283,6 +1286,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue, blk);
|
||||
emit_opcode(opcode::OP_minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
emit_expr(expr->rvalue, blk);
|
||||
|
@ -83,6 +83,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);
|
||||
|
@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
|
||||
// remove last return
|
||||
stmt->list.pop_back();
|
||||
|
||||
// hotfix empty else block at func end
|
||||
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.back().as_jump->value == blk.loc_end)
|
||||
stmt->list.pop_back();
|
||||
}
|
||||
|
||||
blocks_.push_back(blk);
|
||||
|
||||
decompile_statements(stmt);
|
||||
@ -1278,7 +1271,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1338,7 +1331,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = event.as_node->loc();
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
|
||||
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
break;
|
||||
case opcode::OP_ClearLocalVariableFieldCached0:
|
||||
{
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
|
||||
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
|
||||
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
|
||||
}
|
||||
break;
|
||||
@ -1814,11 +1807,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
decompile_switches(stmt);
|
||||
decompile_ifelses(stmt);
|
||||
decompile_aborts(stmt);
|
||||
decompile_tuples(stmt);
|
||||
}
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (auto i = static_cast<std::int32_t>(stmt->list.size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
@ -1827,17 +1823,32 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
{
|
||||
continue;
|
||||
if (static_cast<std::size_t>(i) < find_location_index(stmt, stmt->list.at(i - 1).as_cond->loc().label()))
|
||||
{
|
||||
continue; // do-while
|
||||
}
|
||||
// empty if at loop end
|
||||
}
|
||||
|
||||
if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = static_cast<std::int32_t>(stmt->list.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1897,28 +1908,78 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
|
||||
// if block is a loop check break, continue
|
||||
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// last if/else inside a loop still trigger this :(
|
||||
// check for if/else or if/continue
|
||||
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
|
||||
{
|
||||
// block ends with a return, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
|
||||
{
|
||||
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
// block ends with a break, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
|
||||
{
|
||||
// if { break/return } else { continue } at loop block end
|
||||
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
// block ends with a continue, so jump belows to if/else
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// jump belows to if/continue
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // last if/else inside a loop still trigger this :(
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
|
||||
{
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
|
||||
{
|
||||
decompile_if(stmt, i, j); // if block, have a last empty else inside
|
||||
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
|
||||
{
|
||||
// if block, have a empty else inside at end
|
||||
decompile_if(stmt, i, j);
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
|
||||
decompile_ifelse(stmt, i, j); // if block with empty else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decompile_ifelse(stmt, i, j);
|
||||
}
|
||||
}
|
||||
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
|
||||
{
|
||||
if(entry.as_cond->value != blocks_.back().loc_end)
|
||||
{
|
||||
auto ref = stmt->list.at(j + 1).loc().label();
|
||||
|
||||
if (find_location_reference(stmt, i + 1, j, ref))
|
||||
{
|
||||
// after return is referenced inside the block
|
||||
decompile_if(stmt, i, j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
|
||||
{
|
||||
decompile_if(stmt, i, j); // inside a loop cant be last
|
||||
@ -1977,6 +2038,71 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
|
||||
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
|
||||
block->list.insert(block->list.begin() + i, std::move(stmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
|
||||
{
|
||||
for (auto i = 1u; i < block->list.size(); i++)
|
||||
{
|
||||
if (block->list.at(i) == ast::kind::asm_clear)
|
||||
{
|
||||
auto j = i - 1;
|
||||
auto found = false, done = false;
|
||||
|
||||
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto& expr = block->list.at(j).as_assign->expr;
|
||||
|
||||
if (expr != ast::kind::expr_assign_equal)
|
||||
break;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
|
||||
break;
|
||||
|
||||
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
|
||||
done = true;
|
||||
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
auto& stmt = block->list.at(j); // temp = expr;
|
||||
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
|
||||
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
|
||||
j++;
|
||||
|
||||
while (j < i)
|
||||
{
|
||||
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
|
||||
block->list.erase(block->list.begin() + j);
|
||||
i--;
|
||||
}
|
||||
|
||||
block->list.erase(block->list.begin() + j); // clear temp array
|
||||
i--;
|
||||
|
||||
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2189,7 +2315,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
if (block->list.at(start - index) == ast::kind::stmt_assign)
|
||||
{
|
||||
auto ref = block->list.at(end).loc().label();
|
||||
auto ref2 = block->list.at(start).loc().label();
|
||||
auto ref2 = block->list.at(start - index + 1).loc().label();
|
||||
|
||||
if (find_location_reference(block, start, end, ref))
|
||||
{
|
||||
@ -2199,7 +2325,7 @@ void decompiler::decompile_loop(const ast::stmt_list::ptr& block, std::size_t st
|
||||
}
|
||||
else if (find_location_reference(block, 0, start, ref2))
|
||||
{
|
||||
// begin is at condition, not pre-expr
|
||||
// begin is at condition or localVarCreate, not pre-expr
|
||||
decompile_while(block, start, end);
|
||||
return;
|
||||
}
|
||||
@ -2444,7 +2570,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
@ -3070,17 +3203,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
|
||||
case ast::kind::expr_add_array:
|
||||
process_expr_add_array(expr.as_add_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_array_variable(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_field_variable(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_size:
|
||||
process_expr_size(expr.as_size, blk);
|
||||
break;
|
||||
case ast::kind::expr_tuple:
|
||||
process_expr_tuple(expr.as_tuple, blk);
|
||||
break;
|
||||
case ast::kind::expr_array:
|
||||
process_expr_array(expr.as_array, blk);
|
||||
break;
|
||||
case ast::kind::expr_field:
|
||||
process_expr_field(expr.as_field, blk);
|
||||
break;
|
||||
case ast::kind::expr_identifier:
|
||||
process_local_variable(expr.as_identifier, blk);
|
||||
process_expr_local(expr.as_identifier, blk);
|
||||
break;
|
||||
case ast::kind::expr_vector:
|
||||
process_expr_vector(expr.as_vector, blk);
|
||||
@ -3309,18 +3445,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->temp, blk);
|
||||
|
||||
for (auto& entry : expr->list)
|
||||
{
|
||||
process_expr(entry, blk);
|
||||
}
|
||||
}
|
||||
|
||||
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->key, blk);
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
|
||||
{
|
||||
process_expr(expr->obj, blk);
|
||||
}
|
||||
|
||||
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
void decompile_switches(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_aborts(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_tuples(const ast::stmt_list::ptr& stmt);
|
||||
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
|
||||
@ -89,9 +90,10 @@ private:
|
||||
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
|
||||
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
|
||||
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
|
||||
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
|
||||
void process_var_access(ast::expr& expr, const block::ptr& blk);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -511,134 +511,137 @@ namespace xsk { namespace gsc { namespace s4 {
|
||||
// expr_method
|
||||
char dummy26[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy27[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy27[sizeof (ast::expr_not::ptr)];
|
||||
char dummy28[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy28[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy29[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy29[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy30[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy30[sizeof (ast::expr_path::ptr)];
|
||||
char dummy31[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy31[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy32[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy32[sizeof (ast::expr_self::ptr)];
|
||||
char dummy33[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy33[sizeof (ast::expr_size::ptr)];
|
||||
char dummy34[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy34[sizeof (ast::expr_string::ptr)];
|
||||
char dummy35[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_thisthread
|
||||
char dummy35[sizeof (ast::expr_thisthread::ptr)];
|
||||
char dummy36[sizeof (ast::expr_thisthread::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy36[sizeof (ast::expr_true::ptr)];
|
||||
char dummy37[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy37[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy38[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy38[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy39[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// include
|
||||
char dummy39[sizeof (ast::include::ptr)];
|
||||
char dummy40[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy40[sizeof (ast::program::ptr)];
|
||||
char dummy41[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy41[sizeof (ast::stmt)];
|
||||
char dummy42[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy42[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy43[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy43[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy44[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_breakpoint
|
||||
char dummy44[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
char dummy45[sizeof (ast::stmt_breakpoint::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy45[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy46[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy46[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy47[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy47[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy48[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy48[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy49[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy49[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy50[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy50[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy51[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy51[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy52[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy52[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy53[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy53[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy54[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy54[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy55[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy55[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy56[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy56[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy57[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy57[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy58[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy59[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy60[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy61[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy62[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy63[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waitframe
|
||||
char dummy64[sizeof (ast::stmt_waitframe::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_waitframe::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy65[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy66[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy67[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy68[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy68[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy69[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -646,7 +649,7 @@ namespace xsk { namespace gsc { namespace s4 {
|
||||
// "localized string"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy69[sizeof (std::string)];
|
||||
char dummy70[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -993,42 +996,43 @@ namespace xsk { namespace gsc { namespace s4 {
|
||||
S_expr_binary = 161, // expr_binary
|
||||
S_expr_primitive = 162, // expr_primitive
|
||||
S_expr_complement = 163, // expr_complement
|
||||
S_expr_not = 164, // expr_not
|
||||
S_expr_call = 165, // expr_call
|
||||
S_expr_method = 166, // expr_method
|
||||
S_expr_function = 167, // expr_function
|
||||
S_expr_pointer = 168, // expr_pointer
|
||||
S_expr_add_array = 169, // expr_add_array
|
||||
S_expr_parameters = 170, // expr_parameters
|
||||
S_expr_arguments = 171, // expr_arguments
|
||||
S_expr_arguments_no_empty = 172, // expr_arguments_no_empty
|
||||
S_expr_isdefined = 173, // expr_isdefined
|
||||
S_expr_istrue = 174, // expr_istrue
|
||||
S_expr_reference = 175, // expr_reference
|
||||
S_expr_array = 176, // expr_array
|
||||
S_expr_field = 177, // expr_field
|
||||
S_expr_size = 178, // expr_size
|
||||
S_expr_paren = 179, // expr_paren
|
||||
S_expr_object = 180, // expr_object
|
||||
S_expr_thisthread = 181, // expr_thisthread
|
||||
S_expr_empty_array = 182, // expr_empty_array
|
||||
S_expr_undefined = 183, // expr_undefined
|
||||
S_expr_game = 184, // expr_game
|
||||
S_expr_self = 185, // expr_self
|
||||
S_expr_anim = 186, // expr_anim
|
||||
S_expr_level = 187, // expr_level
|
||||
S_expr_animation = 188, // expr_animation
|
||||
S_expr_animtree = 189, // expr_animtree
|
||||
S_expr_identifier_nosize = 190, // expr_identifier_nosize
|
||||
S_expr_identifier = 191, // expr_identifier
|
||||
S_expr_path = 192, // expr_path
|
||||
S_expr_istring = 193, // expr_istring
|
||||
S_expr_string = 194, // expr_string
|
||||
S_expr_vector = 195, // expr_vector
|
||||
S_expr_float = 196, // expr_float
|
||||
S_expr_integer = 197, // expr_integer
|
||||
S_expr_false = 198, // expr_false
|
||||
S_expr_true = 199 // expr_true
|
||||
S_expr_negate = 164, // expr_negate
|
||||
S_expr_not = 165, // expr_not
|
||||
S_expr_call = 166, // expr_call
|
||||
S_expr_method = 167, // expr_method
|
||||
S_expr_function = 168, // expr_function
|
||||
S_expr_pointer = 169, // expr_pointer
|
||||
S_expr_add_array = 170, // expr_add_array
|
||||
S_expr_parameters = 171, // expr_parameters
|
||||
S_expr_arguments = 172, // expr_arguments
|
||||
S_expr_arguments_no_empty = 173, // expr_arguments_no_empty
|
||||
S_expr_isdefined = 174, // expr_isdefined
|
||||
S_expr_istrue = 175, // expr_istrue
|
||||
S_expr_reference = 176, // expr_reference
|
||||
S_expr_array = 177, // expr_array
|
||||
S_expr_field = 178, // expr_field
|
||||
S_expr_size = 179, // expr_size
|
||||
S_expr_paren = 180, // expr_paren
|
||||
S_expr_object = 181, // expr_object
|
||||
S_expr_thisthread = 182, // expr_thisthread
|
||||
S_expr_empty_array = 183, // expr_empty_array
|
||||
S_expr_undefined = 184, // expr_undefined
|
||||
S_expr_game = 185, // expr_game
|
||||
S_expr_self = 186, // expr_self
|
||||
S_expr_anim = 187, // expr_anim
|
||||
S_expr_level = 188, // expr_level
|
||||
S_expr_animation = 189, // expr_animation
|
||||
S_expr_animtree = 190, // expr_animtree
|
||||
S_expr_identifier_nosize = 191, // expr_identifier_nosize
|
||||
S_expr_identifier = 192, // expr_identifier
|
||||
S_expr_path = 193, // expr_path
|
||||
S_expr_istring = 194, // expr_istring
|
||||
S_expr_string = 195, // expr_string
|
||||
S_expr_vector = 196, // expr_vector
|
||||
S_expr_float = 197, // expr_float
|
||||
S_expr_integer = 198, // expr_integer
|
||||
S_expr_false = 199, // expr_false
|
||||
S_expr_true = 200 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1180,6 +1184,10 @@ namespace xsk { namespace gsc { namespace s4 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -1747,6 +1755,20 @@ namespace xsk { namespace gsc { namespace s4 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2488,6 +2510,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -4899,8 +4925,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 2278, ///< Last index in yytable_.
|
||||
yynnts_ = 85, ///< Number of nonterminal symbols.
|
||||
yylast_ = 2481, ///< Last index in yytable_.
|
||||
yynnts_ = 86, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -5042,6 +5068,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -5368,6 +5398,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -5615,7 +5649,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::gsc::s4
|
||||
#line 5619 "parser.hpp"
|
||||
#line 5653 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -813,6 +813,9 @@ void compiler::emit_expr(const ast::expr& expr)
|
||||
case ast::kind::expr_complement:
|
||||
emit_expr_complement(expr.as_complement);
|
||||
break;
|
||||
case ast::kind::expr_negate:
|
||||
emit_expr_negate(expr.as_negate);
|
||||
break;
|
||||
case ast::kind::expr_not:
|
||||
emit_expr_not(expr.as_not);
|
||||
break;
|
||||
@ -1163,6 +1166,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr)
|
||||
emit_opcode(opcode::OP_BoolComplement);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_negate(const ast::expr_negate::ptr& expr)
|
||||
{
|
||||
emit_opcode(opcode::OP_GetZero);
|
||||
emit_expr(expr->rvalue);
|
||||
emit_opcode(opcode::OP_Minus);
|
||||
}
|
||||
|
||||
void compiler::emit_expr_not(const ast::expr_not::ptr& expr)
|
||||
{
|
||||
emit_expr(expr->rvalue);
|
||||
|
@ -80,6 +80,7 @@ private:
|
||||
void emit_expr_and(const ast::expr_and::ptr& expr);
|
||||
void emit_expr_or(const ast::expr_or::ptr& expr);
|
||||
void emit_expr_complement(const ast::expr_complement::ptr& expr);
|
||||
void emit_expr_negate(const ast::expr_negate::ptr& expr);
|
||||
void emit_expr_not(const ast::expr_not::ptr& expr);
|
||||
void emit_expr_call(const ast::expr_call::ptr& expr, bool is_stmt);
|
||||
void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, bool is_stmt);
|
||||
|
@ -262,9 +262,17 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last)
|
||||
throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode));
|
||||
break;
|
||||
case opcode::OP_EvalLocalVariableCached:
|
||||
{
|
||||
try
|
||||
{
|
||||
auto node = std::make_unique<ast::expr_identifier>(loc, locals_.at(std::stoi(inst->data[0])));
|
||||
stack_.push(std::move(node));
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
auto node = std::make_unique<ast::expr_identifier>(loc, "broken_code!!");
|
||||
stack_.push(std::move(node));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case opcode::OP_EvalArray:
|
||||
@ -1307,12 +1315,12 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc)
|
||||
{
|
||||
@ -1624,7 +1632,7 @@ void decompiler::decompile_infinite(const ast::stmt_list::ptr& stmt, std::size_t
|
||||
block blk;
|
||||
blk.loc_break = last_location_index(stmt, end) ? blocks_.back().loc_end : stmt->list.at(end + 1).loc().label();
|
||||
blk.loc_end = stmt->list.at(end).loc().label();
|
||||
blk.loc_continue = stmt->list.at(end).loc().label();
|
||||
blk.loc_continue = stmt->list.at(begin).loc().label();
|
||||
|
||||
auto loc = stmt->list.at(begin).loc();
|
||||
|
||||
|
@ -81,6 +81,8 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
|
||||
// string list
|
||||
script_->pos(64);
|
||||
|
||||
stringlist_.insert({ 0x3E, "" }); // old compiler null string points to header flags
|
||||
|
||||
while (script_->pos() < header_.include_offset)
|
||||
{
|
||||
auto pos = script_->pos();
|
||||
@ -211,9 +213,16 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (header_.cseg_size == 0) // old compiler fucked!
|
||||
{
|
||||
entry->size = (header_.exports_offset) - entry->offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->size = (header_.cseg_offset + header_.cseg_size) - entry->offset;
|
||||
}
|
||||
}
|
||||
|
||||
script_->pos(entry->offset);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -553,131 +553,134 @@ namespace xsk { namespace arc { namespace t6 {
|
||||
// expr_method
|
||||
char dummy40[sizeof (ast::expr_method::ptr)];
|
||||
|
||||
// expr_negate
|
||||
char dummy41[sizeof (ast::expr_negate::ptr)];
|
||||
|
||||
// expr_not
|
||||
char dummy41[sizeof (ast::expr_not::ptr)];
|
||||
char dummy42[sizeof (ast::expr_not::ptr)];
|
||||
|
||||
// expr_parameters
|
||||
char dummy42[sizeof (ast::expr_parameters::ptr)];
|
||||
char dummy43[sizeof (ast::expr_parameters::ptr)];
|
||||
|
||||
// expr_paren
|
||||
char dummy43[sizeof (ast::expr_paren::ptr)];
|
||||
char dummy44[sizeof (ast::expr_paren::ptr)];
|
||||
|
||||
// expr_path
|
||||
char dummy44[sizeof (ast::expr_path::ptr)];
|
||||
char dummy45[sizeof (ast::expr_path::ptr)];
|
||||
|
||||
// expr_reference
|
||||
char dummy45[sizeof (ast::expr_reference::ptr)];
|
||||
char dummy46[sizeof (ast::expr_reference::ptr)];
|
||||
|
||||
// expr_self
|
||||
char dummy46[sizeof (ast::expr_self::ptr)];
|
||||
char dummy47[sizeof (ast::expr_self::ptr)];
|
||||
|
||||
// expr_size
|
||||
char dummy47[sizeof (ast::expr_size::ptr)];
|
||||
char dummy48[sizeof (ast::expr_size::ptr)];
|
||||
|
||||
// expr_string
|
||||
char dummy48[sizeof (ast::expr_string::ptr)];
|
||||
char dummy49[sizeof (ast::expr_string::ptr)];
|
||||
|
||||
// expr_true
|
||||
char dummy49[sizeof (ast::expr_true::ptr)];
|
||||
char dummy50[sizeof (ast::expr_true::ptr)];
|
||||
|
||||
// expr_undefined
|
||||
char dummy50[sizeof (ast::expr_undefined::ptr)];
|
||||
char dummy51[sizeof (ast::expr_undefined::ptr)];
|
||||
|
||||
// expr_vector
|
||||
char dummy51[sizeof (ast::expr_vector::ptr)];
|
||||
char dummy52[sizeof (ast::expr_vector::ptr)];
|
||||
|
||||
// expr_vectorscale
|
||||
char dummy52[sizeof (ast::expr_vectorscale::ptr)];
|
||||
char dummy53[sizeof (ast::expr_vectorscale::ptr)];
|
||||
|
||||
// expr_vectortoangles
|
||||
char dummy53[sizeof (ast::expr_vectortoangles::ptr)];
|
||||
char dummy54[sizeof (ast::expr_vectortoangles::ptr)];
|
||||
|
||||
// include
|
||||
char dummy54[sizeof (ast::include::ptr)];
|
||||
char dummy55[sizeof (ast::include::ptr)];
|
||||
|
||||
// program
|
||||
char dummy55[sizeof (ast::program::ptr)];
|
||||
char dummy56[sizeof (ast::program::ptr)];
|
||||
|
||||
// stmt
|
||||
// stmt_or_dev
|
||||
char dummy56[sizeof (ast::stmt)];
|
||||
char dummy57[sizeof (ast::stmt)];
|
||||
|
||||
// stmt_assign
|
||||
char dummy57[sizeof (ast::stmt_assign::ptr)];
|
||||
char dummy58[sizeof (ast::stmt_assign::ptr)];
|
||||
|
||||
// stmt_break
|
||||
char dummy58[sizeof (ast::stmt_break::ptr)];
|
||||
char dummy59[sizeof (ast::stmt_break::ptr)];
|
||||
|
||||
// stmt_call
|
||||
char dummy59[sizeof (ast::stmt_call::ptr)];
|
||||
char dummy60[sizeof (ast::stmt_call::ptr)];
|
||||
|
||||
// stmt_case
|
||||
char dummy60[sizeof (ast::stmt_case::ptr)];
|
||||
char dummy61[sizeof (ast::stmt_case::ptr)];
|
||||
|
||||
// stmt_continue
|
||||
char dummy61[sizeof (ast::stmt_continue::ptr)];
|
||||
char dummy62[sizeof (ast::stmt_continue::ptr)];
|
||||
|
||||
// stmt_default
|
||||
char dummy62[sizeof (ast::stmt_default::ptr)];
|
||||
char dummy63[sizeof (ast::stmt_default::ptr)];
|
||||
|
||||
// stmt_dev
|
||||
char dummy63[sizeof (ast::stmt_dev::ptr)];
|
||||
char dummy64[sizeof (ast::stmt_dev::ptr)];
|
||||
|
||||
// stmt_dowhile
|
||||
char dummy64[sizeof (ast::stmt_dowhile::ptr)];
|
||||
char dummy65[sizeof (ast::stmt_dowhile::ptr)];
|
||||
|
||||
// stmt_endon
|
||||
char dummy65[sizeof (ast::stmt_endon::ptr)];
|
||||
char dummy66[sizeof (ast::stmt_endon::ptr)];
|
||||
|
||||
// stmt_expr
|
||||
char dummy66[sizeof (ast::stmt_expr::ptr)];
|
||||
char dummy67[sizeof (ast::stmt_expr::ptr)];
|
||||
|
||||
// stmt_for
|
||||
char dummy67[sizeof (ast::stmt_for::ptr)];
|
||||
char dummy68[sizeof (ast::stmt_for::ptr)];
|
||||
|
||||
// stmt_foreach
|
||||
char dummy68[sizeof (ast::stmt_foreach::ptr)];
|
||||
char dummy69[sizeof (ast::stmt_foreach::ptr)];
|
||||
|
||||
// stmt_if
|
||||
char dummy69[sizeof (ast::stmt_if::ptr)];
|
||||
char dummy70[sizeof (ast::stmt_if::ptr)];
|
||||
|
||||
// stmt_ifelse
|
||||
char dummy70[sizeof (ast::stmt_ifelse::ptr)];
|
||||
char dummy71[sizeof (ast::stmt_ifelse::ptr)];
|
||||
|
||||
// stmt_list
|
||||
// stmt_or_dev_list
|
||||
// stmt_block
|
||||
char dummy71[sizeof (ast::stmt_list::ptr)];
|
||||
char dummy72[sizeof (ast::stmt_list::ptr)];
|
||||
|
||||
// stmt_notify
|
||||
char dummy72[sizeof (ast::stmt_notify::ptr)];
|
||||
char dummy73[sizeof (ast::stmt_notify::ptr)];
|
||||
|
||||
// stmt_prof_begin
|
||||
char dummy73[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
char dummy74[sizeof (ast::stmt_prof_begin::ptr)];
|
||||
|
||||
// stmt_prof_end
|
||||
char dummy74[sizeof (ast::stmt_prof_end::ptr)];
|
||||
char dummy75[sizeof (ast::stmt_prof_end::ptr)];
|
||||
|
||||
// stmt_return
|
||||
char dummy75[sizeof (ast::stmt_return::ptr)];
|
||||
char dummy76[sizeof (ast::stmt_return::ptr)];
|
||||
|
||||
// stmt_switch
|
||||
char dummy76[sizeof (ast::stmt_switch::ptr)];
|
||||
char dummy77[sizeof (ast::stmt_switch::ptr)];
|
||||
|
||||
// stmt_wait
|
||||
char dummy77[sizeof (ast::stmt_wait::ptr)];
|
||||
char dummy78[sizeof (ast::stmt_wait::ptr)];
|
||||
|
||||
// stmt_waittill
|
||||
char dummy78[sizeof (ast::stmt_waittill::ptr)];
|
||||
char dummy79[sizeof (ast::stmt_waittill::ptr)];
|
||||
|
||||
// stmt_waittillframeend
|
||||
char dummy79[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
char dummy80[sizeof (ast::stmt_waittillframeend::ptr)];
|
||||
|
||||
// stmt_waittillmatch
|
||||
char dummy80[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
char dummy81[sizeof (ast::stmt_waittillmatch::ptr)];
|
||||
|
||||
// stmt_while
|
||||
char dummy81[sizeof (ast::stmt_while::ptr)];
|
||||
char dummy82[sizeof (ast::stmt_while::ptr)];
|
||||
|
||||
// "path"
|
||||
// "identifier"
|
||||
@ -686,7 +689,7 @@ namespace xsk { namespace arc { namespace t6 {
|
||||
// "hash"
|
||||
// "float"
|
||||
// "integer"
|
||||
char dummy82[sizeof (std::string)];
|
||||
char dummy83[sizeof (std::string)];
|
||||
};
|
||||
|
||||
/// The size of the largest semantic type.
|
||||
@ -1053,57 +1056,58 @@ namespace xsk { namespace arc { namespace t6 {
|
||||
S_expr_binary = 170, // expr_binary
|
||||
S_expr_primitive = 171, // expr_primitive
|
||||
S_expr_complement = 172, // expr_complement
|
||||
S_expr_not = 173, // expr_not
|
||||
S_expr_call = 174, // expr_call
|
||||
S_expr_method = 175, // expr_method
|
||||
S_expr_function = 176, // expr_function
|
||||
S_expr_pointer = 177, // expr_pointer
|
||||
S_expr_parameters = 178, // expr_parameters
|
||||
S_expr_arguments = 179, // expr_arguments
|
||||
S_expr_arguments_no_empty = 180, // expr_arguments_no_empty
|
||||
S_expr_getnextarraykey = 181, // expr_getnextarraykey
|
||||
S_expr_getfirstarraykey = 182, // expr_getfirstarraykey
|
||||
S_expr_getdvarcoloralpha = 183, // expr_getdvarcoloralpha
|
||||
S_expr_getdvarcolorblue = 184, // expr_getdvarcolorblue
|
||||
S_expr_getdvarcolorgreen = 185, // expr_getdvarcolorgreen
|
||||
S_expr_getdvarcolorred = 186, // expr_getdvarcolorred
|
||||
S_expr_getdvarvector = 187, // expr_getdvarvector
|
||||
S_expr_getdvarfloat = 188, // expr_getdvarfloat
|
||||
S_expr_getdvarint = 189, // expr_getdvarint
|
||||
S_expr_getdvar = 190, // expr_getdvar
|
||||
S_expr_gettime = 191, // expr_gettime
|
||||
S_expr_abs = 192, // expr_abs
|
||||
S_expr_vectortoangles = 193, // expr_vectortoangles
|
||||
S_expr_angleclamp180 = 194, // expr_angleclamp180
|
||||
S_expr_anglestoforward = 195, // expr_anglestoforward
|
||||
S_expr_anglestoright = 196, // expr_anglestoright
|
||||
S_expr_anglestoup = 197, // expr_anglestoup
|
||||
S_expr_vectorscale = 198, // expr_vectorscale
|
||||
S_expr_isdefined = 199, // expr_isdefined
|
||||
S_expr_reference = 200, // expr_reference
|
||||
S_expr_array = 201, // expr_array
|
||||
S_expr_field = 202, // expr_field
|
||||
S_expr_size = 203, // expr_size
|
||||
S_expr_paren = 204, // expr_paren
|
||||
S_expr_object = 205, // expr_object
|
||||
S_expr_empty_array = 206, // expr_empty_array
|
||||
S_expr_undefined = 207, // expr_undefined
|
||||
S_expr_game = 208, // expr_game
|
||||
S_expr_self = 209, // expr_self
|
||||
S_expr_anim = 210, // expr_anim
|
||||
S_expr_level = 211, // expr_level
|
||||
S_expr_animation = 212, // expr_animation
|
||||
S_expr_identifier_nosize = 213, // expr_identifier_nosize
|
||||
S_expr_identifier = 214, // expr_identifier
|
||||
S_expr_path = 215, // expr_path
|
||||
S_expr_istring = 216, // expr_istring
|
||||
S_expr_string = 217, // expr_string
|
||||
S_expr_vector = 218, // expr_vector
|
||||
S_expr_hash = 219, // expr_hash
|
||||
S_expr_float = 220, // expr_float
|
||||
S_expr_integer = 221, // expr_integer
|
||||
S_expr_false = 222, // expr_false
|
||||
S_expr_true = 223 // expr_true
|
||||
S_expr_negate = 173, // expr_negate
|
||||
S_expr_not = 174, // expr_not
|
||||
S_expr_call = 175, // expr_call
|
||||
S_expr_method = 176, // expr_method
|
||||
S_expr_function = 177, // expr_function
|
||||
S_expr_pointer = 178, // expr_pointer
|
||||
S_expr_parameters = 179, // expr_parameters
|
||||
S_expr_arguments = 180, // expr_arguments
|
||||
S_expr_arguments_no_empty = 181, // expr_arguments_no_empty
|
||||
S_expr_getnextarraykey = 182, // expr_getnextarraykey
|
||||
S_expr_getfirstarraykey = 183, // expr_getfirstarraykey
|
||||
S_expr_getdvarcoloralpha = 184, // expr_getdvarcoloralpha
|
||||
S_expr_getdvarcolorblue = 185, // expr_getdvarcolorblue
|
||||
S_expr_getdvarcolorgreen = 186, // expr_getdvarcolorgreen
|
||||
S_expr_getdvarcolorred = 187, // expr_getdvarcolorred
|
||||
S_expr_getdvarvector = 188, // expr_getdvarvector
|
||||
S_expr_getdvarfloat = 189, // expr_getdvarfloat
|
||||
S_expr_getdvarint = 190, // expr_getdvarint
|
||||
S_expr_getdvar = 191, // expr_getdvar
|
||||
S_expr_gettime = 192, // expr_gettime
|
||||
S_expr_abs = 193, // expr_abs
|
||||
S_expr_vectortoangles = 194, // expr_vectortoangles
|
||||
S_expr_angleclamp180 = 195, // expr_angleclamp180
|
||||
S_expr_anglestoforward = 196, // expr_anglestoforward
|
||||
S_expr_anglestoright = 197, // expr_anglestoright
|
||||
S_expr_anglestoup = 198, // expr_anglestoup
|
||||
S_expr_vectorscale = 199, // expr_vectorscale
|
||||
S_expr_isdefined = 200, // expr_isdefined
|
||||
S_expr_reference = 201, // expr_reference
|
||||
S_expr_array = 202, // expr_array
|
||||
S_expr_field = 203, // expr_field
|
||||
S_expr_size = 204, // expr_size
|
||||
S_expr_paren = 205, // expr_paren
|
||||
S_expr_object = 206, // expr_object
|
||||
S_expr_empty_array = 207, // expr_empty_array
|
||||
S_expr_undefined = 208, // expr_undefined
|
||||
S_expr_game = 209, // expr_game
|
||||
S_expr_self = 210, // expr_self
|
||||
S_expr_anim = 211, // expr_anim
|
||||
S_expr_level = 212, // expr_level
|
||||
S_expr_animation = 213, // expr_animation
|
||||
S_expr_identifier_nosize = 214, // expr_identifier_nosize
|
||||
S_expr_identifier = 215, // expr_identifier
|
||||
S_expr_path = 216, // expr_path
|
||||
S_expr_istring = 217, // expr_istring
|
||||
S_expr_string = 218, // expr_string
|
||||
S_expr_vector = 219, // expr_vector
|
||||
S_expr_hash = 220, // expr_hash
|
||||
S_expr_float = 221, // expr_float
|
||||
S_expr_integer = 222, // expr_integer
|
||||
S_expr_false = 223, // expr_false
|
||||
S_expr_true = 224 // expr_true
|
||||
};
|
||||
};
|
||||
|
||||
@ -1311,6 +1315,10 @@ namespace xsk { namespace arc { namespace t6 {
|
||||
value.move< ast::expr_method::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (std::move (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (std::move (that.value));
|
||||
break;
|
||||
@ -2071,6 +2079,20 @@ namespace xsk { namespace arc { namespace t6 {
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_negate::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
, value (std::move (v))
|
||||
, location (std::move (l))
|
||||
{}
|
||||
#else
|
||||
basic_symbol (typename Base::kind_type t, const ast::expr_negate::ptr& v, const location_type& l)
|
||||
: Base (t)
|
||||
, value (v)
|
||||
, location (l)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
|
||||
: Base (t)
|
||||
@ -2854,6 +2876,10 @@ switch (yykind)
|
||||
value.template destroy< ast::expr_method::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.template destroy< ast::expr_negate::ptr > ();
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.template destroy< ast::expr_not::ptr > ();
|
||||
break;
|
||||
@ -5163,7 +5189,7 @@ switch (yykind)
|
||||
// YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
|
||||
// Performed when YYTABLE does not specify something else to do. Zero
|
||||
// means the default is an error.
|
||||
static const unsigned char yydefact_[];
|
||||
static const short yydefact_[];
|
||||
|
||||
// YYPGOTO[NTERM-NUM].
|
||||
static const short yypgoto_[];
|
||||
@ -5427,8 +5453,8 @@ switch (yykind)
|
||||
/// Constants.
|
||||
enum
|
||||
{
|
||||
yylast_ = 3411, ///< Last index in yytable_.
|
||||
yynnts_ = 98, ///< Number of nonterminal symbols.
|
||||
yylast_ = 3562, ///< Last index in yytable_.
|
||||
yynnts_ = 99, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 22 ///< Termination state number.
|
||||
};
|
||||
|
||||
@ -5626,6 +5652,10 @@ switch (yykind)
|
||||
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.copy< ast::expr_negate::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
|
||||
break;
|
||||
@ -6005,6 +6035,10 @@ switch (yykind)
|
||||
value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_negate: // expr_negate
|
||||
value.move< ast::expr_negate::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
|
||||
case symbol_kind::S_expr_not: // expr_not
|
||||
value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
|
||||
break;
|
||||
@ -6249,7 +6283,7 @@ switch (yykind)
|
||||
|
||||
#line 13 "parser.ypp"
|
||||
} } } // xsk::arc::t6
|
||||
#line 6253 "parser.hpp"
|
||||
#line 6287 "parser.hpp"
|
||||
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ auto choose_resolver_file_name(uint32_t id, game& game) -> std::string
|
||||
switch (game)
|
||||
{
|
||||
case game::IW5:
|
||||
return iw5::resolver::file_name(static_cast<std::uint16_t>(id));
|
||||
return iw5::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||
case game::IW6:
|
||||
return iw6::resolver::file_name(static_cast<std::uint16_t>(id));
|
||||
case game::IW7:
|
||||
@ -113,9 +113,9 @@ auto choose_resolver_file_name(uint32_t id, game& game) -> std::string
|
||||
case game::S4:
|
||||
return s4::resolver::file_name(id);
|
||||
case game::H1:
|
||||
return h1::resolver::file_name(static_cast<std::uint16_t>(id));
|
||||
return h1::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||
case game::H2:
|
||||
return h2::resolver::file_name(static_cast<std::uint16_t>(id));
|
||||
return h2::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@ -250,7 +250,7 @@ void disassemble_file(game game, std::string file)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << e.what() << " at " << file << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +394,7 @@ void decompile_file(game game, std::string file)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << e.what() << " at " << file << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ void disassemble_file(game game, const std::filesystem::path& file)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << e.what() << " at " << file.string() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ void decompile_file(game game, const std::filesystem::path& file)
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << e.what() << " at " << file.string() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +292,9 @@ expr_call::expr_call(const location& loc, ast::call call) : node(kind::expr_call
|
||||
expr_complement::expr_complement(expr rvalue) : node(kind::expr_complement), rvalue(std::move(rvalue)) {}
|
||||
expr_complement::expr_complement(const location& loc, expr rvalue) : node(kind::expr_complement, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
expr_negate::expr_negate(expr rvalue) : node(kind::expr_negate), rvalue(std::move(rvalue)) {}
|
||||
expr_negate::expr_negate(const location& loc, expr rvalue) : node(kind::expr_negate, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
expr_not::expr_not(expr rvalue) : node(kind::expr_not), rvalue(std::move(rvalue)) {}
|
||||
expr_not::expr_not(const location& loc, expr rvalue) : node(kind::expr_not, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
@ -806,6 +809,11 @@ auto expr_complement::print() const -> std::string
|
||||
return "~" + rvalue.print();
|
||||
}
|
||||
|
||||
auto expr_negate::print() const -> std::string
|
||||
{
|
||||
return "-" + rvalue.print();
|
||||
}
|
||||
|
||||
auto expr_not::print() const -> std::string
|
||||
{
|
||||
return "!" + rvalue.print();
|
||||
@ -1694,6 +1702,7 @@ expr::~expr()
|
||||
case kind::expr_method: as_method.~unique_ptr(); return;
|
||||
case kind::expr_call: as_call.~unique_ptr(); return;
|
||||
case kind::expr_complement: as_complement.~unique_ptr(); return;
|
||||
case kind::expr_negate: as_negate.~unique_ptr(); return;
|
||||
case kind::expr_not: as_not.~unique_ptr(); return;
|
||||
case kind::expr_add: as_add.~unique_ptr(); return;
|
||||
case kind::expr_sub: as_sub.~unique_ptr(); return;
|
||||
|
@ -59,6 +59,7 @@ enum class kind
|
||||
expr_method,
|
||||
expr_call,
|
||||
expr_complement,
|
||||
expr_negate,
|
||||
expr_not,
|
||||
expr_add,
|
||||
expr_sub,
|
||||
@ -189,6 +190,7 @@ struct expr_function;
|
||||
struct expr_method;
|
||||
struct expr_call;
|
||||
struct expr_complement;
|
||||
struct expr_negate;
|
||||
struct expr_not;
|
||||
struct expr_binary;
|
||||
struct expr_add;
|
||||
@ -341,6 +343,7 @@ union expr
|
||||
std::unique_ptr<expr_method> as_method;
|
||||
std::unique_ptr<expr_call> as_call;
|
||||
std::unique_ptr<expr_complement> as_complement;
|
||||
std::unique_ptr<expr_negate> as_negate;
|
||||
std::unique_ptr<expr_not> as_not;
|
||||
std::unique_ptr<expr_binary> as_binary;
|
||||
std::unique_ptr<expr_add> as_add;
|
||||
@ -1051,6 +1054,17 @@ struct expr_complement : public node
|
||||
auto print() const -> std::string override;
|
||||
};
|
||||
|
||||
struct expr_negate : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_negate>;
|
||||
|
||||
expr rvalue;
|
||||
|
||||
expr_negate(expr rvalue);
|
||||
expr_negate(const location& loc, expr rvalue);
|
||||
auto print() const -> std::string override;
|
||||
};
|
||||
|
||||
struct expr_not : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_not>;
|
||||
|
@ -206,6 +206,9 @@ expr_field::expr_field(const location& loc, expr obj, expr_identifier::ptr field
|
||||
expr_array::expr_array(expr obj, expr key) : node(kind::expr_array), obj(std::move(obj)), key(std::move(key)) {}
|
||||
expr_array::expr_array(const location& loc, expr obj, expr key) : node(kind::expr_array, loc), obj(std::move(obj)), key(std::move(key)) {}
|
||||
|
||||
expr_tuple::expr_tuple() : node(kind::expr_tuple) {}
|
||||
expr_tuple::expr_tuple(const location& loc) : node(kind::expr_tuple, loc) {}
|
||||
|
||||
expr_reference::expr_reference(expr_path::ptr path, expr_identifier::ptr name) : node(kind::expr_reference), path(std::move(path)), name(std::move(name)) {}
|
||||
expr_reference::expr_reference(const location& loc, expr_path::ptr path, expr_identifier::ptr name) : node(kind::expr_reference, loc), path(std::move(path)), name(std::move(name)) {}
|
||||
|
||||
@ -239,6 +242,9 @@ expr_call::expr_call(const location& loc, ast::call call) : node(kind::expr_call
|
||||
expr_complement::expr_complement(expr rvalue) : node(kind::expr_complement), rvalue(std::move(rvalue)) {}
|
||||
expr_complement::expr_complement(const location& loc, expr rvalue) : node(kind::expr_complement, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
expr_negate::expr_negate(expr rvalue) : node(kind::expr_negate), rvalue(std::move(rvalue)) {}
|
||||
expr_negate::expr_negate(const location& loc, expr rvalue) : node(kind::expr_negate, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
expr_not::expr_not(expr rvalue) : node(kind::expr_not), rvalue(std::move(rvalue)) {}
|
||||
expr_not::expr_not(const location& loc, expr rvalue) : node(kind::expr_not, loc), rvalue(std::move(rvalue)) {}
|
||||
|
||||
@ -603,6 +609,19 @@ auto expr_array::print() const -> std::string
|
||||
return obj.print() + "[" + key.print() + "]";
|
||||
}
|
||||
|
||||
auto expr_tuple::print() const -> std::string
|
||||
{
|
||||
std::string data = "[";
|
||||
|
||||
for (const auto& entry : list)
|
||||
{
|
||||
data += " " + entry.print();
|
||||
data += (&entry != &list.back()) ? "," : " ";
|
||||
}
|
||||
|
||||
return data += "]";
|
||||
}
|
||||
|
||||
auto expr_reference::print() const -> std::string
|
||||
{
|
||||
return path->print() + "::" + name->print();
|
||||
@ -693,6 +712,11 @@ auto expr_complement::print() const -> std::string
|
||||
return "~" + rvalue.print();
|
||||
}
|
||||
|
||||
auto expr_negate::print() const -> std::string
|
||||
{
|
||||
return "-" + rvalue.print();
|
||||
}
|
||||
|
||||
auto expr_not::print() const -> std::string
|
||||
{
|
||||
return "!" + rvalue.print();
|
||||
@ -1568,6 +1592,7 @@ expr::~expr()
|
||||
case kind::expr_size: as_size.~unique_ptr(); return;
|
||||
case kind::expr_field: as_field.~unique_ptr(); return;
|
||||
case kind::expr_array: as_array.~unique_ptr(); return;
|
||||
case kind::expr_tuple: as_tuple.~unique_ptr(); return;
|
||||
case kind::expr_reference: as_reference.~unique_ptr(); return;
|
||||
case kind::expr_arguments: as_arguments.~unique_ptr(); return;
|
||||
case kind::expr_parameters: as_parameters.~unique_ptr(); return;
|
||||
@ -1577,6 +1602,7 @@ expr::~expr()
|
||||
case kind::expr_method: as_method.~unique_ptr(); return;
|
||||
case kind::expr_call: as_call.~unique_ptr(); return;
|
||||
case kind::expr_complement: as_complement.~unique_ptr(); return;
|
||||
case kind::expr_negate: as_negate.~unique_ptr(); return;
|
||||
case kind::expr_not: as_not.~unique_ptr(); return;
|
||||
case kind::expr_add: as_add.~unique_ptr(); return;
|
||||
case kind::expr_sub: as_sub.~unique_ptr(); return;
|
||||
|
@ -33,6 +33,7 @@ enum class kind
|
||||
expr_size,
|
||||
expr_field,
|
||||
expr_array,
|
||||
expr_tuple,
|
||||
expr_reference,
|
||||
expr_istrue,
|
||||
expr_isdefined,
|
||||
@ -44,6 +45,7 @@ enum class kind
|
||||
expr_method,
|
||||
expr_call,
|
||||
expr_complement,
|
||||
expr_negate,
|
||||
expr_not,
|
||||
expr_add,
|
||||
expr_sub,
|
||||
@ -151,6 +153,7 @@ struct expr_paren;
|
||||
struct expr_size;
|
||||
struct expr_field;
|
||||
struct expr_array;
|
||||
struct expr_tuple;
|
||||
struct expr_reference;
|
||||
struct expr_istrue;
|
||||
struct expr_isdefined;
|
||||
@ -162,6 +165,7 @@ struct expr_function;
|
||||
struct expr_method;
|
||||
struct expr_call;
|
||||
struct expr_complement;
|
||||
struct expr_negate;
|
||||
struct expr_not;
|
||||
struct expr_binary;
|
||||
struct expr_add;
|
||||
@ -290,6 +294,7 @@ union expr
|
||||
std::unique_ptr<expr_size> as_size;
|
||||
std::unique_ptr<expr_field> as_field;
|
||||
std::unique_ptr<expr_array> as_array;
|
||||
std::unique_ptr<expr_tuple> as_tuple;
|
||||
std::unique_ptr<expr_reference> as_reference;
|
||||
std::unique_ptr<expr_istrue> as_istrue;
|
||||
std::unique_ptr<expr_isdefined> as_isdefined;
|
||||
@ -301,6 +306,7 @@ union expr
|
||||
std::unique_ptr<expr_method> as_method;
|
||||
std::unique_ptr<expr_call> as_call;
|
||||
std::unique_ptr<expr_complement> as_complement;
|
||||
std::unique_ptr<expr_negate> as_negate;
|
||||
std::unique_ptr<expr_not> as_not;
|
||||
std::unique_ptr<expr_binary> as_binary;
|
||||
std::unique_ptr<expr_add> as_add;
|
||||
@ -715,6 +721,18 @@ struct expr_array : public node
|
||||
friend bool operator==(const expr_array& lhs, const expr_array& rhs);
|
||||
};
|
||||
|
||||
struct expr_tuple : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_tuple>;
|
||||
|
||||
std::vector<expr> list;
|
||||
ast::expr temp;
|
||||
|
||||
expr_tuple();
|
||||
expr_tuple(const location& loc);
|
||||
auto print() const -> std::string override;
|
||||
};
|
||||
|
||||
struct expr_reference : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_reference>;
|
||||
@ -843,6 +861,17 @@ struct expr_complement : public node
|
||||
auto print() const -> std::string override;
|
||||
};
|
||||
|
||||
struct expr_negate : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_negate>;
|
||||
|
||||
expr rvalue;
|
||||
|
||||
expr_negate(expr rvalue);
|
||||
expr_negate(const location& loc, expr rvalue);
|
||||
auto print() const -> std::string override;
|
||||
};
|
||||
|
||||
struct expr_not : public node
|
||||
{
|
||||
using ptr = std::unique_ptr<expr_not>;
|
||||
|
Loading…
Reference in New Issue
Block a user