浏览代码

feat & fix: 添加stdin stdout stderr

添加三个新内置变量: stdin, stdout, stderr
修复COPY_LINKVALUE导致gc错误的问题

link #7
SongZihuan 4 年之前
父节点
当前提交
d09ef3e868

+ 2 - 2
vmcore/include/ofunc.h

@@ -37,8 +37,8 @@ struct NameFunc{
 };
 typedef struct NameFunc NameFunc;
 
-void registeredBaseFunction(struct LinkValue *father, Inter *inter);
-void registeredFunctionName(Inter *inter, LinkValue *belong);
+void registeredBaseFunction(struct LinkValue *belong, Inter *inter);
+void registeredFunctionName(LinkValue *belong, Inter *inter);
 
 // 普通模式函数
 LinkValue *intCore(LinkValue *belong, LinkValue *class, Inter *inter);

+ 1 - 0
vmcore/include/value.h

@@ -247,6 +247,7 @@ Value *makeIntValue(vint num, fline line, char *file, FUNC_NT);
 Value *makeDouValue(vdou num, fline line, char *file, FUNC_NT);
 Value *makePointerValue(void *p, fline line, char *file, FUNC_NT);
 Value *makeStringValue(wchar_t *str, fline line, char *file, FUNC_NT);
+Value *makeFileValue(FILE *file_, char *mode, bool is_std, char *path, fline line, char *file, FUNC_NT);
 Value *makeVMFunctionValue(struct Statement *st, struct Parameter *pt, FUNC_NT);
 Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, bool set_var, bool push, FUNC_NT);
 LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFunction function_new, LinkValue *belong, VarList *var_list, Inter *inter);

+ 0 - 1
vmcore/include/var.h

