Compare commits

...

27 Commits

Author SHA1 Message Date
xensik
30352b21a7 fix warning 2022-07-19 14:40:22 +02:00
xensik
0da3653f26 support old compiler shenanigans 2022-07-19 13:57:32 +02:00
xensik
628749631b finish decompiler loop statements 2022-07-19 13:50:12 +02:00
xensik
18db7e071a kekw 2022-07-19 13:49:13 +02:00
xensik
15f76542b1 add h2 foreach tokens 2022-07-19 13:49:05 +02:00
xensik
73ed709fed fix h2 jump offsets 2022-07-19 13:48:08 +02:00
xensik
4fec6cda20 h1 files mapped 2022-07-18 18:13:57 +02:00
xensik
66b5c82840 more iw5 symbols 2022-07-17 20:13:28 +02:00
xensik
a16c70bd54 decompiler support for tuples 2022-07-17 13:49:31 +02:00
xensik
328961ee83 improve decompiler empty blocks & do-while bug 2022-07-16 20:58:59 +02:00
xensik
8e5cea1af7 update h2 symbols 2022-07-16 19:57:50 +02:00
xensik
4d6d9916bf update README 2022-07-16 19:55:31 +02:00
xensik
1a5e39fa0e more functions mapping 2022-07-16 10:44:31 +02:00
xensik
de254a1293 update h1 symbols 2022-07-16 09:21:11 +02:00
xensik
dcff855efb more iw5 sp symbols 2022-07-15 16:32:40 +02:00
xensik
bbce74f47a improve decompiler last stmt detection, loop locals 2022-07-15 16:31:05 +02:00
xensik
2c0a5dce18 update gitignore 2022-07-15 16:16:01 +02:00
xensik
89e34cd3a1 fix warnings 2022-07-14 21:23:29 +02:00
xensik
7eed6f45f8 fix decompiler bugs (inf loops, waittillmatch) 2022-07-14 21:17:59 +02:00
xensik
5eb63e3284 improve iw5 decompilation 2022-07-14 19:04:16 +02:00
xensik
05fc8a7421 prepare iw5 sp/so symbols 2022-07-14 15:31:58 +02:00
xensik
ec91109cc3 impl negate expression properly 2022-06-15 17:06:58 +02:00
xensik
0ec0b4d6f5 [IW] added negative variable expression 2022-06-08 12:05:16 +02:00
xensik
6a0419b5bf [T6] added negative variable expression 2022-06-06 15:32:01 +02:00
xensik
f53fb4fe47 t6: fix decompiler loop bug 2022-05-24 20:11:47 +02:00
dependabot[bot]
b6777295a1 Bump deps/zlib from 53ce271 to 21767c6
Bumps [deps/zlib](https://github.com/madler/zlib) from `53ce271` to `21767c6`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](53ce271311...21767c654d)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-24 16:48:57 +02:00
Xenxo Espasandín
b1ad170030 Create dependabot.yml 2022-05-24 16:40:24 +02:00
91 changed files with 50225 additions and 19614 deletions

7
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10

5
.gitignore vendored
View File

@ -149,6 +149,11 @@ user*.bat
# VScode # VScode
.vscode/ .vscode/
compiled/
decompiled/
assembled/
disassembled/
data/iw5/ data/iw5/
data/iw6/ data/iw6/
data/iw7/ data/iw7/

View File

@ -2,8 +2,10 @@
![license](https://img.shields.io/github/license/xensik/gsc-tool.svg) ![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 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) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/releases)
# GSC Tool # GSC Tool
A utility to compile & decompile IW engine game scripts. A utility to compile & decompile IW engine game scripts.
## Supported Games ## Supported Games
- **IW5** *(Call of Duty: Modern Warfare 3)* - **IW5** *(Call of Duty: Modern Warfare 3)*
- **IW6** *(Call of Duty: Ghosts)* - **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\**** - **T5** *(Call of Duty: Black Ops)* ***\*WIP\****
- **T6** *(Call of Duty: Black Ops II)* - **T6** *(Call of Duty: Black Ops II)*
- **T7** *(Call of Duty: Black Ops III)* ***\*WIP\**** - **T7** *(Call of Duty: Black Ops III)* ***\*WIP\****
## Usage ## Usage
``./gsc-tool.exe <mode> <game> <path>`` ``./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 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 | | Mode |Description | Output |
|:---------|:--------------------------|:------------| |:---------|:--------------------------|:------------|
|`asm` |assemble a `file.gscasm` |`file.gscbin`| |`asm` |assemble a `file.gscasm` |`file.gscbin`|
@ -39,7 +44,13 @@ for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zd
## File Format ## 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). 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``. - 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 ## Credits
This project is based on [*RektInator's* gsc-asm](https://github.com/ZoneTool/gsc-asm). Special thanks to **RektInator**, **JTAG** & **Dasfonia**. This project is based on [*RektInator's* gsc-asm](https://github.com/ZoneTool/gsc-asm). Special thanks to **RektInator**, **JTAG** & **Dasfonia**.
## Disclaimer ## 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. 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

@ -1 +1 @@
Subproject commit 53ce2713117ef2a8ed682d77b944df991c499252 Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -611,6 +612,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -611,6 +612,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -601,6 +602,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -601,6 +602,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -601,6 +602,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -615,6 +616,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -611,6 +612,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -611,6 +612,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -615,6 +616,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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_binary
%type <ast::expr> expr_primitive %type <ast::expr> expr_primitive
%type <ast::expr_complement::ptr> expr_complement %type <ast::expr_complement::ptr> expr_complement
%type <ast::expr_negate::ptr> expr_negate
%type <ast::expr_not::ptr> expr_not %type <ast::expr_not::ptr> expr_not
%type <ast::expr_call::ptr> expr_call %type <ast::expr_call::ptr> expr_call
%type <ast::expr_method::ptr> expr_method %type <ast::expr_method::ptr> expr_method
@ -625,6 +626,7 @@ expr_binary
expr_primitive expr_primitive
: expr_complement { $$.as_node = std::move($1); } : expr_complement { $$.as_node = std::move($1); }
| expr_negate { $$.as_node = std::move($1); }
| expr_not { $$.as_node = std::move($1); } | expr_not { $$.as_node = std::move($1); }
| expr_call { $$.as_node = std::move($1); } | expr_call { $$.as_node = std::move($1); }
| expr_method { $$.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)); } { $$ = 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 expr_not
: NOT expr : NOT expr
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); } { $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }

View File

@ -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]))); 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]); const auto func_id = resolver::token_id(inst->data[1]);
stack_->write<std::uint16_t>(file_id); stack_->write<std::uint16_t>(file_id);

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -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_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_id = stack_->read<std::uint16_t>();
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id); 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

View File

@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace h1 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy62[sizeof (ast::stmt_waitframe::ptr)]; char dummy63[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy63[sizeof (ast::stmt_waittill::ptr)]; char dummy64[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy66[sizeof (ast::stmt_while::ptr)]; char dummy67[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace h1 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy67[sizeof (std::string)]; char dummy68[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 159, // expr_binary
S_expr_primitive = 160, // expr_primitive S_expr_primitive = 160, // expr_primitive
S_expr_complement = 161, // expr_complement S_expr_complement = 161, // expr_complement
S_expr_not = 162, // expr_not S_expr_negate = 162, // expr_negate
S_expr_call = 163, // expr_call S_expr_not = 163, // expr_not
S_expr_method = 164, // expr_method S_expr_call = 164, // expr_call
S_expr_function = 165, // expr_function S_expr_method = 165, // expr_method
S_expr_pointer = 166, // expr_pointer S_expr_function = 166, // expr_function
S_expr_add_array = 167, // expr_add_array S_expr_pointer = 167, // expr_pointer
S_expr_parameters = 168, // expr_parameters S_expr_add_array = 168, // expr_add_array
S_expr_arguments = 169, // expr_arguments S_expr_parameters = 169, // expr_parameters
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty S_expr_arguments = 170, // expr_arguments
S_expr_reference = 171, // expr_reference S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
S_expr_array = 172, // expr_array S_expr_reference = 172, // expr_reference
S_expr_field = 173, // expr_field S_expr_array = 173, // expr_array
S_expr_size = 174, // expr_size S_expr_field = 174, // expr_field
S_expr_paren = 175, // expr_paren S_expr_size = 175, // expr_size
S_expr_object = 176, // expr_object S_expr_paren = 176, // expr_paren
S_expr_thisthread = 177, // expr_thisthread S_expr_object = 177, // expr_object
S_expr_empty_array = 178, // expr_empty_array S_expr_thisthread = 178, // expr_thisthread
S_expr_undefined = 179, // expr_undefined S_expr_empty_array = 179, // expr_empty_array
S_expr_game = 180, // expr_game S_expr_undefined = 180, // expr_undefined
S_expr_self = 181, // expr_self S_expr_game = 181, // expr_game
S_expr_anim = 182, // expr_anim S_expr_self = 182, // expr_self
S_expr_level = 183, // expr_level S_expr_anim = 183, // expr_anim
S_expr_animation = 184, // expr_animation S_expr_level = 184, // expr_level
S_expr_animtree = 185, // expr_animtree S_expr_animation = 185, // expr_animation
S_expr_identifier_nosize = 186, // expr_identifier_nosize S_expr_animtree = 186, // expr_animtree
S_expr_identifier = 187, // expr_identifier S_expr_identifier_nosize = 187, // expr_identifier_nosize
S_expr_path = 188, // expr_path S_expr_identifier = 188, // expr_identifier
S_expr_istring = 189, // expr_istring S_expr_path = 189, // expr_path
S_expr_string = 190, // expr_string S_expr_istring = 190, // expr_istring
S_expr_vector = 191, // expr_vector S_expr_string = 191, // expr_string
S_expr_float = 192, // expr_float S_expr_vector = 192, // expr_vector
S_expr_integer = 193, // expr_integer S_expr_float = 193, // expr_float
S_expr_false = 194, // expr_false S_expr_integer = 194, // expr_integer
S_expr_true = 195 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace h1 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2432,6 +2454,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4813,8 +4839,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2251, ///< Last index in yytable_. yylast_ = 2419, ///< Last index in yytable_.
yynnts_ = 83, ///< Number of nonterminal symbols. yynnts_ = 84, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4948,6 +4974,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5266,6 +5296,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5513,7 +5547,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::h1 } } } // xsk::gsc::h1
#line 5517 "parser.hpp" #line 5551 "parser.hpp"

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,6 @@ public:
static auto method_id(const std::string& name) -> std::uint16_t; static auto method_id(const std::string& name) -> std::uint16_t;
static auto method_name(std::uint16_t id) -> std::string; 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_id(const std::string& name) -> std::uint16_t;
static auto token_name(std::uint16_t id) -> std::string; static auto token_name(std::uint16_t id) -> std::string;

View File

@ -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]))); 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]); const auto func_id = resolver::token_id(inst->data[1]);
stack_->write<std::uint16_t>(file_id); 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 = {}; std::array<std::uint8_t, 4> bytes = {};
offset = (offset << 10) >> 8; offset = (offset << 8) >> 8;
*reinterpret_cast<std::int32_t*>(bytes.data()) = offset; *reinterpret_cast<std::int32_t*>(bytes.data()) = offset;

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -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_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_id = stack_->read<std::uint16_t>();
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id); 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()); auto offset = *reinterpret_cast<std::int32_t*>(bytes.data());
offset = (offset << 8) >> 10; offset = (offset << 8) >> 8;
return offset; return offset;
} }

