فهرست منبع

feat: 信号处理

SongZihuan 4 سال پیش
والد
کامیت
8b4fe3156b
11فایلهای تغییر یافته به همراه90 افزوده شده و 64 حذف شده
  1. 3 1
      include/inter.h
  2. 2 0
      include/value.h
  3. 7 25
      main.c
  4. 0 1
      ofunc/include/error_.h
  5. 5 0
      ofunc/src/error_.c
  6. 5 1
      src/__run.c
  7. 1 7
      src/include/__run.h
  8. 2 6
      src/inter.c
  9. 43 14
      src/run.c
  10. 4 0
      src/value.c
  11. 18 9
      src/virtualmath.c

+ 3 - 1
include/inter.h

@@ -34,6 +34,8 @@ struct Inter{
         struct Value *dict_iter;
 
         struct Value *base_exc;
+        struct Value *sys_exc;
+        struct Value *keyInterrupt_exc;
         struct Value *exc;
         struct Value *type_exc;
         struct Value *arg_exc;
@@ -93,7 +95,7 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong);
 void freeInter(Inter *inter, bool show_gc);
 void setBaseInterData(struct Inter *inter);
 ResultType runCodeBlock(char *code_file, Inter *inter);
-ResultType runCodeStdin(Inter *inter);
+void runCodeStdin(Inter *inter);
 void runParser(char *code_file, Inter *inter, bool is_one, Statement **st);
 ResultType runCode(Statement *st, Inter *inter);
 void mergeInter(Inter *new, Inter *base);

+ 2 - 0
include/value.h

@@ -145,6 +145,8 @@ enum BaseErrorType{
     E_SuperException,
     E_ImportException,
     E_IncludeException,
+    E_SystemException,
+    E_KeyInterrupt,
 };
 
 typedef struct Value Value;

+ 7 - 25
main.c

@@ -1,39 +1,24 @@
 #include "__virtualmath.h"
