فهرست منبع

ncd: Implement Block syntax sugar.

Ambroz Bizjak 11 سال پیش
والد
کامیت
0879bf529e

+ 11 - 1
examples/ncd_parser_test.c

@@ -253,7 +253,17 @@ static void print_block (NCDBlock *block, unsigned int indent)
                 print_block(NCDStatement_ForeachBlock(st), indent + 2);
             } break;
             
-            default: ASSERT(0);
+            case NCDSTATEMENT_BLOCK: {
+                print_indent(indent);
+                printf("block name=%s\n", name);
+                
+                print_block(NCDStatement_BlockBlock(st), indent + 2);
+            } break;
+            
+            default: {
+                print_indent(indent);
+                printf("unknown_statement_type name=%s\n", name);
+            } break;
         }
     }
 }

+ 3 - 0
examples/ncd_tokenizer_test.c

@@ -120,6 +120,9 @@ static int tokenizer_output (void *user, int token, char *value, size_t value_le
         case NCD_TOKEN_AT:
             printf("at\n");
             break;
+        case NCD_TOKEN_BLOCK:
+            printf("block\n");
+            break;
         default:
             printf("UNKNOWN_TOKEN\n");
             break;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 512 - 477
generated/NCDConfigParser_parse.c


+ 8 - 7
generated/NCDConfigParser_parse.h

@@ -14,10 +14,11 @@
 #define COLON                          14
 #define ELIF                           15
 #define ELSE                           16
-#define DOT                            17
-#define COMMA                          18
-#define BRACKET_OPEN                   19
-#define BRACKET_CLOSE                  20
-#define AT_SIGN                        21
-#define PROCESS                        22
-#define TEMPLATE                       23
+#define BLOCK                          17
+#define DOT                            18
+#define COMMA                          19
+#define BRACKET_OPEN                   20
+#define BRACKET_CLOSE                  21
+#define AT_SIGN                        22
+#define PROCESS                        23
+#define TEMPLATE                       24

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 437 - 373
generated/NCDConfigParser_parse.out


+ 21 - 0
generated/NCDConfigParser_parse.y

@@ -457,6 +457,27 @@ else_maybe(R) ::= ELSE CURLY_OPEN statements(B) CURLY_CLOSE. {
     R = B;
 }
 
+statement(R) ::= BLOCK CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. {
+    if (!S.have) {
+        goto failGA0;
+    }
+    
+    if (!NCDStatement_InitBlock(&R.v, N, S.v)) {
+        goto failGA0;
+    }
+    S.have = 0;
+    
+    R.have = 1;
+    goto doneGA0;
+    
+failGA0:
+    R.have = 0;
+    parser_out->out_of_memory = 1;
+doneGA0:
+    free_block(S);
+    free(N);
+}
+
 statements(R) ::= statement(A). {
     if (!A.have) {
         goto failH0;

+ 38 - 0
ncd/NCDAst.c

@@ -831,6 +831,21 @@ fail:
     return 0;
 }
 
+int NCDStatement_InitBlock (NCDStatement *o, const char *name, NCDBlock block)
+{
+    o->name = NULL;
+    
+    if (name && !(o->name = strdup(name))) {
+        return 0;
+    }
+    
+    o->type = NCDSTATEMENT_BLOCK;
+    o->block.block = block;
+    o->block.is_grabbed = 0;
+    
+    return 1;
+}
+
 void NCDStatement_Free (NCDStatement *o)
 {
     switch (o->type) {
@@ -857,6 +872,12 @@ void NCDStatement_Free (NCDStatement *o)
             free(o->foreach.name1);
         } break;
         
+        case NCDSTATEMENT_BLOCK: {
+            if (!o->block.is_grabbed) {
+                NCDBlock_Free(&o->block.block);
+            }
+        } break;
+        
         default: ASSERT(0);
     }
     
@@ -971,6 +992,23 @@ void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlo
     o->foreach.is_grabbed = 1;
 }
 
+NCDBlock * NCDStatement_BlockBlock (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_BLOCK)
+    ASSERT(!o->block.is_grabbed)
+    
+    return &o->block.block;
+}
+
+NCDBlock NCDStatement_BlockGrabBlock (NCDStatement *o)
+{
+    ASSERT(o->type == NCDSTATEMENT_BLOCK)
+    ASSERT(!o->block.is_grabbed)
+    
+    o->block.is_grabbed = 1;
+    return o->block.block;
+}
+
 void NCDIfBlock_Init (NCDIfBlock *o)
 {
     LinkedList1_Init(&o->ifs_list);

+ 8 - 0
ncd/NCDAst.h

@@ -126,6 +126,10 @@ struct NCDStatement_s {
             NCDBlock block;
             int is_grabbed;
         } foreach;
+        struct {
+            NCDBlock block;
+            int is_grabbed;
+        } block;
     };
 };
 
