Browse Source

while和for的else语句

SongZihuan 5 years ago
parent
commit
510bcd5e76
7 changed files with 111 additions and 46 deletions
  1. 1 0
      README.md
  2. 24 39
      inter/interpreter.c
  3. 5 0
      inter/interpreter.h
  4. 0 3
      inter/var.c
  5. 1 0
      paser/lexical.c
  6. 77 3
      paser/syntax.c
  7. 3 1
      paser/token.h

+ 1 - 0
README.md

@@ -75,5 +75,6 @@ return x n  函数返回值x,返回n层
 * 新增Exception, 修复了``to_object``会捕获异常的bug
 * Div和Log运算检查数字类型
 * 调整了运算优先级,修改了无法读取``5 ** -2``而可以读取``5 ** (-2)``的bug
+* while和for循环新增else语句
 ## 关于GWARF
 最后更新时间 : 2020年05月07日 广州

+ 24 - 39
inter/interpreter.c

@@ -1156,31 +1156,15 @@ GWARF_result for_func(statement *the_statement, var_list *the_var, inter *global
     hash_var *tmp = make_hash_var();  // base_var
     the_var = append_var_list(tmp, the_var);
     the_var->tag = run_while;
-    bool condition;
+    bool condition, do_else = true;
     if(the_statement->code.for_cycle.first != NULL){
         GWARF_result tmp_result = traverse(the_statement->code.for_cycle.first, the_var, false, global_inter); // first to do
-        if(is_error(&tmp_result)){  // Name Error错误
-            // puts("STOP:: Name No Found!");
-            value = tmp_result;
-            return value;
-        }
-        else if(is_space(&tmp_result)){
-            value = tmp_result;
-            return value;
-        }
+        error_space(tmp_result, return_value, value);
     }
     while (1){
         if(the_statement->code.for_cycle.condition != NULL){  // 检查是否存在循环条件
             GWARF_result tmp_result = traverse(the_statement->code.for_cycle.condition, the_var, false, global_inter);
-            if(is_error(&tmp_result)){  // Name Error错误
-                // puts("STOP:: Name No Found!");
-                value = tmp_result;
-                goto return_value;
-            }
-            else if(is_space(&tmp_result)){
-                value = tmp_result;
-                goto return_value;
-            }
+            error_space(tmp_result, return_value, value);
             condition = to_bool(tmp_result.value, global_inter);
             printf("for condition = %d\n", condition);
             if(!condition){
@@ -1193,6 +1177,7 @@ GWARF_result for_func(statement *the_statement, var_list *the_var, inter *global
 
         //break操作
         if((value.u == cycle_break) || (value.u == code_broken)){
+            do_else = false;
             if(value.value.type != INT_value){
                 value.value.type = INT_value;
                 value.value.value.int_value = 0;
@@ -1254,6 +1239,10 @@ GWARF_result for_func(statement *the_statement, var_list *the_var, inter *global
             }
         }
     }
+    if(do_else){
+        GWARF_result tmp_result = traverse(the_statement->code.for_cycle.else_do, the_var, false, global_inter);
+        error_space(tmp_result, return_value, value);   
+    }
     return_value: 
     the_var = free_var_list(the_var);  // free the new var
     return value;
@@ -1453,18 +1442,12 @@ GWARF_result forin_func(statement *the_statement, var_list *the_var, inter *glob
     the_var = append_var_list(tmp, the_var);
     the_var->tag = run_while;
     GWARF_result tmp_result = traverse(the_statement->code.for_in_cycle.iter, the_var, false, global_inter);  // 取得迭代器
-    if(is_error(&tmp_result)){  // Name Error错误
-        // puts("STOP:: Name No Found!");
-        value = tmp_result;
-        goto return_value;
-    }
-    else if(is_space(&tmp_result)){
-        value = tmp_result;
-        goto return_value;
-    }
-    
+    error_space(tmp_result, return_value, value);
+
     GWARF_result iter_value = get__iter__(&(tmp_result.value), the_var, global_inter);  // 获取迭代object,一般是返回self
     error_space(iter_value, return_value, value);
+    
+    bool do_else = true;
     while (1){
         GWARF_result tmp_next = get__next__(&(iter_value.value), the_var, global_inter);// 执行__next__的返回值
         if(is_error(&tmp_next)){  // TODO:: 检查是否为IterException
@@ -1483,6 +1466,7 @@ GWARF_result forin_func(statement *the_statement, var_list *the_var, inter *glob
 
         // break的操作
         if((value.u == cycle_break) || (value.u == code_broken)){
+            do_else = false;
             if(value.value.type != INT_value){
                 value.value.type = INT_value;
                 value.value.value.int_value = 0;
@@ -1528,6 +1512,10 @@ GWARF_result forin_func(statement *the_statement, var_list *the_var, inter *glob
             }
         }
     }
+    if(do_else){
+        GWARF_result tmp_result = traverse(the_statement->code.for_in_cycle.else_do, the_var, false, global_inter);
+        error_space(tmp_result, return_value, value);   
+    }
     return_value: 
     the_var = free_var_list(the_var);  // free the new var
     return value;
@@ -1542,19 +1530,11 @@ GWARF_result while_func(statement *the_statement, var_list *the_var, inter *glob
     hash_var *tmp = make_hash_var();  // base_var
     the_var = append_var_list(tmp, the_var);
     the_var->tag = run_while;
-    bool condition;
+    bool condition, do_else = true;
     while (1){
         if(!do_while){  // do_while 为 true的时候跳过条件检查
             GWARF_result tmp_result = traverse(the_statement->code.while_cycle.condition, the_var, false, global_inter);
-            if(is_error(&tmp_result)){  // Name Error错误
-                // puts("STOP:: Name No Found!");
-                value = tmp_result;
-                goto return_value;
-            }
-            else if(is_space(&tmp_result)){
-                value = tmp_result;
-                goto return_value;
-            }
+            error_space(tmp_result, return_value, value);
             condition = to_bool(tmp_result.value, global_inter);
             printf("while condition = %d\n", condition);
             if(!condition){
@@ -1572,6 +1552,7 @@ GWARF_result while_func(statement *the_statement, var_list *the_var, inter *glob
 
         // break的操作
         if((value.u == cycle_break) || (value.u == code_broken)){
+            do_else = false;  // 不执行else部分
             if(value.value.type != INT_value){
                 value.value.type = INT_value;
                 value.value.value.int_value = 0;
@@ -1617,6 +1598,10 @@ GWARF_result while_func(statement *the_statement, var_list *the_var, inter *glob
             }
         }
     }
+    if(do_else){
+        GWARF_result tmp_result = traverse(the_statement->code.while_cycle.else_do, the_var, false, global_inter);
+        error_space(tmp_result, return_value, value);   
+    }
     return_value: 
     the_var = free_var_list(the_var);  // free the new var
     return value;

+ 5 - 0
inter/interpreter.h

@@ -219,6 +219,7 @@ typedef struct statement{
             struct statement *condition;  // when to while 
             struct statement *done;  // while to do
             bool first_do;  // do_while = true, while = false
+            struct statement *else_do;  // else to do
         } while_cycle;
 
         struct{
@@ -226,6 +227,7 @@ typedef struct statement{
             struct statement *condition;  // when to while 
             struct statement *after;  // what to do after the done
             struct statement *done;  // while to do
+            struct statement *else_do;  // else to do
         } for_cycle;
         
         struct{
@@ -367,6 +369,8 @@ typedef struct statement{
             struct statement *try;
             struct statement *except;
             struct statement *var;  // as var
+            struct statement *else_do;  // else to do
+            struct statement *finally_do;  // finally to do
         } try_code;
 
         struct
@@ -396,6 +400,7 @@ typedef struct statement{
             struct statement *var;  // for i in a -> i
             struct statement *iter;  // for i in a -> a
             struct statement *done;  // for while to do
+            struct statement *else_do;  // else to do
         } for_in_cycle;
 
         struct

+ 0 - 3
inter/var.c

@@ -279,11 +279,8 @@ var *find_var(var_list *var_base, int from, char *name, int *index){  // index
     if(index != NULL){
         *index = from;
     }
-    // puts("[tag 3]");
-    // printf("name = %s, from = %d, address = %x\n", name, from, start->var_base);
     while (1)
     {
-        // printf("[tag 4] %x  :  %x\n", start, var_base);
         return_var = find_node(name, start->hash_var_base);
         if((return_var == NULL) && (start->next == NULL)){  // don't get the var and not next
             return NULL;

+ 1 - 0
paser/lexical.c

@@ -193,6 +193,7 @@ int paser(int *index, p_status *status){
         match_text(p, global_paser[PROTECT_PASER], "protect");
         match_text(p, global_paser[PUBLIC_PASER], "public");
         match_text(p, global_paser[PRIVATE_PASER], "private");
+        match_text(p, global_paser[FINALLY_PASER], "finally");
 
         *index = check_list(global_paser, p, status);  // 检查解析结果
 

+ 77 - 3
paser/syntax.c

@@ -328,7 +328,7 @@ for_ : FOR LB top_exp COMMA top_exp COMMA top_exp RB block
 */
 void for_(p_status *status, token_node *list){
     fprintf(status_log, "[info][grammar]  mode status: for_\n");
-    token for_t, exp_1, exp_2, exp_3, block_t, comma_t,new_token;
+    token for_t, exp_1, exp_2, exp_3, block_t, next_t, child_t, comma_t,new_token;
     statement *exp_a, *exp_b, *exp_c;
     for_t = pop_node(list);
     if(for_t.type == FOR_PASER){
@@ -415,12 +415,30 @@ void for_(p_status *status, token_node *list){
             paser_error("Don't get '{'");
         }
 
+        statement *else_do = NULL;
+        el_again: 
+        get_pop_token(status,list,next_t);
+        if(next_t.type == ENTER_PASER){  // 忽略Enter
+            goto el_again;
+        }
+        if(next_t.type == ELSE_PASER){  // else
+            get_right_token(status,list,block_,child_t);
+            if(child_t.type != NON_block){
+                paser_error("Don't get '{'\n");
+            }
+            else_do = child_t.data.statement_value;
+        }
+        else{
+            back_again(list, next_t);  // 下一次读取需要用safe_get_token
+        }
+
         statement *for_tmp =  make_statement();
         if(is_for_in){
             for_tmp->type = for_in_cycle;
             for_tmp->code.for_in_cycle.var = exp_a;
             for_tmp->code.for_in_cycle.iter = exp_c;
             for_tmp->code.for_in_cycle.done = block_t.data.statement_value;
+            for_tmp->code.for_in_cycle.else_do = else_do;
         }
         else{
             for_tmp->type = for_cycle;
@@ -428,12 +446,19 @@ void for_(p_status *status, token_node *list){
             for_tmp->code.for_cycle.condition = exp_b;
             for_tmp->code.for_cycle.after = exp_c;
             for_tmp->code.for_cycle.done = block_t.data.statement_value;
+            for_tmp->code.for_cycle.else_do = else_do;
         }
 
         new_token.type = NON_for;
         new_token.data_type = statement_value;
         new_token.data.statement_value = for_tmp;
         add_node(list, new_token);  // 压入节点[弹出3个压入1个]
+
+        token tmp_enter;
+        tmp_enter.type = ENTER_PASER;
+        tmp_enter.data_type = empty;
+        back_again(list, tmp_enter);  // push入一个ENTER
+
         return;
     }
     else{
@@ -809,7 +834,7 @@ while_ : WHILE LB top_exp RB block
 */
 void do_while_(p_status *status, token_node *list){
     fprintf(status_log, "[info][grammar]  mode status: while_\n");
-    token do_t, while_t, exp_t, block_t, new_token;
+    token do_t, while_t, exp_t, block_t, next_t, child_t, new_token;
     do_t = pop_node(list);
     if(do_t.type == DO_PASER){
         get_right_token(status,list,block_,block_t);
@@ -836,10 +861,35 @@ void do_while_(p_status *status, token_node *list){
             tmp->code.while_cycle.first_do = true;
         }
 
+        statement *else_do = NULL;
+        el_again: 
+        get_pop_token(status,list,next_t);
+        if(next_t.type == ENTER_PASER){  // 忽略Enter
+            goto el_again;
+        }
+        if(next_t.type == ELSE_PASER){  // else
+            get_right_token(status,list,block_,child_t);
+            if(child_t.type != NON_block){
+                paser_error("Don't get '{'\n");
+            }
+            else_do = child_t.data.statement_value;
+        }
+        else{
+            back_again(list, next_t);  // 下一次读取需要用safe_get_token
+        }
+
+        tmp->code.while_cycle.else_do = else_do;
+
         new_token.type = NON_do_while;
         new_token.data_type = statement_value;
         new_token.data.statement_value = tmp;
         add_node(list, new_token);  // 压入节点[弹出3个压入1个]
+
+        token tmp_enter;
+        tmp_enter.type = ENTER_PASER;
+        tmp_enter.data_type = empty;
+        back_again(list, tmp_enter);  // push入一个ENTER
+
         return;
     }
     else{
@@ -853,7 +903,7 @@ while_ : WHILE LB top_exp RB block
 */
 void while_(p_status *status, token_node *list){
     fprintf(status_log, "[info][grammar]  mode status: while_\n");
-    token while_t, exp_t, block_t, new_token;
+    token while_t, exp_t, block_t, next_t, child_t, new_token;
     while_t = pop_node(list);
     if(while_t.type == WHILE_PASER){
         get_right_token(status,list,top_exp,exp_t);
@@ -866,16 +916,40 @@ void while_(p_status *status, token_node *list){
             paser_error("Don't get '{'");
         }
 
+        statement *else_do = NULL;
+        el_again: 
+        get_pop_token(status,list,next_t);
+        if(next_t.type == ENTER_PASER){  // 忽略Enter
+            goto el_again;
+        }
+        if(next_t.type == ELSE_PASER){  // else
+            get_right_token(status,list,block_,child_t);
+            if(child_t.type != NON_block){
+                paser_error("Don't get '{'\n");
+            }
+            else_do = child_t.data.statement_value;
+        }
+        else{
+            back_again(list, next_t);  // 下一次读取需要用safe_get_token
+        }
+
         statement *while_tmp =  make_statement();
         while_tmp->type = while_cycle;
         while_tmp->code.while_cycle.condition = exp_t.data.statement_value;
         while_tmp->code.while_cycle.done = block_t.data.statement_value;
         while_tmp->code.while_cycle.first_do = false;
+        while_tmp->code.while_cycle.else_do = else_do;
 
         new_token.type = NON_while;
         new_token.data_type = statement_value;
         new_token.data.statement_value = while_tmp;
         add_node(list, new_token);  // 压入节点[弹出3个压入1个]
+
+        token tmp_enter;
+        tmp_enter.type = ENTER_PASER;
+        tmp_enter.data_type = empty;
+        back_again(list, tmp_enter);  // push入一个ENTER
+
         return;
     }
     else{

+ 3 - 1
paser/token.h

@@ -3,7 +3,7 @@
 
 #include "../inter/interpreter.h"
 
-#define MAX_PASER_SIZE 106
+#define MAX_PASER_SIZE 107
 #define INT_PASER 0
 #define DOUBLE_PASER 1
 #define ENTER_PASER 2
@@ -110,6 +110,7 @@
 #define BOOLIS_PASER 103
 #define BOOLSAND_PASER 104
 #define BOOLSOR_PASER 105
+#define FINALLY_PASER 106
 
 // 获取并返回一个token
 #define get_pop_token(status,list,new_token) \
@@ -264,6 +265,7 @@ typedef enum token_type
     BOOLIS = BOOLIS_PASER,
     BOOLSAND = BOOLSAND_PASER,
     BOOLSOR = BOOLSOR_PASER,
+    FINALLY = FINALLY_PASER,
 
     // 特殊符号
     BAD_token = -2,