-
-jmp_buf ctrlC_ENV;
-bool ctrlCUseJmp = false;
+volatile bool is_KeyInterrupt = false;
 void signalStop(int signum);
 
 int main(int argc, char *argv[]) {
     Inter *inter = NULL;
-    memVirtualMathUseJmp = true;
+    signal(SIGINT, signalStop);
     if (setjmp(memVirtualMath_Env) == -1){
         fprintf(stderr, "ERROR: Fatal memory error encountered, May be caused by insufficient memory!\n");
         return 1;
     }
+    memVirtualMathUseJmp = true;
 
     if (getArgs(argc, argv))
         goto args_error;
-    inter = makeInter(args.out_file, args.error_file, args.in_file, NULL);
-
-    ctrlCUseJmp = true;
-    signal(SIGINT, signalStop);
-    if (setjmp(ctrlC_ENV) == -1) {
-        freeArgs();
-        freeInter(inter, true);
-        return 2;
-    }
 
+    inter = makeInter(args.out_file, args.error_file, args.in_file, NULL);
     for (ResultType status = not_return; status != error_return && argv[optind] != NULL; optind++)
         status = runCodeBlock(argv[optind], inter);
-    if (args.run_commandLine) {
-        printf("%s", HelloString);
-        while (1) {
-            runCodeStdin(inter);
-            if (ferror(stdin) || feof(stdin))
-                break;
-        }
-    }
+    if (args.run_commandLine)
+        runCodeStdin(inter);
     freeInter(inter, true);
 
     args_error: freeArgs();
@@ -42,10 +27,7 @@ int main(int argc, char *argv[]) {
 
 
 void signalStop(int signum) {
-    if (ctrlCUseJmp)
-        longjmp(ctrlC_ENV, -1);
-    else
-        exit(1);
+    is_KeyInterrupt = true;
 }
 
 /** TODO-szh List

+ 0 - 1
ofunc/include/error_.h

@@ -2,5 +2,4 @@
 #define VIRTUALMATH_ERROR__H
 void makeExcIter(Inter *inter);
 void registeredExcIter(REGISTERED_FUNCTIONSIG);
-
 #endif //VIRTUALMATH_ERROR__H

+ 5 - 0
ofunc/src/error_.c

@@ -30,6 +30,8 @@ void registeredExcIter(REGISTERED_FUNCTIONSIG){
         char *name;
         Value *value;
     } setList[] = {{"Exception", inter->data.exc},
+                   {"SystemException", inter->data.sys_exc},
+                   {"KeyboardInterrupt", inter->data.keyInterrupt_exc},
                    {"TypeException", inter->data.type_exc},
                    {"ArgumentException", inter->data.arg_exc},
                    {"PermissionsException", inter->data.per_exc},
@@ -60,8 +62,11 @@ void registeredExcIter(REGISTERED_FUNCTIONSIG){
 
 void makeExcIter(Inter *inter){
     inter->data.base_exc = makeException(inter->data.object, inter);
+    inter->data.sys_exc = makeException(inter->data.base_exc, inter);
     inter->data.exc = makeException(inter->data.base_exc, inter);
 
+    inter->data.keyInterrupt_exc = makeException(inter->data.sys_exc, inter);
+
     inter->data.type_exc = makeException(inter->data.exc, inter);
     inter->data.arg_exc = makeException(inter->data.exc, inter);
     inter->data.per_exc = makeException(inter->data.exc, inter);

+ 5 - 1
src/__run.c

@@ -346,6 +346,10 @@ char *getRepoStr(LinkValue *value, bool is_repot, fline line, char *file, INTER_
     return NULL;
 }
 
-bool is_iterStop(LinkValue *value, Inter *inter){
+bool is_iterStop(LinkValue *value, Inter *inter) {
     return value->value == inter->data.iterstop_exc || checkAttribution(value->value, inter->data.iterstop_exc);
 }
+
+bool is_SystemError(LinkValue *value, Inter *inter) {
+    return value->value == inter->data.sys_exc || checkAttribution(value->value, inter->data.sys_exc);
+}

+ 1 - 7
src/include/__run.h

@@ -2,13 +2,6 @@
 #define VIRTUALMATH___RUN_H
 #include "__virtualmath.h"
 
-#if OUT_INTER_LOG && OUT_INTER_LOG
-#define writeLog_(...) writeLog(__VA_ARGS__)
-#else
-#define printResult(...)
-#define writeLog_(...)
-#endif
-
 char *setStrVarName(char *old, bool free_old, struct Inter *inter);
 char *setNumVarName(vnum num, struct Inter *inter);
 char *getNameFromValue(Value *value, struct Inter *inter);
@@ -40,4 +33,5 @@ ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_F
 bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 char *getRepoStr(LinkValue *value, bool is_repot, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 bool is_iterStop(LinkValue *value, Inter *inter);
+bool is_SystemError(LinkValue *value, Inter *inter);
 #endif //VIRTUALMATH___RUN_H

+ 2 - 6
src/inter.c

@@ -64,12 +64,6 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
 }
 
 void setBaseInterData(struct Inter *inter){
-    inter->data.object = NULL;
-    inter->data.vobject = NULL;
-    inter->data.num = NULL;
-    inter->data.str = NULL;
-    inter->data.none = NULL;
-    inter->data.list_iter = NULL;
     inter->data.var_str_prefix = memStrcpy("str_");
     inter->data.var_num_prefix = memStrcpy("num_");
     inter->data.var_none = memStrcpy("none");
@@ -121,6 +115,8 @@ void freeBaseInterData(struct Inter *inter){
     gc_freeStatementLink(&inter->data.none->gc_status);
 
     gc_freeStatementLink(&inter->data.base_exc->gc_status);
+    gc_freeStatementLink(&inter->data.sys_exc->gc_status);
+    gc_freeStatementLink(&inter->data.keyInterrupt_exc->gc_status);
     gc_freeStatementLink(&inter->data.exc->gc_status);
     gc_freeStatementLink(&inter->data.type_exc->gc_status);
     gc_freeStatementLink(&inter->data.arg_exc->gc_status);

+ 43 - 14
src/run.c

@@ -110,6 +110,18 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
     return type;
 }
 
+bool checkSignal(ResultType *type, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    extern volatile bool is_KeyInterrupt;
+    if (is_KeyInterrupt){
+        is_KeyInterrupt = false;
+        if (type != NULL)
+            *type = error_return;
+        setResultError(E_KeyInterrupt, "KeyInterrupt", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return true;
+    }
+    return false;
+}
+
 /**
  * 局部程序运行statement
  * @param st
@@ -118,7 +130,7 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
  * @return
  */
 ResultType iterStatement(INTER_FUNCTIONSIG) {
-    Statement *base_st = NULL;
+    Statement *base;
     ResultType type;
     setResultCore(result);
 
@@ -128,9 +140,14 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
     }
 
     do {
-        for (base_st = st; base_st != NULL; PASS) {
+        base = st;
+        if (checkSignal(&type, base->line, base->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+            break;
+        while (base != NULL) {
             freeResult(result);
-            type = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list, result, belong));
+            type = runStatement(CALL_INTER_FUNCTIONSIG(base, var_list, result, belong));
+            if (checkSignal(&type, base->line, base->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+                break;
             if (type == goto_return && result->times == 0){
                 Statement *label_st = checkLabel(st, result->label);
                 if (label_st == NULL){
@@ -141,18 +158,18 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
                 type = runLabel(CALL_INTER_FUNCTIONSIG(label_st, var_list, result, belong));
                 if (!RUN_TYPE(type))
                     break;
-                base_st = label_st->next;
+                base = label_st->next;
             }
             else if (!RUN_TYPE(type))
                 break;
             else
-                base_st = base_st->next;
+                base = base->next;
         }
     } while (type == restart_return && result->times == 0);
 
     if (type == not_return || type == restart_return)
         setResultOperationNone(result, inter, belong);
-    result->node = base_st;
+    result->node = base;
     gc_run(inter, var_list, 1, 0, 0, var_list);
     return result->type;
 }
@@ -163,15 +180,27 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
  * @return
  */
 ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
+    ResultType type;
+    VarList *var_list = NULL;
+    Statement *base;
     LinkValue *belong = inter->base_father;
+
+    if (st == NULL){
+        setResult(result, inter, belong);
+        return result->type;
+    }
+
     gc_addTmpLink(&belong->gc_status);
-    Statement *base_st = NULL;
-    VarList *var_list = NULL;
-    enum ResultType type;
     do {
-        for (base_st = st, var_list = inter->var_list; base_st != NULL; PASS) {
+        base = st;
+        var_list = inter->var_list;
+        if (checkSignal(&type, base->line, base->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+            break;
+        while (base != NULL) {
             freeResult(result);
-            type = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list, result, belong));
+            type = runStatement(CALL_INTER_FUNCTIONSIG(base, var_list, result, belong));
+            if (checkSignal(&type, base->line, base->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+                break;
             if (type == goto_return){
                 Statement *label_st = checkLabel(st, result->label);
                 if (label_st == NULL){
@@ -182,18 +211,18 @@ ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
                 type = runLabel(CALL_INTER_FUNCTIONSIG(label_st, var_list, result, belong));
                 if (!RUN_TYPE(type))
                     break;
-                base_st = label_st->next;
+                base = label_st->next;
             }
             else if (!RUN_TYPE(type))
                 break;
             else
-                base_st = base_st->next;
+                base = base->next;
         }
     } while (type == restart_return && result->times == 0);
 
     if (type != error_return && type != function_return)
         setResultOperationNone(result, inter, belong);
-    result->node = base_st;
+    result->node = base;
     gc_freeTmpLink(&belong->gc_status);
     gc_run(inter, var_list, 1, 0, 0, var_list);
     return result->type;

+ 4 - 0
src/value.c

@@ -312,6 +312,10 @@ Value *findBaseError(BaseErrorType type, Inter *inter){
             return inter->data.import_exc;
         case E_IncludeException:
             return inter->data.include_exp;
+        case E_SystemException:
+            return inter->data.sys_exc;
+        case E_KeyInterrupt:
+            return inter->data.keyInterrupt_exc;
         default:
             return NULL;
     }

+ 18 - 9
src/virtualmath.c

@@ -1,4 +1,4 @@
-#include "__virtualmath.h"
+#include "__run.h"
 
 ResultType runCodeBlock(char *code_file, Inter *inter) {
     Statement *pst = NULL;
@@ -13,16 +13,25 @@ ResultType runCodeBlock(char *code_file, Inter *inter) {
     return type;
 }
 
-ResultType runCodeStdin(Inter *inter) {
+void runCodeStdin(Inter *inter) {
     Statement *pst = NULL;
-    ResultType type = error_return;
-    fprintf(stdout, ">>> ");
-    runParser(NULL, inter, true, &pst);
-    if (pst != NULL) {
-        type = runCode(pst, inter);
-        freeStatement(pst);
+    Result result;
+    bool should_break = false;
+    setResultCore(&result);
+    printf("%s", HelloString);
+    while (!should_break && !ferror(stdin) && !feof(stdin)){
+        fprintf(stdout, ">>> ");
+        runParser(NULL, inter, true, &pst);
+        if (pst != NULL) {
+            globalIterStatement(&result, inter, pst);
+            if (result.type == error_return) {
+                printError(&result, inter, true);
+                should_break = is_SystemError(result.value, inter);
+            }
+            freeStatement(pst);
+            freeResult(&result);
+        }
     }
-    return type;
 }
 
 void runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {