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
@@ -0,0 +1,64 @@
1
+ # Arc Standard Library
2
+
3
+ The Arc standard library provides essential modules for common programming tasks, designed with Arc's token-efficiency philosophy.
4
+
5
+ ## Modules
6
+
7
+ | Module | Status | File | Description |
8
+ |--------|--------|------|-------------|
9
+ | **math** | ✅ Implemented | [`math.arc`](math.arc) | Constants (PI, E) and functions (abs, pow, sqrt, ceil, floor, clamp) |
10
+ | **strings** | ✅ Implemented | [`strings.arc`](strings.arc) | String utilities (pad_left, pad_right, capitalize, words) |
11
+ | **collections** | ✅ Implemented | [`collections.arc`](collections.arc) | List utilities (set, unique, group_by, chunk, flatten, zip_with, partition, sort_by) |
12
+ | **map** | ✅ Implemented | [`map.arc`](map.arc) | Map utilities (merge, map_values, filter_map, from_pairs, pick, omit) |
13
+ | **io** | ✅ Implemented | [`io.arc`](io.arc) | File I/O (read_lines, write_lines, exists, append) |
14
+ | **http** | ✅ Implemented | [`http.arc`](http.arc) | HTTP client (get, post, put, delete, fetch_all, parse_url) |
15
+ | **json** | ✅ Implemented | [`json.arc`](json.arc) | JSON parser/serializer (to_json, from_json, pretty, get_path) |
16
+ | **csv** | ✅ Implemented | [`csv.arc`](csv.arc) | CSV parser/serializer (parse_csv, to_csv, parse_csv_headers) |
17
+ | **test** | ✅ Implemented | [`test.arc`](test.arc) | Testing framework (describe, it, expect_eq, expect_true, run_tests) |
18
+ | **result** | ✅ Implemented | [`result.arc`](result.arc) | Result type (ok, err, is_ok, unwrap, map_result, try_fn) |
19
+ | **time** | ✅ Implemented | [`time.arc`](time.arc) | Time utilities (now, format_duration, sleep) |
20
+
21
+ ## Quick Examples
22
+
23
+ ### math
24
+
25
+ ```arc
26
+ use math
27
+
28
+ math.sqrt(144) # => 12
29
+ math.clamp(15, 0, 10) # => 10
30
+ math.PI # => 3.141592653589793
31
+ ```
32
+
33
+ ### strings
34
+
35
+ ```arc
36
+ use strings
37
+
38
+ strings.pad_left("7", 3, "0") # => "007"
39
+ strings.capitalize("hello") # => "Hello"
40
+ strings.words("one two three") # => ["one", "two", "three"]
41
+ ```
42
+
43
+ ## Built-in Functions (No Import)
44
+
45
+ Many common operations are built into Arc and need no `use` statement:
46
+
47
+ `print`, `len`, `str`, `int`, `float`, `type`, `split`, `join`, `trim`, `upper`, `lower`, `slice`, `map`, `filter`, `reduce`, `find`, `contains`, `push`, `concat`, `take`, `skip`, `sort`, `reverse`, `keys`, `values`
48
+
49
+ ## Documentation
50
+
51
+ - **[Standard Library Reference](../docs/stdlib-reference.md)** — Full API reference
52
+ - **[Standard Library Tutorial](../docs/stdlib-tutorial.md)** — Hands-on usage guide
53
+
54
+ ## Design Principles
55
+
56
+ 1. **Minimal but complete** — Cover common use cases without bloat
57
+ 2. **Token-efficient** — Short names, clear APIs
58
+ 3. **Pipeline-friendly** — Functions work naturally with `|>`
59
+ 4. **Well-documented** — Every function has examples
60
+ 5. **Consistent** — Similar operations have similar signatures
61
+
62
+ ## Contributing
63
+
64
+ Help implement the planned modules! See [CONTRIBUTING.md](../CONTRIBUTING.md).
@@ -0,0 +1,140 @@
1
+ # Arc Standard Library: collections module
2
+ # Advanced collection utilities
3
+
4
+ pub fn set(list) {
5
+ let mut result = []
6
+ for item in list {
7
+ if not contains(result, item) {
8
+ result = push(result, item)
9
+ }
10
+ }
11
+ result
12
+ }
13
+
14
+ pub fn unique(list) => set(list)
15
+
16
+ pub fn group_by(list, f) {
17
+ let mut result = {}
18
+ for item in list {
19
+ let key = str(f(item))
20
+ let existing = if contains(keys(result), key) { result[key] } el { [] }
21
+ result[key] = push(existing, item)
22
+ }
23
+ result
24
+ }
25
+
26
+ pub fn count_by(list, f) {
27
+ let mut result = {}
28
+ for item in list {
29
+ let key = str(f(item))
30
+ let existing = if contains(keys(result), key) { result[key] } el { 0 }
31
+ result[key] = existing + 1
32
+ }
33
+ result
34
+ }
35
+
36
+ pub fn chunk(list, size) {
37
+ if size <= 0 { [] }
38
+ el if len(list) == 0 { [] }
39
+ el {
40
+ let mut result = []
41
+ let mut i = 0
42
+ do {
43
+ let end = if i + size > len(list) { len(list) } el { i + size }
44
+ result = push(result, slice(list, i, end))
45
+ i = i + size
46
+ } until i >= len(list)
47
+ result
48
+ }
49
+ }
50
+
51
+ pub fn flatten(list) => flat(list)
52
+
53
+ pub fn zip_with(a, b, f) {
54
+ let mut result = []
55
+ let pairs = zip(a, b)
56
+ for p in pairs {
57
+ result = push(result, f(p[0], p[1]))
58
+ }
59
+ result
60
+ }
61
+
62
+ pub fn partition(list, f) {
63
+ let passing = filter(list, f)
64
+ let not_f = x => not f(x)
65
+ let failing = filter(list, not_f)
66
+ let result = [passing, failing]
67
+ result
68
+ }
69
+
70
+ pub fn frequencies(list) {
71
+ let mut result = {}
72
+ for item in list {
73
+ let key = str(item)
74
+ let existing = if contains(keys(result), key) { result[key] } el { 0 }
75
+ result[key] = existing + 1
76
+ }
77
+ result
78
+ }
79
+
80
+ pub fn min_by(list, f) {
81
+ if len(list) == 0 { nil }
82
+ el {
83
+ let mut best = list[0]
84
+ let mut best_val = f(best)
85
+ for i in 1..len(list) {
86
+ let val = f(list[i])
87
+ if val < best_val {
88
+ best = list[i]
89
+ best_val = val
90
+ }
91
+ }
92
+ best
93
+ }
94
+ }
95
+
96
+ pub fn max_by(list, f) {
97
+ if len(list) == 0 { nil }
98
+ el {
99
+ let mut best = list[0]
100
+ let mut best_val = f(best)
101
+ for i in 1..len(list) {
102
+ let val = f(list[i])
103
+ if val > best_val {
104
+ best = list[i]
105
+ best_val = val
106
+ }
107
+ }
108
+ best
109
+ }
110
+ }
111
+
112
+ pub fn sort_by(list, f) {
113
+ # Insertion sort by key function
114
+ let mut arr = map(list, x => x)
115
+ for i in 1..len(arr) {
116
+ let mut j = i
117
+ do {
118
+ if j <= 0 { j = 0 }
119
+ el if f(arr[j]) < f(arr[j - 1]) {
120
+ let tmp = arr[j]
121
+ arr[j] = arr[j - 1]
122
+ arr[j - 1] = tmp
123
+ j = j - 1
124
+ } el { j = 0 }
125
+ } until j <= 0
126
+ }
127
+ arr
128
+ }
129
+
130
+ pub fn index_of(list, val) {
131
+ let mut result = nil
132
+ for i in 0..len(list) {
133
+ if list[i] == val and result == nil {
134
+ result = i
135
+ }
136
+ }
137
+ result
138
+ }
139
+
140
+ pub fn includes(list, val) => contains(list, val)
@@ -0,0 +1,62 @@
1
+ # Arc Standard Library: crypto module
2
+ # Hashing, encryption, and cryptographic utilities
3
+
4
+ # --- Hashing ---
5
+
6
+ pub fn md5(text) => crypto_hash("md5", text)
7
+ pub fn sha1(text) => crypto_hash("sha1", text)
8
+ pub fn sha256(text) => crypto_hash("sha256", text)
9
+ pub fn sha512(text) => crypto_hash("sha512", text)
10
+
11
+ # --- HMAC ---
12
+
13
+ pub fn hmac_sha256(key, message) => crypto_hmac("sha256", key, message)
14
+ pub fn hmac_sha512(key, message) => crypto_hmac("sha512", key, message)
15
+
16
+ # --- Random ---
17
+
18
+ pub fn random_bytes(n) {
19
+ if n < 0 { panic("random_bytes: n must be non-negative") }
20
+ el { crypto_random_bytes(n) }
21
+ }
22
+
23
+ pub fn random_int(min, max) {
24
+ if min > max { panic("random_int: min must be <= max") }
25
+ el { crypto_random_int(min, max) }
26
+ }
27
+
28
+ pub fn uuid() => crypto_uuid()
29
+
30
+ # --- Base64 ---
31
+
32
+ pub fn base64_encode(text) => crypto_encode_base64(text)
33
+ pub fn base64_decode(text) => crypto_decode_base64(text)
34
+
35
+ # --- Password Hashing ---
36
+
37
+ pub fn hash_password(password, salt) {
38
+ let input = salt ++ ":" ++ password
39
+ let mut hash = sha256(input)
40
+ for i in 0..100 {
41
+ hash = sha256(hash ++ salt)
42
+ }
43
+ hash
44
+ }
45
+
46
+ pub fn verify_password(password, salt, hash) {
47
+ let computed = hash_password(password, salt)
48
+ computed == hash
49
+ }
50
+
51
+ # --- Utility ---
52
+
53
+ pub fn constant_time_eq(a, b) {
54
+ if len(a) != len(b) { false }
55
+ el {
56
+ let mut result = true
57
+ for i in 0..len(a) {
58
+ if char_at(a, i) != char_at(b, i) { result = false }
59
+ }
60
+ result
61
+ }
62
+ }
package/stdlib/csv.arc ADDED
@@ -0,0 +1,40 @@
1
+ # Arc Standard Library: csv module
2
+ # CSV utilities (pure string manipulation)
3
+
4
+ pub fn parse_csv(text) => __native("csv.parse", text)
5
+
6
+ pub fn to_csv(rows) {
7
+ join(map(rows, row => join(map(row, cell => _escape_csv(str(cell))), ",")), "\n")
8
+ }
9
+
10
+ pub fn parse_csv_headers(text) {
11
+ let rows = __native("csv.parse", text)
12
+ if len(rows) < 2 { [] }
13
+ el {
14
+ let headers = head(rows)
15
+ let data_rows = tail(rows)
16
+ map(data_rows, cells => {
17
+ let mut row = {}
18
+ for i in 0..len(headers) {
19
+ let key = trim(headers[i])
20
+ let val = if i < len(cells) { cells[i] } el { "" }
21
+ row[key] = val
22
+ }
23
+ row
24
+ })
25
+ }
26
+ }
27
+
28
+ fn _parse_csv_line(line) {
29
+ # Simple CSV: split by comma, trim each cell
30
+ let cells = split(line, ",")
31
+ map(cells, cell => trim(cell))
32
+ }
33
+
34
+ fn _escape_csv(s) {
35
+ if contains(s, ",") or contains(s, "\"") or contains(s, "\n") {
36
+ "\"" ++ replace(s, "\"", "\"\"") ++ "\""
37
+ } el {
38
+ s
39
+ }
40
+ }
@@ -0,0 +1,75 @@
1
+ # Arc Standard Library: datetime module
2
+ # Comprehensive date and time utilities
3
+
4
+ # Constants
5
+ let MS_PER_MINUTE = 60000
6
+ let MS_PER_HOUR = 3600000
7
+ let MS_PER_DAY = 86400000
8
+
9
+ # Returns the current timestamp in milliseconds since Unix epoch
10
+ pub fn now() => __builtin_now()
11
+
12
+ # Returns today's date as a map {year, month, day}
13
+ pub fn today() {
14
+ let ts = now()
15
+ let days = int(ts / MS_PER_DAY)
16
+ __builtin_date_from_ts(ts)
17
+ }
18
+
19
+ # Parse a date string with the given format to a timestamp
20
+ # Format tokens: YYYY, MM, DD, hh, mm, ss
21
+ pub fn parse(date_string, format) => __builtin_date_parse(date_string, format)
22
+
23
+ # Format a timestamp to a string using the given format
24
+ # Format tokens: YYYY, MM, DD, hh, mm, ss
25
+ pub fn format(timestamp, format_string) => __builtin_date_format(timestamp, format_string)
26
+
27
+ # Add days to a timestamp, returns new timestamp
28
+ pub fn add_days(timestamp, days) => timestamp + days * MS_PER_DAY
29
+
30
+ # Add hours to a timestamp, returns new timestamp
31
+ pub fn add_hours(timestamp, hours) => timestamp + hours * MS_PER_HOUR
32
+
33
+ # Add minutes to a timestamp, returns new timestamp
34
+ pub fn add_minutes(timestamp, minutes) => timestamp + minutes * MS_PER_MINUTE
35
+
36
+ # Difference in days between two timestamps (absolute value)
37
+ pub fn diff_days(ts1, ts2) {
38
+ let diff = ts1 - ts2
39
+ let abs_diff = if diff < 0 { 0 - diff } el { diff }
40
+ int(abs_diff / MS_PER_DAY)
41
+ }
42
+
43
+ # Difference in hours between two timestamps (absolute value)
44
+ pub fn diff_hours(ts1, ts2) {
45
+ let diff = ts1 - ts2
46
+ let abs_diff = if diff < 0 { 0 - diff } el { diff }
47
+ int(abs_diff / MS_PER_HOUR)
48
+ }
49
+
50
+ # Difference in minutes between two timestamps (absolute value)
51
+ pub fn diff_minutes(ts1, ts2) {
52
+ let diff = ts1 - ts2
53
+ let abs_diff = if diff < 0 { 0 - diff } el { diff }
54
+ int(abs_diff / MS_PER_MINUTE)
55
+ }
56
+
57
+ # Returns the day of the week (0 = Sunday, 6 = Saturday)
58
+ pub fn day_of_week(timestamp) {
59
+ # Jan 1 1970 was a Thursday (4)
60
+ let days = int(timestamp / MS_PER_DAY)
61
+ let result = ((days + 4) % 7 + 7) % 7
62
+ result
63
+ }
64
+
65
+ # Returns true if ts1 is before ts2
66
+ pub fn is_before(ts1, ts2) => ts1 < ts2
67
+
68
+ # Returns true if ts1 is after ts2
69
+ pub fn is_after(ts1, ts2) => ts1 > ts2
70
+
71
+ # Convert a timestamp to an ISO 8601 string
72
+ pub fn to_iso(timestamp) => __builtin_date_to_iso(timestamp)
73
+
74
+ # Parse an ISO 8601 string to a timestamp
75
+ pub fn from_iso(iso_string) => __builtin_date_from_iso(iso_string)
@@ -0,0 +1,42 @@
1
+ # Arc Standard Library: embed module
2
+ # Vector embeddings, similarity search, and text chunking
3
+
4
+ # --- Vector Math (native implementations for performance) ---
5
+
6
+ pub fn dot_product(vec_a, vec_b) => embed_dot_product(vec_a, vec_b)
7
+
8
+ pub fn magnitude(vec) => embed_magnitude(vec)
9
+
10
+ pub fn cosine_similarity(vec_a, vec_b) => embed_cosine_similarity(vec_a, vec_b)
11
+
12
+ pub fn normalize(vec) => embed_normalize(vec)
13
+
14
+ pub fn euclidean_distance(vec_a, vec_b) => embed_euclidean_distance(vec_a, vec_b)
15
+
16
+ pub fn centroid(vectors) => embed_centroid(vectors)
17
+
18
+ # --- Similarity Search ---
19
+
20
+ # Find top_k most similar vectors from candidates list
21
+ # candidates: list of {id, vector} maps
22
+ # Returns: list of {id, score} maps sorted by similarity (descending)
23
+ pub fn most_similar(query_vec, candidates, top_k) => embed_most_similar(query_vec, candidates, top_k)
24
+
25
+ # --- Text Chunking ---
26
+
27
+ # Split text into chunks of approximately chunk_size characters
28
+ # Returns list of {chunk, index} maps
29
+ pub fn chunk_and_embed(text, chunk_size) {
30
+ let mut chunks = []
31
+ let mut i = 0
32
+ let text_len = len(text)
33
+ let mut idx = 0
34
+ do {
35
+ let end = if i + chunk_size > text_len { text_len } el { i + chunk_size }
36
+ let chunk = slice(text, i, end)
37
+ chunks = push(chunks, {chunk: chunk, index: idx})
38
+ i = i + chunk_size
39
+ idx = idx + 1
40
+ } until i >= text_len
41
+ chunks
42
+ }
package/stdlib/env.arc ADDED
@@ -0,0 +1,10 @@
1
+ # Arc Standard Library: env module
2
+ # Environment variable utilities
3
+
4
+ pub fn get(key) => __native("env.get", key)
5
+ pub fn get_or(key, default) => __native("env.get_or", key, default)
6
+ pub fn set(key, val) => __native("env.set", key, val)
7
+ pub fn remove(key) => __native("env.remove", key)
8
+ pub fn has(key) => __native("env.has", key)
9
+ pub fn list() => __native("env.list")
10
+ pub fn require(key) => __native("env.require", key)
@@ -0,0 +1,36 @@
1
+ # Arc Standard Library: error module
2
+ # Structured error handling
3
+
4
+ # Create a structured error
5
+ pub fn error(code, message) => error_new(code, message)
6
+
7
+ # Check if a value is an error
8
+ pub fn is_error(value) => error_is_error(value)
9
+
10
+ # Wrap an error with additional context
11
+ pub fn wrap_error(err, context) => error_wrap(err, context)
12
+
13
+ # Try executing a function, return Ok/Err result
14
+ pub fn try_fn(f) => error_try(f)
15
+
16
+ # Execute fn, call handler if result is an error
17
+ pub fn try_catch(f, handler) {
18
+ let result = f()
19
+ if is_error(result) { handler(result) }
20
+ el { result }
21
+ }
22
+
23
+ # Execute fn, always run cleanup
24
+ pub fn try_finally(f, cleanup) {
25
+ let result = f()
26
+ cleanup()
27
+ result
28
+ }
29
+
30
+ # Full try/catch/finally
31
+ pub fn try_catch_finally(f, handler, cleanup) {
32
+ let result = f()
33
+ let handled = if is_error(result) { handler(result) } el { result }
34
+ cleanup()
35
+ handled
36
+ }
@@ -0,0 +1,30 @@
1
+ # Arc Standard Library: html module
2
+ # HTML parsing and generation utilities
3
+
4
+ pub fn parse(s) {
5
+ __native("html.parse", s)
6
+ }
7
+
8
+ pub fn select(node, selector) {
9
+ __native("html.select", node, selector)
10
+ }
11
+
12
+ pub fn text(node) {
13
+ __native("html.text", node)
14
+ }
15
+
16
+ pub fn attr(node, name) {
17
+ __native("html.attr", node, name)
18
+ }
19
+
20
+ pub fn create(tag, attrs, children) {
21
+ let node = {}
22
+ node["tag"] = tag
23
+ node["attrs"] = attrs
24
+ node["children"] = children
25
+ node
26
+ }
27
+
28
+ pub fn render(node) {
29
+ __native("html.render", node)
30
+ }
@@ -0,0 +1,43 @@
1
+ # Arc Standard Library: http module
2
+ # HTTP utilities built on @ tool calls
3
+
4
+ pub fn get(url) => @GET url
5
+
6
+ pub fn post(url, body) {
7
+ @POST url {data: body}
8
+ }
9
+
10
+ pub fn put(url, body) {
11
+ @PUT url {data: body}
12
+ }
13
+
14
+ pub fn delete(url) => @DELETE url
15
+
16
+ pub fn fetch_all(urls) {
17
+ map(urls, u => @GET u)
18
+ }
19
+
20
+ pub fn parse_url(url) {
21
+ # Extract protocol, host, path from URL string
22
+ let mut protocol = ""
23
+ let mut rest = url
24
+
25
+ if starts(url, "https://") {
26
+ protocol = "https"
27
+ rest = slice(url, 8, len(url))
28
+ } el if starts(url, "http://") {
29
+ protocol = "http"
30
+ rest = slice(url, 7, len(url))
31
+ } el {
32
+ protocol = ""
33
+ rest = url
34
+ }
35
+
36
+ # Find first / after protocol
37
+ let parts = split(rest, "/")
38
+ let host = head(parts)
39
+ let path_parts = tail(parts)
40
+ let path = if len(path_parts) > 0 { "/" ++ join(path_parts, "/") } el { "/" }
41
+
42
+ {protocol: protocol, host: host, path: path}
43
+ }
package/stdlib/io.arc ADDED
@@ -0,0 +1,28 @@
1
+ # Arc Standard Library: io module
2
+ # File I/O utilities (operates on strings/lists; actual I/O via prelude read/write)
3
+
4
+ pub fn read_lines(path) {
5
+ let content = read(path)
6
+ if content == nil { [] }
7
+ el { split(content, "\n") }
8
+ }
9
+
10
+ pub fn write_lines(path, lines) {
11
+ let content = join(lines, "\n")
12
+ write(path, content)
13
+ }
14
+
15
+ pub fn exists(path) {
16
+ # Simulated: try reading, return true if non-nil
17
+ let content = read(path)
18
+ content != nil
19
+ }
20
+
21
+ pub fn append(path, data) {
22
+ let existing = read(path)
23
+ if existing == nil {
24
+ write(path, str(data))
25
+ } el {
26
+ write(path, existing ++ str(data))
27
+ }
28
+ }