-
Notifications
You must be signed in to change notification settings - Fork 2
/
library.sc
2216 lines (1919 loc) · 71.7 KB
/
library.sc
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
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
module ScratchLibrary
/**
* Actor that models the environment, in particular inputs from the
* user using keyboard and mouse and a corresponding event dispatcher loop.
*/
actor IOActor is RuntimeEntity begin
/**
* The current mouse position
*/
declare mouseX as integer
declare mouseY as integer
declare mouseDown as boolean
declare lastMouseDown as boolean
declare mouseClicked as boolean
/**
* Key code of the currently pressed key
*/
declare keyPressed as integer
declare lastKeyPressed as integer
/**
* The last answer given to an `ask` block
*/
declare integerAnswer as integer
declare askActive as boolean
define atomic beginAsk() begin
// declare nondetStr as string
// define answer as nondetStr
declare nondetInt as integer
define integerAnswer as nondetInt
declare inputDurationSecs as integer
assume inputDurationSecs > 0
assume inputDurationSecs < 30
define askActive as true
// ATTENTION/FIXME: The following wait statement should allow to interleave other threads
wait inputDurationSecs seconds
// UNSOUND: might wait arbitrarily long
end
script on bootstrap do begin
define askActive as false
define keyPressed as 0
define lastKeyPressed as 0
end
script on message "ASK" () in "SYSTEM" do begin
beginAsk()
define askActive as false
end
/**
* The event-dispatcher loop that models the timing
* of keyboard and mouse inputs.
*/
script messageDispatcherLoop on startup do begin
// Hack as long no other dispatch handling is in place
repeat forever begin
atomic begin
declare nondetX as integer
define mouseX as nondetX
declare nondetY as integer
define mouseY as nondetY
declare nondetKey as integer
define keyPressed as nondetKey
declare nondetDown as boolean
define mouseDown as nondetDown
define mouseClicked as mouseDown and not lastMouseDown
end
if mouseClicked then begin
broadcast "CLICK" () to "SYSTEM"
end
if keyPressed = 37 then begin
broadcast "KEY_37_PRESSED" () to "SYSTEM"
end else if keyPressed = 38 then begin
broadcast "KEY_38_PRESSED" () to "SYSTEM"
end else if keyPressed = 39 then begin
broadcast "KEY_39_PRESSED" () to "SYSTEM"
end else if keyPressed = 40 then begin
broadcast "KEY_40_PRESSED" () to "SYSTEM"
end
define lastKeyPressed as keyPressed
define lastMouseDown as mouseDown
end
end
end
/**
* Functionality to deal with keyboard inputs.
* In particular the mapping between key codes and the
* corresponding Scratch key identifiers.
*/
role KeyboardIO begin
declare KEY_ANY as integer
declare KEY_ENTER as integer
declare KEY_SPACE as integer
declare KEY_LEFT as integer
declare KEY_UP as integer
declare KEY_RIGHT as integer
declare KEY_DOWN as integer
define KEY_ANY as 0
define KEY_ENTER as 13
define KEY_SPACE as 32
define KEY_LEFT as 37
define KEY_UP as 38
define KEY_RIGHT as 39
define KEY_DOWN as 40
define atomic stringToKey (s: string) begin
if s = " " then begin
define result as KEY_SPACE
end else if s = "ArrowLeft" or s = "Left" then begin
define result as KEY_LEFT
end else if s = "ArrowRight" or s = "Right" then begin
define result as KEY_RIGHT
end else if s = "ArrowUp" or s = "Up" then begin
define result as KEY_UP
end else if s = "ArrowDown" or s = "Down" then begin
define result as KEY_DOWN
end else if s = "Enter" then begin
define result as KEY_ENTER
end else if s = "Any" then begin
// Any key
end else begin
_RUNTIME_signalFailure("Unknown key string")
end
end returns result : integer
end
/**
* Mathematical functions and their approximations that are available
* to model the behavior of Scratch programs.
*
* Approximations are used whenever sufficient to reason about
* particular properties of Scratch programs. In particular
* in cases where we would have to deal with undecidable
* mathematical theories such as natural numbers with multiplication.
*/
role MathActor begin
declare PI as float
declare PI_HALF as float
declare PI_SQR_TIMES_FIVE as float
declare TWO_PI as float
define PI as 3.14159265359
define TWO_PI as 6.28318530718
define PI_HALF as 1.570796326795
define PI_SQR_TIMES_FIVE as 49.34802200545329
/**
* WrampClamp function takes a value and makes sure it is within the given bounds
* param value: float - the value that will be wrapped
* param min: float - the lower bound
* param max: flaot - the upper bound
* return result: float - the wrapped value
*/
define atomic wrapClamp (value: float, min: float, max: float) begin
declare range as float
define range as ((max - min) + 1.0)
define result as (value - (mathFloor((value - min) / range) * range))
end returns result : float
@ Category "Operator"
@ Block "[floor v] of (num)"
@ Opcode "operator_mathop"
define atomic mathFloor (n: float) begin
declare num as integer
define num as cast n to int
define result as cast num to float
if result > n then begin
define result as result - 1.0
end
end returns result : float
/**
* mathAtan approximates the Atan value in radians for a given "real" value
* param n : float - the real value for which the Atan value is approximated
* return result: float - the approximated interval of the Atan value
*/
@ Category "Operator"
@ Block "[atan v] of (num)"
@ Opcode "operator_mathop"
define atomic mathAtan (input: float) begin
if input > TWO_PI then begin
declare asDeg as integer
define asDeg as cast (radToDeg(input)) to int
define asDeg as asDeg mod 360
define input as degToRad(asDeg)
end
if input >= 0.0 and input < 0.1571 then begin
assume result > 0.0
assume result <= 0.1558
end else if input >= 0.1571 and input < 0.3142 then begin
assume result > 0.1558
assume result <= 0.3044
end else if input >= 0.3142 and input < 0.4712 then begin
assume result > 0.3044
assume result <= 0.4403
end else if input >= 0.4712 and input < 0.6283 then begin
assume result > 0.4403
assume result <= 0.561
end else if input >= 0.6283 and input < 0.7854 then begin
assume result > 0.561
assume result <= 0.6658
end else if input >= 0.7854 and input < 0.9425 then begin
assume result > 0.6658
assume result <= 0.7558
end else if input >= 0.9425 and input < 1.0996 then begin
assume result > 0.7558
assume result <= 0.8328
end else if input >= 1.0996 and input < 1.2566 then begin
assume result > 0.8328
assume result <= 0.8986
end else if input >= 1.2566 and input < 1.4137 then begin
assume result > 0.8986
assume result <= 0.9551
end else if input >= 1.4137 and input < 1.5708 then begin
assume result > 0.9551
assume result <= 1.0039
end else if input >= 1.5708 and input < 1.7279 then begin
assume result > 1.0039
assume result <= 1.0462
end else if input >= 1.7279 and input < 1.885 then begin
assume result > 1.0462
assume result <= 1.083
end else if input >= 1.885 and input < 2.042 then begin
assume result > 1.083
assume result <= 1.1154
end else if input >= 2.042 and input < 2.1991 then begin
assume result > 1.1154
assume result <= 1.144
end else if input >= 2.1991 and input < 2.3562 then begin
assume result > 1.144
assume result <= 1.1694
end else if input >= 2.3562 and input < 2.5133 then begin
assume result > 1.1694
assume result <= 1.1921
end else if input >= 2.5133 and input < 2.6704 then begin
assume result > 1.1921
assume result <= 1.2125
end else if input >= 2.6704 and input < 2.8274 then begin
assume result > 1.2125
assume result <= 1.2308
end else if input >= 2.8274 and input < 2.9845 then begin
assume result > 1.2308
assume result <= 1.2475
end else if input >= 2.9845 and input < 3.1416 then begin
assume result > 1.2475
assume result <= 1.2626
end else if input >= 3.1416 and input < 3.2987 then begin
assume result > 1.2626
assume result <= 1.2765
end else if input >= 3.2987 and input < 3.4558 then begin
assume result > 1.2765
assume result <= 1.2891
end else if input >= 3.4558 and input < 3.6128 then begin
assume result > 1.2891
assume result <= 1.3008
end else if input >= 3.6128 and input < 3.7699 then begin
assume result > 1.3008
assume result <= 1.3115
end else if input >= 3.7699 and input < 3.927 then begin
assume result > 1.3115
assume result <= 1.3214
end else if input >= 3.927 and input < 4.0841 then begin
assume result > 1.3214
assume result <= 1.3307
end else if input >= 4.0841 and input < 4.2412 then begin
assume result > 1.3307
assume result <= 1.3392
end else if input >= 4.2412 and input < 4.3982 then begin
assume result > 1.3392
assume result <= 1.3472
end else if input >= 4.3982 and input < 4.5553 then begin
assume result > 1.3472
assume result <= 1.3547
end else if input >= 4.5553 and input < 4.7124 then begin
assume result > 1.3547
assume result <= 1.3617
end else if input >= 4.7124 and input < 4.8695 then begin
assume result > 1.3617
assume result <= 1.3683
end else if input >= 4.8695 and input < 5.0265 then begin
assume result > 1.3683
assume result <= 1.3744
end else if input >= 5.0265 and input < 5.1836 then begin
assume result > 1.3744
assume result <= 1.3802
end else if input >= 5.1836 and input < 5.3407 then begin
assume result > 1.3802
assume result <= 1.3857
end else if input >= 5.3407 and input < 5.4978 then begin
assume result > 1.3857
assume result <= 1.3909
end else if input >= 5.4978 and input < 5.6549 then begin
assume result > 1.3909
assume result <= 1.3958
end else if input >= 5.6549 and input < 5.8119 then begin
assume result > 1.3958
assume result <= 1.4004
end else if input >= 5.8119 and input < 5.969 then begin
assume result > 1.4004
assume result <= 1.4048
end else if input >= 5.969 and input < 6.1261 then begin
assume result > 1.4048
assume result <= 1.409
end
end returns result: float
/**
* mathAtan2 approximates the Atan2 value in radians for two given "real" numbers.
* The result is the angle between the positive x-axis and ray from (0,0) to (x,y)
*
* param x : float - x-coordinate of the target point
* param y : float - y-coordinate of the target point
* return result: float - the approximated interval of the Atan2 value
*/
define atomic mathAtan2 (x: float, y: float) begin
if x > 0.0 then begin
define result as mathAtan((y / x))
end else if x < 0.0 and y > 0.0 then begin
define result as mathAtan((y/x)) + PI
end else if x < 0.0 and y = 0.0 then begin
declare nondet as integer
if nondet = 1 then begin
define result as PI
end else begin
define result as 0.0 - PI
end
end else if x < 0.0 and y < 0.0 then begin
define result as mathAtan((y/x)) - PI
end else if x = 0.0 and y > 0.0 then begin
define result as (PI / 2.0)
end else if x = 0.0 and y < 0.0 then begin
define result as (0.0 - (PI / 2.0))
end else begin
// not defined for (0.0, 0.0)
// but: the JavaScript implementation returns 0
define result as 0.0
end
end returns result: float
@ Category "Operator"
@ Block "[sin v] of (num)"
@ Opcode "operator_mathop"
define atomic mathSinDegree (input: float) begin
declare radians as float
define radians as degToRad(input)
define result as mathSin(radians)
end returns result: float
/**
* mathSin approximates the sin value for a given radians number
*
* param alpha : float - radians number for which the sin value will be approximated
* return result: float - the approximated interval
*/
define atomic mathSin (input: float) begin
if input >= 0.0 and input < 0.3142 then begin
assume result > 0.0
assume result <= 0.3091
end else if input >= 0.3142 and input < 0.4713 then begin
assume result > 0.3091
assume result <= 0.454
end else if input >= 0.4713 and input < 0.6284 then begin
assume result > 0.454
assume result <= 0.5879
end else if input >= 0.6284 and input < 0.7855 then begin
assume result > 0.5879
assume result <= 0.7072
end else if input >= 0.7855 and input < 0.9426 then begin
assume result > 0.7072
assume result <= 0.8091
end else if input >= 0.9426 and input < 1.0997 then begin
assume result > 0.8091
assume result <= 0.8911
end else if input >= 1.0997 and input < 1.2568 then begin
assume result > 0.8911
assume result <= 0.9511
end else if input >= 1.2568 and input < 1.4139 then begin
assume result > 0.9511
assume result <= 0.9877
end else if input >= 1.4139 and input < 1.571 then begin
assume result > 0.9877
assume result <= 1.0
end else if input >= 1.571 and input < 1.7281 then begin
assume result > 0.9877
assume result <= 1.0
end else if input >= 1.7281 and input < 1.8852 then begin
assume result > 0.951
assume result <= 0.9877
end else if input >= 1.8852 and input < 2.0423 then begin
assume result > 0.8909
assume result <= 0.951
end else if input >= 2.0423 and input < 2.1994 then begin
assume result > 0.8088
assume result <= 0.8909
end else if input >= 2.1994 and input < 2.3565 then begin
assume result > 0.7069
assume result <= 0.8088
end else if input >= 2.3565 and input < 2.5136 then begin
assume result > 0.5875
assume result <= 0.7069
end else if input >= 2.5136 and input < 2.6707 then begin
assume result > 0.4537
assume result <= 0.5875
end else if input >= 2.6707 and input < 2.8278 then begin
assume result > 0.3087
assume result <= 0.4537
end else if input >= 2.8278 and input < 2.9849 then begin
assume result > 0.1561
assume result <= 0.3087
end else if input >= 2.9849 and input < 3.142 then begin
assume result > 0.0 - 0.0004
assume result <= 0.1561
end else if input >= 3.142 and input < 3.2991 then begin
assume result > 0.0 - 0.1569
assume result <= 0.0 - 0.0004
end else if input >= 3.2991 and input < 3.4562 then begin
assume result > 0.0 - 0.3094
assume result <= 0.0 - 0.1569
end else if input >= 3.4562 and input < 3.6133 then begin
assume result > 0.0 - 0.4544
assume result <= 0.0 - 0.3094
end else if input >= 3.6133 and input < 3.7704 then begin
assume result > 0.0 - 0.5882
assume result <= 0.0 - 0.4544
end else if input >= 3.7704 and input < 3.9275 then begin
assume result > 0.0 - 0.7075
assume result <= 0.0 - 0.5882
end else if input >= 3.9275 and input < 4.0846 then begin
assume result > 0.0 - 0.8093
assume result <= 0.0 - 0.7075
end else if input >= 4.0846 and input < 4.2417 then begin
assume result > 0.0 - 0.8913
assume result <= 0.0 - 0.8093
end else if input >= 4.2417 and input < 4.3988 then begin
assume result > 0.0 - 0.9512
assume result <= 0.0 - 0.8913
end else if input >= 4.3988 and input < 4.5559 then begin
assume result > 0.0 - 0.9878
assume result <= 0.0 - 0.9512
end else if input >= 4.5559 and input < 4.713 then begin
assume result > 0.0 - 1.0
assume result <= 0.0 - 0.9878
end else if input >= 4.713 and input < 4.8701 then begin
assume result > 0.0 - 1.0
assume result <= 0.0 - 0.9876
end else if input >= 4.8701 and input < 5.0272 then begin
assume result > 0.0 - 0.9876
assume result <= 0.0 - 0.9509
end else if input >= 5.0272 and input < 5.1843 then begin
assume result > 0.0 - 0.9509
assume result <= 0.0 - 0.8907
end else if input >= 5.1843 and input < 5.3414 then begin
assume result > 0.0 - 0.8907
assume result <= 0.0 - 0.8086
end else if input >= 5.3414 and input < 5.4985 then begin
assume result > 0.0 - 0.8086
assume result <= 0.0 - 0.7066
end else if input >= 5.4985 and input < 5.6556 then begin
assume result > 0.0 - 0.7066
assume result <= 0.0 - 0.5872
end else if input >= 5.6556 and input < 5.8127 then begin
assume result > 0.0 - 0.5872
assume result <= 0.0 - 0.4533
end else if input >= 5.8127 and input < 5.9698 then begin
assume result > 0.0 - 0.4533
assume result <= 0.0 - 0.3083
end else if input >= 5.9698 and input < 6.1269 then begin
assume result > 0.0 - 0.3083
assume result <= 0.0 - 0.1556
end else if input >= 6.1269 and input < 6.284 then begin
assume result > 0.0 - 0.1556
assume result <= 0.0008
end
end returns result: float
@ Category "Operator"
@ Block "[cos v] of (num)"
@ Opcode "operator_mathop"
define atomic mathCosDegree (input: float) begin
declare radians as float
define radians as degToRad(input)
define result as mathCos(radians)
end returns result: float
/**
* mathCos approximates the cos value for a given radians number
*
* param alpha : float - radians number for which the cos value will be approximated
* return result: float - the approximated interval
*/
define atomic mathCos (input: float) begin
if input >= 0.0 and input < 0.3142 then begin
assume result > 0.951
assume result <= 1.0
end else if input >= 0.3142 and input < 0.4713 then begin
assume result > 0.891
assume result <= 0.951
end else if input >= 0.4713 and input < 0.6284 then begin
assume result > 0.809
assume result <= 0.891
end else if input >= 0.6284 and input < 0.7855 then begin
assume result > 0.707
assume result <= 0.809
end else if input >= 0.7855 and input < 0.9426 then begin
assume result > 0.5877
assume result <= 0.707
end else if input >= 0.9426 and input < 1.0997 then begin
assume result > 0.4539
assume result <= 0.5877
end else if input >= 1.0997 and input < 1.2568 then begin
assume result > 0.3089
assume result <= 0.4539
end else if input >= 1.2568 and input < 1.4139 then begin
assume result > 0.1563
assume result <= 0.3089
end else if input >= 1.4139 and input < 1.571 then begin
assume result > 0.0 - 0.0002
assume result <= 0.1563
end else if input >= 1.571 and input < 1.7281 then begin
assume result > 0.0 - 0.1567
assume result <= 0.0 - 0.0002
end else if input >= 1.7281 and input < 1.8852 then begin
assume result > 0.0 - 0.3092
assume result <= 0.0 - 0.1567
end else if input >= 1.8852 and input < 2.0423 then begin
assume result > 0.0 - 0.4542
assume result <= 0.0 - 0.3092
end else if input >= 2.0423 and input < 2.1994 then begin
assume result > 0.0 - 0.588
assume result <= 0.0 - 0.4542
end else if input >= 2.1994 and input < 2.3565 then begin
assume result > 0.0 - 0.7073
assume result <= 0.0 - 0.588
end else if input >= 2.3565 and input < 2.5136 then begin
assume result > 0.0 - 0.8092
assume result <= 0.0 - 0.7073
end else if input >= 2.5136 and input < 2.6707 then begin
assume result > 0.0 - 0.8912
assume result <= 0.0 - 0.8092
end else if input >= 2.6707 and input < 2.8278 then begin
assume result > 0.0 - 0.9512
assume result <= 0.0 - 0.8912
end else if input >= 2.8278 and input < 2.9849 then begin
assume result > 0.0 - 0.9877
assume result <= 0.0 - 0.9512
end else if input >= 2.9849 and input < 3.142 then begin
assume result > 0.0 - 1.0
assume result <= 0.0 - 0.9877
end else if input >= 3.142 and input < 3.2991 then begin
assume result > 0.0 - 1.0
assume result <= 0.0 - 0.9876
end else if input >= 3.2991 and input < 3.4562 then begin
assume result > 0.0 - 0.9876
assume result <= 0.0 - 0.9509
end else if input >= 3.4562 and input < 3.6133 then begin
assume result > 0.0 - 0.9509
assume result <= 0.0 - 0.8908
end else if input >= 3.6133 and input < 3.7704 then begin
assume result > 0.0 - 0.8908
assume result <= 0.0 - 0.8087
end else if input >= 3.7704 and input < 3.9275 then begin
assume result > 0.0 - 0.8087
assume result <= 0.0 - 0.7067
end else if input >= 3.9275 and input < 4.0846 then begin
assume result > 0.0 - 0.7067
assume result <= 0.0 - 0.5874
end else if input >= 4.0846 and input < 4.2417 then begin
assume result > 0.0 - 0.5874
assume result <= 0.0 - 0.4535
end else if input >= 4.2417 and input < 4.3988 then begin
assume result > 0.0 - 0.4535
assume result <= 0.0 - 0.3085
end else if input >= 4.3988 and input < 4.5559 then begin
assume result > 0.0 - 0.3085
assume result <= 0.0 - 0.1559
end else if input >= 4.5559 and input < 4.713 then begin
assume result > 0.0 - 0.1559
assume result <= 0.0006
end else if input >= 4.713 and input < 4.8701 then begin
assume result > 0.0006
assume result <= 0.1571
end else if input >= 4.8701 and input < 5.0272 then begin
assume result > 0.1571
assume result <= 0.3096
end else if input >= 5.0272 and input < 5.1843 then begin
assume result > 0.3096
assume result <= 0.4546
end else if input >= 5.1843 and input < 5.3414 then begin
assume result > 0.4546
assume result <= 0.5883
end else if input >= 5.3414 and input < 5.4985 then begin
assume result > 0.5883
assume result <= 0.7076
end else if input >= 5.4985 and input < 5.6556 then begin
assume result > 0.7076
assume result <= 0.8094
end else if input >= 5.6556 and input < 5.8127 then begin
assume result > 0.8094
assume result <= 0.8913
end else if input >= 5.8127 and input < 5.9698 then begin
assume result > 0.8913
assume result <= 0.9513
end else if input >= 5.9698 and input < 6.1269 then begin
assume result > 0.9513
assume result <= 0.9878
end else if input >= 6.1269 and input < 6.284 then begin
assume result > 0.9878
assume result <= 1.0
end
end returns result: float
/**
* radToDeg calculates the degree value for a given radians value
*
* param rad: float - radians number for which the degree value will be calculated
* return result: float - the calculated degree value
*/
define atomic radToDeg (rad: float) begin
// define result as ((rad * 180.0) / PI)
define result as rad * 57.2957795131
end returns result: float
/**
* degToRad calculates the radians value for a given degree value
*
* param deg: float - degree number for which the radians value will be calculated
* return result: float - the calculated radians value [0..2*pi]
*/
define atomic degToRad (deg: float) begin
// define result as (deg * PI) / 180.0
define result as deg * 0.01745329252
end returns result: float
define atomic nearestPerfectSqrt (num: float) begin
if num < 0.0 then begin
_RUNTIME_signalFailure("Sqrt of negative number not allowed")
end else if num = 0.0 then begin
define result as 0.0
end else if num <= 1.0 then begin
define result as 1.0
end else if num <= 4.0 then begin
define result as 2.0
end else if num <= 9.0 then begin
define result as 3.0
end else if num <= 16.0 then begin
define result as 4.0
end else if num <= 25.0 then begin
define result as 5.0
end else if num <= 36.0 then begin
define result as 6.0
end else if num <= 49.0 then begin
define result as 7.0
end else if num <= 64.0 then begin
define result as 8.0
end else if num <= 81.0 then begin
define result as 9.0
end else if num <= 100.0 then begin
define result as 10.0
end else if num <= 121.0 then begin
define result as 11.0
end else if num <= 144.0 then begin
define result as 12.0
end else if num <= 169.0 then begin
define result as 13.0
end else if num <= 196.0 then begin
define result as 14.0
end else if num <= 225.0 then begin
define result as 15.0
end else if num <= 256.0 then begin
define result as 16.0
end else if num <= 289.0 then begin
define result as 17.0
end else if num <= 324.0 then begin
define result as 18.0
end else if num <= 361.0 then begin
define result as 19.0
end else if num <= 400.0 then begin
define result as 20.0
end else if num <= 441.0 then begin
define result as 21.0
end else if num <= 484.0 then begin
define result as 22.0
end else if num <= 529.0 then begin
define result as 23.0
end else if num <= 576.0 then begin
define result as 24.0
end else if num <= 625.0 then begin
define result as 25.0
end
end returns result: float
@ Category "Operator"
@ Block "[sqrt v] of (num)"
@ Opcode "operator_mathop"
define atomic mathSqrt (num: float) begin
declare result as float
define result as nearestPerfectSqrt(num)
if not (num = result) then begin
// Three iterations of newton
define result as (result + (num / result)) / 2.0
define result as (result + (num / result)) / 2.0
define result as (result + (num / result)) / 2.0
end
end returns result: float
define atomic mathAbs (n: integer) begin
if n < 0 then begin
define result as 0 - n
end else begin
define result as n
end
end returns result: integer
@ Category "Operator"
@ Block "[abs v] of (num)"
@ Opcode "operator_mathop"
define atomic mathAbsF (n: float) begin
if n < 0.0 then begin
define result as 0.0 - n
end else begin
define result as n
end
end returns result: float
define atomic mathMax (n1: integer, n2: integer) begin
if (n1 > n2) then begin
define result as n1
end else begin
define result as n2
end
end returns result: integer
define atomic mathMin (n1: integer, n2: integer) begin
if (n1 < n2) then begin
define result as n1
end else begin
define result as n2
end
end returns result: integer
define atomic mathMaxF (n1: float, n2: float) begin
if (n1 > n2) then begin
define result as n1
end else begin
define result as n2
end
end returns result: float
define atomic mathMinF (n1: float, n2: float) begin
if (n1 < n2) then begin
define result as n1
end else begin
define result as n2
end
end returns result: float
end
/**
* The base functionality for all runtime entities available in Scratch.
*/
role RuntimeEntity is MathActor, KeyboardIO begin
extern _RUNTIME_getInitialActors () returns list of string
extern _RUNTIME_getClonesOf (ac: string) returns list of string
extern _RUNTIME_getAllActors () returns list of string
extern _RUNTIME_isActorTypeOf (ac: string, actorType: string) returns boolean
extern _RUNTIME_restart ()
/**
* Signal that the current scene should be rendered,
* or: signal a behavior that should be visible to the user.
*/
extern _RUNTIME_render ()
/**
* Returns the integer of milliseconds that
* elapsed since the VM started.
*/
extern _RUNTIME_millis () returns integer
/**
* Returns the integer of seconds that
* elapsed since the VM started.
*/
extern _RUNTIME_seconds () returns integer
extern _RUNTIME_micros () returns integer
extern _RUNTIME_waitMillis (ms: integer)
extern _RUNTIME_waitMicros (micros: integer)
extern _RUNTIME_waitSeconds (s: integer)
extern _RUNTIME_timerValue () returns integer
extern _RUNTIME_resetTimer ()
extern _RUNTIME_signalFailure ()
extern _RUNTIME_numberFromInterval (fromNum: integer, toNum: integer) returns integer
extern _RUNTIME_integerFromInterval (fromNum: integer, toNum: integer) returns integer
@ Category "Operator"
@ Block "[ceiling v] of (num)"
@ Opcode "operator_mathop"
extern mathCeiling (n: float) returns integer
@ Category "Operator"
@ Block "[tan v] of (num)"
@ Opcode "operator_mathop"
extern mathTan (n: integer) returns integer
@ Category "Operator"
@ Block "[asin v] of (num)"
@ Opcode "operator_mathop"
extern mathAsin (n: integer) returns integer
@ Category "Operator"
@ Block "[acos v] of (num)"
@ Opcode "operator_mathop"
extern mathAcos (n: integer) returns integer
@ Category "Operator"
@ Block "[ln v] of (num)"
@ Opcode "operator_mathop"
extern mathLn(n: integer) returns integer
@ Category "Operator"
@ Block "[log v] of (num)"
@ Opcode "operator_mathop"
extern mathLog(n: integer) returns integer
@ Category "Operator"
@ Block "[e ^ v] of (num)"
@ Opcode "operator_mathop"
extern mathPowe(n: integer) returns integer
@ Category "Operator"
@ Block "[10 ^ v] of (num)"
@ Opcode "operator_mathop"
extern mathPowten(n: integer) returns integer
extern label (str: string)
/**
* A random integer in the interval [from, to],
* that is, both end points are included.
* Only intended for internal use within this library,
* should not be used directly by programs that build upon the library.
*/
define internalRandomBetween (intervalStart: integer, intervalEnd: integer) begin
assume result >= intervalStart
assume result <= intervalEnd
end returns result: integer
/**
* See https://en.scratch-wiki.info/wiki/Pick_Random_()_to_()_(block)
*/
define randomBetween (intervalStart: integer, intervalEnd: integer) begin
define result as internalRandomBetween(intervalStart, intervalEnd)
end returns result: integer
define getGraphicIdByIndex (idx: integer) begin
define result as ""
end returns result: string
define getGraphicIndexById (id: string) begin
define result as (0-1)
end returns result: integer
define getGraphicPixels (id: string) begin
define result as ""
end returns result: string
define getImageWidth (ident: string) begin
define result as 0
end returns result: integer
define getImageHeight (ident: string) begin
define result as 0
end returns result: integer
define getNumGraphics () begin
define result as 0
end returns result: integer
/**
* A busy-waiting implementation.
* The external method `_RUNTIME_waitSeconds` is intended to
* not conduct a busy wait.
*/
@ Category "Control"
@ Block "wait (num) seconds"
@ Opcode "control_wait"
define waitSeconds (secs: integer) begin
declare waitUntil as integer
define waitUntil as _RUNTIME_seconds() + secs
until (_RUNTIME_seconds() > waitUntil) repeat begin
end
end
/**
* A busy-waiting implementation.
* The external method `_RUNTIME_waitMillis` is intended to
* not conduct a busy wait.
*/
@ Category "Control"
@ Block "wait (num) millis"
define waitMillis (millis: integer) begin
declare waitUntil as integer
define waitUntil as _RUNTIME_millis() + millis
until (_RUNTIME_millis() > waitUntil) repeat begin
end
end
/**
* A busy-waiting implementation.
* The external method `_RUNTIME_waitMicros` is intended to
* not conduct a busy wait.
*/
@ Category "Control"
@ Block "wait (num) micros"
define waitMicros (micros: integer) begin
declare waitUntil as integer
define waitUntil as _RUNTIME_micros() + micros
until (_RUNTIME_micros() > waitUntil) repeat begin
end
end
/**
* A busy-waiting implementation for wait-until-condition.
*/
@ Category "Control"
@ Block "wait until <cond>"
@ Opcode "wait_until"
define waitUntil (cond: boolean) begin
until cond repeat begin
end
end
define atomic milliseconds () begin
define result as _RUNTIME_millis()
end returns result: integer
define atomic microseconds () begin
define result as _RUNTIME_micros()
end returns result: integer
@ Category "Sensing"
@ Block "mouse down?"
@ Opcode "sensing_mousedown"
define atomic mouseDown () begin
end returns result : boolean
@ Category "Sensing"
@ Block "mouse x"
@ Opcode "sensing_mousex"
define atomic mouseX () begin
declare io as actor
define io as locate actor "IOActor"
define result as cast (attribute "mouseX" of io) to int
end returns result: integer
@ Category "Sensing"
@ Block "mouse y"
@ Opcode "sensing_mousey"
define atomic mouseY () begin
declare io as actor
define io as locate actor "IOActor"
define result as cast (attribute "mouseY" of io) to int
end returns result: integer