Compare commits

..

2 Commits

Author SHA1 Message Date
vaclavt
48a5d70cc4 small updates 2022-05-27 17:35:22 +02:00
vaclavt
fb552633c2 get-universal-time-ms added 2022-05-27 17:34:57 +02:00
7 changed files with 41 additions and 10 deletions

View File

@@ -77,7 +77,6 @@ utils/local_install.sh
- multiline editing (see kilocpp editor) - multiline editing (see kilocpp editor)
#### Doc #### Doc
- add doc for macros
- add functions from stdlib into doc - add functions from stdlib into doc
- doc for set! - doc for set!

View File

@@ -1,7 +1,6 @@
(dotimes i 4 (print i) ) (dotimes i 4 (print i) )
(def acc 0) (def acc 0)
;(dotimes i 4 (do (set! acc (+ acc i)) (print acc)) )
(print (dotimes i 4 (do (set! acc (+ acc i)) (print acc))) ) (print (dotimes i 4 (do (set! acc (+ acc i)) (print acc))) )
(defmacro until (cnd body) (defmacro until (cnd body)

View File

@@ -2,8 +2,8 @@
|option|Description| |option|Description|
|:-|-| |:-|-|
|-h|Prints help| |-h|Prints help|
|-b|Skips loadin of std lib| |-b|Skips loading of std lib|
|-c code|Runs given code| |-c code|Runs passed code|
|-f source_file ..|Executes code in files| |-f source_file ..|Executes code in files|
|-run source_file ..|Executes code in file, if first line of file is sheebang, it is skipped| |-run source_file ..|Executes code in file, if first line of file is sheebang, it is skipped|
|-i|Runs REPL| |-i|Runs REPL|
@@ -23,7 +23,7 @@
## Syntax and Special Forms ## Syntax and Special Forms
|Special Form|Argument Evaluations|Purpose|Section| |Special Form|Argument Evaluations|Purpose|Section|
|:-|-|-|-| |:-|-|-|-|
|`(if cond a b)`|`if` only evaluates its `cond` argument. If `cond` is truthy (non-zero), then `a` is evaluated. Otherwise, `b` is evaluated.|This special form is the main method of control flow.|Language| |`(if cond a b)`|`if` only evaluates its `cond` argument. If `cond` is truthy, then `a` is evaluated. Otherwise, `b` is evaluated.|This special form is the main method of control flow.|Language|
|`(cond (test1 action1 ..) (test2 action2 ..) ... (testn ..))`|The first clause whose test evaluates to non-nil is selected; all other clauses are ignored, and the consequents of the selected clause are evaluated in order. If none of the test conditions are evaluated to be true, then the cond statement returns nil.|This special form is method of control flow.|Language| |`(cond (test1 action1 ..) (test2 action2 ..) ... (testn ..))`|The first clause whose test evaluates to non-nil is selected; all other clauses are ignored, and the consequents of the selected clause are evaluated in order. If none of the test conditions are evaluated to be true, then the cond statement returns nil.|This special form is method of control flow.|Language|
|`(do a b c ...)`|`do` takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression.|This special form allows lambda functions to have multi-step bodies.|Language| |`(do a b c ...)`|`do` takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression.|This special form allows lambda functions to have multi-step bodies.|Language|
|`(scope a b c ...)`|`scope` takes a list of s-expressions and evaluates them in the order they were given _in a new scope_, and then returns the result of the last s-expression.|This special form allows the user to evaluate blocks of code in new scopes.|Language| |`(scope a b c ...)`|`scope` takes a list of s-expressions and evaluates them in the order they were given _in a new scope_, and then returns the result of the last s-expression.|This special form allows the user to evaluate blocks of code in new scopes.|Language|
@@ -39,6 +39,13 @@
|`(benchmark msg_string ...)`|`benchmark` takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression and prints msg_string and timing info.||Language| |`(benchmark msg_string ...)`|`benchmark` takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression and prints msg_string and timing info.||Language|
|`(set! x)`|`set!` ...|....|Language| |`(set! x)`|`set!` ...|....|Language|
## Macros
|Signature|Description|Return values|Section|
|:-|-|-|-|
|`(unles cond body)`|`unless` only evaluates its `cond` argument. If `cond` is not truthy, then `body` is evaluated.|`>>> (unless #t (print "it is #f")) => nil`|Language|
|`(dotimes v n body)`|Iterates over `v` from 0 below `n` and evaluated `body`. Returns the last value of v|`>>> (dotimes i 5 i) => 4`|Language|
|`(until cond body)`|Evaluated `body` as long as `cond` is not truthy|`>>> (def i 0)(until (> i 3) (set! i (inc i))) => 4`|Language|
## Library ## Library
|Signature|Description|Return values|Section| |Signature|Description|Return values|Section|
|:-|-|-|-| |:-|-|-|-|
@@ -101,7 +108,8 @@
|`(parse-csv string)`|Parse CSV string|`>>> (parse-csv "A,B\n1,1\n2,2") => ((1 1) (2 2))`|String manipulation| |`(parse-csv string)`|Parse CSV string|`>>> (parse-csv "A,B\n1,1\n2,2") => ((1 1) (2 2))`|String manipulation|
|`(parse-json json_string)`|Parse JSON string|`>>> (parse-json "{\"k1\":\"v1\", \"k2\":42, \"k3\":[\"a\",123,true,false,null]}") => (("k1" "v1") ("k2" 42) ("k3" ("a" 123 #t nil nil)))`|String manipulation| |`(parse-json json_string)`|Parse JSON string|`>>> (parse-json "{\"k1\":\"v1\", \"k2\":42, \"k3\":[\"a\",123,true,false,null]}") => (("k1" "v1") ("k2" 42) ("k3" ("a" 123 #t nil nil)))`|String manipulation|
|`(make-csv ..)`|Returns list as csv string|`>>> (make-csv '(("A" "B")(1 1)(2 2))) => "A,B\n1,1\n2,2"`|String manipulation| |`(make-csv ..)`|Returns list as csv string|`>>> (make-csv '(("A" "B")(1 1)(2 2))) => "A,B\n1,1\n2,2"`|String manipulation|
|`(get-universal-time)`|Get current time as secs from epoch|`>>> (get-universal-time) => 1642152733`|Date and time| |`(get-universal-time)`|Get current time as number of seconds from epoch|`>>> (get-universal-time) => 1642152733`|Date and time|
|`(get-universal-time-ms)`|Get current time as number of miliseconds from epoch|`>>> (get-universal-time-ms) => 1653575251097`|Date and time|
|`(get-localtime-offset)`|Offset in seconds between local time and gmt time|`>>> (get-localtime-offset) => 3600`|Date and time| |`(get-localtime-offset)`|Offset in seconds between local time and gmt time|`>>> (get-localtime-offset) => 3600`|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|
|`(str-to-date string format)`|Converst string to time of secs since epoch. |`>>> (str-to-date "2021-03-13 19:53:01" "%Y-%m-%d %H:%M:%S") => 1615665181`|Date and time| |`(str-to-date string format)`|Converst string to time of secs since epoch. |`>>> (str-to-date "2021-03-13 19:53:01" "%Y-%m-%d %H:%M:%S") => 1615665181`|Date and time|

11
ml.cpp
View File

@@ -1298,6 +1298,16 @@ MlValue get_universal_time(std::vector<MlValue> args, MlEnvironment &env) {
return MlValue(now()); return MlValue(now());
} }
// Get current time as miliseconds from epoch
MlValue get_universal_time_ms(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env);
if (!args.empty())
throw MlError(MlValue("get-universal-time-ms", get_universal_time_ms), env, TOO_MANY_ARGS);
return MlValue(now_ms());
}
// Get offsets in secs between local timezone and gmt // Get offsets in secs between local timezone and gmt
MlValue get_localtime_offset(std::vector<MlValue> args, MlEnvironment &env) { MlValue get_localtime_offset(std::vector<MlValue> args, MlEnvironment &env) {
eval_args(args, env); eval_args(args, env);
@@ -2294,6 +2304,7 @@ std::map<const std::string, Builtin> builtin_funcs
// Datetime operations // Datetime operations
std::make_pair("get-universal-time", builtin::get_universal_time), std::make_pair("get-universal-time", builtin::get_universal_time),
std::make_pair("get-universal-time-ms", builtin::get_universal_time_ms),
std::make_pair("get-localtime-offset", builtin::get_localtime_offset), std::make_pair("get-localtime-offset", builtin::get_localtime_offset),
std::make_pair("date-to-str", builtin::date_to_str), std::make_pair("date-to-str", builtin::date_to_str),
std::make_pair("str-to-date", builtin::str_to_date), std::make_pair("str-to-date", builtin::str_to_date),

View File

@@ -2,6 +2,7 @@
#include "ml_date.h" #include "ml_date.h"
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <chrono>
long now() { // get-universal-time long now() { // get-universal-time
time_t t = std::time(nullptr); time_t t = std::time(nullptr);
@@ -10,6 +11,13 @@ long now() { // get-universal-time
return now; return now;
} }
long now_ms() { // get-universal-time-ms
using namespace std::chrono;
milliseconds ms = duration_cast< milliseconds >(system_clock::now().time_since_epoch());
return ms.count();
}
long get_gmt_localtime_offset() { long get_gmt_localtime_offset() {
std::time_t current_time; std::time_t current_time;
std::time(&current_time); std::time(&current_time);

View File

@@ -6,6 +6,7 @@
long now(); long now();
long now_ms();
long get_gmt_localtime_offset(); long get_gmt_localtime_offset();

View File

@@ -9,11 +9,11 @@
(* n (fact (- n 1))) (* n (fact (- n 1)))
)) ))
; for scitej 4000 stack must be 16MB, otherwise 1000 is ok ; for adder 4000 stack must be 16MB, otherwise 1000 is ok
(defn scitej (n) (defn adder (n)
(if (<= n 1) (if (<= n 1)
1 1
(+ n (scitej (- n 1))) (+ n (adder (- n 1)))
)) ))
(write-file "/tmp/f.txt" "line 1\nline 2\nline3") (write-file "/tmp/f.txt" "line 1\nline 2\nline3")
@@ -29,6 +29,11 @@
(thread-create (tcp-server 7778 (lambda (str) (list #t (+ "(print \"" (string-upcase str) "\")"))))) (thread-create (tcp-server 7778 (lambda (str) (list #t (+ "(print \"" (string-upcase str) "\")")))))
(ut::define-test "result of (unless #t (print \"#f\"))" '(ut::assert-false (unless #t (print "#f"))))
(ut::define-test "result of (dotimes i 5 i)" '(ut::assert-equal 4 (dotimes i 5 i)))
(ut::define-test "result of (def i 0)(until (> i 3) (set! i (inc i)))" '(ut::assert-equal 4 (do (def i 0)(until (> i 3) (set! i (inc i))))))
(ut::define-test "result of (and (> 2 1) (> 2 1))" '(ut::assert-true (and (> 2 1) (> 2 1)))) (ut::define-test "result of (and (> 2 1) (> 2 1))" '(ut::assert-true (and (> 2 1) (> 2 1))))
(ut::define-test "result of (or (> 2 1) (> 2 1))" '(ut::assert-true (or (> 2 1) (> 2 1)))) (ut::define-test "result of (or (> 2 1) (> 2 1))" '(ut::assert-true (or (> 2 1) (> 2 1))))
(ut::define-test "retult of (and (> 2 1) (> 1 2))" '(ut::assert-false (and (> 2 1) (> 1 2)))) (ut::define-test "retult of (and (> 2 1) (> 1 2))" '(ut::assert-false (and (> 2 1) (> 1 2))))
@@ -57,7 +62,7 @@
(ut::define-test "result of (range 1.5 5.5)" '(ut::assert-equal '(1.500000 2.500000 3.500000 4.500000) (range 1.5 5.5))) (ut::define-test "result of (range 1.5 5.5)" '(ut::assert-equal '(1.500000 2.500000 3.500000 4.500000) (range 1.5 5.5)))
(ut::define-test "result of (fact 5)" '(ut::assert-equal 120 (fact 5))) (ut::define-test "result of (fact 5)" '(ut::assert-equal 120 (fact 5)))
(ut::define-test "result of (scitej 1000)" '(ut::assert-equal 500500 (scitej 1000))) (ut::define-test "result of (adder 1000)" '(ut::assert-equal 500500 (adder 1000)))
(ut::define-test "result of (len json_list)" '(ut::assert-equal 3 (len json_list))) (ut::define-test "result of (len json_list)" '(ut::assert-equal 3 (len json_list)))