Skip to content

Commit 2d1ab6d

Browse files
committed
Move mangling utilities to a separate module
1 parent df04fe3 commit 2d1ab6d

File tree

7 files changed

+169
-164
lines changed

7 files changed

+169
-164
lines changed

src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
use crate::attributes::Attributes;
33
use crate::error::{QccError, QccErrorKind};
44
use crate::lexer::Location;
5+
use crate::mangle::mangle_fns;
56
use crate::types::Type;
6-
use crate::utils::mangle_fns;
77
use std::borrow::Borrow;
88

99
#[derive(Debug, PartialEq, Copy, Clone)]

src/inference.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Type inference mechanism for qcc.
22
use crate::ast::{Expr, FunctionAST, LiteralAST, Qast, QccCell, VarAST};
33
use crate::error::{QccError, QccErrorKind, Result};
4+
use crate::mangle::{mangle, mangle_module};
45
use crate::types::Type;
5-
use crate::utils::{mangle, mangle_module};
66
use std::borrow::{Borrow, BorrowMut};
77

88
/// A generic symbol table implementation.

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod config;
88
pub mod error;
99
pub mod inference;
1010
mod lexer;
11+
mod mangle;
1112
mod optimizer;
1213
pub mod parser;
1314
mod types;

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod config;
99
mod error;
1010
mod inference;
1111
mod lexer;
12+
mod mangle;
1213
mod optimizer;
1314
mod parser;
1415
mod types;

src/mangle.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/// Simple Name Mangler
2+
///
3+
/// This simple mangler uses module name as prefix and dollar'ed with function
4+
/// names.
5+
use crate::ast::{Expr, FunctionAST, Ident, ModuleAST, Qast, QccCell};
6+
use crate::error::Result;
7+
8+
pub(crate) fn mangle(ast: &mut Qast) -> Result<()> {
9+
for mut module in ast {
10+
let mod_name = module.get_name();
11+
for mut function in &mut *module {
12+
let fn_name = function.get_name().clone();
13+
function.set_name(format!("{}${}", mod_name.clone(), fn_name).into());
14+
15+
for instruction in &mut *function {
16+
mangle_expr(instruction, mod_name.clone() + "$");
17+
}
18+
}
19+
}
20+
21+
Ok(())
22+
}
23+
24+
pub(crate) fn mangle_expr(expr: &mut QccCell<Expr>, prefix: Ident) {
25+
// TODO: prefix: &str
26+
match *expr.as_ref().borrow_mut() {
27+
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
28+
mangle_expr(lhs, prefix.clone());
29+
mangle_expr(rhs, prefix);
30+
}
31+
Expr::Let(_, ref mut val) => {
32+
mangle_expr(val, prefix);
33+
}
34+
Expr::FnCall(ref mut f, ref mut args) => {
35+
for arg in args {
36+
mangle_expr(arg, prefix.clone());
37+
}
38+
39+
f.set_name(prefix + f.get_name());
40+
}
41+
Expr::Tensor(ref mut exprs) => {
42+
for expr in exprs {
43+
mangle_expr(expr, prefix.clone());
44+
}
45+
}
46+
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
47+
mangle_expr(c, prefix.clone());
48+
for expr in t {
49+
mangle_expr(expr, prefix.clone());
50+
}
51+
for expr in f {
52+
mangle_expr(expr, prefix.clone());
53+
}
54+
}
55+
Expr::Var(_) => {}
56+
Expr::Literal(_) => {}
57+
}
58+
}
59+
60+
pub(crate) fn mangle_fns(expr: &mut QccCell<Expr>, module_name: &String, functions: &Vec<String>) {
61+
match *expr.as_ref().borrow_mut() {
62+
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
63+
mangle_fns(lhs, module_name, functions);
64+
mangle_fns(rhs, module_name, functions);
65+
}
66+
Expr::Let(ref mut var, ref mut val) => {
67+
mangle_fns(val, module_name, functions);
68+
}
69+
Expr::FnCall(ref mut f, ref mut args) => {
70+
for arg in args {
71+
mangle_fns(arg, module_name, functions);
72+
}
73+
74+
let fn_name = f.get_name();
75+
if let Some(x) = functions.iter().find(|&f| f == fn_name) {
76+
if !x.contains('$') {
77+
f.set_name(module_name.clone() + "$" + fn_name);
78+
}
79+
}
80+
}
81+
Expr::Tensor(ref mut exprs) => {
82+
for expr in exprs {
83+
mangle_fns(expr, module_name, functions);
84+
}
85+
}
86+
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
87+
mangle_fns(c, module_name, functions);
88+
for expr in t {
89+
mangle_fns(expr, module_name, functions);
90+
}
91+
for expr in f {
92+
mangle_fns(expr, module_name, functions);
93+
}
94+
}
95+
Expr::Var(_) => {}
96+
Expr::Literal(_) => {}
97+
}
98+
}
99+
100+
/// Replaces all occurences of `fn_name` in instructions with
101+
/// (`mod_name + `$` + `fn_name`).
102+
fn mangle_expr_check(expr: &mut QccCell<Expr>, mod_name: &Ident, fn_name: &Ident) {
103+
// TODO: Support tensors
104+
match *expr.as_ref().borrow_mut() {
105+
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
106+
mangle_expr_check(lhs, mod_name, fn_name);
107+
mangle_expr_check(rhs, mod_name, fn_name);
108+
}
109+
Expr::Let(_, ref mut val) => {
110+
mangle_expr_check(val, mod_name, fn_name);
111+
}
112+
Expr::FnCall(ref mut f, ref mut args) => {
113+
for arg in args {
114+
mangle_expr_check(arg, mod_name, fn_name);
115+
}
116+
117+
if *f.get_name() == *fn_name {
118+
f.set_name(mod_name.to_owned() + "$" + f.get_name());
119+
}
120+
}
121+
Expr::Tensor(ref mut exprs) => {
122+
for expr in exprs {
123+
mangle_expr_check(expr, mod_name, fn_name);
124+
}
125+
}
126+
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
127+
mangle_expr_check(c, mod_name, fn_name);
128+
for expr in t {
129+
mangle_expr_check(expr, mod_name, fn_name);
130+
}
131+
for expr in f {
132+
mangle_expr_check(expr, mod_name, fn_name);
133+
}
134+
}
135+
Expr::Var(_) => {}
136+
Expr::Literal(_) => {}
137+
}
138+
}
139+
140+
/// Takes in a mutable reference to a module and replaces all function call
141+
/// instances with a mangled string, which is calculated from a module name and
142+
/// a function name.
143+
pub(crate) fn mangle_module(module: &mut ModuleAST, mod_name: Ident, fn_name: Ident) -> Result<()> {
144+
for mut function in module {
145+
for instruction in &mut *function {
146+
mangle_expr_check(instruction, &mod_name, &fn_name);
147+
}
148+
}
149+
150+
Ok(())
151+
}
152+
153+
pub(crate) fn sanitize(identifier: Ident) -> Ident {
154+
let mut sanitized = String::new();
155+
for c in identifier.bytes() {
156+
if c.is_ascii_alphanumeric() {
157+
sanitized += &(c as char).to_string();
158+
} else {
159+
sanitized += "_"; // TODO: Using '$'
160+
}
161+
}
162+
sanitized
163+
}

