浏览代码

feat: 下标和切片支持[::]和[,,]方法调用

SongZihuan 4 年之前
父节点
当前提交
3f2a4a05ca

+ 1 - 1
vmcore/include/lexical.h

@@ -14,7 +14,7 @@ struct LexFile{
     struct {
         int enter;  // 若计数为0则不忽略enter
     } filter_data;
-    long int line;
+    fline line;
     wchar_t *errsyntax;
 };
 

+ 2 - 2
vmcore/include/token.h

@@ -175,9 +175,9 @@ TokenMessage *makeTokenMessageFile(char *file_dir);
 TokenMessage *makeTokenMessageStr(wchar_t *str);
 void freeTokenMessage(TokenMessage *tm, bool self, bool free_st);
 
-Token *makeToken(long int line);
+Token *makeToken(fline line);
 long freeToken(Token *tk, bool free_st);
-Token *makeLexToken(int type, wchar_t *str, wchar_t *second_str, long int line);
+Token *makeLexToken(int type, wchar_t *str, wchar_t *second_str, fline line);
 Token *makeStatementToken(int type, struct Statement *st);
 
 extern Token *getToken(LexFile *file, LexMathers *mathers);

+ 69 - 55
vmcore/parser/__grammar.c

@@ -20,7 +20,7 @@ inline void twoOperation(P_FUNC, PasersFunction callBack, GetSymbolFunction getS
         Token *left_token = NULL;
         Token *right_token = NULL;
         Statement *st = NULL;
-        long int line;
+        fline line;
 
         if (readBackToken(pm) != self_type) {
             if (!callChildStatement(CP_FUNC, callBack, call_type, &st, NULL))
@@ -63,7 +63,7 @@ inline void twoOperation(P_FUNC, PasersFunction callBack, GetSymbolFunction getS
  * @param message 错误信息
  * @param status 错误类型
  */
-void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
+void syntaxError(ParserMessage *pm, int status, fline line, int num, ...) {
     char *message = NULL;
 
     if (pm->status != success)
@@ -80,7 +80,7 @@ void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
     va_end(message_args);
 
     char info[100];
-    snprintf(info, 100, "\non line %ld\nin file ", line);
+    snprintf(info, 100, "\non line %llu\nin file ", line);
     message = memStrcat(message, info, true, false);
     message = memStrcat(message, pm->file, true, false);
 
@@ -106,10 +106,10 @@ int readBackToken(ParserMessage *pm){
     return type;
 }
 
-bool checkToken(ParserMessage *pm, int type){
+bool checkToken(ParserMessage *pm, int type, fline *line) {
     if (readBackToken(pm) != type)
         return false;
-    delToken(pm);
+    line != NULL ? (*line = delToken(pm)) : delToken(pm);
     return true;
 }
 
@@ -124,7 +124,7 @@ bool commandCallControl_(P_FUNC, MakeControlFunction callBack, int type, Stateme
     freeToken(tmp_token, false);
     return true;
 }
-bool callParserCode(P_FUNC, Statement **st, char *message, long int line) {
+bool callParserCode(P_FUNC, Statement **st, char *message, fline line) {
     Token *tmp;
     *st = NULL;
     parserCode(CP_FUNC);
@@ -202,10 +202,9 @@ bool callChildStatement(P_FUNC, PasersFunction callBack, int type, Statement **s
  * @param ass 设定赋值符号
  * @return
  */
-bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is_list, bool is_dict,
-                     int sep, int ass, int n_sep) {
+bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is_list, int n_sep, bool is_dict, int sep,
+                int ass, bool space) {
     Parameter *new_pt = NULL;
-    Token *tmp;
     bool last_pt = false;
     int is_sep = 0;  // 0: 不需要处理 1: 是is_sep 2: 处理过is_sep (当匹配到;设置is_sep为1)
     enum {
@@ -223,88 +222,103 @@ bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is
         status = s_1;
 
     for (int count = 0; !last_pt; count++){  // 计算匹配到parameter的个数
-        tmp = NULL;
+        Statement *st;
+        fline line;
+        int pt_type = value_par;
+
         if (is_sep == 1 || !is_formal && count > 2)  // 限制实参的;分隔符前最多只有三个参数
             is_sep = 2;
-        if (!is_dict && status != s_2 && checkToken(pm, MATHER_MUL))  // is_formal关闭对*args的支持
+        if (!is_dict && status != s_2 && checkToken(pm, MATHER_MUL, NULL))  // is_formal关闭对*args的支持
             status = s_3;
-        else if (!is_list && checkToken(pm, MATHER_POW))  // is_formal关闭对*args的支持
+        else if (!is_list && checkToken(pm, MATHER_POW, NULL))  // is_formal关闭对*args的支持
             status = s_4;
 
-        parserOr(CP_FUNC);
-        if (!call_success(pm))
-            goto error_;
-        if (readBackToken(pm) != T_OR) {
-            if (status == s_3) {
-                long int line = pm->tm->ts->token_list->line;
-                syntaxError(pm, syntax_error, line, 1, "Don't get a parameter after *");
+        if (space && checkToken(pm, sep, &line))
+            st = makeBaseValueStatement(null_value, line, pm->file);  // 空白符号
+        else {
+            Token *tmp;
+            parserOr(CP_FUNC);
+            if (!call_success(pm))
                 goto error_;
-            }
-            break;
-        }
-        tmp = popNewToken(pm->tm);
-        int pt_type = value_par;
-        if (status == s_1){
-            if (!checkToken(pm, sep)){
-                if (is_sep == 0 && n_sep != -1 && checkToken(pm, n_sep))
-                    is_sep = 1;
-                else if (is_list || !checkToken(pm, ass))  // // is_list关闭对name_value的支持
-                    last_pt = true;
-                else {
-                    pt_type = name_par;
-                    status = s_2;
+            if (readBackToken(pm) != T_OR) {
+                if (status == s_3) {
+                    line = pm->tm->ts->token_list->line;
+                    syntaxError(pm, syntax_error, line, 1, "Don't get a parameter after *");
+                    goto error_;
                 }
+                break;
             }
+            tmp = popNewToken(pm->tm);
+            st = tmp->data.st;
+            freeToken(tmp, false);
         }
-        else if (status == s_2){
-            pt_type = name_par;
-            if (!checkToken(pm, ass))
-                goto error_;
-        }
-        else if (status == s_3){
-            pt_type = args_par;
-            if (!checkToken(pm, sep))
-                last_pt = true;
-        }
-        else {
-            pt_type = kwargs_par;
-            if (!checkToken(pm, sep))
-                last_pt = true;
+
+        switch (status) {
+            case s_1:
+                if (!checkToken(pm, sep, NULL)) {
+                    if (is_sep == 0 && n_sep != -1 && checkToken(pm, n_sep, NULL))
+                        is_sep = 1;
+                    else if (is_list || !checkToken(pm, ass, NULL))  // // is_list关闭对name_value的支持
+                        last_pt = true;
+                    else {
+                        pt_type = name_par;
+                        status = s_2;
+                    }
+                }
+                break;
+            case s_2:
+                pt_type = name_par;
+                if (!checkToken(pm, ass, NULL)) {
+                    freeStatement(st);
+                    goto error_;
+                }
+                break;
+            case s_3:
+                pt_type = args_par;
+                if (!checkToken(pm, sep, NULL))
+                    last_pt = true;
+                break;
+            default:
+                pt_type = kwargs_par;
+                if (!checkToken(pm, sep, NULL))
+                    last_pt = true;
+                break;
         }
 
         if (pt_type == value_par)
-            new_pt = connectValueParameter(tmp->data.st, new_pt, is_sep == 1);
+            new_pt = connectValueParameter(st, new_pt, is_sep == 1);
         else if (pt_type == name_par){
             Statement *tmp_value;
-            if (!callChildStatement(CP_FUNC, parserOr, T_OR, &tmp_value, "Don't get a parameter value"))
+            if (!callChildStatement(CP_FUNC, parserOr, T_OR, &tmp_value, "Don't get a parameter value")) {
+                freeStatement(st);
                 goto error_;
-            new_pt = connectNameParameter(tmp_value, tmp->data.st, new_pt);
-            if (!checkToken(pm, sep))
+            }
+            new_pt = connectNameParameter(tmp_value, st, new_pt);
+            if (!checkToken(pm, sep, NULL))
                 last_pt = true;
         }
         else if (pt_type == args_par){
-            new_pt = connectArgsParameter(tmp->data.st, new_pt, is_sep == 1);
+            new_pt = connectArgsParameter(st, new_pt, is_sep == 1);
             if (is_formal)
                 status = s_2;  // 是否规定*args只出现一次
             else
                 status = s_1;
         }
         else {
-            new_pt = connectKwargsParameter(tmp->data.st, new_pt);
+            new_pt = connectKwargsParameter(st, new_pt);
             if (is_formal)
                 last_pt = true; // 是否规定**kwargs只出现一次
             else
                 status = s_2;
         }
-        freeToken(tmp, false);
     }
+
     *pt = new_pt;
     if (enter)
         lexEnter(pm, false);
     return true;
 
     error_:
-    freeToken(tmp, true);
     freeParameter(new_pt, true);
     *pt = NULL;
     if (enter)

+ 73 - 68
vmcore/parser/grammar.c

@@ -233,7 +233,7 @@ void parserDecoration(P_FUNC){
     Statement *st = NULL;
     DecorationStatement *ds = NULL;
     int tmp;
-    long int line = 0;
+    fline line = 0;
     while ((tmp = readBackToken(pm)) == MATHER_AT || tmp == MATHER_ENTER){
         Statement *dst = NULL;
         line = delToken(pm);
@@ -276,7 +276,7 @@ void parserLabel(P_FUNC){
     Statement *command = NULL;
     int tmp;
     wchar_t *label = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
     if ((tmp = readBackToken(pm)) == MATHER_STRING || tmp == MATHER_VAR) {
         Token *label_ = popNewToken(pm->tm);
@@ -287,10 +287,10 @@ void parserLabel(P_FUNC){
         goto error_;
     }
 
-    if (checkToken(pm, MATHER_AS) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &var, "Don't get a label var"))
+    if (checkToken(pm, MATHER_AS, NULL) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &var, "Don't get a label var"))
         goto error_;
 
-    if (checkToken(pm, MATHER_COLON) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &command, "Don't get a label command"))
+    if (checkToken(pm, MATHER_COLON, NULL) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &command, "Don't get a label command"))
         goto error_;
 
 
@@ -318,15 +318,15 @@ void parserGoto(P_FUNC){
     Statement *label = NULL;
     Statement *times = NULL;
     Statement *return_ = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
     if (!callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &label, "Don't get a goto label"))
         goto error_;
 
-    if (checkToken(pm, MATHER_AT) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &times, "Don't get a goto times"))
+    if (checkToken(pm, MATHER_AT, NULL) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &times, "Don't get a goto times"))
         goto error_;
 
-    if (checkToken(pm, MATHER_COLON) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &return_, "Don't get a goto return"))
+    if (checkToken(pm, MATHER_COLON, NULL) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &return_, "Don't get a goto return"))
         goto error_;
 
     st = makeGotoStatement(return_, times, label, line, pm->file);
@@ -352,9 +352,9 @@ void parserImport(P_FUNC) {
     Statement *st = NULL;
     bool is_lock = false;
     int token_type = readBackToken(pm);
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
-    if (checkToken(pm, MATHER_COLON)) {
+    if (checkToken(pm, MATHER_COLON, NULL)) {
         switch (readBackToken(pm)) {
             case MATHER_PUBLIC:
                 break;
@@ -373,7 +373,7 @@ void parserImport(P_FUNC) {
         goto return_;
     if (token_type == MATHER_IMPORT) {
         Statement *as = NULL;
-        if (checkToken(pm, MATHER_AS) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &as, "Don't get a as after import")) {
+        if (checkToken(pm, MATHER_AS, NULL) && !callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &as, "Don't get a as after import")) {
             freeStatement(opt);
             goto return_;
         }
@@ -382,21 +382,21 @@ void parserImport(P_FUNC) {
     else{
         Parameter *pt = NULL;
         Parameter *as = NULL;
-        if (!checkToken(pm, MATHER_IMPORT)) {
+        if (!checkToken(pm, MATHER_IMPORT, NULL)) {
             syntaxError(pm, syntax_error, opt->line, 1, "Don't get a as after import");
             freeStatement(opt);
             goto return_;
         }
-        if (checkToken(pm, MATHER_MUL))  // 导入所有
+        if (checkToken(pm, MATHER_MUL, NULL))  // 导入所有
             goto mul_;
-        if (!parserParameter(CP_FUNC, &pt, false, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT,
-                             -1) || pt == NULL) {
+        if (!parserParameter(CP_FUNC, &pt, false, false, false,
+                             -1, false, MATHER_COMMA, MATHER_ASSIGNMENT, false) || pt == NULL) {
             syntaxError(pm, syntax_error, line, 1, "Don't get any value to import");
             freeStatement(opt);
             goto return_;
         }
-        if (checkToken(pm, MATHER_AS) && (!parserParameter(CP_FUNC, &as, false, true, false, false,
-                                                           MATHER_COMMA, MATHER_ASSIGNMENT, -1) || as == NULL)) {
+        if (checkToken(pm, MATHER_AS, NULL) && (!parserParameter(CP_FUNC, &as, false, true, false, -1, false,
+                                                                 MATHER_COMMA, MATHER_ASSIGNMENT, false) || as == NULL)) {
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, opt->line, 1, "Don't get any value after import");
             freeStatement(opt);
@@ -433,8 +433,8 @@ void parserVarControl(P_FUNC) {
     Statement *st = NULL;
     Token *tmp = NULL;
     int token_type = readBackToken(pm);
-    long int line = delToken(pm);
-    if (!parserParameter(CP_FUNC, &var, false, true, true, true, MATHER_COMMA, MATHER_ASSIGNMENT, -1) || var == NULL) {
+    fline line = delToken(pm);
+    if (!parserParameter(CP_FUNC, &var, false, true, true, -1, true, MATHER_COMMA, MATHER_ASSIGNMENT, false) || var == NULL) {
         syntaxError(pm, syntax_error, line, 1, "Don't get any var");
         goto return_;
     }
@@ -457,7 +457,7 @@ void parserControl(P_FUNC, MakeControlFunction callBack, int type, bool must_ope
     Statement *opt = NULL;
     Statement *st = NULL;
     Token *tmp = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
     parserOperation(CP_FUNC);
     if (call_success(pm) && readBackToken(pm) == T_OPERATION){
         tmp = popNewToken(pm->tm);
@@ -478,7 +478,7 @@ void parserControl(P_FUNC, MakeControlFunction callBack, int type, bool must_ope
 void parserDo(P_FUNC){
     Statement *st = NULL;
     Statement *do_code = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
     if (readBackToken(pm) == MATHER_WHILE){  // do...while语句
         if (!callChildStatement(CP_FUNC, parserWhile, T_WHILE_BRANCH, &st, "Don't get a while code"))
             goto error_;
@@ -515,7 +515,7 @@ void parserDo(P_FUNC){
                 st->u.set_function.first_do = do_code;
                 break;
             case MATHER_DO: {
-                long int tmp_line = delToken(pm);
+                fline tmp_line = delToken(pm);
                 if (readBackToken(pm) != MATHER_WHILE){
                     syntaxError(pm, syntax_error, tmp_line, 1, "Don't get while after do");
                     goto error_;
@@ -552,12 +552,12 @@ void parserFor(P_FUNC){
     Statement *finally_st = NULL;
     Statement *do_st = NULL;
     StatementList *sl = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
     {
         Statement *code_tmp = NULL, *var_tmp = NULL, *iter_tmp = NULL;
         if (!callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &var_tmp, "Don't get a for var"))
             goto error_;
-        if (!checkToken(pm, MATHER_IN)){
+        if (!checkToken(pm, MATHER_IN, NULL)){
             freeStatement(var_tmp);
             syntaxError(pm, syntax_error, line, 1, "Don't get in after for");
             goto error_;
@@ -579,13 +579,13 @@ void parserFor(P_FUNC){
         case MATHER_DO: {
             if (do_st != NULL || else_st != NULL)
                 goto default_;
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (!callParserCode(CP_FUNC, &do_st, "Don't get a for...do code", tmp_line))
                 goto error_;
             goto again;
         }
         case MATHER_ELSE: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (else_st != NULL) {
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else\n");
                 goto error_;
@@ -595,7 +595,7 @@ void parserFor(P_FUNC){
             goto again;
         }
         case MATHER_FINALLY: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (!callParserCode(CP_FUNC, &finally_st, "Don't get a for...finally code", tmp_line))
                 goto error_;
             break;
@@ -635,8 +635,8 @@ void parserWith(P_FUNC){
     Statement *else_st = NULL;
     Statement *finally_st = NULL;
     StatementList *sl = NULL;
-    long int line = 0;
-    long int tmp_line;
+    fline line = 0;
+    fline tmp_line;
 
     line = delToken(pm);
     if (!callChildStatement(CP_FUNC, parserOperation, T_OPERATION, &condition_tmp, "Don't get a with operation"))
@@ -814,7 +814,7 @@ void parserWhile(P_FUNC){
     Statement *do_st = NULL;
     StatementList *sl = NULL;
     bool have_while = false;
-    long int line = 0;
+    fline line = 0;
     again:
     switch (readBackToken(pm)) {
         case MATHER_WHILE: {
@@ -845,13 +845,13 @@ void parserWhile(P_FUNC){
         case MATHER_DO: {
             if (do_st != NULL || else_st != NULL)
                 goto default_;
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (!callParserCode(CP_FUNC, &do_st, "Don't get a while...do code", tmp_line))
                 goto error_;
             goto again;
         }
         case MATHER_ELSE: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (else_st != NULL) {
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else\n");
                 goto error_;
@@ -861,7 +861,7 @@ void parserWhile(P_FUNC){
             goto again;
         }
         case MATHER_FINALLY: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (!callParserCode(CP_FUNC, &finally_st, "Don't get a while...finally code", tmp_line))
                 goto error_;
             break;
@@ -913,7 +913,7 @@ void parserTry(P_FUNC){
     Statement *else_st = NULL;
     Statement *finally_st = NULL;
     StatementList *sl = NULL;
-    long int line = 0;
+    fline line = 0;
     again:
     switch (readBackToken(pm)) {
         case MATHER_TRY:{
@@ -926,7 +926,7 @@ void parserTry(P_FUNC){
         }
         case MATHER_EXCEPT: {
             Statement *code_tmp = NULL, *var_tmp = NULL, *condition_tmp = NULL;
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (else_st != NULL) {
                 syntaxError(pm, syntax_error, tmp_line, 1, "get except after else");
                 goto error_;
@@ -947,7 +947,7 @@ void parserTry(P_FUNC){
             goto again;
         }
         case MATHER_ELSE: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (else_st != NULL) {
                 syntaxError(pm, syntax_error, tmp_line, 1, "get else after else");
                 goto error_;
@@ -957,7 +957,7 @@ void parserTry(P_FUNC){
             goto again;
         }
         case MATHER_FINALLY: {
-            long int tmp_line = delToken(pm);
+            fline tmp_line = delToken(pm);
             if (!callParserCode(CP_FUNC, &finally_st, "Don't get a try...finally code", tmp_line))
                 goto error_;
             break;
@@ -1005,19 +1005,20 @@ void parserDef(P_FUNC){
     Statement *code_tmp = NULL;
     Parameter *pt = NULL;
     int type = readBackToken(pm);
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
     if (!callChildStatement(CP_FUNC, parserBaseValue, T_BASEVALUE, &name_tmp, "Don't get a func/class name"))
         goto error_;
 
-    if (!checkToken(pm, MATHER_LP))
+    if (!checkToken(pm, MATHER_LP, NULL))
         goto get_code;
-    if (!parserParameter(CP_FUNC, &pt, true, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT, type == MATHER_DEF ? MATHER_SEMICOLON : -1)) {
+    if (!parserParameter(CP_FUNC, &pt, true, true, false, type == MATHER_DEF ? MATHER_SEMICOLON : -1, false,
+                         MATHER_COMMA, MATHER_ASSIGNMENT, false)) {
         lexEnter(pm, false);
         syntaxError(pm, syntax_error, line, 1, "Don't get a func/V_class parameter");
         goto error_;
     }
-    if (!checkToken(pm, MATHER_RP)) {
+    if (!checkToken(pm, MATHER_RP, NULL)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get a func/V_class ) after parameter");
         goto error_;
     }
@@ -1050,7 +1051,7 @@ void parserDef(P_FUNC){
  * @param inter
  */
 void parserCode(P_FUNC) {
-    long int line = 0;
+    fline line = 0;
     Statement *st = makeStatement(line, pm->file);
     bool backup = pm->short_cm;
     bool short_cm = false;
@@ -1077,7 +1078,7 @@ void parserCode(P_FUNC) {
 
     if (short_cm)
         addLexToken(pm, MATHER_ENTER);
-    else if (!checkToken(pm, MATHER_RC)) {
+    else if (!checkToken(pm, MATHER_RC, NULL)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get the }");  // 使用{的行号
         goto error_;
     }
@@ -1146,7 +1147,7 @@ void parserTuple(P_FUNC){
     Parameter *pt = NULL;
     Statement *st = NULL;
     Token *tmp = NULL;
-    long int line = 0;
+    fline line = 0;
     if (readBackToken(pm) == MATHER_MUL) {
         line = pm->tm->ts->token_list->line;
         goto parserPt;
@@ -1163,7 +1164,7 @@ void parserTuple(P_FUNC){
     addToken_(pm ,tmp);
 
     parserPt:
-    if (!parserParameter(CP_FUNC, &pt, false, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT, -1)) {
+    if (!parserParameter(CP_FUNC, &pt, false, false, true, -1, false, MATHER_COMMA, MATHER_ASSIGNMENT, false)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get tuple element");
         goto return_;
     }
@@ -1384,15 +1385,16 @@ void parserNot(P_FUNC){
  */
 bool tailCall(P_FUNC, Token *left_token, Statement **st){
     Parameter *pt = NULL;
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
-    if (checkToken(pm, MATHER_RP))
+    if (checkToken(pm, MATHER_RP, NULL))
         goto not_pt;
-    if (!parserParameter(CP_FUNC, &pt, true, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT, MATHER_SEMICOLON)) {
+    if (!parserParameter(CP_FUNC, &pt, true, false, false, MATHER_SEMICOLON, false, MATHER_COMMA, MATHER_ASSIGNMENT,
+                         false)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get call parameter");
         return false;
     }
-    if (!checkToken(pm, MATHER_RP)) {
+    if (!checkToken(pm, MATHER_RP, NULL)) {
         freeParameter(pt, true);
         syntaxError(pm, syntax_error, line, 1, "Don't get ) from call back");
         return false;
@@ -1407,23 +1409,26 @@ bool tailSlice(P_FUNC, Token *left_token, Statement **st){
     Parameter *pt = NULL;
     Token *tmp = NULL;
     enum SliceType type;  // 0-slice  1-down
-    long int line = delToken(pm);
+    fline line = delToken(pm);
 
-    if (!callChildToken(CP_FUNC, parserOr, T_OR, &tmp, "Don't get slice/down element", syntax_error))
-        return false;
-    else if (readBackToken(pm) == MATHER_COLON)
+    if (readBackToken(pm) == MATHER_COLON)
         type = SliceType_slice_;
-    else
-        type = SliceType_down_;
-    line = tmp->line;
-    addToken_(pm ,tmp);
+    else {
+        if (!callChildToken(CP_FUNC, parserOr, T_OR, &tmp, "Don't get slice/down element", syntax_error))
+            return false;
+        else if (readBackToken(pm) == MATHER_COLON)
+            type = SliceType_slice_;
+        else
+            type = SliceType_down_;
+        line = tmp->line;
+        addToken_(pm ,tmp);
+    }
 
-    if (!parserParameter(CP_FUNC, &pt, true, true, true, true,
-                         (type == SliceType_down_ ? MATHER_COMMA : MATHER_COLON), MATHER_ASSIGNMENT, -1)) {
+    if (!parserParameter(CP_FUNC, &pt, true, true, true, -1, true, (type == SliceType_down_ ? MATHER_COMMA : MATHER_COLON), MATHER_ASSIGNMENT, true)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get slice element");
         return false;
     }
-    if (!checkToken(pm, MATHER_RB)){
+    if (!checkToken(pm, MATHER_RB, NULL)){
         freeParameter(pt, true);
         syntaxError(pm, syntax_error, line, 1, "Don't get ] from slice");
         return false;
@@ -1517,13 +1522,13 @@ void parserNegate(P_FUNC){
  */
 int getOperation(P_FUNC, int right_type, Statement **st, char *name){
     *st = NULL;
-    if (checkToken(pm, right_type))
+    if (checkToken(pm, right_type, NULL))
         goto return_;
 
     if (!callChildStatement(CP_FUNC, parserOperation, T_OPERATION, st, NULL))
         return 0;
 
-    if (!checkToken(pm, right_type)){
+    if (!checkToken(pm, right_type, NULL)){
         freeStatement(*st);
         return -1;
     }
@@ -1573,13 +1578,13 @@ void parserBaseValue(P_FUNC){
         case MATHER_LAMBDA:  {
             Parameter *pt = NULL;
             Statement *lambda_st = NULL;
-            if (!parserParameter(CP_FUNC, &pt, false, true, false, false, MATHER_COMMA,
-                                 MATHER_ASSIGNMENT, -1)) {
+            if (!parserParameter(CP_FUNC, &pt, false, true, false, -1, false, MATHER_COMMA,
+                                 MATHER_ASSIGNMENT, false)) {
                 freeToken(value_token, true);
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a lambda parameter");
                 goto return_;
             }
-            if (!checkToken(pm, MATHER_COLON)) {
+            if (!checkToken(pm, MATHER_COLON, NULL)) {
                 lambda_st = makeStatement(value_token->line, pm->file);
                 goto not_lambda_st;
             }
@@ -1597,7 +1602,7 @@ void parserBaseValue(P_FUNC){
             break;
         case MATHER_SVAR: {
             Statement *svar_st = NULL;
-            bool is_var = checkToken(pm, MATHER_COLON);
+            bool is_var = checkToken(pm, MATHER_COLON, NULL);
             if (!callChildStatement(CP_FUNC, parserBaseValue, T_BASEVALUE, &svar_st, NULL)) {
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get super var after $");
                 freeToken(value_token, true);
@@ -1660,14 +1665,14 @@ void parserBaseValue(P_FUNC){
         case MATHER_LC: {
             Parameter *pt = NULL;
             int parser_status;
-            parser_status = parserParameter(CP_FUNC, &pt, true, false, false, true, MATHER_COMMA,
-                                            MATHER_COLON, -1);
+            parser_status = parserParameter(CP_FUNC, &pt, true, false, false, -1, true, MATHER_COMMA,
+                                            MATHER_COLON, false);
             if (!parser_status) {
                 freeToken(value_token, true);
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a dict parameter");
                 goto return_;
             }
-            if (!checkToken(pm, MATHER_RC)) {
+            if (!checkToken(pm, MATHER_RC, NULL)) {
                 freeToken(value_token, true);
                 freeParameter(pt, true);
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a } after dict");

+ 8 - 4
vmcore/parser/include/__grammar.h

@@ -52,15 +52,19 @@ void parserGoto(P_FUNC);
 void parserDecoration(P_FUNC);
 void parserVarControl(P_FUNC);
 
-void syntaxError(ParserMessage *pm, int status,long int line , int num, ...);
+void syntaxError(ParserMessage *pm, int status,fline line , int num, ...);
 int readBackToken(ParserMessage *pm);
-bool checkToken(ParserMessage *pm, int type);
+
+bool checkToken(ParserMessage *pm, int type, fline *line);
 bool commandCallControl_(P_FUNC, MakeControlFunction callBack, int type, Statement **st, bool must_operation, char *error_message);
-bool callParserCode(P_FUNC, Statement **st, char *message, long int line);
+bool callParserCode(P_FUNC, Statement **st, char *message, fline line);
 bool callParserAs(P_FUNC, Statement **st, char *message);
 bool callChildStatement(P_FUNC, PasersFunction callBack, int type, Statement **st, char *message);
 bool callChildToken(P_FUNC, PasersFunction callBack, int type, Token **tmp, char *message, int error_type);
-bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is_list, bool is_dict, int sep, int ass, int n_sep);
+
+bool
+parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool enter, bool is_formal, bool is_list, int n_sep,
+                bool is_dict, int sep, int ass, bool space);
 void twoOperation(P_FUNC, PasersFunction callBack, GetSymbolFunction getSymbol, ChecktLeftToken checkleft,
                   int call_type, int self_type, char *call_name, char *self_name, bool is_right);
 void lexEnter(ParserMessage *pm, bool lock);

+ 3 - 3
vmcore/parser/token.c

@@ -1,6 +1,6 @@
 #include "__virtualmath.h"
 
-Token *makeToken(long int line) {
+Token *makeToken(fline line) {
     Token *tmp = memCalloc(1, sizeof(Token));
     tmp->token_type = 0;
     tmp->data.str = NULL;
@@ -11,7 +11,7 @@ Token *makeToken(long int line) {
     return tmp;
 }
 
-Token *makeLexToken(int type, wchar_t *str, wchar_t *second_str, long int line) {
+Token *makeLexToken(int type, wchar_t *str, wchar_t *second_str, fline line) {
     Token *tmp = makeToken(line);
     tmp->token_type = type;
     tmp->data.str = memWidecpy(str);
@@ -27,7 +27,7 @@ Token *makeStatementToken(int type, struct Statement *st){
 }
 
 long freeToken(Token *tk, bool free_st) {
-    long int line = 0;
+    fline line = 0;
     FREE_BASE(tk, return_);
     line = tk->line;
     memFree(tk->data.str);

+ 3 - 3
vmcore/src/runcall.c

@@ -217,7 +217,7 @@ static ResultType callObject(LinkValue *object_value, Argument *arg, fline line,
     return result->type;
 }
 
-static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
+static ResultType callCFunction(LinkValue *func_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT){
     VarList *function_var = NULL;
     OfficialFunction of = NULL;
     Argument *bak;
@@ -407,7 +407,7 @@ static ResultType getFuncargs(LinkValue *function_value, ArgumentFFI *af, fline
     return result->type;
 }
 
-static ResultType callFFunction(LinkValue *function_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
+static ResultType callFFunction(LinkValue *function_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT){
     ffi_cif cif;
     ffi_type *re;
     unsigned int size;
@@ -515,7 +515,7 @@ static bool popFuncYieldVarList(Statement *st, VarList **return_, VarList *out_v
     return yield_run;
 }
 
-static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT) {
+static ResultType callVMFunction(LinkValue *func_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT) {
     Argument *bak;
     VarList *var_func = NULL;
     Statement *st_func = NULL;

+ 1 - 1
vmcore/src/value.c

@@ -49,7 +49,7 @@ Value *makeBoolValue(bool bool_num, fline line, char *file, FUNC_NT) {
     return tmp;
 }
 
-Value *makePassValue(fline line, char *file, FUNC_NT){  // TODO-szh 让切片支持该语法 检查语法解析器支持 a[::]的语法
+Value *makePassValue(fline line, char *file, FUNC_NT){
     Value *tmp = NULL;
     setResultCore(result);
     if (inter->data.free_mode) {