ref: 6ac0e591f2297ee9c3a5519844d9825e25db037b
parent: 1f979324794c81c3e8587b27c6124c640be9f9d5
author: Ori Bernstein <[email protected]>
date: Tue Apr 22 14:47:34 EDT 2014
Make slcp handle overlapping ranges correctly.
--- a/libstd/slcp.myr
+++ b/libstd/slcp.myr
@@ -1,16 +1,34 @@
use "die.use"
+use "types.use"
pkg std =
generic slcp : (a : @a[:], b : @a[:] -> void)
;;
-generic slcp = {a, b
+generic slcp = {a : @a[:], b : @a[:]
var i
+ var addr_a, addr_b
assert(a.len == b.len, "arguments to slcp() must be of equal length")
- for i = 0; i < a.len; i++
- a[i] = b[i]
+ addr_a = a castto(@a#) castto(intptr)
+ addr_b = b castto(@a#) castto(intptr)
+ if forwardcopy(addr_a, addr_b)
+ for i = 0; i < a.len; i++
+ a[i] = b[i]
+ ;;
+ else
+ for i = a.len; i > 0; i--
+ a[i - 1] = b[i - 1]
+ ;;
;;
+
}
+const forwardcopy = {a, b
+ if a <= b
+ -> true
+ else
+ -> false
+ ;;
+}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -858,6 +858,7 @@
if (!ng)
fatal(nx->line, "Missing trait impl body for %s %s\n", namestr(nx->impl.traitname), tystr(nx->impl.type));
nx->impl.isproto = 0;
+ nx->impl.trait = ng->impl.trait;
nx->impl.decls = ng->impl.decls;
nx->impl.ndecls = ng->impl.ndecls;
} else {
@@ -1362,6 +1363,7 @@
t = gettrait(curstab(), n->impl.traitname);
if (!t)
fatal(n->line, "No trait %s\n", namestr(n->impl.traitname));
+ n->impl.trait = t;
n->impl.type = tf(st, n->impl.type);
putimpl(curstab(), n);
@@ -1371,11 +1373,12 @@
/* look up the prototype */
proto = NULL;
dcl = n->impl.decls[i];
+
/*
since the decls in an impl are not installed in a namespace, their names
- are not updated when we call updatens() on the symbol table. Since we need
+ are not updated when we call updatens() on the symbol table. Because we need
to do namespace dependent comparisons for specializing, we need to set the
- namespace.
+ namespace here.
*/
if (file->file.globls->name)
setns(dcl->decl.name, namestr(file->file.globls->name));
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -297,6 +297,7 @@
struct {
Node *traitname;
+ Trait *trait;
Type *type;
Node **decls;
size_t ndecls;
--- a/parse/use.c
+++ b/parse/use.c
@@ -265,7 +265,15 @@
static void implpickle(FILE *fd, Node *impl)
{
- die("Pickling impls not yet supported.");
+ size_t i;
+
+ assert(!impl->impl.isproto);
+ assert(impl->impl.trait != NULL);
+
+ wrint(fd, impl->impl.trait->uid);
+ wrtype(fd, impl->impl.type);
+ for (i = 0; i < impl->impl.ndecls; i++)
+ pickle(fd, impl->impl.decls[i]);
}
static void wrtype(FILE *fd, Type *ty)
--- /dev/null
+++ b/test/data/stdslcp-expected
@@ -1,0 +1,2 @@
+3 4 5 4 5
+6 7 6 7 8
--- /dev/null
+++ b/test/stdslcp.myr
@@ -1,0 +1,19 @@
+use std
+
+const main = {
+ var a = [1,2,3,4,5]
+ var b = [6,7,8,9,10]
+
+
+ std.slcp(a[:a.len-2], a[2:])
+ std.slcp(b[2:], b[:b.len-2])
+
+ for x in a
+ std.put("%i ", x)
+ ;;
+ std.put("\n")
+ for x in b
+ std.put("%i ", x)
+ ;;
+ std.put("\n")
+}
--- a/test/tests
+++ b/test/tests
@@ -119,6 +119,7 @@
B strsplit C
B strfind C
B strjoin C
+B stdslcp C
B bigint C
# B local-labels E 10 ## BUGGERED
F declmismatch