Skip to content

Commit

Permalink
[master] changes to algorithm to support move-only types (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhrr committed Apr 22, 2016
1 parent c954925 commit 32c4874
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 21 deletions.
39 changes: 21 additions & 18 deletions modules/algorithms.dt
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ returned.
(def find (fn extern (uq Ti)
((begin (uq Ti))
(end (uq Ti))
(fvalue ((uq tpw-1) (value-type (nullptr (uq Ti))))))
(fvalue ((uq tpw-ro-1) (value-type (nullptr (uq Ti))))))
(for true (!= begin end) (setv begin (successor begin))
(and (= ((uq tvw-1) fvalue) (@ (source begin)))
(and (= ((uq tvw-ro-1) fvalue) (@ (source begin)))
(return begin)))
(return end)))))

Expand Down Expand Up @@ -216,15 +216,15 @@ The function assumes that the range is sorted.
(def lower-bound
(fn extern (uq Ti) ((b (uq Ti))
(e (uq Ti))
(v ((uq tpw-1) (value-type (nullptr (uq Ti))))))
(v ((uq tpw-ro-1) (value-type (nullptr (uq Ti))))))
(let ((count \ (distance b e))
(step size)
(it (uq Ti)))
(while (> count (cast 0 size))
(setv it b)
(setv step (/ count (cast 2 size)))
(setv it (+ it step))
(if (< (@ (source it)) ((uq tvw-1) v))
(if (< (@ (source it)) ((uq tvw-ro-1) v))
(do (setv it (successor it))
(setv b it)
(setv count (- count (+ step (cast 1 size))))
Expand All @@ -249,15 +249,15 @@ The function assumes that the range is sorted.
(def upper-bound
(fn extern (uq Ti) ((b (uq Ti))
(e (uq Ti))
(v ((uq tpw-1) (value-type (nullptr (uq Ti))))))
(v ((uq tpw-ro-1) (value-type (nullptr (uq Ti))))))
(let ((count \ (distance b e))
(step size)
(it (uq Ti)))
(while (> count (cast 0 size))
(setv it b)
(setv step (/ count (cast 2 size)))
(setv it (+ it step))
(if (not (< ((uq tvw-1) v) (@ (source it))))
(if (not (< ((uq tvw-ro-1) v) (@ (source it))))
(do (setv it (successor it))
(setv b it)
(setv count (- count (+ step (cast 1 size))))
Expand All @@ -282,10 +282,10 @@ assumes that the range is sorted.
(def binary-search
(fn extern bool ((b (uq Ti))
(e (uq Ti))
(v ((uq tpw-1) (value-type (nullptr (uq Ti))))))
(setv b (lower-bound b e ((uq tvw-1) v)))
(v ((uq tpw-ro-1) (value-type (nullptr (uq Ti))))))
(setv b (lower-bound b e ((uq tvw-ro-1) v)))
(and (not (= b e))
(not (< ((uq tvw-1) v) (@ (source b)))))))))
(not (< ((uq tvw-ro-1) v) (@ (source b)))))))))

#|
@concept-macro equal-range
Expand All @@ -305,19 +305,20 @@ the value.
(def equal-range
(fn extern (Pair (uq Ti) (uq Ti)) ((b (uq Ti))
(e (uq Ti))
(v ((uq tpw-1) (value-type (nullptr (uq Ti))))))
(let ((it (uq Ti) (lower-bound b e ((uq tvw-1) v)))
(v ((uq tpw-ro-1) (value-type (nullptr (uq Ti))))))
(let ((it (uq Ti) (lower-bound b e ((uq tvw-ro-1) v)))
(pr (Pair (uq Ti) (uq Ti))))
(setf (: pr first) it)
(setf (: pr second) (upper-bound it e ((uq tvw-1) v)))
(setf (: pr second) (upper-bound it e ((uq tvw-ro-1) v)))
pr)))))

#|
@concept-macro max

Expands to a function that takes two values of the specified type. If
the first value is greater than the second value, then the first is
returned. Otherwise, the second is returned.
returned. Otherwise, the second is returned. Does not support types
that do not permit copying.

@param T The type node.
|#
Expand Down Expand Up @@ -355,7 +356,8 @@ returned. Otherwise, the second is returned.

Expands to a function that takes two values of the specified type. If
the first value is less than than the second value, then the first is
returned. Otherwise, the second is returned.
returned. Otherwise, the second is returned. Does not support types
that do not permit copying.

@param T The type node.
|#
Expand Down Expand Up @@ -392,9 +394,9 @@ returned. Otherwise, the second is returned.
@concept-macro copy

Takes input and output iterator types as its arguments. Expands to a
function that two of the input iterators and an output iterator. That
function iterates over the provided range, sinking values into the
output iterator at each step.
function that takes two of the input iterators and an output iterator.
That function iterates over the provided range, sinking values into
the output iterator at each step.

@param Ti The input iterator type.
@param To The output iterator type.
Expand Down Expand Up @@ -475,7 +477,8 @@ into the cleared container.

Takes an input iterator type as its arguments. Expands to a fold-left
function that takes a binary operation function pointer, an initial
value, and a pair of input iterators as its arguments.
value, and a pair of input iterators as its arguments. Does not
support types that do not permit copying.

@param Ti The input iterator type.
|#
Expand Down
21 changes: 18 additions & 3 deletions modules/concepts.dt
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,32 @@ for which copying is disabled, `refconst` for types preferring
references, and `identity` otherwise, and the third is `tvw' (type
value wrapper), which expands to `move@` for types for which copying
is disabled, `@` for types preferring references, and `identity`
otherwise. The form names described above each take a hyphen and the
string of the suffix node, so as to allow disambiguation when multiple
calls are required.
otherwise. There are additionally `tpw-ro` and `tvw-ro`, for when
types are used in a read-only fashion. The form names described above
each take a hyphen and the string of the suffix node, so as to allow
disambiguation when multiple calls are required.

|#
(def prefer-ref-bindings
(macro extern (T2 S)
(def cd-name-str (var auto (array-of 250 char)))
(def pr-name-str (var auto (array-of 250 char)))
(def tpw-name-str (var auto (array-of 250 char)))
(def tpw-ro-name-str (var auto (array-of 250 char)))
(def tvw-name-str (var auto (array-of 250 char)))
(def tvw-ro-name-str (var auto (array-of 250 char)))
(sprintf cd-name-str "copy-disabled-%s" (@:@ S token-str))
(sprintf pr-name-str "prefer-refs-%s" (@:@ S token-str))
(sprintf tpw-name-str "tpw-%s" (@:@ S token-str))
(sprintf tpw-ro-name-str "tpw-ro-%s" (@:@ S token-str))
(sprintf tvw-name-str "tvw-%s" (@:@ S token-str))
(sprintf tvw-ro-name-str "tvw-ro-%s" (@:@ S token-str))
(def cd-name-node (var auto \ (mnfv mc cd-name-str)))
(def pr-name-node (var auto \ (mnfv mc pr-name-str)))
(def tpw-name-node (var auto \ (mnfv mc tpw-name-str)))
(def tpw-ro-name-node (var auto \ (mnfv mc tpw-ro-name-str)))
(def tvw-name-node (var auto \ (mnfv mc tvw-name-str)))
(def tvw-ro-name-node (var auto \ (mnfv mc tvw-ro-name-str)))
(qq do
(def (uq cd-name-node) (var auto bool (not (is-copy-permitted mc (qq do (uq T2)) false))))
(def (uq pr-name-node) (var auto bool (not (has-errors mc
Expand All @@ -80,11 +87,19 @@ calls are required.
"rv-ref"
"refconst")
"identity"))))
(def (uq tpw-ro-name-node) (var auto (p DNode)
(mnfv mc (if (uq pr-name-node)
"refconst"
"identity"))))
(def (uq tvw-name-node) (var auto (p DNode)
(mnfv mc (if (uq pr-name-node)
(if (uq cd-name-node)
"move@"
"@")
"identity"))))
(def (uq tvw-ro-name-node) (var auto (p DNode)
(mnfv mc (if (uq pr-name-node)
"@"
"identity")))))))

(def prefer-ref-bindings
Expand Down
35 changes: 35 additions & 0 deletions t/015algorithm/014algorithm-rv.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/perl

use warnings;
use strict;
$ENV{"DALE_TEST_ARGS"} ||= "";
my $test_dir = $ENV{"DALE_TEST_DIR"} || ".";
$ENV{PATH} .= ":.";

use Data::Dumper;
use Test::More tests => 3;

my @res = `dalec $ENV{"DALE_TEST_ARGS"} -lm $test_dir/t/src/algorithm-rv.dt -o algorithm-rv `;
is_deeply(\@res, [], 'No compilation errors');
@res = `./algorithm-rv`;
is($?, 0, 'Program executed successfully');

chomp for @res;

is_deeply(\@res, [
'Did not find pointer',
'Found pointer',
'Did not find lower bound for 4',
'Found lower bound for 3 (3)',
'Did not find upper bound for 3',
'Found upper bound for 2 (3)',
'Found 3',
'Did not find 4',
'Lower bound is 2',
'Upper bound is 3',
],
'Got correct results');

`rm algorithm-rv`;

1;
132 changes: 132 additions & 0 deletions t/src/algorithm-rv.dt
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
(import cstdio)
(import unistd)
(import macros)
(import unique-ptr)
(import vector)
(import derivations)
(import algorithms)

(std.concepts.instantiate UniquePtr int)

(def = (fn intern bool ((a (const (p int))) (b (const (p int))))
(= (@ a) (@ b))))
(def < (fn intern bool ((a (const (p int))) (b (const (p int))))
(< (@ a) (@ b))))
(def = (fn extern bool ((a (ref (const (UniquePtr int))))
(b (ref (const (UniquePtr int)))))
(= (core-@:@ a pointer) (core-@:@ b pointer))))
(def < (fn extern bool ((a (ref (const (UniquePtr int))))
(b (ref (const (UniquePtr int)))))
(< (core-@:@ a pointer) (core-@:@ b pointer))))

(std.concepts.instantiate relations (UniquePtr int))
(std.concepts.instantiate swap (UniquePtr int))
(std.concepts.implement Swappable (UniquePtr int))
(std.concepts.implement EqualityComparable (UniquePtr int))
(std.concepts.implement LessThanComparable (UniquePtr int))

(std.concepts.instantiate Vector (UniquePtr int))
(std.concepts.instantiate find (Iterator (Vector (UniquePtr int))))
(std.concepts.instantiate lower-bound (Iterator (Vector (UniquePtr int))))
(std.concepts.instantiate upper-bound (Iterator (Vector (UniquePtr int))))
(std.concepts.instantiate binary-search (Iterator (Vector (UniquePtr int))))
(std.concepts.instantiate equal-range (Iterator (Vector (UniquePtr int))))

(def main
(fn extern-c int (void)
(let ((vec (Vector (UniquePtr int)) (init vec 1))
(myint1 \ (malloc' 1 int))
(myptr1 (UniquePtr int))
(myint2 \ (malloc' 1 int))
(myptr2 (UniquePtr int))
(myint22 \ (malloc' 1 int))
(myptr22 (UniquePtr int))
(myint3 \ (malloc' 1 int))
(myptr3 (UniquePtr int))
(myint32 \ (malloc' 1 int))
(myptr32 (UniquePtr int))
(myint4 \ (malloc' 1 int))
(myptr4 (UniquePtr int)))
(setf myint1 1)
(init myptr1 myint1)
(setf myint2 2)
(init myptr2 myint2)
(setf myint22 2)
(init myptr22 myint2)
(setf myint3 3)
(init myptr3 myint3)
(setf myint32 3)
(init myptr32 myint32)
(setf myint4 4)
(init myptr4 myint4)

(push-back vec (move myptr1))
(push-back vec (move myptr2))
(push-back vec (move myptr3))

; find.
(let ((b \ (begin vec))
(e \ (end vec))
(f (Iterator (Vector (UniquePtr int)))))
(setv f (find b e myptr4))
(if (not (= f e))
(printf "Found pointer\n")
(printf "Did not find pointer\n"))
(setv f (find b e myptr32))
(if (not (= f e))
(printf "Found pointer\n")
(printf "Did not find pointer\n")))

; lower-bound.
(let ((b \ (begin vec))
(e \ (end vec))
(f (Iterator (Vector (UniquePtr int)))))
(setv f (lower-bound b e myptr4))
(if (not (= f e))
(printf "Found lower bound for 4\n")
(printf "Did not find lower bound for 4\n"))
(setv f (lower-bound b e myptr32))
(if (not (= f e))
(printf "Found lower bound for 3 (%d)\n"
(@ (get (@ (source f)))))
(printf "Did not find lower bound for 3\n")))

; upper-bound.
(let ((b \ (begin vec))
(e \ (end vec))
(f (Iterator (Vector (UniquePtr int)))))
(setv f (upper-bound b e myptr32))
(if (not (= f e))
(printf "Found upper bound for 3\n")
(printf "Did not find upper bound for 3\n"))
(setv f (upper-bound b e myptr22))
(if (not (= f e))
(printf "Found upper bound for 2 (%d)\n"
(@ (get (@ (source f)))))
(printf "Did not find upper bound for 2\n")))

; binary-search.
(let ((b \ (begin vec))
(e \ (end vec))
(f bool))
(setv f (binary-search b e myptr32))
(if f
(printf "Found 3\n")
(printf "Did not find 3\n"))
(setv f (binary-search b e myptr4))
(if f
(printf "Found 4\n")
(printf "Did not find 4\n")))

; equal-range.
(let ((b \ (begin vec))
(e \ (end vec))
(f (Pair (Iterator (Vector (UniquePtr int)))
(Iterator (Vector (UniquePtr int))))))
(setv f (equal-range b e myptr22))
(printf "Lower bound is %d\n"
(@ (get (@ (source (@: f first))))))
(printf "Upper bound is %d\n"
(@ (get (@ (source (@: f second)))))))

0)))

0 comments on commit 32c4874

Please sign in to comment.