add strictness
[lambda.git] / lambda.y
index 813b77d..07c6b80 100644 (file)
--- a/lambda.y
+++ b/lambda.y
@@ -43,12 +43,13 @@ struct lambda *make_ident(char *i)
        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;
 }
@@ -67,14 +68,14 @@ struct lambda *make_numeral(unsigned int i)
        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)
@@ -106,7 +107,7 @@ int main()
 
 %}
 
-%token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN LITERAL
+%token LAMBDA DOT OBRACE CBRACE IDENT FUNC SEMICOLON ASSIGN LITERAL BANG
 
 %%
 
@@ -122,11 +123,24 @@ lambda
                        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
@@ -143,18 +157,20 @@ appterm
                        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