-
Notifications
You must be signed in to change notification settings - Fork 0
/
c3-mro
executable file
·61 lines (59 loc) · 2.8 KB
/
c3-mro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env bash
# ---
# This file is automatically generated from c3-mro.md - DO NOT EDIT
# ---
# MIT License
#
# Copyright (c) 2023 PJ Eby
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
# modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
declare -gA c3_mro c3_cache=() c3_seen=()
c3::call(){ ${c3_cache["$2$1"]-c3::invoke "$1" "$2"} "${@:3}";}
c3::super(){ : "${1#*<$2>}"; ${c3_cache["$3$_"]-c3::invoke "$_" "$3"} "${@:4}";}
c3::invoke(){ REPLY= c3::find-method "$1" "$2"; ${c3_cache["$2$1"]-c3::unknown-method "$1" "$2"} "${@:3}";}
c3::find-method(){
REPLY=("${c3_cache["$2$1"]-}");${REPLY:+return};REPLY=${1%%>*};REPLY=${REPLY#<}::$2
c3_seen["$REPLY"]=
if c3::exists "$REPLY"||{ [[ ${1#*>} ]]&& c3::find-method "${1#*>}" "$2";}
then c3_cache["$2$1"]=$REPLY; else REPLY=; false; fi
}
c3::unknown-method(){ echo -n "Unknown method: $2 in $*; at ";caller 3;exit 70;} >&2
c3::resolve(){
local -n mro=c3_mro["$1"]
case $# in 1|2) mro="<$1>${2:+${c3_mro[$2]=<$2>}}";; 0) return;;
*) printf -v mro '<%s>' "$@"; c3::mixin mro "${@:2}"
esac
}
c3::mixin(){
local REPLY t m=(); for t in "${@:2}"; do m+=("${c3_mro[$t]=<$t>}"); done
c3::merge ${m[@]+"${m[@]}"} "${!1}" && printf -v "$1" %s "$REPLY"
}
c3::merge(){
if (($#==1)); then REPLY=("$1"); return; fi
local list head f=$-; set -f; REPLY=("")
while (($#)); do
for list; do
[[ $list ]] || continue; head="${list%%>*}>"
if [[ "$*" == "${*/">$head"*/}" ]]; then
REPLY[0]+=$head; set -- ${*//"$head"/}; continue 2
fi
done
break # error, can't merge
done
[[ $f == *f* ]] || set +f
((!$#)) # fail if unmerged args
}
c3::defun(){ [[ $1 != *::* ]]||c3::exists "$1"||${c3_seen["$1"]+c3::methods-changed};eval "$1(){ ${2:-:}"$'\n}';}
c3::methods-changed(){ c3_cache=(); c3_seen=();}
c3::undef(){ local m; for m; do c3::exists "$m" && unset -f "$m" && ${c3_seen["$m"]+c3::methods-changed} ||:; done;}
c3::exists(){ declare -pF "$1" &>/dev/null;}