From 46b29fc229c3a6de191fbef80245b31b711171b5 Mon Sep 17 00:00:00 2001 From: VaclavT Date: Sun, 28 Feb 2021 12:53:06 +0100 Subject: [PATCH] string pad/rpad/lpad --- Readme.md | 5 +++++ debug.lsp | 27 +++------------------------ doc/Doc.md | 1 + ml.cpp | 13 ++++++++++++- ml_string.cpp | 18 ++++++++++++++++-- ml_string.h | 3 ++- stdlib/stdlib.lsp | 10 ++++++++++ 7 files changed, 49 insertions(+), 28 deletions(-) diff --git a/Readme.md b/Readme.md index f5ce727..cd60a1f 100644 --- a/Readme.md +++ b/Readme.md @@ -46,6 +46,11 @@ #### Performance - push_back - repeatedly without reserving size +#### Install +``` +cp build/ml /usr/local/bin/ml +cp stdlib/stdlib.lsp /usr/local/var/mlisp/stdlib.lsp +``` ### Example of use diff --git a/debug.lsp b/debug.lsp index 6ce1e7c..887b0b5 100644 --- a/debug.lsp +++ b/debug.lsp @@ -18,31 +18,10 @@ ;; (print (member '(1 2 3) 10)) -(define csv_list '()) -(for f (ls-dir "tests/divi") - (if (regex-search? f "^divi.*\.csv$") - (do - (define filename (+ "tests/divi/" f)) - ; (print filename) - (define csv_str (read-file filename)) - (define csv_file_list (parse-csv csv_str)) - (define csv_list (+ csv_list csv_file_list)) - ) - )) -;; (for x csv_list (print x)) +(print (string-rpad "rpad0123456789" 10 "x")) +(print (string-rpad "rpad " 10 "x")) -(print (len csv_list)) - -(define my_tickers '("FDX" "C" "AIG" "BAC" "BK" "PBF" "PBFX" "SYF" "WFC" "TEVA" "XOM")) - -; (print (filter (lambda (x) (= (first x) "CLX")) csv_list)) -; (print (filter (lambda (x) (member my_tickers (first x))) csv_list)) -(define csv_list (filter (lambda (x) (member my_tickers (first x))) csv_list)) - - -(define sorted_list (quick-sort-by csv_list (lambda (a b) (> (str-to-date (second a) "%m/%d/%Y") (str-to-date (second b) "%m/%d/%Y"))))) - -(for x csv_list (print x)) +(print (string-lpad "lpad" 10 "x")) (print "Debug ends") diff --git a/doc/Doc.md b/doc/Doc.md index ba130c0..a6eb331 100644 --- a/doc/Doc.md +++ b/doc/Doc.md @@ -68,6 +68,7 @@ |`(display ..)`||| |`(replace ..)`||| |`(regex-search? ..)`||| +|`(string-pad str len char rpad_lpad)`||| |`(int ..)`||| |`(float ..)`||| |`(eval ..)`||| diff --git a/ml.cpp b/ml.cpp index 0051a1c..0d13f9c 100644 --- a/ml.cpp +++ b/ml.cpp @@ -1496,11 +1496,21 @@ namespace builtin { eval_args(args, env); if (args.size() != 2) // if (args.size() < 2 || args.size() > 3) - throw MlError(MlValue("regex_search", regex_search), env, args.size() > 3 ? TOO_MANY_ARGS : TOO_FEW_ARGS); + throw MlError(MlValue("regex_search", regex_search), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS); return MlValue(regexp_search(args[0].as_string(), args[1].as_string())); } + MlValue string_pad(std::vector args, MlEnvironment &env) { + eval_args(args, env); + + if (args.size() != 4) + throw MlError(MlValue("regex_search", regex_search), env, args.size() > 4 ? TOO_MANY_ARGS : TOO_FEW_ARGS); + + // TODO validate len > 0 etc + return MlValue::string(string_padd(args[0].as_string(), args[1].as_int(), args[2].as_string()[0], (args[3].as_string()=="rpad"))); + } + MlValue display(std::vector args, MlEnvironment &env) { eval_args(args, env); @@ -1724,6 +1734,7 @@ MlValue MlEnvironment::get(const std::string &name) const { if (name == "display") return MlValue("display", builtin::display); if (name == "replace") return MlValue("replace", builtin::replace); if (name == "regex-search?") return MlValue("regex-search?", builtin::regex_search); + if (name == "string-pad") return MlValue("string-pad", builtin::string_pad); // Casting operations if (name == "int") return MlValue("int", builtin::cast_to_int); diff --git a/ml_string.cpp b/ml_string.cpp index 9bf542e..cc8ce88 100644 --- a/ml_string.cpp +++ b/ml_string.cpp @@ -2,7 +2,6 @@ #include "ml_string.h" - // Replace a substring with a replacement string in a source string void replace_substring(std::string &src, const std::string &substr, const std::string &replacement) { size_t i = 0; @@ -19,7 +18,7 @@ bool regexp_search(const std::string &where, const std::string ®ex_str) { std::regex regex(regex_str); std::smatch match; - if(std::regex_search(where, match, regex)) { + if (std::regex_search(where, match, regex)) { // std::cout << "matches for '" << where << "'\n"; // std::cout << "Prefix: '" << match.prefix() << "'\n"; // for (size_t i = 0; i < match.size(); ++i) @@ -30,3 +29,18 @@ bool regexp_search(const std::string &where, const std::string ®ex_str) { } return false; } + +std::string string_padd(const std::string &str, int pad_len, char fill_char, bool from_right) { + int str_len = str.length(); + + if (str_len == pad_len) + return str; + else if (str_len > pad_len) { + return (from_right ? str.substr(0, pad_len) : str.substr(str_len - pad_len, std::string::npos)); + } + + if (from_right) + return str + std::string(pad_len - str.size(), fill_char); + else + return std::string(pad_len - str.size(), fill_char) + str; +} diff --git a/ml_string.h b/ml_string.h index ce2ea70..6bdb454 100644 --- a/ml_string.h +++ b/ml_string.h @@ -6,9 +6,10 @@ #include #include - // Replace a substring with a replacement string in a source string void replace_substring(std::string &src, const std::string &substr, const std::string &replacement); // Returns true if where contains regex bool regexp_search(const std::string &where, const std::string ®ex_str); + +std::string string_padd(const std::string & str, int pad_len, char fill_char, bool from_right); \ No newline at end of file diff --git a/stdlib/stdlib.lsp b/stdlib/stdlib.lsp index a9be27e..528f12a 100644 --- a/stdlib/stdlib.lsp +++ b/stdlib/stdlib.lsp @@ -26,6 +26,16 @@ (defun inc (n) (+ n 1)) +; pad string on the end +(defun string-rpad (str length pad_char) + (string-pad str length pad_char "rpad")) + +; pad string on the begining +(defun string-lpad (str length pad_char) + (string-pad str length pad_char "lpad")) + + + ; return second element of list (defun second (l) (index l 1))