IncludeCPP 4.5.2__py3-none-any.whl → 4.9.3__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.
Files changed (35) hide show
  1. includecpp/CHANGELOG.md +241 -0
  2. includecpp/__init__.py +89 -3
  3. includecpp/__init__.pyi +2 -1
  4. includecpp/cli/commands.py +1747 -266
  5. includecpp/cli/config_parser.py +1 -1
  6. includecpp/core/build_manager.py +64 -13
  7. includecpp/core/cpp_api_extensions.pyi +43 -270
  8. includecpp/core/cssl/CSSL_DOCUMENTATION.md +1799 -1445
  9. includecpp/core/cssl/cpp/build/api.pyd +0 -0
  10. includecpp/core/cssl/cpp/build/api.pyi +274 -0
  11. includecpp/core/cssl/cpp/build/cssl_core.pyi +0 -99
  12. includecpp/core/cssl/cpp/cssl_core.cp +2 -23
  13. includecpp/core/cssl/cssl_builtins.py +2116 -171
  14. includecpp/core/cssl/cssl_builtins.pyi +1324 -104
  15. includecpp/core/cssl/cssl_compiler.py +4 -1
  16. includecpp/core/cssl/cssl_modules.py +605 -6
  17. includecpp/core/cssl/cssl_optimizer.py +12 -1
  18. includecpp/core/cssl/cssl_parser.py +1048 -52
  19. includecpp/core/cssl/cssl_runtime.py +2041 -131
  20. includecpp/core/cssl/cssl_syntax.py +405 -277
  21. includecpp/core/cssl/cssl_types.py +5891 -1655
  22. includecpp/core/cssl_bridge.py +429 -3
  23. includecpp/core/error_catalog.py +54 -10
  24. includecpp/core/homeserver.py +1037 -0
  25. includecpp/generator/parser.cpp +203 -39
  26. includecpp/generator/parser.h +15 -1
  27. includecpp/templates/cpp.proj.template +1 -1
  28. includecpp/vscode/cssl/snippets/cssl.snippets.json +163 -0
  29. includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +87 -12
  30. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/METADATA +81 -10
  31. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/RECORD +35 -33
  32. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/WHEEL +1 -1
  33. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/entry_points.txt +0 -0
  34. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/licenses/LICENSE +0 -0
  35. {includecpp-4.5.2.dist-info → includecpp-4.9.3.dist-info}/top_level.txt +0 -0
@@ -366,7 +366,10 @@ def compile_cssl_core(force: bool = False) -> Optional[Path]:
366
366
 
367
367
  if result.returncode == 0:
368
368
  # Find built module and copy to bundled folder
369
- appdata = Path(os.environ.get('APPDATA', ''))
369
+ if sys.platform == 'win32':
370
+ appdata = Path(os.environ.get('APPDATA', Path.home() / 'AppData' / 'Roaming'))
371
+ else:
372
+ appdata = Path.home() / '.local' / 'share'
370
373
  icpp_build = appdata / 'cssl_core-g-build-proj' / 'bindings'
371
374
 
372
375
  # Copy api.pyd to bundled folder
@@ -1551,11 +1551,8 @@ class ConsoleModule(CSSLModuleBase):
1551
1551
  self._methods['beep'] = self.beep
1552
1552
 
1553
1553
  def clear(self):
1554
- """Clear the console screen."""
1555
- if os.name == 'nt':
1556
- os.system('cls')
1557
- else:
1558
- print('\033[2J\033[H', end='')
1554
+ """Clear the console screen using ANSI escape codes (works on all modern terminals)."""
1555
+ print('\033[2J\033[H', end='', flush=True)
1559
1556
 
1560
1557
  def print_styled(self, text: str, color: str = None) -> None:
1561
1558
  """Print text with optional color."""
@@ -1708,6 +1705,496 @@ class ConsoleModule(CSSLModuleBase):
1708
1705
  print('\a', end='')
1709
1706
 
1710
1707
 
