mirror of
https://github.com/janet-lang/janet
synced 2024-09-29 07:20:41 +00:00
Rename seq abstraction to iterator. Add random functions.
This commit is contained in:
parent
5f0bd1e082
commit
5738f6c8b1
@ -2,7 +2,7 @@
|
|||||||
"Solve the 3SUM problem O(n^2) time."
|
"Solve the 3SUM problem O(n^2) time."
|
||||||
[s]
|
[s]
|
||||||
(def tab @{})
|
(def tab @{})
|
||||||
(def solutions [])
|
(def solutions @{})
|
||||||
(def len (length s))
|
(def len (length s))
|
||||||
(for [k 0 len]
|
(for [k 0 len]
|
||||||
(put tab (get s k) k))
|
(put tab (get s k) k))
|
||||||
@ -10,5 +10,5 @@
|
|||||||
(for [j 0 len]
|
(for [j 0 len]
|
||||||
(def k (get tab (- 0 (get s i) (get s j))))
|
(def k (get tab (- 0 (get s i) (get s j))))
|
||||||
(when (and k (not= k i) (not= k j) (not= i j))
|
(when (and k (not= k i) (not= k j) (not= i j))
|
||||||
(array-push solutions [i j k]))))
|
(put solutions {i true j true k true} true))))
|
||||||
solutions)
|
(iter2array (map (fn [x] (iter2array (keys x))) (keys solutions))))
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
"Get the number of occurences of each value in a sequence."
|
"Get the number of occurences of each value in a sequence."
|
||||||
[s]
|
[s]
|
||||||
(let [freqs @{}
|
(let [freqs @{}
|
||||||
fop (fn [x]
|
_ (foreach s (fn [x]
|
||||||
(let [n (get freqs x)]
|
(let [n (get freqs x)]
|
||||||
(put freqs x (if n (+ 1 n) 1))))
|
(put freqs x (if n (+ 1 n) 1)))))]
|
||||||
_ (domap fop s)]
|
|
||||||
freqs))
|
freqs))
|
||||||
|
@ -39,6 +39,14 @@
|
|||||||
(defn one? [x] (== x 1))
|
(defn one? [x] (== x 1))
|
||||||
(defn inc [x] (+ x 1))
|
(defn inc [x] (+ x 1))
|
||||||
(defn dec [x] (- x 1))
|
(defn dec [x] (- x 1))
|
||||||
|
(def atomic? (do
|
||||||
|
(def non-atomic-types {
|
||||||
|
:array true
|
||||||
|
:tuple true
|
||||||
|
:table true
|
||||||
|
:struct true
|
||||||
|
})
|
||||||
|
(fn [x] (not (get non-atomic-types (type x))))))
|
||||||
|
|
||||||
(defmacro comment
|
(defmacro comment
|
||||||
"Ignores the body of the comment."
|
"Ignores the body of the comment."
|
||||||
@ -109,8 +117,8 @@ If no match is found, returns nil"
|
|||||||
"A function that returns its first argument."
|
"A function that returns its first argument."
|
||||||
[x] x)
|
[x] x)
|
||||||
|
|
||||||
(def seq (do
|
(def iter (do
|
||||||
(defn array-seq [x]
|
(defn array-iter [x]
|
||||||
(def len (length x))
|
(def len (length x))
|
||||||
(var i 0)
|
(var i 0)
|
||||||
{
|
{
|
||||||
@ -120,22 +128,13 @@ If no match is found, returns nil"
|
|||||||
(varset! i (+ i 1))
|
(varset! i (+ i 1))
|
||||||
ret)
|
ret)
|
||||||
})
|
})
|
||||||
(defn fiber-seq [x]
|
(def iters {
|
||||||
{
|
:array array-iter
|
||||||
:more (fn [] (or
|
:tuple array-iter
|
||||||
(= (fiber-status x) :pending)
|
|
||||||
(= (fiber-status x) :new)))
|
|
||||||
:next (fn []
|
|
||||||
(resume x))
|
|
||||||
})
|
|
||||||
(def seqs {
|
|
||||||
:array array-seq
|
|
||||||
:tuple array-seq
|
|
||||||
:fiber fiber-seq
|
|
||||||
:struct (fn [x] x)})
|
:struct (fn [x] x)})
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(def makeseq (get seqs (type x)))
|
(def makei (get iters (type x)))
|
||||||
(if makeseq (makeseq x) (error "expected sequence")))))
|
(if makei (makei x) (error "expected sequence")))))
|
||||||
|
|
||||||
(defn range [top]
|
(defn range [top]
|
||||||
(var i 0)
|
(var i 0)
|
||||||
@ -147,34 +146,34 @@ If no match is found, returns nil"
|
|||||||
ret)
|
ret)
|
||||||
})
|
})
|
||||||
|
|
||||||
(defn doseq [s]
|
(defn doiter [itr]
|
||||||
(def {:more more :next next} (seq s))
|
(def {:more more :next next} (iter itr))
|
||||||
(while (more) (next)))
|
(while (more) (next)))
|
||||||
|
|
||||||
(defn domap [f s]
|
(defn foreach [itr f]
|
||||||
(def {:more more :next next} (seq s))
|
(def {:more more :next next} (iter itr))
|
||||||
(while (more) (f (next))))
|
(while (more) (f (next))))
|
||||||
|
|
||||||
(defn seq-array [s]
|
(defn iter2array [itr]
|
||||||
(def {:more more :next next} (seq s))
|
(def {:more more :next next} (iter itr))
|
||||||
(def a [])
|
(def a [])
|
||||||
(while (more) (array-push a (next)))
|
(while (more) (array-push a (next)))
|
||||||
a)
|
a)
|
||||||
|
|
||||||
(defn map [f s]
|
(defn map [f itr]
|
||||||
(def {:more more :next next} (seq s))
|
(def {:more more :next next} (iter itr))
|
||||||
{:more more :next (fn [] (f (next)))})
|
{:more more :next (fn [] (f (next)))})
|
||||||
|
|
||||||
(defn reduce [f start s]
|
(defn reduce [f start itr]
|
||||||
(def s (seq s))
|
(def itr (iter itr))
|
||||||
(def {:more more :next next} s)
|
(def {:more more :next next} itr)
|
||||||
(if (more)
|
(if (more)
|
||||||
(reduce f (f start (next)) s)
|
(reduce f (f start (next)) itr)
|
||||||
start))
|
start))
|
||||||
|
|
||||||
(defn filter [pred s]
|
(defn filter [pred itr]
|
||||||
(def s (seq s))
|
(def itr (iter itr))
|
||||||
(def {:more more :next next} s)
|
(def {:more more :next next} itr)
|
||||||
(var alive true)
|
(var alive true)
|
||||||
(var temp nil)
|
(var temp nil)
|
||||||
(var isnew true)
|
(var isnew true)
|
||||||
@ -322,13 +321,15 @@ If no match is found, returns nil"
|
|||||||
|
|
||||||
(defn unique [s]
|
(defn unique [s]
|
||||||
(def tab @{})
|
(def tab @{})
|
||||||
(domap (fn [x] (put tab x true)) s)
|
(foreach s (fn [x] (put tab x true)))
|
||||||
(keys tab))
|
(keys tab))
|
||||||
|
|
||||||
(defn make-env [parent]
|
(defn make-env [parent]
|
||||||
(def parent (if parent parent _env))
|
(def parent (if parent parent _env))
|
||||||
(def newenv (setproto @{} parent))
|
(def newenv (setproto @{} parent))
|
||||||
newenv)
|
newenv)
|
||||||
|
|
||||||
|
# Remove the reference to the default _env
|
||||||
(put _env '_env nil)
|
(put _env '_env nil)
|
||||||
|
|
||||||
(def run-context
|
(def run-context
|
||||||
@ -392,7 +393,7 @@ onvalue."
|
|||||||
(onvalue res)))
|
(onvalue res)))
|
||||||
(def oldenv *env*)
|
(def oldenv *env*)
|
||||||
(varset! *env* env)
|
(varset! *env* env)
|
||||||
(doseq (map doone (val-stream chunks onerr)))
|
(foreach (val-stream chunks onerr) doone)
|
||||||
(varset! *env* oldenv)
|
(varset! *env* oldenv)
|
||||||
env)))
|
env)))
|
||||||
|
|
||||||
@ -420,10 +421,9 @@ onvalue."
|
|||||||
(def {
|
(def {
|
||||||
:prefix prefix
|
:prefix prefix
|
||||||
} (apply table args))
|
} (apply table args))
|
||||||
(defn one [[k v]]
|
(foreach (pairs env) (fn [[k v]]
|
||||||
(when (not (get v :private))
|
(when (not (get v :private))
|
||||||
(put *env* (symbol (if prefix prefix "") k) v)))
|
(put *env* (symbol (if prefix prefix "") k) v)))))
|
||||||
(doseq (map one (pairs env))))
|
|
||||||
|
|
||||||
(defn repl [getchunk]
|
(defn repl [getchunk]
|
||||||
(def newenv (make-env))
|
(def newenv (make-env))
|
||||||
|
@ -23,16 +23,26 @@
|
|||||||
#include <dst/dst.h>
|
#include <dst/dst.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
/* Get a random number */
|
||||||
|
int dst_rand(DstArgs args) {
|
||||||
|
double r = (rand() % RAND_MAX) / ((double) RAND_MAX);
|
||||||
|
return dst_return(args, dst_wrap_real(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Seed the random number generator */
|
||||||
|
int dst_srand(DstArgs args) {
|
||||||
|
if (args.n != 1 || !dst_checktype(args.v[0], DST_INTEGER))
|
||||||
|
return dst_throw(args, "expected integer");
|
||||||
|
srand((unsigned) dst_unwrap_integer(args.v[0]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a number to an integer */
|
/* Convert a number to an integer */
|
||||||
int dst_int(DstArgs args) {
|
int dst_int(DstArgs args) {
|
||||||
if (args.n != 1) {
|
if (args.n != 1) return dst_throw(args, "expected one argument");
|
||||||
*args.ret = dst_cstringv("expected 1 argument");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
switch (dst_type(args.v[0])) {
|
switch (dst_type(args.v[0])) {
|
||||||
default:
|
default:
|
||||||
*args.ret = dst_cstringv("could not convert to integer");
|
return dst_throw(args, "could not convert to integer");
|
||||||
return 1;
|
|
||||||
case DST_REAL:
|
case DST_REAL:
|
||||||
*args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0]));
|
*args.ret = dst_wrap_integer((int32_t) dst_unwrap_real(args.v[0]));
|
||||||
break;
|
break;
|
||||||
@ -45,14 +55,10 @@ int dst_int(DstArgs args) {
|
|||||||
|
|
||||||
/* Convert a number to a real number */
|
/* Convert a number to a real number */
|
||||||
int dst_real(DstArgs args) {
|
int dst_real(DstArgs args) {
|
||||||
if (args.n != 1) {
|
if (args.n != 1) return dst_throw(args, "expected one argument");
|
||||||
*args.ret = dst_cstringv("expected 1 argument");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
switch (dst_type(args.v[0])) {
|
switch (dst_type(args.v[0])) {
|
||||||
default:
|
default:
|
||||||
*args.ret = dst_cstringv("could not convert to real");
|
return dst_throw(args, "could not convert to real");
|
||||||
return 1;
|
|
||||||
case DST_REAL:
|
case DST_REAL:
|
||||||
*args.ret = args.v[0];
|
*args.ret = args.v[0];
|
||||||
break;
|
break;
|
||||||
@ -379,6 +385,8 @@ DEF_NUMERIC_COMP(eq, ==)
|
|||||||
DEF_NUMERIC_COMP(neq, !=)
|
DEF_NUMERIC_COMP(neq, !=)
|
||||||
|
|
||||||
static const DstReg cfuns[] = {
|
static const DstReg cfuns[] = {
|
||||||
|
{"random", dst_rand},
|
||||||
|
{"seedrandom", dst_srand},
|
||||||
{"int", dst_int},
|
{"int", dst_int},
|
||||||
{"real", dst_real},
|
{"real", dst_real},
|
||||||
{"+", dst_add},
|
{"+", dst_add},
|
||||||
|
@ -40,6 +40,8 @@ int dst_subtract(DstArgs args);
|
|||||||
int dst_multiply(DstArgs args);
|
int dst_multiply(DstArgs args);
|
||||||
int dst_divide(DstArgs args);
|
int dst_divide(DstArgs args);
|
||||||
int dst_modulo(DstArgs args);
|
int dst_modulo(DstArgs args);
|
||||||
|
int dst_rand(DstArgs args);
|
||||||
|
int dst_srand(DstArgs args);
|
||||||
int dst_strict_equal(DstArgs args);
|
int dst_strict_equal(DstArgs args);
|
||||||
int dst_strict_notequal(DstArgs args);
|
int dst_strict_notequal(DstArgs args);
|
||||||
int dst_ascending(DstArgs args);
|
int dst_ascending(DstArgs args);
|
||||||
|
Loading…
Reference in New Issue
Block a user