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
47 changes: 32 additions & 15 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};
use super::{Expr, Gen, Stmt, Var, VarOccurrencesProvider};

struct Des {
checks: bool,
buf: Vec<Stmt>,
var_occurrences: HashMap<String, i32>,
Ketasaja marked this conversation as resolved.
Show resolved Hide resolved
}

impl Gen for Des {
Expand Down Expand Up @@ -86,34 +88,36 @@ 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 = format!("len_{}", self.add_occurrence("len".into()));
Ketasaja marked this conversation as resolved.
Show resolved Hide resolved
self.push_local(len_name.clone().leak(), Some(self.readnumty(NumTy::U16)));

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

self.push_assign(into, self.readstring(Expr::from("len")));
self.push_assign(into, self.readstring(Expr::from(len_name.as_str())));
}
}

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 = format!("len_{}", self.add_occurrence("len".into()));
self.push_local(len_name.clone().leak(), Some(self.readnumty(NumTy::U16)));

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

self.push_read_copy(into, Expr::from("len"))
self.push_read_copy(into, Expr::from(len_name.as_str()))
}
}

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: String = format!("i_{}", self.add_occurrence("i".into()));

if let Some(len) = range.exact() {
self.push_stmt(Stmt::NumFor {
Expand All @@ -125,19 +129,21 @@ impl Des {
self.push_ty(ty, into.clone().eindex(var_name.as_str().into()));
self.push_stmt(Stmt::End);
} else {
self.push_local("len", Some(self.readnumty(NumTy::U16)));
let len_name = format!("len_{}", self.add_occurrence("len".into()));

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

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

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

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

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

Expand All @@ -161,9 +167,9 @@ impl Des {
to: self.readu16(),
});

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

self.push_ty(key, Var::Name(key_name.clone()));
Expand Down Expand Up @@ -370,6 +376,17 @@ impl Des {
}
}

impl VarOccurrencesProvider for Des {
fn get_var_occurrences(&mut self) -> &mut HashMap<String, i32> {
&mut self.var_occurrences
}
}

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)
}
32 changes: 18 additions & 14 deletions zap/src/irgen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
#![allow(dead_code)]
use std::collections::HashMap;
use std::{fmt::Display, vec};

use crate::config::{NumTy, Range, Ty};

pub mod des;
pub mod ser;

