Data/Random/Buffer, spec updated

This commit is contained in:
Dmitry Boulytchev 2020-08-22 20:11:41 +03:00
parent 94e4b16267
commit f08cd8396f
9 changed files with 164 additions and 10 deletions

Binary file not shown.

View file

@ -1512,7 +1512,7 @@ extern void __gc_root_scan_stack ();
/* ======================================== */ /* ======================================== */
//static size_t SPACE_SIZE = 16; //static size_t SPACE_SIZE = 16;
static size_t SPACE_SIZE = 64 * 1024 * 1024; static size_t SPACE_SIZE = 256 * 1024 * 1024;
// static size_t SPACE_SIZE = 128; // static size_t SPACE_SIZE = 128;
// static size_t SPACE_SIZE = 1024 * 1024; // static size_t SPACE_SIZE = 1024 * 1024;

View file

@ -94,6 +94,45 @@ program start time.}
\descr{\lstinline|fun time ()|}{Returns the elapsed time from program start in microseconds.} \descr{\lstinline|fun time ()|}{Returns the elapsed time from program start in microseconds.}
\section{Unit \texttt{Data}}
\label{sec:data}
Generic data manupulation.
\descr{\lstinline|infix =?= at < (x, y)|}{A generic comparison operator similar to \lstinline|compare|, but capable of handling cyclic/shared data structures.}
\descr{\lstinline|infix === at == (x, y)|}{A generic equality operator capable of handling cyclic/shared data structures.}
\section{Unit \texttt{Random}}
\label{sec:random}
Random data structures generation functions.
\descr{\lstinline|fun randomInt ()|}{Generates a random representable integer value.}
\descr{\lstinline|fun randomString (len)|}{Generates a random string of printable ASCII characters of given length.}
\descr{\lstinline|fun randomArray (f, n)|}{Generates a random array of \emph{deep} size \lstinline|n|. The length of the array is chosen randomly, and \lstinline|f| is intended to be an element-generating function which takes the size of the element as an argument.}
\descr{\lstinline|fun split (n, k)|}{Splits a non-negative integer \lstinline|n| in \lstinline|k| random summands. Returns an array if length \lstinline|k|. \lstinline|k| has to be non-negative.}
\newsavebox\strubox
\begin{lrbox}{\strubox}
\begin{lstlisting}
structure (100,
[[2, fun ([x, y]) {Add (x, y)}],
[2, fun ([x, y]) {Sub (x, y)}]],
fun () {Const (randomInt ())}
)
\end{lstlisting}
\end{lrbox}
\descr{\lstinline|fun structure (n, nodeSpec, leaf)|}{Generates a random tree-shaped data structure of size \lstinline|n|. \lstinline|nodeSpec| is an array of pairs \lstinline|[$k$, $f_k$]|, where $k$ is a non-negative integer and $f_k$ is a function which takes an array of length $k$ as its argument. Each pair describes a generator of a certain kind of interior node with degree $k$. \lstinline|leaf| is a zero-argument function which generates the leaves of the tree. For example, the following code
\usebox\strubox
can be used to generate a random arithmetic expression of size 100.}
\section{Unit \texttt{Array}} \section{Unit \texttt{Array}}
\label{sec:array} \label{sec:array}
@ -308,6 +347,27 @@ fresh list if images in the same order.}
\descr{\lstinline|fun filter (f, l)|}{Removes all values, not satisfying the predicate "\lstinline|f|", from the list "\lstinline|l|". The function \descr{\lstinline|fun filter (f, l)|}{Removes all values, not satisfying the predicate "\lstinline|f|", from the list "\lstinline|l|". The function
"\lstinline|f|" should return integers, treated as booleans.} "\lstinline|f|" should return integers, treated as booleans.}
\section{Unit \texttt{Buffer}}
\label{sec:std:buffer}
Mutable buffers.
\descr{\lstinline|fun emptyBuffer ()|}{Creates an empty buffer.}
\descr{\lstinline|fun singletonBuffer (x)|}{Creates a buffer from a single element.}
\descr{\lstinline|fun listBuffer (x)|}{Creates a buffer from a list.}
\descr{\lstinline|fun getBuffer (buf)|}{Gets the contents of a buffer as a list.}
\descr{\lstinline|fun addBuffer (buf, x)|}{Adds an element \lstinline|x| to the end of buffer \lstinline|buf| and returns the updated buffer. The buffer \lstinline|buf| can be updated in-place.}
\descr{\lstinline|fun concatBuffer (buf, x)|}{Adds buffer \lstinline|x| to the end of buffer \lstinline|buf| and returns the updated buffer. The buffer \lstinline|buf| can be updated in-place.}
\descr{\lstinline|infixl <+> before + (b1, b2)|}{Infix synonym for \lstinline|concatBuffer|.}
\descr{\lstinline|infix <+ at <+> (b, x)|}{Infix synonym for \lstinline|addBuffer|.}
\section{Unit \texttt{Matcher}} \section{Unit \texttt{Matcher}}
The unit provides some primitives for matching strings against regular patterns. Matchers are immutable structures which store The unit provides some primitives for matching strings against regular patterns. Matchers are immutable structures which store

