Get some indenting right.
This commit is contained in:
@@ -13,6 +13,7 @@ use std::str::FromStr;
|
|||||||
use std::sync::atomic::AtomicU64;
|
use std::sync::atomic::AtomicU64;
|
||||||
|
|
||||||
pub const VALID_VARIABLE_NAMES: &str = r"[a-z][a-zA-Z0-9_]*";
|
pub const VALID_VARIABLE_NAMES: &str = r"[a-z][a-zA-Z0-9_]*";
|
||||||
|
const MAX_COMPLEX_DEPTH: usize = 4;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref BASE_PROGRAM_LENGTH: WeightedIndex<usize> = WeightedIndex::new([
|
static ref BASE_PROGRAM_LENGTH: WeightedIndex<usize> = WeightedIndex::new([
|
||||||
@@ -50,6 +51,11 @@ lazy_static::lazy_static! {
|
|||||||
(1, ExpressionType::Binding),
|
(1, ExpressionType::Binding),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
static ref SIMPLIFIED_EXPRESSION_TYPES: WeightedMap<ExpressionType> = WeightedMap::new(&[
|
||||||
|
(1, ExpressionType::Reference),
|
||||||
|
(1, ExpressionType::Value),
|
||||||
|
]);
|
||||||
|
|
||||||
static ref TYPE_FREQUENCIES: WeightedMap<&'static str> = WeightedMap::new(&[
|
static ref TYPE_FREQUENCIES: WeightedMap<&'static str> = WeightedMap::new(&[
|
||||||
(1, "void"),
|
(1, "void"),
|
||||||
(5, "i8"),
|
(5, "i8"),
|
||||||
@@ -166,13 +172,14 @@ impl ProgramTree {
|
|||||||
|
|
||||||
while current.len() < base_program_length {
|
while current.len() < base_program_length {
|
||||||
let (expression, mut requirements) =
|
let (expression, mut requirements) =
|
||||||
generate_expr(&mut rng, &mut established_structs, &mut env, None);
|
generate_expr(0, &mut rng, &mut established_structs, &mut env, None);
|
||||||
|
|
||||||
current.push_front(TopLevel::Expression(expression));
|
current.push_front(TopLevel::Expression(expression));
|
||||||
while let Some(requirement) = requirements.pop() {
|
while let Some(requirement) = requirements.pop() {
|
||||||
match requirement {
|
match requirement {
|
||||||
Requirement::Function(name, args, result) => {
|
Requirement::Function(name, args, result) => {
|
||||||
let (expression, newreqs) = generate_function(
|
let (expression, newreqs) = generate_function(
|
||||||
|
1,
|
||||||
&mut rng,
|
&mut rng,
|
||||||
&mut established_structs,
|
&mut established_structs,
|
||||||
&mut env,
|
&mut env,
|
||||||
@@ -203,8 +210,13 @@ impl ProgramTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Requirement::Variable(name, ty) => {
|
Requirement::Variable(name, ty) => {
|
||||||
let (newexpr, newreqs) =
|
let (newexpr, newreqs) = generate_expr(
|
||||||
generate_expr(&mut rng, &mut established_structs, &mut env, Some(ty));
|
1,
|
||||||
|
&mut rng,
|
||||||
|
&mut established_structs,
|
||||||
|
&mut env,
|
||||||
|
Some(ty),
|
||||||
|
);
|
||||||
let binding =
|
let binding =
|
||||||
Expression::Binding(Location::manufactured(), name, Box::new(newexpr));
|
Expression::Binding(Location::manufactured(), name, Box::new(newexpr));
|
||||||
current.push_front(TopLevel::Expression(binding));
|
current.push_front(TopLevel::Expression(binding));
|
||||||
@@ -222,6 +234,7 @@ impl ProgramTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_expr(
|
fn generate_expr(
|
||||||
|
depth: usize,
|
||||||
rng: &mut TestRng,
|
rng: &mut TestRng,
|
||||||
established_struct_types: &mut EstablishedStructMap,
|
established_struct_types: &mut EstablishedStructMap,
|
||||||
env: &mut ScopedMap<Name, Type>,
|
env: &mut ScopedMap<Name, Type>,
|
||||||
@@ -229,22 +242,26 @@ fn generate_expr(
|
|||||||
) -> (Expression, Vec<Requirement>) {
|
) -> (Expression, Vec<Requirement>) {
|
||||||
let target_type =
|
let target_type =
|
||||||
optional_target_type.unwrap_or_else(|| generate_type(rng, established_struct_types));
|
optional_target_type.unwrap_or_else(|| generate_type(rng, established_struct_types));
|
||||||
let expression_type = EXPRESSION_TYPE_FREQUENCIES.sample(rng);
|
let expression_type = if depth > MAX_COMPLEX_DEPTH {
|
||||||
|
SIMPLIFIED_EXPRESSION_TYPES.sample(rng)
|
||||||
|
} else {
|
||||||
|
EXPRESSION_TYPE_FREQUENCIES.sample(rng)
|
||||||
|
};
|
||||||
|
|
||||||
match expression_type {
|
match expression_type {
|
||||||
ExpressionType::Value => match target_type {
|
ExpressionType::Value => match target_type {
|
||||||
Type::Named(ref x) => match ConstantType::from_str(x.current_name()) {
|
Type::Named(ref x) => match ConstantType::from_str(x.current_name()) {
|
||||||
Ok(ct) => (generate_constant(rng, ct), vec![]),
|
Ok(ct) => (generate_constant(rng, ct), vec![]),
|
||||||
_ => generate_constructor(rng, established_struct_types, env, target_type),
|
_ => generate_constructor(depth, rng, established_struct_types, env, target_type),
|
||||||
},
|
},
|
||||||
|
|
||||||
Type::Struct(_) => {
|
Type::Struct(_) => {
|
||||||
generate_constructor(rng, established_struct_types, env, target_type)
|
generate_constructor(depth, rng, established_struct_types, env, target_type)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ExpressionType::Constructor => {
|
ExpressionType::Constructor => {
|
||||||
generate_constructor(rng, established_struct_types, env, target_type)
|
generate_constructor(depth, rng, established_struct_types, env, target_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionType::Reference => {
|
ExpressionType::Reference => {
|
||||||
@@ -292,8 +309,13 @@ fn generate_expr(
|
|||||||
.get(new_target_type_idx)
|
.get(new_target_type_idx)
|
||||||
.expect("generated reasonable index")
|
.expect("generated reasonable index")
|
||||||
.clone();
|
.clone();
|
||||||
let (subexp, newreqs) =
|
let (subexp, newreqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(new_target_type));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(new_target_type),
|
||||||
|
);
|
||||||
requirements.extend(newreqs);
|
requirements.extend(newreqs);
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -309,8 +331,13 @@ fn generate_expr(
|
|||||||
let idx = rng.gen_range(0..new_targets.len());
|
let idx = rng.gen_range(0..new_targets.len());
|
||||||
let new_constant_type = new_targets.get(idx).expect("generates in bounds");
|
let new_constant_type = new_targets.get(idx).expect("generates in bounds");
|
||||||
let new_type = Type::Named(Name::manufactured(new_constant_type.name()));
|
let new_type = Type::Named(Name::manufactured(new_constant_type.name()));
|
||||||
let (subexpr, reqs) =
|
let (subexpr, reqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(new_type));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(new_type),
|
||||||
|
);
|
||||||
(
|
(
|
||||||
Expression::Cast(Location::manufactured(), ct.name(), Box::new(subexpr)),
|
Expression::Cast(Location::manufactured(), ct.name(), Box::new(subexpr)),
|
||||||
reqs,
|
reqs,
|
||||||
@@ -319,6 +346,7 @@ fn generate_expr(
|
|||||||
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let (subexpr, reqs) = generate_expr(
|
let (subexpr, reqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
rng,
|
rng,
|
||||||
established_struct_types,
|
established_struct_types,
|
||||||
env,
|
env,
|
||||||
@@ -349,6 +377,7 @@ fn generate_expr(
|
|||||||
|
|
||||||
established_struct_types.insert(name.clone(), new_fields.clone());
|
established_struct_types.insert(name.clone(), new_fields.clone());
|
||||||
let (subexpr, mut reqs) = generate_expr(
|
let (subexpr, mut reqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
rng,
|
rng,
|
||||||
established_struct_types,
|
established_struct_types,
|
||||||
env,
|
env,
|
||||||
@@ -365,6 +394,7 @@ fn generate_expr(
|
|||||||
|
|
||||||
Some((name, _)) => {
|
Some((name, _)) => {
|
||||||
let (subexpr, reqs) = generate_expr(
|
let (subexpr, reqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
rng,
|
rng,
|
||||||
established_struct_types,
|
established_struct_types,
|
||||||
env,
|
env,
|
||||||
@@ -382,9 +412,13 @@ fn generate_expr(
|
|||||||
|
|
||||||
ExpressionType::Call => match target_type {
|
ExpressionType::Call => match target_type {
|
||||||
Type::Named(ref x) => match ConstantType::from_str(x.current_name()) {
|
Type::Named(ref x) => match ConstantType::from_str(x.current_name()) {
|
||||||
Err(_) => {
|
Err(_) => genererate_call_to_function(
|
||||||
genererate_call_to_function(rng, established_struct_types, env, target_type)
|
depth,
|
||||||
}
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
target_type,
|
||||||
|
),
|
||||||
Ok(prim) if CALL_SHOULD_BE_PRIMITIVE.sample(rng) => {
|
Ok(prim) if CALL_SHOULD_BE_PRIMITIVE.sample(rng) => {
|
||||||
let options = prim.primitives_for();
|
let options = prim.primitives_for();
|
||||||
let idx = rng.gen_range(0..options.len());
|
let idx = rng.gen_range(0..options.len());
|
||||||
@@ -398,6 +432,7 @@ fn generate_expr(
|
|||||||
|
|
||||||
for possible_type in argtypes.iter() {
|
for possible_type in argtypes.iter() {
|
||||||
let (expr, new_prereqs) = generate_expr(
|
let (expr, new_prereqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
rng,
|
rng,
|
||||||
established_struct_types,
|
established_struct_types,
|
||||||
env,
|
env,
|
||||||
@@ -412,13 +447,17 @@ fn generate_expr(
|
|||||||
|
|
||||||
(retval, prereqs)
|
(retval, prereqs)
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => genererate_call_to_function(
|
||||||
genererate_call_to_function(rng, established_struct_types, env, target_type)
|
depth,
|
||||||
}
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
target_type,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
Type::Struct(_) => {
|
Type::Struct(_) => {
|
||||||
genererate_call_to_function(rng, established_struct_types, env, target_type)
|
genererate_call_to_function(depth, rng, established_struct_types, env, target_type)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -434,15 +473,20 @@ fn generate_expr(
|
|||||||
Some(generate_type(rng, established_struct_types))
|
Some(generate_type(rng, established_struct_types))
|
||||||
};
|
};
|
||||||
let (expr, new_prereqs) =
|
let (expr, new_prereqs) =
|
||||||
generate_expr(rng, established_struct_types, env, inner_type);
|
generate_expr(depth + 1, rng, established_struct_types, env, inner_type);
|
||||||
block.push_back(expr);
|
block.push_back(expr);
|
||||||
|
|
||||||
let mut new_work_queue: VecDeque<Requirement> = new_prereqs.into_iter().collect();
|
let mut new_work_queue: VecDeque<Requirement> = new_prereqs.into_iter().collect();
|
||||||
|
|
||||||
while let Some(next) = new_work_queue.pop_front() {
|
while let Some(next) = new_work_queue.pop_front() {
|
||||||
if let Requirement::Variable(name, varty) = next {
|
if let Requirement::Variable(name, varty) = next {
|
||||||
let (value, even_newer_reqs) =
|
let (value, even_newer_reqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(varty));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(varty),
|
||||||
|
);
|
||||||
|
|
||||||
block.push_front(Expression::Binding(
|
block.push_front(Expression::Binding(
|
||||||
Location::manufactured(),
|
Location::manufactured(),
|
||||||
@@ -465,6 +509,7 @@ fn generate_expr(
|
|||||||
ExpressionType::Binding => {
|
ExpressionType::Binding => {
|
||||||
let name = generate_name(rng);
|
let name = generate_name(rng);
|
||||||
let (expr, prereqs) = generate_expr(
|
let (expr, prereqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
rng,
|
rng,
|
||||||
established_struct_types,
|
established_struct_types,
|
||||||
env,
|
env,
|
||||||
@@ -497,6 +542,7 @@ fn generate_constant(rng: &mut TestRng, ct: ConstantType) -> Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_constructor(
|
fn generate_constructor(
|
||||||
|
depth: usize,
|
||||||
rng: &mut TestRng,
|
rng: &mut TestRng,
|
||||||
established_struct_types: &mut EstablishedStructMap,
|
established_struct_types: &mut EstablishedStructMap,
|
||||||
env: &mut ScopedMap<Name, Type>,
|
env: &mut ScopedMap<Name, Type>,
|
||||||
@@ -520,8 +566,13 @@ fn generate_constructor(
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (field_name, field_type) in fields.into_iter() {
|
for (field_name, field_type) in fields.into_iter() {
|
||||||
let (subexpr, reqs) =
|
let (subexpr, reqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(field_type));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(field_type),
|
||||||
|
);
|
||||||
requirements.extend(reqs.into_iter());
|
requirements.extend(reqs.into_iter());
|
||||||
field_assignments.push((field_name, subexpr));
|
field_assignments.push((field_name, subexpr));
|
||||||
}
|
}
|
||||||
@@ -560,8 +611,13 @@ fn generate_constructor(
|
|||||||
|
|
||||||
let mut field_assignments = vec![];
|
let mut field_assignments = vec![];
|
||||||
for (field_name, field_type) in fields.into_iter() {
|
for (field_name, field_type) in fields.into_iter() {
|
||||||
let (subexpr, reqs) =
|
let (subexpr, reqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(field_type));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(field_type),
|
||||||
|
);
|
||||||
requirements.extend(reqs.into_iter());
|
requirements.extend(reqs.into_iter());
|
||||||
field_assignments.push((field_name, subexpr));
|
field_assignments.push((field_name, subexpr));
|
||||||
}
|
}
|
||||||
@@ -573,6 +629,7 @@ fn generate_constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_function(
|
fn generate_function(
|
||||||
|
depth: usize,
|
||||||
rng: &mut TestRng,
|
rng: &mut TestRng,
|
||||||
established_struct_types: &mut EstablishedStructMap,
|
established_struct_types: &mut EstablishedStructMap,
|
||||||
env: &mut ScopedMap<Name, Type>,
|
env: &mut ScopedMap<Name, Type>,
|
||||||
@@ -588,7 +645,13 @@ fn generate_function(
|
|||||||
args.push((arg_name.clone(), Some(arg_type.clone())));
|
args.push((arg_name.clone(), Some(arg_type.clone())));
|
||||||
env.insert(arg_name, arg_type);
|
env.insert(arg_name, arg_type);
|
||||||
}
|
}
|
||||||
let (body, prereqs) = generate_expr(rng, established_struct_types, env, Some(ret.clone()));
|
let (body, prereqs) = generate_expr(
|
||||||
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(ret.clone()),
|
||||||
|
);
|
||||||
env.release_scope();
|
env.release_scope();
|
||||||
|
|
||||||
let function = Expression::Function(
|
let function = Expression::Function(
|
||||||
@@ -715,6 +778,7 @@ fn find_variables_with_type(env: &ScopedMap<Name, Type>, target_type: &Type) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn genererate_call_to_function(
|
fn genererate_call_to_function(
|
||||||
|
depth: usize,
|
||||||
rng: &mut TestRng,
|
rng: &mut TestRng,
|
||||||
established_struct_types: &mut EstablishedStructMap,
|
established_struct_types: &mut EstablishedStructMap,
|
||||||
env: &mut ScopedMap<Name, Type>,
|
env: &mut ScopedMap<Name, Type>,
|
||||||
@@ -728,8 +792,13 @@ fn genererate_call_to_function(
|
|||||||
|
|
||||||
for _ in 0..arg_count {
|
for _ in 0..arg_count {
|
||||||
let arg_type = generate_type(rng, established_struct_types);
|
let arg_type = generate_type(rng, established_struct_types);
|
||||||
let (arg_expr, new_reqs) =
|
let (arg_expr, new_reqs) = generate_expr(
|
||||||
generate_expr(rng, established_struct_types, env, Some(arg_type.clone()));
|
depth + 1,
|
||||||
|
rng,
|
||||||
|
established_struct_types,
|
||||||
|
env,
|
||||||
|
Some(arg_type.clone()),
|
||||||
|
);
|
||||||
arg_types.push(arg_type);
|
arg_types.push(arg_type);
|
||||||
arg_exprs.push(arg_expr);
|
arg_exprs.push(arg_expr);
|
||||||
prereqs.extend(new_reqs.into_iter());
|
prereqs.extend(new_reqs.into_iter());
|
||||||
|
|||||||
@@ -7,35 +7,37 @@ impl Program {
|
|||||||
let mut result = allocator.nil();
|
let mut result = allocator.nil();
|
||||||
|
|
||||||
for definition in self.structures.values() {
|
for definition in self.structures.values() {
|
||||||
result = result
|
let mut interior = allocator.nil();
|
||||||
.append(allocator.text("struct"))
|
|
||||||
|
for (name, ty) in definition.fields.iter() {
|
||||||
|
let mut type_bit = allocator.nil();
|
||||||
|
|
||||||
|
if let Some(ty) = ty {
|
||||||
|
type_bit = allocator
|
||||||
|
.text(":")
|
||||||
|
.append(allocator.space())
|
||||||
|
.append(ty.pretty(allocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
interior = interior
|
||||||
|
.append(name.original_name().to_string())
|
||||||
|
.append(type_bit)
|
||||||
|
.append(allocator.text(";"))
|
||||||
|
.append(allocator.hardline());
|
||||||
|
}
|
||||||
|
|
||||||
|
interior = interior.indent(9);
|
||||||
|
|
||||||
|
let start = allocator.text("struct")
|
||||||
.append(allocator.space())
|
.append(allocator.space())
|
||||||
.append(allocator.text(definition.name.original_name().to_string()))
|
.append(allocator.text(definition.name.original_name().to_string()))
|
||||||
.append(allocator.space())
|
.append(allocator.space())
|
||||||
.append(allocator.text("{"))
|
.append(allocator.text("{"));
|
||||||
.append(allocator.hardline())
|
|
||||||
.append(
|
|
||||||
allocator
|
|
||||||
.concat(definition.fields.iter().map(|(name, ty)| {
|
|
||||||
let mut type_bit = allocator.nil();
|
|
||||||
|
|
||||||
if let Some(ty) = ty {
|
let conclusion = allocator.text("}")
|
||||||
type_bit = allocator
|
|
||||||
.text(":")
|
|
||||||
.append(allocator.space())
|
|
||||||
.append(ty.pretty(allocator));
|
|
||||||
}
|
|
||||||
|
|
||||||
allocator
|
|
||||||
.text(name.original_name().to_string())
|
|
||||||
.append(type_bit)
|
|
||||||
.append(allocator.text(";"))
|
|
||||||
.append(allocator.hardline())
|
|
||||||
}))
|
|
||||||
.nest(2),
|
|
||||||
)
|
|
||||||
.append(allocator.text("}"))
|
|
||||||
.append(allocator.hardline());
|
.append(allocator.hardline());
|
||||||
|
|
||||||
|
result = result.append(start.append(interior).append(conclusion));
|
||||||
}
|
}
|
||||||
|
|
||||||
for definition in self.functions.values() {
|
for definition in self.functions.values() {
|
||||||
@@ -111,8 +113,7 @@ impl TopLevel {
|
|||||||
.append(type_bit)
|
.append(type_bit)
|
||||||
.append(allocator.text(";"))
|
.append(allocator.text(";"))
|
||||||
.append(allocator.hardline())
|
.append(allocator.hardline())
|
||||||
}))
|
})).indent(2)
|
||||||
.nest(2),
|
|
||||||
)
|
)
|
||||||
.append(allocator.text("}"))
|
.append(allocator.text("}"))
|
||||||
.append(allocator.hardline()),
|
.append(allocator.hardline()),
|
||||||
@@ -127,6 +128,8 @@ impl Expression {
|
|||||||
Expression::Constructor(_, name, fields) => allocator
|
Expression::Constructor(_, name, fields) => allocator
|
||||||
.text(name.to_string())
|
.text(name.to_string())
|
||||||
.append(allocator.space())
|
.append(allocator.space())
|
||||||
|
.append(allocator.text("{"))
|
||||||
|
.append(allocator.hardline())
|
||||||
.append(
|
.append(
|
||||||
allocator
|
allocator
|
||||||
.concat(fields.iter().map(|(n, e)| {
|
.concat(fields.iter().map(|(n, e)| {
|
||||||
@@ -138,9 +141,9 @@ impl Expression {
|
|||||||
.append(allocator.text(";"))
|
.append(allocator.text(";"))
|
||||||
.append(allocator.hardline())
|
.append(allocator.hardline())
|
||||||
}))
|
}))
|
||||||
.nest(2)
|
.indent(2)
|
||||||
.braces(),
|
)
|
||||||
),
|
.append(allocator.text("}")),
|
||||||
Expression::Reference(var) => allocator.text(var.to_string()),
|
Expression::Reference(var) => allocator.text(var.to_string()),
|
||||||
Expression::FieldRef(_, val, field) => val
|
Expression::FieldRef(_, val, field) => val
|
||||||
.pretty(allocator)
|
.pretty(allocator)
|
||||||
@@ -152,27 +155,55 @@ impl Expression {
|
|||||||
.append(e.pretty(allocator)),
|
.append(e.pretty(allocator)),
|
||||||
Expression::Primitive(_, op) => allocator.text(op.original_name().to_string()),
|
Expression::Primitive(_, op) => allocator.text(op.original_name().to_string()),
|
||||||
Expression::Call(_, fun, args) => {
|
Expression::Call(_, fun, args) => {
|
||||||
let args = args.iter().map(|x| x.pretty(allocator));
|
let mut args = args.iter().map(|x| x.pretty(allocator)).collect::<Vec<_>>();
|
||||||
let comma_sepped_args = allocator.intersperse(args, allocator.text(","));
|
|
||||||
fun.pretty(allocator).append(comma_sepped_args.parens())
|
match fun.as_ref() {
|
||||||
|
Expression::Primitive(_, name) if ["/", "*", "+", "-"].contains(&name.current_name()) && args.len() == 2 => {
|
||||||
|
let second = args.pop().unwrap();
|
||||||
|
args.pop()
|
||||||
|
.unwrap()
|
||||||
|
.append(allocator.space())
|
||||||
|
.append(allocator.text(name.current_name().to_string()))
|
||||||
|
.append(allocator.space())
|
||||||
|
.append(second)
|
||||||
|
.parens()
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::Primitive(_, name) if ["negate"].contains(&name.current_name()) && args.len() == 1 =>
|
||||||
|
allocator.text("-").append(args.pop().unwrap()),
|
||||||
|
|
||||||
|
Expression::Primitive(_, name) if ["print"].contains(&&name.current_name()) && args.len() == 1 =>
|
||||||
|
allocator.text("print")
|
||||||
|
.append(allocator.space())
|
||||||
|
.append(args.pop().unwrap()),
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
let comma_sepped_args = allocator.intersperse(args, allocator.text(","));
|
||||||
|
fun.pretty(allocator).append(comma_sepped_args.parens())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Expression::Block(_, stmts) => match stmts.split_last() {
|
Expression::Block(_, stmts) => match stmts.split_last() {
|
||||||
None => allocator.text("()"),
|
None => allocator.text("()"),
|
||||||
Some((last, &[])) => last.pretty(allocator),
|
Some((last, &[])) => last.pretty(allocator),
|
||||||
Some((last, start)) => {
|
Some((last, start)) => {
|
||||||
let mut result = allocator.text("{").append(allocator.hardline());
|
let beginning = allocator.text("{").append(allocator.hardline());
|
||||||
|
let mut inner = allocator.nil();
|
||||||
|
|
||||||
for stmt in start.iter() {
|
for stmt in start.iter() {
|
||||||
result = result
|
inner = inner
|
||||||
.append(stmt.pretty(allocator))
|
.append(stmt.pretty(allocator))
|
||||||
.append(allocator.text(";"))
|
.append(allocator.text(";"))
|
||||||
.append(allocator.hardline());
|
.append(allocator.hardline());
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
inner = inner
|
||||||
.append(last.pretty(allocator))
|
.append(last.pretty(allocator))
|
||||||
.append(allocator.hardline())
|
.append(allocator.hardline());
|
||||||
.append(allocator.text("}"))
|
|
||||||
|
inner = inner.indent(2);
|
||||||
|
|
||||||
|
beginning.append(inner).append(allocator.text("}"))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expression::Binding(_, var, expr) => allocator
|
Expression::Binding(_, var, expr) => allocator
|
||||||
|
|||||||
Reference in New Issue
Block a user