@@ -63,7 +63,6 @@ void addFromVarList(wchar_t *name, LinkValue *name_, vint times, LinkValue *valu
 
 VarList *pushVarList(VarList *base, Inter *inter);
 VarList *copyVarList(VarList *base, bool n_new, Inter *inter);
-VarList *connectVarListBack(VarList *base, VarList *back);
 VarList *makeObjectVarList(Inherit *value, Inter *inter, VarList *base);
 
 vint findDefault(DefaultVar *base, wchar_t *name);

+ 2 - 2
vmcore/ofunc/src/file_.c

@@ -48,7 +48,7 @@ ResultType file_init(O_FUNC){
         return R_error;
     }
 
-    if (ap[1].value->value == NULL) {
+    if (ap[1].value == NULL) {
         setResult(result, inter);
         return result->type;
     } else if (ap[1].value->value->type != V_str) {
@@ -364,7 +364,7 @@ void registeredFile(R_FUNC){
                       {L"err", file_iserr, object_free_, .var=nfv_notpush},
                       {L"clean", file_clean_err, object_free_, .var=nfv_notpush},
                       {inter->data.mag_func[M_ENTER], file_enter, object_free_, .var=nfv_notpush},
-                      {inter->data.mag_func[M_DEL], file_close, object_free_, .var=nfv_notpush},
+//                      {inter->data.mag_func[M_DEL], file_close, object_free_, .var=nfv_notpush},
                       {inter->data.mag_func[M_EXIT], file_close, object_free_, .var=nfv_notpush},
                       {inter->data.mag_func[M_NEW], file_new, class_free_, .var=nfv_notpush},
                       {inter->data.mag_func[M_INIT], file_init, object_free_, .var=nfv_notpush},

+ 8 - 1
vmcore/ofunc/src/vobject.c

@@ -387,7 +387,7 @@ ResultType vobject_repo(O_FUNC){
     freeResult(result);
     value = ap[0].value->value;
 
-    switch (value->type){
+    switch (value->type){  // node和list以及dict都不再此处设定
         case V_int: {
             char str[30] = { NUL };
             snprintf(str, 30, "%lld", value->data.int_.num);
@@ -433,6 +433,13 @@ ResultType vobject_repo(O_FUNC){
         case V_ell:
             repo = memStrToWcs("...", false);
             break;
+        case V_file: {
+            size_t len = memStrlen(value->data.file.path) + memStrlen(value->data.file.mode) + 20;
+            char str[len];  // 变长数组
+            snprintf(str, len, "(file on %s %s)", value->data.file.path, value->data.file.mode);
+            repo = memStrToWcs(str, false);
+            break;
+        }
         default:
             setResultError(E_TypeException, CUL_ERROR(repo/str), LINEFILE, true, CNEXT_NT);
             return R_error;

+ 1 - 1
vmcore/src/inter.c

@@ -47,7 +47,7 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
         tmp->data.is_stdin = true;
     }
 
-    registeredFunctionName(tmp, belong);
+    registeredFunctionName(belong, tmp);
     tmp->data.start_gc = true;
 #if START_GC
     gc_run(tmp, tmp->var_list);

+ 31 - 5
vmcore/src/ofunc.c

@@ -20,13 +20,38 @@ static Registered base_func_list[] = {registeredVObject,
                                       registeredIOFunction,
                                       NULL};
 
-void registeredBaseFunction(struct LinkValue *father, Inter *inter){
+void registeredBaseFunction(LinkValue *belong, Inter *inter){
     for (Registered *list = base_func_list; *list != NULL; list++)
-        (*list)(CR_FUNC(father, inter->var_list));
+        (*list)(CR_FUNC(belong, inter->var_list));
 }
 
-void registeredFunctionName(Inter *inter, LinkValue *belong){
-    makeBaseObject(inter, belong);
+static void registeredStdFile(FILE *std, char *path, char *mode, wchar_t *name, LinkValue *belong, Inter *inter) {
+    Result result;
+    setResultCore(&result);
+
+    makeFileValue(std, mode, true, path, LINEFILE, CFUNC_NT(inter->var_list, &result, belong));
+    if (RUN_TYPE(result.type)) {
+        LinkValue *new = result.value;
+        result.value = NULL;
+        freeResult(&result);
+        addStrVar(name, false, false, new, LINEFILE, false, CFUNC_NT(inter->var_list, &result, belong));
+        gc_freeTmpLink(&new->gc_status);
+        if (!RUN_TYPE(result.type))
+            goto error;
+        freeResult(&result);
+    } else {
+        error: printError(&result, inter, true);
+    }
+}
+
+static void registeredBaseVar(LinkValue *belong, Inter *inter){
+    registeredStdFile(stdin, "stdin", "r", L"stdin", belong, inter);
+    registeredStdFile(stdout, "stdout", "w", L"stdout", belong, inter);
+    registeredStdFile(stderr, "stderr", "w", L"stderr", belong, inter);
+}
+
+void registeredFunctionName(LinkValue *belong, Inter *inter) {
+    makeBaseObject(inter, belong);  // 在makeBaseObject之前base_belong还是NULL, object要关联于belong参数给定的值(用于import的时候)
 
     makeBaseVObject(inter);
 
@@ -45,8 +70,9 @@ void registeredFunctionName(Inter *inter, LinkValue *belong){
     makeBasePointer(inter);
 
     makeBaseStr(inter);
-    functionPresetting(inter->data.base_obj[B_FUNCTION], inter);
+    functionPresetting(inter->data.base_obj[B_FUNCTION], inter);  // 预设定function的__new__方法
 
     registeredObject(inter->base_belong, CFUNC_CORE(inter->var_list));
     registeredBaseFunction(inter->base_belong, inter);
+    registeredBaseVar(inter->base_belong, inter);
 }

+ 3 - 0
vmcore/src/runoperation.c

@@ -190,11 +190,14 @@ ResultType pointOperation(FUNC) {
         goto return_;
     }
     optSafeInterStatement(CFUNC(st->u.operation.right, object, result, left));  // 点运算运算时需要调整belong为点的左值
+    // TODO-szh 该检查移动到 get_var 中
     pri_auto = result->value->belong == NULL || result->value->belong->value == belong->value || checkAttribution(belong->value, result->value->belong->value);  // 检查获取的value是是否属于belong, 或属于belong的父亲
     if (!CHECK_RESULT(result) || !checkAut(left->aut, result->value->aut, st->line, st->code_file, NULL, pri_auto, CNEXT_NT))
         PASS;
     else if (result->value->belong != NULL && result->value->belong->value != left->value && checkAttribution(left->value, result->value->belong->value)) { // 检查result所属于的对象是否位左值的父亲(若是则需要重新设定belong)
+        gc_freeTmpLink(&result->value->gc_status);
         result->value = COPY_LINKVALUE(result->value, inter);
+        gc_addTmpLink(&result->value->gc_status);
         result->value->belong = left;
     }
 

+ 16 - 2
vmcore/src/value.c

@@ -122,6 +122,20 @@ Value *makeStringValue(wchar_t *str, fline line, char *file, FUNC_NT) {
     return tmp;
 }
 
+Value *makeFileValue(FILE *file_, char *mode, bool is_std, char *path, fline line, char *file, FUNC_NT) {
+    Value *tmp = NULL;
+    setResultCore(result);
+    callBackCore(inter->data.base_obj[B_FILE], NULL, line, file, 0, CNEXT_NT);
+    if (!CHECK_RESULT(result))
+        return NULL;
+    tmp = result->value->value;
+    tmp->data.file.file = file_;
+    tmp->data.file.mode = memStrcpy(mode);
+    tmp->data.file.path = memStrcpy(path);
+    tmp->data.file.is_std = is_std;
+    return tmp;
+}
+
 Value *makeVMFunctionValue(Statement *st, Parameter *pt, FUNC_NT) {
     Value *tmp = NULL;
     callBackCore(inter->data.base_obj[B_FUNCTION], NULL, st->line, st->code_file, 0, CNEXT_NT);
@@ -600,12 +614,12 @@ bool callDel(Value *object_value, Result *result, Inter *inter, VarList *var_lis
     LinkValue *_del_ = findStrVarOnly(inter->data.mag_func[M_DEL], false, CFUNC_CORE(object_value->object.var));
     setResultCore(result);
 
-    if (_del_ != NULL){  // TODO-szh 让__del__只运行一次
-        gc_addTmpLink(&_del_->gc_status);
+    if (_del_ != NULL){
         if (_del_->belong != NULL && _del_->belong->value != object_value && checkAttribution(object_value, _del_->belong->value)) {  // 与point运算道理相同
             _del_ = COPY_LINKVALUE(_del_, inter);
             _del_->belong = makeLinkValue(object_value, inter->base_belong, auto_aut, inter);
         }
+        gc_addTmpLink(&_del_->gc_status);
         callBackCore(_del_, NULL, LINEFILE, 0, CFUNC_NT(var_list, result, inter->base_belong));
         gc_freeTmpLink(&_del_->gc_status);
         return true;