diff modules/array.tp @ 84:9811040704ac

Add support for llMessage:withVars:andCode and llProperty:withType for specifying low level code without having to stick C inside the compiler. Redo array built-in type to use this feature.
author Mike Pavone <pavone@retrodev.com>
date Sat, 21 Jul 2012 22:30:21 -0700
parents
children 547153211389
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/array.tp	Sat Jul 21 22:30:21 2012 -0700
@@ -0,0 +1,102 @@
+#{
+	llProperty: size withType: uint32_t
+	llProperty: storage withType: uint32_t
+	llProperty: data withType: ((object ptr) ptr)
+	llMessage: get withVars: {
+		index <- obj_int32 ptr
+	} andCode: :index {
+		if: (index num) >= 0 && (index num) < size {
+			(self data) get: (index num)
+		} else: {
+			false
+		}
+	}
+	
+	llMessage: set withVars: {
+		index <- obj_int32 ptr
+		value <- object ptr
+	} andCode: :index value {
+		if: (index num) >= 0 && (index num) < size {
+			data set: (index num) value
+		}
+		self
+	}
+	
+	llMessage: foreach withVars: {
+		clos <- lambda ptr
+		i <- uint32_t
+		index <- obj_int32 ptr
+	} andCode: :clos {
+		i <- 0
+		while: { i < size } do: {
+			index <- make_object: (addr_of: obj_int32_meta) NULL 0
+			index num!: i
+			ccall: clos 2 index (data get: i)
+			i <- i + 1
+		}
+		self
+	}
+	
+	llMessage: append withVars: {
+		value <- object ptr
+		tmp <- (object ptr) ptr
+	} andCode: :value {
+		if: storage = size {
+			storage <- storage * 2
+			tmp <- GC_REALLOC: data storage * (sizeof: (object ptr))
+			if: (not: tmp) {
+				fputs: "Failed to increase array size\n" stderr
+				exit: 1
+			}
+			data <- tmp
+		}
+		data set: size value
+		size <- size + 1
+		self
+	}
+	
+	llMessage: length withVars: {
+		intret <- obj_int32 ptr
+	} andCode: {
+		intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+		intret num!: size
+		intret
+	}
+	
+	fold:with <- :acc :fun {
+		foreach: self :idx el {
+			fun: acc el
+		}
+	}
+	
+	foldr:with <- :acc :fun {
+		idx <- length - 1
+		while: {idx >= 0} do: {
+			fun: acc (get: idx)
+		}
+	}
+	
+	map <- :fun {
+		new <- #[]
+		foreach: self :idx el {
+			new append: (fun: el)
+		}
+	}
+	
+	find:withDefault <- :pred :default{
+		idx <- 0
+		l <- length
+		ret <- default
+		while: {idx < l} do: {
+			v <- get: idx
+			if: (pred: v) {
+				ret <- #{
+					key <- idx
+					value <- v
+				}
+				idx <- l
+			}
+		}
+		ret
+	}
+}