Browse Source

feat: 允许使用C定义的函数

SongZihuan 4 năm trước cách đây
mục cha
commit
59a8ff293f

+ 3 - 1
CMakeLists.txt

@@ -5,6 +5,7 @@ SET(CMAKE_C_STANDARD 11)
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/parser/include)
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/include)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/ofunc/include)
 
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/memory MEM_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/parser PASER_LIST)
@@ -12,6 +13,7 @@ AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST)
 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)
 
 MESSAGE("project dir is ${PROJECT_SOURCE_DIR}")
-ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST})
+ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST})

+ 5 - 5
include/__macro.h

@@ -20,11 +20,11 @@
 #define run_continue_type(type) (type == not_return || type == operation_return)
 #define run_continue(result) (result->type == not_return || result->type == operation_return)
 
-#define freeBase(element, return_) do{ \
-if (element == NULL){ \
-goto return_; \
-} \
-}while(0) \
+#define freeBase(element, return_) do{if(element == NULL)goto return_;}while(0)
 
+#define OfficialFunctionSig struct LinkValue *self, struct Argument *arg, INTER_FUNCTIONSIG_NOT_ST
+#define CALL_OfficialFunction(self, arg, var_list, result, father) self, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father)
+#define RegisteredFunctionSig struct LinkValue *father, INTER_FUNCTIONSIG_CORE
+#define CALL_RegisteredFunction(father, var_list) father, CALL_INTER_FUNCTIONSIG_CORE(var_list)
 
 #endif //VIRTUALMATH___MACRO_H

+ 2 - 0
include/__virtualmath.h

@@ -5,6 +5,7 @@
 #include "mem.h"
 #include "gc.h"
 #include "inter.h"
+#include "ofunc.h"
 #include "value.h"
 #include "var.h"
 #include "parameter.h"
@@ -22,4 +23,5 @@ void printLinkValueGC(char *tag, Inter *inter);
 void printValueGC(char *tag, Inter *inter);
 void printVarGC(char *tag, Inter *inter);
 void printHashTableGC(char *tag, Inter *inter);
+void printTokenStream(TokenStream *ts);
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 2 - 1
include/inter.h

