Jelajahi Sumber

feat: 设置__bool__函数

SongZihuan 4 tahun lalu
induk
melakukan
8c9cf2f306
7 mengubah file dengan 94 tambahan dan 27 penghapusan
  1. 4 2
      ofunc/src/bool.c
  2. 0 2
      ofunc/src/pass.c
  3. 45 0
      ofunc/src/vobject.c
  4. 14 18
      src/__run.c
  5. 1 1
      src/include/__run.h
  6. 26 4
      src/runbranch.c
  7. 4 0
      src/runcall.c

+ 4 - 2
ofunc/src/bool.c

@@ -13,8 +13,10 @@ ResultType bool_init(OFFICAL_FUNCTIONSIG){
 
     base = ap[0].value;
     base->value->type = bool_;
-    base->value->data.bool_.bool_ = checkBool(ap[1].value->value);
-    setResultBase(result, inter, belong);
+    base->value->data.bool_.bool_ = checkBool(ap[1].value, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    setResult(result, inter, belong);
     return result->type;
 }
 

+ 0 - 2
ofunc/src/pass.c

@@ -2,10 +2,8 @@
 
 void registeredEllipisis(REGISTERED_FUNCTIONSIG){
     LinkValue *object = makeLinkValue(inter->data.pass_, inter->base_father, inter);
-//    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("ellipsis", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
-//    iterClassFunc(tmp, object, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
     gc_freeTmpLink(&object->gc_status);
 }
 

+ 45 - 0
ofunc/src/vobject.c

@@ -90,12 +90,57 @@ ResultType vobject_div(OFFICAL_FUNCTIONSIG){
     return vobject_opt_core(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), vobject_div_base);
 }
 
+ResultType vobject_bool(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    bool result_ = false;
+    Value *value = NULL;
+    Value *return_value = NULL;
+    setResultCore(result);
+    {
+        parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            return result->type;
+        freeResult(result);
+    }
+    value = ap[0].value->value;
+    switch (value->type) {
+        case number:
+            result_ = value->data.num.num != 0;
+            break;
+        case string:
+            result_ = memStrlen(value->data.str.str) > 0;
+            break;
+        case bool_:
+            result_ = value->data.bool_.bool_;
+            break;
+        case pass_:
+        case none:
+            result_ = false;
+            break;
+        case list:
+            result_ = value->data.list.size > 0;
+            break;
+        case dict:
+            result_ = value->data.dict.size > 0;
+            break;
+        default:
+            setResultError(E_TypeException, "\"vobject.__bool__\" gets an unsupported value type",
+                           0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            return error_return;
+    }
+    return_value = makeBoolValue(result_, inter);
+    setResultOperationBase(result, makeLinkValue(return_value, belong, inter));
+    return result->type;
+}
+
 void registeredVObject(REGISTERED_FUNCTIONSIG){
     LinkValue *object = makeLinkValue(inter->data.vobject, inter->base_father, inter);
     NameFunc tmp[] = {{"__add__", vobject_add, object_free_},
                       {"__sub__", vobject_sub, object_free_},
                       {"__mul__", vobject_mul, object_free_},
                       {"__div__", vobject_div, object_free_},
+                      {"__bool__", vobject_bool, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("vobject", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));

+ 14 - 18
src/__run.c

@@ -281,22 +281,18 @@ ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_F
     return result->type;
 }
 
-bool checkBool(Value *value){
-    switch (value->type) {
-        case number:
-            return value->data.num.num != 0;
-        case string:
-            return memStrlen(value->data.str.str) > 0;
-        case bool_:
-            return value->data.bool_.bool_;
-        case pass_:
-        case none:
-            return false;
-        case list:
-            return value->data.list.size > 0;
-        case dict:
-            return value->data.dict.size > 0;
-        default:
-            return true;
-    }
+bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
+    LinkValue *_bool_ = findAttributes("__bool__", false, value, inter);
+    setResultCore(result);
+    if (_bool_ != NULL){
+        gc_addTmpLink(&_bool_->gc_status);
+        callBackCore(_bool_, NULL, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&_bool_->gc_status);
+        if (result->value->value->type != bool_)
+            setResultError(E_TypeException, "__bool__ function should return bool type data", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        else
+            return result->value->value->data.bool_.bool_;
+    } else
+        setResultError(E_TypeException, "Object does not support __bool__ function", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return false;
 }

+ 1 - 1
src/include/__run.h

@@ -37,5 +37,5 @@ void addAttributes(char *name, bool free_old, LinkValue *value, LinkValue *belon
 void newObjectSetting(LinkValue *name, LinkValue *belong, Inter *inter);
 ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
-bool checkBool(Value *value);
+bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH___RUN_H

+ 26 - 4
src/runbranch.c

@@ -79,6 +79,7 @@ ResultType ifBranch(INTER_FUNCTIONSIG) {
     }
 
     for (PASS; if_list != NULL; if_list = if_list->next){
+        bool condition;
         freeResult(result);
         if (info_vl != NULL){
             if (ifBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(info_vl, var_list, result, belong))){
@@ -108,7 +109,15 @@ ResultType ifBranch(INTER_FUNCTIONSIG) {
                 freeResult(result);
             }
 
-            bool condition = is_rego ? true : checkBool(condition_value->value);  // 若是rego则不执行checkbool的判断了
+            if (!(condition = is_rego)){
+                condition = checkBool(condition_value, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                if (!CHECK_RESULT(result)) {
+                    set_result = false;
+                    goto not_else;
+                }
+                freeResult(result);
+            }
+
             if (condition){
                 is_rego = false;
                 if (ifBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(if_list->code, var_list, result, belong))){
@@ -217,7 +226,7 @@ ResultType whileBranch(INTER_FUNCTIONSIG) {
         LinkValue *condition_value = NULL;
         Statement *after_st = after;
         Statement *while_st = while_list->code;
-        bool condition = false;
+        bool condition;
         freeResult(result);
 
         if (info_vl != NULL){
@@ -247,8 +256,17 @@ ResultType whileBranch(INTER_FUNCTIONSIG) {
             freeResult(result);  // 赋值的返回值被丢弃
         }
 
-        condition = do_while || checkBool(condition_value->value);
+        condition = do_while;
+        if (!(condition = do_while)){
+            condition = checkBool(condition_value, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            if (!CHECK_RESULT(result)){
+                set_result = false;
+                goto not_else;
+            }
+            freeResult(result);
+        }
         do_while = false;
+
         if (condition){
             do_while_st:
             if (cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(while_st, var_list, result, belong))){
@@ -935,11 +953,15 @@ ResultType raiseCode(INTER_FUNCTIONSIG){
 }
 
 ResultType assertCode(INTER_FUNCTIONSIG){
+    bool result_;
     setResultCore(result);
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.raise_code.value, var_list, result, belong)))
         return result->type;
 
-    if (checkBool(result->value->value))
+    result_ = checkBool(result->value, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    else if (result_)
         setResult(result, inter, belong);
     else
         setResultErrorSt(E_AssertException, "Assertion check error", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));

+ 4 - 0
src/runcall.c

@@ -225,6 +225,10 @@ ResultType callCFunction(LinkValue *function_value, Argument *arg, long int line
 
     freeResult(result);
     of(CALL_OFFICAL_FUNCTION(arg, function_var, result, function_value->belong));
+    if (result->type == function_return)
+        result->type = operation_return;
+    else if (result->type != operation_return)
+        setResult(result, inter, function_value->belong);
 
     gc_freeze(inter, var_list, function_var, false);
     freeFunctionArgument(arg, bak);