@@ -149,6 +153,7 @@ struct NCDIf_s {
 #define NCDSTATEMENT_REG 1
 #define NCDSTATEMENT_IF 2
 #define NCDSTATEMENT_FOREACH 3
+#define NCDSTATEMENT_BLOCK 4
 
 void NCDValue_Free (NCDValue *o);
 int NCDValue_Type (NCDValue *o);
@@ -213,6 +218,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;
+int NCDStatement_InitBlock (NCDStatement *o, const char *name, NCDBlock block) WARN_UNUSED;
 void NCDStatement_Free (NCDStatement *o);
 int NCDStatement_Type (NCDStatement *o);
 const char * NCDStatement_Name (NCDStatement *o);
@@ -228,6 +234,8 @@ 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);
+NCDBlock * NCDStatement_BlockBlock (NCDStatement *o);
+NCDBlock NCDStatement_BlockGrabBlock (NCDStatement *o);
 
 void NCDIfBlock_Init (NCDIfBlock *o);
 void NCDIfBlock_Free (NCDIfBlock *o);

+ 4 - 0
ncd/NCDConfigParser.c

@@ -162,6 +162,10 @@ static int tokenizer_output (void *user, int token, char *value, size_t value_le
             Parse(state->parser, AT_SIGN, minor, &state->out);
         } break;
         
+        case NCD_TOKEN_BLOCK: {
+            Parse(state->parser, BLOCK, minor, &state->out);
+        } break;
+        
         default:
             BLog(BLOG_ERROR, "line %zu, character %zu: invalid token", line, line_char);
             free(minor.str);

+ 21 - 0
ncd/NCDConfigParser_parse.y

@@ -457,6 +457,27 @@ else_maybe(R) ::= ELSE CURLY_OPEN statements(B) CURLY_CLOSE. {
     R = B;
 }
 
+statement(R) ::= BLOCK CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. {
+    if (!S.have) {
+        goto failGA0;
+    }
+    
+    if (!NCDStatement_InitBlock(&R.v, N, S.v)) {
+        goto failGA0;
+    }
+    S.have = 0;
+    
+    R.have = 1;
+    goto doneGA0;
+    
+failGA0:
+    R.have = 0;
+    parser_out->out_of_memory = 1;
+doneGA0:
+    free_block(S);
+    free(N);
+}
+
 statements(R) ::= statement(A). {
     if (!A.have) {
         goto failH0;

+ 3 - 0
ncd/NCDConfigTokenizer.c

@@ -138,6 +138,9 @@ void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_out
         else if (l = data_begins_with(str, left, "As")) {
             token = NCD_TOKEN_AS;
         }
+        else if (l = data_begins_with(str, left, "Block")) {
+            token = NCD_TOKEN_BLOCK;
+        }
         else if (l = data_begins_with(str, left, "include_guard")) {
             token = NCD_TOKEN_INCLUDE_GUARD;
         }

+ 1 - 0
ncd/NCDConfigTokenizer.h

@@ -57,6 +57,7 @@
 #define NCD_TOKEN_INCLUDE 21
 #define NCD_TOKEN_INCLUDE_GUARD 22
 #define NCD_TOKEN_AT 23
+#define NCD_TOKEN_BLOCK 24
 
 typedef int (*NCDConfigTokenizer_output) (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char);
 

+ 44 - 1
ncd/NCDSugar.c

@@ -42,6 +42,7 @@ static int add_template (struct desugar_state *state, NCDBlock block, NCDValue *
 static int desugar_block (struct desugar_state *state, NCDBlock *block);
 static int desugar_if (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next);
 static int desugar_foreach (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next);
+static int desugar_blockstmt (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next);
 
 static int add_template (struct desugar_state *state, NCDBlock block, NCDValue *out_name_val)
 {
@@ -97,7 +98,15 @@ static int desugar_block (struct desugar_state *state, NCDBlock *block)
                 }
             } break;
             
-            default: ASSERT(0);
+            case NCDSTATEMENT_BLOCK: {
+                if (!desugar_blockstmt(state, block, stmt, &stmt)) {
+                    return 0;
+                }
+            } break;
+            
+            default: {
+                return 0;
+            } break;
         }
     }
     
@@ -231,6 +240,40 @@ fail:
     return 0;
 }
 
+static int desugar_blockstmt (struct desugar_state *state, NCDBlock *block, NCDStatement *stmt, NCDStatement **out_next)
+{
+    ASSERT(NCDStatement_Type(stmt) == NCDSTATEMENT_BLOCK)
+    
+    NCDValue args;
+    NCDValue_InitList(&args);
+    
+    NCDBlock block_block = NCDStatement_BlockGrabBlock(stmt);
+    
+    NCDValue template_arg;
+    if (!add_template(state, block_block, &template_arg)) {
+        goto fail;
+    }
+    
+    if (!NCDValue_ListAppend(&args, template_arg)) {
+        NCDValue_Free(&template_arg);
+        goto fail;
+    }
+    
+    NCDStatement new_stmt;
+    if (!NCDStatement_InitReg(&new_stmt, NCDStatement_Name(stmt), NULL, "inline_code", args)) {
+        goto fail;
+    }
+    
+    stmt = NCDBlock_ReplaceStatement(block, stmt, new_stmt);
+    
+    *out_next = NCDBlock_NextStatement(block, stmt);
+    return 1;
+    
+fail:
+    NCDValue_Free(&args);
+    return 0;
+}
+
 int NCDSugar_Desugar (NCDProgram *prog)
 {
     ASSERT(!NCDProgram_ContainsElemType(prog, NCDPROGRAMELEM_INCLUDE))

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است