summaryrefslogtreecommitdiff
path: root/tnslc/c_wrap.tnsl
blob: eead086fd04f610f502149c6c87334b000c676da (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
asm "extern malloc"
asm "extern realloc"
asm "extern free"
asm "extern printf"

{}uint8 _alert = "Alert!"
uint _stop = 0

/; _alloc (uint size) [~void]
    ~void out
    # Mov size into proper register, and set all extras to zero
    asm "mov rax, 0"
    asm "mov rbx, 0"
    asm "mov rcx, r8"
    asm "mov rdx, 0"
    asm "mov rdi, 0"
    asm "mov rsi, 0"
    asm "mov r8, 0"
    asm "mov r9, 0"
    asm "mov r10, 0"
    asm "call malloc"
    # Set out to the returned value
    # (The compiler assignes spaces sequentially, and we have a uint in r8)
    asm "mov r9, rax"
    return out
;/

/; _realloc (~void ptr, uint new_size) [~void]
    ~void out
    # Mov ptr and new size into proper registers, and set all extras to zero
    asm "mov rax, 0"
    asm "mov rbx, 0"
    asm "mov rcx, r8"
    asm "mov rdx, r9"
    asm "mov rdi, 0"
    asm "mov rsi, 0"
    asm "mov r8, 0"
    asm "mov r9, 0"
    asm "mov r10, 0"
    # Do call
    asm "call realloc"
    # Set out to the returned value
    # (The compiler assignes spaces sequentially. We have a ptr in r8, and a uint in r9)
    asm "mov r10, rax"
    return out
;/

/; _delete (~void ptr)
    # setup call by clearing most values
    asm "mov rax, 0"
    asm "mov rbx, 0"
    asm "mov rcx, rax"
    asm "mov rdx, 0"
    asm "mov rdi, 0"
    asm "mov rsi, 0"
    asm "mov r8, 0"
    asm "mov r9, 0"
    asm "mov r10, 0"
    # do call
    asm "call free"
    # there's no more to do 'cause free returns nothing 
;/

/; _printf (~void str)
    # setup call by clearing most values
    asm "mov rcx, rax"
    asm "mov rdx, 0"
    asm "mov rdi, 0"
    asm "mov rsi, 0"
    asm "mov r8, 0"
    asm "mov r9, 0"
    asm "mov r10, 0"
    # do call
    asm "call printf"
    # there's no more to do 'cause free returns nothing 
;/

/; print_alert
    _printf(~_alert{0})
;/

struct Vector {
    uint
        el_size,
        num_el,
        dat_size,
    ~uint8 dat
}

/; method Vector

    /; resize (uint num_el)
        self.dat_size = num_el
        self.dat = _realloc(self.dat, num_el * self.el_size)
    ;/

    /; get (uint i) [~uint8]
        /; if (i !< self.num_el)
            return self.dat
        ;/
        return self.dat + (i * self.el_size)
    ;/

    /; set (uint i, ~uint8 data)
        ~uint8 index = self.get(i)
        /; loop (i = 0; i < self.el_size) [i++]
            index` = data`
            index++
            data++
        ;/
    ;/

    /; push (~uint8 data)
        self.set(self.num_el, data)
        self.num_el = self.num_el + 1
        /; if (self.num_el !< self.dat_size)
            self.resize(2 * self.dat_size)
        ;/
    ;/

    /; pop
        self.num_el = self.num_el - 1
        /; if (self.num_el !== 0 && self.num_el < self.dat_size / 4)
            self.resize(self.dat_size / 2)
        ;/
    ;/

    /; remove (int index)
        index++
        /; loop (index < self.num_el) [index++]
            self.set(index - 1, self.get(index))
        ;/
        self.pop()
    ;/

    /; start (int el_size)
        self.num_el = 0
        self.el_size = el_size
        self.dat_size = 1
        self.dat = _alloc(self.el_size)
    ;/

    /; clean
        self.num_el = 0
        self.el_size = 0
        self.dat_size = 0
        _delete(self.dat)
        self.dat = 0
    ;/
;/