Skip to content

Commit 2e6b805

Browse files
committed
Renaming, avoid escaping known modules, Parameterise builder types
1 parent b4547e2 commit 2e6b805

3 files changed

Lines changed: 238 additions & 265 deletions

File tree

compiler-core/src/erlang.rs

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ use std::{collections::HashMap, ops::Deref, sync::Arc};
3232

3333
/// This is an open runtime error to which more fields can still be added.
3434
#[must_use]
35-
struct RuntimeError {
35+
struct RuntimeError<Map, Call> {
3636
/// This is the map that is going to be thrown by the `erlang:error` call.
37-
error_map: erlang_generation::Map,
37+
error_map: Map,
3838
/// This is the call to `erlang:error` that will throw the error, with the
3939
/// map as an argument.
40-
erlang_error_call: erlang_generation::Call,
40+
erlang_error_call: Call,
4141
}
4242

4343
/// Represents all the different kind of runtime errors that Gleam can raise.
@@ -154,7 +154,7 @@ struct FunctionGenerator<'a, 'generator> {
154154
///
155155
variable_names: im::HashMap<SrcSpan, EcoString>,
156156

157-
/// This keeps track of the number of throwaway variables that have already
157+
/// This keeps track of the number of generated variables that have already
158158
/// been generated in the current function.
159159
/// For example if this is `2` it means we've already generated:
160160
///
@@ -164,10 +164,10 @@ struct FunctionGenerator<'a, 'generator> {
164164
/// _value@2
165165
/// ```
166166
///
167-
/// We need this to make sure that every time we generate a new throwaway
167+
/// We need this to make sure that every time we generate a new generated
168168
/// variable it has a unique name not shadowing anything else.
169169
///
170-
throwaway_variables: usize,
170+
generated_variables: usize,
171171

172172
/// This keeps track of all the names that are taken for the current
173173
/// function and can't be used when defining new variables.
@@ -488,7 +488,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
488488
module_generator,
489489
taken_names: im::HashMap::new(),
490490
variable_names: im::HashMap::new(),
491-
throwaway_variables: 0,
491+
generated_variables: 0,
492492
}
493493
}
494494

@@ -562,13 +562,13 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
562562
/// The generated name is guaranteed to always be unique for the given
563563
/// function.
564564
///
565-
fn new_throwaway_variable(&mut self) -> EcoString {
566-
let name = if self.throwaway_variables == 0 {
565+
fn new_generated_variable(&mut self) -> EcoString {
566+
let name = if self.generated_variables == 0 {
567567
EcoString::from("_value")
568568
} else {
569-
eco_format!("_value@{}", self.throwaway_variables)
569+
eco_format!("_value@{}", self.generated_variables)
570570
};
571-
self.throwaway_variables += 1;
571+
self.generated_variables += 1;
572572
name
573573
}
574574

@@ -732,7 +732,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
732732
// If an argument is made of just underscores, then that would result
733733
// in a syntax error in the generated Erlang, where the external
734734
// function is called with a discard `io:format(_, _)`!
735-
// So in this case we use a throwaway name to make sure the external
735+
// So in this case we use a generated name to make sure the external
736736
// function can be called correctly.
737737
ArgNames::Discard { name, location }
738738
| ArgNames::LabelledDiscard {
@@ -741,7 +741,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
741741
..
742742
} if is_external => {
743743
if name.chars().all(|char| char == '_') {
744-
self.new_throwaway_variable()
744+
self.new_generated_variable()
745745
} else {
746746
self.new_erlang_variable(name, *location)
747747
}
@@ -764,8 +764,8 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
764764
// We go over each statement one by one and produce the code they need.
765765
for i in 0..statements.len() {
766766
match statements.get(i).expect("statement in range") {
767-
Statement::Expression(expression) => self.expr(builder, expression),
768-
Statement::Use(use_) => self.expr(builder, &use_.call),
767+
Statement::Expression(expression) => self.expression(builder, expression),
768+
Statement::Use(use_) => self.expression(builder, &use_.call),
769769
Statement::Assert(assert) => self.assert(builder, assert),
770770
Statement::Assignment(assignment) => match &assignment.kind {
771771
AssignmentKind::Let | AssignmentKind::Generated => {
@@ -812,7 +812,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
812812
}
813813
}
814814

815-
fn expr<Output>(
815+
fn expression<Output>(
816816
&mut self,
817817
builder: &mut impl ErlangBuilder<Output>,
818818
expression: &'a TypedExpr,
@@ -858,7 +858,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
858858
left,
859859
right,
860860
..
861-
} => self.bin_op(builder, operator, left, right),
861+
} => self.binary_operator(builder, operator, left, right),
862862

863863
//
864864
// BitArrays, Lists, and Tuples.
@@ -1091,14 +1091,14 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
10911091
/// After you're done generating those additional fields remember you _must_
10921092
/// call `end_runtime_error` before generating any other piece of code!
10931093
///
1094-
fn start_runtime_error<Output>(
1094+
fn start_runtime_error<Output, Builder: ErlangBuilder<Output>>(
10951095
&mut self,
1096-
builder: &mut impl ErlangBuilder<Output>,
1096+
builder: &mut Builder,
10971097
error_kind: RuntimeErrorKind,
10981098
location: SrcSpan,
10991099
message: Option<&'a TypedExpr>,
1100-
) -> RuntimeError {
1101-
let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "error");
1100+
) -> RuntimeError<Builder::Map, Builder::Call> {
1101+
let call = builder.start_remote_call(ErlangModuleName::erlang(), "error");
11021102
let map = builder.start_map();
11031103

11041104
builder.map_field();
@@ -1146,10 +1146,10 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
11461146
}
11471147

11481148
/// This closes an open runtime error.
1149-
fn end_runtime_error<Output>(
1149+
fn end_runtime_error<Output, Builder: ErlangBuilder<Output>>(
11501150
&self,
1151-
builder: &mut impl ErlangBuilder<Output>,
1152-
runtime_error: RuntimeError,
1151+
builder: &mut Builder,
1152+
runtime_error: RuntimeError<Builder::Map, Builder::Call>,
11531153
) {
11541154
builder.end_map(runtime_error.error_map);
11551155
builder.end_call(runtime_error.erlang_error_call);
@@ -1162,10 +1162,10 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
11621162
) {
11631163
if needs_begin_end_wrapping(expression) {
11641164
let block = builder.start_block();
1165-
self.expr(builder, expression);
1165+
self.expression(builder, expression);
11661166
builder.end_block(block);
11671167
} else {
1168-
self.expr(builder, expression);
1168+
self.expression(builder, expression);
11691169
}
11701170
}
11711171

@@ -1232,7 +1232,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
12321232
// end
12331233
// ```
12341234
let clause = builder.start_case_clause();
1235-
let matched_value_name = self.new_throwaway_variable();
1235+
let matched_value_name = self.new_generated_variable();
12361236
builder.match_pattern();
12371237
let mut generator = PatternGenerator::new(self);
12381238
generator.pattern(builder, pattern);
@@ -1246,7 +1246,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
12461246

12471247
// This is the catch all branch to throw an error otherwise.
12481248
let clause = builder.start_case_clause();
1249-
let value_name = self.new_throwaway_variable();
1249+
let value_name = self.new_generated_variable();
12501250
builder.variable_pattern(&value_name);
12511251
let clause = builder.end_clause_pattern(clause);
12521252
let clause = builder.end_clause_guards(clause);
@@ -1355,7 +1355,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
13551355
},
13561356
)
13571357
} else {
1358-
self.expr(builder, finally)
1358+
self.expression(builder, finally)
13591359
}
13601360
}
13611361

@@ -1413,24 +1413,24 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
14131413
};
14141414

14151415
// If the left or right hand side are not simple variables we'll
1416-
// need to first assign those to throwaway variables and keep
1416+
// need to first assign those to generated variables and keep
14171417
// track of those names.
14181418
let left = if !left.is_var() {
1419-
let name = self.new_throwaway_variable();
1419+
let name = self.new_generated_variable();
14201420
builder.match_operator();
14211421
builder.variable_pattern(&name);
14221422
self.maybe_block_expr(builder, left);
1423-
AssertionExpression::from_throwaway_variable(name, left)
1423+
AssertionExpression::from_generated_variable(name, left)
14241424
} else {
14251425
AssertionExpression::from_expression(left)
14261426
};
14271427

14281428
let right = if !right.is_var() {
1429-
let name = self.new_throwaway_variable();
1429+
let name = self.new_generated_variable();
14301430
builder.match_operator();
14311431
builder.variable_pattern(&name);
14321432
self.maybe_block_expr(builder, right);
1433-
AssertionExpression::from_throwaway_variable(name, right)
1433+
AssertionExpression::from_generated_variable(name, right)
14341434
} else {
14351435
AssertionExpression::from_expression(right)
14361436
};
@@ -1479,11 +1479,11 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
14791479
let mut call_arguments = Vec::with_capacity(arguments.len());
14801480
for argument in arguments {
14811481
let argument = if !argument.value.is_var() {
1482-
let name = self.new_throwaway_variable();
1482+
let name = self.new_generated_variable();
14831483
builder.match_operator();
14841484
builder.variable_pattern(&name);
14851485
self.maybe_block_expr(builder, &argument.value);
1486-
AssertionExpression::from_throwaway_variable(name, &argument.value)
1486+
AssertionExpression::from_generated_variable(name, &argument.value)
14871487
} else {
14881488
AssertionExpression::from_expression(&argument.value)
14891489
};
@@ -1904,7 +1904,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
19041904
tuple: &'a TypedExpr,
19051905
index: u64,
19061906
) {
1907-
let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "element");
1907+
let call = builder.start_remote_call(ErlangModuleName::erlang(), "element");
19081908
builder.int((index + 1).into());
19091909
self.maybe_block_expr(builder, tuple);
19101910
builder.end_call(call);
@@ -2213,7 +2213,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
22132213
if let TypedExpr::Block { statements, .. } = &clause.then {
22142214
self.statement_sequence(builder, statements);
22152215
} else {
2216-
self.expr(builder, &clause.then);
2216+
self.expression(builder, &clause.then);
22172217
}
22182218
builder.end_clause_body(clause_body);
22192219
}
@@ -2487,7 +2487,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
24872487
});
24882488
}
24892489

