new functions, doc updates

This commit is contained in:
vaclavt 2022-02-25 00:04:14 +01:00
parent c16b062267
commit 0f184461fe
5 changed files with 70 additions and 17 deletions

View File

@ -80,10 +80,8 @@ utils/local_install.sh
- better output of !e in repl (resp !e !ee) - better output of !e in repl (resp !e !ee)
#### Doc #### Doc
- fix an error in printing multiline examples in doc - string-case, make-csv fix doc
- string-case, save-csv fix doc
- add functions from stdlib into doc - add functions from stdlib into doc
- fix man entry on (member) example and retval
- doc for set! - doc for set!
#### Code #### Code
@ -95,9 +93,6 @@ utils/local_install.sh
- string functions - string functions
- compare - needed for sorting, cmp ignore case - compare - needed for sorting, cmp ignore case
- regexp match, regexp tokens - regexp match, regexp tokens
- env functions
- get-env, set-env; set-env cannot be implemented in stdlib.lsp, because popen is in fact subshell
- macros and then loop, let etc
#### Performance #### Performance
- push_back - repeatedly without reserving size - push_back - repeatedly without reserving size

View File

@ -65,7 +65,7 @@
|`(first list)`|Returns first element of a list|`>>> (first '(1 2 3)) => 1`|List manipulation| |`(first list)`|Returns first element of a list|`>>> (first '(1 2 3)) => 1`|List manipulation|
|`(last list)`|Returns last element of list|`>>> (last '(1 2 3)) => 2`|List manipulation| |`(last list)`|Returns last element of list|`>>> (last '(1 2 3)) => 2`|List manipulation|
|`(range low high)`|Returns list with elements in range low .. high|`(range 1 5) => (1 2 3 4)`|List manipulation| |`(range low high)`|Returns list with elements in range low .. high|`(range 1 5) => (1 2 3 4)`|List manipulation|
|`(member lst item)`|Returns #t when item is inluded in lst otherwise nil||List manipulation| |`(member lst item)`|Returns #t when item is inluded in lst otherwise nil|`>>> (member '(1 2 3) 1) => #t`|List manipulation|
|`(uniq list)`|Filter out any duplicates from list|`>>> (uniq '(1 2 2 3 4 5 2 2)) => (1 2 3 4 5)`|List manipulation| |`(uniq list)`|Filter out any duplicates from list|`>>> (uniq '(1 2 2 3 4 5 2 2)) => (1 2 3 4 5)`|List manipulation|
|`(flatten list)`|Flattens a list to single level|`>>> (flatten '(1 (2 2) 3)) => (1 2 2 3)`|List manipulation| |`(flatten list)`|Flattens a list to single level|`>>> (flatten '(1 (2 2) 3)) => (1 2 2 3)`|List manipulation|
|`(take list count)`|Returns sublist with count element of list|`>>> (take '(1 2 3 4) 3) => (1 2 3)`|List manipulation| |`(take list count)`|Returns sublist with count element of list|`>>> (take '(1 2 3 4) 3) => (1 2 3)`|List manipulation|
@ -83,6 +83,8 @@
|`(input [prompt])`|Get user input with an optional prompt||IO| |`(input [prompt])`|Get user input with an optional prompt||IO|
|`(random low high)`|Get a random number between two numbers inclusively||System| |`(random low high)`|Get a random number between two numbers inclusively||System|
|`(include file)`|Read a file and execute its code||IO| |`(include file)`|Read a file and execute its code||IO|
|`(read)`|Reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object||IO|
|`(read-line)`|Reads in a line of text terminated by a newline||IO|
|`(read-file filename)`|Get the contents of a file||IO| |`(read-file filename)`|Get the contents of a file||IO|
|`(read-file-lines filename lambda)`|Reads file and for each line call lambda with passing the line as a parameter|`(read-file-lines "/tmp/f.txt" (lambda (ln) (print ln))`|IO| |`(read-file-lines filename lambda)`|Reads file and for each line call lambda with passing the line as a parameter|`(read-file-lines "/tmp/f.txt" (lambda (ln) (print ln))`|IO|
|`(write-file filename content-str)`|Write a string to a file||IO| |`(write-file filename content-str)`|Write a string to a file||IO|
@ -94,9 +96,9 @@
|`(tcp-server port handler)`|Starts listening on port and when request comes calls passed lambda and writes its returned value back to client. Lambda must return either string or two element list where first element is boolean and second string.When first element is true it closes listening socker.|(`tcp-server 7777 (lambda (str) (list #t (string-upcase str))))`|IO| |`(tcp-server port handler)`|Starts listening on port and when request comes calls passed lambda and writes its returned value back to client. Lambda must return either string or two element list where first element is boolean and second string.When first element is true it closes listening socker.|(`tcp-server 7777 (lambda (str) (list #t (string-upcase str))))`|IO|
|`(tcp-client address port data)`|Opens connection to server on port, writes there data and returns response.|`(print (tcp-client "127.0.0.1" 7777 "abcd"))`|IO| |`(tcp-client address port data)`|Opens connection to server on port, writes there data and returns response.|`(print (tcp-client "127.0.0.1" 7777 "abcd"))`|IO|
|`(is-dir? filename)`|Returns true if passed filename is a directory||IO| |`(is-dir? filename)`|Returns true if passed filename is a directory||IO|
|`(parse-csv string)`|Parse CSV string||String manipulation| |`(parse-csv string)`|Parse CSV string|`>>> (make-csv '(("A" "B")(1 1)(2 2))) => "A,B\n1,1\n2,2"`|String manipulation|
|`(parse-json json_string)`|Parse JSON string||String manipulation| |`(parse-json json_string)`|Parse JSON string||String manipulation|
|`(save-csv ..)`|Save list as csv||IO| |`(make-csv ..)`|Returns list as csv string||IO|
|`(get-universal-time)`|Get current time as secs from epoch|`>>> (get-universal-time) => 1642152733`|Date and time| |`(get-universal-time)`|Get current time as secs from epoch|`>>> (get-universal-time) => 1642152733`|Date and time|
|`(get-localtime-offset)`|Offset in seconds between local time and gmt time||Date and time| |`(get-localtime-offset)`|Offset in seconds between local time and gmt time||Date and time|
|`(date-to-str date format)`|Converts date to formated string. Format is strftime format (https://www.tutorialspoint.com/c_standard_library/c_function_strftime.htm)|`>>> (date-to-str (get-universal-time) "%Y-%m-%d %H:%M:%S") => "2021-03-13 19:53:01"`|Date and time| |`(date-to-str date format)`|Converts date to formated string. Format is strftime format (https://www.tutorialspoint.com/c_standard_library/c_function_strftime.htm)|`>>> (date-to-str (get-universal-time) "%Y-%m-%d %H:%M:%S") => "2021-03-13 19:53:01"`|Date and time|
@ -165,6 +167,7 @@
|`(doc::look "string")`|Alias for appropos||Language| |`(doc::look "string")`|Alias for appropos||Language|
|`(doc::lookup "string")`|Alias for appropos||Language| |`(doc::lookup "string")`|Alias for appropos||Language|
|`(get-env var)`|Return environment variable var|`>>> (get-env "HOME") => "/Users/vaclavt"`|System| |`(get-env var)`|Return environment variable var|`>>> (get-env "HOME") => "/Users/vaclavt"`|System|
|`(set-env var value)`|Sets environment variable var to value|`>>> (set-env "XXYYZZ" "haha") => "haha"`|System|
|`(second list)`|Returns second element of list|`>>> (second '(1 2 3 4 5 6 7)) => 2`|List manipulation| |`(second list)`|Returns second element of list|`>>> (second '(1 2 3 4 5 6 7)) => 2`|List manipulation|
|`(third list)`|Returns third element of list|`>>> (third '(1 2 3 4 5 6 7)) => 3`|List manipulation| |`(third list)`|Returns third element of list|`>>> (third '(1 2 3 4 5 6 7)) => 3`|List manipulation|
|`(fourth list)`|Returns fourth element of list|`>>> (fourth '(1 2 3 4 5 6 7)) => 4`|List manipulation| |`(fourth list)`|Returns fourth element of list|`>>> (fourth '(1 2 3 4 5 6 7)) => 4`|List manipulation|

55
ml.cpp
View File

@ -1153,6 +1153,30 @@ MlValue parse_csv(std::vector<MlValue> args, MlEnvironment &env) {
return csv.parseCSV(args[0].as_string()); return csv.parseCSV(args[0].as_string());
} }
// Reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object
MlValue read(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 0)
throw MlError(MlValue("read", read), env, TOO_MANY_ARGS);
std::string line;
std::getline(std::cin, line);
return run(line, env);
}
// Read line from stdin
MlValue read_line(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 0)
throw MlError(MlValue("read-line", read_line), env, TOO_MANY_ARGS);
std::string line;
std::getline(std::cin, line);
return MlValue::string(line);
}
// Get the contents of a file // Get the contents of a file
MlValue read_file(std::vector<MlValue> args, MlEnvironment &env) { MlValue read_file(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@ -1346,6 +1370,7 @@ MlValue is_dir(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue(is_path_dir(args[0].as_string())); return MlValue(is_path_dir(args[0].as_string()));
} }
// starts tcp listening server
MlValue tcp_server(std::vector<MlValue> args, MlEnvironment &env) { MlValue tcp_server(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@ -1369,6 +1394,7 @@ MlValue tcp_server(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue((long)r); return MlValue((long)r);
} }
// tcp client
MlValue tcp_client(std::vector<MlValue> args, MlEnvironment &env) { MlValue tcp_client(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@ -1389,6 +1415,31 @@ MlValue tcp_client(std::vector<MlValue> args, MlEnvironment &env) {
} }
} }
// get environment variable
MlValue get_env(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 1)
throw MlError(MlValue("get-env", get_env), env, args.size() > 1 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
if (const char* env_p = std::getenv(args[0].as_string().c_str()))
return MlValue::string(env_p);
else
return MlValue::nil();
}
// set environment variable
MlValue set_env(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (args.size() != 2)
throw MlError(MlValue("set-env", set_env), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
setenv(args[0].as_string().c_str(), args[1].as_string().c_str(), true);
return args[1];
}
// Read a file and execute its code // Read a file and execute its code
MlValue include(std::vector<MlValue> args, MlEnvironment &env) { MlValue include(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@ -2160,6 +2211,8 @@ std::map <const std::string, Builtin> builtin_funcs
std::make_pair("input", builtin::input), std::make_pair("input", builtin::input),
std::make_pair("random", builtin::random), std::make_pair("random", builtin::random),
std::make_pair("include", builtin::include), std::make_pair("include", builtin::include),
std::make_pair("read", builtin::read),
std::make_pair("read-line", builtin::read_line),
std::make_pair("read-file", builtin::read_file), std::make_pair("read-file", builtin::read_file),
std::make_pair("read-file-lines", builtin::read_file_lines), std::make_pair("read-file-lines", builtin::read_file_lines),
std::make_pair("write-file", builtin::write_file), std::make_pair("write-file", builtin::write_file),
@ -2170,6 +2223,8 @@ std::map <const std::string, Builtin> builtin_funcs
std::make_pair("is-dir?", builtin::is_dir), std::make_pair("is-dir?", builtin::is_dir),
std::make_pair("tcp-server", builtin::tcp_server), std::make_pair("tcp-server", builtin::tcp_server),
std::make_pair("tcp-client", builtin::tcp_client), std::make_pair("tcp-client", builtin::tcp_client),
std::make_pair("get-env", builtin::get_env),
std::make_pair("set-env", builtin::set_env),
// parsing operations // parsing operations
std::make_pair("parse-csv", builtin::parse_csv), std::make_pair("parse-csv", builtin::parse_csv),

View File

@ -46,9 +46,6 @@
(defn sleep (time) (defn sleep (time)
(system-cmd (+ "sleep " (string time)))) (system-cmd (+ "sleep " (string time))))
(defn get-env (var)
(second (system-cmd (+ "echo ${" var "} | tr -d \"\n\""))))
(defn third (l) (index l 2)) (defn third (l) (index l 2))
(defn fourth (l) (index l 3)) (defn fourth (l) (index l 3))
@ -196,7 +193,7 @@
(def c 0) (def c 0)
(for col row (for col row
(if (= c 0) (if (= c 0)
(def cols_str col) (def cols_str (display col))
(def cols_str (+ cols_str "," (display col)))) (def cols_str (+ cols_str "," (display col))))
(def c (inc c))) (def c (inc c)))
(if (= r 0) (if (= r 0)

View File

@ -43,11 +43,11 @@
(ut::define-test "result of (def a 20) (cond ((> a 30)" '(ut::assert-equal "a <= 20" (cond ((> a 30) "a > 30") ((> a 20) "a > 20")(#t "a <= 20")))) (ut::define-test "result of (def a 20) (cond ((> a 30)" '(ut::assert-equal "a <= 20" (cond ((> a 30) "a > 30") ((> a 20) "a > 20")(#t "a <= 20"))))
(ut::define-test "result of (def b 30) (cond ((> b 30)" '(ut::assert-equal "b > 20" (cond ((> b 30) "b > 30") ((> b 20) "b > 20")(#t "b <= 20")))) (ut::define-test "result of (def b 30) (cond ((> b 30)" '(ut::assert-equal "b > 20" (cond ((> b 30) "b > 30") ((> b 20) "b > 20")(#t "b <= 20"))))
(ut::define-test "result of (member '(1 2 3) 1" '(ut::assert-true (member '(1 2 3) 1))) (ut::define-test "result of (member '(1 2 3) 1)" '(ut::assert-true (member '(1 2 3) 1)))
(ut::define-test "result of (member '(1 2 3) 3" '(ut::assert-true (member '(1 2 3) 3))) (ut::define-test "result of (member '(1 2 3) 3)" '(ut::assert-true (member '(1 2 3) 3)))
(ut::define-test "result of (member '(1 2 3) 4" '(ut::assert-false (member '(1 2 3) 4))) (ut::define-test "result of (member '(1 2 3) 4)" '(ut::assert-false (member '(1 2 3) 4)))
(ut::define-test "result of (take '(1 2 3 4) 3" '(ut::assert-equal '(1 2 3) (take '(1 2 3 4) 3))) (ut::define-test "result of (take '(1 2 3 4) 3)" '(ut::assert-equal '(1 2 3) (take '(1 2 3 4) 3)))
(ut::define-test "result of (make-list 3)" '(ut::assert-equal '(nil nil nil) (make-list 3))) (ut::define-test "result of (make-list 3)" '(ut::assert-equal '(nil nil nil) (make-list 3)))
(ut::define-test "result of (make-list-of 3 999)" '(ut::assert-equal '(999 999 999) (make-list-of 3 999))) (ut::define-test "result of (make-list-of 3 999)" '(ut::assert-equal '(999 999 999) (make-list-of 3 999)))
@ -115,6 +115,8 @@
(ut::define-test "result of (sprintf \"%.2f\" '(1.23456))" '(ut::assert-equal "1.23" (sprintf "%.2f" '(1.23456)))) (ut::define-test "result of (sprintf \"%.2f\" '(1.23456))" '(ut::assert-equal "1.23" (sprintf "%.2f" '(1.23456))))
(ut::define-test "result of (sprintf \"%.d\" '(10000000))" '(ut::assert-equal "10000000" (sprintf "%.d" '(10000000)))) (ut::define-test "result of (sprintf \"%.d\" '(10000000))" '(ut::assert-equal "10000000" (sprintf "%.d" '(10000000))))
(ut::define-test "result of (set-env \"XXYYZZ\" \"haha\")" '(ut::assert-equal "haha" (set-env "XXYYZZ" "haha")))
(ut::define-test "result of (get-env \"XXYYZZ\")" '(ut::assert-equal "haha" (get-env "XXYYZZ")))
(ut::define-test "result of (get-env \"HOME\")" '(ut::assert-equal "/Users/vaclavt" (get-env "HOME"))) (ut::define-test "result of (get-env \"HOME\")" '(ut::assert-equal "/Users/vaclavt" (get-env "HOME")))
(ut::define-test "result of (!= nil nil)" '(ut::assert-false (!= nil nil))) (ut::define-test "result of (!= nil nil)" '(ut::assert-false (!= nil nil)))
@ -138,6 +140,7 @@
(ut::define-test "result of (end-of-year)" '(ut::assert-equal 1640995199 (end-of-year (str-to-date "2021-05-13 10:32:12" "%Y-%m-%d %H:%M:%S")))) (ut::define-test "result of (end-of-year)" '(ut::assert-equal 1640995199 (end-of-year (str-to-date "2021-05-13 10:32:12" "%Y-%m-%d %H:%M:%S"))))
(ut::define-test "result of (decode-universal-time 0)" '(ut::assert-equal '(0 0 0 1 1 1970 4) (decode-universal-time 0))) (ut::define-test "result of (decode-universal-time 0)" '(ut::assert-equal '(0 0 0 1 1 1970 4) (decode-universal-time 0)))
;(ut::define-test "result of (print ( + 15.0 (read)))" '(ut::assert-equal 30 (print ( + 15.0 (read)))))
(ut::define-test "result of (read-file-lines \"/tmp/f.txt\" counter)" '(ut::assert-equal 3 (read-file-lines "/tmp/f.txt" counter))) (ut::define-test "result of (read-file-lines \"/tmp/f.txt\" counter)" '(ut::assert-equal 3 (read-file-lines "/tmp/f.txt" counter)))
(ut::define-test "result of create table" '(ut::assert-equal ((0 "table created" 0)) (usql "create table a (i integer not null, s varchar(64), f float null, d date null, b boolean)"))) (ut::define-test "result of create table" '(ut::assert-equal ((0 "table created" 0)) (usql "create table a (i integer not null, s varchar(64), f float null, d date null, b boolean)")))