1708
+ # =============================================================================
1709
+ # @fmt Module - Text formatting and colors (ANSI)
1710
+ # =============================================================================
1711
+
1712
+ class FmtModule(CSSLModuleBase):
1713
+ """
1714
+ @fmt - Text formatting with ANSI colors and utilities
1715
+
1716
+ Usage: fmt::green("Success!"), fmt::bold("Important")
1717
+
1718
+ Colors (basic):
1719
+ red, green, blue, yellow, cyan, magenta, white, black
1720
+
1721
+ Colors (extended):
1722
+ pink, purple, orange, gold, lime, teal, navy, olive,
1723
+ maroon, coral, salmon, turquoise, silver, brown, gray
1724
+
1725
+ Light/Dark variants:
1726
+ light_red, dark_red, light_green, dark_green, etc.
1727
+
1728
+ Styles:
1729
+ bold, dim, italic, underline, blink, reverse
1730
+
1731
+ Advanced:
1732
+ color(text, fg, bg) - Custom foreground/background
1733
+ rgb(text, r, g, b) - RGB color (24-bit)
1734
+ hex(text, "#rrggbb") - Hex color
1735
+ reset() - Reset all formatting
1736
+
1737
+ Utilities:
1738
+ clear() - Clear screen
1739
+ log(msg) - Log with timestamp [INFO]
1740
+ error(msg) - Log error in red [ERROR]
1741
+ warning(msg) - Log warning in yellow [WARNING]
1742
+ success(msg) - Log success in green [SUCCESS]
1743
+ debug(msg) - Log debug in gray [DEBUG]
1744
+ hidden_input(prompt) - Hidden input (for passwords)
1745
+ cursor_up(n) - Move cursor up n lines
1746
+ cursor_down(n) - Move cursor down n lines
1747
+ cursor_hide() - Hide cursor
1748
+ cursor_show() - Show cursor
1749
+ """
1750
+
1751
+ def __init__(self, runtime=None):
1752
+ super().__init__(runtime)
1753
+
1754
+ def _register_methods(self):
1755
+ # Basic colors
1756
+ self._methods['red'] = self.red
1757
+ self._methods['green'] = self.green
1758
+ self._methods['blue'] = self.blue
1759
+ self._methods['yellow'] = self.yellow
1760
+ self._methods['cyan'] = self.cyan
1761
+ self._methods['magenta'] = self.magenta
1762
+ self._methods['white'] = self.white
1763
+ self._methods['black'] = self.black
1764
+ # Bright colors
1765
+ self._methods['bright_red'] = self.bright_red
1766
+ self._methods['bright_green'] = self.bright_green
1767
+ self._methods['bright_blue'] = self.bright_blue
1768
+ self._methods['bright_yellow'] = self.bright_yellow
1769
+ self._methods['bright_cyan'] = self.bright_cyan
1770
+ self._methods['bright_magenta'] = self.bright_magenta
1771
+ self._methods['bright_white'] = self.bright_white
1772
+ # Extended colors (24-bit RGB)
1773
+ self._methods['pink'] = self.pink
1774
+ self._methods['purple'] = self.purple
1775
+ self._methods['orange'] = self.orange
1776
+ self._methods['gold'] = self.gold
1777
+ self._methods['lime'] = self.lime
1778
+ self._methods['teal'] = self.teal
1779
+ self._methods['navy'] = self.navy
1780
+ self._methods['olive'] = self.olive
1781
+ self._methods['maroon'] = self.maroon
1782
+ self._methods['coral'] = self.coral
1783
+ self._methods['salmon'] = self.salmon
1784
+ self._methods['turquoise'] = self.turquoise
1785
+ self._methods['silver'] = self.silver
1786
+ self._methods['brown'] = self.brown
1787
+ self._methods['gray'] = self.gray
1788
+ self._methods['grey'] = self.gray # Alias
1789
+ # Light variants
1790
+ self._methods['light_red'] = self.light_red
1791
+ self._methods['light_green'] = self.light_green
1792
+ self._methods['light_blue'] = self.light_blue
1793
+ self._methods['light_yellow'] = self.light_yellow
1794
+ self._methods['light_cyan'] = self.light_cyan
1795
+ self._methods['light_magenta'] = self.light_magenta
1796
+ self._methods['light_pink'] = self.light_pink
1797
+ self._methods['light_purple'] = self.light_purple
1798
+ self._methods['light_gray'] = self.light_gray
1799
+ self._methods['light_grey'] = self.light_gray # Alias
1800
+ # Dark variants
1801
+ self._methods['dark_red'] = self.dark_red
1802
+ self._methods['dark_green'] = self.dark_green
1803
+ self._methods['dark_blue'] = self.dark_blue
1804
+ self._methods['dark_yellow'] = self.dark_yellow
1805
+ self._methods['dark_cyan'] = self.dark_cyan
1806
+ self._methods['dark_magenta'] = self.dark_magenta
1807
+ self._methods['dark_gray'] = self.dark_gray
1808
+ self._methods['dark_grey'] = self.dark_gray # Alias
1809
+ # Styles
1810
+ self._methods['bold'] = self.bold
1811
+ self._methods['dim'] = self.dim
1812
+ self._methods['italic'] = self.italic
1813
+ self._methods['underline'] = self.underline
1814
+ self._methods['blink'] = self.blink
1815
+ self._methods['reverse'] = self.reverse
1816
+ # Advanced
1817
+ self._methods['color'] = self.color
1818
+ self._methods['rgb'] = self.rgb
1819
+ self._methods['hex'] = self.hex_color
1820
+ # v4.8.8: Code-only variants (return just ANSI code, no text)
1821
+ self._methods['rgb_code'] = self.rgb_code
1822
+ self._methods['hex_code'] = self.hex_code_only
1823
+ self._methods['reset'] = self.reset
1824
+ self._methods['strip'] = self.strip_ansi
1825
+ # Utilities
1826
+ self._methods['clear'] = self.clear
1827
+ self._methods['log'] = self.log
1828
+ self._methods['error'] = self.error
1829
+ self._methods['warning'] = self.warning
1830
+ self._methods['warn'] = self.warning # Alias
1831
+ self._methods['success'] = self.success
1832
+ self._methods['debug'] = self.debug
1833
+ self._methods['info'] = self.info
1834
+ self._methods['hidden_input'] = self.hidden_input
1835
+ self._methods['password'] = self.hidden_input # Alias
1836
+ self._methods['cursor_up'] = self.cursor_up
1837
+ self._methods['cursor_down'] = self.cursor_down
1838
+ self._methods['cursor_hide'] = self.cursor_hide
1839
+ self._methods['cursor_show'] = self.cursor_show
1840
+ self._methods['cursor_save'] = self.cursor_save
1841
+ self._methods['cursor_restore'] = self.cursor_restore
1842
+ self._methods['erase_line'] = self.erase_line
1843
+ self._methods['move_to'] = self.move_to
1844
+ self._methods['progress'] = self.progress
1845
+
1846
+ def _to_str(self, value) -> str:
1847
+ """Convert value to string."""
1848
+ return str(value) if value is not None else "null"
1849
+
1850
+ # Basic colors
1851
+ def red(self, text) -> str:
1852
+ return f'\033[31m{self._to_str(text)}\033[0m'
1853
+
1854
+ def green(self, text) -> str:
1855
+ return f'\033[32m{self._to_str(text)}\033[0m'
1856
+
1857
+ def blue(self, text) -> str:
1858
+ return f'\033[34m{self._to_str(text)}\033[0m'
1859
+
1860
+ def yellow(self, text) -> str:
1861
+ return f'\033[33m{self._to_str(text)}\033[0m'
1862
+
1863
+ def cyan(self, text) -> str:
1864
+ return f'\033[36m{self._to_str(text)}\033[0m'
1865
+
1866
+ def magenta(self, text) -> str:
1867
+ return f'\033[35m{self._to_str(text)}\033[0m'
1868
+
1869
+ def white(self, text) -> str:
1870
+ return f'\033[37m{self._to_str(text)}\033[0m'
1871
+
1872
+ def black(self, text) -> str:
1873
+ return f'\033[30m{self._to_str(text)}\033[0m'
1874
+
1875
+ # Bright colors
1876
+ def bright_red(self, text) -> str:
1877
+ return f'\033[91m{self._to_str(text)}\033[0m'
1878
+
1879
+ def bright_green(self, text) -> str:
1880
+ return f'\033[92m{self._to_str(text)}\033[0m'
1881
+
1882
+ def bright_blue(self, text) -> str:
1883
+ return f'\033[94m{self._to_str(text)}\033[0m'
1884
+
1885
+ def bright_yellow(self, text) -> str:
1886
+ return f'\033[93m{self._to_str(text)}\033[0m'
1887
+
1888
+ def bright_cyan(self, text) -> str:
1889
+ return f'\033[96m{self._to_str(text)}\033[0m'
1890
+
1891
+ def bright_magenta(self, text) -> str:
1892
+ return f'\033[95m{self._to_str(text)}\033[0m'
1893
+
1894
+ def bright_white(self, text) -> str:
1895
+ return f'\033[97m{self._to_str(text)}\033[0m'
1896
+
1897
+ # Extended colors (24-bit RGB)
1898
+ def pink(self, text) -> str:
1899
+ return f'\033[38;2;255;105;180m{self._to_str(text)}\033[0m'
1900
+
1901
+ def purple(self, text) -> str:
1902
+ return f'\033[38;2;128;0;128m{self._to_str(text)}\033[0m'
1903
+
1904
+ def orange(self, text) -> str:
1905
+ return f'\033[38;2;255;165;0m{self._to_str(text)}\033[0m'
1906
+
1907
+ def gold(self, text) -> str:
1908
+ return f'\033[38;2;255;215;0m{self._to_str(text)}\033[0m'
1909
+
1910
+ def lime(self, text) -> str:
1911
+ return f'\033[38;2;0;255;0m{self._to_str(text)}\033[0m'
1912
+
1913
+ def teal(self, text) -> str:
1914
+ return f'\033[38;2;0;128;128m{self._to_str(text)}\033[0m'
1915
+
1916
+ def navy(self, text) -> str:
1917
+ return f'\033[38;2;0;0;128m{self._to_str(text)}\033[0m'
1918
+
1919
+ def olive(self, text) -> str:
1920
+ return f'\033[38;2;128;128;0m{self._to_str(text)}\033[0m'
1921
+
1922
+ def maroon(self, text) -> str:
1923
+ return f'\033[38;2;128;0;0m{self._to_str(text)}\033[0m'
1924
+
1925
+ def coral(self, text) -> str:
1926
+ return f'\033[38;2;255;127;80m{self._to_str(text)}\033[0m'
1927
+
1928
+ def salmon(self, text) -> str:
1929
+ return f'\033[38;2;250;128;114m{self._to_str(text)}\033[0m'
1930
+
1931
+ def turquoise(self, text) -> str:
1932
+ return f'\033[38;2;64;224;208m{self._to_str(text)}\033[0m'
1933
+
1934
+ def silver(self, text) -> str:
1935
+ return f'\033[38;2;192;192;192m{self._to_str(text)}\033[0m'
1936
+
1937
+ def brown(self, text) -> str:
1938
+ return f'\033[38;2;139;69;19m{self._to_str(text)}\033[0m'
1939
+
1940
+ def gray(self, text) -> str:
1941
+ return f'\033[38;2;128;128;128m{self._to_str(text)}\033[0m'
1942
+
1943
+ # Light color variants
1944
+ def light_red(self, text) -> str:
1945
+ return f'\033[38;2;255;102;102m{self._to_str(text)}\033[0m'
1946
+
1947
+ def light_green(self, text) -> str:
1948
+ return f'\033[38;2;144;238;144m{self._to_str(text)}\033[0m'
1949
+
1950
+ def light_blue(self, text) -> str:
1951
+ return f'\033[38;2;173;216;230m{self._to_str(text)}\033[0m'
1952
+
1953
+ def light_yellow(self, text) -> str:
1954
+ return f'\033[38;2;255;255;224m{self._to_str(text)}\033[0m'
1955
+
1956
+ def light_cyan(self, text) -> str:
1957
+ return f'\033[38;2;224;255;255m{self._to_str(text)}\033[0m'
1958
+
1959
+ def light_magenta(self, text) -> str:
1960
+ return f'\033[38;2;255;119;255m{self._to_str(text)}\033[0m'
1961
+
1962
+ def light_pink(self, text) -> str:
1963
+ return f'\033[38;2;255;182;193m{self._to_str(text)}\033[0m'
1964
+
1965
+ def light_purple(self, text) -> str:
1966
+ return f'\033[38;2;221;160;221m{self._to_str(text)}\033[0m'
1967
+
1968
+ def light_gray(self, text) -> str:
1969
+ return f'\033[38;2;211;211;211m{self._to_str(text)}\033[0m'
1970
+
1971
+ # Dark color variants
1972
+ def dark_red(self, text) -> str:
1973
+ return f'\033[38;2;139;0;0m{self._to_str(text)}\033[0m'
1974
+
1975
+ def dark_green(self, text) -> str:
1976
+ return f'\033[38;2;0;100;0m{self._to_str(text)}\033[0m'
1977
+
1978
+ def dark_blue(self, text) -> str:
1979
+ return f'\033[38;2;0;0;139m{self._to_str(text)}\033[0m'
1980
+
1981
+ def dark_yellow(self, text) -> str:
1982
+ return f'\033[38;2;204;153;0m{self._to_str(text)}\033[0m'
1983
+
1984
+ def dark_cyan(self, text) -> str:
1985
+ return f'\033[38;2;0;139;139m{self._to_str(text)}\033[0m'
1986
+
1987
+ def dark_magenta(self, text) -> str:
1988
+ return f'\033[38;2;139;0;139m{self._to_str(text)}\033[0m'
1989
+
1990
+ def dark_gray(self, text) -> str:
1991
+ return f'\033[38;2;105;105;105m{self._to_str(text)}\033[0m'
1992
+
1993
+ # Styles
1994
+ def bold(self, text) -> str:
1995
+ return f'\033[1m{self._to_str(text)}\033[0m'
1996
+
1997
+ def dim(self, text) -> str:
1998
+ return f'\033[2m{self._to_str(text)}\033[0m'
1999
+
2000
+ def italic(self, text) -> str:
2001
+ return f'\033[3m{self._to_str(text)}\033[0m'
2002
+
2003
+ def underline(self, text) -> str:
2004
+ return f'\033[4m{self._to_str(text)}\033[0m'
2005
+
2006
+ def blink(self, text) -> str:
2007
+ return f'\033[5m{self._to_str(text)}\033[0m'
2008
+
2009
+ def reverse(self, text) -> str:
2010
+ return f'\033[7m{self._to_str(text)}\033[0m'
2011
+
2012
+ # Advanced
2013
+ def color(self, text, fg: str = None, bg: str = None) -> str:
2014
+ """Apply custom foreground and/or background color."""
2015
+ colors = {
2016
+ 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
2017
+ 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37,
2018
+ 'bright_black': 90, 'bright_red': 91, 'bright_green': 92,
2019
+ 'bright_yellow': 93, 'bright_blue': 94, 'bright_magenta': 95,
2020
+ 'bright_cyan': 96, 'bright_white': 97
2021
+ }
2022
+ codes = []
2023
+ if fg and fg.lower() in colors:
2024
+ codes.append(str(colors[fg.lower()]))
2025
+ if bg and bg.lower() in colors:
2026
+ codes.append(str(colors[bg.lower()] + 10))
2027
+ if codes:
2028
+ return f'\033[{";".join(codes)}m{self._to_str(text)}\033[0m'
2029
+ return self._to_str(text)
2030
+
2031
+ def rgb(self, text, r: int, g: int, b: int) -> str:
2032
+ """Apply 24-bit RGB color."""
2033
+ return f'\033[38;2;{r};{g};{b}m{self._to_str(text)}\033[0m'
2034
+
2035
+ def hex_color(self, text, hex_code: str) -> str:
2036
+ """Apply hex color (#rrggbb or rrggbb)."""
2037
+ hex_code = hex_code.lstrip('#')
2038
+ if len(hex_code) == 6:
2039
+ r = int(hex_code[0:2], 16)
2040
+ g = int(hex_code[2:4], 16)
2041
+ b = int(hex_code[4:6], 16)
2042
+ return self.rgb(text, r, g, b)
2043
+ return self._to_str(text)
2044
+
2045
+ def rgb_code(self, r: int, g: int, b: int) -> str:
2046
+ """v4.8.8: Return just the RGB ANSI code (no text, no reset).
2047
+
2048
+ Usage:
2049
+ OUTPUT_PREFIX = fmt::rgb_code(180, 66, 175); // Just the color code
2050
+ println(OUTPUT_PREFIX + "colored text" + fmt::reset());
2051
+ """
2052
+ return f'\033[38;2;{r};{g};{b}m'
2053
+
2054
+ def hex_code_only(self, hex_code: str) -> str:
2055
+ """v4.8.8: Return just the hex color ANSI code (no text, no reset).
2056
+
2057
+ Usage:
2058
+ OUTPUT_PREFIX = fmt::hex_code("#b442af"); // Just the color code
2059
+ println(OUTPUT_PREFIX + "colored text" + fmt::reset());
2060
+ """
2061
+ hex_code = hex_code.lstrip('#')
2062
+ if len(hex_code) == 6:
2063
+ r = int(hex_code[0:2], 16)
2064
+ g = int(hex_code[2:4], 16)
2065
+ b = int(hex_code[4:6], 16)
2066
+ return f'\033[38;2;{r};{g};{b}m'
2067
+ return ''
2068
+
2069
+ def reset(self) -> str:
2070
+ """Return ANSI reset code."""
2071
+ return '\033[0m'
2072
+
2073
+ def strip_ansi(self, text) -> str:
2074
+ """Strip all ANSI codes from text."""
2075
+ import re
2076
+ return re.sub(r'\033\[[0-9;]*m', '', self._to_str(text))
2077
+
2078
+ # Utilities
2079
+ def clear(self) -> str:
2080
+ """Clear screen and move cursor to top-left."""
2081
+ import sys
2082
+ sys.stdout.write('\033[2J\033[H')
2083
+ sys.stdout.flush()
2084
+ return ''
2085
+
2086
+ def log(self, msg, level: str = 'INFO') -> str:
2087
+ """Log message with timestamp and level."""
2088
+ from datetime import datetime
2089
+ timestamp = datetime.now().strftime('%H:%M:%S')
2090
+ colors = {
2091
+ 'INFO': '\033[36m', # Cyan
2092
+ 'DEBUG': '\033[90m', # Gray
2093
+ 'WARNING': '\033[33m', # Yellow
2094
+ 'ERROR': '\033[31m', # Red
2095
+ 'SUCCESS': '\033[32m', # Green
2096
+ }
2097
+ color = colors.get(level.upper(), '\033[0m')
2098
+ return f'\033[90m[{timestamp}]\033[0m {color}[{level.upper()}]\033[0m {self._to_str(msg)}'
2099
+
2100
+ def info(self, msg) -> str:
2101
+ """Log info message."""
2102
+ return self.log(msg, 'INFO')
2103
+
2104
+ def error(self, msg) -> str:
2105
+ """Log error message in red."""
2106
+ return self.log(msg, 'ERROR')
2107
+
2108
+ def warning(self, msg) -> str:
2109
+ """Log warning message in yellow."""
2110
+ return self.log(msg, 'WARNING')
2111
+
2112
+ def success(self, msg) -> str:
2113
+ """Log success message in green."""
2114
+ return self.log(msg, 'SUCCESS')
2115
+
2116
+ def debug(self, msg) -> str:
2117
+ """Log debug message in gray."""
2118
+ return self.log(msg, 'DEBUG')
2119
+
2120
+ def hidden_input(self, prompt: str = '') -> str:
2121
+ """Get hidden input (for passwords). Returns the input string."""
2122
+ import getpass
2123
+ import sys
2124
+ # Print prompt with formatting
2125
+ if prompt:
2126
+ sys.stdout.write(self._to_str(prompt))
2127
+ sys.stdout.flush()
2128
+ try:
2129
+ return getpass.getpass(prompt='')
2130
+ except Exception:
2131
+ return input()
2132
+
2133
+ def cursor_up(self, n: int = 1) -> str:
2134
+ """Move cursor up n lines."""
2135
+ import sys
2136
+ sys.stdout.write(f'\033[{n}A')
2137
+ sys.stdout.flush()
2138
+ return ''
2139
+
2140
+ def cursor_down(self, n: int = 1) -> str:
2141
+ """Move cursor down n lines."""
2142
+ import sys
2143
+ sys.stdout.write(f'\033[{n}B')
2144
+ sys.stdout.flush()
2145
+ return ''
2146
+
2147
+ def cursor_hide(self) -> str:
2148
+ """Hide cursor."""
2149
+ import sys
2150
+ sys.stdout.write('\033[?25l')
2151
+ sys.stdout.flush()
2152
+ return ''
2153
+
2154
+ def cursor_show(self) -> str:
2155
+ """Show cursor."""
2156
+ import sys
2157
+ sys.stdout.write('\033[?25h')
2158
+ sys.stdout.flush()
2159
+ return ''
2160
+
2161
+ def cursor_save(self) -> str:
2162
+ """Save cursor position."""
2163
+ import sys
2164
+ sys.stdout.write('\033[s')
2165
+ sys.stdout.flush()
2166
+ return ''
2167
+
2168
+ def cursor_restore(self) -> str:
2169
+ """Restore cursor position."""
2170
+ import sys
2171
+ sys.stdout.write('\033[u')
2172
+ sys.stdout.flush()
2173
+ return ''
2174
+
2175
+ def erase_line(self) -> str:
2176
+ """Erase current line."""
2177
+ import sys
2178
+ sys.stdout.write('\033[2K\r')
2179
+ sys.stdout.flush()
2180
+ return ''
2181
+
2182
+ def move_to(self, row: int, col: int) -> str:
2183
+ """Move cursor to specific position (1-indexed)."""
2184
+ import sys
2185
+ sys.stdout.write(f'\033[{row};{col}H')
2186
+ sys.stdout.flush()
2187
+ return ''
2188
+
2189
+ def progress(self, current: int, total: int, width: int = 40, prefix: str = '', suffix: str = '') -> str:
2190
+ """Create a progress bar string."""
2191
+ percent = current / total if total > 0 else 0
2192
+ filled = int(width * percent)
2193
+ bar = '█' * filled + '░' * (width - filled)
2194
+ percent_str = f'{percent * 100:.1f}%'
2195
+ return f'{prefix}|{bar}| {percent_str} {suffix}'
2196
+
2197
+
1711
2198
  # =============================================================================
