Переглянути джерело

feat: 处理程序退出方式

SongZihuan 4 роки тому
батько
коміт
8e69fcece4
16 змінених файлів з 90 додано та 47 видалено
  1. 2 1
      CMakeLists.txt
  2. 1 0
      include/__virtualmath.h
  3. 15 0
      include/handler.h
  4. 3 3
      include/inter.h
  5. 1 0
      include/value.h
  6. 3 4
      main.c
  7. 2 0
      ofunc/src/error_.c
  8. 9 0
      ofunc/src/sys.c
  9. 9 3
      parser/syntax.c
  10. 6 0
      signalhandler/handler.c
  11. 2 2
      src/__run.c
  12. 1 1
      src/include/__run.h
  13. 3 0
      src/inter.c
  14. 2 3
      src/run.c
  15. 2 0
      src/value.c
  16. 29 30
      src/virtualmath.c

+ 2 - 1
CMakeLists.txt

@@ -14,6 +14,7 @@ AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/file FILE_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/gc GC_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/argument ARGUMENT_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/ofunc/src OFUNC_LIST)
+AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/signalhandler HANDLER_LIST)
 
 MESSAGE("project dir is ${PROJECT_SOURCE_DIR}")
-ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST})
+ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST} ${HANDLER_LIST})

+ 1 - 0
include/__virtualmath.h

@@ -5,6 +5,7 @@
 
 #include "mem.h"
 #include "arguement.h"
+#include "handler.h"
 #include "file.h"
 
 #include "gc.h"

+ 15 - 0
include/handler.h

@@ -0,0 +1,15 @@
+#ifndef VIRTUALMATH_HANDLER_H
+#define VIRTUALMATH_HANDLER_H
+
+enum SignalType{
+    signal_reset,  // 没有信号
+    signal_check,  // 信号已经被处理, 等待异步处理
+    signal_appear,  // 信号未被处理
+};
+
+typedef enum SignalType SignalType;
+extern volatile SignalType is_KeyInterrupt;
+
+void resetHandler();
+
+#endif //VIRTUALMATH_HANDLER_H

+ 3 - 3
include/inter.h

@@ -36,6 +36,7 @@ struct Inter{
         struct Value *base_exc;
         struct Value *sys_exc;
         struct Value *keyInterrupt_exc;
+        struct Value *quit_exc;
         struct Value *exc;
         struct Value *type_exc;
         struct Value *arg_exc;
@@ -94,9 +95,8 @@ typedef enum ResultType ResultType;
 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);
 void runCodeStdin(Inter *inter);
-void runParser(char *code_file, Inter *inter, bool is_one, Statement **st);
-ResultType runCode(Statement *st, Inter *inter);
+void runCodeFile(Inter *inter, char *file[]);
+bool runParser(char *code_file, Inter *inter, bool is_one, Statement **st);
 void mergeInter(Inter *new, Inter *base);
 #endif //VIRTUALMATH_INTER_H

+ 1 - 0
include/value.h

@@ -147,6 +147,7 @@ enum BaseErrorType{
     E_IncludeException,
     E_SystemException,
     E_KeyInterrupt,
+    E_QuitException,
 };
 
 typedef struct Value Value;

+ 3 - 4
main.c

@@ -1,5 +1,4 @@
 #include "__virtualmath.h"
