-
Notifications
You must be signed in to change notification settings - Fork 0
/
overview.kek
417 lines (308 loc) · 9.67 KB
/
overview.kek
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# single line comment
##
Multi line comment
-> Commas are optional
Code is organized in files.
Files can be imported using use.
Usually just git clone the repos.
Otherwise just paste the code files/libs.
-> Dont make packages to easy to add, so we dont end
up in the same mess as npm.
##
##
You can set rules for all scopes
Scopes inherit the rules from the parent scope
##
use RuleSet(
no_fuck_around = true
)
##
Use called as a function
imports a module
-> it only loads the module once
-> modules never contain logic.
Except for the main module
##
# if you load a type into an alias it needs to be an upper case letter
# Files also need to start with an upper case letter
Std :: import("std") # load the whole std module into this const
out :: import("std.fmt").out
MyClass :: import("./path/to/file/with/MyClass").MyClass
# the type of a const with a module within is a "module"
# then function, struct, trait, or some other value
# module constants are special, in that they can be called to get their consts
# but only the exported ones
# modules can span multiple files, but they need to be
# in the same module directory.
my_const :: 1
my_fn :: fn(a:Int b:Int) -> Int {
return a + b
}
MyEnum :: enum{ KEK::1 LOL::2 ROFL::3 }
##
A trait is basically a interface, as well as a code reuse
vehicle for object composition.
This depends on the use.
##
MyTrait :: trait{
field: Int
static_field :: 123
abstract_method : Fn(Self)->String
abstract_static_method :: Fn()->String
method_to_share : fn(self){
out( self.field )
}
}
# structs and traits NEED TO BE UpperCase
##
Structs allow to structure data.
You can use traits to compose structs or to
ensure functionality on structs.
Structs can have methods and static methods, so
a struct can also act as a name-space.
##
MyStruct :: struct{
use MyTrait
# this adds all the runtime type info
# methods and data to this struct.
use RuntimeTypeInformation
some_other_field: Int
abstract_method : fn(self) -> String {
return "implemented" + self.field
}
# scope is the static scope of the struct definition
abstract_static_method :: fn(scope)->String {
return "implemented" + scope.static_field
}
}
GenericTrait :: trait(T){
field: T
method :: fn(self) -> T
}
GenericStruct :: trait(T: TraitThisTypeNeedsToImplement){
field: T
method :: fn(self) -> T
}
# generic struct
MyGenericStruct :: struct(
T1: TraitThisTypeNeedsToImplement
T2: TraitThisTypeNeedsToImplement
){
field: T1
field2: T2
method :: fn(self) -> T1 {
return self.field
}
}
Utils :: struct(RuleSet(namespace = true)){
RuleSet(namespace = true) # this struct can only contain static methods and other static field values
add :: fn(a:Int b:Int) -> Int {
return a + b
}
}
# we can use ruleset to disable the creation of an struct via literal
# or even make fields private
ILoveOOP :: struct{
use RuleSet(
outside_literal_creation = false
)
a: Bool
b: MyStruct
new :: fn() -> self {
return self(
a = false,
b = MyStruct()
)
}
}
# we can put together rulesets
# the ruleset itself has the const-values only rule
# so you cannot put in expressions, only literals
strict_function_rules :: RuleSet(
allow_variables = false
)
# functions can only see const values from the top level scope
foo :: fn(){
# nice we can set the rules for our function
use strict_function
}
other_foo :: fn(){
# nice we can set the rules for our function
use strict_function
}
number_guess :: fn(number: Int) -> Union(Bool, Error, String){
if number < 0 {
return ->(bool = false) #-> shorthand for return type construction literal Union(Bool, Error, String)
# return Union(Bool, Error, String)(bool = false)
}elif number > 100 {
return ->(error = Error("You suck"))
}else{
return ->(string = "Eat Ass!")
# return -> induces the return type
}
}
get_option :: fn() -> Option(MyStruct) {
return ->(some = false)
}
main :: fn(){
local_const :: MyStruct(
field = 124
some_other_field = 124
)
variable := MyStruct(
field = 124
some_other_field = 124
)
variable.field = 99999
if my_struct := get_option?value {
out("nice we got a value")
}else{
out("bad...")
}
myList := List(MyStruct)()
myMap := Map(String MyStruct)(
"Kacke" = MyStruct(
field = 124
some_other_field = 124
)
)
myList2 := List(Int)(1 2 (3-4) 5 6 7 8 9)
# the -> before a ( means assume the type of the construction literal from the left hand side
localf :: fn(a: List(Int)){}
localf(->(1 2 3 4 5 6 7))
for i := 0 .. myList2.len {
out(i)
}
for i := 0 .. myList2.len; 2{
out(i)
}
if(b := number_guess()?bool){
out("we got " + b)
}elif(s := _?string){
out(s)
}elif(err := _?error){
out(err.message)
out(err.traceback)
}
b := 14
{
a := 124 + b
}
# a is not defined here
(){
a := 124 # b isnot defined here
# since the () makes this a capture block
}
a := ->( 1 2 4 5 6 ) # type induced
tuple := ->(1 true "kek" 1.2) # type == Tuple(Int, Bool, String, Float)
b :: ->(
"KEK" = "LOL"
)
needs_vector(->(x=2 y=3 z=4))
(b){
a := 124 + b
}
{
a := (b) -> { # this is a return block
return 124 + b
}
{
a := -> { # this is a return block
return 124 + b
}
}
}
}
##
Local keyword
-> before a field means
that this field can not leave the scope
-> so it is basically an private field
-> local in a function means that the variable
can not be set to any value from outside the
using scope.
-> this means, that if we share a reference we know
that it will not appear in another portion of persistent
state.
##
local_struct :: struct{
# field definitions
aa : Int
aa : Int
aaa : Int
private_const : local const Int
a : local Int
b : local Int
my : local MyStruct
##
My struct can be read but not set to a leaking field outside the scope
Only to a local field in the calling scope
##
get_my_as_local :: fn() -> local MyStruct {
local_const_field :: local MyStruct(
field = 124
some_other_field = 124
)
local_variable_field := local MyStruct(
field = 124
some_other_field = 124
)
out(local_const_field.field)
return my
}
# now MyStruct can not even be changed by the calling scope
# and only be assigned to local const values
get_my_as_local_const :: fn() -> local const MyStruct {
return my
}
get_readonly_param :: fn(
localParam: local MyStruct
){}
get_readonly_param :: fn(readOnlyParam: const MyStruct){
}
get_readonly_param :: fn(readOnlyParamNoLeak: local const MyStruct){
}
}
pure_function :: fn(a: local const MyStruct) -> local const MyStruct {
return a
}
instances :: List(MyStruct)
{
instances.append(MyStruct(
field = 124
some_other_field = 124
))
local my_struct := MyStruct(
field = 124
some_other_field = 124
)
instances.append(my_struct) # this is not allowed
local mys2 = my_struct.getmy_as_local() # this is allowed
instances.append(my_struct) # this is not allowed
# error would be: Type-Error local value my_struct is not allowed to leave the scope
# append would need to consume a local value
# but this is not the case with append, since
# append would assign the value to the inner state
# local in the variable list is the promise that the variable
# will not be set to from outside the scope
# so if the function has concluded
# no references to the passed in variable will exist
mf :: fn(m: local MyStruct) {
out(m.field)
}
# const means value cannot be changed
# but could "leave the scope"
# maybe we can create "managed" values?
# which are refernce counted??
}
# offer full c interop by offering pointers and structs
# pointer are disabled in modules by default but can be
# enabled.
# so we can write code that calls s code directly in kek
# do we need a cfn keyword to define the c functions
# cfn
# ?
# or can we use Ptr() or Addr() as special type for this case?
# MemoryArray() -> C-array
# usw.
}