2490-
fn bin_op<Output>(
2490+
fn binary_operator<Output>(
24912491
&mut self,
24922492
builder: &mut impl ErlangBuilder<Output>,
24932493
name: &'a BinOp,
@@ -2548,7 +2548,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
25482548
// We first have to evaluate the left hand side, and store its
25492549
// result in a variable to use later.
25502550
let left_name = if !is_left_hand_side_pure {
2551-
let left_name = self.new_throwaway_variable();
2551+
let left_name = self.new_generated_variable();
25522552
builder.match_operator();
25532553
builder.variable_pattern(&left_name);
25542554
self.maybe_block_expr(builder, left);
@@ -2577,7 +2577,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
25772577
builder.end_clause_body(body);
25782578

25792579
// _value -> left / _value
2580-
let denominator = self.new_throwaway_variable();
2580+
let denominator = self.new_generated_variable();
25812581
let clause = builder.start_case_clause();
25822582
builder.variable_pattern(&denominator);
25832583
let guards = builder.end_clause_pattern(clause);
@@ -2624,7 +2624,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
26242624
} => {
26252625
// If the left hand side is not a pure expression we will have
26262626
// to evaluate it before the right hand side of the expression.
2627-
// So we assign it to a throwaway variable that we will then
2627+
// So we assign it to a generated variable that we will then
26282628
// reference in the case expression's body.
26292629
// It will look something like this:
26302630
//
@@ -2637,7 +2637,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
26372637
// ```
26382638
//
26392639
let left_name = if !is_left_hand_side_pure {
2640-
let left_name = self.new_throwaway_variable();
2640+
let left_name = self.new_generated_variable();
26412641
builder.match_operator();
26422642
builder.variable_pattern(&left_name);
26432643
self.maybe_block_expr(builder, left);
@@ -2658,7 +2658,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
26582658
builder.end_clause_body(body);
26592659

26602660
// _value -> left div _value
2661-
let denominator = self.new_throwaway_variable();
2661+
let denominator = self.new_generated_variable();
26622662
let clause = builder.start_case_clause();
26632663
builder.variable_pattern(&denominator);
26642664
let guards = builder.end_clause_pattern(clause);
@@ -2763,7 +2763,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
27632763
// unicode:characters_to_binary(<segment_value>, utf8, {utf16, big})
27642764
// ```
27652765
let call =
2766-
builder.start_remote_call(ErlangModuleName::new("unicode"), "characters_to_binary");
2766+
builder.start_remote_call(ErlangModuleName::unicode(), "characters_to_binary");
27672767
{
27682768
self.maybe_block_expr(builder, &segment.value);
27692769
builder.atom("utf8");
@@ -2814,7 +2814,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
28142814
builder.int(int_value.clone());
28152815
}
28162816
} else {
2817-
let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "max");
2817+
let call = builder.start_remote_call(ErlangModuleName::erlang(), "max");
28182818
builder.int(BigInt::ZERO);
28192819
self.maybe_block_expr(builder, size);
28202820
builder.end_call(call);
@@ -2916,7 +2916,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
29162916
tuple: &'a TypedClauseGuard,
29172917
index: u64,
29182918
) {
2919-
let call = builder.start_remote_call(ErlangModuleName::new("erlang"), "element");
2919+
let call = builder.start_remote_call(ErlangModuleName::erlang(), "element");
29202920
builder.int((index + 1).into());
29212921
self.clause_guard(builder, tuple, &HashMap::new());
29222922
builder.end_call(call);
@@ -2989,7 +2989,7 @@ impl<'a, 'generator> FunctionGenerator<'a, 'generator> {
29892989
arguments: usize,
29902990
) {
29912991
let arguments = (0..arguments)
2992-
.map(|_| self.new_throwaway_variable())
2992+
.map(|_| self.new_generated_variable())
29932993
.collect_vec();
29942994
let function = builder.start_anonymous_function(&arguments);
29952995

@@ -3265,7 +3265,7 @@ fn how_to_divide(left: &TypedExpr, right: &TypedExpr) -> HowToDivide {
32653265
pub fn record_definition(record_name: &str, fields: &[(&str, Arc<Type>)]) -> String {
32663266
let mut builder = ErlangSourceBuilder::new(None);
32673267

3268-
let record = builder.start_record_attribute(&to_snake_case(record_name));
3268+
builder.start_record_attribute(&to_snake_case(record_name));
32693269

32703270
let type_printer = TypeGenerator::new("").var_as_any();
32713271
for (field_name, field_type) in fields {
@@ -3274,7 +3274,7 @@ pub fn record_definition(record_name: &str, fields: &[(&str, Arc<Type>)]) -> Str
32743274
type_printer.type_(&mut builder, field_type);
32753275
}
32763276

3277-
builder.end_record_attribute(record);
3277+
builder.end_record_attribute(());
32783278
builder.into_output()
32793279
}
32803280

@@ -3563,7 +3563,7 @@ impl<'a> AssertionExpression<'a> {
35633563
self
35643564
}
35653565

3566-
fn from_throwaway_variable(name: EcoString, original_expression: &'a TypedExpr) -> Self {
3566+
fn from_generated_variable(name: EcoString, original_expression: &'a TypedExpr) -> Self {
35673567
Self {
35683568
runtime_value: Some(AssertedExpressionRuntimeValue::Variable(name)),
35693569
kind: if original_expression.is_literal() {
@@ -3628,7 +3628,7 @@ enum AssertedExpressionRuntimeValue<'a> {
36283628
/// That's because we know wether the assertion failed (it must be false),
36293629
/// or not (it must be true).
36303630
KnownBool(bool),
3631-
/// The asserted value was bound to a throwaway variable with the given
3631+
/// The asserted value was bound to a generated variable with the given
36323632
/// name, and we can reference it using that name.
36333633
Variable(EcoString),
36343634
/// The asserted value is an expression we need to inline in the error.

compiler-core/src/erlang/pattern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ impl<'a, 'generator, 'module> PatternGenerator<'a, 'generator, 'module> {
415415
builder.end_clause_body(clause);
416416

417417
let clause = builder.start_case_clause();
418-
let denominator = self.generator.new_throwaway_variable();
418+
let denominator = self.generator.new_generated_variable();
419419
builder.variable_pattern(&denominator);
420420
let clause = builder.end_clause_pattern(clause);
421421
let clause = builder.end_clause_guards(clause);

0 commit comments

Comments
 (0)