-volatile bool is_KeyInterrupt = false;
 void signalStop(int signum);
 
 int main(int argc, char *argv[]) {
@@ -15,8 +14,7 @@ int main(int argc, char *argv[]) {
         goto args_error;
 
     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);
+    runCodeFile(inter, argv + optind);
     if (args.run_commandLine)
         runCodeStdin(inter);
     freeInter(inter, true);
@@ -27,7 +25,8 @@ int main(int argc, char *argv[]) {
 
 
 void signalStop(int signum) {
-    is_KeyInterrupt = true;
+    if (is_KeyInterrupt == signal_reset)
+        is_KeyInterrupt = signal_appear;
 }
 
 /** TODO-szh List

+ 2 - 0
ofunc/src/error_.c

@@ -32,6 +32,7 @@ void registeredExcIter(REGISTERED_FUNCTIONSIG){
     } setList[] = {{"Exception", inter->data.exc},
                    {"SystemException", inter->data.sys_exc},
                    {"KeyboardInterrupt", inter->data.keyInterrupt_exc},
+                   {"QuitException", inter->data.quit_exc},
                    {"TypeException", inter->data.type_exc},
                    {"ArgumentException", inter->data.arg_exc},
                    {"PermissionsException", inter->data.per_exc},
@@ -66,6 +67,7 @@ void makeExcIter(Inter *inter){
     inter->data.exc = makeException(inter->data.base_exc, inter);
 
     inter->data.keyInterrupt_exc = makeException(inter->data.sys_exc, inter);
+    inter->data.quit_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);

+ 9 - 0
ofunc/src/sys.c

@@ -94,6 +94,14 @@ ResultType vm_allstaticmethod(OFFICAL_FUNCTIONSIG){
     return vm_setMethodCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), all_static_);
 }
 
+ResultType vm_quit(OFFICAL_FUNCTIONSIG){
+    if (arg != NULL)
+        setResultError(E_ArgumentException, "Too Many Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    else
+        setResultError(E_QuitException, "Quit By User", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return error_return;
+}
+
 void registeredSysFunction(REGISTERED_FUNCTIONSIG){
     NameFunc tmp[] = {{"super", vm_super, free_},
                       {"freemethod", vm_freemethod, free_},
@@ -104,6 +112,7 @@ void registeredSysFunction(REGISTERED_FUNCTIONSIG){
                       {"objectmethod", vm_objectfreemethod, free_},
                       {"simplemethod", vm_allfreemethod, free_},
                       {"simplestaticmethod", vm_allstaticmethod, free_},
+                      {"quit", vm_quit, free_},
                       {NULL, NULL}};
     iterNameFunc(tmp, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));
 }

+ 9 - 3
parser/syntax.c

@@ -239,19 +239,25 @@ void commentMather(int p, LexMather *mather){
  * @return
  */
 int getMatherStatus(LexFile *file, LexMathers *mathers) {
-    setupMathers(mathers);
     int status = -1;
+    int p;
+    setupMathers(mathers);
     while (status == -1){
-        int p = readChar(file);
+        p = readChar(file);
+        if (is_KeyInterrupt == signal_appear) {
+            is_KeyInterrupt = signal_check;
+            return -2;
+        }
+
         numberMather(p ,mathers->mathers[MATHER_NUMBER]);
         varMather(p ,mathers->mathers[MATHER_VAR]);
         spaceMather(p ,mathers->mathers[MATHER_SPACE]);
         stringMather(p, mathers->mathers[MATHER_STRING]);
         backslashMather(p, mathers->mathers[MATHER_NOTENTER]);
         commentMather(p, mathers->mathers[MATHER_COMMENT]);
-        charMatherMacro(MATHER_EOF, EOF);
         aCharMather(p, mathers->mathers[MATHER_ENTER], '\n');
 
+        charMatherMacro(MATHER_EOF, EOF);
         strMatherMacro(MATHER_IF, "if");  // 条件判断
         strMatherMacro(MATHER_ELIF, "elif");  // 条件循环
         strMatherMacro(MATHER_WHILE, "while");  // 条件循环

+ 6 - 0
signalhandler/handler.c

@@ -0,0 +1,6 @@
+#include "__virtualmath.h"
+volatile SignalType is_KeyInterrupt;
+
+void resetHandler() {
+    is_KeyInterrupt = signal_reset;
+}

+ 2 - 2
src/__run.c

@@ -350,6 +350,6 @@ 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);
+bool is_quitExc(LinkValue *value, Inter *inter) {
+    return value->value == inter->data.quit_exc || checkAttribution(value->value, inter->data.quit_exc);
 }

+ 1 - 1
src/include/__run.h

@@ -33,5 +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);
+bool is_quitExc(LinkValue *value, Inter *inter);
 #endif //VIRTUALMATH___RUN_H

+ 3 - 0
src/inter.c

@@ -115,8 +115,11 @@ 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.quit_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);

+ 2 - 3
src/run.c

@@ -111,9 +111,8 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
 }
 
 bool checkSignal(ResultType *type, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
-    extern volatile bool is_KeyInterrupt;
-    if (is_KeyInterrupt){
-        is_KeyInterrupt = false;
+    if (is_KeyInterrupt == signal_appear){
+        is_KeyInterrupt = signal_reset;
         if (type != NULL)
             *type = error_return;
         setResultError(E_KeyInterrupt, "KeyInterrupt", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));

+ 2 - 0
src/value.c

@@ -316,6 +316,8 @@ Value *findBaseError(BaseErrorType type, Inter *inter){
             return inter->data.sys_exc;
         case E_KeyInterrupt:
             return inter->data.keyInterrupt_exc;
+        case E_QuitException:
+            return inter->data.quit_exc;
         default:
             return NULL;
     }

+ 29 - 30
src/virtualmath.c

@@ -1,18 +1,24 @@
 #include "__run.h"
 
-ResultType runCodeBlock(char *code_file, Inter *inter) {
+void runCodeFile(Inter *inter, char *file[]) {
     Statement *pst = NULL;
-    ResultType type = error_return;
-    if (checkFile(code_file) != 1)
-        return error_return;
-    runParser(code_file, inter, false, &pst);
-    if (pst != NULL) {
-        type = runCode(pst, inter);
-        freeStatement(pst);
+    Result result;
+    bool should_break = false;
+    setResultCore(&result);
+    for (PASS; !should_break && *file != NULL; file++) {
+        if (checkFile((*file)) != 1)
+            continue;
+        if (runParser(*file, inter, false, &pst)) {
+            globalIterStatement(&result, inter, pst);
+            if (result.type == error_return) {
+                printError(&result, inter, true);
+                should_break = true;
+            }
+            freeStatement(pst);
+            freeResult(&result);
+        }
     }
-    return type;
 }
-
 void runCodeStdin(Inter *inter) {
     Statement *pst = NULL;
     Result result;
@@ -21,38 +27,31 @@ void runCodeStdin(Inter *inter) {
     printf("%s", HelloString);
     while (!should_break && !ferror(stdin) && !feof(stdin)){
         fprintf(stdout, ">>> ");
-        runParser(NULL, inter, true, &pst);
-        if (pst != NULL) {
+        if (runParser(NULL, inter, true, &pst)) {
             globalIterStatement(&result, inter, pst);
-            if (result.type == error_return) {
+            if (result.type == error_return && !(should_break = is_quitExc(result.value, inter)))
                 printError(&result, inter, true);
-                should_break = is_SystemError(result.value, inter);
-            }
             freeStatement(pst);
             freeResult(&result);
         }
     }
 }
 
-void runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {
+bool runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {
     ParserMessage *pm = makeParserMessage(code_file);
     *st = makeStatement(0, (code_file == NULL) ? "stdin" : code_file);
     parserCommandList(pm, inter, true, is_one, *st);
-    if (pm->status != success) {
+    if (is_KeyInterrupt != signal_reset) {
+        is_KeyInterrupt = signal_reset;
+        fprintf(stderr, "KeyInterrupt\n");
+    } else if (pm->status != success)
         fprintf(stderr, "Syntax Error: %s\n", pm->status_message);
-        freeStatement(*st);
-        *st = NULL;
+    else {
+        freeParserMessage(pm, true);
+        return true;
     }
+    freeStatement(*st);
+    *st = NULL;
     freeParserMessage(pm, true);
-}
-
-ResultType runCode(Statement *st, Inter *inter) {
-    Result result;
-    ResultType type;
-    setResultCore(&result);
-    type = globalIterStatement(&result, inter, st);
-    if (type == error_return)
-        printError(&result, inter, true);
-    freeResult(&result);
-    return type;
+    return false;
 }