From 5315e58823c002440deb6455187e600e95c1de78 Mon Sep 17 00:00:00 2001 From: VaclavT Date: Tue, 9 Feb 2021 17:19:46 +0100 Subject: [PATCH] csv parser initial version --- .vscode/c_cpp_properties.json | 20 ++++++++++++++++++ CMakeLists.txt | 2 +- Readme.md | 3 ++- debug.lisp | 4 +++- ml.cpp | 38 +++++++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4a4d1df --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/**", + "${workspaceFolder}/stdlib" + ], + "defines": [], + "macFrameworkPath": [ + "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "c11", + "intelliSenseMode": "macos-clang-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fa6938..0f56f26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0.0) project(ml VERSION 0.1.0) -# set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) # set(CMAKE_CXX_STANDARD_REQUIRED ON) # set(CMAKE_CXX_EXTENSIONS OFF) # set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") diff --git a/Readme.md b/Readme.md index a140077..8c37d43 100644 --- a/Readme.md +++ b/Readme.md @@ -20,5 +20,6 @@ ### Example of use ``` -time ./ml -c '(include "../example.lisp") (print (fact 1000))' +time ./build/ml -c '(include "../example.lisp") (print (fact 1000))' +./build/ml -f debug.lisp ``` diff --git a/debug.lisp b/debug.lisp index 9328a60..b481db5 100644 --- a/debug.lisp +++ b/debug.lisp @@ -1,3 +1,5 @@ (print "Debug starts") -(read-file "tmp/data.csv") +(define csv (read-file "tmp/data.csv")) +(print csv) +(print (parse-csv csv)) (print "Debug ends") diff --git a/ml.cpp b/ml.cpp index b46c55c..1a17c0d 100644 --- a/ml.cpp +++ b/ml.cpp @@ -51,6 +51,8 @@ std::string read_file_contents(std::string filename) { #include #include +#include "csvparser.h" + //////////////////////////////////////////////////////////////////////////////// /// ERROR MESSAGES ///////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -89,7 +91,7 @@ std::string read_file_contents(std::string filename) { //////////////////////////////////////////////////////////////////////////////// // Convert an object to a string using a stringstream conveniently -#define to_string( x ) static_cast((std::ostringstream() << std::dec << x )).str() +#define to_string( x ) static_cast((std::ostringstream() << std::dec << x )).str() // Replace a substring with a replacement string in a source string void replace_substring(std::string &src, std::string substr, std::string replacement) { @@ -1189,6 +1191,38 @@ namespace builtin { return Value(rand()%(high-low+1) + low); } + // Get the contents of a file + Value parse_csv(std::vector args, Environment &env) { + eval_args(args, env); + + // TODO add support for more params specifying options + if (args.size() != 1) + throw Error(Value("read-csv", parse_csv), env, args.size() > 1? TOO_MANY_ARGS : TOO_FEW_ARGS); + + // PERF optimize it for memory usage and performance + CsvParser csv(true); + std::vector< std::vector > parsed_data; // TODO some default size here + csv.parseCSV(args[0].as_string(), parsed_data); + + int rows = parsed_data.size(); + int cols = rows > 0 ? parsed_data[0].size() : 0; + + std::vector result; + + if (rows > 0 && cols > 0) { + for (int r = 0; r < rows; r++) { + std::vector row; + for (int c = 0; c < cols; c++) { + std::string value = parsed_data[r][c]; + row.push_back(Value::string(value)); + } + result.push_back(row); + } + } + + return Value(result); + } + // Get the contents of a file Value read_file(std::vector args, Environment &env) { // Is not a special form, so we can evaluate our args. @@ -1197,7 +1231,6 @@ namespace builtin { if (args.size() != 1) throw Error(Value("read-file", read_file), env, args.size() > 1? TOO_MANY_ARGS : TOO_FEW_ARGS); - // return Value::string(content); return Value::string(read_file_contents(args[0].as_string())); } @@ -1736,6 +1769,7 @@ Value Environment::get(std::string name) const { if (name == "input") return Value("input", builtin::input); if (name == "random") return Value("random", builtin::random); if (name == "include") return Value("include", builtin::include); + if (name == "parse-csv") return Value("parse-csv", builtin::parse_csv); if (name == "read-file") return Value("read-file", builtin::read_file); if (name == "write-file") return Value("write-file", builtin::write_file); #endif