Browse Source

refactor & feat: 修复vs运行时问题

SongZihuan 3 years ago
parent
commit
efff1554fc
9 changed files with 216 additions and 105 deletions
  1. 24 51
      cmake/WindowsInstall.cmake
  2. 1 1
      include/runtime/rt-inter.h
  3. 8 0
      src/__main.h
  4. 8 18
      src/main-help.cpp
  5. 57 2
      src/main-run.cpp
  6. 85 0
      src/main-tool.cpp
  7. 15 15
      src/main.cpp
  8. 2 2
      test/bytecode/test1.aun
  9. 16 16
      test/src/run-code.cpp

+ 24 - 51
cmake/WindowsInstall.cmake

@@ -2,23 +2,21 @@
 
 # 安装 dll
 function(_wi_install_import_inline target run)
-    if(WIN32 OR CYGWIN)  # 只有windows需要执行该操作 (包括cygwin也需要处理.dll依赖的问题)
-        if (CMAKE_BUILD_TYPE)
-            string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type)
-        else()
-            set(_build_type DEBUG)
-        endif()
+    if(WIN32 OR CYGWIN)
+        get_target_property(imp ${target} IMPORTED_IMPLIB)
+        get_target_property(imp_debug ${target} IMPORTED_IMPLIB_DEBUG)
+        get_target_property(imp_release ${target} IMPORTED_IMPLIB_RELEASE)
 
         get_target_property(loc ${target} IMPORTED_LOCATION)
-        get_target_property(loc_t ${target} IMPORTED_LOCATION_${_build_type})
+        get_target_property(loc_debug ${target} IMPORTED_LOCATION_DEBUG)
+        get_target_property(loc_release ${target} IMPORTED_LOCATION_RELEASE)
 
         if(run)
-            if (loc)
-                install(FILES ${loc} DESTINATION ${run})
-            endif()
-            if (loc_t)
-                install(FILES ${loc_t} DESTINATION ${run})
-            endif()
+            foreach(tmp ${imp} ${imp_debug} ${imp_release} ${loc} ${loc_debug} ${loc_release})
+                if (tmp AND tmp MATCHES ".+dll")
+                    install(FILES ${tmp} DESTINATION ${run})
+                endif()
+            endforeach()
         endif()
     endif()
 endfunction()
@@ -36,43 +34,28 @@ macro(set_copy_command target a b)
             WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 endmacro()
 
-function(_wi_build_import_inline target run lib)
+function(_wi_build_import_inline target run)
     if(WIN32 OR CYGWIN)
-        if (CMAKE_BUILD_TYPE)
-            string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type)
-        else()
-            set(_build_type DEBUG)
-        endif()
-
         get_target_property(imp ${target} IMPORTED_IMPLIB)
-        get_target_property(imp_t ${target} IMPORTED_IMPLIB_${_build_type})
+        get_target_property(imp_debug ${target} IMPORTED_IMPLIB_DEBUG)
+        get_target_property(imp_release ${target} IMPORTED_IMPLIB_RELEASE)
 
         get_target_property(loc ${target} IMPORTED_LOCATION)
-        get_target_property(loc_t ${target} IMPORTED_LOCATION_${_build_type})
-
-        if(lib)
-            if (imp AND imp MATCHES ".+dll")
-                set_copy_command(deps-copy ${imp} ${lib})
-            endif()
-
-            if (imp_t AND imp_t MATCHES ".+dll")
-                set_copy_command(deps-copy ${imp_t} ${lib})
-            endif()
-        endif()
+        get_target_property(loc_debug ${target} IMPORTED_LOCATION_DEBUG)
+        get_target_property(loc_release ${target} IMPORTED_LOCATION_RELEASE)
 
         if(run)
-            if (loc AND loc MATCHES ".+dll")
-                set_copy_command(deps-copy ${loc} ${run})
-            endif()
-            if (loc_t AND loc_t MATCHES ".+dll")
-                set_copy_command(deps-copy ${loc_t} ${run})
-            endif()
+            foreach(tmp ${imp} ${imp_debug} ${imp_release} ${loc} ${loc_debug} ${loc_release})
+                if (tmp AND tmp MATCHES ".+dll")
+                    set_copy_command(deps-copy ${tmp} ${run})
+                endif()
+            endforeach()
         endif()
     endif()
 endfunction()
 
 function(wi_install_import)
