shithub: mc

Download patch

ref: 48d725508d3c6759e9560c26f87de19acd5c5b59
parent: fd6413695a72cde96cbf0644083e06f65ecdec9f
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Aug 5 12:13:14 EDT 2017

Add support for a version distance metric.

--- a/mbld/main.myr
+++ b/mbld/main.myr
@@ -45,7 +45,7 @@
 	ok = true
 
 	bld.initopts()
-	for opt in cmd.opts
+	for opt : cmd.opts
 		match opt
 		| ('S', ""):	bld.opt_genasm = true
 		| ('I', arg):	std.slpush(&bld.opt_incpaths, arg)
@@ -62,7 +62,7 @@
 	path = std.pathcat(bld.opt_instbase, config.Libpath)
 	std.slpush(&bld.opt_incpaths, path)
 
-	for (e, v) in config.Env
+	for (e, v) : config.Env
 		std.setenv(e, v)
 	;;
 
@@ -91,7 +91,7 @@
 		if cmd.args.len == 0
 			ok = bld.buildtarg(b, "all")
 		else
-			for c in cmd.args
+			for c : cmd.args
 				match c
 				| "clean":	r = bld.clean(b)
 				| "install":	r = bld.install(b)
--- a/mbld/syssel.myr
+++ b/mbld/syssel.myr
@@ -9,7 +9,7 @@
 		line	: int
 		targ	: byte[:]
 		sysattrs	: std.htab(byte[:], (int, int, int))#
-		_match	: std.htab(byte[:], int)#
+		_match	: std.htab(byte[:], (int, int))#
 		_best	: std.htab(byte[:], @a)#
 	;;
 
@@ -60,9 +60,10 @@
 }
 
 generic sysseladdlist = {syssel, base, attrs, val
-	var nmatch, curbest, n, v
+	var nmatch, vscore, n, v, s
 
 	nmatch = 0
+	vscore = 0
 	for a : attrs
 		match std.strfind(a, ":")
 		| `std.Some i:
@@ -77,26 +78,47 @@
 		| `std.None:
 			nmatch = -1
 			break
-		| `std.Some av:
-			if newenough(syssel, av, v)
-				nmatch++
+		| `std.Some have:
+			s = versionscore(syssel, have, v)
+			if s < 0
+				nmatch = -1
+				break
 			;;
+			vscore += s
+			nmatch++
 		;;
 	;;
-	curbest = std.htgetv(syssel._match, base, -1)
-	if curbest < nmatch
-		std.htput(syssel._match, base, nmatch)
-		std.htput(syssel._best, base, val)
+	match std.htgetv(syssel._match, base, (-1, -1))
+	| (curbest, curscore):
+		if curbest < nmatch || (nmatch >= 0 && curbest == nmatch && curscore < vscore)
+			std.htput(syssel._match, base, (nmatch, vscore))
+			std.htput(syssel._best, base, val)
+		;;
 	;;
 }
 
-const newenough = {syssel, attr, vers
-	match (attr, vers)
+const versionscore = {syssel, have, want
+	var s
+
+	s = 0
+	match (have, want)
 	| ((a0, a1, a2), (v0, v1, v2)):
 		if a0 == -1 && a1 == -1 && a2 == -1
-			-> true
+			-> s
+		elif v0 == -1 && v1 == -1 && v2 == -1
+			-> s
 		else
-			-> a0 >= v0 && a1 >= v1 && a2 >= v2
+			s = 1_000_000 * (a0 - v0)
+			if s == 0
+				s += 1_000 * (a1 - v1)
+			;;
+			if s == 0
+				s += (a2 - v2)
+			;;
+			if s >= 0
+				s = 100_000_000 - s
+			;;
+			-> s
 		;;
 	;;
 }
@@ -107,7 +129,7 @@
 	keys = std.htkeys(syssel._match)
 	ret = [][:]
 	for k : keys
-		nmatch = std.htgetv(syssel._match, k, -1)
+		(nmatch, _) = std.htgetv(syssel._match, k, (-1, -1))
 		if nmatch == -1
 			std.fatal("{}:{}: target {}, no applicable file for '{}'\n", \
 				syssel.file, syssel.line, syssel.targ, k)