Skip to content
Merged
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
3 changes: 3 additions & 0 deletions docs/generated/minlam.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ flowchart LR
MinExpTable --entries--> MinExp
MinLam --args--> SymbolList
MinLam --exp--> MinExp
MinLam --cc--> bool
MinExprList --exp--> MinExp
MinExprList --next--> MinExprList
MinPrimApp --type--> MinPrimOp
Expand All @@ -15,6 +16,7 @@ MinPrimApp --exp2--> MinExp
MinApply --function--> MinExp
MinApply --args--> MinExprList
MinApply --isBuiltin--> bool
MinApply --cc--> bool
MinIff --condition--> MinExp
MinIff --consequent--> MinExp
MinIff --alternative--> MinExp
Expand Down Expand Up @@ -53,6 +55,7 @@ MinExp --bindings--> MinBindings
MinExp --callCC--> MinExp
MinExp --character--> character
MinExp --cond--> MinCond
MinExp --done--> void_ptr
MinExp --iff--> MinIff
MinExp --lam--> MinLam
MinExp --letRec--> MinLetRec
Expand Down
1 change: 1 addition & 0 deletions docs/generated/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SymbolEnv --parent--> SymbolEnv
SymbolEnv --bindings--> SymbolSet
SCharVec["(SCharVec)"] --entries--> schar
WCharVec["(WCharVec)"] --entries--> character
SymbolVec["(SymbolVec)"] --entries--> HashSymbol
StringArray["StringArray[]"] --entries--> string
WCharArray["WCharArray[]"] --entries--> character
UCharArray["UCharArray[]"] --entries--> byte
Expand Down
11 changes: 11 additions & 0 deletions fn/rewrite/closure-convert.fn
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ import list operator "_|>_";

// https://matt.might.net/articles/closure-conversion/

// How to avoid having to declare extra types just to support closure conversion?
// I'm thinking make_env is obviously just make_vec, likewise make_closure.
// env_ref becomes vec, lambdac becomes lambda.
// The `(VEC index vector)` needs to know the index of the var in the vector.
// That can work if we keep an additional IntMap from fv to index, and sort
// by that when creating the make_vec env.
// apply closure is just `(λ (vec . args) (apply (VEC 0 vec) (cons (VEC 1 vec) args)))`
// How to optimize that?
// minApplyClosure(vec, args) |-->
// newMinApply(newMinPrimApp(MINPRIMOP_TYPE_VEC, 0, vec),
// newMinExprList(newMinPrimApp(MINPRIMOP_TYPE_VEC, 1, vec), args))
fn closure_convert {
(exp=M.lambda(params, body)) {
let
Expand Down
4 changes: 3 additions & 1 deletion fn/rewrite/test_harness.fn
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ let
link "closure-convert.fn" as CC;
link "curry.fn" as C;
link "uncurry.fn" as U;
link "transform.fn" as TR;
in
list.for_each(fn {
(';' @ s) {
Expand Down Expand Up @@ -61,4 +62,5 @@ in
M.print_expr(h);
puts("\n\n")
}
}, Samples.data());
}, Samples.data());
print typeof(TR._transform);
42 changes: 21 additions & 21 deletions fn/rewrite/transform.fn
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ link "minexpr.fn" as M;
link "../listutils.fn" as list;
import list operators;

// (M.expr -> M.expr) -> M.expr -> M.expr
// (exp -> exp) -> exp -> exp
fn bottom_up(f, exp) {
f(_transform(bottom_up(f), exp))
f(_transform(bottom_up, f, exp))
}

// (M.expr -> M.expr) -> M.expr -> M.expr
// (exp -> exp) -> exp -> exp
fn top_down(f, exp) {
_transform(top_down(f), f(exp))
_transform(top_down, f, f(exp))
}

