brittainscript 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brittainscript-0.1.0.dist-info/METADATA +276 -0
- brittainscript-0.1.0.dist-info/RECORD +14 -0
- brittainscript-0.1.0.dist-info/WHEEL +5 -0
- brittainscript-0.1.0.dist-info/entry_points.txt +2 -0
- brittainscript-0.1.0.dist-info/licenses/LICENSE +21 -0
- brittainscript-0.1.0.dist-info/top_level.txt +2 -0
- core/__init__.py +0 -0
- core/lexer.py +132 -0
- core/main.py +364 -0
- core/parser.py +384 -0
- core/parsetab.py +71 -0
- libs/__init__.py +0 -0
- libs/convert.bs +57 -0
- libs/math.bs +47 -0
core/parser.py
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import ply.yacc as yacc
|
|
2
|
+
import lexer as lexer_module
|
|
3
|
+
from lexer import tokens
|
|
4
|
+
import math
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
# variable storage
|
|
8
|
+
names = {}
|
|
9
|
+
scopes = [names]
|
|
10
|
+
function_caller = None
|
|
11
|
+
module_caller = None
|
|
12
|
+
|
|
13
|
+
precedence = (
|
|
14
|
+
('left', 'OR'),
|
|
15
|
+
('left', 'AND'),
|
|
16
|
+
('right', 'NOT'),
|
|
17
|
+
('left', 'EQUALTO', 'NOTEQUALTO'),
|
|
18
|
+
('left', 'LESSTHAN', 'GREATERTHAN', 'LESSTHANEQUALTO', 'GREATERTHANEQUALTO'),
|
|
19
|
+
('left', 'PLUS', 'MINUS'),
|
|
20
|
+
('left', 'MULTIPLY', 'DIVIDE'),
|
|
21
|
+
('right', 'POWER'),
|
|
22
|
+
('left', 'LBRACKET'),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def push_scope(scope=None):
|
|
26
|
+
scopes.append({} if scope is None else scope)
|
|
27
|
+
|
|
28
|
+
def pop_scope():
|
|
29
|
+
if len(scopes) > 1:
|
|
30
|
+
scopes.pop()
|
|
31
|
+
|
|
32
|
+
def get_name(name):
|
|
33
|
+
for scope in reversed(scopes):
|
|
34
|
+
if name in scope:
|
|
35
|
+
return scope[name]
|
|
36
|
+
raise KeyError(name)
|
|
37
|
+
|
|
38
|
+
def set_name(name, value):
|
|
39
|
+
for scope in reversed(scopes):
|
|
40
|
+
if name in scope:
|
|
41
|
+
scope[name] = value
|
|
42
|
+
return
|
|
43
|
+
scopes[-1][name] = value
|
|
44
|
+
|
|
45
|
+
def assign_target(target, value):
|
|
46
|
+
target = target.strip()
|
|
47
|
+
indexed = re_match_index(target)
|
|
48
|
+
if indexed:
|
|
49
|
+
name, index_text = indexed
|
|
50
|
+
try:
|
|
51
|
+
container = get_name(name)
|
|
52
|
+
index = parser.parse(index_text, lexer=lexer_module.lexer.clone())
|
|
53
|
+
container[index] = value
|
|
54
|
+
except KeyError:
|
|
55
|
+
print(f'Undefined variable: {name}')
|
|
56
|
+
except (TypeError, IndexError):
|
|
57
|
+
print("Error: invalid assignment target")
|
|
58
|
+
return
|
|
59
|
+
set_name(target, value)
|
|
60
|
+
|
|
61
|
+
def re_match_index(target):
|
|
62
|
+
import re
|
|
63
|
+
match = re.fullmatch(r'([A-Za-z_][A-Za-z0-9_]*)\s*\[(.+)\]', target)
|
|
64
|
+
if not match:
|
|
65
|
+
return None
|
|
66
|
+
return match.group(1), match.group(2)
|
|
67
|
+
|
|
68
|
+
def set_function_caller(caller):
|
|
69
|
+
global function_caller
|
|
70
|
+
function_caller = caller
|
|
71
|
+
|
|
72
|
+
def set_module_caller(caller):
|
|
73
|
+
global module_caller
|
|
74
|
+
module_caller = caller
|
|
75
|
+
|
|
76
|
+
def p_expression_number(p):
|
|
77
|
+
'expression : NUMBER'
|
|
78
|
+
p[0] = p[1]
|
|
79
|
+
|
|
80
|
+
def p_expression_group(p):
|
|
81
|
+
'expression : LPAREN expression RPAREN'
|
|
82
|
+
p[0] = p[2]
|
|
83
|
+
|
|
84
|
+
def p_expression_plus(p):
|
|
85
|
+
'expression : expression PLUS expression'
|
|
86
|
+
try:
|
|
87
|
+
p[0] = p[1] + p[3]
|
|
88
|
+
except TypeError:
|
|
89
|
+
print(f"Error: cannot add {type(p[1]).__name__} and {type(p[3]).__name__}")
|
|
90
|
+
p[0] = None
|
|
91
|
+
|
|
92
|
+
def p_expression_minus(p):
|
|
93
|
+
'expression : expression MINUS expression'
|
|
94
|
+
p[0] = p[1] - p[3]
|
|
95
|
+
|
|
96
|
+
def p_expression_divide(p):
|
|
97
|
+
'expression : expression DIVIDE expression'
|
|
98
|
+
if p[3] == 0:
|
|
99
|
+
print("Error: division by zero")
|
|
100
|
+
p[0] = None
|
|
101
|
+
return
|
|
102
|
+
p[0] = p[1] / p[3]
|
|
103
|
+
|
|
104
|
+
def p_expression_times(p):
|
|
105
|
+
'expression : expression MULTIPLY expression'
|
|
106
|
+
try:
|
|
107
|
+
p[0] = p[1] * p[3]
|
|
108
|
+
except TypeError:
|
|
109
|
+
print(f"Error: cannot multiply {type(p[1]).__name__} and {type(p[3]).__name__}")
|
|
110
|
+
p[0] = None
|
|
111
|
+
|
|
112
|
+
def p_expression_modulo(p):
|
|
113
|
+
'expression : expression MODULO expression'
|
|
114
|
+
p[0] = p[1] % p[3]
|
|
115
|
+
|
|
116
|
+
def p_expression_power(p):
|
|
117
|
+
'expression : expression POWER expression'
|
|
118
|
+
p[0] = math.pow(p[1], p[3])
|
|
119
|
+
|
|
120
|
+
def p_expression_squareroot(p):
|
|
121
|
+
'expression : SQUAREROOT LPAREN expression RPAREN'
|
|
122
|
+
p[0] = math.sqrt(p[3])
|
|
123
|
+
|
|
124
|
+
def p_expression_sine(p):
|
|
125
|
+
'expression : SINE LPAREN expression RPAREN'
|
|
126
|
+
p[0] = math.sin(math.radians(p[3]))
|
|
127
|
+
|
|
128
|
+
def p_expression_cosine(p):
|
|
129
|
+
'expression : COSINE LPAREN expression RPAREN'
|
|
130
|
+
p[0] = math.cos(math.radians(p[3]))
|
|
131
|
+
|
|
132
|
+
def p_expression_tangent(p):
|
|
133
|
+
'expression : TANGENT LPAREN expression RPAREN'
|
|
134
|
+
p[0] = math.tan(math.radians(p[3]))
|
|
135
|
+
|
|
136
|
+
def p_expression_pi(p):
|
|
137
|
+
'expression : PI'
|
|
138
|
+
p[0] = math.pi
|
|
139
|
+
|
|
140
|
+
def p_expression_print(p):
|
|
141
|
+
'expression : PRINT LPAREN expression RPAREN'
|
|
142
|
+
print(p[3])
|
|
143
|
+
p[0] = None
|
|
144
|
+
|
|
145
|
+
def p_expression_string(p):
|
|
146
|
+
'expression : STRING'
|
|
147
|
+
p[0] = p[1]
|
|
148
|
+
|
|
149
|
+
def p_statement_assign(p):
|
|
150
|
+
'expression : NAME EQ expression'
|
|
151
|
+
set_name(p[1], p[3])
|
|
152
|
+
p[0] = None
|
|
153
|
+
|
|
154
|
+
def p_expression_name(p):
|
|
155
|
+
'expression : NAME'
|
|
156
|
+
try:
|
|
157
|
+
p[0] = get_name(p[1])
|
|
158
|
+
except KeyError:
|
|
159
|
+
print(f'Undefined variable: {p[1]}')
|
|
160
|
+
p[0] = 0
|
|
161
|
+
|
|
162
|
+
def p_expression_list(p):
|
|
163
|
+
'expression : LBRACKET optional_arguments RBRACKET'
|
|
164
|
+
p[0] = p[2]
|
|
165
|
+
|
|
166
|
+
def p_expression_index(p):
|
|
167
|
+
'expression : expression LBRACKET expression RBRACKET'
|
|
168
|
+
try:
|
|
169
|
+
p[0] = p[1][p[3]]
|
|
170
|
+
except (TypeError, IndexError, KeyError):
|
|
171
|
+
print("Error: invalid index")
|
|
172
|
+
p[0] = None
|
|
173
|
+
|
|
174
|
+
def p_expression_slice(p):
|
|
175
|
+
'expression : expression LBRACKET optional_expression COLON optional_expression RBRACKET'
|
|
176
|
+
try:
|
|
177
|
+
p[0] = p[1][p[3]:p[5]]
|
|
178
|
+
except TypeError:
|
|
179
|
+
print("Error: invalid slice")
|
|
180
|
+
p[0] = None
|
|
181
|
+
|
|
182
|
+
def p_optional_expression_empty(p):
|
|
183
|
+
'optional_expression :'
|
|
184
|
+
p[0] = None
|
|
185
|
+
|
|
186
|
+
def p_optional_expression_value(p):
|
|
187
|
+
'optional_expression : expression'
|
|
188
|
+
p[0] = p[1]
|
|
189
|
+
|
|
190
|
+
def p_optional_arguments_empty(p):
|
|
191
|
+
'optional_arguments :'
|
|
192
|
+
p[0] = []
|
|
193
|
+
|
|
194
|
+
def p_optional_arguments_value(p):
|
|
195
|
+
'optional_arguments : arguments'
|
|
196
|
+
p[0] = p[1]
|
|
197
|
+
|
|
198
|
+
def p_arguments_single(p):
|
|
199
|
+
'arguments : expression'
|
|
200
|
+
p[0] = [p[1]]
|
|
201
|
+
|
|
202
|
+
def p_arguments_many(p):
|
|
203
|
+
'arguments : arguments COMMA expression'
|
|
204
|
+
p[0] = p[1] + [p[3]]
|
|
205
|
+
|
|
206
|
+
def p_expression_function_call(p):
|
|
207
|
+
'expression : NAME LPAREN optional_arguments RPAREN'
|
|
208
|
+
p[0] = call_function(p[1], p[3])
|
|
209
|
+
|
|
210
|
+
def p_expression_range_call(p):
|
|
211
|
+
'expression : RANGE LPAREN optional_arguments RPAREN'
|
|
212
|
+
p[0] = call_function('range', p[3])
|
|
213
|
+
|
|
214
|
+
def p_expression_method_call(p):
|
|
215
|
+
'expression : expression DOT NAME LPAREN optional_arguments RPAREN'
|
|
216
|
+
p[0] = call_method(p[1], p[3], p[5])
|
|
217
|
+
|
|
218
|
+
def call_function(name, args):
|
|
219
|
+
if name == 'len':
|
|
220
|
+
if len(args) != 1:
|
|
221
|
+
print("Error: len() expects 1 argument")
|
|
222
|
+
return None
|
|
223
|
+
return len(args[0])
|
|
224
|
+
if name == 'tonum':
|
|
225
|
+
if len(args) != 1:
|
|
226
|
+
print("Error: tonum() expects 1 argument")
|
|
227
|
+
return None
|
|
228
|
+
try:
|
|
229
|
+
value = float(args[0]) if '.' in str(args[0]) else int(args[0])
|
|
230
|
+
return value
|
|
231
|
+
except ValueError:
|
|
232
|
+
print("Error: tonum() could not convert value")
|
|
233
|
+
return None
|
|
234
|
+
if name == 'tostr':
|
|
235
|
+
if len(args) != 1:
|
|
236
|
+
print("Error: tostr() expects 1 argument")
|
|
237
|
+
return None
|
|
238
|
+
return str(args[0])
|
|
239
|
+
if name == 'input':
|
|
240
|
+
if len(args) > 1:
|
|
241
|
+
print("Error: input() expects 0 or 1 arguments")
|
|
242
|
+
return None
|
|
243
|
+
return input(args[0] if args else '')
|
|
244
|
+
if name == 'range':
|
|
245
|
+
if len(args) not in (1, 2, 3):
|
|
246
|
+
print("Error: range() expects 1 to 3 arguments")
|
|
247
|
+
return []
|
|
248
|
+
return list(range(*args))
|
|
249
|
+
if name == 'clear':
|
|
250
|
+
os.system('cls' if os.name == 'nt' else 'clear')
|
|
251
|
+
return None
|
|
252
|
+
if name == 'absolute':
|
|
253
|
+
if len(args) > 1:
|
|
254
|
+
print("Error: absolute expects one argument")
|
|
255
|
+
return None
|
|
256
|
+
return abs(args)
|
|
257
|
+
if name == 'round':
|
|
258
|
+
if len(args) > 1:
|
|
259
|
+
print("Error: round expects one argument")
|
|
260
|
+
return None
|
|
261
|
+
return round(args)
|
|
262
|
+
if name == 'floor':
|
|
263
|
+
if len(args) > 1:
|
|
264
|
+
print("Error: floor expects one argument")
|
|
265
|
+
return None
|
|
266
|
+
return math.floor(args)
|
|
267
|
+
if name == 'ceiling':
|
|
268
|
+
if len(args) > 1:
|
|
269
|
+
print("Error: ceiling expects one argument")
|
|
270
|
+
return None
|
|
271
|
+
return math.ceil(args)
|
|
272
|
+
if name == 'type':
|
|
273
|
+
if len(args) > 1:
|
|
274
|
+
print("Error: type expects one argument")
|
|
275
|
+
return None
|
|
276
|
+
return type(args)
|
|
277
|
+
if function_caller:
|
|
278
|
+
return function_caller(name, args)
|
|
279
|
+
print(f"Undefined function: {name}")
|
|
280
|
+
return None
|
|
281
|
+
|
|
282
|
+
def call_method(receiver, name, args):
|
|
283
|
+
if isinstance(receiver, dict) and receiver.get('__bs_module__'):
|
|
284
|
+
if module_caller:
|
|
285
|
+
return module_caller(receiver, name, args)
|
|
286
|
+
print(f"Error: no module caller set")
|
|
287
|
+
return None
|
|
288
|
+
if name == 'upper' and isinstance(receiver, str) and not args:
|
|
289
|
+
return receiver.upper()
|
|
290
|
+
if name == 'lower' and isinstance(receiver, str) and not args:
|
|
291
|
+
return receiver.lower()
|
|
292
|
+
if name == 'trim' and isinstance(receiver, str) and not args:
|
|
293
|
+
return receiver.strip()
|
|
294
|
+
if name == 'add' and isinstance(receiver, list) and len(args) == 1:
|
|
295
|
+
receiver.append(args[0])
|
|
296
|
+
return None
|
|
297
|
+
if name == 'contains' and isinstance(receiver, str):
|
|
298
|
+
if args[0] in receiver:
|
|
299
|
+
return True
|
|
300
|
+
else:
|
|
301
|
+
return False
|
|
302
|
+
if name == 'locate' and isinstance(receiver, str) and len(args == 1):
|
|
303
|
+
return receiver.find(args[0])
|
|
304
|
+
if name == 'remove' and isinstance(receiver, list) and len(args == 1):
|
|
305
|
+
receiver.remove(args[0])
|
|
306
|
+
return None
|
|
307
|
+
if name == 'pop' and isinstance(receiver, list) and len(args == 1):
|
|
308
|
+
receiver.pop()
|
|
309
|
+
return None
|
|
310
|
+
if name == 'has' and isinstance(receiver, list) and len(args == 1):
|
|
311
|
+
if args[0] in receiver:
|
|
312
|
+
return True
|
|
313
|
+
else:
|
|
314
|
+
return False
|
|
315
|
+
print(f"Error: unsupported method {name}()")
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
def p_expression_and(p):
|
|
319
|
+
'expression : expression AND expression'
|
|
320
|
+
p[0] = bool(p[1]) and bool(p[3])
|
|
321
|
+
|
|
322
|
+
def p_expression_or(p):
|
|
323
|
+
'expression : expression OR expression'
|
|
324
|
+
p[0] = bool(p[1]) or bool(p[3])
|
|
325
|
+
|
|
326
|
+
def p_expression_not(p):
|
|
327
|
+
'expression : NOT expression'
|
|
328
|
+
p[0] = not bool(p[2])
|
|
329
|
+
|
|
330
|
+
def p_expression_equalto(p):
|
|
331
|
+
'expression : expression EQUALTO expression'
|
|
332
|
+
p[0] = p[1] == p[3]
|
|
333
|
+
|
|
334
|
+
def p_expression_notequalto(p):
|
|
335
|
+
'expression : expression NOTEQUALTO expression'
|
|
336
|
+
p[0] = p[1] != p[3]
|
|
337
|
+
|
|
338
|
+
def p_expression_greaterthan(p):
|
|
339
|
+
'expression : expression GREATERTHAN expression'
|
|
340
|
+
p[0] = p[1] > p[3]
|
|
341
|
+
|
|
342
|
+
def p_expression_lessthan(p):
|
|
343
|
+
'expression : expression LESSTHAN expression'
|
|
344
|
+
p[0] = p[1] < p[3]
|
|
345
|
+
|
|
346
|
+
def p_expression_greaterthanequalto(p):
|
|
347
|
+
'expression : expression GREATERTHANEQUALTO expression'
|
|
348
|
+
p[0] = p[1] >= p[3]
|
|
349
|
+
|
|
350
|
+
def p_expression_lessthanequalto(p):
|
|
351
|
+
'expression : expression LESSTHANEQUALTO expression'
|
|
352
|
+
p[0] = p[1] <= p[3]
|
|
353
|
+
|
|
354
|
+
def p_expression_true(p):
|
|
355
|
+
'expression : TRUE'
|
|
356
|
+
p[0] = True
|
|
357
|
+
|
|
358
|
+
def p_expression_false(p):
|
|
359
|
+
'expression : FALSE'
|
|
360
|
+
p[0] = False
|
|
361
|
+
|
|
362
|
+
def p_expression_cond(p):
|
|
363
|
+
'expression : COND LPAREN expression RPAREN'
|
|
364
|
+
p[0] = bool(p[3])
|
|
365
|
+
|
|
366
|
+
def p_error(p):
|
|
367
|
+
if p:
|
|
368
|
+
print("Syntax error at '%s'" % p.value)
|
|
369
|
+
else:
|
|
370
|
+
print("Syntax error at end of input")
|
|
371
|
+
|
|
372
|
+
parser = yacc.yacc()
|
|
373
|
+
|
|
374
|
+
if __name__ == '__main__':
|
|
375
|
+
while True:
|
|
376
|
+
try:
|
|
377
|
+
text = input('bs> ')
|
|
378
|
+
except (EOFError, KeyboardInterrupt):
|
|
379
|
+
break
|
|
380
|
+
if not text.strip():
|
|
381
|
+
continue
|
|
382
|
+
result = parser.parse(text, lexer=lexer_module.lexer.clone())
|
|
383
|
+
if result is not None:
|
|
384
|
+
print(result)
|
core/parsetab.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
# parsetab.py
|
|
3
|
+
# This file is automatically generated. Do not edit.
|
|
4
|
+
# pylint: disable=W,C,R
|
|
5
|
+
_tabversion = '3.10'
|
|
6
|
+
|
|
7
|
+
_lr_method = 'LALR'
|
|
8
|
+
|
|
9
|
+
_lr_signature = 'leftORleftANDrightNOTleftEQUALTONOTEQUALTOleftLESSTHANGREATERTHANLESSTHANEQUALTOGREATERTHANEQUALTOleftPLUSMINUSleftMULTIPLYDIVIDErightPOWERleftLBRACKETADD AND COLON COMMA COND COSINE DIVIDE DOT EQ EQUALTO FALSE GREATERTHAN GREATERTHANEQUALTO LBRACKET LESSTHAN LESSTHANEQUALTO LPAREN MINUS MODULO MULTIPLY NAME NOT NOTEQUALTO NUMBER OR PI PLUS POWER PRINT RANGE RBRACKET RPAREN SINE SQUAREROOT STRING TANGENT TRUEexpression : NUMBERexpression : LPAREN expression RPARENexpression : expression PLUS expressionexpression : expression MINUS expressionexpression : expression DIVIDE expressionexpression : expression MULTIPLY expressionexpression : expression MODULO expressionexpression : expression POWER expressionexpression : SQUAREROOT LPAREN expression RPARENexpression : SINE LPAREN expression RPARENexpression : COSINE LPAREN expression RPARENexpression : TANGENT LPAREN expression RPARENexpression : PIexpression : PRINT LPAREN expression RPARENexpression : STRINGexpression : NAME EQ expressionexpression : NAMEexpression : LBRACKET optional_arguments RBRACKETexpression : expression LBRACKET expression RBRACKETexpression : expression LBRACKET optional_expression COLON optional_expression RBRACKEToptional_expression :optional_expression : expressionoptional_arguments :optional_arguments : argumentsarguments : expressionarguments : arguments COMMA expressionexpression : NAME LPAREN optional_arguments RPARENexpression : RANGE LPAREN optional_arguments RPARENexpression : expression DOT NAME LPAREN optional_arguments RPARENexpression : expression AND expressionexpression : expression OR expressionexpression : NOT expressionexpression : expression EQUALTO expressionexpression : expression NOTEQUALTO expressionexpression : expression GREATERTHAN expressionexpression : expression LESSTHAN expressionexpression : expression GREATERTHANEQUALTO expressionexpression : expression LESSTHANEQUALTO expressionexpression : TRUEexpression : FALSEexpression : COND LPAREN expression RPAREN'
|
|
10
|
+
|
|
11
|
+
_lr_action_items = {'NUMBER':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,]),'LPAREN':([0,3,4,5,6,7,9,11,12,13,14,17,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,56,74,78,79,],[3,3,35,36,37,38,39,41,3,45,3,47,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,79,3,3,3,]),'SQUAREROOT':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,]),'SINE':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'COSINE':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'TANGENT':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'PI':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,]),'PRINT':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'STRING':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,]),'NAME':([0,3,12,14,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[11,11,11,11,11,11,11,11,11,11,11,56,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'LBRACKET':([0,1,2,3,8,10,11,12,14,15,16,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,74,76,77,78,79,80,81,82,83,84,85,86,87,88,89,92,93,],[12,24,-1,12,-13,-15,-17,12,12,-39,-40,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,24,12,12,12,12,12,12,12,24,12,24,12,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,-2,24,24,24,24,24,24,-18,12,24,-19,12,12,-9,-10,-11,-12,-14,-27,24,-28,-41,24,-20,-29,]),'RANGE':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'NOT':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'TRUE':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'FALSE':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'COND':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'$end':([1,2,8,10,11,15,16,46,48,49,50,51,52,53,57,58,59,60,61,62,63,64,65,71,73,77,80,81,82,83,84,85,87,88,92,93,],[0,-1,-13,-15,-17,-39,-40,-32,-3,-4,-5,-6,-7,-8,-30,-31,-33,-34,-35,-36,-37,-38,-2,-16,-18,-19,-9,-10,-11,-12,-14,-27,-28,-41,-20,-29,]),'PLUS':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[18,-1,-13,-15,-17,-39,-40,18,18,18,-3,-4,-5,-6,18,-8,18,18,18,18,18,18,18,18,18,-2,18,18,18,18,18,18,-18,18,-19,-9,-10,-11,-12,-14,-27,18,-28,-41,18,-20,-29,]),'MINUS':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[19,-1,-13,-15,-17,-39,-40,19,19,19,-3,-4,-5,-6,19,-8,19,19,19,19,19,19,19,19,19,-2,19,19,19,19,19,19,-18,19,-19,-9,-10,-11,-12,-14,-27,19,-28,-41,19,-20,-29,]),'DIVIDE':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[20,-1,-13,-15,-17,-39,-40,20,20,20,20,20,-5,-6,20,-8,20,20,20,20,20,20,20,20,20,-2,20,20,20,20,20,20,-18,20,-19,-9,-10,-11,-12,-14,-27,20,-28,-41,20,-20,-29,]),'MULTIPLY':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[21,-1,-13,-15,-17,-39,-40,21,21,21,21,21,-5,-6,21,-8,21,21,21,21,21,21,21,21,21,-2,21,21,21,21,21,21,-18,21,-19,-9,-10,-11,-12,-14,-27,21,-28,-41,21,-20,-29,]),'MODULO':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[22,-1,-13,-15,-17,-39,-40,22,22,-32,-3,-4,-5,-6,22,-8,22,-30,-31,-33,-34,-35,-36,-37,-38,-2,22,22,22,22,22,22,-18,22,-19,-9,-10,-11,-12,-14,-27,22,-28,-41,22,-20,-29,]),'POWER':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[23,-1,-13,-15,-17,-39,-40,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,-2,23,23,23,23,23,23,-18,23,-19,-9,-10,-11,-12,-14,-27,23,-28,-41,23,-20,-29,]),'DOT':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[25,-1,-13,-15,-17,-39,-40,25,25,-32,-3,-4,-5,-6,25,-8,25,-30,-31,-33,-34,-35,-36,-37,-38,-2,25,25,25,25,25,25,-18,25,-19,-9,-10,-11,-12,-14,-27,25,-28,-41,25,-20,-29,]),'AND':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[26,-1,-13,-15,-17,-39,-40,26,26,-32,-3,-4,-5,-6,26,-8,26,-30,26,-33,-34,-35,-36,-37,-38,-2,26,26,26,26,26,26,-18,26,-19,-9,-10,-11,-12,-14,-27,26,-28,-41,26,-20,-29,]),'OR':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[27,-1,-13,-15,-17,-39,-40,27,27,-32,-3,-4,-5,-6,27,-8,27,-30,-31,-33,-34,-35,-36,-37,-38,-2,27,27,27,27,27,27,-18,27,-19,-9,-10,-11,-12,-14,-27,27,-28,-41,27,-20,-29,]),'EQUALTO':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[28,-1,-13,-15,-17,-39,-40,28,28,28,-3,-4,-5,-6,28,-8,28,28,28,-33,-34,-35,-36,-37,-38,-2,28,28,28,28,28,28,-18,28,-19,-9,-10,-11,-12,-14,-27,28,-28,-41,28,-20,-29,]),'NOTEQUALTO':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[29,-1,-13,-15,-17,-39,-40,29,29,29,-3,-4,-5,-6,29,-8,29,29,29,-33,-34,-35,-36,-37,-38,-2,29,29,29,29,29,29,-18,29,-19,-9,-10,-11,-12,-14,-27,29,-28,-41,29,-20,-29,]),'GREATERTHAN':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[30,-1,-13,-15,-17,-39,-40,30,30,30,-3,-4,-5,-6,30,-8,30,30,30,30,30,-35,-36,-37,-38,-2,30,30,30,30,30,30,-18,30,-19,-9,-10,-11,-12,-14,-27,30,-28,-41,30,-20,-29,]),'LESSTHAN':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[31,-1,-13,-15,-17,-39,-40,31,31,31,-3,-4,-5,-6,31,-8,31,31,31,31,31,-35,-36,-37,-38,-2,31,31,31,31,31,31,-18,31,-19,-9,-10,-11,-12,-14,-27,31,-28,-41,31,-20,-29,]),'GREATERTHANEQUALTO':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[32,-1,-13,-15,-17,-39,-40,32,32,32,-3,-4,-5,-6,32,-8,32,32,32,32,32,-35,-36,-37,-38,-2,32,32,32,32,32,32,-18,32,-19,-9,-10,-11,-12,-14,-27,32,-28,-41,32,-20,-29,]),'LESSTHANEQUALTO':([1,2,8,10,11,15,16,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,76,77,80,81,82,83,84,85,86,87,88,89,92,93,],[33,-1,-13,-15,-17,-39,-40,33,33,33,-3,-4,-5,-6,33,-8,33,33,33,33,33,-35,-36,-37,-38,-2,33,33,33,33,33,33,-18,33,-19,-9,-10,-11,-12,-14,-27,33,-28,-41,33,-20,-29,]),'RPAREN':([2,8,10,11,15,16,34,41,43,44,45,46,48,49,50,51,52,53,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,75,76,77,79,80,81,82,83,84,85,86,87,88,91,92,93,],[-1,-13,-15,-17,-39,-40,65,-23,-24,-25,-23,-32,-3,-4,-5,-6,-7,-8,-30,-31,-33,-34,-35,-36,-37,-38,-2,80,81,82,83,84,-16,85,-18,87,88,-19,-23,-9,-10,-11,-12,-14,-27,-26,-28,-41,93,-20,-29,]),'COMMA':([2,8,10,11,15,16,43,44,46,48,49,50,51,52,53,57,58,59,60,61,62,63,64,65,71,73,77,80,81,82,83,84,85,86,87,88,92,93,],[-1,-13,-15,-17,-39,-40,74,-25,-32,-3,-4,-5,-6,-7,-8,-30,-31,-33,-34,-35,-36,-37,-38,-2,-16,-18,-19,-9,-10,-11,-12,-14,-27,-26,-28,-41,-20,-29,]),'RBRACKET':([2,8,10,11,12,15,16,42,43,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,65,71,73,77,78,80,81,82,83,84,85,86,87,88,89,90,92,93,],[-1,-13,-15,-17,-23,-39,-40,73,-24,-25,-32,-3,-4,-5,-6,-7,-8,77,-30,-31,-33,-34,-35,-36,-37,-38,-2,-16,-18,-19,-21,-9,-10,-11,-12,-14,-27,-26,-28,-41,-22,92,-20,-29,]),'COLON':([2,8,10,11,15,16,24,46,48,49,50,51,52,53,54,55,57,58,59,60,61,62,63,64,65,71,73,77,80,81,82,83,84,85,87,88,92,93,],[-1,-13,-15,-17,-39,-40,-21,-32,-3,-4,-5,-6,-7,-8,-22,78,-30,-31,-33,-34,-35,-36,-37,-38,-2,-16,-18,-19,-9,-10,-11,-12,-14,-27,-28,-41,-20,-29,]),'EQ':([11,],[40,]),}
|
|
12
|
+
|
|
13
|
+
_lr_action = {}
|
|
14
|
+
for _k, _v in _lr_action_items.items():
|
|
15
|
+
for _x,_y in zip(_v[0],_v[1]):
|
|
16
|
+
if not _x in _lr_action: _lr_action[_x] = {}
|
|
17
|
+
_lr_action[_x][_k] = _y
|
|
18
|
+
del _lr_action_items
|
|
19
|
+
|
|
20
|
+
_lr_goto_items = {'expression':([0,3,12,14,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,35,36,37,38,39,40,41,45,47,74,78,79,],[1,34,44,46,48,49,50,51,52,53,54,57,58,59,60,61,62,63,64,66,67,68,69,70,71,44,44,76,86,89,44,]),'optional_arguments':([12,41,45,79,],[42,72,75,91,]),'arguments':([12,41,45,79,],[43,43,43,43,]),'optional_expression':([24,78,],[55,90,]),}
|
|
21
|
+
|
|
22
|
+
_lr_goto = {}
|
|
23
|
+
for _k, _v in _lr_goto_items.items():
|
|
24
|
+
for _x, _y in zip(_v[0], _v[1]):
|
|
25
|
+
if not _x in _lr_goto: _lr_goto[_x] = {}
|
|
26
|
+
_lr_goto[_x][_k] = _y
|
|
27
|
+
del _lr_goto_items
|
|
28
|
+
_lr_productions = [
|
|
29
|
+
("S' -> expression","S'",1,None,None,None),
|
|
30
|
+
('expression -> NUMBER','expression',1,'p_expression_number','parser.py',77),
|
|
31
|
+
('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','parser.py',81),
|
|
32
|
+
('expression -> expression PLUS expression','expression',3,'p_expression_plus','parser.py',85),
|
|
33
|
+
('expression -> expression MINUS expression','expression',3,'p_expression_minus','parser.py',93),
|
|
34
|
+
('expression -> expression DIVIDE expression','expression',3,'p_expression_divide','parser.py',97),
|
|
35
|
+
('expression -> expression MULTIPLY expression','expression',3,'p_expression_times','parser.py',105),
|
|
36
|
+
('expression -> expression MODULO expression','expression',3,'p_expression_modulo','parser.py',113),
|
|
37
|
+
('expression -> expression POWER expression','expression',3,'p_expression_power','parser.py',117),
|
|
38
|
+
('expression -> SQUAREROOT LPAREN expression RPAREN','expression',4,'p_expression_squareroot','parser.py',121),
|
|
39
|
+
('expression -> SINE LPAREN expression RPAREN','expression',4,'p_expression_sine','parser.py',125),
|
|
40
|
+
('expression -> COSINE LPAREN expression RPAREN','expression',4,'p_expression_cosine','parser.py',129),
|
|
41
|
+
('expression -> TANGENT LPAREN expression RPAREN','expression',4,'p_expression_tangent','parser.py',133),
|
|
42
|
+
('expression -> PI','expression',1,'p_expression_pi','parser.py',137),
|
|
43
|
+
('expression -> PRINT LPAREN expression RPAREN','expression',4,'p_expression_print','parser.py',141),
|
|
44
|
+
('expression -> STRING','expression',1,'p_expression_string','parser.py',146),
|
|
45
|
+
('expression -> NAME EQ expression','expression',3,'p_statement_assign','parser.py',150),
|
|
46
|
+
('expression -> NAME','expression',1,'p_expression_name','parser.py',155),
|
|
47
|
+
('expression -> LBRACKET optional_arguments RBRACKET','expression',3,'p_expression_list','parser.py',163),
|
|
48
|
+
('expression -> expression LBRACKET expression RBRACKET','expression',4,'p_expression_index','parser.py',167),
|
|
49
|
+
('expression -> expression LBRACKET optional_expression COLON optional_expression RBRACKET','expression',6,'p_expression_slice','parser.py',175),
|
|
50
|
+
('optional_expression -> <empty>','optional_expression',0,'p_optional_expression_empty','parser.py',183),
|
|
51
|
+
('optional_expression -> expression','optional_expression',1,'p_optional_expression_value','parser.py',187),
|
|
52
|
+
('optional_arguments -> <empty>','optional_arguments',0,'p_optional_arguments_empty','parser.py',191),
|
|
53
|
+
('optional_arguments -> arguments','optional_arguments',1,'p_optional_arguments_value','parser.py',195),
|
|
54
|
+
('arguments -> expression','arguments',1,'p_arguments_single','parser.py',199),
|
|
55
|
+
('arguments -> arguments COMMA expression','arguments',3,'p_arguments_many','parser.py',203),
|
|
56
|
+
('expression -> NAME LPAREN optional_arguments RPAREN','expression',4,'p_expression_function_call','parser.py',207),
|
|
57
|
+
('expression -> RANGE LPAREN optional_arguments RPAREN','expression',4,'p_expression_range_call','parser.py',211),
|
|
58
|
+
('expression -> expression DOT NAME LPAREN optional_arguments RPAREN','expression',6,'p_expression_method_call','parser.py',215),
|
|
59
|
+
('expression -> expression AND expression','expression',3,'p_expression_and','parser.py',319),
|
|
60
|
+
('expression -> expression OR expression','expression',3,'p_expression_or','parser.py',323),
|
|
61
|
+
('expression -> NOT expression','expression',2,'p_expression_not','parser.py',327),
|
|
62
|
+
('expression -> expression EQUALTO expression','expression',3,'p_expression_equalto','parser.py',331),
|
|
63
|
+
('expression -> expression NOTEQUALTO expression','expression',3,'p_expression_notequalto','parser.py',335),
|
|
64
|
+
('expression -> expression GREATERTHAN expression','expression',3,'p_expression_greaterthan','parser.py',339),
|
|
65
|
+
('expression -> expression LESSTHAN expression','expression',3,'p_expression_lessthan','parser.py',343),
|
|
66
|
+
('expression -> expression GREATERTHANEQUALTO expression','expression',3,'p_expression_greaterthanequalto','parser.py',347),
|
|
67
|
+
('expression -> expression LESSTHANEQUALTO expression','expression',3,'p_expression_lessthanequalto','parser.py',351),
|
|
68
|
+
('expression -> TRUE','expression',1,'p_expression_true','parser.py',355),
|
|
69
|
+
('expression -> FALSE','expression',1,'p_expression_false','parser.py',359),
|
|
70
|
+
('expression -> COND LPAREN expression RPAREN','expression',4,'p_expression_cond','parser.py',363),
|
|
71
|
+
]
|
libs/__init__.py
ADDED
|
File without changes
|
libs/convert.bs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# distance conversions
|
|
2
|
+
func inchesToCentimeters(a):
|
|
3
|
+
return a * 2.54
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
func centimetersToInches(a):
|
|
7
|
+
return a / 2.54
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# temperature conversions
|
|
11
|
+
func celToFahrenheit(a):
|
|
12
|
+
f = (a*(9/5))+32
|
|
13
|
+
return f
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
func fahrenheitToCel(a):
|
|
17
|
+
c = (a-32)*(5/9)
|
|
18
|
+
return c
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
func celToKelvin(a):
|
|
22
|
+
k = a + 273.15
|
|
23
|
+
return k
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# energy conversions
|
|
27
|
+
func calToJoule(a):
|
|
28
|
+
j = a * 4.184
|
|
29
|
+
return j
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
func jouleToCal(a):
|
|
33
|
+
c = a / 4.184
|
|
34
|
+
return c
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
func atmToPa(a):
|
|
38
|
+
p = a * 101325
|
|
39
|
+
return p
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# mass and weight
|
|
43
|
+
func kgToLbs(a):
|
|
44
|
+
return a * 2.2046226218
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
func lbsToKg(a):
|
|
48
|
+
return a / 2.2046226218
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
func ozToGrams(a):
|
|
52
|
+
return a * 28.35
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
func gramsToOz(a):
|
|
56
|
+
return a / 28.35
|
|
57
|
+
end
|
libs/math.bs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
func max(a, b):
|
|
2
|
+
cond a > b:
|
|
3
|
+
return a
|
|
4
|
+
end
|
|
5
|
+
return b
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
func min(a, b):
|
|
9
|
+
cond a < b:
|
|
10
|
+
return a
|
|
11
|
+
end
|
|
12
|
+
return b
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
func abs(x):
|
|
16
|
+
cond x < 0:
|
|
17
|
+
return x * -1
|
|
18
|
+
end
|
|
19
|
+
return x
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
func clamp(x, low, high):
|
|
23
|
+
cond x < low:
|
|
24
|
+
return low
|
|
25
|
+
end
|
|
26
|
+
cond x > high:
|
|
27
|
+
return high
|
|
28
|
+
end
|
|
29
|
+
return x
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
func factorial(n):
|
|
33
|
+
cond n <= 1:
|
|
34
|
+
return 1
|
|
35
|
+
end
|
|
36
|
+
return n * factorial(n - 1)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
func pow(base, exp):
|
|
40
|
+
result = 1
|
|
41
|
+
i = 0
|
|
42
|
+
while i < exp:
|
|
43
|
+
result = result * base
|
|
44
|
+
i = i + 1
|
|
45
|
+
end
|
|
46
|
+
return result
|
|
47
|
+
end
|