]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Started laying the groundwork for a-normalization pass
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 17 Dec 2015 02:46:57 +0000 (21:46 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 17 Dec 2015 02:46:57 +0000 (21:46 -0500)
source/ast.c
source/main.c
source/pprint.c
source/sclpl.h
spec/anf_spec.rb [new file with mode: 0644]

index dd764876c748621968197d4ebff588bb7b2135a8..7185904bdf090822f970d0333346ab095d88f6cb 100644 (file)
@@ -2,27 +2,22 @@
 
 static void ast_free(void* ptr)
 {
+//    AST_LET AST_TEMP
+
     AST* ast = (AST*)ptr;
     switch(ast->type) {
+        case AST_REQ:
         case AST_IDENT:
         case AST_STRING:
+        case AST_SYMBOL:
             gc_delref(ast->value.text);
             break;
 
-        case AST_REQ:
-            gc_delref(ast->value.req.name);
-            break;
-
         case AST_DEF:
             gc_delref(ast->value.def.name);
             gc_delref(ast->value.def.value);
             break;
 
-        case AST_ANN:
-            gc_delref(ast->value.ann.name);
-            gc_delref(ast->value.ann.value);
-            break;
-
         case AST_IF:
             gc_delref(ast->value.ifexpr.cond);
             gc_delref(ast->value.ifexpr.bthen);
@@ -39,6 +34,16 @@ static void ast_free(void* ptr)
             vec_deinit(&(ast->value.fnapp.args));
             break;
 
+        case AST_BLOCK:
+            vec_deinit(&(ast->value.exprs));
+            break;
+
+        case AST_LET:
+            break;
+
+        case AST_TEMP:
+            break;
+
         default:
             break;
     }
@@ -294,3 +299,11 @@ void fnapp_add_arg(AST* fnapp, AST* arg)
     vec_push_back(&(fnapp->value.fnapp.args), gc_addref(arg));
 }
 
+AST* Let(AST* temp, AST* val, AST* body)
+{
+    AST* node = ast(AST_LET);
+    node->value.let.temp  = (AST*)gc_addref(temp);
+    node->value.let.value = (AST*)gc_addref(val);
+    node->value.let.body  = (AST*)gc_addref(body);
+    return node;
+}
index 114dac0c7ea5e3f1de44011caf57dcaffac28374..de5700ca3f4359fbc016c66b77bbecbfc9f34957 100644 (file)
@@ -4,6 +4,28 @@ char* ARGV0;
 bool Verbose   = false;
 char* Artifact = "bin";
 
+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(AST* tree)
+{
+    return tree;
+}
+
 /* Driver Modes
  *****************************************************************************/
 static int emit_tokens(void) {
@@ -14,7 +36,7 @@ static int emit_tokens(void) {
     return 0;
 }
 
-static int emit_tree(void) {
+static int emit_ast(void) {
     AST* tree = NULL;
     Parser* ctx = parser_new(NULL, stdin);
     while(NULL != (tree = toplevel(ctx)))
@@ -22,6 +44,14 @@ static int emit_tree(void) {
     return 0;
 }
 
+static int emit_anf(void) {
+    AST* tree = NULL;
+    Parser* ctx = parser_new(NULL, stdin);
+    while(NULL != (tree = toplevel(ctx)))
+        pprint_tree(stdout, normalize(tree), 0);
+    return 0;
+}
+
 static int emit_csource(void) {
     return 0;
 }
@@ -58,16 +88,19 @@ int user_main(int argc, char **argv) {
     } OPTEND;
 
     /* Execute the main compiler process */
-    if (0 == strcmp("bin", Artifact)) {
+
+    if (0 == strcmp("tok", Artifact)) {
+        return emit_tokens();
+    } else if (0 == strcmp("ast", Artifact)) {
+        return emit_ast();
+    } else if (0 == strcmp("anf", Artifact)) {
+        return emit_anf();
+    } else if (0 == strcmp("src", Artifact)) {
+        return emit_csource();
+    } else if (0 == strcmp("bin", Artifact)) {
         return emit_program();
     } else if (0 == strcmp("lib", Artifact)) {
         return emit_staticlib();
-    } else if (0 == strcmp("src", Artifact)) {
-        return emit_csource();
-    } else if (0 == strcmp("ast", Artifact)) {
-        return emit_tree();
-    } else if (0 == strcmp("tok", Artifact)) {
-        return emit_tokens();
     } else {
         fprintf(stderr, "Unknonwn artifact type: '%s'\n\n", Artifact);
         usage();
index 2dea5c7e732c9591cc743bd7e74a4779557868f9..2758203e75513a68c0271917831e932b49a3a722 100644 (file)
@@ -149,9 +149,6 @@ void pprint_tree(FILE* file, AST* tree, int depth)
             printf(")");
             break;
 
-        case AST_ANN:
-            break;
-
         case AST_FUNC:
             printf("(fn (");
             for (size_t i = 0; i < vec_size(func_args(tree)); i++) {
@@ -176,6 +173,10 @@ void pprint_tree(FILE* file, AST* tree, int depth)
             printf(")");
             break;
 
+        case AST_LET:
+            printf("(let)");
+            break;
+
         default:
             pprint_literal(file, tree, depth);
             break;
index 18bdd1c55c6d16e81ffcd11351f78ca6686355c2..92acc642adbe717def87f964d91d4dd8db3e2da9 100644 (file)
@@ -72,27 +72,18 @@ typedef struct {
 /* AST Types
  *****************************************************************************/
 typedef enum ASTType {
-    AST_STRING = 0, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT,
-    AST_REQ, AST_DEF, AST_ANN, AST_IF, AST_FUNC, AST_FNAPP, AST_BLOCK
+    AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT,
+    AST_REQ, AST_DEF, AST_IF, AST_FUNC, AST_FNAPP, AST_BLOCK, AST_LET, AST_TEMP
 } ASTType;
 
 typedef struct AST {
     ASTType type;
     union {
-        /* Require Node */
-        struct {
-            char* name;
-        } req;
         /* Definition Node */
         struct {
             char* name;
             struct AST* value;
         } def;
-        /* Annotation Node */
-        struct {
-            char* name;
-            struct AST* value;
-        } ann;
         /* If Expression */
         struct {
             struct AST* cond;
@@ -109,6 +100,12 @@ typedef struct AST {
             struct AST* fn;
             vec_t args;
         } fnapp;
+        /* Let Expression */
+        struct {
+            struct AST* temp;
+            struct AST* value;
+            struct AST* body;
+        } let;
         /* Code Block */
         vec_t exprs;
         /* String, Symbol, Identifier */
@@ -189,6 +186,9 @@ AST* fnapp_fn(AST* fnapp);
 vec_t* fnapp_args(AST* fnapp);
 void fnapp_add_arg(AST* func, AST* arg);
 
+/* Let Expression */
+AST* Let(AST* temp, AST* val, AST* body);
+
 /* Lexer and Parser Types
  *****************************************************************************/
 typedef struct {
diff --git a/spec/anf_spec.rb b/spec/anf_spec.rb
new file mode 100644 (file)
index 0000000..0f70771
--- /dev/null
@@ -0,0 +1,29 @@
+require 'open3'
+
+describe "sclpl a-normal form" do
+  context "literals" do
+    it "strings should remain untouched" do
+      expect(ast('"foo"')).to eq(['T_STRING:"foo"'])
+    end
+
+    it "characters should remain untouched" do
+      expect(ast('\\c')).to eq(['T_CHAR:c'])
+    end
+
+    it "integers should remain untouched" do
+      expect(ast('123')).to eq(['T_INT:123'])
+    end
+
+    it "floats should remain untouched" do
+      expect(ast('123.0')).to eq(['T_FLOAT:123.000000'])
+    end
+
+    it "booleans should remain untouched" do
+      expect(ast('true')).to eq(['T_BOOL:true'])
+    end
+
+    it "ids should remain untouched" do
+      expect(ast('foo')).to eq(['T_ID:foo'])
+    end
+  end
+end