return r;
}
-struct lambda *make_abstraction(char *i, struct lambda *t)
+struct lambda *make_abstraction(char *i, bool strict, struct lambda *t)
{
struct lambda *r = make_lambda();
r->which = lambda_abs;
r->data.abstraction.ident = strdup(i);
r->data.abstraction.revision = 0;
+ r->data.abstraction.strict = strict;
r->data.abstraction.expr = t;
return r;
}
struct lambda *body = make_ident("x");
while(i-- > 0)
body = make_application(make_ident("f"), body);
- return make_abstraction("f", make_abstraction("x", body));
+ return make_abstraction("f", false, make_abstraction("x", false, body));
}
struct lambda *make_bool(bool b)
{
return b
- ? make_abstraction("a", make_abstraction("b", make_ident("a")))
- : make_abstraction("a", make_abstraction("b", make_ident("b")));
+ ? make_abstraction("a", false, make_abstraction("b", false, make_ident("a")))
+ : make_abstraction("a", false, make_abstraction("b", false, make_ident("b")));
}
void decls_prepend(char *ident, struct lambda *value)
%}
-%token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN LITERAL
+%token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN LITERAL BANG
%%
lambda_print($1, NULL);
lambda_free($1);
}
- | FUNC ASSIGN term
+ | FUNC func
{
- decls_prepend($1->data.identifier.ident, $3);
+ decls_prepend($1->data.identifier.ident, $2);
printf("%s = ", $1->data.identifier.ident);
- lambda_print($3, NULL);
+ lambda_print($2, NULL);
+ lambda_free($1);
+ }
+func
+ : ASSIGN term
+ { $$ = $2; }
+ | BANG IDENT func
+ {
+ $$ = make_abstraction($2->data.identifier.ident, true, $3);
+ lambda_free($2);
+ }
+ | IDENT func
+ {
+ $$ = make_abstraction($1->data.identifier.ident, false, $2);
lambda_free($1);
}
term
lambda_free($1);
}
| IDENT
- {
- $$ = make_ident($1->data.identifier.ident);
- lambda_free($1);
- }
+ { $$ = $1; }
| LAMBDA abstraction
{ $$ = $2; }
| OBRACE term CBRACE
{ $$ = $2; }
abstraction
- : IDENT abstraction
+ : BANG IDENT abstraction
+ {
+ $$ = make_abstraction($2->data.identifier.ident, true, $3);
+ lambda_free($2);
+ }
+ | IDENT abstraction
{
- $$ = make_abstraction($1->data.identifier.ident, $2);
+ $$ = make_abstraction($1->data.identifier.ident, false, $2);
lambda_free($1);
}
| DOT term