summaryrefslogtreecommitdiff
path: root/bos-sugar.sh
blob: add408aefa16ab2ac1fbb9ab84e5c8e21b4731b6 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!bash 
 
declare -a bos_sugar_block_stack
 
function bos-sugar/push() {
    bos_sugar_block_stack+=( 0 )
}
 
function bos-sugar/block-and-pop() {
    local on_open="$1"; shift
    local on_close="$1"; shift
 
    if [[ "${bos_sugar_block_stack[-1]}" == 0 ]]; then
        bos_sugar_block_stack[-1]=1
        "$on_open" "$@" && return 0
    else
        unset "bos_sugar_block_toggle[-1]"
        "$on_close" "$@" && return 1
    fi
}
 
function bos-sugar/declare-block() {
    local block_name="$1"
    local open_func="$2"
    local close_func="$3"
 
    shopt -s expand_aliases
 
    eval "alias $1='bos-sugar/push; while bos-sugar/block-and-pop $open_func $close_func'"
}
 
# ---- 
 
function bos-sugar/declare-helpers() {
    function extends() {
        local fq_class; bos-namespaces/current-namespace-into fq_class
        local metaclass_instance; bos-meta/metaclass-instance-for-class-into metaclass_instance "$fq_class"
        $metaclass_instance set-superclasses-for "$fq_class" "$@"
    }
}
 
function bos-sugar/remove-helpers() {
    unset extends
}
 
function bos-sugar/class-open() {
    if [[ "${#*}" -lt 1 || "${#*}" -gt 2 ]]; then
        bos/log 1 "'class \$class_name [\$metaclass]; do …; done', not 'class $*'"
        return 1
    fi
    local class="$1"
    local metaclass="${2:-bos/meta/class}"
 
    bos-sugar/declare-helpers
 
    bos-namespaces/namespace-open "$1"
 
    local fq_class; bos-namespaces/current-namespace-into fq_class
    local class_open_metaclass_instance; $metaclass new-into class_open_metaclass_instance
 
    bos-meta/set-metaclass-instance-for "$fq_class" "$class_open_metaclass_instance"
 
    return 0
}
 
function bos-sugar/class-close() {
    local class="$1";
 
    local fq_class; bos-namespaces/current-namespace-into fq_class
 
    bos-namespaces/namespace-close
 
    local class_close_metaclass_instance; bos-meta/metaclass-instance-for-class-into class_close_metaclass_instance "$fq_class"
 
    $class_close_metaclass_instance make-mro-for "$fq_class"
 
    # TODO this should probably be done by the metaclass?
    eval "function $fq_class { bos-dispatch/invoke \"$fq_class\" 0 \"\$@\"; }"
 
    bos-sugar/remove-helpers
 
    return 0
}
 
bos-sugar/declare-block class bos-sugar/class-open bos-sugar/class-close
 
function bos-sugar/namespace-open() {
    if [[ "${#*}" -ne 1 ]]; then
        bos/log 1 "'namespace \$namespace_name; do …; done', not 'namespace $*'"
        return 1
    fi
 
    bos-namespaces/namespace-open "$1"
 
    return 0
}
 
function bos-sugar/namespace-close() {
    bos-namespaces/namespace-close
 
    return 0
}
 
bos-sugar/declare-block namespace bos-sugar/namespace-open bos-sugar/namespace-close