forked from FlatAssembler/AECforWebAssembly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
namedArgumentsTest.aec
148 lines (136 loc) · 5.87 KB
/
namedArgumentsTest.aec
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
/*
* This is a test whether the compiler properly supports named function
* parameters (arguments), so that arguments of functions do not always
* need to be written in the same order.
*/
#target WASI //Will make JavaScript a bit shorter.
Structure ComplexNumber Consists Of
Decimal32 real, imaginary;
EndStructure
Structure QuadraticEquationSolution Consists Of
ComplexNumber firstSolution, secondSolution;
EndStructure
Function solveQuadraticEquation(Decimal32 a := 1, Decimal32 b := 0,
Decimal32 c := 0,
QuadraticEquationSolutionPointer solution)
Which Returns Nothing Is Declared;
Function abs(Decimal32 x) Which Returns Decimal32 Is Declared;
Function areStructuresEqual(NothingPointer first, NothingPointer second,
Integer32 sizeOfStructuresInBytes)
Which Returns Integer32 Is Declared;
Decimal32 goldenRatio := (sqrt(5) + 1) / 2,
epsilon := 1 / 100;
Function printFloat32(Decimal32 x) Which Returns Nothing Is Declared;
/*
* We cannot make it external because we are not actually using WASI, and the
* compiler thinks we are, and will output code that will not run in NodeJS.
* Therefore, we need to import the function from JavaScript manually in
* inline assembly. Not hard, fortunately.
*/
asm("(func $printFloat32 (import \"JavaScript\" \"printFloat32\") (param f32))");
// Should return 0.
Function namedArgumentsTest() Which Returns Integer32 Does
InstantiateStructure QuadraticEquationSolution solution[1 * 2 * 3];
solveQuadraticEquation(a := 1 , b := -1, c := -1, AddressOf(solution[0]));
// Since 'a' is set to default to 1 in the declaration of the
// "solveQuadraticEquation" function, it does not need to be written
// if it is indeed 1 when calling that function. In the next line, it is not.
solveQuadraticEquation(c := -1, b := -1, solution := AddressOf(solution[1]));
solveQuadraticEquation(b := -1, c := -1, solution := AddressOf(solution[2]));
solveQuadraticEquation(b := -1, c := -1, a := 1 , AddressOf(solution[3]));
solveQuadraticEquation(c := -1, a := 1 , b := -1, AddressOf(solution[4]));
solveQuadraticEquation(c := -1, b := -1, solution := AddressOf(solution[5]));
Integer32 iterator := 0;
While iterator < 1*2*3 - 1 Loop
If not(areStructuresEqual(AddressOf(solution[iterator]),
AddressOf(solution[iterator + 1]),
SizeOf(QuadraticEquationSolution))) Then
Return iterator + 1;
EndIf
iterator += 1;
EndWhile
iterator := 0;
// Let's test whether structure comparisons work...
While iterator < 1*2*3 - 1 Loop
If not(solution[iterator] = solution[iterator + 1]) Then
/*
* The line above appears to betray a bug in the compiler,
* which is exposed only when the compiler itself is compiled
* using Microsoft C++ compiler:
* https://github.com/FlatAssembler/AECforWebAssembly/issues/20
*/
Return iterator + 7;
EndIf
iterator += 1;
EndWhile
iterator := 0;
While iterator < 1*2*3 - 1 Loop /*
* This loop should have no effect,
* but the compiler must not crash
* when compiling it.
*/
solution[iterator] := solution[iterator + 1];
iterator += 1;
EndWhile
If not(solution[0].firstSolution.imaginary = 0 and
solution[0].secondSolution.imaginary = 0 and
abs(solution[0].firstSolution.real + goldenRatio - 1) < epsilon and
abs(solution[0].secondSolution.real - goldenRatio) < epsilon) Then
printFloat32(solution[0].firstSolution.real);
printFloat32(solution[0].firstSolution.imaginary);
printFloat32(solution[0].secondSolution.real);
printFloat32(solution[0].secondSolution.imaginary);
Return 15;
EndIf
Return 0;
EndFunction
Function abs(Decimal32 x) Which Returns Decimal32 Does
Return x < 0 ? -x : x;
EndFunction
Function areStructuresEqual(CharacterPointer first, CharacterPointer second,
Integer32 size) Which Returns Integer32 Does
Integer32 i := 0;
While i < size Loop
If not(ValueAt(first + i) = ValueAt(second + i)) Then
Return 0;
EndIf
i += 1;
EndWhile
Return 1;
EndFunction
Function sqrt(Decimal32 realNumber, ComplexNumberPointer result)
Which Returns Nothing Is Declared;
Function solveQuadraticEquation(Decimal32 a, Decimal32 b, Decimal32 c,
QuadraticEquationSolutionPointer solution)
Which Returns Nothing Does
solution->firstSolution.real := -b;
solution->firstSolution.imaginary := 0;
solution->secondSolution := solution->firstSolution;
InstantiateStructure ComplexNumber rootOfDiscriminant;
sqrt(b*b - 4*a*c, AddressOf(rootOfDiscriminant));
solution->firstSolution.real -= rootOfDiscriminant.real;
solution->firstSolution.imaginary -= rootOfDiscriminant.imaginary;
solution->secondSolution.real += rootOfDiscriminant.real;
solution->secondSolution.imaginary += rootOfDiscriminant.imaginary;
solution->firstSolution.real /= 2*a;
solution->firstSolution.imaginary /= 2*a;
solution->secondSolution.real /= 2*a;
solution->secondSolution.imaginary /= 2*a;
EndFunction
Function sqrt(Decimal32 x, ComplexNumberPointer result)
Which Returns Nothing Does
If x < 0 Then
result->real := 0;
result->imaginary := asm_f32("(f32.sqrt\n"
"\t(f32.sub\n"
"\t\t(f32.const 0)\n"
"\t\t(local.get 0)\n"
"\t)\n"
")");
Else
result->real := asm_f32("(f32.sqrt\n"
"\t(local.get 0)\n"
")");
result->imaginary := 0;
EndIf
EndFunction