Przeglądaj źródła

函数形参和实参匹配

SongZihuan 5 lat temu
rodzic
commit
539f3c4b18
7 zmienionych plików z 575 dodań i 401 usunięć
  1. BIN
      gwarf
  2. 5 2
      inter/cfunc.c
  3. 167 79
      inter/interpreter.c
  4. 13 4
      inter/interpreter.h
  5. 7 2
      inter/parameter.c
  6. 63 2
      paser/gwarf_yacc.y
  7. 320 312
      paser/y.tab.c

BIN
gwarf


+ 5 - 2
inter/cfunc.c

@@ -230,8 +230,8 @@ class_object *object_login_official(var_list *the_var, GWARF_result (*paser)(fun
 
 
     // 注册函数
-    int a[][2] = {{3,1}};
-    char *name[] = {"__value__"};
+    int a[][2] = {{3,1}, {__assignment__func, 1}};
+    char *name[] = {"__value__", "__assignment__"};
 
     int lenth = sizeof(a)/sizeof(a[0]);
     for(int i = 0;i < lenth;i+=1){
@@ -1846,6 +1846,9 @@ GWARF_value parameter_to_list(parameter *tmp_s, var_list *the_var){  // 把param
         if(tmp_s == NULL){
             break;
         }
+        if(tmp_s->type != only_value){
+            goto next;  // 跳过这一个
+        }
         result_tmp = traverse(tmp_s->u.value, the_var, false);  // 不需要取__value__
         if(is_error(&result_tmp)){  // Name Error错误
             goto next;  // 直接指向下一个

+ 167 - 79
inter/interpreter.c

@@ -1716,6 +1716,146 @@ GWARF_result call_back(statement *the_statement, var_list *the_var){  // the fun
     return result;
 }
 
+GWARF_result login_var(var_list *the_var, var_list *old_var_list, parameter *tmp_x, parameter *tmp_s){
+    GWARF_result return_result;
+    return_result.u = statement_end;
+    return_result.value.type = NULL_value;
+    return_result.value.value.int_value = 0;
+
+    int assignment_type = 0;  // 0-根据tmp_x进行赋值,1-根据tmp_s赋值
+    var_list *tmp_var = make_var_base(make_var());  // 为1-模式准备
+
+    while(1){
+        if ((tmp_x == NULL)&&(tmp_s == NULL)){  // the last
+            break;
+        }
+        if(assignment_type == 0){  // 对位赋值
+            if ((tmp_x == NULL)&&(tmp_s != NULL)){  // 参数过多
+                printf("Warning!!!\n");
+                break;
+            }
+            else if ((tmp_x != NULL)&&(tmp_s == NULL)){  // 使用默认值
+                while(1){  // 如果是name_value类型则继续赋值
+                    if(tmp_x == NULL){
+                        break;
+                    }
+                    else if(tmp_x->type == name_value){
+                        GWARF_result tmp = traverse(tmp_x->u.value, the_var, false);  // 执行形参
+                        if(is_error(&tmp) || is_space(&tmp)){
+                            return tmp;
+                        }
+                        assignment_func(tmp_x->u.name, tmp, the_var, 0);
+                        tmp_x = tmp_x->next;  // get the next to iter
+                    }
+                    else if(tmp_x->type == put_args){  // args默认为[]
+                        GWARF_result func_result;
+                        var *list_init;
+                        func_result.u = statement_end;
+                        list_init = find_var(old_var_list, 0, "list");
+                        if(list_init != NULL){
+                            func_result.value = list_init->value;
+                        }
+                        assignment_func(tmp_x->u.name, call_back_core(func_result, old_var_list, NULL), the_var, 0);
+                        tmp_x = tmp_x->next;  // get the next to iter
+                    }
+                    else{
+                        printf("warning!!!\n");
+                        break;
+                    }
+
+                }
+                break;
+            }
+        }
+        else if(assignment_type == 1){  // 根据实参  a = b 来赋值
+            if ((tmp_x != NULL)&&(tmp_s == NULL)){  // 实参录入完毕
+                while(1){
+                    if(tmp_x == NULL){
+                        break;  // 形参录入完毕
+                    }
+                    var *tmp_x_var = find_var(tmp_var, 0, tmp_x->u.name);
+                    if(tmp_x_var != NULL){
+                        GWARF_result tmp_result;
+                        tmp_result.value = tmp_x_var->value;
+                        assignment_func(tmp_x->u.name, tmp_result, the_var, 0);
+                    }
+                    else if(tmp_x->type == name_value){
+                        GWARF_result tmp = traverse(tmp_x->u.value, the_var, false);  // 执行形参
+                        if(is_error(&tmp) || is_space(&tmp)){
+                            return tmp;
+                        }
+                        assignment_func(tmp_x->u.name, tmp, the_var, 0);
+                    }
+                    else{
+                        printf("Warning!!!");
+                        break;
+                    }
+                    tmp_x = tmp_x->next;
+                }
+                break;
+            }
+        }
+
+        GWARF_result tmp = traverse(tmp_s->u.value, old_var_list, false);  // 不需要取__value__
+        if(is_error(&tmp)){
+            return tmp;
+        }
+        else if(is_space(&tmp)){
+            return tmp;
+        }
+
+        if(assignment_type == 1 || tmp_s->type == name_value){
+            if(tmp_s->type != name_value){
+                printf("Warning!!!");  // 进入了模式1, 但不是name_value
+                break;
+            }
+            assignment_type = 1;
+            assignment_func(tmp_s->u.name, tmp, tmp_var, 0);  // 先赋值到tmp_var上
+            tmp_s = tmp_s->next;
+        }
+        else if(tmp_s->type == put_args){  // assignment_type不在1模式
+            parameter *before = tmp_s, *after = tmp_s->next;
+            GWARF_value iter_value = get__iter__(&(tmp.value), old_var_list).value;  // 获取迭代object,一般是返回self
+            while (1){
+                GWARF_result tmp_next = get__next__(&(iter_value), old_var_list);// 执行__next__的返回值
+                if(is_error(&tmp_next)){  // TODO:: 检查是否为IterException
+                    break;  // goto return_value;
+                }
+                if(is_space(&tmp_next)){  // TODO:: 检查是否为IterException
+                    return tmp_next;
+                }
+                before->next = pack_value_parameter(tmp_next.value);
+                before = before->next;
+            }
+            before->next = after;
+            tmp_s = tmp_s->next;  // 实参去下一位, 形参不变
+        }
+        else if(assignment_type == 0 && tmp_x->type == put_args){
+            // 放入list中
+            GWARF_result list_tmp;
+            list_tmp.value = to_object(parameter_to_list(tmp_s, old_var_list), old_var_list);
+            assignment_func(tmp_x->u.name, list_tmp, the_var, 0);
+            assignment_type = 1;  // 进入根据实参赋值模式
+            tmp_x = tmp_x->next;
+            while(1){
+                if(tmp_s == NULL){
+                    break;
+                }
+                if(tmp_s->type != only_value){
+                    break;
+                }
+                tmp_s = tmp_s->next;
+            }
+        }
+        else if(assignment_type == 0){
+            assignment_func(tmp_x->u.name, tmp, the_var, 0);
+            tmp_x = tmp_x->next;  // get the next to iter
+            tmp_s = tmp_s->next;
+        }
+    }
+    return return_result;
+}
+
 GWARF_result call_back_core(GWARF_result get, var_list *the_var, parameter *tmp_s){  // the func for add and call from read_statement_list
     GWARF_result result;
     var_list *old_var_list = the_var;
@@ -1731,41 +1871,29 @@ GWARF_result call_back_core(GWARF_result get, var_list *the_var, parameter *tmp_
         // printf("----new address = %d----\n", the_var);
 
         if(func_->type == customize){  // 用户定义的方法
-            if(tmp_x == NULL){
-                goto no_tmp_x;  // 无形参
-            }
+            // 赋值self
             GWARF_result father;
             if(func_->is_class  == 1){
-                father.value = *(get.father);
-                assignment_func(tmp_x->u.name, father, the_var, 0);
-                if (tmp_x->next == NULL){  // the last
-                    goto no_tmp_x;
-                }
-                tmp_x = tmp_x->next;  // get the next to iter
-            }
-            while(1){
-                GWARF_result tmp = traverse(tmp_s->u.value, the_var, false);  // 不需要取__value__
-                if(is_error(&tmp)){  // Name Error错误
-                    // puts("STOP:: Name No Found!");
-                    the_var = free_var_list(the_var);  // free the new var
-                    return tmp;
-                }
-                else if(is_space(&tmp)){
-                    the_var = free_var_list(the_var);  // free the new var
-                    return tmp;
+                if(get.father != NULL){
+                    father.value = *(get.father);
+                    assignment_func(tmp_x->u.name, father, the_var, 0);
+                    tmp_x = tmp_x->next;  // get the next to iter
                 }
-                assignment_func(tmp_x->u.name, tmp, the_var, 0);
-                if ((tmp_x->next == NULL)||(tmp_s->next == NULL)){  // the last
-                    break;
+                else{
+                    printf("Warning!!!\n");
+                    // TODO:: 抛出错误
                 }
-                tmp_x = tmp_x->next;  // get the next to iter
-                tmp_s = tmp_s->next;
             }
-            no_tmp_x: 
+
+            GWARF_result tmp_return = login_var(the_var, old_var_list, tmp_x, tmp_s);
+            if(tmp_return.u != statement_end){
+                the_var = free_var_list(the_var);  // free the new var
+                return tmp_return;
+            }
+
             puts("----start func----");
             result = traverse(func_->done, the_var, false);  // 执行func_value->done
             if(is_error(&result)){  // Name Error错误
-                // puts("STOP:: Name No Found!");
                 the_var = free_var_list(the_var);  // free the new var
                 return result;
             }
@@ -1796,45 +1924,24 @@ GWARF_result call_back_core(GWARF_result get, var_list *the_var, parameter *tmp_
             the_var = func_->the_var;
             // tmp_x:形参,tmp_s:实参
 
-            // // printf("----address = %d----\n", the_var);
             var *tmp = make_var();  // base_var
             the_var = append_var_list(tmp, the_var);
-            // // printf("----new address = %d----\n", the_var);
 
             if(func_->type == customize){  // 用户定义的方法
-                if(tmp_x == NULL){
-                    puts("No tmp_x");
-                    goto no_tmp_x_init;  // 无形参
-                }
                 GWARF_result father;
                 father.value.type = OBJECT_value;
                 father.value.value.object_value = object_tmp;
                 if(func_->is_class  == 1){
                     assignment_func(tmp_x->u.name, father, the_var, 0);
-                    if (tmp_x->next == NULL){  // the last
-                        goto no_tmp_x_init;
-                    }
                     tmp_x = tmp_x->next;  // get the next to iter
                 }
-                while(1){
-                    GWARF_result tmp = traverse(tmp_s->u.value, the_var, false);
-                    if(is_error(&tmp)){  // Name Error错误
-                        // puts("STOP:: Name No Found!");
-                        the_var = free_var_list(the_var);  // free the new var
-                        return tmp;
-                    }
-                    else if(is_space(&tmp)){
-                        the_var = free_var_list(the_var);  // free the new var
-                        return tmp;
-                    }
-                    assignment_func(tmp_x->u.name, tmp, the_var, 0);
-                    if ((tmp_x->next == NULL)||(tmp_s->next == NULL)){  // the last
-                        break;
-                    }
-                    tmp_x = tmp_x->next;  // get the next to iter
-                    tmp_s = tmp_s->next;
+
+                GWARF_result tmp_return = login_var(the_var, old_var_list, tmp_x, tmp_s);
+                if(tmp_return.u != statement_end){
+                    the_var = free_var_list(the_var);  // free the new var
+                    return tmp_return;
                 }
-                no_tmp_x_init: 
+
                 puts("----start func----");
                 {
                     GWARF_result tmp = traverse(func_->done, the_var, false);  // 执行func_value->done
@@ -1888,39 +1995,20 @@ GWARF_result call_back_core(GWARF_result get, var_list *the_var, parameter *tmp_
             // // printf("----new address = %d----\n", the_var);
 
             if(func_->type == customize){  // 用户定义的方法
-                if(tmp_x == NULL){
-                    puts("No tmp_x");
-                    goto no_tmp_x_call;  // 无形参
-                }
                 GWARF_result father;
                 father.value.type = OBJECT_value;
                 father.value.value.object_value = get.value.value.object_value;
                 if(func_->is_class  == 1){
                     assignment_func(tmp_x->u.name, father, the_var, 0);
-                    if (tmp_x->next == NULL){  // the last
-                        goto no_tmp_x_call;
-                    }
                     tmp_x = tmp_x->next;  // get the next to iter
                 }
-                while(1){
-                    GWARF_result tmp = traverse(tmp_s->u.value, the_var, false);
-                    if(is_error(&tmp)){  // Name Error错误
-                        // puts("STOP:: Name No Found!");
-                        the_var = free_var_list(the_var);  // free the new var
-                        return tmp;
-                    }
-                    else if(is_space(&tmp)){
-                        the_var = free_var_list(the_var);  // free the new var
-                        return tmp;
-                    }
-                    assignment_func(tmp_x->u.name, tmp, the_var, 0);
-                    if ((tmp_x->next == NULL)||(tmp_s->next == NULL)){  // the last
-                        break;
-                    }
-                    tmp_x = tmp_x->next;  // get the next to iter
-                    tmp_s = tmp_s->next;
+
+                GWARF_result tmp_return = login_var(the_var, old_var_list, tmp_x, tmp_s);
+                if(tmp_return.u != statement_end){
+                    the_var = free_var_list(the_var);  // free the new var
+                    return tmp_return;
                 }
-                no_tmp_x_call: 
+
                 puts("----start func----");
                 {
                     GWARF_result tmp = traverse(func_->done, the_var, false);  // 执行func_value->done

+ 13 - 4
inter/interpreter.h

@@ -44,11 +44,20 @@ typedef struct GWARF_value{
 
 // ------------------------- parameter for def
 typedef struct parameter{
-    union
+    struct
     {
         char *name;  // var name
-        struct statement *value;  // or value
+        struct statement *value;  // var value
     } u;
+    enum {
+        only_name,  // 形参
+        only_value,  // 实参
+        name_value,  // 形参/实参
+        put_args,
+        // put_kwargs,
+        // get_args,
+        // get_kwargs,
+    } type;
     struct parameter *next;  // for list
 } parameter;
 
@@ -578,10 +587,10 @@ void add_var(var_list *,int , char *, GWARF_value);
 var_list *copy_var_list(var_list *);
 
 parameter *make_parameter_name(char *);
-void append_parameter_name(char *, parameter *);
+parameter *append_parameter_name(char *, parameter *);
 
 parameter *make_parameter_value(statement *);
-void append_parameter_value(statement *, parameter *);
+parameter *append_parameter_value(statement *, parameter *);
 parameter *add_parameter_value(statement *, parameter *);
 
 parameter *pack_value_parameter(GWARF_value);

+ 7 - 2
inter/parameter.c

@@ -7,11 +7,12 @@ parameter *make_parameter_name(char *name){
     tmp = malloc(sizeof(parameter));  // get an address for base var
     tmp->next = NULL;
     tmp->u.name = malloc(sizeof(name));
+    tmp->type = only_name;
     strcpy(tmp->u.name, name);
     return tmp;
 }
 
-void append_parameter_name(char *name, parameter *parameter_base){
+parameter *append_parameter_name(char *name, parameter *parameter_base){
     parameter *tmp = parameter_base;  // iter var
     while(1){
         if (tmp->next == NULL){  // the last
@@ -21,6 +22,7 @@ void append_parameter_name(char *name, parameter *parameter_base){
     }
     parameter *new_tmp = make_parameter_name(name);
     tmp->next = new_tmp;
+    return new_tmp;
 }
 
 // ---- parameter func[实参]
@@ -28,11 +30,12 @@ parameter *make_parameter_value(statement *value){
     parameter *tmp;
     tmp = malloc(sizeof(parameter));  // get an address for base var
     tmp->next = NULL;
+    tmp->type = only_value;
     tmp->u.value = value;
     return tmp;
 }
 
-void append_parameter_value(statement *value, parameter *parameter_base){  // add at last
+parameter *append_parameter_value(statement *value, parameter *parameter_base){  // add at last
     parameter *tmp = parameter_base;  // iter var
     while(1){
         if (tmp->next == NULL){  // the last
@@ -42,6 +45,7 @@ void append_parameter_value(statement *value, parameter *parameter_base){  // ad
     }
     parameter *new_tmp = make_parameter_value(value);
     tmp->next = new_tmp;
+    return new_tmp;
 }
 
 parameter *add_parameter_value(statement *value, parameter *parameter_base){  // add at first
@@ -54,6 +58,7 @@ parameter *pack_value_parameter(GWARF_value value){  // 把value封装成参数
     parameter *tmp;
     tmp = malloc(sizeof(parameter));  // get an address for base var
     tmp->next = NULL;
+    tmp->type = only_value;
     statement *statement_tmp = make_statement();
     statement_tmp->type = base_value;
     statement_tmp->code.base_value.value = value;

+ 63 - 2
paser/gwarf_yacc.y

@@ -1111,25 +1111,86 @@ formal_parameter
     : base_var_
     {
         $$ = make_parameter_name($1->code.base_var.var_name);
+        $$->type = only_name;
+        free($1->code.base_var.var_name);
+        free($1);
+    }
+    | MUL base_var_
+    {
+        $$ = make_parameter_name($2->code.base_var.var_name);
+        $$->type = put_args;
+        free($2->code.base_var.var_name);
+        free($2);
+    }
+    | base_var_ EQ top_exp
+    {
+        $$ = make_parameter_name($1->code.base_var.var_name);
+        $$->u.value = $3;
+        $$->type = name_value;
         free($1->code.base_var.var_name);
         free($1);
     }
     | formal_parameter COMMA base_var_
     {
-        append_parameter_name($3->code.base_var.var_name, $1);
+        parameter *tmp = append_parameter_name($3->code.base_var.var_name, $1);
+        tmp->type = only_name;
+        $$ = $1;
+        free($3->code.base_var.var_name);
+        free($3);
+    }
+    | formal_parameter COMMA MUL base_var_
+    {
+        parameter *tmp = append_parameter_name($4->code.base_var.var_name, $1);
+        tmp->type = put_args;
+        $$ = $1;
+        free($4->code.base_var.var_name);
+        free($4);
+    }
+    | formal_parameter COMMA base_var_ EQ top_exp
+    {
+        parameter *tmp = append_parameter_name($3->code.base_var.var_name, $1);
+        tmp->u.value = $5;
+        tmp->type = name_value;
         $$ = $1;
+        free($3->code.base_var.var_name);
+        free($3);
     }
+    ;
 
 arguments
     : top_exp
     {
         $$ = make_parameter_value($1);
+        $$->type = only_value;
     }
     | arguments COMMA top_exp
     {
-        append_parameter_value($3, $1);
+        parameter *tmp = append_parameter_value($3, $1);
+        tmp->type = only_value;
         $$ = $1;
     }
+    | base_var_ EQ top_exp
+    {
+        $$ = make_parameter_name($1->code.base_var.var_name);
+        $$->u.value = $3;
+        $$->type = name_value;
+        free($1->code.base_var.var_name);
+        free($1);
+    }
+    | arguments COMMA base_var_ EQ top_exp
+    {
+        parameter *tmp = append_parameter_name($3->code.base_var.var_name, $1);
+        tmp->u.value = $5;
+        tmp->type = name_value;
+        $$ = $1;
+        free($3->code.base_var.var_name);
+        free($3);
+    }
+    | MUL top_exp
+    {
+        $$ = make_parameter_value($2);
+        $$->type = put_args;
+    }
     ;
 
 slice_arguments

Plik diff jest za duży
+ 320 - 312
paser/y.tab.c


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików