aboutsummaryrefslogtreecommitdiff
path: root/compiler/misc.slul
blob: dd9d03a944235bda222b4908ccb45e194de43aff (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

#
# Currently this is just a dummy/placeholder file.
#
# Copyright © 2025 Samuel Lidén Borell <samuel@kodafritt.se>
#
# SPDX-License-Identifier: EUPL-1.2+ OR LGPL-2.1-or-later
#


# Problems:
#
# - Want to be able to have variables in the main file also,
#   so it has to be a class.
# - Should it be possible to pass around the Main object?
# - Should it be possible to support event-driven flows?
#   e.g. for GUI programs, or for phone apps (that can be stopped/
#   started by decisions by the OS), or for services (also start/stop),
#   or for socket-activated stuff (could allow multiple activations
#   per instance/process), or FastCGI, etc...
#
# Should the main file be:
#    1. a special case
#    2. an external extension of an abstract class
#    3. a standard class that has a `main` method that takes some
#       parameter with the main class?
#    4. a standard class that has a `start` method that takes the
#       main class (and e.g. stores it in an instance variable),
#       plus "event" methods? or the possibility to register events?

func testfunc
    String s
    SomeClass! sc
returns
    bool res
code
    int x = 4321
    unsigned y = 1111
    unsigned z = 2222
    int w
    w = 3333
    aliased SomeClass! sc_aliased = sc
    SomeClass sc2 = new
    sc2 = new_with_n 123
    assert sc2.n == 123
    assert sc == sc_aliased
    assert sc.b
    assert sc.b == true
    # Test of incompatible types
    #assert sc.b == ""
    return true and false
    return true or false
    return (true and false) or true
    return 123 == 999 or 123 == 123
    return not (true or (not false))
    f x (g y z) w
    # Negation inside function arguments has to be written as follows:
    #     f x (-y)
    # However, the bootstrap compiler doesn't support signed integers.
    g x y
    g (x - y) y
    int use_return = g x y
    assert use_return == 4321
    assert (g x y) == 4321
    #assert g x y == 4321  # <-- TODO make this work
    # FIXME emit correct constness of function's `this` parameters
    assert sc.get_count == 123
    sc.get_count_and_add 10
    assert (sc.get_count_and_add 10) == 133
    assert 133 == (sc.get_count_and_add 10)
    assert (sc.get_count_and_add 10) + 0 == 133
    assert 0 + (sc.get_count_and_add 10) == 133
    #assert sc.get_count_and_add 10 == 133  # <-- TODO make this work
    #assert 123 == sc.get_count_and_add 10  # <-- TODO make this work
    while false
        while false
            # Not allowed, since it would shadow another variable
            #int x = 123
            break
        end
        break
    loopempty
        return false
    loopend
        return false
    end
    for Thing t in 123  # FIXME should be an array, iterator or iterable
        Thing t1
        t1 = t
        assert t1 == t
        return 123 == 456
    end
    bool b = get_bool
    assert false == false
    assert (1==2) == (3==4)
    assert (1==2) <> (3==3)
    assert (0<>1) == true
    assert s <> "no"
    if false
        # FIXME commenting out this leads to a segfault
        return true
    elif not (b == true)
        return false
    else
        return true
    end
    int lowest_int = 0
    unsigned max_uint = 4294967295
    assert lowest_int == 1 - 1
    assert max_uint == 0xFFFF_FFFF
    String empty1 = ""
    String s1 = "test"
    String empty2 = ""
    String escapetest = "test\\ escapes «f?"
    String longstring = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"
    assert empty1 == empty2
    assert s1 == "test"
    assert escapetest <> longstring
    assert longstring == longstring
    assert 0xffff_fffe + 1 > 0
    assert 65536*65535 > 0
    assert 8 / 2 == 4
    assert 3 * 5 == 15
    assert 7 / (10 - 4 - 5) == 1
    int int1 = 0
    int int2 = 2147483647
    assert int1 == 0
    assert int2 == 0x7FFF_FFFF
    unsigned uint1 = 0
    unsigned uint2 = 4294967295
    assert uint1 == 0
    assert uint2 == 0xFFFF_FFFF
    int mod1 = 1000 mod 256
    int mod2 = 255 mod 1000
    int mod3 = 127 mod 321
    int mod4 = 0 mod 1000
    assert mod1 == 232
    assert mod2 == 255
    assert mod3 == 127
    assert mod4 == 0
    int assign1!
    int assign2!
    assign1 = 123
    assign1 = assign2 = 456
    assert assign1 == 456
    assert assign2 == 456
    #bool not_allowed = (assign1 = assign2)
    # Also not allowed:
    #assert assign1 = 123
    if true
    end
    switch max_uint
    end
    switch max_uint
    case 1
        return true
    case 2
        return false
    # TODO multi-valued cases
    # this is tricky to do safely, because `case 1` immediately followed by
    # `case 2` can happen if all statements in the block of `case 1` have
    # been commented out.
    # options:
    # 1. special handling if multiple cases appear on consecutive lines.
    # 2. multiple values separated by spaces
    # 3. multiple values in array literals? (this would make it impossible
    #    to add support for switching on arrays)
    end
    switch max_uint
    default
        return true
    end
    switch max_uint
    case 1
        return true
    default
        return false
    end
    assert 111 < 222
    assert 1+2 <> 3+4 and 5*6 == (711*511)-363291
    assert 321 <> 320
    assert 11 + 0x22 - 33 + 4_4 - (0b11011 - (66 - 55)) == 40
    return true # TODO check for presence of return in all code paths
section sec1
    return true
    if true
        return false
    end
    return true
section done
    return false
    return true
section fail
    return false
end

# TODO multiple return values are not yet implemented
ignore
func other
    A a1
    A a2
    B b
returns
    A x
    B y
end

func noargs
code
end

func f
    int arg1
    int arg2
    int arg3
code
    assert arg1 <> 999
    assert arg2 <> 999
    assert arg3 <> 999
end

func f2
    int n
code
    assert n == 2
end

func g
    int x
    int y
returns
    int ret
code
    # TODO varstate tracking
    assert y <= 0x3FFF_FFF8
    assert x <= 0xF
    #return x + (2*y)
    return x
end

func get_bool
returns
    bool b
code
    return true
end