Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove benign shadowing #104

Merged
merged 15 commits into from
Jun 29, 2024
78 changes: 47 additions & 31 deletions zap/src/irgen/des.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::config::{Enum, NumTy, Struct, Ty};
use std::collections::HashMap;

use super::{Expr, Gen, Stmt, Var};

struct Des {
checks: bool,
buf: Vec<Stmt>,
var_occurrences: HashMap<String, usize>,
}

impl Gen for Des {
Expand All @@ -16,6 +18,10 @@ impl Gen for Des {
self.push_ty(ty, var);
self.buf
}

fn get_var_occurrences(&mut self) -> &mut HashMap<String, usize> {
&mut self.var_occurrences
}
}

impl Des {
Expand All @@ -30,7 +36,7 @@ impl Des {
Enum::Unit(enumerators) => {
let numty = NumTy::from_f64(0.0, enumerators.len() as f64 - 1.0);

self.push_local("enum_value", Some(self.readnumty(numty)));
self.push_local("enum_value".into(), Some(self.readnumty(numty)));
Ketasaja marked this conversation as resolved.
Show resolved Hide resolved

for (i, enumerator) in enumerators.iter().enumerate() {
if i == 0 {
Expand All @@ -50,7 +56,7 @@ impl Des {
Enum::Tagged { tag, variants } => {
let numty = NumTy::from_f64(0.0, variants.len() as f64 - 1.0);

self.push_local("enum_value", Some(self.readnumty(numty)));
self.push_local("enum_value".into(), Some(self.readnumty(numty)));

for (i, (name, struct_ty)) in variants.iter().enumerate() {
if i == 0 {
Expand Down Expand Up @@ -86,66 +92,71 @@ impl Des {
if let Some(len) = range.exact() {
self.push_assign(into, self.readstring(len.into()));
} else {
self.push_local("len", Some(self.readnumty(NumTy::U16)));
let (len_name, len_expr) = self.add_occurrence("len");

self.push_local(len_name.clone(), Some(self.readnumty(NumTy::U16)));

if self.checks {
self.push_range_check(Expr::from("len"), *range);
self.push_range_check(len_expr.clone(), *range);
}

self.push_assign(into, self.readstring(Expr::from("len")));
self.push_assign(into, self.readstring(len_expr.clone()));
}
}

Ty::Buf(range) => {
if let Some(len) = range.exact() {
self.push_read_copy(into, len.into());
} else {
self.push_local("len", Some(self.readnumty(NumTy::U16)));
let (len_name, len_expr) = self.add_occurrence("len");
self.push_local(len_name.clone(), Some(self.readnumty(NumTy::U16)));

if self.checks {
self.push_range_check(Expr::from("len"), *range);
self.push_range_check(len_expr.clone(), *range);
}

self.push_read_copy(into, Expr::from("len"))
self.push_read_copy(into, len_expr.clone())
}
}

Ty::Arr(ty, range) => {
self.push_assign(into.clone(), Expr::EmptyTable);

let var_name: String = format!("i_{}", into.display_escaped_suffix() + 1);
let (var_name, var_expr) = self.add_occurrence("i");

if let Some(len) = range.exact() {
self.push_stmt(Stmt::NumFor {
var: var_name.clone().leak(),
var: var_name.clone(),
from: 1.0.into(),
to: len.into(),
});

self.push_ty(ty, into.clone().eindex(var_name.as_str().into()));
self.push_ty(ty, into.clone().eindex(var_expr.clone()));
self.push_stmt(Stmt::End);
} else {
self.push_local("len", Some(self.readnumty(NumTy::U16)));
let (len_name, len_expr) = self.add_occurrence("len");

self.push_local(len_name.clone(), Some(self.readnumty(NumTy::U16)));

if self.checks {
self.push_range_check(Expr::from("len"), *range);
self.push_range_check(len_expr.clone(), *range);
}

self.push_stmt(Stmt::NumFor {
var: var_name.clone().leak(),
var: var_name.clone(),
from: 1.0.into(),
to: "len".into(),
to: len_expr.clone(),
});

let inner_var_name = format!("j_{}", into.display_escaped_suffix() + 1);
let (inner_var_name, _) = self.add_occurrence("j");

self.push_local(inner_var_name.clone().leak(), None);
self.push_local(inner_var_name.clone(), None);

self.push_ty(ty, Var::Name(inner_var_name.clone()));

self.push_stmt(Stmt::Assign(
into.clone().eindex(var_name.clone().as_str().into()),
Var::Name(inner_var_name).into(),
into.clone().eindex(var_expr.clone()),
Var::Name(inner_var_name.clone()).into(),
));

self.push_stmt(Stmt::End);
Expand All @@ -156,20 +167,20 @@ impl Des {
self.push_assign(into.clone(), Expr::EmptyTable);

self.push_stmt(Stmt::NumFor {
var: "_",
var: "_".into(),
from: 1.0.into(),
to: self.readu16(),
});

let key_name = format!("key_{}", into.display_escaped_suffix() + 1);
self.push_local(key_name.clone().leak(), None);
let val_name = format!("val_{}", into.display_escaped_suffix() + 1);
self.push_local(val_name.clone().leak(), None);
let (key_name, key_expr) = self.add_occurrence("key");
self.push_local(key_name.clone(), None);
let (val_name, val_expr) = self.add_occurrence("val");
self.push_local(val_name.clone(), None);

self.push_ty(key, Var::Name(key_name.clone()));
self.push_ty(val, Var::Name(val_name.clone()));

self.push_assign(into.clone().eindex(key_name.as_str().into()), val_name.as_str().into());
self.push_assign(into.clone().eindex(key_expr.clone()), val_expr.clone());

self.push_stmt(Stmt::End);
}
Expand Down Expand Up @@ -315,9 +326,9 @@ impl Des {
Ty::Vector3 => self.push_assign(into, self.readvector3()),

Ty::AlignedCFrame => {
self.push_local("axis_alignment", Some(self.readu8()));
self.push_local("axis_alignment".into(), Some(self.readu8()));

self.push_local("pos", Some(self.readvector3()));
self.push_local("pos".into(), Some(self.readvector3()));

self.push_assign(
into,
Expand All @@ -332,9 +343,9 @@ impl Des {
);
}
Ty::CFrame => {
self.push_local("pos", Some(self.readvector3()));
self.push_local("axisangle", Some(self.readvector3()));
self.push_local("angle", Some(Var::from("axisangle").nindex("Magnitude").into()));
self.push_local("pos".into(), Some(self.readvector3()));
self.push_local("axisangle".into(), Some(self.readvector3()));
self.push_local("angle".into(), Some(Var::from("axisangle").nindex("Magnitude").into()));

// We don't need to convert the axis back to a unit vector as the constructor does that for us
// The angle is the magnitude of the axis vector
Expand Down Expand Up @@ -371,5 +382,10 @@ impl Des {
}

pub fn gen(ty: &Ty, var: &str, checks: bool) -> Vec<Stmt> {
Des { checks, buf: vec![] }.gen(var.into(), ty)
Des {
checks,
buf: vec![],
var_occurrences: HashMap::new(),
}
.gen(var.into(), ty)
}
48 changes: 22 additions & 26 deletions zap/src/irgen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(dead_code)]
use std::collections::HashMap;
use std::{fmt::Display, vec};

use crate::config::{NumTy, Range, Ty};
Expand All @@ -10,7 +11,7 @@ pub trait Gen {
fn push_stmt(&mut self, stmt: Stmt);
fn gen(self, var: Var, ty: &Ty<'_>) -> Vec<Stmt>;

fn push_local(&mut self, name: &'static str, expr: Option<Expr>) {
fn push_local(&mut self, name: String, expr: Option<Expr>) {
self.push_stmt(Stmt::Local(name, expr))
}

Expand Down Expand Up @@ -244,28 +245,37 @@ pub trait Gen {
self.push_assert(expr.clone().lte(max.into()), None)
}
}

fn get_var_occurrences(&mut self) -> &mut HashMap<String, usize>;
fn add_occurrence(&mut self, name: &str) -> (String, Expr) {
match self.get_var_occurrences().get(name.into()) {
Some(occurrences) => {
let occurrences_inc = occurrences + 1;
self.get_var_occurrences().insert(name.into(), occurrences_inc);
let suffixed_name = format!("{name}_{occurrences_inc}");
(suffixed_name.clone(), Expr::from(suffixed_name.as_str()))
}
None => {
self.get_var_occurrences().insert(name.into(), 1);
let suffixed_name = format!("{name}_1");
(suffixed_name.clone(), Expr::from(suffixed_name.as_str()))
}
}
}
}

#[derive(Debug, Clone)]
pub enum Stmt {
Local(&'static str, Option<Expr>),
Local(String, Option<Expr>),
LocalTuple(Vec<&'static str>, Option<Expr>),
Assign(Var, Expr),
Error(String),
Assert(Expr, Option<String>),

Call(Var, Option<String>, Vec<Expr>),

NumFor {
var: &'static str,
from: Expr,
to: Expr,
},
GenFor {
key: &'static str,
val: &'static str,
obj: Expr,
},
NumFor { var: String, from: Expr, to: Expr },
GenFor { key: String, val: String, obj: Expr },
If(Expr),
ElseIf(Expr),
Else,
Expand Down Expand Up @@ -293,20 +303,6 @@ impl Var {
pub fn call(self, args: Vec<Expr>) -> Expr {
Expr::Call(Box::new(self), None, args)
}

pub fn display_escaped_suffix(&self) -> i32 {
match self {
Self::Name(name) => match name.find('_') {
Some(underscore_index) => match name[underscore_index + 1..].parse::<i32>() {
Ok(number) => number + 1,
Err(_) => 0,
},
None => 0,
},
Self::NameIndex(var, _) => var.display_escaped_suffix() + 1,
Self::ExprIndex(var, _) => var.display_escaped_suffix() + 1,
}
}
}

impl From<&str> for Var {
Expand Down
Loading