// (M.expr -> M.expr) -> M.expr -> M.expr
fn _transform(t, exp) {
// ((exp -> exp) -> exp -> exp) -> (exp -> exp) -> exp -> exp
fn _transform(t, a, exp) {
switch (exp) {

(M.amb_expr(e1, e2)) {
M.amb_expr(t(e1), t(e2))
M.amb_expr(t(a, e1), t(a, e2))
}

(M.back_expr) |
Expand All @@ -31,59 +31,59 @@ fn _transform(t, exp) {


(M.apply_closure(fun, args)) {
M.apply_closure(t(fun), args |> t)
M.apply_closure(t(a, fun), args |> t(a))
}

(M.apply(fun, args)) {
M.apply(t(fun), args |> t)
M.apply(t(a, fun), args |> t(a))
}

(M.callcc_expr(e)) {
M.callcc_expr(t(e))
M.callcc_expr(t(a, e))
}

(M.cond_expr(test, branches)) {
M.cond_expr(t(test), branches |> t && t)
M.cond_expr(t(a, test), branches |> t(a) && t(a))
}

(M.env_ref(e, s)) {
M.env_ref(t(e), s)
M.env_ref(t(a, e), s)
}

(M.if_expr(test, consequent, alternative)) {
M.if_expr(t(test), t(consequent), t(alternative))
M.if_expr(t(a, test), t(a, consequent), t(a, alternative))
}

(M.lambda(params, body)) {
M.lambda(params, t(body))
M.lambda(params, t(a, body))
}

(M.lambdac(params, body)) {
M.lambdac(params, t(body))
M.lambdac(params, t(a, body))
}

(M.letrec_expr(bindings, body)) {
M.letrec_expr(bindings |> identity && (t && identity), t(body))
M.letrec_expr(bindings |> identity && (t(a) && identity), t(a, body))
}

(M.make_closure(lam, env)) {
M.make_closure(t(lam), t(env))
M.make_closure(t(a, lam), t(a, env))
}

(M.make_env(bindings)) {
M.make_env(bindings |> identity && t)
M.make_env(bindings |> identity && t(a))
}

(M.make_vec(size, elements)) {
M.make_vec(size, elements |> t)
M.make_vec(size, elements |> t(a))
}

(M.match_cases(e, cases)) {
M.match_cases(t(e), cases |> identity && t)
M.match_cases(t(a, e), cases |> identity && t(a))
}

(M.sequence(exps)) {
M.sequence(exps |> t)
M.sequence(exps |> t(a))
}

(_) {
Expand Down
57 changes: 30 additions & 27 deletions src/lambda_desugar.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static MinExp *desugarLamMakeTuple(LamExp *);
static MinExp *desugarLamTag(LamExp *);
static MinExp *desugarLamTupleIndex(LamExp *);
static MinExp *desugarLamTypeDefs(LamExp *);
static MinExp *_desugarLamExp(LamExp *);

static MinLam *desugarLamLam(LamLam *node);
static SymbolList *desugarLamVarList(SymbolList *node);
Expand Down Expand Up @@ -133,9 +134,9 @@ static MinPrimApp *desugarLamPrimApp(LamPrimApp *node) {
return NULL;
}

MinExp *new_exp1 = desugarLamExp(node->exp1);
MinExp *new_exp1 = _desugarLamExp(node->exp1);
int save = PROTECT(new_exp1);
MinExp *new_exp2 = desugarLamExp(node->exp2);
MinExp *new_exp2 = _desugarLamExp(node->exp2);
PROTECT(new_exp2);
MinPrimApp *result = newMinPrimApp(CPI(node), desugarLamPrimOp(node->type),
new_exp1, new_exp2);
Expand All @@ -153,7 +154,7 @@ static MinLam *desugarLamLam(LamLam *node) {

SymbolList *params = desugarLamVarList(node->args);
int save = PROTECT(params);
MinExp *body = desugarLamExp(node->exp);
MinExp *body = _desugarLamExp(node->exp);
PROTECT(body);
MinLam *result = newMinLam(CPI(node), params, body);
UNPROTECT(save);
Expand All @@ -170,7 +171,7 @@ static MinExprList *desugarLamSequence(LamSequence *node) {

MinExprList *next = desugarLamSequence(node->next);
int save = PROTECT(next);
MinExp *exp = desugarLamExp(node->exp);
MinExp *exp = _desugarLamExp(node->exp);
PROTECT(exp);
MinExprList *result = newMinExprList(CPI(node), exp, next);
UNPROTECT(save);
Expand All @@ -187,7 +188,7 @@ static MinExprList *desugarLamArgs(LamArgs *node) {

MinExprList *next = desugarLamArgs(node->next);
int save = PROTECT(next);
MinExp *exp = desugarLamExp(node->exp);
MinExp *exp = _desugarLamExp(node->exp);
PROTECT(exp);
MinExprList *result = newMinExprList(CPI(node), exp, next);
UNPROTECT(save);
Expand All @@ -202,7 +203,7 @@ static MinApply *desugarLamApply(LamApply *node) {
return NULL;
}

MinExp *function = desugarLamExp(node->function);
MinExp *function = _desugarLamExp(node->function);
int save = PROTECT(function);
MinExprList *args = desugarLamArgs(node->args);
PROTECT(args);
Expand Down Expand Up @@ -303,11 +304,11 @@ static MinIff *desugarLamIff(LamIff *node) {
return NULL;
}

MinExp *condition = desugarLamExp(node->condition);
MinExp *condition = _desugarLamExp(node->condition);
int save = PROTECT(condition);
MinExp *consequent = desugarLamExp(node->consequent);
MinExp *consequent = _desugarLamExp(node->consequent);
PROTECT(consequent);
MinExp *alternative = desugarLamExp(node->alternative);
MinExp *alternative = _desugarLamExp(node->alternative);
PROTECT(alternative);
MinIff *result = newMinIff(CPI(node), condition, consequent, alternative);
UNPROTECT(save);
Expand All @@ -322,7 +323,7 @@ static MinCond *desugarLamCond(LamCond *node) {
return NULL;
}

MinExp *value = desugarLamExp(node->value);
MinExp *value = _desugarLamExp(node->value);
int save = PROTECT(value);
MinCondCases *cases = desugarLamCondCases(node->cases);
PROTECT(cases);
Expand All @@ -339,7 +340,7 @@ static MinIntCondCases *desugarLamIntCondCases(LamIntCondCases *node) {
return NULL;
}

MinExp *body = desugarLamExp(node->body);
MinExp *body = _desugarLamExp(node->body);
int save = PROTECT(body);
MinIntCondCases *next = desugarLamIntCondCases(node->next);
PROTECT(next);
Expand All @@ -357,7 +358,7 @@ static MinCharCondCases *desugarLamCharCondCases(LamCharCondCases *node) {
return NULL;
}

MinExp *body = desugarLamExp(node->body);
MinExp *body = _desugarLamExp(node->body);
int save = PROTECT(body);
MinCharCondCases *next = desugarLamCharCondCases(node->next);
PROTECT(next);
Expand All @@ -375,7 +376,7 @@ static MinMatch *desugarLamMatch(LamMatch *node) {
return NULL;
}

MinExp *index = desugarLamExp(node->index);
MinExp *index = _desugarLamExp(node->index);
int save = PROTECT(index);
MinMatchList *cases = desugarLamMatchList(node->cases);
PROTECT(cases);
Expand All @@ -394,7 +395,7 @@ static MinMatchList *desugarLamMatchList(LamMatchList *node) {

MinIntList *matches = desugarLamIntList(node->matches);
int save = PROTECT(matches);
MinExp *body = desugarLamExp(node->body);
MinExp *body = _desugarLamExp(node->body);
PROTECT(body);
MinMatchList *next = desugarLamMatchList(node->next);
PROTECT(next);
Expand Down Expand Up @@ -452,7 +453,7 @@ static MinExp *desugarLamLet(LamExp *exp) {
LamLet *node = getLamExp_Let(exp);
MinBindings *bindings = desugarLamBindings(node->bindings);
int save = PROTECT(bindings);
MinExp *body = desugarLamExp(node->body);
MinExp *body = _desugarLamExp(node->body);
PROTECT(body);
SymbolList *fargs = extractKeysFromBindings(bindings);
PROTECT(fargs);
Expand All @@ -475,7 +476,7 @@ static MinLetRec *desugarLamLetRec(LamLetRec *node) {

MinBindings *bindings = desugarLamBindings(node->bindings);
int save = PROTECT(bindings);
MinExp *body = desugarLamExp(node->body);
MinExp *body = _desugarLamExp(node->body);
PROTECT(body);
MinLetRec *result = newMinLetRec(CPI(node), bindings, body);
UNPROTECT(save);
Expand Down Expand Up @@ -506,7 +507,7 @@ static MinExp *desugarLamLetStar(LamExp *exp) {
// build a nest of lets, then desugar that
LamExp *lets = nestLets(node->bindings, node->body);
int save = PROTECT(lets);
MinExp *result = desugarLamExp(lets);
MinExp *result = _desugarLamExp(lets);
UNPROTECT(save);
LEAVE(desugarLamLetStar);
return result;
Expand All @@ -519,7 +520,7 @@ static MinBindings *desugarLamBindings(LamBindings *node) {
return NULL;
}

MinExp *val = desugarLamExp(node->val);
MinExp *val = _desugarLamExp(node->val);
int save = PROTECT(val);
MinBindings *next = desugarLamBindings(node->next);
PROTECT(next);
Expand All @@ -542,9 +543,9 @@ static MinAmb *desugarLamAmb(LamAmb *node) {
return NULL;
}

MinExp *left = desugarLamExp(node->left);
MinExp *left = _desugarLamExp(node->left);
int save = PROTECT(left);
MinExp *right = desugarLamExp(node->right);
MinExp *right = _desugarLamExp(node->right);
PROTECT(right);
MinAmb *result = newMinAmb(CPI(node), left, right);
UNPROTECT(save);
Expand All @@ -555,22 +556,22 @@ static MinAmb *desugarLamAmb(LamAmb *node) {
static MinExp *desugarLamTypeOf(LamExp *exp) {
ENTER(desugarLamTypeOf);
LamTypeOf *node = getLamExp_TypeOf(exp);
MinExp *result = desugarLamExp(node->typeString);
MinExp *result = _desugarLamExp(node->typeString);
LEAVE(desugarLamTypeOf);
return result;
}

static MinExp *desugarLamTypeDefs(LamExp *exp) {
ENTER(desugarLamTypeDefs);
MinExp *result = desugarLamExp(getLamExp_TypeDefs(exp)->body);
MinExp *result = _desugarLamExp(getLamExp_TypeDefs(exp)->body);
LEAVE(desugarLamTypeDefs);
return result;
}

static MinExp *desugarLamPrint(LamExp *node) {
MinExp *printer = desugarLamExp(getLamExp_Print(node)->printer);
MinExp *printer = _desugarLamExp(getLamExp_Print(node)->printer);
int save = PROTECT(printer);
MinExp *arg = desugarLamExp(getLamExp_Print(node)->exp);
MinExp *arg = _desugarLamExp(getLamExp_Print(node)->exp);
PROTECT(arg);
MinExprList *args = newMinExprList(CPI(node), arg, NULL);
PROTECT(args);
Expand Down Expand Up @@ -655,7 +656,9 @@ static MinCondCases *desugarLamCondCases(LamCondCases *node) {
}

// Main desugaring function and public interface
MinExp *desugarLamExp(LamExp *node) {
MinExp *desugarLamExp(LamExp *node) { return _desugarLamExp(node); }

static MinExp *_desugarLamExp(LamExp *node) {
ENTER(desugarLamExp);
if (node == NULL) {
LEAVE(desugarLamExp);
Expand Down Expand Up @@ -699,7 +702,7 @@ MinExp *desugarLamExp(LamExp *node) {
}
case LAMEXP_TYPE_CALLCC: {
// LamExp
MinExp *new_callcc = desugarLamExp(getLamExp_CallCC(node));
MinExp *new_callcc = _desugarLamExp(getLamExp_CallCC(node));
PROTECT(new_callcc);
result = newMinExp_CallCC(CPI(node), new_callcc);
break;
Expand Down Expand Up @@ -767,7 +770,7 @@ MinExp *desugarLamExp(LamExp *node) {
LamPrimApp *prim = getLamExp_Prim(node);
if (prim->replacement != NULL) {
// Use the replacement instead of the primitive
result = desugarLamExp(prim->replacement);
result = _desugarLamExp(prim->replacement);
} else {
MinPrimApp *new = desugarLamPrimApp(prim);
PROTECT(new);
Expand Down
Loading