-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdynamic_module_example.py
More file actions
131 lines (103 loc) · 4.09 KB
/
Copy pathdynamic_module_example.py
File metadata and controls
131 lines (103 loc) · 4.09 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
"""
Example dynamic Forthic module for testing configuration-based loading.
This demonstrates how to create a custom module that can be loaded
via the module configuration system.
Usage:
1. Create a modules config file pointing to this module
2. Start the server with --modules-config
3. Use the module from TypeScript via USE-PY-MODULES
"""
from forthic.decorators import DecoratedModule, ForthicDirectWord, ForthicWord
class ExampleModule(DecoratedModule):
"""Example module with math and string operations"""
def __init__(self):
super().__init__("example")
# ==================
# Math Operations
# ==================
@ForthicWord("( a:int b:int -- c:int )", "Multiply two numbers")
async def MULTIPLY(self, a: int, b: int) -> int:
"""Multiply two numbers."""
return a * b
@ForthicWord("( n:int -- n:int )", "Square a number")
async def SQUARE(self, n: int) -> int:
"""Square a number (n * n)."""
return n * n
@ForthicWord("( a:int b:int -- c:int )", "Calculate power (a^b)")
async def POWER(self, a: int, b: int) -> int:
"""Calculate a raised to the power of b."""
return a ** b
# ==================
# String Operations
# ==================
@ForthicWord("( text:str -- text:str )", "Reverse a string")
async def REVERSE_TEXT(self, text: str) -> str:
"""Reverse a string."""
return text[::-1]
@ForthicWord("( text:str char:str -- count:int )", "Count character occurrences")
async def COUNT_CHAR(self, text: str, char: str) -> int:
"""Count occurrences of a character in text."""
return text.count(char)
@ForthicWord("( words:list -- sentence:str )", "Join words into sentence")
async def MAKE_SENTENCE(self, words: list) -> str:
"""Join list of words into a sentence."""
return " ".join(str(w) for w in words)
# ==================
# List Operations
# ==================
@ForthicWord("( items:list -- sum:int )", "Sum all numbers in list")
async def SUM_LIST(self, items: list) -> int:
"""Sum all numbers in a list."""
return sum(items)
@ForthicWord("( items:list -- avg:float )", "Average of numbers in list")
async def AVG_LIST(self, items: list) -> float:
"""Calculate average of numbers in list."""
if not items:
return 0.0
return sum(items) / len(items)
@ForthicWord("( items:list n:int -- chunks:list )", "Chunk list into groups of n")
async def CHUNK_LIST(self, items: list, n: int) -> list:
"""Split list into chunks of size n."""
return [items[i:i + n] for i in range(0, len(items), n)]
# ==================
# Utility Operations
# ==================
@ForthicWord("( n:int -- fibonacci:int )", "Calculate nth Fibonacci number")
async def FIBONACCI(self, n: int) -> int:
"""Calculate nth Fibonacci number (0-indexed)."""
if n <= 0:
return 0
elif n == 1:
return 1
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
@ForthicWord("( n:int -- is_prime:bool )", "Check if number is prime")
async def IS_PRIME(self, n: int) -> bool:
"""Check if a number is prime."""
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
@ForthicDirectWord("( n:int forthic:str -- results:list )", "Map Forthic over range")
async def MAP_RANGE(self, interp) -> None:
"""
Map Forthic code over range(n).
Example: 5 "DUP *" MAP-RANGE # [0, 1, 4, 9, 16]
"""
forthic = interp.stack_pop()
n = interp.stack_pop()
string_location = interp.get_string_location()
results = []
for i in range(n):
interp.stack_push(i)
await interp.run(forthic, string_location)
results.append(interp.stack_pop())
interp.stack_push(results)