pub trait VarOccurrencesProvider {
Ketasaja marked this conversation as resolved.
Show resolved Hide resolved
fn get_var_occurrences(&mut self) -> &mut HashMap<String, i32>;
fn add_occurrence(&mut self, name: String) -> i32 {
match self.get_var_occurrences().get(&name) {
Some(occurrences) => {
let occurrences_inc = occurrences + 1;
self.get_var_occurrences().insert(name, occurrences_inc);
occurrences_inc
}
None => {
self.get_var_occurrences().insert(name, 1);
1
}
Ketasaja marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

pub trait Gen {
fn push_stmt(&mut self, stmt: Stmt);
fn gen(self, var: Var, ty: &Ty<'_>) -> Vec<Stmt>;
Expand Down Expand Up @@ -293,20 +311,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
90 changes: 64 additions & 26 deletions zap/src/irgen/ser.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};
use super::{Expr, Gen, Stmt, Var, VarOccurrencesProvider};

struct Ser {
checks: bool,
buf: Vec<Stmt>,
var_occurrences: HashMap<String, i32>,
}

impl Gen for Ser {
Expand Down Expand Up @@ -87,14 +89,15 @@ impl Ser {

self.push_writestring(from_expr, len.into());
} else {
self.push_local("len", Some(from_expr.clone().len()));
let len_name = format!("len_{}", self.add_occurrence("len".into()));
self.push_local(len_name.clone().leak(), Some(from_expr.clone().len()));

if self.checks {
self.push_range_check("len".into(), *range);
self.push_range_check(len_name.as_str().into(), *range);
}

self.push_writeu16("len".into());
self.push_writestring(from_expr, "len".into());
self.push_writeu16(len_name.as_str().into());
self.push_writestring(from_expr, len_name.as_str().into());
}
}

Expand All @@ -106,22 +109,27 @@ impl Ser {

self.push_write_copy(from_expr, len.into());
} else {
let len_name = format!("len_{}", self.add_occurrence("len".into()));
self.push_local(
"len",
Some(Var::from("buffer").nindex("len").call(vec![from_expr.clone()])),
len_name.clone().leak(),
Some(
Var::from("buffer")
.nindex(len_name.clone())
.call(vec![from_expr.clone()]),
),
);

if self.checks {
self.push_range_check("len".into(), *range);
self.push_range_check(len_name.clone().into(), *range);
}

self.push_writeu16("len".into());
self.push_write_copy(from_expr, "len".into())
self.push_writeu16(len_name.as_str().into());
self.push_write_copy(from_expr, len_name.clone().into())
}
}

Ty::Arr(ty, range) => {
let var_name = format!("i_{}", from.display_escaped_suffix() + 1);
let var_name = format!("i_{}", self.add_occurrence("i".into()));

if let Some(len) = range.exact() {
if self.checks {
Expand All @@ -137,50 +145,69 @@ impl Ser {
self.push_ty(ty, from.clone().eindex(var_name.as_str().into()));
self.push_stmt(Stmt::End);
} else {
self.push_local("len", Some(from_expr.clone().len()));
let len_name = format!("len_{}", self.add_occurrence("len".into()));
self.push_local(len_name.clone().leak(), Some(from_expr.clone().len()));

if self.checks {
self.push_range_check("len".into(), *range);
self.push_range_check(len_name.clone().into(), *range);
}

self.push_writeu16("len".into());
self.push_writeu16(len_name.as_str().into());

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

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

self.push_stmt(Stmt::Local(
var_name.clone().leak(),
inner_var_name.clone().leak(),
Some(from.clone().eindex(var_name.as_str().into()).into()),
));

self.push_ty(ty, Var::Name(var_name));
self.push_ty(ty, Var::Name(inner_var_name));
self.push_stmt(Stmt::End);
}
}

Ty::Map(key, val) => {
self.push_local("len_pos", Some(Var::from("alloc").call(vec![2.0.into()])));
self.push_local("len", Some(0.0.into()));
let len_name = format!("len_{}", self.add_occurrence("len".into()));
let len_pos_name = format!("len_pos_{}", self.add_occurrence("len_pos".into()));

self.push_local(
len_pos_name.clone().leak(),
Some(Var::from("alloc").call(vec![2.0.into()])),
);
self.push_local(len_name.clone().leak(), Some(0.0.into()));

let key_name = format!("k_{}", self.add_occurrence("k".into()));
let val_name = format!("v_{}", self.add_occurrence("v".into()));

self.push_stmt(Stmt::GenFor {
key: "k",
val: "v",
key: key_name.clone().leak(),
val: val_name.clone().leak(),
obj: from_expr,
});

self.push_assign("len".into(), Expr::from("len").add(1.0.into()));
self.push_ty(key, "k".into());
self.push_ty(val, "v".into());
self.push_assign(
Var::Name(len_name.clone()),
Expr::from(len_name.as_str()).add(1.0.into()),
);
self.push_ty(key, key_name.as_str().into());
self.push_ty(val, val_name.as_str().into());

self.push_stmt(Stmt::End);

self.push_stmt(Stmt::Call(
Var::from("buffer").nindex("writeu16"),
None,
vec!["outgoing_buff".into(), "len_pos".into(), "len".into()],
vec![
"outgoing_buff".into(),
len_pos_name.as_str().into(),
len_name.as_str().into(),
],
));
}

Expand Down Expand Up @@ -304,6 +331,17 @@ impl Ser {
}
}

impl VarOccurrencesProvider for Ser {
fn get_var_occurrences(&mut self) -> &mut HashMap<String, i32> {
&mut self.var_occurrences
}
}

pub fn gen(ty: &Ty, var: &str, checks: bool) -> Vec<Stmt> {
Ser { checks, buf: vec![] }.gen(var.into(), ty)
Ser {
checks,
buf: vec![],
var_occurrences: HashMap::new(),
}
.gen(var.into(), ty)
}
2 changes: 1 addition & 1 deletion zap/src/output/luau/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub trait Output {
self.push_line("--!optimize 2");
self.push_line("--!nocheck");
self.push_line("--!nolint");
self.push_line("--#selene: allow(unused_variable, shadowing, incorrect_standard_library_use)");
self.push_line("--#selene: allow(unused_variable, incorrect_standard_library_use)");

self.push_line(&format!(
"-- {scope} generated by Zap v{} (https://github.com/red-blox/zap)",
Expand Down