Permalink
Browse files

New builtin type: tuple -- immutable array.

  • Loading branch information...
1 parent cde7002 commit 3983955cf0d4a8c7ef258015168686cdf33e1762 @kr committed Mar 19, 2009
Showing with 154 additions and 4 deletions.
  1. +1 −0 Makefile
  2. +2 −0 array.na
  3. +2 −0 int.na
  4. +1 −1 lx.py
  5. +1 −0 nil.na
  6. +1 −0 prelude.na
  7. +3 −3 sh-tests/methods.exp
  8. 0 sh-tests/tuple-err.fail
  9. +4 −0 sh-tests/tuple-err.na
  10. +4 −0 sh-tests/tuple.exp
  11. +13 −0 sh-tests/tuple.na
  12. +2 −0 str.na
  13. +12 −0 tuple.h
  14. +108 −0 tuple.na
View
@@ -12,6 +12,7 @@ namodules := \
re.na \
str.na \
symbol.na \
+ tuple.na \
cmodules := vm.c mem.c gen.c prim.c
sources := $(cmodules) index.c $(namodules:.na=.na.c)
View
@@ -103,6 +103,8 @@ def array: sobj:
(assq name):
? (is? (self.car.car) name) (self.car) (self.cdr.assq name)
+ (frozen.): tuple.from (map [x.frozen] self)
+
def array-factory: sobj:
(run . args):
len = args.length
View
@@ -93,4 +93,6 @@ def int: sobj:
else:
(upper.str) / (table lower)
+ (frozen.) self
+
'()
View
@@ -466,7 +466,7 @@ def compile_smeth_body(meth, meth_entry):
compile_sequence(body, val_r, return_s, cenv, pop_all_symbol))
def munge_sym_to_c(name):
- return 'n_' + str(name).translate(maketrans('-*', '__'))
+ return 'n_' + str(name).translate(maketrans('-*!', '___'))
def make_c_undefine(name):
return '#undef %s /* %s */\n' % (munge_sym_to_c(name), name)
View
@@ -20,6 +20,7 @@ def nil: sobj:
(== x) (is? x nil)
(assq name) '()
(length.): 0
+ (frozen.) self
. '()
View
@@ -99,6 +99,7 @@ def (ensure try finally):
try:run.wait+ success failure
import array
+import tuple
def (map f a):
if (is? a '()): return a
@@ -1,8 +1,8 @@
-(intern:0 %:0 %:1 %:2 %:3 %:4 %:5 %:6 %:7 %:8 %:9 %:+ %*:1 find:1 find-from:2 starts-with?:1 head:1 tail:1 substring:2 ==:1 length:0 encode:0 run:1 /:1)
-(length:0 assq:1 ==:1 schedule:1 run:1 filter:1 str:0)
+(frozen:0 intern:0 %:0 %:1 %:2 %:3 %:4 %:5 %:6 %:7 %:8 %:9 %:+ %*:1 find:1 find-from:2 starts-with?:1 head:1 tail:1 substring:2 ==:1 length:0 encode:0 run:1 /:1)
+(frozen:0 length:0 assq:1 ==:1 schedule:1 run:1 filter:1 str:0)
(assq:1 ==:1 run:1 filter:1 length:0 cdr:0 car:0 set-cdr!:1)
(str:0)
-(str:0 **:1 %:1 /:1 *:1 -:1 +:1 >=:1 <:1 >:1 ==:1 cmp:1)
+(frozen:0 str:0 **:1 %:1 /:1 *:1 -:1 +:1 >=:1 <:1 >:1 ==:1 cmp:1)
(there:0 hi:0)
(a b c)
ok
No changes.
@@ -0,0 +1,4 @@
+x = (tuple.make 3)
+
+# attempt some sort of setting... lame.
+x 1 "hi"
View
@@ -0,0 +1,4 @@
+()
+hi
+hi
+hi
View
@@ -0,0 +1,13 @@
+x = (tuple.make 3)
+
+pr (x 1)
+
+y = (array.make 3)
+y.put! 1 "hi"
+
+pr (y.get 1)
+
+z = (tuple.from y)
+pr (z 1)
+zz = y.frozen
+pr (zz 1)
View
@@ -199,4 +199,6 @@ def str: sobj:
return intern_str(rcv);
end
+ (frozen.) self
+
. '()
View
@@ -0,0 +1,12 @@
+/* tuple.h - tuple type header */
+
+#ifndef tuple_h
+#define tuple_h
+
+datum make_tuple(uint len);
+
+int tuplep(datum x);
+datum tuple_get(datum arr, uint index);
+uint tuple_len(datum arr);
+
+#endif /*tuple_h*/
View
@@ -0,0 +1,108 @@
+
+inline C <<end
+#include "tuple.h"
+
+#define CLIP_LEN(l) ((l) & 0x0fffffff)
+
+datum
+make_tuple(uint len)
+{
+ datum p;
+
+ if (len < 1) return nil;
+ if (len != CLIP_LEN(len)) die("make_tuple -- too big");
+ p = make_record(len, mtab, nil, nil);
+ for (;--len;) p[len] = (size_t) nil;
+ return p;
+}
+
+datum
+tuple_get(datum arr, uint index)
+{
+ if (!tuplep(arr)) die1("tuple_get -- not an tuple", arr);
+ if (index >= datum_size(arr)) die("tuple_get -- index out of bounds");
+ return (datum) arr[index];
+}
+
+datum
+tuple_put(datum arr, uint index, datum val)
+{
+ if (!tuplep(arr)) die1("tuple_put -- not an tuple", arr);
+ if (index >= datum_size(arr)) die("tuple_put -- index out of bounds");
+ return (datum) (arr[index] = (size_t) val);
+}
+
+uint
+tuple_len(datum arr)
+{
+ return datum_size(arr);
+}
+
+int
+tuplep(datum x)
+{
+ return !(((size_t) x) & 1) && (((datum) x[-1]) == mtab);
+}
+
+end
+
+def tuple: sobj:
+ inline C (run i) <<end
+ int i;
+
+ if (!intp(n_i)) die1("tuple#get -- not an int", n_i);
+
+ i = datum2int(n_i);
+ return tuple_get(rcv, i);
+ end
+
+ inline C (length.) <<end
+ return int2datum(datum_size(rcv));
+ end
+
+ (filter f):
+ def rest ((self.cdr).filter f)
+ ? (f (self.car)):
+ cons (self.car) rest
+ . rest
+
+ (each f):
+ def (iter i):
+ if (i > self.length): return 'ok
+ if (i == self.length): return 'ok
+ f (self.get i)
+ iter (i + 1)
+ iter 0
+ . 'ok
+
+ (== p):
+ ? ((self.car) == (p.car)):
+ ? ((self.cdr) == (p.cdr)) true false
+ . false
+
+ (assq name):
+ ? (is? (self.car.car) name) (self.car) (self.cdr.assq name)
+
+def tuple-set!: obj:
+ inline C (run t i x) <<end
+ n_t[datum2int(n_i)] = (size_t) n_x;
+ return nil;
+ end
+
+def maker: obj:
+ inline C (make size) <<end
+ if (!intp(n_size)) die1("tuple.make -- not an int", n_size);
+ return make_tuple(datum2int(n_size));
+ end
+
+ (from container):
+ len = container.length
+ new = (maker.make len)
+ i = 0
+ for x in container:
+ if i > len: error "boo"
+ tuple-set! new i x
+ i = i + 1
+ new
+
+maker

0 comments on commit 3983955

Please sign in to comment.