-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmath.cfg
More file actions
146 lines (128 loc) · 3.71 KB
/
Copy pathmath.cfg
File metadata and controls
146 lines (128 loc) · 3.71 KB
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
// Primitive example of a math library, functions like square, power, max, and
// min are here as a "proof of concept", use their respective xSVM instruction
// instead for better performance.
#define _MATHLIB 1; // This is used with #ifndef or #ifdef to control, inclusion
// of math.cfg, for example:
// #ifndef _MATHLIB
// d #include ${BASE_PATH ?}stackvm-xonotic/examples/math.cfg
// #endif
// this will only include the file if it's not already included.
// int square(int base)
// {
// return base * base;
// }
label square
s dup; // duplicate the stack head, [..., base] -> [..., base, base]
s mul; // multiply top two values on the stack [..., base, base] -> [..., base * base]
s ret; // return to caller!
// int power(int base, int n)
// {
// int i = 1;
// while (n > 0) {
// i = base * i;
// --n;
// }
// return i;
// }
label power
// Store the arguments passed to "power" from the stack in reverse order.
// As the arguments live on stack like this [..., base, n].
s store_l n
s store_l base
s push 1; // Initialize a local variable i with value 1
s store_l i; // int i = 1;
label _power_loop
s load_l n; // Check when n is not greater than 0
s push 0; // when that happens, branch to _exit_power_loop
s isgt
s not
s load_g _exit_power_loop
s jif_vfs
// i = base * i;
s load_l base
s load_l i
s mul
s store_l i
// --n;
s load_l n
s push 1
s sub
s store_l n
s load_g _power_loop
s jmp_vfs
label _exit_power_loop
// return i;
s load_l i
s ret
// int max(int a, int b)
// {
// if (a > b)
// return a;
// return b;
// }
label max
// store the arguments in reverse order. just like power
s store_l b
s store_l a
// if (a > b) return a;
s load_l a
s load_l b
s isgt
s load_g _return_a
s jif_vfs
label _return_b
// return b;
s load_l b
s ret
label _return_a
s load_l a
s ret
// int min(int a, int b)
// {
// if(a < b)
// return a;
// return b;
// }
label min
s store_l b
s store_l a
// if (a < b) return a;
s load_l a
s load_l b
s islt
s load_g _return_a; // Here we're branching to what appears to be code related with max.
s jif_vfs; // But in reality max and min share the same if branch code, i.e "return a;"
// so instead of creating separate code section for min, we'll use max's
// return code. Same goes for "return b;".
// ... Optimization baby! ;-)
// return b;
s load_g _return_b
s jmp_vfs
// Factorial AHHHHHHH!!
// int factorial(int num)
// {
// if (num < 1)
// return 1;
// else
// return n * factorial(num - 1);
// }
label factorial
s store_l num
// if (num < 1) return 1;
s load_l num
s push 1
s islt
s load_g _return_one
s jif_vfs
// else return num * factorial(num - 1);
s load_l num
s push 1
s sub
s load_g factorial; // Recursive function call baby! woohoo! :-)
s call_vfs
s load_l num
s mul
s ret
label _return_one
s push 1
s ret