shithub: femtolisp

Download patch

ref: c3958c2e17268358e7a228871b7b1cbe73f7734e
parent: bb2fbaf5bfc89548c026bc07e90fd2baaea9366e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Dec 17 20:44:34 EST 2024

length: return number of entries in a hash table

Fixes: https://todo.sr.ht/~ft/femtolisp/25

--- a/builtins.c
+++ b/builtins.c
@@ -6,6 +6,7 @@
 #include "operators.h"
 #include "cvalues.h"
 #include "timefuncs.h"
+#include "table.h"
 #include "random.h"
 
 #define DBL_MAXINT (1LL<<53)
@@ -86,10 +87,6 @@
 	value_t a = args[0];
 	cvalue_t *cv;
 
-	if(isvector(a))
-		return fixnum(vector_size(a));
-	if(a == FL_nil)
-		return fixnum(0);
 	if(iscons(a)){
 		size_t n = 0;
 		value_t v = a, v2 = a;
@@ -103,7 +100,7 @@
 		if(iscons(v2))
 			return mk_double(D_PINF);
 		n += llength(v);
-		return fixnum(n);
+		return size_wrap(n);
 	}
 	if(iscprim(a)){
 		cv = ptr(a);
@@ -114,6 +111,21 @@
 	}
 	if(iscvalue(a) && cv_class(ptr(a))->eltype != nil)
 		return size_wrap(cvalue_arraylen(a));
+	if(isvector(a))
+		return size_wrap(vector_size(a));
+	if(ishashtable(a)){
+		htable_t *h = totable(a);
+		void **t = h->table;
+		size_t sz = h->size;
+		size_t n = 0;
+		for(size_t i = 0; i < sz; i += 2){
+			if(t[i+1] != HT_NOTFOUND)
+				n++;
+		}
+		return size_wrap(n);
+	}
+	if(a == FL_nil)
+		return fixnum(0);
 	type_error("sequence", a);
 }
 
--- a/table.c
+++ b/table.c
@@ -176,12 +176,12 @@
 	argcount(nargs, 3);
 	value_t f = args[0], zero = args[1], t = args[2];
 	htable_t *h = totable(t);
-	size_t i, n = h->size;
+	size_t n = h->size;
 	void **table = h->table;
 	fl_gc_handle(&f);
 	fl_gc_handle(&zero);
 	fl_gc_handle(&t);
-	for(i = 0; i < n; i += 2){
+	for(size_t i = 0; i < n; i += 2){
 		if(table[i+1] != HT_NOTFOUND){
 			zero = fl_applyn(3, f, (value_t)table[i], (value_t)table[i+1], zero);
 			// reload pointer