-    cmake_parse_arguments(ii "" "RUNTIME;LIBRARY" "TARGETS" ${ARGN})
+    cmake_parse_arguments(ii "" "RUNTIME" "TARGETS" ${ARGN})
     if (NOT ii_RUNTIME)
         if (INSTALL_BINDIR)
             set(runtime ${INSTALL_BINDIR})
@@ -83,19 +66,9 @@ function(wi_install_import)
         set(runtime ${ii_RUNTIME})
     endif()
 
-    if (NOT ii_LIBRARY)
-        if (INSTALL_LIBRARY)
-            set(library ${INSTALL_LIBRARY})
-        else()
-            set(library ${CMAKE_INSTALL_LIBDIR})
-        endif()
-    else()
-        set(library ${ii_LIBRARY})
-    endif()
-
     set(targets ${ii_TARGETS})
     foreach(tgt IN LISTS targets) # 不需要 ${}
-        _wi_install_import_inline(${tgt} ${runtime} ${library})
-        _wi_build_import_inline(${tgt} ${runtime} ${library})
+        _wi_install_import_inline(${tgt} ${runtime})
+        _wi_build_import_inline(${tgt} ${runtime})
     endforeach()
 endfunction()

+ 1 - 1
include/runtime/rt-inter.h

@@ -4,7 +4,7 @@
 #include "aFuncore.h"
 
 namespace aFunrt {
-    class aFunEnvironment : public aFuncore::Environment {
+    class AFUN_LANG_EXPORT aFunEnvironment : public aFuncore::Environment {
     public:
         explicit aFunEnvironment(int argc = 0, char **argv = nullptr);
     };

+ 8 - 0
src/__main.h

@@ -3,7 +3,15 @@
 #include "aFunrt.h"
 #include "fflags.h"
 
+namespace aFun {
+    using namespace aFuntool;
+    using namespace aFuncore;
+    using namespace aFunrt;
+};
+
 void printError(ff_FFlags *ff);
+void printParserError(aFun::Parser &parser, const aFun::FilePath &file);
+void progressInterEvent(aFun::Inter &inter);
 
 extern std::string program_name;
 extern std::string home_path;

+ 8 - 18
src/main-help.cpp

@@ -1,31 +1,21 @@
 #include "__main.h"
 
-/*
- * 函数名: printError
- * 目标: 打印参数错误信息
- */
-void printError(ff_FFlags *ff) {
-    errorLog(aFunrt::aFunLogger, "%s argument error", ff_getChild(ff));
-    aFuntool::cout << "Command line argument error (" << ff_getChild(ff) << ")\n";
-    printHelp();
-}
-
 void printVersion() {
     /* Version的显示不被翻译, 因为它通常还需要被其他程序读取而进行处理, 必须保证一致性 */
-    aFuntool::cout << "aFunlang at      " << program_name << "\n";
-    aFuntool::cout << "aFunlang home at " << home_path << "\n";
-    aFuntool::cout << "version: " aFunVersion "\n";
-    aFuntool::cout << aFunDescription "\n";
+    aFun::cout << "aFunlang at      " << program_name << "\n";
+    aFun::cout << "aFunlang home at " << home_path << "\n";
+    aFun::cout << "version: " aFunVersion "\n";
+    aFun::cout << aFunDescription "\n";
 }
 
 void printWelcomeInfo() {
-    aFuntool::cout << "aFunlang " aFunVersion " CommandLine (" __DATE__ ", " __TIME__ ")\n";
-    aFuntool::cout << "[" compilerID "] on " systemName "\n";
-    aFuntool::cout << "(Enter the aFun code to run in the top activity)\n";
+    aFun::cout << "aFunlang " aFunVersion " CommandLine (" __DATE__ ", " __TIME__ ")\n";
+    aFun::cout << "[" compilerID "] on " systemName "\n";
+    aFun::cout << "(Enter the aFun code to run in the top activity)\n";
 }
 
 void printHelp() {
-    aFuntool::cout << "aFunlang Usage:\n";
+    aFun::cout << "aFunlang Usage:\n";
 }
 
 int mainHelp(ff_FFlags *ff) {

+ 57 - 2
src/main-run.cpp

@@ -1,5 +1,60 @@
 #include "__main.h"
+#include <thread>
+#include <mutex>
+
+static void runCodeThread(aFun::Inter &inter, aFun::Code &code, std::mutex &mutex, bool &is_end) {
+    try {
+        inter.runCode(code);
+    } catch (std::exception &e) {
+        errorLog(aFun::aFunLogger, "Exception not catch: %s", e.what());
+    }
+
+    std::unique_lock<std::mutex> lock{mutex};
+    is_end = true;
+}
+
+static int runCode(aFun::Code &code, aFun::aFunEnvironment &env, aFun::Inter &inter, int argc, char **argv) {
+    std::mutex mutex;
+    bool is_end = false;
+    auto thread = std::thread(runCodeThread, std::ref(inter), std::ref(code), std::ref(mutex), std::ref(is_end));
+
+    while (true) {
+        {
+            std::unique_lock<std::mutex> lock{mutex};
+            if (is_end)
+                break;
+        }
+        progressInterEvent(inter);
+    }
+
+    thread.join();
+    progressInterEvent(inter);
+    int exit_code = 0;
+    inter.getEnvVarSpace().findNumber("sys:exit-code", exit_code);
+    return exit_code;
+}
 
 int mainRun(ff_FFlags *ff) {
-    return 0;
-}
+    char **argv = nullptr;
+    int argc = ff_get_process_argv(&argv, ff);
+
+    if (argc == 0) {
+        return 0;
+    } else {
+        try {
+            auto reader = aFun::FileReader(argv[0]);
+            auto parser = aFun::Parser(reader);
+            auto code = aFun::Code(argv[0]);
+            bool ret = parser.parserCode(code);
+            printParserError(parser, argv[0]);
+            if (!ret)
+                return EXIT_FAILURE;
+            auto env = aFun::aFunEnvironment(argc - 1, argv + 1);
+            auto inter = aFun::Inter(env);
+            return runCode(code, env, inter, argc, argv);
+        } catch (aFun::readerFileOpenError &e) {
+            aFun::cout << "Cannot open file: " << argv[0] << "\n";
+            return EXIT_FAILURE;
+        }
+    }
+}

+ 85 - 0
src/main-tool.cpp

@@ -0,0 +1,85 @@
+#include "__main.h"
+
+/*
+ * 函数名: printError
+ * 目标: 打印参数错误信息
+ */
+void printError(ff_FFlags *ff) {
+    errorLog(aFun::aFunLogger, "%s argument error", ff_getChild(ff));
+    aFun::cout << "Command line argument error (" << ff_getChild(ff) << ")\n";
+    printHelp();
+}
+
+void printParserError(aFun::Parser &parser, const aFun::FilePath &file) {
+    while (parser.countEvent() != 0) {
+        auto event = parser.popEvent();
+        switch (event.type) {
+            case aFun::Parser::ParserEvent::lexical_error_char:
+                aFun::cout << "ERROR: Parser find an error character.";
+                break;
+            case aFun::Parser::ParserEvent::lexical_error_element_end:
+                aFun::cout << "ERROR: Long element without end.";
+                break;
+            case aFun::Parser::ParserEvent::syntactic_error_nested_too_deep:
+                aFun::cout << "ERROR: Nested too deep.";
+                break;
+            case aFun::Parser::ParserEvent::syntactic_error_block_p_end:
+                aFun::cout << "ERROR: '(' without end.";
+                break;
+            case aFun::Parser::ParserEvent::syntactic_error_block_b_end:
+                aFun::cout << "ERROR: '[' without end.";
+                break;
+            case aFun::Parser::ParserEvent::syntactic_error_block_c_end:
+                aFun::cout << "ERROR: '{' without end.";
+                break;
+            case aFun::Parser::ParserEvent::syntactic_error_prefix:
+                aFun::cout << "ERROR: Parser find an error prefix character.";
+                break;
+            case aFun::Parser::ParserEvent::reader_error:
+                aFun::cout << "ERROR: Reader error.";
+                break;
+            case aFun::Parser::ParserEvent::lexical_warning_comment_end:
+                aFun::cout << "WARNING: Comment without end.";
+                break;
+            case aFun::Parser::ParserEvent::parser_error_unknown:
+            default:
+                aFun::cout << "ERROR: Parser sends unknown error.";
+                break;
+        }
+        aFun::cout << " (At " << file << ":" << event.line << ")\n";
+    }
+}
+
+static void printMessage(const std::string &type, aFun::Message *msg, aFun::Inter &inter) {
+    if (type == "NORMAL") {
+        auto *msg_ = dynamic_cast<aFun::NormalMessage *>(msg);
+        if (msg_ == nullptr)
+            return;
+        aFun::cout << "Inter result: " << msg_->getObject() <<"\n";
+    } else if (type == "ERROR") {
+        auto *msg_ = dynamic_cast<aFun::ErrorMessage *>(msg);
+        if (msg_ == nullptr)
+            return;
+        int32_t error_std = 0;
+        inter.getEnvVarSpace().findNumber("sys:error_std", error_std);
+        if (error_std == 0) {
+            aFuntool::printf_stderr(0, "Error TrackBack\n");
+            for (auto &begin: msg_->getTrackBack())
+                aFuntool::printf_stderr(0, "  File \"%s\", line %d\n", begin.path.c_str(), begin.line);
+            aFuntool::printf_stderr(0, "%s: %s\n", msg_->getErrorType().c_str(), msg_->getErrorInfo().c_str());
+        } else {
+            aFuntool::printf_stdout(0, "Error TrackBack\n");
+            for (auto &begin: msg_->getTrackBack())
+                aFuntool::printf_stdout(0, "  File \"%s\", line %d\n", begin.path.c_str(), begin.line);
+            aFuntool::printf_stdout(0, "%s: %s\n", msg_->getErrorType().c_str(), msg_->getErrorInfo().c_str());
+        }
+    }
+}
+
+void progressInterEvent(aFun::Inter &inter) {
+    std::string type;
+    for (auto msg = inter.getOutMessageStream().popFrontMessage(type); msg != nullptr; msg = inter.getOutMessageStream().popFrontMessage(type)) {
+        printMessage(type, msg, inter);
+        delete msg;
+    }
+}

+ 15 - 15
src/main.cpp

@@ -14,10 +14,10 @@ char **argv_s = nullptr;
 
 static void convertArgs(int argc, char *argv_ansi[]) {
     argc_s = argc;
-    argv_s = aFuntool::safeCalloc<char *>((size_t)argc);
+    argv_s = aFun::safeCalloc<char *>((size_t)argc);
     for(int i = 0; i < argc; i++) {
-        if (aFuntool::convertMultiByte(argv_s + i, argv_ansi[i], CP_ACP, CP_UTF8) == 0) {
-            aFuntool::cerr << "Argument conversion error";
+        if (aFun::convertMultiByte(argv_s + i, argv_ansi[i], CP_ACP, CP_UTF8) == 0) {
+            aFun::cerr << "Argument conversion error";
             exit(EXIT_FAILURE);
         }
     }
@@ -31,36 +31,36 @@ static void convertArgsFree(void *) {
 
 int main(int argc, char **argv_ansi) {
     convertArgs(argc, argv_ansi);
-    aFuntool::aFunAtExit(convertArgsFree, nullptr);
+    aFun::aFunAtExit(convertArgsFree, nullptr);
 
     char **argv = argv_s;
 #else
     int main(int argc, char **argv) {
 #endif
     tty_stdin = isatty(fileno(stdin));
-    home_path = aFuntool::getExedir(1);
+    home_path = aFun::getExedir(1);
     if (home_path.empty()) {
-        aFuntool::cerr << "aFunlang init error.";
+        aFun::cerr << "aFunlang init error.";
         exit(EXIT_FAILURE);
     }
 
     try {
-        aFuntool::LogFactory factor{};
-        factor.initLogSystem(home_path + aFuntool::SEP + "aFunlog");
+        aFun::LogFactory factor{};
+        factor.initLogSystem(home_path + aFun::SEP + "aFunlog");
 
 #ifdef aFunDEBUG
-        aFunrt::aFunInitInfo info{home_path, factor, true, aFuntool::log_debug, aFuntool::log_debug};
+        aFun::aFunInitInfo info{home_path, factor, true, aFun::log_debug, aFun::log_debug};
 #else
-        aFunrt::aFunInitInfo info{base_path, factor, true, aFuntool::log_info, aFuntool::log_info};
+        aFun::aFunInitInfo info{base_path, factor, true, aFun::log_info, aFun::log_info};
 #endif
 
         ff_FFlags *ff = ff_initFFlags(argc, argv, true, false, stderr, aFunlang_exe);
         if (ff == nullptr)
-            aFuntool::aFunExit(EXIT_FAILURE);
+            aFun::aFunExit(EXIT_FAILURE);
 
         if (!aFunInit(&info)) {
-            aFuntool::cerr << "aFunlang init error.";
-            aFuntool::aFunExit(EXIT_FAILURE);
+            aFun::cerr << "aFunlang init error.";
+            aFun::aFunExit(EXIT_FAILURE);
         }
 
         int exit_code = EXIT_SUCCESS;
@@ -77,8 +77,8 @@ int main(int argc, char **argv_ansi) {
             exit_code = mainHelp(ff);
 
         ff_freeFFlags(ff);
-        aFuntool::aFunExit(exit_code);
-    } catch (aFuntool::Exit &e) {
+        aFun::aFunExit(exit_code);
+    } catch (aFun::Exit &e) {
         return e.getExitCode();
     }
 }

+ 2 - 2
test/bytecode/test1.aun

@@ -1,2 +1,2 @@
-global
-{str,}
+{import aFun-1.0}
+{exit}

+ 16 - 16
test/src/run-code.cpp

@@ -4,7 +4,7 @@ using namespace aFunrt;
 using namespace aFuncore;
 using namespace aFuntool;
 
-void printInterEvent(Inter &inter);
+static void progressInterEvent(Inter &inter);
 
 class Func1 : public Function {
     class CallFunc1 : public CallFunction {
@@ -60,7 +60,7 @@ public:
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_p,
                                                        new Code::ByteCode(code, "test-var", 1), 0));
         gc_inter.runCode(code);
-        printInterEvent(gc_inter);
+        progressInterEvent(gc_inter);
     };
 };
 
@@ -124,7 +124,7 @@ static void printMessage(const std::string &type, Message *msg, Inter &inter) {
     }
 }
 
-void printInterEvent(Inter &inter) {
+static void progressInterEvent(Inter &inter) {
     std::string type;
     for (auto msg = inter.getOutMessageStream().popFrontMessage(type); msg != nullptr; msg = inter.getOutMessageStream().popFrontMessage(type)) {
         printMessage(type, msg, inter);
@@ -132,12 +132,12 @@ void printInterEvent(Inter &inter) {
     }
 }
 
-void thread_test(Inter &son) {
+static void thread_test(Inter &son) {
     auto code = Code("run-code.aun");
     code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_p,
                                                    new Code::ByteCode(code, "test-var", 1), 0));
     son.runCode(code);
-    printInterEvent(son);
+    progressInterEvent(son);
     fputs_stdout("\n");
 }
 
@@ -184,7 +184,7 @@ int Main() {
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_p,
                                                        new Code::ByteCode(code, "test-var", 1), 0));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -198,7 +198,7 @@ int Main() {
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_c, arg, 0));
 
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -211,7 +211,7 @@ int Main() {
 
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_b, arg, 0));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -221,7 +221,7 @@ int Main() {
         auto code = Code("run-code.aun");
         code.getByteCode()->connect(new Code::ByteCode(code, "data4", 1));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -230,14 +230,14 @@ int Main() {
         auto code = Code("run-code.aun");
         code.getByteCode()->connect(new Code::ByteCode(code, "test-cbv", 1));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
     {
         fputs_stdout("Test-6: run-function\n");
         inter.runCode(func);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -251,7 +251,7 @@ int Main() {
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_c, arg, 0));
 
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -266,7 +266,7 @@ int Main() {
             code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_p,
                                                            new Code::ByteCode(code, "test-var", 1), 0));
             inter.runCode(code);
-            printInterEvent(inter);
+            progressInterEvent(inter);
             fputs_stdout("\n");
         }
 
@@ -279,7 +279,7 @@ int Main() {
         auto code = Code("run-code.aun");
         code.getByteCode()->connect(new Code::ByteCode(code, "test-not-var", 1));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -289,7 +289,7 @@ int Main() {
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_c,
                                                        new Code::ByteCode(code, "exit", 1), 0));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
         fputs_stdout("\n");
     }
 
@@ -298,7 +298,7 @@ int Main() {
         code.getByteCode()->connect(new Code::ByteCode(code, Code::ByteCode::block_p,
                                                        new Code::ByteCode(code, "test-var", 1), 0));
         inter.runCode(code);
-        printInterEvent(inter);
+        progressInterEvent(inter);
     }
 
     return 0;