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
|