Skip to content

Commit d876fbf

Browse files
authored
Add Bubble Sort in M4 (#4965)
1 parent cdfe602 commit d876fbf

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

archive/m/m4/bubble-sort.m4

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
divert(-1)
2+
define(`show_usage',
3+
`Usage: please provide a list of at least two integers to sort in the format "1, 2, 3, 4, 5"
4+
m4exit(`1')')
5+
6+
dnl Reference: https://www.gnu.org/software/m4/manual/m4.html#index-array
7+
dnl array_get(var_name, idx)
8+
define(`array_get', `defn(format(``%s[%s]'', `$1', `$2'))')
9+
10+
dnl array_set(var_name, idx, value)
11+
define(`array_set', `define(format(``%s[%s]'', `$1', `$2'), `$3')')
12+
13+
dnl array_swap(var_name, idx1, idx2):
14+
dnl t = var_name[idx1]
15+
dnl var_name[idx1] = var_name[idx2]
16+
dnl var_name[idx] = t
17+
define(`array_swap',
18+
`pushdef(`t', array_get(`$1', `$2'))dnl
19+
array_set(`$1', `$2', array_get(`$1', `$3'))dnl
20+
array_set(`$1', `$3', t)dnl
21+
popdef(`t')'dnl
22+
)
23+
24+
dnl is_valid(n)
25+
define(`is_valid', `eval(regexp(`$1', `^\s*-?[0-9]+\s*$') >= 0)')
26+
27+
dnl parse_int_list(varname, args):
28+
dnl varname[length] = 0
29+
dnl foreach arg in args:
30+
dnl if not is_valid(arg):
31+
dnl Return 0
32+
dnl varname[varname[length]] = arg
33+
dnl varname[length] = varname[length] + 1
34+
dnl Return 1
35+
define(`parse_int_list',
36+
`array_set(`$1', `length', 0)dnl
37+
_parse_int_list(`$1', $2)'dnl
38+
)
39+
define(`_parse_int_list',
40+
`ifelse(is_valid(`$2'), 0, `0',
41+
`array_set(`$1', array_get(`$1', `length'), `$2')dnl
42+
array_set(`$1', `length', incr(array_get(`$1', `length')))dnl
43+
ifelse(eval($# > 2), 1, `_parse_int_list(`$1', shift(shift($@)))', `1')'dnl
44+
)'dnl
45+
)
46+
47+
dnl show_int_list(varname):
48+
dnl for i = 0 to n-1:
49+
dnl if i > 0:
50+
dnl Output ", "
51+
dnl Output varname[i]
52+
define(`show_int_list', `_show_int_list(`$1', 0)')
53+
define(`_show_int_list',
54+
`ifelse(eval($2 < array_get(`$1', `length')), 1,
55+
`ifelse(eval($2 > 0), 1, `, ')dnl
56+
array_get(`$1', $2)`'dnl
57+
_show_int_list(`$1', incr($2))'`'dnl
58+
)'dnl
59+
)
60+
61+
dnl Reference: https://en.wikipedia.org/wiki/Bubble_sort#Pseudocode_implementation
62+
dnl bubble_sort(varname):
63+
dnl n = varname[length]
64+
dnl do:
65+
dnl swapped = false
66+
dnl for i from 1 to n-1:
67+
dnl if varname[i-1] > varname[i]:
68+
dnl swap(varname, i-1, i)
69+
dnl swapped = true
70+
dnl while swapped
71+
define(`bubble_sort', `ifelse(_bubble_sort_outer(`$1', 1, 0), 1, `bubble_sort(`$1')')')
72+
define(`_bubble_sort_outer',
73+
`ifelse(eval($2 < array_get(`$1', `length')), 0,
74+
`$3',
75+
`ifelse(_bubble_sort_inner(`$1', $2), 1,
76+
`_bubble_sort_outer(`$1', incr($2), 1)', `_bubble_sort_outer(`$1', incr($2), $3)'dnl
77+
)'dnl
78+
)'dnl
79+
)
80+
define(`_bubble_sort_inner',
81+
`ifelse(eval(array_get(`$1', decr($2)) <= array_get(`$1', $2)), 1,
82+
0, `array_swap(`$1', decr($2), $2)1'`'dnl
83+
)'dnl
84+
)
85+
86+
divert(0)dnl
87+
ifelse(eval(ARGC < 1 || len(ARGV1) < 1 || !parse_int_list(`arr', ARGV1)), 1, `show_usage()')dnl
88+
ifelse(eval(array_get(`arr', `length') < 2), 1, `show_usage()')dnl
89+
bubble_sort(`arr')dnl
90+
show_int_list(`arr')

0 commit comments

Comments
 (0)