Skip to content

Commit

Permalink
Changes the structure of Document, try to fix depending code
Browse files Browse the repository at this point in the history
Disclaimer: this code currently does not compile due to some borrow problems.
I have fixed as much errors as I can.
  • Loading branch information
scrabsha committed Jun 3, 2020
1 parent 887fca0 commit 3ca5535
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 184 deletions.
81 changes: 41 additions & 40 deletions src/erl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl<'a> Env<'a> {
}
}

pub fn local_var_name(&mut self, name: String) -> Document {
pub fn local_var_name(&mut self, name: String) -> Document<'static> {
match self.current_scope_vars.get(&name) {
None => {
self.current_scope_vars.insert(name.clone(), 0);
Expand All @@ -80,7 +80,7 @@ impl<'a> Env<'a> {
}
}

pub fn next_local_var_name(&mut self, name: String) -> Document {
pub fn next_local_var_name(&mut self, name: String) -> Document<'static> {
let next = self.erl_function_scope_vars.get(&name).map_or(0, |i| i + 1);
self.erl_function_scope_vars.insert(name.clone(), next);
self.current_scope_vars.insert(name.clone(), next);
Expand Down Expand Up @@ -190,7 +190,7 @@ pub fn module(module: &TypedModule) -> String {
.format(80)
}

fn statement(statement: &TypedStatement, module: &[String]) -> Option<Document> {
fn statement<'a>(statement: &'a TypedStatement, module: &'a [String]) -> Option<Document<'a>> {
match statement {
Statement::TypeAlias { .. } => None,
Statement::CustomType { .. } => None,
Expand All @@ -217,7 +217,7 @@ fn statement(statement: &TypedStatement, module: &[String]) -> Option<Document>
}
}

fn mod_fun(name: &str, args: &[TypedArg], body: &TypedExpr, module: &[String]) -> Document {
fn mod_fun<'a>(name: &str, args: &'a [TypedArg], body: &'a TypedExpr, module: &'a [String]) -> Document<'a> {
let mut env = Env::new(module);

atom(name.to_string())
Expand All @@ -227,7 +227,7 @@ fn mod_fun(name: &str, args: &[TypedArg], body: &TypedExpr, module: &[String]) -
.append(".")
}

fn fun_args(args: &[TypedArg], env: &mut Env) -> Document {
fn fun_args<'a>(args: &[TypedArg], env: &mut Env) -> Document<'a> {
wrap_args(args.into_iter().map(|a| match &a.names {
ArgNames::Discard { .. } | ArgNames::LabelledDiscard { .. } => "_".to_doc(),
ArgNames::Named { name } | ArgNames::NamedLabelled { name, .. } => {
Expand All @@ -236,13 +236,13 @@ fn fun_args(args: &[TypedArg], env: &mut Env) -> Document {
}))
}

fn call_args(args: &[CallArg<TypedExpr>], env: &mut Env) -> Document {
fn call_args<'a>(args: &'a [CallArg<TypedExpr>], env: &mut Env<'a>) -> Document<'a> {
wrap_args(args.into_iter().map(|arg| wrap_expr(&arg.value, env)))
}

fn wrap_args<I>(args: I) -> Document
fn wrap_args<'a, I>(args: I) -> Document<'a>
where
I: Iterator<Item = Document>,
I: Iterator<Item = Document<'a>>,
{
break_("", "")
.append(concat(args.intersperse(delim(","))))
Expand All @@ -252,7 +252,7 @@ where
.group()
}

fn atom(value: String) -> Document {
fn atom<'a>(value: String) -> Document<'a> {
use regex::Regex;
lazy_static! {
static ref RE: Regex = Regex::new(r"^[a-z][a-z0-9_@]*$").unwrap();
Expand All @@ -274,22 +274,22 @@ fn string(value: &str) -> Document {
value.to_doc().surround("<<\"", "\"/utf8>>")
}

fn tuple(elems: impl Iterator<Item = Document>) -> Document {
fn tuple<'a>(elems: impl Iterator<Item = Document<'a>>) -> Document<'a> {
concat(elems.intersperse(delim(",")))
.nest_current()
.surround("{", "}")
.group()
}

fn seq(first: &TypedExpr, then: &TypedExpr, env: &mut Env) -> Document {
fn seq<'a>(first: &'a TypedExpr, then: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
force_break()
.append(expr(first, env))
.append(",")
.append(line())
.append(expr(then, env))
}

fn bin_op(name: &BinOp, left: &TypedExpr, right: &TypedExpr, env: &mut Env) -> Document {
fn bin_op<'a>(name: &BinOp, left: &'a TypedExpr, right: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
let op = match name {
BinOp::And => "andalso",
BinOp::Or => "orelse",
Expand Down Expand Up @@ -327,7 +327,7 @@ fn bin_op(name: &BinOp, left: &TypedExpr, right: &TypedExpr, env: &mut Env) -> D
.append(right_expr)
}

fn pipe(value: &TypedExpr, fun: &TypedExpr, env: &mut Env) -> Document {
fn pipe<'a>(value: &TypedExpr, fun: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
let arg = CallArg {
label: None,
location: Default::default(),
Expand All @@ -337,7 +337,7 @@ fn pipe(value: &TypedExpr, fun: &TypedExpr, env: &mut Env) -> Document {
call(fun, &[arg], env)
}

fn try_(value: &TypedExpr, pat: &TypedPattern, then: &TypedExpr, env: &mut Env) -> Document {
fn try_<'a>(value: &'a TypedExpr, pat: &'a TypedPattern, then: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
let try_error_name = "gleam@try_error";

"case "
Expand Down Expand Up @@ -366,7 +366,7 @@ fn try_(value: &TypedExpr, pat: &TypedPattern, then: &TypedExpr, env: &mut Env)
.group()
}

fn let_(value: &TypedExpr, pat: &TypedPattern, then: &TypedExpr, env: &mut Env) -> Document {
fn let_<'a>(value: &'a TypedExpr, pat: &'a TypedPattern, then: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
let body = expr(value, env);
pattern(pat, env)
.append(" = ")
Expand All @@ -376,7 +376,7 @@ fn let_(value: &TypedExpr, pat: &TypedPattern, then: &TypedExpr, env: &mut Env)
.append(expr(then, env))
}

fn pattern(p: &TypedPattern, env: &mut Env) -> Document {
fn pattern<'a>(p: &'a TypedPattern, env: &mut Env<'a>) -> Document<'a> {
match p {
Pattern::Nil { .. } => "[]".to_doc(),

Expand Down Expand Up @@ -414,7 +414,7 @@ fn float(value: &str) -> Document {
}
}

fn pattern_list_cons(head: &TypedPattern, tail: &TypedPattern, env: &mut Env) -> Document {
fn pattern_list_cons<'a>(head: &'a TypedPattern, tail: &'a TypedPattern, env: &mut Env<'a>) -> Document<'a> {
list_cons(head, tail, env, pattern, |expr| match expr {
Pattern::Nil { .. } => ListType::Nil,

Expand All @@ -424,7 +424,7 @@ fn pattern_list_cons(head: &TypedPattern, tail: &TypedPattern, env: &mut Env) ->
})
}

fn expr_list_cons(head: &TypedExpr, tail: &TypedExpr, env: &mut Env) -> Document {
fn expr_list_cons<'a>(head: &'a TypedExpr, tail: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
list_cons(head, tail, env, wrap_expr, |expr| match expr {
TypedExpr::ListNil { .. } => ListType::Nil,

Expand All @@ -434,16 +434,17 @@ fn expr_list_cons(head: &TypedExpr, tail: &TypedExpr, env: &mut Env) -> Document
})
}

fn list_cons<ToDoc, Categorise, Elem>(
head: Elem,
tail: Elem,
env: &mut Env,
fn list_cons<'a, ToDoc, Categorise, Elem>(
head: &'a Elem,
tail: &'a Elem,
env: &mut Env<'a>,
to_doc: ToDoc,
categorise_element: Categorise,
) -> Document
) -> Document<'a>
where
ToDoc: Fn(Elem, &mut Env) -> Document,
Categorise: Fn(Elem) -> ListType<Elem, Elem>,
Elem: 'a,
ToDoc: Fn(&'a Elem, &mut Env<'a>) -> Document<'a>,
Categorise: Fn(&'a Elem) -> ListType<&'a Elem, &'a Elem>,
{
let mut elems = vec![head];
let final_tail = collect_cons(tail, &mut elems, categorise_element);
Expand Down Expand Up @@ -486,7 +487,7 @@ enum ListType<E, T> {
NotList(T),
}

fn var(name: &str, constructor: &ValueConstructor, env: &mut Env) -> Document {
fn var<'a>(name: &str, constructor: &ValueConstructor, env: &mut Env<'a>) -> Document<'a> {
match &constructor.variant {
ValueConstructorVariant::Record {
name: record_name, ..
Expand Down Expand Up @@ -525,7 +526,7 @@ fn var(name: &str, constructor: &ValueConstructor, env: &mut Env) -> Document {
}
}

fn tag_tuple_pattern(name: &str, args: &[CallArg<TypedPattern>], env: &mut Env) -> Document {
fn tag_tuple_pattern<'a>(name: &str, args: &'a [CallArg<TypedPattern>], env: &mut Env<'a>) -> Document<'a> {
if args.is_empty() {
atom(name.to_snake_case())
} else {
Expand All @@ -536,7 +537,7 @@ fn tag_tuple_pattern(name: &str, args: &[CallArg<TypedPattern>], env: &mut Env)
}
}

fn clause(clause: &TypedClause, env: &mut Env) -> Document {
fn clause<'a>(clause: &'a TypedClause, env: &mut Env<'a>) -> Document<'a> {
let Clause {
guard,
pattern: pat,
Expand Down Expand Up @@ -565,14 +566,14 @@ fn clause(clause: &TypedClause, env: &mut Env) -> Document {
concat(docs)
}

fn optional_clause_guard(guard: Option<&TypedClauseGuard>, env: &mut Env) -> Document {
fn optional_clause_guard<'a>(guard: Option<&'a TypedClauseGuard>, env: &mut Env<'a>) -> Document<'a> {
match guard {
Some(guard) => " when ".to_doc().append(bare_clause_guard(guard, env)),
None => nil(),
}
}

fn bare_clause_guard(guard: &TypedClauseGuard, env: &mut Env) -> Document {
fn bare_clause_guard<'a>(guard: &'a TypedClauseGuard, env: &mut Env<'a>) -> Document<'a> {
match guard {
ClauseGuard::Or { left, right, .. } => clause_guard(left.as_ref(), env)
.append(" orelse ")
Expand Down Expand Up @@ -649,7 +650,7 @@ fn bare_clause_guard(guard: &TypedClauseGuard, env: &mut Env) -> Document {
}
}

fn clause_guard(guard: &TypedClauseGuard, env: &mut Env) -> Document {
fn clause_guard<'a>(guard: &'a TypedClauseGuard, env: &mut Env<'a>) -> Document<'a> {
match guard {
// Binary ops are wrapped in parens
ClauseGuard::Or { .. }
Expand Down Expand Up @@ -678,7 +679,7 @@ fn clause_guard(guard: &TypedClauseGuard, env: &mut Env) -> Document {
}
}

fn clauses(cs: &[TypedClause], env: &mut Env) -> Document {
fn clauses<'a>(cs: &'a [TypedClause], env: &mut Env<'a>) -> Document<'a> {
concat(
cs.into_iter()
.map(|c| {
Expand All @@ -691,7 +692,7 @@ fn clauses(cs: &[TypedClause], env: &mut Env) -> Document {
)
}

fn case(subjects: &[TypedExpr], cs: &[TypedClause], env: &mut Env) -> Document {
fn case<'a>(subjects: &'a [TypedExpr], cs: &'a [TypedClause], env: &mut Env<'a>) -> Document<'a> {
let subjects_doc = if subjects.len() == 1 {
let subject = subjects
.get(0)
Expand All @@ -710,7 +711,7 @@ fn case(subjects: &[TypedExpr], cs: &[TypedClause], env: &mut Env) -> Document {
.group()
}

fn call(fun: &TypedExpr, args: &[CallArg<TypedExpr>], env: &mut Env) -> Document {
fn call<'a>(fun: &'a TypedExpr, args: &'a [CallArg<TypedExpr>], env: &mut Env<'a>) -> Document<'a> {
match fun {
TypedExpr::ModuleSelect {
constructor: ModuleValueConstructor::Record { name, .. },
Expand Down Expand Up @@ -816,15 +817,15 @@ fn begin_end(document: Document) -> Document {

/// Same as expr, expect it wraps seq, let, etc in begin end
///
fn wrap_expr(expression: &TypedExpr, env: &mut Env) -> Document {
fn wrap_expr<'a>(expression: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
match &expression {
TypedExpr::Seq { .. } => begin_end(expr(expression, env)),
TypedExpr::Let { .. } => begin_end(expr(expression, env)),
_ => expr(expression, env),
}
}

fn expr(expression: &TypedExpr, env: &mut Env) -> Document {
fn expr<'a>(expression: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
match expression {
TypedExpr::ListNil { .. } => "[]".to_doc(),
TypedExpr::Todo { .. } => "erlang:error({gleam_error, todo})".to_doc(),
Expand Down Expand Up @@ -903,15 +904,15 @@ fn expr(expression: &TypedExpr, env: &mut Env) -> Document {
}
}

fn tuple_index(tuple: &TypedExpr, index: u64, env: &mut Env) -> Document {
fn tuple_index<'a>(tuple: &'a TypedExpr, index: u64, env: &mut Env<'a>) -> Document<'a> {
use std::iter::once;
let index_doc = format!("{}", (index + 1)).to_doc();
let tuple_doc = expr(tuple, env);
let iter = once(index_doc).chain(once(tuple_doc));
"erlang:element".to_doc().append(wrap_args(iter))
}

fn module_select_fn(typ: Arc<crate::typ::Type>, module_name: &[String], label: &str) -> Document {
fn module_select_fn<'a>(typ: Arc<crate::typ::Type>, module_name: &[String], label: &str) -> Document<'a> {
match crate::typ::collapse_links(typ).as_ref() {
crate::typ::Type::Fn { args, .. } => "fun "
.to_doc()
Expand All @@ -930,7 +931,7 @@ fn module_select_fn(typ: Arc<crate::typ::Type>, module_name: &[String], label: &
}
}

fn fun(args: &[TypedArg], body: &TypedExpr, env: &mut Env) -> Document {
fn fun<'a>(args: &[TypedArg], body: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> {
"fun"
.to_doc()
.append(fun_args(args, env).append(" ->"))
Expand All @@ -948,7 +949,7 @@ fn incrementing_args_list(arity: usize) -> String {
.collect()
}

fn external_fun(name: &str, module: &str, fun: &str, arity: usize) -> Document {
fn external_fun<'a>(name: &'a str, module: &'a str, fun: &'a str, arity: usize) -> Document<'a> {
let chars: String = incrementing_args_list(arity);

atom(name.to_string())
Expand Down
Loading

0 comments on commit 3ca5535

Please sign in to comment.