@@ -8,6 +8,7 @@ struct Inter{
     struct LinkValue *link_base;
     struct HashTable *hash_base;
     struct Var *base_var;
+    struct LinkValue *base_father;
 
     struct VarList *var_list;
     struct InterData{
@@ -26,7 +27,7 @@ struct Inter{
 typedef struct Inter Inter;
 typedef struct Statement Statement;
 
-Inter *makeInter(char *debug);
+Inter *makeInter(char *debug, struct LinkValue *father);
 void freeInter(Inter *inter, bool show_gc);
 void setBaseInterData(struct Inter *inter);
 int runCodeBlock(char *code_file, Inter *inter);

+ 21 - 0
include/ofunc.h

@@ -0,0 +1,21 @@
+#ifndef VIRTUALMATH_OFUNC_H
+#define VIRTUALMATH_OFUNC_H
+#include "__macro.h"
+#include "io.h"
+
+struct Argument;
+struct VarList;
+typedef enum ResultType (*OfficialFunction)(OfficialFunctionSig);
+typedef void (*Registered)(RegisteredFunctionSig);
+
+struct NameFunc{
+    char *name;
+    OfficialFunction of;
+};
+typedef struct NameFunc NameFunc;
+
+void registeredFunctionCore(OfficialFunction of, char *name, struct LinkValue *father, INTER_FUNCTIONSIG_CORE);
+void iterNameFunc(NameFunc list[],struct LinkValue *father, INTER_FUNCTIONSIG_CORE);
+void registeredBaseFunction(struct LinkValue *father, Inter *inter);
+
+#endif //VIRTUALMATH_OFUNC_H

+ 3 - 2
include/run.h

@@ -15,7 +15,7 @@ typedef struct Parameter Parameter;
 typedef struct DecorationStatement DecorationStatement;
 typedef ResultType (*VarInfo)(char **name, int *times, INTER_FUNCTIONSIG);
 
-ResultType globalIterStatement(Result *result, LinkValue *base_father, Inter *inter, Statement *st);
+ResultType globalIterStatement(Result *result, Inter *inter, Statement *st);
 bool operationSafeInterStatement(INTER_FUNCTIONSIG);
 bool ifBranchSafeInterStatement(INTER_FUNCTIONSIG);
 bool functionSafeInterStatement(INTER_FUNCTIONSIG);
@@ -31,7 +31,8 @@ ResultType setLambda(INTER_FUNCTIONSIG);
 ResultType callBack(INTER_FUNCTIONSIG);
 ResultType callBackCore(LinkValue *function_value, Parameter *parameter, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 ResultType callClass(LinkValue *class_value, Parameter *parameter, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST);
-ResultType callFunction(LinkValue *function_value, Parameter *parameter, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST);
+ResultType callVMFunction(LinkValue *function_value, Parameter *parameter, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST);
+ResultType callCFunction(LinkValue *function_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST);
 ResultType setDecoration(DecorationStatement *ds, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
 ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info);
 ResultType getBaseValue(INTER_FUNCTIONSIG);

+ 7 - 1
include/value.h

@@ -43,8 +43,13 @@ struct Value{
             char *str;
         } str;
         struct Function{
+            enum{
+                c_function,
+                vm_function,
+            } type;
             struct Statement *function;
             struct Parameter *pt;
+            OfficialFunction of;
         } function;
         struct List{
             enum ListType{
@@ -126,7 +131,8 @@ Value *makeBoolValue(bool bool_num, Inter *inter);
 Value *makePassValue(Inter *inter);
 Value *makeNumberValue(long num, Inter *inter);
 Value *makeStringValue(char *str, Inter *inter);
-Value *makeFunctionValue(struct Statement *st, struct Parameter *pt, struct VarList *var_list, Inter *inter);
+Value *makeVMFunctionValue(struct Statement *st, struct Parameter *pt, struct VarList *var_list, Inter *inter);
+Value *makeCFunctionValue(OfficialFunction of, VarList *var_list, Inter *inter);
 Value *makeClassValue(VarList *var_list, Inter *inter, FatherValue *father);
 Value *makeListValue(struct Argument **arg_ad, Inter *inter, enum ListType type);
 Value *makeDictValue(struct Argument **arg_ad, bool new_hash, INTER_FUNCTIONSIG_NOT_ST);

+ 1 - 1
main.c

@@ -10,7 +10,7 @@ int main(int argc, char *argv[]) {
     if (getArgs(argc, argv))
         goto args_error;
 
-    inter = makeInter(args.log_file);
+    inter = makeInter(args.log_file, NULL);
     for (int status=0; status == 0 && argv[optind] != NULL; optind++)
         status = runCodeBlock(argv[optind], inter);
     freeInter(inter, true);

+ 7 - 0
ofunc/include/io.h

@@ -0,0 +1,7 @@
+#ifndef VIRTUALMATH_IO_H
+#define VIRTUALMATH_IO_H
+#include "__macro.h"
+
+typedef enum ResultType ResultType;
+void registeredIOFunction(RegisteredFunctionSig);
+#endif //VIRTUALMATH_IO_H

+ 18 - 0
ofunc/src/io.c

@@ -0,0 +1,18 @@
+#include "__virtualmath.h"
+
+ResultType vm_print(OfficialFunctionSig){
+    setResultBase(result, inter, father);
+    if (arg == NULL){
+        setResultError(result, inter, "ArgumentException", "Don't get any Argument for print", 0, "sys", father, true);
+        return error_return;
+    }
+    for (PASS; arg != NULL; arg = arg->next)
+        printValue(arg->data.value->value, stdout);
+    printf("\n");
+    return result->type;
+}
+
+void registeredIOFunction(RegisteredFunctionSig){
+    NameFunc tmp[] = {{"print", vm_print}, {NULL, NULL}};
+    iterNameFunc(tmp, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+}

+ 7 - 6
parser/__grammar.c

@@ -245,7 +245,7 @@ bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Stat
  * @param ass 设定赋值符号
  * @return
  */
-bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_list, bool is_dict, int sep,
+bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool enter, bool is_formal, bool is_list, bool is_dict, int sep,
                      int ass) {
     Parameter *new_pt = NULL;
     Token *tmp;
@@ -257,7 +257,8 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
         s_4,  // name_args模式
     } status;
 
-    lexEnter(pm, true);
+    if (enter)
+        lexEnter(pm, true);
     if (is_dict && !is_list)
         status = s_2;  // is_formal关闭对only_value的支持
     else
@@ -269,7 +270,6 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
             status = s_3;
         else if (!is_list && checkToken(pm, MATHER_POW))  // is_formal关闭对*args的支持
             status = s_4;
-
         parserPolynomial(CALLPASERSSIGNATURE);
         if (!call_success(pm))
             goto error_;
@@ -282,7 +282,6 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
             break;
         }
         tmp = popNewToken(pm->tm);
-
         int pt_type = value_par;
         if (status == s_1){
             if (!checkToken(pm, sep)){
@@ -337,14 +336,16 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
         freeToken(tmp, false);
     }
     *pt = new_pt;
-    lexEnter(pm, false);
+    if (enter)
+        lexEnter(pm, false);
     return true;
 
     error_:
     freeToken(tmp, true);
     freeParameter(new_pt, true);
     *pt = NULL;
-    lexEnter(pm, false);
+    if (enter)
+        lexEnter(pm, false);
     return false;
 }
 

+ 12 - 13
parser/grammar.c

@@ -56,6 +56,8 @@ void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
             else  if(stop != MATHER_EOF){
                 if (global) {
                     fprintf(stderr, "stop = %d\n", stop);
+                    Token *tk = popNewToken(pm->tm);
+                    freeToken(tk, true);
                     syntaxError(pm, command_list_error, command_token->line, 1, "ERROR from parserCommand list(get stop)");
                     freeToken(command_token, true);
                 }
@@ -357,7 +359,6 @@ void parserImport(PASERSSIGNATURE) {
     Statement *st = NULL;
     int token_type = readBackToken(pm);
     long int line = delToken(pm);
-
     if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &opt, "Don't get a import file"))
         goto return_;
     if (token_type == MATHER_IMPORT) {
@@ -378,18 +379,18 @@ void parserImport(PASERSSIGNATURE) {
         }
         if (checkToken(pm, MATHER_MUL))  // 导入所有
             goto mul_;
-        if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || pt == NULL) {
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || 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(CALLPASERSSIGNATURE, &as, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || as == NULL)) {
+        if (checkToken(pm, MATHER_AS) && (!parserParameter(CALLPASERSSIGNATURE, &as, false, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || as == NULL)) {
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, opt->line, 1, "Don't get any value after import");
             freeStatement(opt);
             goto return_;
         }
-        else if (checkFormal(pt)){
+        if (as == NULL && !checkFormal(pt)){
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, opt->line, 1, "Don't get success value to import");
             freeStatement(opt);
@@ -421,7 +422,7 @@ void parserVarControl(PASERSSIGNATURE) {
     Token *tmp = NULL;
     int token_type = readBackToken(pm);
     long int line = delToken(pm);
-    if (!parserParameter(CALLPASERSSIGNATURE, &var, true, true, true, MATHER_COMMA, MATHER_ASSIGNMENT) || var == NULL) {
+    if (!parserParameter(CALLPASERSSIGNATURE, &var, false, true, true, true, MATHER_COMMA, MATHER_ASSIGNMENT) || var == NULL) {
         syntaxError(pm, syntax_error, line, 1, "Don't get any var");
         goto return_;
     }
@@ -905,7 +906,8 @@ void parserDef(PASERSSIGNATURE){
         syntaxError(pm, syntax_error, line, 1, "Don't get a function/class ( before parameter");
         goto error_;
     }
-    if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+        lexEnter(pm, false);
         syntaxError(pm, syntax_error, line, 1, "Don't get a function/class parameter");
         goto error_;
     }
@@ -1044,7 +1046,7 @@ void parserTuple(PASERSSIGNATURE){
     addToken_(pm ,tmp);
 
     parserPt:
-    if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get tuple element");
         goto return_;
     }
@@ -1119,8 +1121,7 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
 
     if (checkToken(pm, MATHER_RP))
         goto not_pt;
-
-    if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+    if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get call parameter");
         return 0;
     }
@@ -1225,7 +1226,7 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_LAMBDA == value_token->token_type){
         Parameter *pt = NULL;
         Statement *lambda_st = NULL;
-        if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
             freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a lambda parameter");
             goto return_;
@@ -1304,9 +1305,7 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_LC == value_token->token_type){
         Parameter *pt = NULL;
         int parser_status;
-        lexEnter(pm, true);
-        parser_status = parserParameter(CALLPASERSSIGNATURE, &pt, false, false, true, MATHER_COMMA, MATHER_COLON);
-        lexEnter(pm, false);
+        parser_status = parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, true, MATHER_COMMA, MATHER_COLON);
         if (!parser_status) {
             freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a dict parameter");

+ 1 - 1
parser/include/__grammar.h

@@ -55,7 +55,7 @@ bool callParserAs(PASERSSIGNATURE, Statement **st,char *message);
 bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Statement **st, char *message);
 bool callChildToken(PASERSSIGNATURE, PasersFunction callBack, int type, Token **tmp, char *message,
                     int error_type);
-bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_list, bool is_dict,
+bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool enter, bool is_formal, bool is_list, bool is_dict,
                      int sep,int ass);
 
 void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol, ChecktLeftToken checkleft,

+ 1 - 2
parser/lexical.c

@@ -81,9 +81,8 @@ LexMathers *makeMathers(int size){
 
 void freeMathers(LexMathers *mathers) {
     freeBase(mathers, return_);
-    for(int i=0;i < mathers->size; i++){
+    for(int i=0;i < mathers->size; i++)
         freeMather(mathers->mathers[i]);
-    }
     memFree(mathers->mathers);
     mathers->size = 0;
     memFree(mathers);

+ 3 - 1
parser/syntax.c

@@ -338,8 +338,10 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
 int lexFilter(LexFile *file, int status){
     if (status == MATHER_SPACE || status == MATHER_NOTENTER || status == MATHER_COMMENT)
         return -1;
-    if (file->filter_data.enter != 0 && status == MATHER_ENTER)
+    if (file->filter_data.enter != 0 && status == MATHER_ENTER) {
+        printf("TAG A\n");
         return -1;
+    }
     return status;
 }
 

+ 47 - 1
src/inter.c

@@ -1,8 +1,9 @@
 #include "__virtualmath.h"
 
-Inter *makeInter(char *debug) {
+Inter *makeInter(char *debug, LinkValue *father) {
     Inter *tmp = memCalloc(1, sizeof(Inter));
     Value *none_value = NULL;
+    LinkValue *base_father = NULL;
     setBaseInterData(tmp);
     tmp->base = NULL;
     tmp->link_base = NULL;
@@ -29,6 +30,12 @@ Inter *makeInter(char *debug) {
     }
     none_value = makeNoneValue(tmp);  // 注册None值
     gc_addStatementLink(&none_value->gc_status);
+
+    base_father = makeLinkValue(makeObject(tmp, copyVarList(tmp->var_list, false, tmp), NULL, NULL), father, tmp);
+    gc_addStatementLink(&base_father->gc_status);
+    tmp->base_father = base_father;
+
+    registeredBaseFunction(base_father, tmp);
     return tmp;
 }
 
@@ -59,6 +66,9 @@ void freeBaseInterData(struct Inter *inter){
 void freeInter(Inter *inter, bool show_gc) {
     freeBase(inter, return_);
 
+    gc_freeStatementLink(&inter->base_father->gc_status);
+    inter->base_father = NULL;
+
     freeVarList(inter->var_list);
     freeBaseInterData(inter);
 
@@ -89,6 +99,8 @@ void mergeInter(Inter *new, Inter *base){
     LinkValue **base_linkValue = NULL;
     HashTable **base_hash = NULL;
     Var **base_var = NULL;
+    gc_freeStatementLink(&new->base_father->gc_status);
+    new->base_father = NULL;
 
     for (base_value = &base->base; *base_value != NULL; base_value = &(*base_value)->gc_next)
             PASS;
@@ -168,4 +180,38 @@ void printHashTableGC(char *tag, Inter *inter){
         base = base->gc_next;
     }
     printf("printHashTableGC TAG : END\n");
+}
+
+void printToken(Token *tk) {
+    if (tk->token_type >= 0) {
+        char *tmp = tk->data.str, *second_tmp = tk->data.second_str;
+        if (!strcmp(tmp, "\n")) {
+            tmp = "\\n";
+        }
+        if (!strcmp(second_tmp, "\n")) {
+            second_tmp = "\\n";
+        }
+        if (tmp[0] == EOF) {
+            tmp = "(EOF)";
+        }
+        printf("<token str = ('%s','%s'), type = %d>", tmp, second_tmp, tk->token_type);
+    }
+    else{
+        printf("<token statement, type = %d>", tk->token_type);
+    }
+
+}
+
+void printTokenStream(TokenStream *ts) {
+    printf("token_list: ");
+    Token *tmp = ts->token_list;
+    int i = 0;
+    while (tmp != NULL){
+        if (i > 0)
+            printf("-");
+        printToken(tmp);
+        tmp = tmp->next;
+        i++;
+    }
+    printf("\n");
 }

+ 23 - 0
src/ofunc.c

@@ -0,0 +1,23 @@
+#include "__virtualmath.h"
+
+static Registered base_func_list[] = {registeredIOFunction, NULL};
+
+void registeredFunctionCore(OfficialFunction of, char *name, struct LinkValue *father, INTER_FUNCTIONSIG_CORE) {
+    LinkValue *value = NULL;
+    LinkValue *name_ = NULL;
+    char *var_name = setStrVarName(name, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    name_ = makeLinkValue(makeStringValue(var_name, inter), father, inter);
+    value = makeLinkValue(makeCFunctionValue(of, var_list, inter), father, inter);
+    addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    memFree(var_name);
+}
+
+void iterNameFunc(NameFunc list[], LinkValue *father, INTER_FUNCTIONSIG_CORE){
+    for (PASS; list->of != NULL; list++)
+        registeredFunctionCore(list->of, list->name, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+}
+
+void registeredBaseFunction(struct LinkValue *father, Inter *inter){
+    for (Registered *list = base_func_list; *list != NULL; list++)
+        (*list)(CALL_RegisteredFunction(father, inter->var_list));
+}

+ 5 - 7
src/run.c

@@ -31,8 +31,6 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
             break;
         case operation:
             type = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
-            if (run_continue_type(type))
-                printLinkValue(result->value, "operation result = ", "\n", inter->data.debug);
             break;
         case set_class:
             type = setClass(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
@@ -158,8 +156,9 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
  * @param inter
  * @return
  */
-ResultType globalIterStatement(Result *result, LinkValue *base_father, Inter *inter, Statement *st) {
-    LinkValue *father = makeLinkValue(makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL), base_father, inter);
+ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
+    LinkValue *father = inter->base_father;
+    gc_addTmpLink(&father->gc_status);
     Statement *base_st = NULL;
     VarList *var_list = NULL;
     enum ResultType type;
@@ -189,6 +188,7 @@ ResultType globalIterStatement(Result *result, LinkValue *base_father, Inter *in
     if (type != error_return && type != function_return)
         setResultOperationNone(result, inter, father);
     result->node = base_st;
+    gc_freeTmpLink(&father->gc_status);
     gc_run(inter, 1, 0, 0, var_list);
     return result->type;
 }
@@ -199,10 +199,8 @@ bool operationSafeInterStatement(INTER_FUNCTIONSIG){
     type = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
     if (run_continue_type(type))
         return false;
-    else if (type != return_code && type != error_return) {
-        printf("type = %d\n", type);
+    else if (type != return_code && type != error_return)
         setResultErrorSt(result, inter, "ResultException", "Get Not Support Result", st, father, true);
-    }
     return true;
 }
 

+ 33 - 5
src/runcall.c

@@ -79,7 +79,7 @@ ResultType setFunction(INTER_FUNCTIONSIG) {
     setResultCore(result);
 
     function_var = copyVarList(var_list, false, inter);
-    function_value = makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, function_var, inter);
+    function_value = makeVMFunctionValue(st->u.set_function.function, st->u.set_function.parameter, function_var, inter);
     tmp = makeLinkValue(function_value, father, inter);
     gc_addTmpLink(&tmp->gc_status);
     if (st->u.set_function.decoration != NULL){
@@ -110,7 +110,7 @@ ResultType setLambda(INTER_FUNCTIONSIG) {
 
     result->type = operation_return;
     function_var = copyVarList(var_list, false, inter);
-    function_value = makeFunctionValue(st->u.base_lambda.function, st->u.base_lambda.parameter, function_var, inter);
+    function_value = makeVMFunctionValue(st->u.base_lambda.function, st->u.base_lambda.parameter, function_var, inter);
     result->value = makeLinkValue(function_value, father, inter);
     gc_addTmpLink(&result->value->gc_status);
     return result->type;
@@ -119,8 +119,10 @@ ResultType setLambda(INTER_FUNCTIONSIG) {
 ResultType callBackCore(LinkValue *function_value, Parameter *parameter, long line, char *file, INTER_FUNCTIONSIG_NOT_ST){
     setResultCore(result);
     gc_addTmpLink(&function_value->gc_status);
-    if (function_value->value->type == function)
-        callFunction(function_value, parameter, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    if (function_value->value->type == function && function_value->value->data.function.type == vm_function)
+        callVMFunction(function_value, parameter, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    else if (function_value->value->type == function && function_value->value->data.function.type == c_function)
+        callCFunction(function_value, parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     else if (function_value->value->type == class)
         callClass(function_value, parameter, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     else{
@@ -195,7 +197,33 @@ Statement *getRunInfoStatement(Statement *funtion_st){  // TODO-szh 去除该函
     return funtion_st->info.node;
 }
 
-ResultType callFunction(LinkValue *function_value, Parameter *parameter, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+ResultType callCFunction(LinkValue *function_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST){
+    VarList *function_var = NULL;
+    OfficialFunction of = NULL;
+    Argument *arg = NULL;
+    setResultCore(result);
+    gc_addTmpLink(&function_value->gc_status);
+    of = function_value->value->data.function.of;
+    function_var = function_value->value->object.out_var;
+    gc_freeze(inter, var_list, function_var, true);
+
+    gc_addTmpLink(&function_var->hashtable->gc_status);
+    arg = getArgument(parameter, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    gc_freeTmpLink(&function_var->hashtable->gc_status);
+    if (!run_continue(result))
+        goto return_;
+
+    freeResult(result);
+    of(CALL_OfficialFunction(function_value, arg, function_var, result, father));
+
+    return_:
+    freeArgument(arg, true);
+    gc_freeze(inter, var_list, function_var, false);
+    gc_freeTmpLink(&function_value->gc_status);
+    return result->type;
+}
+
+ResultType callVMFunction(LinkValue *function_value, Parameter *parameter, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
     VarList *function_var = NULL;
     Statement *funtion_st = NULL;
     bool yield_run = false;

+ 2 - 2
src/runfile.c

@@ -61,7 +61,7 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
     }
 
 
-    import_inter = makeInter(NULL);
+    import_inter = makeInter(NULL, father);
     pm = makeParserMessage(*file_dir);
     run_st = makeStatement(0, *file_dir);
     parserCommandList(pm, import_inter, true, run_st);
@@ -71,7 +71,7 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
         goto return_;
     }
 
-    globalIterStatement(result, father, import_inter, run_st);
+    globalIterStatement(result, import_inter, run_st);
     if (!run_continue(result)) {
         freeInter(import_inter, false);
         result->value = makeLinkValue(inter->base, father, inter);  // 重新设定none值

+ 2 - 1
src/runoperation.c

@@ -233,7 +233,8 @@ ResultType assOperation(INTER_FUNCTIONSIG) {
         Value *function_value = NULL;
         LinkValue *tmp = NULL;
         function_var = copyVarList(var_list, false, inter);
-        function_value = makeFunctionValue(st->u.operation.right, st->u.operation.left->u.call_function.parameter, function_var, inter);
+        function_value = makeVMFunctionValue(st->u.operation.right, st->u.operation.left->u.call_function.parameter,
+                                             function_var, inter);
         tmp = makeLinkValue(function_value, father, inter);
         assCore(st->u.operation.left->u.call_function.function, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     }

+ 14 - 1
src/value.c

@@ -67,12 +67,25 @@ Value *makeStringValue(char *str, Inter *inter) {
     return tmp;
 }
 
-Value *makeFunctionValue(Statement *st, Parameter *pt, VarList *var_list, Inter *inter) {
+Value *makeVMFunctionValue(Statement *st, Parameter *pt, VarList *var_list, Inter *inter) {
     Value *tmp;
     tmp = makeObject(inter, NULL, var_list, NULL);
     tmp->type = function;
+    tmp->data.function.type = vm_function;
     tmp->data.function.function = copyStatement(st);
     tmp->data.function.pt = copyParameter(pt);
+    tmp->data.function.of = NULL;
+    return tmp;
+}
+
+Value *makeCFunctionValue(OfficialFunction of, VarList *var_list, Inter *inter) {
+    Value *tmp;
+    tmp = makeObject(inter, NULL, copyVarList(var_list, false, inter), NULL);
+    tmp->type = function;
+    tmp->data.function.type = c_function;
+    tmp->data.function.function = NULL;
+    tmp->data.function.pt = NULL;
+    tmp->data.function.of = of;
     return tmp;
 }
 

+ 1 - 1
src/virtualmath.c

@@ -28,7 +28,7 @@ void runCode(Statement *st, Inter *inter) {
     Result result;
     ResultType type;
     setResultCore(&result);
-    type = globalIterStatement(&result, NULL, inter, st);
+    type = globalIterStatement(&result, inter, st);
     if (type == error_return)
         printError(&result, inter, true);
     freeResult(&result);