Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ val it = [4,6,8] : int list
* [Change log](CHANGELOG.md)
* Reading [test scripts](tests/script)
can be instructive; try, for example,
[builtIn.smli](tests/script/builtIn.smli)
[built-in.smli](tests/script/built-in.smli)

## More information

Expand Down
133 changes: 69 additions & 64 deletions src/compile/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,80 +606,85 @@ impl Pretty {
return self
.pretty1(buf, indent, line_end, depth, &args[0], value, 0, 0);
}
let list = match &value {

let mut print_wrapped =
|prefix: &str, type_arg: &Type, inner_val: &Val| {
self.pretty_raw(buf, indent, line_end, depth, prefix)?;
let need_parens = matches!(type_arg, Type::Data(..));

if need_parens { buf.push('('); }
self.pretty1(
buf,
indent,
line_end,
depth,
type_arg,
inner_val,
0,
0
)?;
if need_parens { buf.push(')'); }
Ok(())
};

match value {
Val::Fn(f) => {
let name = match f {
let fname = match f {
BuiltInFunction::OrderEqual => "EQUAL",
BuiltInFunction::OrderGreater => "GREATER",
BuiltInFunction::OrderLess => "LESS",
_ => panic!("Expected list"),
};
return self.pretty_raw(buf, indent, line_end, depth, name);
}
Val::List(list) => list,
Val::Order(o) => {
return self.pretty_raw(buf, indent, line_end, depth, o.name());
}
Val::Inl(v) => {
self.pretty_raw(buf, indent, line_end, depth, "INL ")?;
return self
.pretty1(buf, indent, line_end, depth, &args[0], v, 0, 0);
}
Val::Inr(v) => {
self.pretty_raw(buf, indent, line_end, depth, "INR ")?;
return self
.pretty1(buf, indent, line_end, depth, &args[1], v, 0, 0);
}
Val::Some(v) => {
self.pretty_raw(buf, indent, line_end, depth, "SOME ")?;
return self
.pretty1(buf, indent, line_end, depth, &args[0], v, 0, 0);
}
Val::Unit => {
if name == "option" {
return self
.pretty_raw(buf, indent, line_end, depth, "NONE");
self.pretty_raw(buf, indent, line_end, depth, fname)
}
Val::Order(o) =>
self.pretty_raw(buf, indent, line_end, depth, o.name()),

Val::Inl(v) =>
print_wrapped("INL ", &args[0], v),
Val::Inr(v) =>
print_wrapped("INR ", &args[1], v),
Val::Some(v) =>
print_wrapped("SOME ", &args[0], v),

Val::Unit if name == "option" =>
self.pretty_raw(buf, indent, line_end, depth, "NONE"),

// 5. Handle Lists (Vector, Bag, or Generic Constructors)
Val::List(list) => {
if name == "vector" || name == "bag" {
if name == "vector" { buf.push('#'); }
let arg_type = args.first().unwrap();
return self.print_list(
buf,
indent,
line_end,
depth,
arg_type,
list
);
}

let ty_con_name = list.first().unwrap().expect_string();
buf.push_str(&ty_con_name);

if let Some(arg) = list.get(1) {
buf.push(' ');
let need_parens = matches!(arg, Val::List(_));
if need_parens { buf.push('('); }

self.pretty2(
buf, indent, line_end, depth + 1,
&Type::Primitive(PrimitiveType::String),
arg, 0, 0
)?;

if need_parens { buf.push(')'); }
}
panic!("Expected list")
Ok(())
}
_ => panic!("Expected list"),
};
if name == "vector" {
let arg_type = args.first().unwrap();
buf.push('#');
return self
.print_list(buf, indent, line_end, depth, arg_type, list);
}
if name == "bag" {
let arg_type = args.first().unwrap();
return self
.print_list(buf, indent, line_end, depth, arg_type, list);
}
let ty_con_name = list.first().unwrap().expect_string();
buf.push_str(&ty_con_name);
if let Some(arg) = list.get(1) {
// This is a parameterized constructor. (For example, NONE is
// not parameterized, SOME x is parameterized with x.)
buf.push(' ');
let need_parentheses = matches!(arg, Val::List(_));
if need_parentheses {
buf.push('(');
}
self.pretty2(
buf,
indent,
line_end,
depth + 1,
&Type::Primitive(PrimitiveType::String),
arg,
0,
0,
)?;
if need_parentheses {
buf.push(')');
}
}
Ok(())
}

fn pretty_type(
Expand Down
9 changes: 9 additions & 0 deletions tests/script/datatype.smli
Original file line number Diff line number Diff line change
Expand Up @@ -392,4 +392,13 @@ datatype `foo bar baz` = `Foo Bar` of {a: int, b: string} | Baz of int;
`Foo Bar`;
> val it = fn : {a:int, b:string} -> foo bar baz

(*) Nested data types.
set("mode", "evaluate");
> val it = () : unit
SOME (SOME 1);
> val it = SOME (SOME 1) : int option option
SOME (INL (INR 1));
> val it = SOME (INL (INR 1)) : (('a,int) either,'b) either option
SOME [SOME (SOME 1), NONE];
> val it = SOME [SOME (SOME 1),NONE] : int option option list option
(*) End datatype.smli
Loading