View file

@ -1 +1 @@
let version = "Version 1.00, 6f9d0850c, Fri Aug 7 21:40:51 2020 +0300" let version = "Version 1.00, 94e4b1626, Mon Aug 10 20:55:10 2020 +0300"

66
stdlib/Buffer.lama Normal file
View file

@ -0,0 +1,66 @@
-- Buffer.
-- (C) Dmitry Boulytchev, JetBrains Research, St. Petersburg State University, 2020
--
-- This unit provides a simple add-to-the-end buffer implemetation.
import List;
-- Creates an empty buffer
public fun emptyBuffer () {
{}
}
-- Creates a buffer with one element x
public fun singletonBuffer (x) {
local y = singleton (x);
[y, y]
}
-- Creates a buffer from a list x
public fun listBuffer (x) {
foldl (addBuffer, emptyBuffer (), x)
}
-- Adds x to the end of buffer buf
public fun addBuffer (buf, x) {
case buf of
{} -> local y = singleton (x);
[y, y]
| [head, last] ->
last[1] := singleton (x);
[head, last[1]]
esac
}
-- Adds the contents of buffer x to the end of buffer buf
public fun concatBuffer (buf, x) {
case buf of
{} -> x
| [head, last] ->
case x of
{} -> buf
| [h, l] ->
last[1] := h;
[head, l]
esac
esac
}
-- Infix synonym for concatBuffer
public infixl <+> before + (b1, b2) {
concatBuffer (b1, b2)
}
-- Infix synonym for addBuffer
public infix <+ at <+> (b, x) {
addBuffer (b, x)
}
-- Gets the contents of the buffer buf (as a list)
public fun getBuffer (buf) {
case buf of
{} -> {}
| [head, _] -> head
esac
}

View file

@ -84,7 +84,15 @@ public fun flatten (l) {
curr [0] := new curr [0] := new
} }
iter (fun (x) {iter (append, x)}, l); fun traverse (l) {
case l of
_ : _ -> iter (traverse, l)
| {} -> skip
| _ -> append (l)
esac
}
traverse (l);
res [1] res [1]
} }

View file

@ -16,6 +16,8 @@ Array.o: List.o
Ostap.o: List.o Collection.o Ref.o Fun.o Matcher.o Ostap.o: List.o Collection.o Ref.o Fun.o Matcher.o
Buffer.o: List.o
Expr.o: Ostap.o Expr.o: Ostap.o
%.o: %.lama %.o: %.lama

View file

@ -28,13 +28,12 @@ public fun randomString (len) {
-- Generates a random array of (deep) size n. f is element-generation -- Generates a random array of (deep) size n. f is element-generation
-- function which takes the size of the element -- function which takes the size of the element
public fun randomArray (f, n) { public fun randomArray (f, n) {
mapArray (f, split (n)) mapArray (f, split (n, random (n + 1)))
} }
-- Splits a number in a random sequence of summands -- Splits a number n in a random sequence of k summands
public fun split (n) { public fun split (n, k) {
local k = random (n) + 1, local a = makeArray (k),
a = makeArray (k),
m = n; m = n;
for local i = 0;, i < k, i := i + 1 for local i = 0;, i < k, i := i + 1
@ -49,3 +48,22 @@ public fun split (n) {
a a
} }
-- Generates a (recursive) data structure of size n. nodeSpec is an array of pairs [n, fn] where
-- fn gets an array of values of length n and generates some node; leaf is a fucntion without
-- arguments which create a leaf.
public fun structure (n, nodeSpec, leaf) {
local k = nodeSpec.length;
fun rec (n) {
if n <= 1
then leaf ()
else
local ns = nodeSpec [random (k)];
ns [1] (mapArray (rec, split (n, ns [0])))
fi
}
rec (n)
}

View file

@ -24,7 +24,7 @@ fun genCyclicArrays (n, eq, cross) {
x -> [x, clone (x)] x -> [x, clone (x)]
esac esac
else else
local a = split (n), local a = split (n, random (n+1)),
b = mapArray (id, a), b = mapArray (id, a),
index = initArray (random (a.length + 1), fun (_) {random (a.length)}); index = initArray (random (a.length + 1), fun (_) {random (a.length)});