فهرست منبع

feat: 支持命令行模式

SongZihuan 4 سال پیش
والد
کامیت
ccbed8b085
14فایلهای تغییر یافته به همراه97 افزوده شده و 42 حذف شده
  1. 8 0
      argument/argument.c
  2. 1 2
      include/__virtualmath.h
  3. 1 0
      include/arguement.h
  4. 1 1
      include/grammar.h
  5. 6 4
      include/inter.h
  6. 1 0
      include/lexical.h
  7. 1 1
      include/syntax.h
  8. 7 1
      main.c
  9. 12 6
      parser/grammar.c
  10. 9 5
      parser/lexical.c
  11. 18 8
      parser/syntax.c
  12. 3 3
      src/inter.c
  13. 6 2
      src/runfile.c
  14. 23 9
      src/virtualmath.c

+ 8 - 0
argument/argument.c

@@ -1,5 +1,13 @@
 #include "__virtualmath.h"
 
+char *HelloString = "Welcome To VirtualMath ("__TIME__", "__DATE__") \n"
+#ifdef __linux__
+                    "On Linux\n"
+#else
+                    "On windows"
+#endif
+                    "VirtualMath Command Line Mode\n";
+
 static const struct option long_option[]={
         {"log-err",required_argument,NULL,'o'},
         {"log-out",required_argument,NULL,'e'},

+ 1 - 2
include/__virtualmath.h

@@ -18,8 +18,7 @@
 #include "arguement.h"
 #include "file.h"
 
-#define DEBUG 0
-
+#define DEBUG 1
 #if DEBUG
 /* DEBUG */
 void printGC(Inter *inter);

+ 1 - 0
include/arguement.h

@@ -1,6 +1,7 @@
 #ifndef VIRTUALMATH_ARGUEMENT_H
 #define VIRTUALMATH_ARGUEMENT_H
 
+extern char *HelloString;
 struct Args{
     char *error_file;
     char *out_file;

+ 1 - 1
include/grammar.h

@@ -18,7 +18,7 @@ typedef struct ParserMessage ParserMessage;
 
 ParserMessage *makeParserMessage(char *file_dir);
 void freeParserMessage(ParserMessage *pm, bool self);
-void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st);
+void parserCommandList(ParserMessage *pm, Inter *inter, bool global, bool is_one, Statement *st);
 // PASERSSIGNATURE 位于__grammar
 
 #endif //VIRTUALMATH_GRAMMAR_H

+ 6 - 4
include/inter.h

@@ -14,7 +14,7 @@ struct Inter{
     struct InterData{
         FILE *inter_stdout;
         FILE *inter_stderr;
-        bool log_dir;
+        bool is_std;
 
         struct Value *object;
         struct Value *vobject;
@@ -56,12 +56,14 @@ struct Inter{
 
 typedef struct Inter Inter;
 typedef struct Statement Statement;
+typedef enum ResultType ResultType;
 
 Inter *makeInter(char *out, char *error_, struct LinkValue *belong);
 void freeInter(Inter *inter, bool show_gc);
 void setBaseInterData(struct Inter *inter);
-int runCodeBlock(char *code_file, Inter *inter);
-void runParser(char *code_file, Inter *inter, Statement **st);
-void runCode(Statement *st, Inter *inter);
+ResultType runCodeBlock(char *code_file, Inter *inter);
+ResultType 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);
 #endif //VIRTUALMATH_INTER_H

+ 1 - 0
include/lexical.h

@@ -4,6 +4,7 @@
 
 struct LexFile{
     FILE *file;
+    bool is_std;  // 是否位stdin
     struct LexFileBack{
         bool is_back;
         int p;

+ 1 - 1
include/syntax.h

@@ -9,8 +9,8 @@ void varMather(int p, LexMather *mather);
 void stringMather(int p, LexMather *mather);
 void strMather(int p, LexMather *mather, const char *dest_p);
 void charMather(int p, LexMather *mather, int dest_p);
+void aCharMather(int p, LexMather *mather, int dest_p);
 void spaceMather(int p, LexMather *mather);
 void commentMather(int p, LexMather *mather);
 void backslashMather(int p, LexMather *mather);
-
 #endif //VIRTUALMATH_SYNTAX_H

+ 7 - 1
main.c

@@ -11,8 +11,14 @@ int main(int argc, char *argv[]) {
         goto args_error;
 
     inter = makeInter(args.out_file, args.error_file, NULL);
-    for (int status=0; status == 0 && argv[optind] != NULL; optind++)
+    for (ResultType status = not_return; status != error_return && argv[optind] != NULL; optind++)
         status = runCodeBlock(argv[optind], inter);
+    printf("%s", HelloString);
+    while (1){
+        runCodeStdin(inter);
+        if (ferror(stdin) || feof(stdin))
+            break;
+    }
     freeInter(inter, true);
 
     args_error: freeArgs();

+ 12 - 6
parser/grammar.c

@@ -2,7 +2,7 @@
 
 ParserMessage *makeParserMessage(char *file_dir) {
     ParserMessage *tmp = memCalloc(1, sizeof(ParserMessage));
-    tmp->file = file_dir;
+    tmp->file = memStrcpy(file_dir == NULL ? "stdin" : file_dir);
     tmp->tm = makeTokenMessage(file_dir);
     tmp->status = success;
     tmp->status_message = NULL;
@@ -13,6 +13,7 @@ void freeParserMessage(ParserMessage *pm, bool self) {
     freeBase(pm, return_);
     freeTokenMessage(pm->tm, true, true);
     memFree(pm->status_message);
+    memFree(pm->file);
     if (self)
         memFree(pm);
     return_:
@@ -29,12 +30,13 @@ void freeParserMessage(ParserMessage *pm, bool self) {
  * | parserCommand MATHER_SEMICOLON
  * | parserCommand MATHER_EOF
  */
-void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
+void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st) {
     int token_type;
+    bool should_break = false;
     char *command_message = global ? "ERROR from command list(get parserCommand)" : NULL;
     int save_enter = pm->tm->file->filter_data.enter;
     pm->tm->file->filter_data.enter = 0;
-    while (true){
+    while (!should_break){
         token_type = readBackToken(pm);
         if (token_type == MATHER_EOF){
             delToken(pm);
@@ -51,7 +53,12 @@ void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
                 goto return_;
 
             stop = readBackToken(pm);
-            if (stop == MATHER_ENTER || stop == MATHER_SEMICOLON)
+            if (stop == MATHER_ENTER) {
+                delToken(pm);
+                if (is_one)
+                    should_break = true;
+            }
+            else if (stop == MATHER_SEMICOLON)
                 delToken(pm);
             else  if(stop != MATHER_EOF){
                 if (global) {
@@ -61,7 +68,6 @@ void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
                     freeToken(command_token, true);
                 }
                 else{
-                    printf("stop = %d\n", stop);
                     connectStatement(st, command_token->data.st);
                     freeToken(command_token, false);
                 }
@@ -1050,7 +1056,7 @@ void parserCode(PASERSSIGNATURE) {
         if (!checkToken(pm, MATHER_ENTER))
             goto return_;
     }
-    parserCommandList(CALLPASERSSIGNATURE, false, st);
+    parserCommandList(CALLPASERSSIGNATURE, false, false, st);
     if (!call_success(pm))
         goto error_;
 

+ 9 - 5
parser/lexical.c

@@ -10,7 +10,7 @@ int readChar(LexFile *file){
     if (file->back.is_back)
         file->back.is_back = false;
     else
-        file->back.p = fgetc(file->file);
+        file->back.p = getc(file->file);
     if (file->back.p == '\n')
         file->line++;
     return file->back.p;
@@ -28,7 +28,11 @@ void backChar(LexFile *file){
 
 LexFile *makeLexFile(char *dir){
     LexFile *tmp = memCalloc(1, sizeof(LexFile));
-    tmp->file = fopen(dir, "r");
+    tmp->is_std = (bool)(dir == NULL);
+    if (tmp->is_std)
+        tmp->file = stdin;
+    else
+        tmp->file = fopen(dir, "r");
     tmp->back.is_back = false;
     tmp->back.p = EOF;
     tmp->line = 1;
@@ -38,7 +42,8 @@ LexFile *makeLexFile(char *dir){
 
 void freeLexFile(LexFile *file) {
     freeBase(file, return_);
-    fclose(file->file);
+    if (!file->is_std)
+        fclose(file->file);
     memFree(file);
     return_:
     return;
@@ -73,9 +78,8 @@ LexMathers *makeMathers(int size){
     LexMathers *tmp = memCalloc(1, sizeof(LexMathers));
     tmp->size = size;
     tmp->mathers = (struct LexMather**)memCalloc(size, sizeof(LexMather*));
-    for(int i=0;i < size; i++){
+    for(int i=0;i < size; i++)
         tmp->mathers[i] = makeMather();
-    }
     return tmp;
 }
 

+ 18 - 8
parser/syntax.c

@@ -147,6 +147,16 @@ void charMather(int p, LexMather *mather, int dest_p){
         mather->status = LEXMATHER_MISTAKE;
 }
 
+void aCharMather(int p, LexMather *mather, int dest_p) {
+    if (p == dest_p && mather->status == LEXMATHER_START){
+        mather->str = memStrCharcpy(mather->str, 1, true, true, p);
+        mather->len ++;
+        mather->status = LEXMATHER_END_1;
+    }
+    else
+        mather->status = LEXMATHER_MISTAKE;
+}
+
 /**
  * 匹配空白符号
  * @param p
@@ -234,13 +244,13 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
     while (status == -1){
         int p = readChar(file);
         numberMather(p ,mathers->mathers[MATHER_NUMBER]);
-        stringMather(p ,mathers->mathers[MATHER_STRING]);
         varMather(p ,mathers->mathers[MATHER_VAR]);
         spaceMather(p ,mathers->mathers[MATHER_SPACE]);
-        commentMather(p ,mathers->mathers[MATHER_COMMENT]);
-        backslashMather(p ,mathers->mathers[MATHER_NOTENTER]);
+        stringMather(p, mathers->mathers[MATHER_STRING]);
+        backslashMather(p, mathers->mathers[MATHER_NOTENTER]);
+        commentMather(p, mathers->mathers[MATHER_COMMENT]);
         charMatherMacro(MATHER_EOF, EOF);
-        charMatherMacro(MATHER_ENTER, '\n');
+        aCharMather(p, mathers->mathers[MATHER_ENTER], '\n');
 
         strMatherMacro(MATHER_IF, "if");  // 条件判断
         strMatherMacro(MATHER_ELIF, "elif");  // 条件循环
@@ -331,17 +341,16 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
 
         status = checkoutMather(mathers, MATHER_MAX);
     }
-    backChar(file);
+    if (status != MATHER_ENTER)
+        backChar(file);
     return status;
 }
 
 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) {
-        printf("TAG A\n");
+    if (file->filter_data.enter != 0 && status == MATHER_ENTER)
         return -1;
-    }
     return status;
 }
 
@@ -364,6 +373,7 @@ Token *getToken(LexFile *file, LexMathers *mathers) {
         goto return_;
     }
     tmp = makeLexToken(filter, mathers->mathers[status]->str, mathers->mathers[status]->second_str, file->line);
+
     return_:
     return tmp;
 }

+ 3 - 3
src/inter.c

@@ -14,12 +14,12 @@ Inter *makeInter(char *out, char *error_, LinkValue *belong) {
     if (out != NULL && error_ != NULL){
         tmp->data.inter_stdout = fopen(out, "w");
         tmp->data.inter_stderr = fopen(error_, "w");
-        tmp->data.log_dir = true;
+        tmp->data.is_std = true;
     }
     else {
         tmp->data.inter_stdout = stdout;
         tmp->data.inter_stderr = stderr;
-        tmp->data.log_dir = false;
+        tmp->data.is_std = false;
     }
 
     registeredFunctionName(tmp);
@@ -105,7 +105,7 @@ void freeBaseInterData(struct Inter *inter){
     memFree(inter->data.object_iter);
     memFree(inter->data.object_next);
 
-    if (inter->data.log_dir) {
+    if (inter->data.is_std) {
         fclose(inter->data.inter_stdout);
         fclose(inter->data.inter_stderr);
     }

+ 6 - 2
src/runfile.c

@@ -24,7 +24,7 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
 
     new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir);
-    parserCommandList(pm, inter, true, new_st);
+    parserCommandList(pm, inter, true, false, new_st);
     if (pm->status != success){
         setResultErrorSt(result, inter, "IncludeSyntaxException", pm->status_message, st, belong, true);
         goto return_;
@@ -62,9 +62,13 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
 
 
     import_inter = makeInter(NULL, NULL, belong);
+    import_inter->data.inter_stdout = inter->data.inter_stdout;
+    import_inter->data.inter_stderr = inter->data.inter_stderr;
+    import_inter->data.is_std = true;
+
     pm = makeParserMessage(*file_dir);
     run_st = makeStatement(0, *file_dir);
-    parserCommandList(pm, import_inter, true, run_st);
+    parserCommandList(pm, import_inter, true, false, run_st);
     if (pm->status != success) {
         freeInter(import_inter, false);
         setResultErrorSt(result, inter, "ImportSyntaxException", pm->status_message, st, belong, true);

+ 23 - 9
src/virtualmath.c

@@ -1,21 +1,34 @@
 #include "__virtualmath.h"
 
-int runCodeBlock(char *code_file, Inter *inter) {
+ResultType runCodeBlock(char *code_file, Inter *inter) {
     Statement *pst = NULL;
+    ResultType type = error_return;
     if (checkFile(code_file) != 1)
-        return -1;
-    runParser(code_file, inter, &pst);
+        return error_return;
+    runParser(code_file, inter, false, &pst);
     if (pst != NULL) {
-        runCode(pst, inter);
+        type = runCode(pst, inter);
         freeStatement(pst);
     }
-    return 0;
+    return type;
 }
 
-void runParser(char *code_file, Inter *inter, Statement **st) {
+ResultType 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);
+    }
+    return type;
+}
+
+void runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {
     ParserMessage *pm = makeParserMessage(code_file);
-    *st = makeStatement(0, code_file);
-    parserCommandList(pm, inter, true, *st);
+    *st = makeStatement(0, (code_file == NULL) ? "stdin" : code_file);
+    parserCommandList(pm, inter, true, is_one, *st);
     if (pm->status != success) {
         fprintf(stderr, "Syntax Error: %s\n", pm->status_message);
         freeStatement(*st);
@@ -24,7 +37,7 @@ void runParser(char *code_file, Inter *inter, Statement **st) {
     freeParserMessage(pm, true);
 }
 
-void runCode(Statement *st, Inter *inter) {
+ResultType runCode(Statement *st, Inter *inter) {
     Result result;
     ResultType type;
     setResultCore(&result);
@@ -32,4 +45,5 @@ void runCode(Statement *st, Inter *inter) {
     if (type == error_return)
         printError(&result, inter, true);
     freeResult(&result);
+    return type;
 }