aboutsummaryrefslogtreecommitdiff
path: root/compiler/main.slul
blob: 506f1e614013132ffe3119a92c930a4e34453550 (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

#
# 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 functions 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
    SomeType st
returns
    bool res
code
    int x = 4321
    unsigned y = 1111
    wrapping z = 2222
    int w
    long l
    unsigned long vul!
    signed byte sgb
    aliased SomeType st_aliased
    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
    # This is not allowed, since it would be ambiguous
    #g x - y
    # It should be written with parentheses
    signed m = -123
    g x (-m)
    g (x - y) y
    int use_return = g x (-m)
    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
        return 123 == 456
    end
    Thing t1
    bool b = get_bool
    assert false == false
    assert (1==2) == (3==4)
    assert (1==2) <> (3==3)
    assert (-1<>1) == true
    if false
        return true
    elif not (b == true)
        return false
    else
        return true
    end
    signed long lowest_int = -0x8000_0000_0000_0000
    unsigned long max_uint = 18446744073709551615
    String empty1 = ""
    String s1 = "test"
    String empty2 = ""
    String escapetest = "test\\ escapes «f?"
    String longstring = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"
    assert 0xffff_ffff_ffff_fffe + 1 > 0
    assert 65536*65536*65536*65535 > 0
    assert 8 / 2 == 4
    assert -3 * 5 == -15
    assert 7 / (0 - 3 - -2) == -7
    byte byte1 = 0
    byte byte2 = 255
    int int1 = 0
    int int2 = 2147483647
    signed sint1 = -2147483648
    signed sint2 = 2147483647
    unsigned uint1 = 0
    unsigned uint2 = 4294967295
    wrapping wint1 = 0
    wrapping wint2 = 4294967295
    long long1 = 0
    long long2 = 9223372036854775807
    signed long slong1 = -9223372036854775808
    signed long slong2 = 9223372036854775807
    unsigned long ulong1 = 0
    unsigned long ulong2 = 18446744073709551615
    wrapping long wlong1 = 0
    wrapping long wlong2 = 18446744073709551615
    byte mod1 = 1000 mod 256
    byte mod2 = -1000 mod 256
    byte mod3 = 255 mod 1000
    signed byte mod4 = 127 mod 321
    signed byte mod5 = -194 mod 321
    signed byte mod6 = 0 mod 1000
    int assign1!
    int assign2!
    assign1 = 123
    assign1 = assign2 = 456
    assert assign1 == 456
    #bool not_allowed = (assign1 = assign2)
    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 -333 < 222
    assert 1+2 <> 3+4 and 5*6 == (711*511)-363291
    assert -321 <> 321
    assert 11 - 0x22 + 33 + 4_4 - (0b101 - (55 - 66)) == 38
    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
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 y <= 0x3FFF_FFF8
    #assert x >= -0x10
    #assert x <= 0xF
    #return x + (2*y)
    return x
end

func get_bool
returns
    bool b
code
    return true
end