瀏覽代碼

ncd: NCDAst: add Foreach syntax

ambrop7 13 年之前
父節點
當前提交
1637bd7583
共有 2 個文件被更改,包括 97 次插入0 次删除
  1. 83 0
      ncd/NCDAst.c
  2. 14 0
      ncd/NCDAst.h

+ 83 - 0
ncd/NCDAst.c

@@ -282,6 +282,40 @@ int NCDStatement_InitIf (NCDStatement *o, const char *name, NCDIfBlock ifblock)
     return 1;
 }
 
+int NCDStatement_InitForeach (NCDStatement *o, const char *name, NCDValue collection, const char *name1, const char *name2, NCDBlock block)
+{
+    ASSERT(name1)
+    
+    o->name = NULL;
+    o->foreach.name1 = NULL;
+    o->foreach.name2 = NULL;
+    
+    if (name && !(o->name = strdup(name))) {
+        goto fail;
+    }
+    
+    if (!(o->foreach.name1 = strdup(name1))) {
+        goto fail;
+    }
+    
+    if (name2 && !(o->foreach.name2 = strdup(name2))) {
+        goto fail;
+    }
+    
+    o->type = NCDSTATEMENT_FOREACH;
+    o->foreach.collection = collection;
+    o->foreach.block = block;
+    o->foreach.is_grabbed = 0;
+    
+    return 1;
+    
+fail:
+    free(o->name);
+    free(o->foreach.name1);
+    free(o->foreach.name2);
+    return 0;
+}
+
 void NCDStatement_Free (NCDStatement *o)
 {
     switch (o->type) {
@@ -299,6 +333,15 @@ void NCDStatement_Free (NCDStatement *o)
             NCDIfBlock_Free(&o->ifc.ifblock);
         } break;
         
+        case NCDSTATEMENT_FOREACH: {
+            if (!o->foreach.is_grabbed) {
+                NCDBlock_Free(&o->foreach.block);
+                NCDValue_Free(&o->foreach.collection);
+            }
+            free(o->foreach.name2);
+            free(o->foreach.name1);
+        } break;
+        
         default: ASSERT(0);
     }
     
@@ -373,6 +416,46 @@ NCDBlock NCDStatement_IfGrabElse (NCDStatement *o)
     return o->ifc.else_block;
 }
 
+NCDValue * NCDStatement_ForeachCollection (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_FOREACH)
+    ASSERT(!o->foreach.is_grabbed)
+    
+    return &o->foreach.collection;
+}
+
+const char * NCDStatement_ForeachName1 (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_FOREACH)
+    
+    return o->foreach.name1;
+}
+
+const char * NCDStatement_ForeachName2 (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_FOREACH)
+    
+    return o->foreach.name2;
+}
+
+NCDBlock * NCDStatement_ForeachBlock (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_FOREACH)
+    ASSERT(!o->foreach.is_grabbed)
+    
+    return &o->foreach.block;
+}
+
+void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlock *out_block)
+{
+    ASSERT(o->type == NCDSTATEMENT_FOREACH)
+    ASSERT(!o->foreach.is_grabbed)
+    
+    *out_collection = o->foreach.collection;
+    *out_block = o->foreach.block;
+    o->foreach.is_grabbed = 1;
+}
+
 void NCDIfBlock_Init (NCDIfBlock *o)
 {
     LinkedList1_Init(&o->ifs_list);

+ 14 - 0
ncd/NCDAst.h

@@ -75,6 +75,13 @@ struct NCDStatement_s {
             int have_else;
             NCDBlock else_block;
         } ifc;
+        struct {
+            NCDValue collection;
+            char *name1;
+            char *name2;
+            NCDBlock block;
+            int is_grabbed;
+        } foreach;
     };
 };
 
@@ -102,6 +109,7 @@ struct IfBlockIf {
 
 #define NCDSTATEMENT_REG 1
 #define NCDSTATEMENT_IF 2
+#define NCDSTATEMENT_FOREACH 3
 
 void NCDProgram_Init (NCDProgram *o);
 void NCDProgram_Free (NCDProgram *o);
@@ -127,6 +135,7 @@ size_t NCDBlock_NumStatements (NCDBlock *o);
 
 int NCDStatement_InitReg (NCDStatement *o, const char *name, const char *objname, const char *cmdname, NCDValue args) WARN_UNUSED;
 int NCDStatement_InitIf (NCDStatement *o, const char *name, NCDIfBlock ifblock) WARN_UNUSED;
+int NCDStatement_InitForeach (NCDStatement *o, const char *name, NCDValue collection, const char *name1, const char *name2, NCDBlock block) WARN_UNUSED;
 void NCDStatement_Free (NCDStatement *o);
 int NCDStatement_Type (NCDStatement *o);
 const char * NCDStatement_Name (NCDStatement *o);
@@ -137,6 +146,11 @@ NCDIfBlock * NCDStatement_IfBlock (NCDStatement *o);
 void NCDStatement_IfAddElse (NCDStatement *o, NCDBlock else_block);
 NCDBlock * NCDStatement_IfElse (NCDStatement *o);
 NCDBlock NCDStatement_IfGrabElse (NCDStatement *o);
+NCDValue * NCDStatement_ForeachCollection (NCDStatement *o);
+const char * NCDStatement_ForeachName1 (NCDStatement *o);
+const char * NCDStatement_ForeachName2 (NCDStatement *o);
+NCDBlock * NCDStatement_ForeachBlock (NCDStatement *o);
+void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlock *out_block);
 
 void NCDIfBlock_Init (NCDIfBlock *o);
 void NCDIfBlock_Free (NCDIfBlock *o);