arc-lang 0.6.2 → 0.6.4

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 (48) hide show
  1. package/README.md +65 -130
  2. package/dist/ast.d.ts +30 -2
  3. package/dist/build.js +1 -1
  4. package/dist/formatter.js +15 -3
  5. package/dist/index.js +104 -0
  6. package/dist/interpreter.js +130 -17
  7. package/dist/lexer.d.ts +41 -37
  8. package/dist/lexer.js +47 -39
  9. package/dist/linter.js +18 -0
  10. package/dist/modules.js +5 -1
  11. package/dist/parser.d.ts +2 -0
  12. package/dist/parser.js +91 -11
  13. package/dist/repl.js +66 -1
  14. package/dist/version.d.ts +1 -1
  15. package/dist/version.js +1 -1
  16. package/package.json +4 -2
  17. package/stdlib/API_DESIGN.md +357 -0
  18. package/stdlib/ASYNC_DESIGN.md +815 -0
  19. package/stdlib/EXAMPLES.md +710 -0
  20. package/stdlib/MODULES.md +854 -0
  21. package/stdlib/README.md +64 -0
  22. package/stdlib/collections.arc +140 -0
  23. package/stdlib/crypto.arc +62 -0
  24. package/stdlib/csv.arc +40 -0
  25. package/stdlib/datetime.arc +75 -0
  26. package/stdlib/embed.arc +42 -0
  27. package/stdlib/env.arc +10 -0
  28. package/stdlib/error.arc +36 -0
  29. package/stdlib/html.arc +30 -0
  30. package/stdlib/http.arc +43 -0
  31. package/stdlib/io.arc +28 -0
  32. package/stdlib/json.arc +204 -0
  33. package/stdlib/llm.arc +193 -0
  34. package/stdlib/log.arc +20 -0
  35. package/stdlib/map.arc +72 -0
  36. package/stdlib/math.arc +133 -0
  37. package/stdlib/net.arc +17 -0
  38. package/stdlib/os.arc +81 -0
  39. package/stdlib/path.arc +11 -0
  40. package/stdlib/prompt.arc +49 -0
  41. package/stdlib/regex.arc +59 -0
  42. package/stdlib/result.arc +50 -0
  43. package/stdlib/store.arc +62 -0
  44. package/stdlib/strings.arc +44 -0
  45. package/stdlib/test.arc +61 -0
  46. package/stdlib/time.arc +19 -0
  47. package/stdlib/toml.arc +10 -0
  48. package/stdlib/yaml.arc +10 -0
