1*d5e0a182SSimon J. Gerraty# $NetBSD: hanoi-include.mk,v 1.5 2023/10/19 18:24:33 rillig Exp $ 2956e45f6SSimon J. Gerraty# 3954401e6SSimon J. Gerraty# Implements the Towers of Hanoi puzzle, demonstrating a bunch of more or less 4954401e6SSimon J. Gerraty# useful programming techniques: 5956e45f6SSimon J. Gerraty# 6956e45f6SSimon J. Gerraty# * default assignment using the ?= assignment operator 79f45a3c8SSimon J. Gerraty# * including the same file recursively (rather unusual) 8956e45f6SSimon J. Gerraty# * extracting the current value of a variable using the .for loop 9956e45f6SSimon J. Gerraty# * using the :: dependency operator for adding commands to a target 10956e45f6SSimon J. Gerraty# * on-the-fly variable assignment expressions using the ::= modifier 11956e45f6SSimon J. Gerraty# 12956e45f6SSimon J. Gerraty# usage: 13954401e6SSimon J. Gerraty# env N=3 make -r -f hanoi-include.mk 14954401e6SSimon J. Gerraty# 15*d5e0a182SSimon J. Gerraty# Specifying N in the command line instead of in the environment would produce 16*d5e0a182SSimon J. Gerraty# an endless loop, since variables from the command line cannot be overridden 17*d5e0a182SSimon J. Gerraty# by global variables: 18954401e6SSimon J. Gerraty# make -r -f hanoi-include.mk N=3 19956e45f6SSimon J. Gerraty 20956e45f6SSimon J. GerratyN?= 5 # Move this number of disks ... 21956e45f6SSimon J. GerratyFROM?= A # ... from this stack ... 22956e45f6SSimon J. GerratyVIA?= B # ... via this stack ... 23956e45f6SSimon J. GerratyTO?= C # ... to this stack. 24956e45f6SSimon J. Gerraty 254fde40d9SSimon J. Gerraty# Since make has no built-in arithmetic functions, convert N to a list of 264fde40d9SSimon J. Gerraty# words and use the built-in word counting instead. 274fde40d9SSimon J. Gerraty.if ${N:[#]} == 1 284fde40d9SSimon J. GerratyN:= count ${:U:${:Urange=$N}} # 'count' + one word for every disk 294fde40d9SSimon J. Gerraty.endif 304fde40d9SSimon J. Gerraty 314fde40d9SSimon J. Gerraty.if ${N:[#]} == 2 32956e45f6SSimon J. Gerraty. for from to in ${FROM} ${TO} 33956e45f6SSimon J. Gerratyall:: 34956e45f6SSimon J. Gerraty @echo "Move the upper disk from stack ${from} to stack ${to}." 35956e45f6SSimon J. Gerraty. endfor 36956e45f6SSimon J. Gerraty.else 374fde40d9SSimon J. Gerraty_:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}} 38956e45f6SSimon J. Gerraty. include "${.PARSEDIR}/${.PARSEFILE}" 394fde40d9SSimon J. Gerraty_:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${TO}} ${TO::=${TMP}} 40956e45f6SSimon J. Gerraty 41956e45f6SSimon J. Gerraty. for from to in ${FROM} ${TO} 42956e45f6SSimon J. Gerratyall:: 43956e45f6SSimon J. Gerraty @echo "Move the upper disk from stack ${from} to stack ${to}." 44956e45f6SSimon J. Gerraty. endfor 45956e45f6SSimon J. Gerraty 464fde40d9SSimon J. Gerraty_:= ${N::=${N:[1..-2]}} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}} 47956e45f6SSimon J. Gerraty. include "${.PARSEDIR}/${.PARSEFILE}" 484fde40d9SSimon J. Gerraty_:= ${N::+=D} ${TMP::=${VIA}} ${VIA::=${FROM}} ${FROM::=${TMP}} 49956e45f6SSimon J. Gerraty.endif 50