diff --git a/CMakeLists.txt b/CMakeLists.txt index 960fd271..e513476d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,5 @@ include_directories(dispatchkit langkit) add_subdirectory(langkit bin) add_subdirectory(dispatchkit bin) add_subdirectory(chaiscript bin) +add_subdirectory(chaioop bin) diff --git a/chaioop/CMakeLists.txt b/chaioop/CMakeLists.txt index df0e108d..1dc9c0ac 100644 --- a/chaioop/CMakeLists.txt +++ b/chaioop/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.6) project(chaioop) SET (CMAKE_BUILD_TYPE gdb) -SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb -O3") -SET (CMAKE_CXX_FLAGS_GDB " -Wall -ggdb -O3") +SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb") +SET (CMAKE_CXX_FLAGS_GDB " -Wall -ggdb") include_directories(../langkit ../dispatchkit) diff --git a/chaioop/main.cpp b/chaioop/main.cpp index 5c23be99..20bd0808 100644 --- a/chaioop/main.cpp +++ b/chaioop/main.cpp @@ -7,6 +7,27 @@ #include namespace langkit { + struct File_Position { + int line; + int column; + const char *filename; + + File_Position(int file_line, int file_column, const char *file_name) + : line(file_line), column(file_column), filename(file_name) { } + + File_Position() : line(0), column(0), filename(NULL) { } + }; + + struct Parse_Error { + std::string reason; + File_Position position; + + Parse_Error(const std::string &why, const File_Position &where) : + reason(why), position(where) { } + + virtual ~Parse_Error() throw() {} + }; + class Token { std::string text; @@ -15,14 +36,85 @@ namespace langkit { class Parser { std::string::iterator input_pos, input_end; + int line, col; + std::string multiline_comment_begin, multiline_comment_end; + std::string singleline_comment; public: - bool Int() { + bool SkipComment() { + bool retval = false; + + if (Str_(multiline_comment_begin.c_str())) { + while (input_pos != input_end) { + if (Str_(multiline_comment_end.c_str())) { + break; + } + else if (!Eol_()) { + ++col; + ++input_pos; + } + } + retval = true; + } + else if (Str_(singleline_comment.c_str())) { + while (input_pos != input_end) { + if (Eol_()) { + break; + } + else { + ++col; + ++input_pos; + } + } + retval = true; + } + return retval; + } + + bool SkipWS() { + bool retval = false; + while (input_pos != input_end) { + if ((*input_pos == ' ') || (*input_pos == '\t')) { + ++input_pos; + ++col; + retval = true; + } + else if (SkipComment()) { + retval = true; + } + else { + break; + } + } + return retval; + } + + bool Int_() { bool retval = false; if ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) { retval = true; while ((input_pos != input_end) && (*input_pos >= '0') && (*input_pos <= '9')) { ++input_pos; + ++col; + } + } + + return retval; + } + + bool Int() { + SkipWS(); + + return Int_(); + } + + bool Id_() { + bool retval = false; + if ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) { + retval = true; + while ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) { + ++input_pos; + ++col; } } @@ -30,28 +122,29 @@ namespace langkit { } bool Id() { + SkipWS(); + + return Id_(); + } + + bool Char_(char c) { bool retval = false; - if ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) { + if ((input_pos != input_end) && (*input_pos == c)) { + ++input_pos; + ++col; retval = true; - while ((input_pos != input_end) && (((*input_pos >= 'A') && (*input_pos <= 'Z')) || ((*input_pos >= 'a') && (*input_pos <= 'z')))) { - ++input_pos; - } } return retval; } bool Char(char c) { - bool retval = false; - if ((input_pos != input_end) && (*input_pos == c)) { - ++input_pos; - retval = true; - } + SkipWS(); - return retval; + return Char_(c); } - bool Str(const char *s) { + bool Str_(const char *s) { bool retval = false; int len = strlen(s); @@ -61,18 +154,46 @@ namespace langkit { if (*tmp != s[i]) { return false; } + ++tmp; } retval = true; input_pos = tmp; + col += len; } return retval; } + bool Str(const char *s) { + SkipWS(); + return Str_(s); + } + + bool Eol_() { + bool retval = false; + + if ((input_pos != input_end) && (Str_("\r\n") || Char_('\n'))) { + retval = true; + ++line; + col = 1; + } + + return retval; + } + + bool Eol() { + SkipWS(); + + return Eol_(); + } + bool Arg_List() { bool retval = Id() || Int(); while (retval && Char(',')) { retval = Id() || Int(); + if (!retval) { + throw Parse_Error("Unexpected value in parameter list", File_Position(line, col, "_INPUT_")); + } } return retval; } @@ -81,6 +202,8 @@ namespace langkit { bool retval = false; std::string::iterator prev = input_pos; + int prev_line = line; + int prev_col = col; if (Id() && Char('(')) { @@ -88,16 +211,10 @@ namespace langkit { retval = Char(')'); } - if (!retval) { input_pos = prev; } - - return retval; - } - - bool Eol() { - bool retval = false; - - if ((input_pos != input_end) && (Str("\r\n") || Char('\n'))) { - retval = true; + if (!retval) { + input_pos = prev; + prev_line = line; + prev_col = col; } return retval; @@ -117,6 +234,10 @@ namespace langkit { bool parse(std::string input) { input_pos = input.begin(); input_end = input.end(); + line = 1; col = 1; + multiline_comment_begin = "/*"; + multiline_comment_end = "*/"; + singleline_comment = "//"; return Fun_Calls(); } @@ -144,9 +265,29 @@ std::string load_file(const char *filename) { int main(int argc, char *argv[]) { langkit::Parser parser; + std::string input; if (argc > 1) { - std::cout << parser.parse(load_file(argv[1])) << std::endl; + try { + std::cout << parser.parse(load_file(argv[1])) << std::endl; + } + catch (langkit::Parse_Error &pe) { + std::cout << pe.reason << " at " << pe.position.line << ", " << pe.position.column << std::endl; + } + } + else { + std::cout << "eval> "; + std::getline(std::cin, input); + while (input != "quit") { + try { + std::cout << parser.parse(input) << std::endl; + } + catch (langkit::Parse_Error &pe) { + std::cout << pe.reason << " at " << pe.position.line << ", " << pe.position.column << std::endl; + } + std::cout << "eval> "; + std::getline(std::cin, input); + } } return 0; diff --git a/chaiscript/CMakeLists.txt b/chaiscript/CMakeLists.txt index 82dbc263..066ac5de 100644 --- a/chaiscript/CMakeLists.txt +++ b/chaiscript/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.6) enable_testing() -project(wesley) +project(chaiscript) SET (CMAKE_BUILD_TYPE gdb) SET (CMAKE_C_FLAGS_GDB " -Wall -ggdb") @@ -15,11 +15,11 @@ if(Boost_FOUND) add_executable(chaiscript_test main.cpp) target_link_libraries(chaiscript_test ${Boost_LIBRARIES}) - add_executable(chaiscript_callbacktest callbacktest.cpp) - target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES}) + add_executable(chaiscript_callbacktest callbacktest.cpp) + target_link_libraries(chaiscript_callbacktest ${Boost_LIBRARIES}) - add_executable(sensors sensors.cpp) - target_link_libraries(sensors ${Boost_LIBRARIES}) + add_executable(sensors sensors.cpp) + target_link_libraries(sensors ${Boost_LIBRARIES}) endif() diff --git a/chaiscript/main.cpp b/chaiscript/main.cpp index 9b99a85c..e08c065d 100644 --- a/chaiscript/main.cpp +++ b/chaiscript/main.cpp @@ -18,11 +18,11 @@ int main(int argc, char *argv[]) { if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) { try { - dispatchkit::Boxed_Value printeval - = dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"), + dispatchkit::Boxed_Value printeval + = dispatchkit::dispatch(chai.get_eval_engine().get_function("to_string"), dispatchkit::Param_List_Builder() << val); std::cout << "result: "; - dispatchkit::dispatch(chai.get_eval_engine().get_function("print"), + dispatchkit::dispatch(chai.get_eval_engine().get_function("print"), dispatchkit::Param_List_Builder() << printeval); } catch (const std::runtime_error &e) { std::cout << "result: object #" << &val << std::endl; diff --git a/dispatchkit/CMakeLists.txt b/dispatchkit/CMakeLists.txt index 3d2db848..b2cf357d 100644 --- a/dispatchkit/CMakeLists.txt +++ b/dispatchkit/CMakeLists.txt @@ -12,11 +12,11 @@ if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) include_directories(.) - add_executable(dispatchkit_test test.cpp) + add_executable(dispatchkit_test test.cpp) - add_executable(dispatchkit_unittest unittest.cpp) + add_executable(dispatchkit_unittest unittest.cpp) - target_link_libraries(dispatchkit_unittest ${Boost_LIBRARIES}) + target_link_libraries(dispatchkit_unittest ${Boost_LIBRARIES}) endif() diff --git a/langkit/CMakeLists.txt b/langkit/CMakeLists.txt index 9fb8abfd..3eabd68c 100644 --- a/langkit/CMakeLists.txt +++ b/langkit/CMakeLists.txt @@ -11,11 +11,11 @@ find_package( Boost 1.36.0 COMPONENTS regex unit_test_framework) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) - add_executable(langkit_test main.cpp) - target_link_libraries(langkit_test ${Boost_LIBRARIES}) + add_executable(langkit_test main.cpp) + target_link_libraries(langkit_test ${Boost_LIBRARIES}) - add_executable(langkit_unittest unittest.cpp) - target_link_libraries(langkit_unittest ${Boost_LIBRARIES}) + add_executable(langkit_unittest unittest.cpp) + target_link_libraries(langkit_unittest ${Boost_LIBRARIES}) endif() add_test(langkit_unittest ${EXECUTABLE_OUTPUT_PATH}/langkit_unittest)