package/stdlib/os.arc ADDED
@@ -0,0 +1,81 @@
1
+ # Arc Standard Library: os module
2
+ # Filesystem and system operations
3
+
4
+ # Returns the current working directory
5
+ pub fn cwd() => __native("os.cwd")
6
+
7
+ # Get environment variable by name, returns nil if not set
8
+ pub fn get_env(name) => __native("os.env", name)
9
+
10
+ # Set environment variable
11
+ pub fn set_env(name, value) => __native("os.set_env", name, value)
12
+
13
+ # List files and directories in the given path, returns a list of strings
14
+ pub fn list_dir(path) => __native("os.list_dir", path)
15
+
16
+ # Check if path points to a file
17
+ pub fn is_file(path) => __native("os.is_file", path)
18
+
19
+ # Check if path points to a directory
20
+ pub fn is_dir(path) => __native("os.is_dir", path)
21
+
22
+ # Create a directory (and parent directories if needed)
23
+ pub fn mkdir(path) => __native("os.mkdir", path)
24
+
25
+ # Remove an empty directory
26
+ pub fn rmdir(path) => __native("os.rmdir", path)
27
+
28
+ # Remove a file
29
+ pub fn remove(path) => __native("os.remove", path)
30
+
31
+ # Rename or move a file/directory
32
+ pub fn rename(old_path, new_path) => __native("os.rename", old_path, new_path)
33
+
34
+ # Copy a file from src to dest
35
+ pub fn copy(src, dest) => __native("os.copy", src, dest)
36
+
37
+ # Get file size in bytes
38
+ pub fn file_size(path) => __native("os.file_size", path)
39
+
40
+ # Get file extension (e.g. ".txt"), returns "" if none
41
+ pub fn file_ext(path) {
42
+ let parts = split(path, ".")
43
+ if len(parts) <= 1 { "" }
44
+ el { "." ++ last(parts) }
45
+ }
46
+
47
+ # Join path segments with the platform separator
48
+ pub fn join_path(parts) {
49
+ let sep = if platform() == "windows" { "\\" } el { "/" }
50
+ join(parts, sep)
51
+ }
52
+
53
+ # Get the parent directory of a path
54
+ pub fn parent_dir(path) {
55
+ let sep = if platform() == "windows" { "\\" } el { "/" }
56
+ let parts = split(path, sep)
57
+ if len(parts) <= 1 { "." }
58
+ el {
59
+ let parent_parts = slice(parts, 0, len(parts) - 1)
60
+ join(parent_parts, sep)
61
+ }
62
+ }
63
+
64
+ # Get the filename (basename) from a path
65
+ pub fn basename(path) {
66
+ let sep = if platform() == "windows" { "\\" } el { "/" }
67
+ let parts = split(path, sep)
68
+ last(parts)
69
+ }
70
+
71
+ # Execute a shell command and return its output as a string
72
+ pub fn exec(command) => __native("os.exec", command)
73
+
74
+ # Returns the platform: "windows", "linux", or "macos"
75
+ pub fn platform() => __native("os.platform")
76
+
77
+ # Returns the user's home directory
78
+ pub fn home_dir() => __native("os.home_dir")
79
+
80
+ # Returns the system temp directory
81
+ pub fn temp_dir() => __native("os.temp_dir")
@@ -0,0 +1,11 @@
1
+ # Arc Standard Library: path module
2
+ # Path manipulation utilities
3
+
4
+ pub fn join(...parts) => __native("path.join_list", parts)
5
+ pub fn dirname(p) => __native("path.dirname", p)
6
+ pub fn basename(p) => __native("path.basename", p)
7
+ pub fn extname(p) => __native("path.extname", p)
8
+ pub fn resolve(p) => __native("path.resolve", p)
9
+ pub fn normalize(p) => __native("path.normalize", p)
10
+ pub fn is_absolute(p) => __native("path.is_absolute", p)
11
+ pub fn sep() => __native("path.sep")
@@ -0,0 +1,49 @@
1
+ # Arc Standard Library: prompt module
2
+ # Template management, token counting, and context windowing for AI agents
3
+
4
+ ## Template filling — replace <<var>> placeholders with values from a map
5
+ ## Example: template("Hello <<name>>", {name: "World"}) => "Hello World"
6
+ pub fn template(tmpl, vars) {
7
+ __native("prompt.template", tmpl, vars)
8
+ }
9
+
10
+ ## Estimate token count (~4 chars per token)
11
+ pub fn token_count(text) {
12
+ __native("prompt.token_count", text)
13
+ }
14
+
15
+ ## Truncate text to fit within a token limit
16
+ pub fn token_truncate(text, max_tokens) {
17
+ __native("prompt.token_truncate", text, max_tokens)
18
+ }
19
+
20
+ ## Fit as many messages as possible within a token budget (keeps newest)
21
+ ## Each message should be a map with at least a "content" key
22
+ pub fn context_window(messages, max_tokens) {
23
+ __native("prompt.context_window", messages, max_tokens)
24
+ }
25
+
26
+ ## Split text into chunks that fit within token limits
27
+ pub fn chunk(text, max_tokens) {
28
+ __native("prompt.chunk", text, max_tokens)
29
+ }
30
+
31
+ ## Format a system prompt
32
+ pub fn system_prompt(role, instructions) {
33
+ {role: "system", content: "You are " ++ role ++ ". " ++ instructions}
34
+ }
35
+
36
+ ## Format a user message
37
+ pub fn user_message(text) {
38
+ {role: "user", content: text}
39
+ }
40
+
41
+ ## Format an assistant message
42
+ pub fn assistant_message(text) {
43
+ {role: "assistant", content: text}
44
+ }
45
+
46
+ ## Format a list of messages into a chat string
47
+ pub fn format_chat(messages) {
48
+ messages |> map(m => "[" ++ m.role ++ "]: " ++ m.content) |> fold("", (acc, line) => if acc == "" { line } el { acc ++ "\n" ++ line })
49
+ }
@@ -0,0 +1,59 @@
1
+ # Arc Standard Library: regex module
2
+ # Provides regular expression matching, replacing, splitting, and validation.
3
+
4
+ # Returns the first match of `pattern` in `text`, or nil if no match
5
+ pub fn find(pattern, text) {
6
+ let re = regex_new(pattern)
7
+ regex_find(re, text)
8
+ }
9
+
10
+ # Returns a list of all matches of `pattern` in `text`
11
+ pub fn find_all(pattern, text) {
12
+ let re = regex_new(pattern)
13
+ regex_find_all(re, text)
14
+ }
15
+
16
+ # Returns true if `pattern` matches anywhere in `text`, false otherwise
17
+ pub fn test(pattern, text) {
18
+ let result = find(pattern, text)
19
+ result != nil
20
+ }
21
+
22
+ # Replaces the first occurrence of `pattern` with `replacement` in `text`
23
+ pub fn replace(pattern, replacement, text) {
24
+ let re = regex_new(pattern)
25
+ regex_replace(re, replacement, text)
26
+ }
27
+
28
+ # Replaces all occurrences of `pattern` with `replacement` in `text`
29
+ pub fn replace_all(pattern, replacement, text) {
30
+ let re = regex_new(pattern)
31
+ regex_replace_all(re, replacement, text)
32
+ }
33
+
34
+ # Splits `text` by occurrences of `pattern`
35
+ pub fn split(pattern, text) {
36
+ let re = regex_new(pattern)
37
+ regex_split(re, text)
38
+ }
39
+
40
+ # Returns a list of capture groups from the first match of `pattern` in `text`
41
+ pub fn capture(pattern, text) {
42
+ let re = regex_new(pattern)
43
+ regex_captures(re, text)
44
+ }
45
+
46
+ # Returns a list of all capture group sets from all matches of `pattern` in `text`
47
+ pub fn capture_all(pattern, text) {
48
+ let re = regex_new(pattern)
49
+ regex_captures_all(re, text)
50
+ }
51
+
52
+ # Escapes all regex special characters in `text`
53
+ pub fn escape(text) => __native("regex.escape", text)
54
+
55
+ # Returns true if `pattern` is a valid regex, false otherwise
56
+ pub fn is_valid(pattern) {
57
+ let result = regex_try_new(pattern)
58
+ result != nil
59
+ }
@@ -0,0 +1,50 @@
1
+ # Arc Standard Library: result module
2
+ # Result type pattern for error handling using native builtins
3
+
4
+ # Capture builtins before any shadowing
5
+ let _builtin_is_ok = is_ok
6
+ let _builtin_is_err = is_err
7
+ let _builtin_unwrap = unwrap
8
+ let _builtin_unwrap_or = unwrap_or
9
+ let _builtin_unwrap_err = unwrap_err
10
+ let _builtin_map_result = map_result
11
+
12
+ # Ok(value) - wraps a success value in a Result
13
+ pub fn ok(value) => Ok(value)
14
+
15
+ # err(error) - wraps an error in a Result
16
+ pub fn err(error) => Err(error)
17
+
18
+ # --- Clean aliases (no prefix stutter: result.is_ok instead of result.result_is_ok) ---
19
+
20
+ pub fn is_ok(result) => _builtin_is_ok(result)
21
+ pub fn is_err(result) => _builtin_is_err(result)
22
+ pub fn unwrap(result) => _builtin_unwrap(result)
23
+ pub fn unwrap_or(result, default) => _builtin_unwrap_or(result, default)
24
+ pub fn unwrap_err(result) => _builtin_unwrap_err(result)
25
+ pub fn map(result, f) => _builtin_map_result(result, f)
26
+ pub fn flat_map(result, f) {
27
+ if _builtin_is_ok(result) {
28
+ f(_builtin_unwrap(result))
29
+ } el {
30
+ result
31
+ }
32
+ }
33
+
34
+ # try_fn - wraps a function call in a Result (uses native error_try)
35
+ pub fn try_fn(f) => error_try(f)
36
+
37
+ # --- Legacy prefixed names (backward compat) ---
38
+
39
+ pub fn result_is_ok(result) => _builtin_is_ok(result)
40
+ pub fn result_is_err(result) => _builtin_is_err(result)
41
+ pub fn result_unwrap(result) => _builtin_unwrap(result)
42
+ pub fn result_unwrap_or(result, default) => _builtin_unwrap_or(result, default)
43
+ pub fn result_map(result, f) => _builtin_map_result(result, f)
44
+ pub fn flat_map_result(result, f) {
45
+ if _builtin_is_ok(result) {
46
+ f(_builtin_unwrap(result))
47
+ } el {
48
+ result
49
+ }
50
+ }
@@ -0,0 +1,62 @@
1
+ # Arc Standard Library: store module
2
+ # Persistent key-value storage backed by JSON files
3
+ #
4
+ # Usage:
5
+ # use store
6
+ # let s = store.open("my_data.json")
7
+ # store.set(s, "key", "value")
8
+ # let v = store.get(s, "key")
9
+
10
+ pub fn open(path) {
11
+ __native("store.open", path)
12
+ }
13
+
14
+ pub fn get(store, key) {
15
+ __native("store.get", store, key)
16
+ }
17
+
18
+ pub fn set(store, key, value) {
19
+ __native("store.set", store, key, value)
20
+ }
21
+
22
+ pub fn delete(store, key) {
23
+ __native("store.delete", store, key)
24
+ }
25
+
26
+ pub fn has(store, key) {
27
+ __native("store.has", store, key)
28
+ }
29
+
30
+ pub fn keys(store) {
31
+ __native("store.keys", store)
32
+ }
33
+
34
+ pub fn values(store) {
35
+ __native("store.values", store)
36
+ }
37
+
38
+ pub fn entries(store) {
39
+ __native("store.entries", store)
40
+ }
41
+
42
+ pub fn clear(store) {
43
+ __native("store.clear", store)
44
+ }
45
+
46
+ pub fn size(store) {
47
+ __native("store.size", store)
48
+ }
49
+
50
+ pub fn merge(store, map) {
51
+ __native("store.merge", store, map)
52
+ }
53
+
54
+ pub fn get_or_set(store, key, default_fn) {
55
+ let existing = get(store, key)
56
+ if existing != nil { existing }
57
+ el {
58
+ let val = default_fn()
59
+ set(store, key, val)
60
+ val
61
+ }
62
+ }
@@ -0,0 +1,44 @@
1
+ # Arc Standard Library: strings module
2
+
3
+ pub fn pad_left(s, width, ch) {
4
+ let mut result = str(s)
5
+ if len(str(ch)) == 0 { result }
6
+ el {
7
+ let pad_char = slice(str(ch), 0, 1)
8
+ if len(result) >= width { result }
9
+ el {
10
+ do {
11
+ result = pad_char ++ result
12
+ } until len(result) >= width
13
+ result
14
+ }
15
+ }
16
+ }
17
+
18
+ pub fn pad_right(s, width, ch) {
19
+ let mut result = str(s)
20
+ if len(str(ch)) == 0 { result }
21
+ el {
22
+ let pad_char = slice(str(ch), 0, 1)
23
+ if len(result) >= width { result }
24
+ el {
25
+ do {
26
+ result = result ++ pad_char
27
+ } until len(result) >= width
28
+ result
29
+ }
30
+ }
31
+ }
32
+
33
+ pub fn capitalize(s) {
34
+ if len(s) == 0 { "" }
35
+ el {
36
+ let first = upper(slice(s, 0, 1))
37
+ let rest = lower(slice(s, 1, len(s)))
38
+ first ++ rest
39
+ }
40
+ }
41
+
42
+ pub fn words(s) {
43
+ split(trim(s), " ") |> filter(w => len(w) > 0)
44
+ }
@@ -0,0 +1,61 @@
1
+ # Arc Standard Library: test module
2
+ # A lightweight testing framework
3
+
4
+ let mut _passed = 0
5
+ let mut _failed = 0
6
+ let mut _current_group = ""
7
+
8
+ pub fn describe(name, f) {
9
+ _current_group = name
10
+ print("--- " ++ name ++ " ---")
11
+ f()
12
+ print("")
13
+ }
14
+
15
+ pub fn it(name, f) {
16
+ let label = if _current_group != "" { _current_group ++ " > " ++ name } el { name }
17
+ f()
18
+ _passed = _passed + 1
19
+ print(" ✓ " ++ name)
20
+ }
21
+
22
+ pub fn expect_eq(a, b, msg) {
23
+ let m = msg or ("Expected " ++ str(a) ++ " to equal " ++ str(b))
24
+ assert(a == b, m)
25
+ }
26
+
27
+ pub fn expect_neq(a, b, msg) {
28
+ let m = msg or ("Expected " ++ str(a) ++ " to not equal " ++ str(b))
29
+ assert(a != b, m)
30
+ }
31
+
32
+ pub fn expect_true(val, msg) {
33
+ let m = msg or ("Expected truthy, got " ++ str(val))
34
+ assert(val, m)
35
+ }
36
+
37
+ pub fn expect_false(val, msg) {
38
+ let m = msg or ("Expected falsy, got " ++ str(val))
39
+ assert(not val, m)
40
+ }
41
+
42
+ pub fn expect_nil(val, msg) {
43
+ let m = msg or ("Expected nil, got " ++ str(val))
44
+ assert(val == nil, m)
45
+ }
46
+
47
+ pub fn expect_gt(a, b, msg) {
48
+ let m = msg or ("Expected " ++ str(a) ++ " > " ++ str(b))
49
+ assert(a > b, m)
50
+ }
51
+
52
+ pub fn expect_lt(a, b, msg) {
53
+ let m = msg or ("Expected " ++ str(a) ++ " < " ++ str(b))
54
+ assert(a < b, m)
55
+ }
56
+
57
+ pub fn run_tests() {
58
+ print("========================")
59
+ print("Tests: " ++ str(_passed) ++ " passed, " ++ str(_failed) ++ " failed")
60
+ print("========================")
61
+ }
@@ -0,0 +1,19 @@
1
+ # Arc Standard Library: time module
2
+ # Simulated time utilities
3
+
4
+ pub fn now() => __native("time.now")
5
+
6
+ pub fn format_duration(ms) {
7
+ let total_s = int(ms / 1000)
8
+ let h = int(total_s / 3600)
9
+ let m = int((total_s % 3600) / 60)
10
+ let s = total_s % 60
11
+ let parts = []
12
+ let mut result = ""
13
+ if h > 0 { result = str(h) ++ "h " }
14
+ if m > 0 { result = result ++ str(m) ++ "m " }
15
+ result = result ++ str(s) ++ "s"
16
+ result
17
+ }
18
+
19
+ pub fn sleep(ms) => __native("time.sleep", ms)
@@ -0,0 +1,10 @@
1
+ # Arc Standard Library: toml module
2
+ # TOML parsing and stringifying
3
+
4
+ pub fn parse(text) {
5
+ __native("toml.parse", text)
6
+ }
7
+
8
+ pub fn stringify(value) {
9
+ __native("toml.stringify", value)
10
+ }
@@ -0,0 +1,10 @@
1
+ # Arc Standard Library: yaml module
2
+ # YAML parsing and stringifying
3
+
4
+ pub fn parse(text) {
5
+ __native("yaml.parse", text)
6
+ }
7
+
8
+ pub fn stringify(value) {
9
+ __native("yaml.stringify", value)
10
+ }