]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Finished anf transformation
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 28 Dec 2015 23:37:50 +0000 (18:37 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 28 Dec 2015 23:37:50 +0000 (18:37 -0500)
Makefile
source/anf.c [new file with mode: 0644]
source/main.c
source/sclpl.h

index c6fe2cf8dd0a08d1fa9ad9c4efbc25f52226920c..56d89fc002a581c9152cc4e5eea3ce55799c6d1d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,8 @@ OBJS = source/main.o    \
        source/pprint.o  \
        source/gc.o      \
        source/vec.o     \
-       source/ast.o
+       source/ast.o     \
+       source/anf.o
 
 all: options sclpl test
 
diff --git a/source/anf.c b/source/anf.c
new file mode 100644 (file)
index 0000000..2f3e8c5
--- /dev/null
@@ -0,0 +1,133 @@
+#include <sclpl.h>
+
+static bool isatomic(AST* tree)
+{
+    switch (tree->type) {
+        case AST_STRING:
+        case AST_SYMBOL:
+        case AST_IDENT:
+        case AST_CHAR:
+        case AST_INT:
+        case AST_FLOAT:
+        case AST_BOOL:
+        case AST_FUNC:
+            return true;
+        default:
+            return false;
+    }
+}
+
+static bool isconst(AST* tree) {
+    bool ret = isatomic(tree);
+    if (!ret) {
+        if (tree->type == AST_FNAPP) {
+            ret = isatomic(fnapp_fn(tree));
+            for (int i = 0; i < vec_size(fnapp_args(tree)); i++) {
+                ret = ret && isatomic(vec_at(fnapp_args(tree), i));
+            }
+        } else if (tree->type == AST_IF) {
+            ret = isatomic(ifexpr_cond(tree));
+        }
+    }
+    return ret;
+}
+
+static AST* normalize_def(AST* tree)
+{
+    Tok name = { .value.text = def_name(tree) };
+    return Def(&name, normalize(def_value(tree)));
+}
+
+static AST* normalize_fnapp(AST* tree)
+{
+    AST* normalized = tree;
+    AST* fn = fnapp_fn(tree);
+    /* Normalize the function */
+    if (!isatomic(fn)) {
+        AST* temp = TempVar();
+        fnapp_set_fn(tree, temp);
+        normalized = Let(temp, fn, tree);
+    }
+    /* Normalize the function arguments */
+    vec_t temps;
+    vec_init(&temps);
+    vec_t* args = fnapp_args(tree);
+    for (int i = 0; i < vec_size(args); i++) {
+        AST* arg = (AST*)vec_at(args, i);
+        if (!isatomic(arg)) {
+            AST* temp = TempVar();
+            vec_push_back(&temps, Let(temp, arg, NULL));
+            vec_set(args, i, temp);
+        }
+    }
+    /* Nest all the scopes and return the new form */
+    for (int i = vec_size(&temps); i > 0; i--) {
+        AST* let = (AST*)vec_at(&temps,i-1);
+        let_set_body(let, normalized);
+        normalized = let;
+    }
+    vec_deinit(&temps);
+    return normalized;
+}
+
+static AST* normalize_if(AST* tree)
+{
+    AST* cond   = normalize(ifexpr_cond(tree));
+    AST* thenbr = normalize(ifexpr_then(tree));
+    AST* elsebr = normalize(ifexpr_else(tree));
+    if (!isatomic(cond)) {
+        AST* temp = TempVar();
+        AST* body = IfExpr(); //(temp, thenbr, elsebr);
+        ifexpr_set_cond(body, temp);
+        ifexpr_set_then(body, thenbr);
+        ifexpr_set_else(body, elsebr);
+        tree = Let(temp, cond, body);
+    } else {
+        tree = IfExpr(); //(cond, thenbr, elsebr);
+        ifexpr_set_cond(tree, cond);
+        ifexpr_set_then(tree, thenbr);
+        ifexpr_set_else(tree, elsebr);
+    }
+    return tree;
+}
+
+static AST* normalize_func(AST* tree)
+{
+    func_set_body(tree, normalize(func_body(tree)));
+    return tree;
+}
+
+static AST* normalize_let(AST* tree)
+{
+    AST* var  = let_var(tree);
+    AST* val  = normalize(let_val(tree));
+    AST* body = normalize(let_body(tree));
+    /* Find the inner most let block */
+    if (!isconst(val)) {
+        AST* let = val;
+        while (let->type == AST_LET && let_body(let)->type == AST_LET)
+            let = let_body(let);
+        let_set_body(let, Let(var, let_body(let), body));
+        tree = let;
+    } else {
+        tree = Let(var, val, body);
+    }
+    return tree;
+}
+
+AST* normalize(AST* tree)
+{
+    if (NULL == tree)
+        return tree;
+    switch (tree->type)
+    {
+        case AST_DEF:   tree = normalize_def(tree);   break;
+        case AST_FNAPP: tree = normalize_fnapp(tree); break;
+        case AST_IF:    tree = normalize_if(tree);    break;
+        case AST_FUNC:  tree = normalize_func(tree);  break;
+        case AST_LET:   tree = normalize_let(tree);   break;
+        default: break;
+    }
+    return tree;
+}
+
index 19f45b9c4de4a7cb0d0238527639e63324d1212d..8af8530cede41dfeb164aa47288edf74b086ad49 100644 (file)
@@ -4,124 +4,6 @@ char* ARGV0;
 bool Verbose   = false;
 char* Artifact = "bin";
 
-AST* normalize(AST* tree);
-
-bool isatomic(AST* tree)
-{
-    switch (tree->type) {
-        case AST_STRING:
-        case AST_SYMBOL:
-        case AST_IDENT:
-        case AST_CHAR:
-        case AST_INT:
-        case AST_FLOAT:
-        case AST_BOOL:
-        case AST_FUNC:
-            return true;
-        default:
-            return false;
-    }
-}
-
-AST* normalize_def(AST* tree)
-{
-    Tok name = { .value.text = def_name(tree) };
-    return Def(&name, normalize(def_value(tree)));
-}
-
-AST* normalize_fnapp(AST* tree)
-{
-    AST* normalized = tree;
-    AST* fn = fnapp_fn(tree);
-    /* Normalize the function */
-    if (!isatomic(fn)) {
-        AST* temp = TempVar();
-        fnapp_set_fn(tree, temp);
-        normalized = Let(temp, fn, tree);
-    }
-    /* Normalize the function arguments */
-    vec_t temps;
-    vec_init(&temps);
-    vec_t* args = fnapp_args(tree);
-    for (int i = 0; i < vec_size(args); i++) {
-        AST* arg = (AST*)vec_at(args, i);
-        if (!isatomic(arg)) {
-            AST* temp = TempVar();
-            vec_push_back(&temps, Let(temp, arg, NULL));
-            vec_set(args, i, temp);
-        }
-    }
-    /* Nest all the scopes and return the new form */
-    for (int i = vec_size(&temps); i > 0; i--) {
-        AST* let = (AST*)vec_at(&temps,i-1);
-        let_set_body(let, normalized);
-        normalized = let;
-    }
-    vec_deinit(&temps);
-    return normalized;
-}
-
-AST* normalize_if(AST* tree)
-{
-    AST* cond   = normalize(ifexpr_cond(tree));
-    AST* thenbr = normalize(ifexpr_then(tree));
-    AST* elsebr = normalize(ifexpr_else(tree));
-    if (!isatomic(cond)) {
-        AST* temp = TempVar();
-        AST* body = IfExpr(); //(temp, thenbr, elsebr);
-        ifexpr_set_cond(body, temp);
-        ifexpr_set_then(body, thenbr);
-        ifexpr_set_else(body, elsebr);
-        tree = Let(temp, cond, body);
-    } else {
-        tree = IfExpr(); //(cond, thenbr, elsebr);
-        ifexpr_set_cond(tree, cond);
-        ifexpr_set_then(tree, thenbr);
-        ifexpr_set_else(tree, elsebr);
-    }
-    return tree;
-}
-
-AST* normalize_func(AST* tree)
-{
-    func_set_body(tree, normalize(func_body(tree)));
-    return tree;
-}
-
-AST* normalize_let(AST* tree)
-{
-    AST* var  = let_var(tree);
-    AST* val  = normalize(let_val(tree));
-    AST* body = normalize(let_body(tree));
-    /* Find the inner most let block */
-    if (!isatomic(val)) {
-        AST* let = val;
-        while (let->type == AST_LET && let_body(let)->type == AST_LET)
-            let = let_body(let);
-        let_set_body(let, Let(var, let_body(let), body));
-        tree = let;
-    } else {
-        tree = Let(var, val, body);
-    }
-    return tree;
-}
-
-AST* normalize(AST* tree)
-{
-    if (NULL == tree)
-        return tree;
-    switch (tree->type)
-    {
-        case AST_DEF:   tree = normalize_def(tree);   break;
-        case AST_FNAPP: tree = normalize_fnapp(tree); break;
-        case AST_IF:    tree = normalize_if(tree);    break;
-        case AST_FUNC:  tree = normalize_func(tree);  break;
-        case AST_LET:   tree = normalize_let(tree);   break;
-        default: break;
-    }
-    return tree;
-}
-
 /* Driver Modes
  *****************************************************************************/
 static int emit_tokens(void) {
index 9ddc8d81823f90c4682f66246b027626b0b5adfe..1a2282ee19dcd00532b798e08ec532bab2d771ee 100644 (file)
@@ -212,6 +212,9 @@ Parser* parser_new(char* p_prompt, FILE* input);
 // Grammar Routines
 AST* toplevel(Parser* p);
 
+// Compiler Passes
+AST* normalize(AST* tree);
+
 /* Pretty Printing
  *****************************************************************************/
 void pprint_token_type(FILE* file, Tok* token);