summaryrefslogtreecommitdiff
path: root/bos-sugar.sh
blob: a199ed933f87b9f139f1859a343fe2797922e480 (plain)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!bash 
 
declare -a bos_sugar_block_toggle
 
function bos-sugar/block() {
    local on_open="$1"; shift
    local on_close="$1"; shift
    local depth="${#FUNCNAME[*]}"
    if [[ -z "${bos_sugar_block_toggle[$depth]}" ]]; then
        bos_sugar_block_toggle=( ["$depth"]=1 )
        "$on_open" "$@"
    else
        unset "bos_sugar_block_toggle[$depth]"
        "$on_close" "$@"
    fi
}
 
declare -a bos_sugar_class_stack
 
function bos-sugar/current-class-into() {
    local -n bos_sugar_current_class_result="$1"
    local IFS=/
    bos_sugar_current_class_result="${bos_sugar_class_stack[*]}"
}
 
function bos-sugar/set-metaclass-for-current-class() {
    local class; bos-sugar/current-class-into class
    local metaclass_ref; bos-namespaces/store-scalar-for-into meta "$class" metaclass_ref
    local -n metaclass_object="$metaclass_ref"
    metaclass_object='bos-dispatch/invoke bos/mop/inheritance 0'
}
 
function bos-sugar/class-open() {
    if [[ "${#*}" -gt 1 ]]; then
        >&2 echo "'class \$class_name; do …; done', not 'class $*'"
        return 1
    fi
    local class="$1"
    bos_sugar_class_stack+=( "$class" )
    bos-sugar/set-metaclass-for-current-class
    local fq_class; bos-sugar/current-class-into fq_class
 
    function extends() {
        local fq_class; bos-sugar/current-class-into fq_class
        local metaclass_ref; bos-namespaces/store-scalar-for-into meta "$fq_class" metaclass_ref
        local -n metaclass_object="$metaclass_ref"
        $metaclass_object set-superclasses-for "$fq_class" "$@"
    }
 
    eval "function $fq_class { bos-dispatch/invoke \"$fq_class\" 0 \"\$@\"; }"
 
    bos-namespaces/start "$fq_class"
 
    # this will get renamed into the class
    function new-into() {
        local class _; bos-object/unpack-self-into "$self" class _
        local -n new_into_result="$1"; shift
        local metaclass_ref; bos-namespaces/store-scalar-for-into meta "$class" metaclass_ref
        local -n metaclass_object="$metaclass_ref"
 
        local new_object
        $metaclass_object create-object-into new_object "$class"
 
        new_into_result="$new_object"
    }
 
    return 0
}
 
function bos-sugar/class-close() {
    local class="$1"
 
    local fq_class; bos-sugar/current-class-into fq_class
    local metaclass_ref; bos-namespaces/store-scalar-for-into meta "$fq_class" metaclass_ref
    local -n metaclass_object="$metaclass_ref"
 
    local -a methods_list; bos-namespaces/list-new-funcs-into "$fq_class" methods_list
    bos-namespaces/qualify-funcs "$fq_class" "${methods_list[@]}"
 
    $metaclass_object make-mro-for "$fq_class"
 
    unset "bos_sugar_class_stack[-1]"
 
    return 1
}
 
shopt -s expand_aliases
 
alias class='while bos-sugar/block bos-sugar/class-open bos-sugar/class-close'