runtime: add dharma-required functions to el_runtime.c and runtime/*.el

Add the following functions that dharma registry calls but were missing
from the El runtime:

el_runtime.c (consumed by the old build system via released SDK):
  - list_len, list_get — aliases for el_list_len/el_list_get (handlers.el)
  - json_array_push — append pre-encoded element to JSON array string
  - now_millis, unix_timestamp_ms, time_now_ms — ms-since-epoch aliases
  - log_info, log_warn — structured stderr log helpers
  - config — reads config from environment (alias for getenv)
  - http_patch — HTTP PATCH with Content-Type: application/json
  - http_post_engram — HTTP POST with optional X-API-Key header
  - http_get_engram — HTTP GET with optional X-API-Key header
  - str_to_bytes — encode string as JSON byte array [72,101,...]
  - bytes_to_str — decode JSON byte array back to string
  - hash_sha256 — SHA-256 hex digest using built-in sha256 impl

runtime/*.el (consumed by the new build system):
  - http.el: http_patch, http_post_engram, http_get_engram
  - time.el: now_millis, unix_timestamp_ms, time_now_ms
  - env.el: config, log_info, log_warn, list_len, list_get
  - json.el: json_array_push, bytes_to_str
  - string.el: str_to_bytes, hash_sha256 (via __sha256_hex seed)

el_seed.h / el_seed.c:
  - __sha256_hex primitive with self-contained SHA-256 implementation
This commit is contained in:
Will Anderson
2026-05-04 19:07:08 -05:00
parent 245eb2898e
commit 53f2df500d
8 changed files with 580 additions and 0 deletions
+40
View File
@@ -157,6 +157,24 @@ fn json_build_array(items: [String]) -> String {
return result + "]"
}
// json_array_push append a pre-encoded JSON element to a JSON array string.
// elem must be a valid JSON fragment (e.g. "\"foo\"" or "42").
// Returns a new JSON array string with elem appended.
// Example: json_array_push("[]", "\"alice\"") -> "[\"alice\"]"
fn json_array_push(arr: String, elem: String) -> String {
let n: Int = json_array_len(arr)
if n == 0 {
return "[" + elem + "]"
}
// arr ends with ']'; insert before it
let inner_end: Int = str_last_index_of(arr, "]")
if inner_end < 0 {
return "[" + elem + "]"
}
let prefix: String = str_slice(arr, 0, inner_end)
return prefix + "," + elem + "]"
}
// json_escape_string escape a raw string so it can be safely embedded as a
// JSON string value.
//
@@ -171,3 +189,25 @@ fn json_escape_string(s: String) -> String {
let s5: String = str_replace(s4, "\t", "\\t")
return s5
}
// ---------------------------------------------------------------------------
// DHARMA byte decoding
// ---------------------------------------------------------------------------
// bytes_to_str decode a JSON array of integer byte values back to a string.
// "[104,105]" -> "hi"
// Inverse of str_to_bytes (defined in string.el). Defined here because it
// depends on json_array_len and json_array_get_string which live in this file.
fn bytes_to_str(arr: String) -> String {
let n: Int = json_array_len(arr)
if n == 0 { return "" }
let out: String = __str_alloc(n)
let i: Int = 0
while i < n {
let elem: String = json_array_get_string(arr, i)
let b: Int = __str_to_int(elem)
out = __str_set_char(out, i, b)
i = i + 1
}
return out
}