src/parser.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ use crate::attributes::{Attribute, Attributes};
55
use crate::config::*;
66
use crate::error::{QccError, QccErrorKind, QccErrorLoc, Result};
77
use crate::lexer::{Lexer, Location};
8+
use crate::mangle::{mangle_module, sanitize};
89
use crate::types::Type;
9-
use crate::utils::{mangle_module, sanitize, usage};
10+
use crate::utils::usage;
1011
use std::collections::BTreeSet;
1112
use std::collections::HashSet;
1213
use std::path::Path;

src/utils.rs

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -65,167 +65,6 @@ pub(crate) fn usage() {
6565
);
6666
}
6767

68-
/// Simple Name Mangler
69-
///
70-
/// This simple mangler uses module name as prefix and dollar'ed with function
71-
/// names.
72-
pub(crate) fn mangle(ast: &mut Qast) -> Result<()> {
73-
for mut module in ast {
74-
let mod_name = module.get_name();
75-
for mut function in &mut *module {
76-
let fn_name = function.get_name().clone();
77-
function.set_name(format!("{}${}", mod_name.clone(), fn_name).into());
78-
79-
for instruction in &mut *function {
80-
mangle_expr(instruction, mod_name.clone() + "$");
81-
}
82-
}
83-
}
84-
85-
Ok(())
86-
}
87-
88-
pub(crate) fn mangle_expr(expr: &mut QccCell<Expr>, prefix: Ident) {
89-
// TODO: prefix: &str
90-
match *expr.as_ref().borrow_mut() {
91-
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
92-
mangle_expr(lhs, prefix.clone());
93-
mangle_expr(rhs, prefix);
94-
}
95-
Expr::Let(_, ref mut val) => {
96-
mangle_expr(val, prefix);
97-
}
98-
Expr::FnCall(ref mut f, ref mut args) => {
99-
for arg in args {
100-
mangle_expr(arg, prefix.clone());
101-
}
102-
103-
f.set_name(prefix + f.get_name());
104-
}
105-
Expr::Tensor(ref mut exprs) => {
106-
for expr in exprs {
107-
mangle_expr(expr, prefix.clone());
108-
}
109-
}
110-
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
111-
mangle_expr(c, prefix.clone());
112-
for expr in t {
113-
mangle_expr(expr, prefix.clone());
114-
}
115-
for expr in f {
116-
mangle_expr(expr, prefix.clone());
117-
}
118-
}
119-
Expr::Var(_) => {}
120-
Expr::Literal(_) => {}
121-
}
122-
}
123-
124-
pub(crate) fn mangle_fns(expr: &mut QccCell<Expr>, module_name: &String, functions: &Vec<String>) {
125-
match *expr.as_ref().borrow_mut() {
126-
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
127-
mangle_fns(lhs, module_name, functions);
128-
mangle_fns(rhs, module_name, functions);
129-
}
130-
Expr::Let(ref mut var, ref mut val) => {
131-
mangle_fns(val, module_name, functions);
132-
}
133-
Expr::FnCall(ref mut f, ref mut args) => {
134-
for arg in args {
135-
mangle_fns(arg, module_name, functions);
136-
}
137-
138-
let fn_name = f.get_name();
139-
if let Some(x) = functions.iter().find(|&f| f == fn_name) {
140-
if !x.contains('$') {
141-
f.set_name(module_name.clone() + "$" + fn_name);
142-
}
143-
}
144-
}
145-
Expr::Tensor(ref mut exprs) => {
146-
for expr in exprs {
147-
mangle_fns(expr, module_name, functions);
148-
}
149-
}
150-
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
151-
mangle_fns(c, module_name, functions);
152-
for expr in t {
153-
mangle_fns(expr, module_name, functions);
154-
}
155-
for expr in f {
156-
mangle_fns(expr, module_name, functions);
157-
}
158-
}
159-
Expr::Var(_) => {}
160-
Expr::Literal(_) => {}
161-
}
162-
}
163-
164-
/// Replaces all occurences of `fn_name` in instructions with
165-
/// (`mod_name + `$` + `fn_name`).
166-
fn mangle_expr_check(expr: &mut QccCell<Expr>, mod_name: &Ident, fn_name: &Ident) {
167-
// TODO: Support tensors
168-
match *expr.as_ref().borrow_mut() {
169-
Expr::BinaryExpr(ref mut lhs, _, ref mut rhs) => {
170-
mangle_expr_check(lhs, mod_name, fn_name);
171-
mangle_expr_check(rhs, mod_name, fn_name);
172-
}
173-
Expr::Let(_, ref mut val) => {
174-
mangle_expr_check(val, mod_name, fn_name);
175-
}
176-
Expr::FnCall(ref mut f, ref mut args) => {
177-
for arg in args {
178-
mangle_expr_check(arg, mod_name, fn_name);
179-
}
180-
181-
if *f.get_name() == *fn_name {
182-
f.set_name(mod_name.to_owned() + "$" + f.get_name());
183-
}
184-
}
185-
Expr::Tensor(ref mut exprs) => {
186-
for expr in exprs {
187-
mangle_expr_check(expr, mod_name, fn_name);
188-
}
189-
}
190-
Expr::Conditional(ref mut c, ref mut t, ref mut f) => {
191-
mangle_expr_check(c, mod_name, fn_name);
192-
for expr in t {
193-
mangle_expr_check(expr, mod_name, fn_name);
194-
}
195-
for expr in f {
196-
mangle_expr_check(expr, mod_name, fn_name);
197-
}
198-
}
199-
Expr::Var(_) => {}
200-
Expr::Literal(_) => {}
201-
}
202-
}
203-
204-
/// Takes in a mutable reference to a module and replaces all function call
205-
/// instances with a mangled string, which is calculated from a module name and
206-
/// a function name.
207-
pub(crate) fn mangle_module(module: &mut ModuleAST, mod_name: Ident, fn_name: Ident) -> Result<()> {
208-
for mut function in module {
209-
for instruction in &mut *function {
210-
mangle_expr_check(instruction, &mod_name, &fn_name);
211-
}
212-
}
213-
214-
Ok(())
215-
}
216-
217-
pub(crate) fn sanitize(identifier: Ident) -> Ident {
218-
let mut sanitized = String::new();
219-
for c in identifier.bytes() {
220-
if c.is_ascii_alphanumeric() {
221-
sanitized += &(c as char).to_string();
222-
} else {
223-
sanitized += "_"; // TODO: Using '$'
224-
}
225-
}
226-
sanitized
227-
}
228-
22968
/// RefSet is a wrapper over HashSet but with no Eq trait. Equality is assumed
23069
/// to be different because it only stores references.
23170

0 commit comments

Comments
 (0)