1712
2199
  # @Process Module - Process and subprocess management
1713
2200
  # =============================================================================
@@ -1872,7 +2359,9 @@ class ProcessModule(CSSLModuleBase):
1872
2359
 
1873
2360
  def shell_command(self, cmd: str) -> int:
1874
2361
  """Run command in system shell, returns exit code."""
1875
- return os.system(cmd)
2362
+ import subprocess
2363
+ result = subprocess.run(cmd, shell=True)
2364
+ return result.returncode
1876
2365
 
1877
2366
  def popen_process(self, cmd: Union[str, List[str]], cwd: str = None) -> int:
1878
2367
  """Open process for streaming, returns handle ID."""
@@ -2732,6 +3221,113 @@ class AppServiceBuilder:
2732
3221
  return None
2733
3222
 
2734
3223
 
3224
+ # =============================================================================
3225
+ # @Async Module - Async/await operations (v4.9.3)
3226
+ # =============================================================================
3227
+
3228
+ class AsyncCSSLModule(CSSLModuleBase):
3229
+ """
3230
+ @Async - Async/await operations for concurrent execution
3231
+
3232
+ v4.9.3: Full async support for CSSL.
3233
+
3234
+ Methods:
3235
+ run(func, *args) - Run function asynchronously, returns Future
3236
+ stop(future) - Cancel an async operation
3237
+ wait(future, timeout) - Wait for a Future to complete
3238
+ all(futures, timeout) - Wait for all Futures to complete
3239
+ race(futures, timeout) - Return first completed Future's result
3240
+ sleep(ms) - Async sleep for milliseconds
3241
+ create_generator(name) - Create a generator
3242
+
3243
+ Example:
3244
+ async define fetchData(url) {
3245
+ return http.get(url);
3246
+ }
3247
+
3248
+ future f = Async.run(fetchData, "http://example.com");
3249
+ data = await f;
3250
+
3251
+ // Or with async function call:
3252
+ future f = fetchData("http://example.com");
3253
+ data = await f;
3254
+
3255
+ // Wait for multiple:
3256
+ results = Async.all([f1, f2, f3]);
3257
+
3258
+ // First to complete:
3259
+ result = Async.race([f1, f2, f3]);
3260
+ """
3261
+
3262
+ def _register_methods(self):
3263
+ self._methods['run'] = self.run
3264
+ self._methods['stop'] = self.stop
3265
+ self._methods['wait'] = self.wait
3266
+ self._methods['all'] = self.all_futures
3267
+ self._methods['race'] = self.race
3268
+ self._methods['sleep'] = self.sleep
3269
+ self._methods['create_generator'] = self.create_generator
3270
+
3271
+ def run(self, func, *args, **kwargs):
3272
+ """Run a function asynchronously."""
3273
+ from .cssl_types import AsyncModule, CSSLFuture
3274
+ from .cssl_parser import ASTNode
3275
+
3276
+ # If func is a CSSL ASTNode function, wrap it for async execution
3277
+ if isinstance(func, ASTNode) and func.type == 'function':
3278
+ func_name = func.value.get('name', 'anonymous') if isinstance(func.value, dict) else 'anonymous'
3279
+ future = CSSLFuture(func_name)
3280
+ future._state = CSSLFuture.RUNNING
3281
+
3282
+ import threading
3283
+ def execute():
3284
+ try:
3285
+ if self.runtime:
3286
+ result = self.runtime._call_function(func, list(args), kwargs)
3287
+ else:
3288
+ result = None
3289
+ future.set_result(result)
3290
+ except Exception as e:
3291
+ future.set_exception(e)
3292
+
3293
+ thread = threading.Thread(target=execute, daemon=True)
3294
+ future._thread = thread
3295
+ thread.start()
3296
+ return future
3297
+
3298
+ return AsyncModule.run(func, *args, runtime=self.runtime, **kwargs)
3299
+
3300
+ def stop(self, future_or_name):
3301
+ """Stop an async operation."""
3302
+ from .cssl_types import AsyncModule
3303
+ return AsyncModule.stop(future_or_name)
3304
+
3305
+ def wait(self, future, timeout=None):
3306
+ """Wait for a future to complete."""
3307
+ from .cssl_types import AsyncModule
3308
+ return AsyncModule.wait(future, timeout)
3309
+
3310
+ def all_futures(self, futures, timeout=None):
3311
+ """Wait for all futures to complete."""
3312
+ from .cssl_types import AsyncModule
3313
+ return AsyncModule.all(futures, timeout)
3314
+
3315
+ def race(self, futures, timeout=None):
3316
+ """Return result of first completed future."""
3317
+ from .cssl_types import AsyncModule
3318
+ return AsyncModule.race(futures, timeout)
3319
+
3320
+ def sleep(self, ms):
3321
+ """Async sleep for ms milliseconds."""
3322
+ from .cssl_types import AsyncModule
3323
+ return AsyncModule.sleep(ms)
3324
+
3325
+ def create_generator(self, name, values=None):
3326
+ """Create a generator."""
3327
+ from .cssl_types import AsyncModule
3328
+ return AsyncModule.create_generator(name, values)
3329
+
3330
+
2735
3331
  # =============================================================================
2736
3332
  # Module Registry
2737
3333
  # =============================================================================
@@ -2765,9 +3361,12 @@ class CSSLModuleRegistry:
2765
3361
  'Queue': QueueModule(),
2766
3362
  'Format': FormatModule(),
2767
3363
  'Console': ConsoleModule(),
3364
+ 'fmt': FmtModule(),
2768
3365
  'Process': ProcessModule(),
2769
3366
  'Config': ConfigModule(),
2770
3367
  'Server': ServerModule(),
3368
+ 'Async': AsyncCSSLModule(), # v4.9.3: Async module
3369
+ 'async': AsyncCSSLModule(), # v4.9.3: Async module (lowercase alias)
2771
3370
  }
2772
3371
 
2773
3372
  # Register Desktop module (lazy loaded)