File diff suppressed because it is too large Load Diff

View File

@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace h2 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy62[sizeof (ast::stmt_waitframe::ptr)]; char dummy63[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy63[sizeof (ast::stmt_waittill::ptr)]; char dummy64[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy66[sizeof (ast::stmt_while::ptr)]; char dummy67[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace h2 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy67[sizeof (std::string)]; char dummy68[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 159, // expr_binary
S_expr_primitive = 160, // expr_primitive S_expr_primitive = 160, // expr_primitive
S_expr_complement = 161, // expr_complement S_expr_complement = 161, // expr_complement
S_expr_not = 162, // expr_not S_expr_negate = 162, // expr_negate
S_expr_call = 163, // expr_call S_expr_not = 163, // expr_not
S_expr_method = 164, // expr_method S_expr_call = 164, // expr_call
S_expr_function = 165, // expr_function S_expr_method = 165, // expr_method
S_expr_pointer = 166, // expr_pointer S_expr_function = 166, // expr_function
S_expr_add_array = 167, // expr_add_array S_expr_pointer = 167, // expr_pointer
S_expr_parameters = 168, // expr_parameters S_expr_add_array = 168, // expr_add_array
S_expr_arguments = 169, // expr_arguments S_expr_parameters = 169, // expr_parameters
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty S_expr_arguments = 170, // expr_arguments
S_expr_reference = 171, // expr_reference S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
S_expr_array = 172, // expr_array S_expr_reference = 172, // expr_reference
S_expr_field = 173, // expr_field S_expr_array = 173, // expr_array
S_expr_size = 174, // expr_size S_expr_field = 174, // expr_field
S_expr_paren = 175, // expr_paren S_expr_size = 175, // expr_size
S_expr_object = 176, // expr_object S_expr_paren = 176, // expr_paren
S_expr_thisthread = 177, // expr_thisthread S_expr_object = 177, // expr_object
S_expr_empty_array = 178, // expr_empty_array S_expr_thisthread = 178, // expr_thisthread
S_expr_undefined = 179, // expr_undefined S_expr_empty_array = 179, // expr_empty_array
S_expr_game = 180, // expr_game S_expr_undefined = 180, // expr_undefined
S_expr_self = 181, // expr_self S_expr_game = 181, // expr_game
S_expr_anim = 182, // expr_anim S_expr_self = 182, // expr_self
S_expr_level = 183, // expr_level S_expr_anim = 183, // expr_anim
S_expr_animation = 184, // expr_animation S_expr_level = 184, // expr_level
S_expr_animtree = 185, // expr_animtree S_expr_animation = 185, // expr_animation
S_expr_identifier_nosize = 186, // expr_identifier_nosize S_expr_animtree = 186, // expr_animtree
S_expr_identifier = 187, // expr_identifier S_expr_identifier_nosize = 187, // expr_identifier_nosize
S_expr_path = 188, // expr_path S_expr_identifier = 188, // expr_identifier
S_expr_istring = 189, // expr_istring S_expr_path = 189, // expr_path
S_expr_string = 190, // expr_string S_expr_istring = 190, // expr_istring
S_expr_vector = 191, // expr_vector S_expr_string = 191, // expr_string
S_expr_float = 192, // expr_float S_expr_vector = 192, // expr_vector
S_expr_integer = 193, // expr_integer S_expr_float = 193, // expr_float
S_expr_false = 194, // expr_false S_expr_integer = 194, // expr_integer
S_expr_true = 195 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace h2 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2432,6 +2454,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4813,8 +4839,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2251, ///< Last index in yytable_. yylast_ = 2419, ///< Last index in yytable_.
yynnts_ = 83, ///< Number of nonterminal symbols. yynnts_ = 84, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4948,6 +4974,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5266,6 +5296,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5513,7 +5547,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::h2 } } } // xsk::gsc::h2
#line 5517 "parser.hpp" #line 5551 "parser.hpp"

View File

@ -17,12 +17,10 @@ namespace xsk::gsc::h2
std::unordered_map<std::uint8_t, std::string_view> opcode_map; 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> function_map;
std::unordered_map<std::uint16_t, std::string_view> method_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::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::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> function_map_rev;
std::unordered_map<std::string_view, std::uint16_t> method_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_view, std::uint16_t> token_map_rev;
std::unordered_map<std::string, std::vector<std::uint8_t>> files; std::unordered_map<std::string, std::vector<std::uint8_t>> files;
read_cb_type read_callback = nullptr; 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); 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 auto resolver::token_id(const std::string& name) -> std::uint16_t
{ {
if (name.starts_with("_id_")) 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" }, { 0x02C, "_func_02C" },
{ 0x02D, "_func_02D" }, { 0x02D, "_func_02D" },
{ 0x02E, "_func_02E" }, { 0x02E, "_func_02E" },
{ 0x02F, "_func_02F" }, { 0x02F, "isdefined" },
{ 0x030, "_func_030" }, { 0x030, "_func_030" },
{ 0x031, "_func_031" }, { 0x031, "_func_031" },
{ 0x032, "_func_032" }, { 0x032, "_func_032" },
@ -876,7 +845,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 800> function_list
{ 0x1BC, "_func_1BC" }, { 0x1BC, "_func_1BC" },
{ 0x1BD, "_func_1BD" }, { 0x1BD, "_func_1BD" },
{ 0x1BE, "_func_1BE" }, { 0x1BE, "_func_1BE" },
{ 0x1BF, "_func_1BF" }, { 0x1BF, "getnextarraykey" },
{ 0x1C0, "_func_1C0" }, { 0x1C0, "_func_1C0" },
{ 0x1C1, "_func_1C1" }, { 0x1C1, "_func_1C1" },
{ 0x1C2, "_func_1C2" }, { 0x1C2, "_func_1C2" },
@ -903,7 +872,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 800> function_list
{ 0x1D7, "_func_1D7" }, { 0x1D7, "_func_1D7" },
{ 0x1D8, "_func_1D8" }, { 0x1D8, "_func_1D8" },
{ 0x1D9, "_func_1D9" }, { 0x1D9, "_func_1D9" },
{ 0x1DA, "_func_1DA" }, { 0x1DA, "getfirstarraykey" },
{ 0x1DB, "_func_1DB" }, { 0x1DB, "_func_1DB" },
{ 0x1DC, "_func_1DC" }, { 0x1DC, "_func_1DC" },
{ 0x1DD, "_func_1DD" }, { 0x1DD, "_func_1DD" },
@ -2727,11 +2696,6 @@ const std::array<std::pair<std::uint16_t, const char*>, 1491> method_list
{ 0x85D2, "_meth_85D2" }, { 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 const std::array<std::pair<std::uint16_t, const char*>, 5> token_list
{{ {{
{ 0x0000, "" }, { 0x0000, "" },
@ -2755,8 +2719,6 @@ struct __init__
function_map_rev.reserve(function_list.size()); function_map_rev.reserve(function_list.size());
method_map.reserve(method_list.size()); method_map.reserve(method_list.size());
method_map_rev.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.reserve(token_list.size());
token_map_rev.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 }); 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) for (const auto& entry : token_list)
{ {
token_map.insert({ entry.first, entry.second }); token_map.insert({ entry.first, entry.second });

View File

@ -129,7 +129,6 @@ void assembler::assemble(const std::string& file, std::vector<function::ptr>& fu
functions_ = std::move(funcs); functions_ = std::move(funcs);
script_->write<std::uint8_t>(static_cast<std::uint8_t>(opcode::OP_End)); script_->write<std::uint8_t>(static_cast<std::uint8_t>(opcode::OP_End));
stack_->write<std::uint32_t>(0x62727568);
for (const auto& func : functions_) 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]))); 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]); const auto func_id = resolver::token_id(inst->data[1]);
stack_->write<std::uint16_t>(file_id); stack_->write<std::uint16_t>(file_id);

View File

@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -82,6 +82,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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); decompile_while(block, start, end);
return; return;
} }
else if (find_location_reference(block, 0, start, ref2)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -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_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_id = stack_->read<std::uint16_t>();
const auto func_name = func_id == 0 ? stack_->read_c_string() : resolver::token_name(func_id); 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

View File

@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw5 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waittill // stmt_waittill
char dummy62[sizeof (ast::stmt_waittill::ptr)]; char dummy63[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy65[sizeof (ast::stmt_while::ptr)]; char dummy66[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw5 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy66[sizeof (std::string)]; char dummy67[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 157, // expr_binary
S_expr_primitive = 158, // expr_primitive S_expr_primitive = 158, // expr_primitive
S_expr_complement = 159, // expr_complement S_expr_complement = 159, // expr_complement
S_expr_not = 160, // expr_not S_expr_negate = 160, // expr_negate
S_expr_call = 161, // expr_call S_expr_not = 161, // expr_not
S_expr_method = 162, // expr_method S_expr_call = 162, // expr_call
S_expr_function = 163, // expr_function S_expr_method = 163, // expr_method
S_expr_pointer = 164, // expr_pointer S_expr_function = 164, // expr_function
S_expr_add_array = 165, // expr_add_array S_expr_pointer = 165, // expr_pointer
S_expr_parameters = 166, // expr_parameters S_expr_add_array = 166, // expr_add_array
S_expr_arguments = 167, // expr_arguments S_expr_parameters = 167, // expr_parameters
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty S_expr_arguments = 168, // expr_arguments
S_expr_reference = 169, // expr_reference S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
S_expr_array = 170, // expr_array S_expr_reference = 170, // expr_reference
S_expr_field = 171, // expr_field S_expr_array = 171, // expr_array
S_expr_size = 172, // expr_size S_expr_field = 172, // expr_field
S_expr_paren = 173, // expr_paren S_expr_size = 173, // expr_size
S_expr_object = 174, // expr_object S_expr_paren = 174, // expr_paren
S_expr_thisthread = 175, // expr_thisthread S_expr_object = 175, // expr_object
S_expr_empty_array = 176, // expr_empty_array S_expr_thisthread = 176, // expr_thisthread
S_expr_undefined = 177, // expr_undefined S_expr_empty_array = 177, // expr_empty_array
S_expr_game = 178, // expr_game S_expr_undefined = 178, // expr_undefined
S_expr_self = 179, // expr_self S_expr_game = 179, // expr_game
S_expr_anim = 180, // expr_anim S_expr_self = 180, // expr_self
S_expr_level = 181, // expr_level S_expr_anim = 181, // expr_anim
S_expr_animation = 182, // expr_animation S_expr_level = 182, // expr_level
S_expr_animtree = 183, // expr_animtree S_expr_animation = 183, // expr_animation
S_expr_identifier_nosize = 184, // expr_identifier_nosize S_expr_animtree = 184, // expr_animtree
S_expr_identifier = 185, // expr_identifier S_expr_identifier_nosize = 185, // expr_identifier_nosize
S_expr_path = 186, // expr_path S_expr_identifier = 186, // expr_identifier
S_expr_istring = 187, // expr_istring S_expr_path = 187, // expr_path
S_expr_string = 188, // expr_string S_expr_istring = 188, // expr_istring
S_expr_vector = 189, // expr_vector S_expr_string = 189, // expr_string
S_expr_float = 190, // expr_float S_expr_vector = 190, // expr_vector
S_expr_integer = 191, // expr_integer S_expr_float = 191, // expr_float
S_expr_false = 192, // expr_false S_expr_integer = 192, // expr_integer
S_expr_true = 193 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw5 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2408,6 +2430,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4770,8 +4796,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2303, ///< Last index in yytable_. yylast_ = 2363, ///< Last index in yytable_.
yynnts_ = 82, ///< Number of nonterminal symbols. yynnts_ = 83, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4905,6 +4931,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5219,6 +5249,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5462,7 +5496,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::iw5 } } } // xsk::gsc::iw5
#line 5466 "parser.hpp" #line 5500 "parser.hpp"

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,6 @@ public:
static auto method_id(const std::string& name) -> std::uint16_t; static auto method_id(const std::string& name) -> std::uint16_t;
static auto method_name(std::uint16_t id) -> std::string; 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_id(const std::string& name) -> std::uint16_t;
static auto token_name(std::uint16_t id) -> std::string; static auto token_name(std::uint16_t id) -> std::string;

View File

@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -82,6 +82,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw6 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waittill // stmt_waittill
char dummy62[sizeof (ast::stmt_waittill::ptr)]; char dummy63[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy65[sizeof (ast::stmt_while::ptr)]; char dummy66[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw6 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy66[sizeof (std::string)]; char dummy67[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 157, // expr_binary
S_expr_primitive = 158, // expr_primitive S_expr_primitive = 158, // expr_primitive
S_expr_complement = 159, // expr_complement S_expr_complement = 159, // expr_complement
S_expr_not = 160, // expr_not S_expr_negate = 160, // expr_negate
S_expr_call = 161, // expr_call S_expr_not = 161, // expr_not
S_expr_method = 162, // expr_method S_expr_call = 162, // expr_call
S_expr_function = 163, // expr_function S_expr_method = 163, // expr_method
S_expr_pointer = 164, // expr_pointer S_expr_function = 164, // expr_function
S_expr_add_array = 165, // expr_add_array S_expr_pointer = 165, // expr_pointer
S_expr_parameters = 166, // expr_parameters S_expr_add_array = 166, // expr_add_array
S_expr_arguments = 167, // expr_arguments S_expr_parameters = 167, // expr_parameters
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty S_expr_arguments = 168, // expr_arguments
S_expr_reference = 169, // expr_reference S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
S_expr_array = 170, // expr_array S_expr_reference = 170, // expr_reference
S_expr_field = 171, // expr_field S_expr_array = 171, // expr_array
S_expr_size = 172, // expr_size S_expr_field = 172, // expr_field
S_expr_paren = 173, // expr_paren S_expr_size = 173, // expr_size
S_expr_object = 174, // expr_object S_expr_paren = 174, // expr_paren
S_expr_thisthread = 175, // expr_thisthread S_expr_object = 175, // expr_object
S_expr_empty_array = 176, // expr_empty_array S_expr_thisthread = 176, // expr_thisthread
S_expr_undefined = 177, // expr_undefined S_expr_empty_array = 177, // expr_empty_array
S_expr_game = 178, // expr_game S_expr_undefined = 178, // expr_undefined
S_expr_self = 179, // expr_self S_expr_game = 179, // expr_game
S_expr_anim = 180, // expr_anim S_expr_self = 180, // expr_self
S_expr_level = 181, // expr_level S_expr_anim = 181, // expr_anim
S_expr_animation = 182, // expr_animation S_expr_level = 182, // expr_level
S_expr_animtree = 183, // expr_animtree S_expr_animation = 183, // expr_animation
S_expr_identifier_nosize = 184, // expr_identifier_nosize S_expr_animtree = 184, // expr_animtree
S_expr_identifier = 185, // expr_identifier S_expr_identifier_nosize = 185, // expr_identifier_nosize
S_expr_path = 186, // expr_path S_expr_identifier = 186, // expr_identifier
S_expr_istring = 187, // expr_istring S_expr_path = 187, // expr_path
S_expr_string = 188, // expr_string S_expr_istring = 188, // expr_istring
S_expr_vector = 189, // expr_vector S_expr_string = 189, // expr_string
S_expr_float = 190, // expr_float S_expr_vector = 190, // expr_vector
S_expr_integer = 191, // expr_integer S_expr_float = 191, // expr_float
S_expr_false = 192, // expr_false S_expr_integer = 192, // expr_integer
S_expr_true = 193 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw6 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2408,6 +2430,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4770,8 +4796,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2303, ///< Last index in yytable_. yylast_ = 2363, ///< Last index in yytable_.
yynnts_ = 82, ///< Number of nonterminal symbols. yynnts_ = 83, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4905,6 +4931,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5219,6 +5249,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5462,7 +5496,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::iw6 } } } // xsk::gsc::iw6
#line 5466 "parser.hpp" #line 5500 "parser.hpp"

View File

@ -938,6 +938,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1251,6 +1254,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -82,6 +82,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1601,7 +1594,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1777,11 +1770,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -505,131 +505,134 @@ namespace xsk { namespace gsc { namespace iw7 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waittill // stmt_waittill
char dummy62[sizeof (ast::stmt_waittill::ptr)]; char dummy63[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy63[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy64[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy64[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy65[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy65[sizeof (ast::stmt_while::ptr)]; char dummy66[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -637,7 +640,7 @@ namespace xsk { namespace gsc { namespace iw7 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy66[sizeof (std::string)]; char dummy67[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 157, // expr_binary
S_expr_primitive = 158, // expr_primitive S_expr_primitive = 158, // expr_primitive
S_expr_complement = 159, // expr_complement S_expr_complement = 159, // expr_complement
S_expr_not = 160, // expr_not S_expr_negate = 160, // expr_negate
S_expr_call = 161, // expr_call S_expr_not = 161, // expr_not
S_expr_method = 162, // expr_method S_expr_call = 162, // expr_call
S_expr_function = 163, // expr_function S_expr_method = 163, // expr_method
S_expr_pointer = 164, // expr_pointer S_expr_function = 164, // expr_function
S_expr_add_array = 165, // expr_add_array S_expr_pointer = 165, // expr_pointer
S_expr_parameters = 166, // expr_parameters S_expr_add_array = 166, // expr_add_array
S_expr_arguments = 167, // expr_arguments S_expr_parameters = 167, // expr_parameters
S_expr_arguments_no_empty = 168, // expr_arguments_no_empty S_expr_arguments = 168, // expr_arguments
S_expr_reference = 169, // expr_reference S_expr_arguments_no_empty = 169, // expr_arguments_no_empty
S_expr_array = 170, // expr_array S_expr_reference = 170, // expr_reference
S_expr_field = 171, // expr_field S_expr_array = 171, // expr_array
S_expr_size = 172, // expr_size S_expr_field = 172, // expr_field
S_expr_paren = 173, // expr_paren S_expr_size = 173, // expr_size
S_expr_object = 174, // expr_object S_expr_paren = 174, // expr_paren
S_expr_thisthread = 175, // expr_thisthread S_expr_object = 175, // expr_object
S_expr_empty_array = 176, // expr_empty_array S_expr_thisthread = 176, // expr_thisthread
S_expr_undefined = 177, // expr_undefined S_expr_empty_array = 177, // expr_empty_array
S_expr_game = 178, // expr_game S_expr_undefined = 178, // expr_undefined
S_expr_self = 179, // expr_self S_expr_game = 179, // expr_game
S_expr_anim = 180, // expr_anim S_expr_self = 180, // expr_self
S_expr_level = 181, // expr_level S_expr_anim = 181, // expr_anim
S_expr_animation = 182, // expr_animation S_expr_level = 182, // expr_level
S_expr_animtree = 183, // expr_animtree S_expr_animation = 183, // expr_animation
S_expr_identifier_nosize = 184, // expr_identifier_nosize S_expr_animtree = 184, // expr_animtree
S_expr_identifier = 185, // expr_identifier S_expr_identifier_nosize = 185, // expr_identifier_nosize
S_expr_path = 186, // expr_path S_expr_identifier = 186, // expr_identifier
S_expr_istring = 187, // expr_istring S_expr_path = 187, // expr_path
S_expr_string = 188, // expr_string S_expr_istring = 188, // expr_istring
S_expr_vector = 189, // expr_vector S_expr_string = 189, // expr_string
S_expr_float = 190, // expr_float S_expr_vector = 190, // expr_vector
S_expr_integer = 191, // expr_integer S_expr_float = 191, // expr_float
S_expr_false = 192, // expr_false S_expr_integer = 192, // expr_integer
S_expr_true = 193 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1689,6 +1697,20 @@ namespace xsk { namespace gsc { namespace iw7 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2408,6 +2430,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4770,8 +4796,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2303, ///< Last index in yytable_. yylast_ = 2363, ///< Last index in yytable_.
yynnts_ = 82, ///< Number of nonterminal symbols. yynnts_ = 83, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4905,6 +4931,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5219,6 +5249,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5462,7 +5496,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::iw7 } } } // xsk::gsc::iw7
#line 5466 "parser.hpp" #line 5500 "parser.hpp"

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1283,6 +1286,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1814,11 +1807,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -511,134 +511,137 @@ namespace xsk { namespace gsc { namespace iw8 {
// expr_method // expr_method
char dummy26[sizeof (ast::expr_method::ptr)]; char dummy26[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy27[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy27[sizeof (ast::expr_not::ptr)]; char dummy28[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy28[sizeof (ast::expr_parameters::ptr)]; char dummy29[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy29[sizeof (ast::expr_paren::ptr)]; char dummy30[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy30[sizeof (ast::expr_path::ptr)]; char dummy31[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy31[sizeof (ast::expr_reference::ptr)]; char dummy32[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy32[sizeof (ast::expr_self::ptr)]; char dummy33[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy33[sizeof (ast::expr_size::ptr)]; char dummy34[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy34[sizeof (ast::expr_string::ptr)]; char dummy35[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy35[sizeof (ast::expr_thisthread::ptr)]; char dummy36[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy36[sizeof (ast::expr_true::ptr)]; char dummy37[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy37[sizeof (ast::expr_undefined::ptr)]; char dummy38[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy38[sizeof (ast::expr_vector::ptr)]; char dummy39[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy39[sizeof (ast::include::ptr)]; char dummy40[sizeof (ast::include::ptr)];
// program // program
char dummy40[sizeof (ast::program::ptr)]; char dummy41[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy41[sizeof (ast::stmt)]; char dummy42[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy42[sizeof (ast::stmt_assign::ptr)]; char dummy43[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy43[sizeof (ast::stmt_break::ptr)]; char dummy44[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy44[sizeof (ast::stmt_breakpoint::ptr)]; char dummy45[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy45[sizeof (ast::stmt_call::ptr)]; char dummy46[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy46[sizeof (ast::stmt_case::ptr)]; char dummy47[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy47[sizeof (ast::stmt_continue::ptr)]; char dummy48[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy48[sizeof (ast::stmt_default::ptr)]; char dummy49[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy49[sizeof (ast::stmt_dev::ptr)]; char dummy50[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy50[sizeof (ast::stmt_dowhile::ptr)]; char dummy51[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy51[sizeof (ast::stmt_endon::ptr)]; char dummy52[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy52[sizeof (ast::stmt_expr::ptr)]; char dummy53[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy53[sizeof (ast::stmt_for::ptr)]; char dummy54[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy54[sizeof (ast::stmt_foreach::ptr)]; char dummy55[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy55[sizeof (ast::stmt_if::ptr)]; char dummy56[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy56[sizeof (ast::stmt_ifelse::ptr)]; char dummy57[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy57[sizeof (ast::stmt_list::ptr)]; char dummy58[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy58[sizeof (ast::stmt_notify::ptr)]; char dummy59[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy59[sizeof (ast::stmt_prof_begin::ptr)]; char dummy60[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy60[sizeof (ast::stmt_prof_end::ptr)]; char dummy61[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy61[sizeof (ast::stmt_return::ptr)]; char dummy62[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy62[sizeof (ast::stmt_switch::ptr)]; char dummy63[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy63[sizeof (ast::stmt_wait::ptr)]; char dummy64[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy64[sizeof (ast::stmt_waitframe::ptr)]; char dummy65[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy65[sizeof (ast::stmt_waittill::ptr)]; char dummy66[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy66[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy67[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy67[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy68[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy68[sizeof (ast::stmt_while::ptr)]; char dummy69[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -646,7 +649,7 @@ namespace xsk { namespace gsc { namespace iw8 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy69[sizeof (std::string)]; char dummy70[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 161, // expr_binary
S_expr_primitive = 162, // expr_primitive S_expr_primitive = 162, // expr_primitive
S_expr_complement = 163, // expr_complement S_expr_complement = 163, // expr_complement
S_expr_not = 164, // expr_not S_expr_negate = 164, // expr_negate
S_expr_call = 165, // expr_call S_expr_not = 165, // expr_not
S_expr_method = 166, // expr_method S_expr_call = 166, // expr_call
S_expr_function = 167, // expr_function S_expr_method = 167, // expr_method
S_expr_pointer = 168, // expr_pointer S_expr_function = 168, // expr_function
S_expr_add_array = 169, // expr_add_array S_expr_pointer = 169, // expr_pointer
S_expr_parameters = 170, // expr_parameters S_expr_add_array = 170, // expr_add_array
S_expr_arguments = 171, // expr_arguments S_expr_parameters = 171, // expr_parameters
S_expr_arguments_no_empty = 172, // expr_arguments_no_empty S_expr_arguments = 172, // expr_arguments
S_expr_isdefined = 173, // expr_isdefined S_expr_arguments_no_empty = 173, // expr_arguments_no_empty
S_expr_istrue = 174, // expr_istrue S_expr_isdefined = 174, // expr_isdefined
S_expr_reference = 175, // expr_reference S_expr_istrue = 175, // expr_istrue
S_expr_array = 176, // expr_array S_expr_reference = 176, // expr_reference
S_expr_field = 177, // expr_field S_expr_array = 177, // expr_array
S_expr_size = 178, // expr_size S_expr_field = 178, // expr_field
S_expr_paren = 179, // expr_paren S_expr_size = 179, // expr_size
S_expr_object = 180, // expr_object S_expr_paren = 180, // expr_paren
S_expr_thisthread = 181, // expr_thisthread S_expr_object = 181, // expr_object
S_expr_empty_array = 182, // expr_empty_array S_expr_thisthread = 182, // expr_thisthread
S_expr_undefined = 183, // expr_undefined S_expr_empty_array = 183, // expr_empty_array
S_expr_game = 184, // expr_game S_expr_undefined = 184, // expr_undefined
S_expr_self = 185, // expr_self S_expr_game = 185, // expr_game
S_expr_anim = 186, // expr_anim S_expr_self = 186, // expr_self
S_expr_level = 187, // expr_level S_expr_anim = 187, // expr_anim
S_expr_animation = 188, // expr_animation S_expr_level = 188, // expr_level
S_expr_animtree = 189, // expr_animtree S_expr_animation = 189, // expr_animation
S_expr_identifier_nosize = 190, // expr_identifier_nosize S_expr_animtree = 190, // expr_animtree
S_expr_identifier = 191, // expr_identifier S_expr_identifier_nosize = 191, // expr_identifier_nosize
S_expr_path = 192, // expr_path S_expr_identifier = 192, // expr_identifier
S_expr_istring = 193, // expr_istring S_expr_path = 193, // expr_path
S_expr_string = 194, // expr_string S_expr_istring = 194, // expr_istring
S_expr_vector = 195, // expr_vector S_expr_string = 195, // expr_string
S_expr_float = 196, // expr_float S_expr_vector = 196, // expr_vector
S_expr_integer = 197, // expr_integer S_expr_float = 197, // expr_float
S_expr_false = 198, // expr_false S_expr_integer = 198, // expr_integer
S_expr_true = 199 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1747,6 +1755,20 @@ namespace xsk { namespace gsc { namespace iw8 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2488,6 +2510,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4899,8 +4925,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2278, ///< Last index in yytable_. yylast_ = 2481, ///< Last index in yytable_.
yynnts_ = 85, ///< Number of nonterminal symbols. yynnts_ = 86, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -5042,6 +5068,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5368,6 +5398,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5615,7 +5649,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::iw8 } } } // xsk::gsc::iw8
#line 5619 "parser.hpp" #line 5653 "parser.hpp"

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1783,11 +1776,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace s1 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy62[sizeof (ast::stmt_waitframe::ptr)]; char dummy63[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy63[sizeof (ast::stmt_waittill::ptr)]; char dummy64[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy66[sizeof (ast::stmt_while::ptr)]; char dummy67[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace s1 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy67[sizeof (std::string)]; char dummy68[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 159, // expr_binary
S_expr_primitive = 160, // expr_primitive S_expr_primitive = 160, // expr_primitive
S_expr_complement = 161, // expr_complement S_expr_complement = 161, // expr_complement
S_expr_not = 162, // expr_not S_expr_negate = 162, // expr_negate
S_expr_call = 163, // expr_call S_expr_not = 163, // expr_not
S_expr_method = 164, // expr_method S_expr_call = 164, // expr_call
S_expr_function = 165, // expr_function S_expr_method = 165, // expr_method
S_expr_pointer = 166, // expr_pointer S_expr_function = 166, // expr_function
S_expr_add_array = 167, // expr_add_array S_expr_pointer = 167, // expr_pointer
S_expr_parameters = 168, // expr_parameters S_expr_add_array = 168, // expr_add_array
S_expr_arguments = 169, // expr_arguments S_expr_parameters = 169, // expr_parameters
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty S_expr_arguments = 170, // expr_arguments
S_expr_reference = 171, // expr_reference S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
S_expr_array = 172, // expr_array S_expr_reference = 172, // expr_reference
S_expr_field = 173, // expr_field S_expr_array = 173, // expr_array
S_expr_size = 174, // expr_size S_expr_field = 174, // expr_field
S_expr_paren = 175, // expr_paren S_expr_size = 175, // expr_size
S_expr_object = 176, // expr_object S_expr_paren = 176, // expr_paren
S_expr_thisthread = 177, // expr_thisthread S_expr_object = 177, // expr_object
S_expr_empty_array = 178, // expr_empty_array S_expr_thisthread = 178, // expr_thisthread
S_expr_undefined = 179, // expr_undefined S_expr_empty_array = 179, // expr_empty_array
S_expr_game = 180, // expr_game S_expr_undefined = 180, // expr_undefined
S_expr_self = 181, // expr_self S_expr_game = 181, // expr_game
S_expr_anim = 182, // expr_anim S_expr_self = 182, // expr_self
S_expr_level = 183, // expr_level S_expr_anim = 183, // expr_anim
S_expr_animation = 184, // expr_animation S_expr_level = 184, // expr_level
S_expr_animtree = 185, // expr_animtree S_expr_animation = 185, // expr_animation
S_expr_identifier_nosize = 186, // expr_identifier_nosize S_expr_animtree = 186, // expr_animtree
S_expr_identifier = 187, // expr_identifier S_expr_identifier_nosize = 187, // expr_identifier_nosize
S_expr_path = 188, // expr_path S_expr_identifier = 188, // expr_identifier
S_expr_istring = 189, // expr_istring S_expr_path = 189, // expr_path
S_expr_string = 190, // expr_string S_expr_istring = 190, // expr_istring
S_expr_vector = 191, // expr_vector S_expr_string = 191, // expr_string
S_expr_float = 192, // expr_float S_expr_vector = 192, // expr_vector
S_expr_integer = 193, // expr_integer S_expr_float = 193, // expr_float
S_expr_false = 194, // expr_false S_expr_integer = 194, // expr_integer
S_expr_true = 195 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace s1 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2432,6 +2454,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4813,8 +4839,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2251, ///< Last index in yytable_. yylast_ = 2419, ///< Last index in yytable_.
yynnts_ = 83, ///< Number of nonterminal symbols. yynnts_ = 84, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4948,6 +4974,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5266,6 +5296,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5513,7 +5547,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::s1 } } } // xsk::gsc::s1
#line 5517 "parser.hpp" #line 5551 "parser.hpp"

View File

@ -464,10 +464,10 @@ const std::array<std::pair<std::uint16_t, const char*>, 735> function_list
{ 0x020, "badplace_cylinder" }, { 0x020, "badplace_cylinder" },
{ 0x021, "badplace_arc" }, { 0x021, "badplace_arc" },
{ 0x022, "badplace_brush" }, { 0x022, "badplace_brush" },
{ 0x023, "_func_023" }, // SP 0x140261020 { 0x023, "clearallcorpses" }, // SP 0x140261020
{ 0x024, "_func_024" }, // SP 0x14027EA80 { 0x024, "setturretnode" }, // SP 0x14027EA80
{ 0x025, "_func_025" }, // SP 0x14027EB20 { 0x025, "unsetturretnode" }, // SP 0x14027EB20
{ 0x026, "_func_026" }, // SP 0x14027E9B0 { 0x026, "setnodepriority" }, // SP 0x14027E9B0
{ 0x027, "_func_027" }, // SP 0x14027E870 { 0x027, "_func_027" }, // SP 0x14027E870
{ 0x028, "_func_028" }, // empty { 0x028, "_func_028" }, // empty
{ 0x029, "_func_029" }, // empty { 0x029, "_func_029" }, // empty
@ -492,7 +492,7 @@ const std::array<std::pair<std::uint16_t, const char*>, 735> function_list
{ 0x03C, "getdvarvector" }, { 0x03C, "getdvarvector" },
{ 0x03D, "gettime" }, { 0x03D, "gettime" },
{ 0x03E, "gettimeutc" }, { 0x03E, "gettimeutc" },
{ 0x03F, "_func_03F" }, // SP 0x14024B9C0, MP 0x1403156A0 { 0x03F, "getradiometricunit" },
{ 0x040, "getentbynum" }, { 0x040, "getentbynum" },
{ 0x041, "getweaponmodel" }, { 0x041, "getweaponmodel" },
{ 0x042, "getculldist" }, { 0x042, "getculldist" },

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1259,6 +1262,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1790,11 +1783,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -505,134 +505,137 @@ namespace xsk { namespace gsc { namespace s2 {
// expr_method // expr_method
char dummy24[sizeof (ast::expr_method::ptr)]; char dummy24[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy25[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy25[sizeof (ast::expr_not::ptr)]; char dummy26[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy26[sizeof (ast::expr_parameters::ptr)]; char dummy27[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy27[sizeof (ast::expr_paren::ptr)]; char dummy28[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy28[sizeof (ast::expr_path::ptr)]; char dummy29[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy29[sizeof (ast::expr_reference::ptr)]; char dummy30[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy30[sizeof (ast::expr_self::ptr)]; char dummy31[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy31[sizeof (ast::expr_size::ptr)]; char dummy32[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy32[sizeof (ast::expr_string::ptr)]; char dummy33[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy33[sizeof (ast::expr_thisthread::ptr)]; char dummy34[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy34[sizeof (ast::expr_true::ptr)]; char dummy35[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy35[sizeof (ast::expr_undefined::ptr)]; char dummy36[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy36[sizeof (ast::expr_vector::ptr)]; char dummy37[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy37[sizeof (ast::include::ptr)]; char dummy38[sizeof (ast::include::ptr)];
// program // program
char dummy38[sizeof (ast::program::ptr)]; char dummy39[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy39[sizeof (ast::stmt)]; char dummy40[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy40[sizeof (ast::stmt_assign::ptr)]; char dummy41[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy41[sizeof (ast::stmt_break::ptr)]; char dummy42[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy42[sizeof (ast::stmt_breakpoint::ptr)]; char dummy43[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy43[sizeof (ast::stmt_call::ptr)]; char dummy44[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy44[sizeof (ast::stmt_case::ptr)]; char dummy45[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy45[sizeof (ast::stmt_continue::ptr)]; char dummy46[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy46[sizeof (ast::stmt_default::ptr)]; char dummy47[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy47[sizeof (ast::stmt_dev::ptr)]; char dummy48[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy48[sizeof (ast::stmt_dowhile::ptr)]; char dummy49[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy49[sizeof (ast::stmt_endon::ptr)]; char dummy50[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy50[sizeof (ast::stmt_expr::ptr)]; char dummy51[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy51[sizeof (ast::stmt_for::ptr)]; char dummy52[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy52[sizeof (ast::stmt_foreach::ptr)]; char dummy53[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy53[sizeof (ast::stmt_if::ptr)]; char dummy54[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy54[sizeof (ast::stmt_ifelse::ptr)]; char dummy55[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy55[sizeof (ast::stmt_list::ptr)]; char dummy56[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy56[sizeof (ast::stmt_notify::ptr)]; char dummy57[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy57[sizeof (ast::stmt_prof_begin::ptr)]; char dummy58[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy58[sizeof (ast::stmt_prof_end::ptr)]; char dummy59[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy59[sizeof (ast::stmt_return::ptr)]; char dummy60[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy60[sizeof (ast::stmt_switch::ptr)]; char dummy61[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy61[sizeof (ast::stmt_wait::ptr)]; char dummy62[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy62[sizeof (ast::stmt_waitframe::ptr)]; char dummy63[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy63[sizeof (ast::stmt_waittill::ptr)]; char dummy64[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy64[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy65[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy65[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy66[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy66[sizeof (ast::stmt_while::ptr)]; char dummy67[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -640,7 +643,7 @@ namespace xsk { namespace gsc { namespace s2 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy67[sizeof (std::string)]; char dummy68[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 159, // expr_binary
S_expr_primitive = 160, // expr_primitive S_expr_primitive = 160, // expr_primitive
S_expr_complement = 161, // expr_complement S_expr_complement = 161, // expr_complement
S_expr_not = 162, // expr_not S_expr_negate = 162, // expr_negate
S_expr_call = 163, // expr_call S_expr_not = 163, // expr_not
S_expr_method = 164, // expr_method S_expr_call = 164, // expr_call
S_expr_function = 165, // expr_function S_expr_method = 165, // expr_method
S_expr_pointer = 166, // expr_pointer S_expr_function = 166, // expr_function
S_expr_add_array = 167, // expr_add_array S_expr_pointer = 167, // expr_pointer
S_expr_parameters = 168, // expr_parameters S_expr_add_array = 168, // expr_add_array
S_expr_arguments = 169, // expr_arguments S_expr_parameters = 169, // expr_parameters
S_expr_arguments_no_empty = 170, // expr_arguments_no_empty S_expr_arguments = 170, // expr_arguments
S_expr_reference = 171, // expr_reference S_expr_arguments_no_empty = 171, // expr_arguments_no_empty
S_expr_array = 172, // expr_array S_expr_reference = 172, // expr_reference
S_expr_field = 173, // expr_field S_expr_array = 173, // expr_array
S_expr_size = 174, // expr_size S_expr_field = 174, // expr_field
S_expr_paren = 175, // expr_paren S_expr_size = 175, // expr_size
S_expr_object = 176, // expr_object S_expr_paren = 176, // expr_paren
S_expr_thisthread = 177, // expr_thisthread S_expr_object = 177, // expr_object
S_expr_empty_array = 178, // expr_empty_array S_expr_thisthread = 178, // expr_thisthread
S_expr_undefined = 179, // expr_undefined S_expr_empty_array = 179, // expr_empty_array
S_expr_game = 180, // expr_game S_expr_undefined = 180, // expr_undefined
S_expr_self = 181, // expr_self S_expr_game = 181, // expr_game
S_expr_anim = 182, // expr_anim S_expr_self = 182, // expr_self
S_expr_level = 183, // expr_level S_expr_anim = 183, // expr_anim
S_expr_animation = 184, // expr_animation S_expr_level = 184, // expr_level
S_expr_animtree = 185, // expr_animtree S_expr_animation = 185, // expr_animation
S_expr_identifier_nosize = 186, // expr_identifier_nosize S_expr_animtree = 186, // expr_animtree
S_expr_identifier = 187, // expr_identifier S_expr_identifier_nosize = 187, // expr_identifier_nosize
S_expr_path = 188, // expr_path S_expr_identifier = 188, // expr_identifier
S_expr_istring = 189, // expr_istring S_expr_path = 189, // expr_path
S_expr_string = 190, // expr_string S_expr_istring = 190, // expr_istring
S_expr_vector = 191, // expr_vector S_expr_string = 191, // expr_string
S_expr_float = 192, // expr_float S_expr_vector = 192, // expr_vector
S_expr_integer = 193, // expr_integer S_expr_float = 193, // expr_float
S_expr_false = 194, // expr_false S_expr_integer = 194, // expr_integer
S_expr_true = 195 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1699,6 +1707,20 @@ namespace xsk { namespace gsc { namespace s2 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2432,6 +2454,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4813,8 +4839,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2251, ///< Last index in yytable_. yylast_ = 2419, ///< Last index in yytable_.
yynnts_ = 83, ///< Number of nonterminal symbols. yynnts_ = 84, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -4948,6 +4974,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5266,6 +5296,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5513,7 +5547,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::s2 } } } // xsk::gsc::s2
#line 5517 "parser.hpp" #line 5551 "parser.hpp"

View File

@ -946,6 +946,9 @@ void compiler::emit_expr(const ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement, blk); emit_expr_complement(expr.as_complement, blk);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate, blk);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not, blk); emit_expr_not(expr.as_not, blk);
break; break;
@ -1283,6 +1286,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr, const
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr, const block::ptr& blk)
{ {
emit_expr(expr->rvalue, blk); emit_expr(expr->rvalue, blk);

View File

@ -83,6 +83,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr, const block::ptr& blk); 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_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_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_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(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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, const block::ptr& blk, bool is_stmt);

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return // remove last return
stmt->list.pop_back(); 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); blocks_.push_back(blk);
decompile_statements(stmt); 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(); auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
loc = expr.as_node->loc(); 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(); auto node = std::move(stack_.top()); stack_.pop();
loc = node->loc(); 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 obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop(); auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc(); 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1607,7 +1600,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break; break;
case opcode::OP_ClearLocalVariableFieldCached0: 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))); func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
} }
break; break;
@ -1814,11 +1807,14 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt); decompile_switches(stmt);
decompile_ifelses(stmt); decompile_ifelses(stmt);
decompile_aborts(stmt); decompile_aborts(stmt);
decompile_tuples(stmt);
} }
void decompiler::decompile_infinites(const ast::stmt_list::ptr& 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) 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) 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); 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); 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 block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_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
decompile_if(stmt, i, j); 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) else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{ {
decompile_if(stmt, i, j); 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) 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); // if block with empty else
}
} }
else else
{ {
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if! 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) 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 != "") if (blocks_.back().loc_break != "" || blocks_.back().loc_continue != "")
{ {
decompile_if(stmt, i, j); // inside a loop cant be last 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)); auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt)); 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) if (block->list.at(start - index) == ast::kind::stmt_assign)
{ {
auto ref = block->list.at(end).loc().label(); 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)) 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)) 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); decompile_while(block, start, end);
return; 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() + start); // remove 'switch'
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' 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: case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk); process_expr_add_array(expr.as_add_array, blk);
break; 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: case ast::kind::expr_size:
process_expr_size(expr.as_size, blk); process_expr_size(expr.as_size, blk);
break; 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: case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk); process_expr_local(expr.as_identifier, blk);
break; break;
case ast::kind::expr_vector: case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk); 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); 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->key, blk);
process_expr(expr->obj, 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); 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; return;
} }

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt); void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(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_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_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_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); 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_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_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_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_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk); void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::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_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_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk); void process_var_access(ast::expr& expr, const block::ptr& blk);

File diff suppressed because it is too large Load Diff

View File

@ -511,134 +511,137 @@ namespace xsk { namespace gsc { namespace s4 {
// expr_method // expr_method
char dummy26[sizeof (ast::expr_method::ptr)]; char dummy26[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy27[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy27[sizeof (ast::expr_not::ptr)]; char dummy28[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy28[sizeof (ast::expr_parameters::ptr)]; char dummy29[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy29[sizeof (ast::expr_paren::ptr)]; char dummy30[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy30[sizeof (ast::expr_path::ptr)]; char dummy31[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy31[sizeof (ast::expr_reference::ptr)]; char dummy32[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy32[sizeof (ast::expr_self::ptr)]; char dummy33[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy33[sizeof (ast::expr_size::ptr)]; char dummy34[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy34[sizeof (ast::expr_string::ptr)]; char dummy35[sizeof (ast::expr_string::ptr)];
// expr_thisthread // expr_thisthread
char dummy35[sizeof (ast::expr_thisthread::ptr)]; char dummy36[sizeof (ast::expr_thisthread::ptr)];
// expr_true // expr_true
char dummy36[sizeof (ast::expr_true::ptr)]; char dummy37[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy37[sizeof (ast::expr_undefined::ptr)]; char dummy38[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy38[sizeof (ast::expr_vector::ptr)]; char dummy39[sizeof (ast::expr_vector::ptr)];
// include // include
char dummy39[sizeof (ast::include::ptr)]; char dummy40[sizeof (ast::include::ptr)];
// program // program
char dummy40[sizeof (ast::program::ptr)]; char dummy41[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy41[sizeof (ast::stmt)]; char dummy42[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy42[sizeof (ast::stmt_assign::ptr)]; char dummy43[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy43[sizeof (ast::stmt_break::ptr)]; char dummy44[sizeof (ast::stmt_break::ptr)];
// stmt_breakpoint // stmt_breakpoint
char dummy44[sizeof (ast::stmt_breakpoint::ptr)]; char dummy45[sizeof (ast::stmt_breakpoint::ptr)];
// stmt_call // stmt_call
char dummy45[sizeof (ast::stmt_call::ptr)]; char dummy46[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy46[sizeof (ast::stmt_case::ptr)]; char dummy47[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy47[sizeof (ast::stmt_continue::ptr)]; char dummy48[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy48[sizeof (ast::stmt_default::ptr)]; char dummy49[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy49[sizeof (ast::stmt_dev::ptr)]; char dummy50[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy50[sizeof (ast::stmt_dowhile::ptr)]; char dummy51[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy51[sizeof (ast::stmt_endon::ptr)]; char dummy52[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy52[sizeof (ast::stmt_expr::ptr)]; char dummy53[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy53[sizeof (ast::stmt_for::ptr)]; char dummy54[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy54[sizeof (ast::stmt_foreach::ptr)]; char dummy55[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy55[sizeof (ast::stmt_if::ptr)]; char dummy56[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy56[sizeof (ast::stmt_ifelse::ptr)]; char dummy57[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy57[sizeof (ast::stmt_list::ptr)]; char dummy58[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy58[sizeof (ast::stmt_notify::ptr)]; char dummy59[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy59[sizeof (ast::stmt_prof_begin::ptr)]; char dummy60[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy60[sizeof (ast::stmt_prof_end::ptr)]; char dummy61[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy61[sizeof (ast::stmt_return::ptr)]; char dummy62[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy62[sizeof (ast::stmt_switch::ptr)]; char dummy63[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy63[sizeof (ast::stmt_wait::ptr)]; char dummy64[sizeof (ast::stmt_wait::ptr)];
// stmt_waitframe // stmt_waitframe
char dummy64[sizeof (ast::stmt_waitframe::ptr)]; char dummy65[sizeof (ast::stmt_waitframe::ptr)];
// stmt_waittill // stmt_waittill
char dummy65[sizeof (ast::stmt_waittill::ptr)]; char dummy66[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy66[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy67[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy67[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy68[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy68[sizeof (ast::stmt_while::ptr)]; char dummy69[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -646,7 +649,7 @@ namespace xsk { namespace gsc { namespace s4 {
// "localized string" // "localized string"
// "float" // "float"
// "integer" // "integer"
char dummy69[sizeof (std::string)]; char dummy70[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 161, // expr_binary
S_expr_primitive = 162, // expr_primitive S_expr_primitive = 162, // expr_primitive
S_expr_complement = 163, // expr_complement S_expr_complement = 163, // expr_complement
S_expr_not = 164, // expr_not S_expr_negate = 164, // expr_negate
S_expr_call = 165, // expr_call S_expr_not = 165, // expr_not
S_expr_method = 166, // expr_method S_expr_call = 166, // expr_call
S_expr_function = 167, // expr_function S_expr_method = 167, // expr_method
S_expr_pointer = 168, // expr_pointer S_expr_function = 168, // expr_function
S_expr_add_array = 169, // expr_add_array S_expr_pointer = 169, // expr_pointer
S_expr_parameters = 170, // expr_parameters S_expr_add_array = 170, // expr_add_array
S_expr_arguments = 171, // expr_arguments S_expr_parameters = 171, // expr_parameters
S_expr_arguments_no_empty = 172, // expr_arguments_no_empty S_expr_arguments = 172, // expr_arguments
S_expr_isdefined = 173, // expr_isdefined S_expr_arguments_no_empty = 173, // expr_arguments_no_empty
S_expr_istrue = 174, // expr_istrue S_expr_isdefined = 174, // expr_isdefined
S_expr_reference = 175, // expr_reference S_expr_istrue = 175, // expr_istrue
S_expr_array = 176, // expr_array S_expr_reference = 176, // expr_reference
S_expr_field = 177, // expr_field S_expr_array = 177, // expr_array
S_expr_size = 178, // expr_size S_expr_field = 178, // expr_field
S_expr_paren = 179, // expr_paren S_expr_size = 179, // expr_size
S_expr_object = 180, // expr_object S_expr_paren = 180, // expr_paren
S_expr_thisthread = 181, // expr_thisthread S_expr_object = 181, // expr_object
S_expr_empty_array = 182, // expr_empty_array S_expr_thisthread = 182, // expr_thisthread
S_expr_undefined = 183, // expr_undefined S_expr_empty_array = 183, // expr_empty_array
S_expr_game = 184, // expr_game S_expr_undefined = 184, // expr_undefined
S_expr_self = 185, // expr_self S_expr_game = 185, // expr_game
S_expr_anim = 186, // expr_anim S_expr_self = 186, // expr_self
S_expr_level = 187, // expr_level S_expr_anim = 187, // expr_anim
S_expr_animation = 188, // expr_animation S_expr_level = 188, // expr_level
S_expr_animtree = 189, // expr_animtree S_expr_animation = 189, // expr_animation
S_expr_identifier_nosize = 190, // expr_identifier_nosize S_expr_animtree = 190, // expr_animtree
S_expr_identifier = 191, // expr_identifier S_expr_identifier_nosize = 191, // expr_identifier_nosize
S_expr_path = 192, // expr_path S_expr_identifier = 192, // expr_identifier
S_expr_istring = 193, // expr_istring S_expr_path = 193, // expr_path
S_expr_string = 194, // expr_string S_expr_istring = 194, // expr_istring
S_expr_vector = 195, // expr_vector S_expr_string = 195, // expr_string
S_expr_float = 196, // expr_float S_expr_vector = 196, // expr_vector
S_expr_integer = 197, // expr_integer S_expr_float = 197, // expr_float
S_expr_false = 198, // expr_false S_expr_integer = 198, // expr_integer
S_expr_true = 199 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -1747,6 +1755,20 @@ namespace xsk { namespace gsc { namespace s4 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2488,6 +2510,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -4899,8 +4925,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 2278, ///< Last index in yytable_. yylast_ = 2481, ///< Last index in yytable_.
yynnts_ = 85, ///< Number of nonterminal symbols. yynnts_ = 86, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -5042,6 +5068,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -5368,6 +5398,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -5615,7 +5649,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::gsc::s4 } } } // xsk::gsc::s4
#line 5619 "parser.hpp" #line 5653 "parser.hpp"

View File

@ -813,6 +813,9 @@ void compiler::emit_expr(const ast::expr& expr)
case ast::kind::expr_complement: case ast::kind::expr_complement:
emit_expr_complement(expr.as_complement); emit_expr_complement(expr.as_complement);
break; break;
case ast::kind::expr_negate:
emit_expr_negate(expr.as_negate);
break;
case ast::kind::expr_not: case ast::kind::expr_not:
emit_expr_not(expr.as_not); emit_expr_not(expr.as_not);
break; break;
@ -1163,6 +1166,13 @@ void compiler::emit_expr_complement(const ast::expr_complement::ptr& expr)
emit_opcode(opcode::OP_BoolComplement); 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) void compiler::emit_expr_not(const ast::expr_not::ptr& expr)
{ {
emit_expr(expr->rvalue); emit_expr(expr->rvalue);

View File

@ -80,6 +80,7 @@ private:
void emit_expr_and(const ast::expr_and::ptr& expr); void emit_expr_and(const ast::expr_and::ptr& expr);
void emit_expr_or(const ast::expr_or::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_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_not(const ast::expr_not::ptr& expr);
void emit_expr_call(const ast::expr_call::ptr& expr, bool is_stmt); 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); void emit_expr_call_pointer(const ast::expr_pointer::ptr& expr, bool is_stmt);

View File

@ -263,8 +263,16 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last)
break; break;
case opcode::OP_EvalLocalVariableCached: case opcode::OP_EvalLocalVariableCached:
{ {
auto node = std::make_unique<ast::expr_identifier>(loc, locals_.at(std::stoi(inst->data[0]))); try
stack_.push(std::move(node)); {
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; break;
case opcode::OP_EvalArray: 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) else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
{ {
decompile_infinite(stmt, start, i); decompile_infinite(stmt, start, i);
i = start; i = 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)
{ {
decompile_infinite(stmt, start, i); decompile_infinite(stmt, start, i);
i = start; i = 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)
{ {
@ -1624,7 +1632,7 @@ void decompiler::decompile_infinite(const ast::stmt_list::ptr& stmt, std::size_t
block blk; block blk;
blk.loc_break = last_location_index(stmt, end) ? blocks_.back().loc_end : stmt->list.at(end + 1).loc().label(); 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_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(); auto loc = stmt->list.at(begin).loc();

View File

@ -81,6 +81,8 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
// string list // string list
script_->pos(64); script_->pos(64);
stringlist_.insert({ 0x3E, "" }); // old compiler null string points to header flags
while (script_->pos() < header_.include_offset) while (script_->pos() < header_.include_offset)
{ {
auto pos = script_->pos(); auto pos = script_->pos();
@ -212,7 +214,14 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
} }
else else
{ {
entry->size = (header_.cseg_offset + header_.cseg_size) - entry->offset; 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); script_->pos(entry->offset);

File diff suppressed because it is too large Load Diff

View File

@ -553,131 +553,134 @@ namespace xsk { namespace arc { namespace t6 {
// expr_method // expr_method
char dummy40[sizeof (ast::expr_method::ptr)]; char dummy40[sizeof (ast::expr_method::ptr)];
// expr_negate
char dummy41[sizeof (ast::expr_negate::ptr)];
// expr_not // expr_not
char dummy41[sizeof (ast::expr_not::ptr)]; char dummy42[sizeof (ast::expr_not::ptr)];
// expr_parameters // expr_parameters
char dummy42[sizeof (ast::expr_parameters::ptr)]; char dummy43[sizeof (ast::expr_parameters::ptr)];
// expr_paren // expr_paren
char dummy43[sizeof (ast::expr_paren::ptr)]; char dummy44[sizeof (ast::expr_paren::ptr)];
// expr_path // expr_path
char dummy44[sizeof (ast::expr_path::ptr)]; char dummy45[sizeof (ast::expr_path::ptr)];
// expr_reference // expr_reference
char dummy45[sizeof (ast::expr_reference::ptr)]; char dummy46[sizeof (ast::expr_reference::ptr)];
// expr_self // expr_self
char dummy46[sizeof (ast::expr_self::ptr)]; char dummy47[sizeof (ast::expr_self::ptr)];
// expr_size // expr_size
char dummy47[sizeof (ast::expr_size::ptr)]; char dummy48[sizeof (ast::expr_size::ptr)];
// expr_string // expr_string
char dummy48[sizeof (ast::expr_string::ptr)]; char dummy49[sizeof (ast::expr_string::ptr)];
// expr_true // expr_true
char dummy49[sizeof (ast::expr_true::ptr)]; char dummy50[sizeof (ast::expr_true::ptr)];
// expr_undefined // expr_undefined
char dummy50[sizeof (ast::expr_undefined::ptr)]; char dummy51[sizeof (ast::expr_undefined::ptr)];
// expr_vector // expr_vector
char dummy51[sizeof (ast::expr_vector::ptr)]; char dummy52[sizeof (ast::expr_vector::ptr)];
// expr_vectorscale // expr_vectorscale
char dummy52[sizeof (ast::expr_vectorscale::ptr)]; char dummy53[sizeof (ast::expr_vectorscale::ptr)];
// expr_vectortoangles // expr_vectortoangles
char dummy53[sizeof (ast::expr_vectortoangles::ptr)]; char dummy54[sizeof (ast::expr_vectortoangles::ptr)];
// include // include
char dummy54[sizeof (ast::include::ptr)]; char dummy55[sizeof (ast::include::ptr)];
// program // program
char dummy55[sizeof (ast::program::ptr)]; char dummy56[sizeof (ast::program::ptr)];
// stmt // stmt
// stmt_or_dev // stmt_or_dev
char dummy56[sizeof (ast::stmt)]; char dummy57[sizeof (ast::stmt)];
// stmt_assign // stmt_assign
char dummy57[sizeof (ast::stmt_assign::ptr)]; char dummy58[sizeof (ast::stmt_assign::ptr)];
// stmt_break // stmt_break
char dummy58[sizeof (ast::stmt_break::ptr)]; char dummy59[sizeof (ast::stmt_break::ptr)];
// stmt_call // stmt_call
char dummy59[sizeof (ast::stmt_call::ptr)]; char dummy60[sizeof (ast::stmt_call::ptr)];
// stmt_case // stmt_case
char dummy60[sizeof (ast::stmt_case::ptr)]; char dummy61[sizeof (ast::stmt_case::ptr)];
// stmt_continue // stmt_continue
char dummy61[sizeof (ast::stmt_continue::ptr)]; char dummy62[sizeof (ast::stmt_continue::ptr)];
// stmt_default // stmt_default
char dummy62[sizeof (ast::stmt_default::ptr)]; char dummy63[sizeof (ast::stmt_default::ptr)];
// stmt_dev // stmt_dev
char dummy63[sizeof (ast::stmt_dev::ptr)]; char dummy64[sizeof (ast::stmt_dev::ptr)];
// stmt_dowhile // stmt_dowhile
char dummy64[sizeof (ast::stmt_dowhile::ptr)]; char dummy65[sizeof (ast::stmt_dowhile::ptr)];
// stmt_endon // stmt_endon
char dummy65[sizeof (ast::stmt_endon::ptr)]; char dummy66[sizeof (ast::stmt_endon::ptr)];
// stmt_expr // stmt_expr
char dummy66[sizeof (ast::stmt_expr::ptr)]; char dummy67[sizeof (ast::stmt_expr::ptr)];
// stmt_for // stmt_for
char dummy67[sizeof (ast::stmt_for::ptr)]; char dummy68[sizeof (ast::stmt_for::ptr)];
// stmt_foreach // stmt_foreach
char dummy68[sizeof (ast::stmt_foreach::ptr)]; char dummy69[sizeof (ast::stmt_foreach::ptr)];
// stmt_if // stmt_if
char dummy69[sizeof (ast::stmt_if::ptr)]; char dummy70[sizeof (ast::stmt_if::ptr)];
// stmt_ifelse // stmt_ifelse
char dummy70[sizeof (ast::stmt_ifelse::ptr)]; char dummy71[sizeof (ast::stmt_ifelse::ptr)];
// stmt_list // stmt_list
// stmt_or_dev_list // stmt_or_dev_list
// stmt_block // stmt_block
char dummy71[sizeof (ast::stmt_list::ptr)]; char dummy72[sizeof (ast::stmt_list::ptr)];
// stmt_notify // stmt_notify
char dummy72[sizeof (ast::stmt_notify::ptr)]; char dummy73[sizeof (ast::stmt_notify::ptr)];
// stmt_prof_begin // stmt_prof_begin
char dummy73[sizeof (ast::stmt_prof_begin::ptr)]; char dummy74[sizeof (ast::stmt_prof_begin::ptr)];
// stmt_prof_end // stmt_prof_end
char dummy74[sizeof (ast::stmt_prof_end::ptr)]; char dummy75[sizeof (ast::stmt_prof_end::ptr)];
// stmt_return // stmt_return
char dummy75[sizeof (ast::stmt_return::ptr)]; char dummy76[sizeof (ast::stmt_return::ptr)];
// stmt_switch // stmt_switch
char dummy76[sizeof (ast::stmt_switch::ptr)]; char dummy77[sizeof (ast::stmt_switch::ptr)];
// stmt_wait // stmt_wait
char dummy77[sizeof (ast::stmt_wait::ptr)]; char dummy78[sizeof (ast::stmt_wait::ptr)];
// stmt_waittill // stmt_waittill
char dummy78[sizeof (ast::stmt_waittill::ptr)]; char dummy79[sizeof (ast::stmt_waittill::ptr)];
// stmt_waittillframeend // stmt_waittillframeend
char dummy79[sizeof (ast::stmt_waittillframeend::ptr)]; char dummy80[sizeof (ast::stmt_waittillframeend::ptr)];
// stmt_waittillmatch // stmt_waittillmatch
char dummy80[sizeof (ast::stmt_waittillmatch::ptr)]; char dummy81[sizeof (ast::stmt_waittillmatch::ptr)];
// stmt_while // stmt_while
char dummy81[sizeof (ast::stmt_while::ptr)]; char dummy82[sizeof (ast::stmt_while::ptr)];
// "path" // "path"
// "identifier" // "identifier"
@ -686,7 +689,7 @@ namespace xsk { namespace arc { namespace t6 {
// "hash" // "hash"
// "float" // "float"
// "integer" // "integer"
char dummy82[sizeof (std::string)]; char dummy83[sizeof (std::string)];
}; };
/// The size of the largest semantic type. /// 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_binary = 170, // expr_binary
S_expr_primitive = 171, // expr_primitive S_expr_primitive = 171, // expr_primitive
S_expr_complement = 172, // expr_complement S_expr_complement = 172, // expr_complement
S_expr_not = 173, // expr_not S_expr_negate = 173, // expr_negate
S_expr_call = 174, // expr_call S_expr_not = 174, // expr_not
S_expr_method = 175, // expr_method S_expr_call = 175, // expr_call
S_expr_function = 176, // expr_function S_expr_method = 176, // expr_method
S_expr_pointer = 177, // expr_pointer S_expr_function = 177, // expr_function
S_expr_parameters = 178, // expr_parameters S_expr_pointer = 178, // expr_pointer
S_expr_arguments = 179, // expr_arguments S_expr_parameters = 179, // expr_parameters
S_expr_arguments_no_empty = 180, // expr_arguments_no_empty S_expr_arguments = 180, // expr_arguments
S_expr_getnextarraykey = 181, // expr_getnextarraykey S_expr_arguments_no_empty = 181, // expr_arguments_no_empty
S_expr_getfirstarraykey = 182, // expr_getfirstarraykey S_expr_getnextarraykey = 182, // expr_getnextarraykey
S_expr_getdvarcoloralpha = 183, // expr_getdvarcoloralpha S_expr_getfirstarraykey = 183, // expr_getfirstarraykey
S_expr_getdvarcolorblue = 184, // expr_getdvarcolorblue S_expr_getdvarcoloralpha = 184, // expr_getdvarcoloralpha
S_expr_getdvarcolorgreen = 185, // expr_getdvarcolorgreen S_expr_getdvarcolorblue = 185, // expr_getdvarcolorblue
S_expr_getdvarcolorred = 186, // expr_getdvarcolorred S_expr_getdvarcolorgreen = 186, // expr_getdvarcolorgreen
S_expr_getdvarvector = 187, // expr_getdvarvector S_expr_getdvarcolorred = 187, // expr_getdvarcolorred
S_expr_getdvarfloat = 188, // expr_getdvarfloat S_expr_getdvarvector = 188, // expr_getdvarvector
S_expr_getdvarint = 189, // expr_getdvarint S_expr_getdvarfloat = 189, // expr_getdvarfloat
S_expr_getdvar = 190, // expr_getdvar S_expr_getdvarint = 190, // expr_getdvarint
S_expr_gettime = 191, // expr_gettime S_expr_getdvar = 191, // expr_getdvar
S_expr_abs = 192, // expr_abs S_expr_gettime = 192, // expr_gettime
S_expr_vectortoangles = 193, // expr_vectortoangles S_expr_abs = 193, // expr_abs
S_expr_angleclamp180 = 194, // expr_angleclamp180 S_expr_vectortoangles = 194, // expr_vectortoangles
S_expr_anglestoforward = 195, // expr_anglestoforward S_expr_angleclamp180 = 195, // expr_angleclamp180
S_expr_anglestoright = 196, // expr_anglestoright S_expr_anglestoforward = 196, // expr_anglestoforward
S_expr_anglestoup = 197, // expr_anglestoup S_expr_anglestoright = 197, // expr_anglestoright
S_expr_vectorscale = 198, // expr_vectorscale S_expr_anglestoup = 198, // expr_anglestoup
S_expr_isdefined = 199, // expr_isdefined S_expr_vectorscale = 199, // expr_vectorscale
S_expr_reference = 200, // expr_reference S_expr_isdefined = 200, // expr_isdefined
S_expr_array = 201, // expr_array S_expr_reference = 201, // expr_reference
S_expr_field = 202, // expr_field S_expr_array = 202, // expr_array
S_expr_size = 203, // expr_size S_expr_field = 203, // expr_field
S_expr_paren = 204, // expr_paren S_expr_size = 204, // expr_size
S_expr_object = 205, // expr_object S_expr_paren = 205, // expr_paren
S_expr_empty_array = 206, // expr_empty_array S_expr_object = 206, // expr_object
S_expr_undefined = 207, // expr_undefined S_expr_empty_array = 207, // expr_empty_array
S_expr_game = 208, // expr_game S_expr_undefined = 208, // expr_undefined
S_expr_self = 209, // expr_self S_expr_game = 209, // expr_game
S_expr_anim = 210, // expr_anim S_expr_self = 210, // expr_self
S_expr_level = 211, // expr_level S_expr_anim = 211, // expr_anim
S_expr_animation = 212, // expr_animation S_expr_level = 212, // expr_level
S_expr_identifier_nosize = 213, // expr_identifier_nosize S_expr_animation = 213, // expr_animation
S_expr_identifier = 214, // expr_identifier S_expr_identifier_nosize = 214, // expr_identifier_nosize
S_expr_path = 215, // expr_path S_expr_identifier = 215, // expr_identifier
S_expr_istring = 216, // expr_istring S_expr_path = 216, // expr_path
S_expr_string = 217, // expr_string S_expr_istring = 217, // expr_istring
S_expr_vector = 218, // expr_vector S_expr_string = 218, // expr_string
S_expr_hash = 219, // expr_hash S_expr_vector = 219, // expr_vector
S_expr_float = 220, // expr_float S_expr_hash = 220, // expr_hash
S_expr_integer = 221, // expr_integer S_expr_float = 221, // expr_float
S_expr_false = 222, // expr_false S_expr_integer = 222, // expr_integer
S_expr_true = 223 // expr_true 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)); value.move< ast::expr_method::ptr > (std::move (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (std::move (that.value)); value.move< ast::expr_not::ptr > (std::move (that.value));
break; break;
@ -2071,6 +2079,20 @@ namespace xsk { namespace arc { namespace t6 {
{} {}
#endif #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 #if 201103L <= YY_CPLUSPLUS
basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l) basic_symbol (typename Base::kind_type t, ast::expr_not::ptr&& v, location_type&& l)
: Base (t) : Base (t)
@ -2854,6 +2876,10 @@ switch (yykind)
value.template destroy< ast::expr_method::ptr > (); value.template destroy< ast::expr_method::ptr > ();
break; 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 case symbol_kind::S_expr_not: // expr_not
value.template destroy< ast::expr_not::ptr > (); value.template destroy< ast::expr_not::ptr > ();
break; break;
@ -5163,7 +5189,7 @@ switch (yykind)
// YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
// Performed when YYTABLE does not specify something else to do. Zero // Performed when YYTABLE does not specify something else to do. Zero
// means the default is an error. // means the default is an error.
static const unsigned char yydefact_[]; static const short yydefact_[];
// YYPGOTO[NTERM-NUM]. // YYPGOTO[NTERM-NUM].
static const short yypgoto_[]; static const short yypgoto_[];
@ -5427,8 +5453,8 @@ switch (yykind)
/// Constants. /// Constants.
enum enum
{ {
yylast_ = 3411, ///< Last index in yytable_. yylast_ = 3562, ///< Last index in yytable_.
yynnts_ = 98, ///< Number of nonterminal symbols. yynnts_ = 99, ///< Number of nonterminal symbols.
yyfinal_ = 22 ///< Termination state number. yyfinal_ = 22 ///< Termination state number.
}; };
@ -5626,6 +5652,10 @@ switch (yykind)
value.copy< ast::expr_method::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_method::ptr > (YY_MOVE (that.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.copy< ast::expr_not::ptr > (YY_MOVE (that.value)); value.copy< ast::expr_not::ptr > (YY_MOVE (that.value));
break; break;
@ -6005,6 +6035,10 @@ switch (yykind)
value.move< ast::expr_method::ptr > (YY_MOVE (s.value)); value.move< ast::expr_method::ptr > (YY_MOVE (s.value));
break; 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 case symbol_kind::S_expr_not: // expr_not
value.move< ast::expr_not::ptr > (YY_MOVE (s.value)); value.move< ast::expr_not::ptr > (YY_MOVE (s.value));
break; break;
@ -6249,7 +6283,7 @@ switch (yykind)
#line 13 "parser.ypp" #line 13 "parser.ypp"
} } } // xsk::arc::t6 } } } // xsk::arc::t6
#line 6253 "parser.hpp" #line 6287 "parser.hpp"

View File

@ -99,7 +99,7 @@ auto choose_resolver_file_name(uint32_t id, game& game) -> std::string
switch (game) switch (game)
{ {
case game::IW5: 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: case game::IW6:
return iw6::resolver::file_name(static_cast<std::uint16_t>(id)); return iw6::resolver::file_name(static_cast<std::uint16_t>(id));
case game::IW7: case game::IW7:
@ -113,9 +113,9 @@ auto choose_resolver_file_name(uint32_t id, game& game) -> std::string
case game::S4: case game::S4:
return s4::resolver::file_name(id); return s4::resolver::file_name(id);
case game::H1: 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: 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: default:
return ""; return "";
} }
@ -250,7 +250,7 @@ void disassemble_file(game game, std::string file)
} }
catch (const std::exception& e) 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) 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) 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) catch (const std::exception& e)
{ {
std::cerr << e.what() << '\n'; std::cerr << e.what() << " at " << file.string() << '\n';
} }
} }

View File

@ -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(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_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(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)) {} 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(); return "~" + rvalue.print();
} }
auto expr_negate::print() const -> std::string
{
return "-" + rvalue.print();
}
auto expr_not::print() const -> std::string auto expr_not::print() const -> std::string
{ {
return "!" + rvalue.print(); return "!" + rvalue.print();
@ -1694,6 +1702,7 @@ expr::~expr()
case kind::expr_method: as_method.~unique_ptr(); return; case kind::expr_method: as_method.~unique_ptr(); return;
case kind::expr_call: as_call.~unique_ptr(); return; case kind::expr_call: as_call.~unique_ptr(); return;
case kind::expr_complement: as_complement.~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_not: as_not.~unique_ptr(); return;
case kind::expr_add: as_add.~unique_ptr(); return; case kind::expr_add: as_add.~unique_ptr(); return;
case kind::expr_sub: as_sub.~unique_ptr(); return; case kind::expr_sub: as_sub.~unique_ptr(); return;

View File

@ -59,6 +59,7 @@ enum class kind
expr_method, expr_method,
expr_call, expr_call,
expr_complement, expr_complement,
expr_negate,
expr_not, expr_not,
expr_add, expr_add,
expr_sub, expr_sub,
@ -189,6 +190,7 @@ struct expr_function;
struct expr_method; struct expr_method;
struct expr_call; struct expr_call;
struct expr_complement; struct expr_complement;
struct expr_negate;
struct expr_not; struct expr_not;
struct expr_binary; struct expr_binary;
struct expr_add; struct expr_add;
@ -341,6 +343,7 @@ union expr
std::unique_ptr<expr_method> as_method; std::unique_ptr<expr_method> as_method;
std::unique_ptr<expr_call> as_call; std::unique_ptr<expr_call> as_call;
std::unique_ptr<expr_complement> as_complement; 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_not> as_not;
std::unique_ptr<expr_binary> as_binary; std::unique_ptr<expr_binary> as_binary;
std::unique_ptr<expr_add> as_add; std::unique_ptr<expr_add> as_add;
@ -1051,6 +1054,17 @@ struct expr_complement : public node
auto print() const -> std::string override; 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 struct expr_not : public node
{ {
using ptr = std::unique_ptr<expr_not>; using ptr = std::unique_ptr<expr_not>;

View File

@ -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(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_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(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)) {} 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(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_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(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)) {} 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() + "]"; 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 auto expr_reference::print() const -> std::string
{ {
return path->print() + "::" + name->print(); return path->print() + "::" + name->print();
@ -693,6 +712,11 @@ auto expr_complement::print() const -> std::string
return "~" + rvalue.print(); return "~" + rvalue.print();
} }
auto expr_negate::print() const -> std::string
{
return "-" + rvalue.print();
}
auto expr_not::print() const -> std::string auto expr_not::print() const -> std::string
{ {
return "!" + rvalue.print(); return "!" + rvalue.print();
@ -1568,6 +1592,7 @@ expr::~expr()
case kind::expr_size: as_size.~unique_ptr(); return; case kind::expr_size: as_size.~unique_ptr(); return;
case kind::expr_field: as_field.~unique_ptr(); return; case kind::expr_field: as_field.~unique_ptr(); return;
case kind::expr_array: as_array.~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_reference: as_reference.~unique_ptr(); return;
case kind::expr_arguments: as_arguments.~unique_ptr(); return; case kind::expr_arguments: as_arguments.~unique_ptr(); return;
case kind::expr_parameters: as_parameters.~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_method: as_method.~unique_ptr(); return;
case kind::expr_call: as_call.~unique_ptr(); return; case kind::expr_call: as_call.~unique_ptr(); return;
case kind::expr_complement: as_complement.~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_not: as_not.~unique_ptr(); return;
case kind::expr_add: as_add.~unique_ptr(); return; case kind::expr_add: as_add.~unique_ptr(); return;
case kind::expr_sub: as_sub.~unique_ptr(); return; case kind::expr_sub: as_sub.~unique_ptr(); return;

View File

@ -33,6 +33,7 @@ enum class kind
expr_size, expr_size,
expr_field, expr_field,
expr_array, expr_array,
expr_tuple,
expr_reference, expr_reference,
expr_istrue, expr_istrue,
expr_isdefined, expr_isdefined,
@ -44,6 +45,7 @@ enum class kind
expr_method, expr_method,
expr_call, expr_call,
expr_complement, expr_complement,
expr_negate,
expr_not, expr_not,
expr_add, expr_add,
expr_sub, expr_sub,
@ -151,6 +153,7 @@ struct expr_paren;
struct expr_size; struct expr_size;
struct expr_field; struct expr_field;
struct expr_array; struct expr_array;
struct expr_tuple;
struct expr_reference; struct expr_reference;
struct expr_istrue; struct expr_istrue;
struct expr_isdefined; struct expr_isdefined;
@ -162,6 +165,7 @@ struct expr_function;
struct expr_method; struct expr_method;
struct expr_call; struct expr_call;
struct expr_complement; struct expr_complement;
struct expr_negate;
struct expr_not; struct expr_not;
struct expr_binary; struct expr_binary;
struct expr_add; struct expr_add;
@ -290,6 +294,7 @@ union expr
std::unique_ptr<expr_size> as_size; std::unique_ptr<expr_size> as_size;
std::unique_ptr<expr_field> as_field; std::unique_ptr<expr_field> as_field;
std::unique_ptr<expr_array> as_array; 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_reference> as_reference;
std::unique_ptr<expr_istrue> as_istrue; std::unique_ptr<expr_istrue> as_istrue;
std::unique_ptr<expr_isdefined> as_isdefined; std::unique_ptr<expr_isdefined> as_isdefined;
@ -301,6 +306,7 @@ union expr
std::unique_ptr<expr_method> as_method; std::unique_ptr<expr_method> as_method;
std::unique_ptr<expr_call> as_call; std::unique_ptr<expr_call> as_call;
std::unique_ptr<expr_complement> as_complement; 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_not> as_not;
std::unique_ptr<expr_binary> as_binary; std::unique_ptr<expr_binary> as_binary;
std::unique_ptr<expr_add> as_add; 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); 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 struct expr_reference : public node
{ {
using ptr = std::unique_ptr<expr_reference>; using ptr = std::unique_ptr<expr_reference>;
@ -843,6 +861,17 @@ struct expr_complement : public node
auto print() const -> std::string override; 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 struct expr_not : public node
{ {
using ptr = std::unique_ptr<expr_not>; using ptr = std::unique_ptr<expr_not>;