Skip to content

Commit

Permalink
Initial attempt at implementing switch support
Browse files Browse the repository at this point in the history
  • Loading branch information
Gui-Yom committed Jul 23, 2022
1 parent 778bb79 commit f8f1f3c
Show file tree
Hide file tree
Showing 4 changed files with 344 additions and 139 deletions.
26 changes: 26 additions & 0 deletions data/Switch.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Switch {
static function main() {
var a = 3;
var b = switch (a) {
case 0: a * 2;
case 3: a - 1;
default: a << 2;
}
switch (b) {
case 0: b += 1;
case 1: b += 1;
case 2: b += 1;
//case 4: b += 1;
}
/*
switch (a) {
case -1: b += 1;
case -5: b += 1;
}
var c = "hello";
switch (c) {
case "hello": a += 1;
case "world": a += 1;
}*/
}
}
20 changes: 14 additions & 6 deletions src/decompiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,10 @@ pub enum Statement {
variable: Expr,
assign: Expr,
},
// Call a void function (no assignment)
Call(Call),
/// Return an expression
Return(Expr),
/// Return nothing / early return
ReturnVoid,
/// Expression statement
ExprStatement(Expr),
/// Return an expression or nothing (void)
Return(Option<Expr>),
/// If statement
If {
cond: Expr,
Expand All @@ -273,6 +271,11 @@ pub enum Statement {
Else {
stmts: Vec<Statement>,
},
Switch {
arg: Expr,
default: Vec<Statement>,
cases: Vec<(Expr, Vec<Statement>)>,
},
/// While statement
While {
cond: Expr,
Expand All @@ -282,3 +285,8 @@ pub enum Statement {
Continue,
Throw(Expr),
}

/// Create an expression statement
pub fn stmt(e: Expr) -> Statement {
Statement::ExprStatement(e)
}
27 changes: 22 additions & 5 deletions src/decompiler/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;
use std::fmt::{Display, Formatter};

use crate::decompiler::ast::{
Call, Class, Constant, ConstructorCall, Expr, Method, Operation, Statement,
Class, Constant, ConstructorCall, Expr, Method, Operation, Statement,
};
use crate::types::{Function, RefField, Type};
use crate::Bytecode;
Expand Down Expand Up @@ -245,13 +245,12 @@ impl Statement {
} => {
if *declaration { "var " } else { "" }{disp!(variable)}" = "{disp!(assign)}";"
}
Statement::Call(Call { fun, args }) => {
{disp!(fun)}"("{fmtools::join(", ", args.iter().map(|e| disp!(e)))}");"
Statement::ExprStatement(expr) => {
{disp!(expr)}";"
}
Statement::Return(expr) => {
"return "{disp!(expr)}";"
"return" if let Some(e) = expr { " "{disp!(e)} } ";"
}
Statement::ReturnVoid => "return;",
Statement::If { cond, stmts } => {
"if ("{disp!(cond)}") {\n"
let indent2 = indent.inc_nesting();
Expand All @@ -268,6 +267,24 @@ impl Statement {
}
{indent}"}"
}
Statement::Switch {arg, default, cases} => {
"switch ("{disp!(arg)}") {\n"
let indent2 = indent.inc_nesting();
let indent3 = indent2.inc_nesting();
if !default.is_empty() {
{indent2}"default:\n"
for stmt in default {
{indent3}{stmt.display(&indent3, code, f)}"\n"
}
}
for (pattern, stmts) in cases {
{indent2}"case "{disp!(pattern)}":\n"
for stmt in stmts {
{indent3}{stmt.display(&indent3, code, f)}"\n"
}
}
{indent}"}"
}
Statement::While { cond, stmts } => {
"while ("{disp!(cond)}") {\n"
let indent2 = indent.inc_nesting();
Expand Down
Loading

0 comments on commit f8f1f3c

Please sign in to comment.