From 9b473c667c76a5afd31008661cff58d9015bd17e Mon Sep 17 00:00:00 2001 From: dimgigov Date: Tue, 9 Jun 2026 21:23:05 +0300 Subject: [PATCH] closures with captures: env struct + global instance + body rewriting - AST: captureCount + captureName0..7 + captureType0..7 in Expr - Sema: Scope_LookupUpTo + closureScope for capture analysis - HIR Lower: env struct generation, capture assignments in skLet, body rewriting (ekIdent -> hFieldAccess on env instance) - C Backend: env struct def + global instance emission for closures - Bootstrap: full capture support in sema, hir_lower, lir_lower, lir_c_backend - Selfhost loop remains deterministic --- _test_closure/build/closure_test | Bin 221104 -> 220896 bytes _test_closure/build/main | Bin 62984 -> 0 bytes _test_closure/build/main.c | 4845 +++++++++++++++++++++++++++++- bootstrap/ast.nim | 3 + bootstrap/c_backend.nim | 16 + bootstrap/hir.nim | 12 + bootstrap/hir_lower.nim | 44 +- bootstrap/lir_c_backend.nim | 14 + bootstrap/lir_lower.nim | 14 + bootstrap/scope.nim | 10 + bootstrap/sema.nim | 23 + src/ast.bux | 18 + src/c_backend.bux | 45 + src/hir.bux | 25 +- src/hir_lower.bux | 171 +- src/scope.bux | 19 + src/sema.bux | 61 + 17 files changed, 5267 insertions(+), 53 deletions(-) delete mode 100755 _test_closure/build/main diff --git a/_test_closure/build/closure_test b/_test_closure/build/closure_test index 4637bfd0c0794e227b6f9a78698c6900195ef4e7..4b7c03c9f378cbd77f8bfead492e584b3c820709 100755 GIT binary patch delta 76296 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

1)|4$$6D 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 diff --git a/_test_closure/build/main b/_test_closure/build/main deleted file mode 100755 index 91e1ee8064f1a9a4c0f346f767b4425fdd7c1ef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62984 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 XG0Z;vVmhbB|M)L|hsD#1P>H=;4 +#include #include #include #include -#include -#include -typedef const char* String; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef unsigned long long uint64; -typedef signed char int8; -typedef short int16; -typedef long long int64; -typedef float float32; -typedef double float64; -typedef char char8; +typedef struct TaskHandle TaskHandle; +typedef struct Mutex Mutex; +typedef struct RwLock RwLock; +typedef struct JsonValue JsonValue; +typedef struct JsonParser JsonParser; +typedef struct StringBuilder StringBuilder; +typedef struct Channel_int Channel_int; +typedef struct Channel_float64 Channel_float64; -void* bux_alloc(unsigned int size); -void bux_free(void* ptr); +/* Extern function declarations */ +extern void* bux_alloc(unsigned int size); +extern void* bux_realloc(void* ptr, unsigned int size); +extern void bux_free(void* ptr); +extern void bux_bounds_check(unsigned int index, unsigned int len); +extern void* bux_channel_new(int64_t capacity, int64_t elem_size); +extern void bux_channel_send(void* handle, void* elem); +extern int bux_channel_recv(void* handle, void* out); +extern void bux_channel_close(void* handle); +extern void bux_channel_free(void* handle); +extern int bux_dir_exists(const char* path); +extern int bux_mkdir_if_needed(const char* path); +extern const char** bux_list_dir(const char* dir, const char* ext, int* out_count); +extern void PrintLine(const char* s); +extern void Print(const char* s); +extern void PrintInt(int n); +extern void PrintInt64(int64_t n); +extern void PrintFloat(double f); +extern void PrintBool(bool b); +extern const char* ReadLine(void); +extern const char* bux_read_file(const char* path); +extern int bux_write_file(const char* path, const char* content); +extern int bux_file_exists(const char* path); +extern unsigned int bux_hash_bytes(void* ptr, unsigned int size); +extern unsigned int bux_hash_string(const char* s); +extern double bux_sqrt(double x); +extern double bux_pow(double x, double y); +extern int64_t bux_abs_i64(int64_t x); +extern double bux_abs_f64(double x); +extern int64_t bux_min_i64(int64_t a, int64_t b); +extern int64_t bux_max_i64(int64_t a, int64_t b); +extern double bux_min_f64(double a, double b); +extern double bux_max_f64(double a, double b); +extern void* bux_alloc(unsigned int size); +extern void* bux_realloc(void* ptr, unsigned int size); +extern void bux_free(void* ptr); +extern int bux_mem_eq(void* a, void* b, unsigned int size); +extern const char* bux_path_join(const char* a, const char* b); +extern const char* bux_path_parent(const char* path); +extern const char* bux_path_ext(const char* path); +extern unsigned int bux_hash_bytes(void* ptr, unsigned int size); +extern int bux_mem_eq(void* a, void* b, unsigned int size); +extern void* bux_alloc(unsigned int size); +extern void bux_free(void* ptr); +extern void* bux_task_spawn(void* fn, void* arg); +extern void bux_task_join(void* handle); +extern void bux_task_sleep(int64_t ms); +extern int bux_argc(void); +extern const char* bux_argv(int index); +extern const char* bux_getenv(const char* name); +extern int bux_setenv(const char* name, const char* value); +extern const char* bux_getcwd(void); +extern int bux_chdir(const char* path); +extern int64_t bux_time_ms(void); +extern int64_t bux_time_us(void); +extern void bux_sleep_ms(int64_t ms); +extern int bux_process_run(const char* cmd); +extern const char* bux_process_output(const char* cmd); +extern int bux_socket_create(void); +extern int bux_socket_reuse(int fd); +extern int bux_socket_bind(int fd, const char* addr, int port); +extern int bux_socket_listen(int fd, int backlog); +extern int bux_socket_accept(int fd); +extern int bux_socket_connect(int fd, const char* addr, int port); +extern int bux_socket_send(int fd, const char* data, int len); +extern const char* bux_socket_recv(int fd, int maxLen); +extern int bux_socket_close(int fd); +extern const char* bux_socket_error(void); +extern unsigned int bux_strlen(const char* s); +extern int64_t bux_str_to_int(const char* s); +extern void* bux_alloc(unsigned int size); +extern void bux_sha256(const char* data, int len, void* out); +extern void bux_hmac_sha256(const char* key, int keylen, const char* msg, int msglen, void* out); +extern int bux_random_bytes(void* buf, int len); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_base64_decode(const char* data, int len, int* outlen); +extern const char* bux_bytes_to_hex(void* data, int len); +extern void* bux_mutex_new(void); +extern void bux_mutex_lock(void* handle); +extern void bux_mutex_unlock(void* handle); +extern void bux_mutex_free(void* handle); +extern void* bux_rwlock_new(void); +extern void bux_rwlock_rdlock(void* handle); +extern void bux_rwlock_wrlock(void* handle); +extern void bux_rwlock_unlock(void* handle); +extern void bux_rwlock_free(void* handle); +extern void bux_exit(int code); +extern void bux_assert(int cond, const char* file, int line, const char* expr); +extern JsonValue JsonParser_ParseValue(JsonParser* p); +extern unsigned int bux_strlen(const char* s); +extern int bux_strcmp(const char* a, const char* b); +extern int bux_strncmp(const char* a, const char* b, unsigned int n); +extern char* bux_strcpy(char* dest, const char* src); +extern char* bux_strcat(char* dest, const char* src); +extern char* bux_strncpy(char* dest, const char* src, unsigned int n); +extern const char* bux_strstr(const char* haystack, const char* needle); +extern int bux_str_contains(const char* haystack, const char* needle); +extern unsigned int bux_str_offset(const char* pos, const char* base); +extern int bux_str_is_null(const char* s); +extern const char* bux_str_slice(const char* s, unsigned int start, unsigned int len); +extern const char* bux_str_trim_left(const char* s); +extern const char* bux_str_trim_right(const char* s); +extern const char* bux_str_trim(const char* s); +extern const char* bux_int_to_str(int64_t n); +extern int64_t bux_str_to_int(const char* s); +extern void* bux_sb_new(unsigned int initial_cap); +extern void bux_sb_append(void* sb, const char* s); +extern void bux_sb_append_int(void* sb, int64_t n); +extern void bux_sb_append_float(void* sb, double f); +extern void bux_sb_append_char(void* sb, char c); +extern const char* bux_sb_build(void* sb); +extern void bux_sb_free(void* sb); +extern unsigned int bux_str_split_count(const char* s, const char* delim); +extern const char* bux_str_split_part(const char* s, const char* delim, unsigned int index); +extern const char* bux_str_join2(const char* a, const char* b, const char* sep); +extern const char* bux_float_to_string(double f); +extern const char* bux_str_format(const char* pattern, const char* a0, const char* a1, const char* a2, const char* a3, const char* a4, const char* a5, const char* a6, const char* a7); +extern double bux_str_to_float(const char* s); +extern void bux_sha1(const char* data, int len, void* out); +extern void bux_sha256(const char* data, int len, void* out); +extern void bux_sha384(const char* data, int len, void* out); +extern void bux_sha512(const char* data, int len, void* out); +extern const char* bux_bytes_to_hex(void* data, int len); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_base64_decode(const char* data, int len, int* outlen); +extern const char* bux_base64url_encode(const char* data, int len); +extern const char* bux_base64url_decode(const char* data, int len, int* outlen); +extern void bux_hmac_sha256(const char* key, int keylen, const char* msg, int msglen, void* out); +extern void bux_hmac_sha384(const char* key, int keylen, const char* msg, int msglen, void* out); +extern void bux_hmac_sha512(const char* key, int keylen, const char* msg, int msglen, void* out); +extern const char* bux_bytes_to_hex(void* data, int len); +extern const char* bux_base64_encode(const char* data, int len); +extern int bux_random_bytes(void* buf, int len); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_bytes_to_hex(void* data, int len); +extern int bux_random_bytes(void* buf, int len); +extern const char* bux_aes_256_cbc_encrypt(const char* plain, int plainlen, const char* key, const char* iv, int* outlen); +extern const char* bux_aes_256_cbc_decrypt(const char* cipher, int cipherlen, const char* key, const char* iv, int* outlen); +extern const char* bux_aes_256_gcm_encrypt(const char* plain, int plainlen, const char* key, const char* iv, void* tag, int* outlen); +extern const char* bux_aes_256_gcm_decrypt(const char* cipher, int cipherlen, const char* key, const char* iv, const char* tag, int* outlen); +extern const char* bux_base64_encode(const char* data, int len); +extern unsigned int bux_str_split_count(const char* s, const char* delim); +extern const char* bux_str_split_part(const char* s, const char* delim, unsigned int index); +extern const char* bux_ecdsa_sign_p256(const char* key, int keylen, const char* data, int datalen, int* outlen); +extern int bux_ecdsa_verify_p256(const char* key, int keylen, const char* data, int datalen, const char* sig, int siglen); +extern const char* bux_ecdsa_sign_p384(const char* key, int keylen, const char* data, int datalen, int* outlen); +extern int bux_ecdsa_verify_p384(const char* key, int keylen, const char* data, int datalen, const char* sig, int siglen); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_base64_decode(const char* data, int len, int* outlen); +extern int bux_ed25519_keypair(void* pubKey, void* privKey); +extern int bux_ed25519_sign(const char* privKey, const char* data, int datalen, void* sig); +extern int bux_ed25519_verify(const char* pubKey, const char* sig, const char* data, int datalen); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_base64_decode(const char* data, int len, int* outlen); +extern const char* bux_rsa_sign_sha256(const char* key, int keylen, const char* data, int datalen, int* outlen); +extern const char* bux_rsa_sign_sha384(const char* key, int keylen, const char* data, int datalen, int* outlen); +extern const char* bux_rsa_sign_sha512(const char* key, int keylen, const char* data, int datalen, int* outlen); +extern int bux_rsa_verify_sha256(const char* key, int keylen, const char* data, int datalen, const char* sig, int siglen); +extern int bux_rsa_verify_sha384(const char* key, int keylen, const char* data, int datalen, const char* sig, int siglen); +extern int bux_rsa_verify_sha512(const char* key, int keylen, const char* data, int datalen, const char* sig, int siglen); +extern const char* bux_base64_encode(const char* data, int len); +extern const char* bux_base64_decode(const char* data, int len, int* outlen); + +/* Constants */ +#define JsonTagNull 0 +#define JsonTagBool 1 +#define JsonTagNumber 2 +#define JsonTagString 3 +#define JsonTagArray 4 +#define JsonTagObject 5 +#define AES_KEY_SIZE 32 +#define AES_IV_SIZE 16 +#define AES_GCM_TAG_SIZE 16 +#define ED25519_PUBKEY_SIZE 32 +#define ED25519_PRIVKEY_SIZE 32 +#define ED25519_SIG_SIZE 64 + +typedef enum { + Result_Ok, + Result_Err +} Result_Tag; + +typedef union { + int Ok_0; + const char* Err_0; +} Result_Data; + +typedef struct { + Result_Tag tag; + Result_Data data; +} Result; + +typedef enum { + Option_Some, + Option_None +} Option_Tag; + +typedef union { + int Some_0; +} Option_Data; + +typedef struct { + Option_Tag tag; + Option_Data data; +} Option; + +typedef enum { + JwtAlg_HS256, + JwtAlg_HS384, + JwtAlg_HS512, + JwtAlg_RS256, + JwtAlg_RS384, + JwtAlg_RS512, + JwtAlg_ES256, + JwtAlg_ES384, + JwtAlg_EdDSA +} JwtAlg; -int Apply(int x, int (*op)(int)); -int Double(int x); -int __closure_2(int a, int b); -int __closure_3(int x); -int main(); +typedef struct TaskHandle { + void* handle; +} TaskHandle; -void PrintInt(int x); -void PrintLine(String msg); +typedef struct Mutex { + void* handle; +} Mutex; -int Apply(int x, int (*op)(int)) { - return op(x); +typedef struct RwLock { + void* handle; +} RwLock; +typedef struct JsonValue { + int tag; + bool boolVal; + double numVal; + const char* strVal; + JsonValue* arrData; + unsigned int arrLen; + unsigned int arrCap; + const char** objKeys; + JsonValue* objValues; + unsigned int objLen; + unsigned int objCap; +} JsonValue; + +typedef struct JsonParser { + const char* src; + unsigned int pos; + unsigned int len; + const char* error; +} JsonParser; + +typedef struct StringBuilder { + void* handle; +} StringBuilder; + +typedef struct Channel_int { + void* handle; +} Channel_int; + +typedef struct Channel_float64 { + void* handle; +} Channel_float64; + +void Channel_SendInt(Channel_int* ch, int value); +int Channel_RecvInt(Channel_int* ch); +void Channel_SendFloat64(Channel_float64* ch, double value); +double Channel_RecvFloat64(Channel_float64* ch); +bool DirExists(const char* path); +bool Mkdir(const char* path); +const char** ListDir(const char* dir, const char* ext, int* count); +const char* ReadFile(const char* path); +bool WriteFile(const char* path, const char* content); +bool FileExists(const char* path); +double Sqrt(double x); +double Pow(double x, double y); +int64_t Abs(int64_t n); +double AbsF(double f); +int64_t Min(int64_t a, int64_t b); +int64_t Max(int64_t a, int64_t b); +double MinF(double a, double b); +double MaxF(double a, double b); +void* Alloc(unsigned int size); +void* Realloc(void* ptr, unsigned int size); +void Free(void* ptr); +bool MemEq(void* a, void* b, unsigned int size); +const char* Path_Join(const char* a, const char* b); +const char* Path_Parent(const char* path); +const char* Path_Ext(const char* path); +TaskHandle Task_Spawn(void* fn, void* arg); +void Task_Join(TaskHandle t); +void Task_Sleep(int64_t ms); +int Os_ArgsCount(void); +const char* Os_Args(int index); +const char* Os_GetEnv(const char* name); +bool Os_SetEnv(const char* name, const char* value); +const char* Os_GetCwd(void); +bool Os_Chdir(const char* path); +int64_t Time_NowMs(void); +int64_t Time_NowUs(void); +void Time_SleepMs(int64_t ms); +int Process_Run(const char* cmd); +const char* Process_Output(const char* cmd); +int Net_Create(void); +bool Net_SetReuse(int fd); +bool Net_Bind(int fd, const char* addr, int port); +bool Net_Listen(int fd, int backlog); +int Net_Accept(int fd); +bool Net_Connect(int fd, const char* addr, int port); +int Net_Send(int fd, const char* data); +const char* Net_Recv(int fd, int maxLen); +bool Net_Close(int fd); +const char* Net_LastError(void); +const char* Fmt_Format(const char* tmpl, const char** argStrs, int argCount); +const char* Fmt_Fmt1(const char* tmpl, const char* a1); +const char* Fmt_FmtInt(const char* tmpl, int64_t val); +const char* Fmt_FmtBool(const char* tmpl, bool val); +const char* Fmt_FmtFloat(const char* tmpl, double val); +const char* Fmt_Fmt2(const char* tmpl, const char* a1, const char* a2); +const char* Fmt_Fmt3(const char* tmpl, const char* a1, const char* a2, const char* a3); +const char* Crypto_Sha256(const char* data); +const char* Crypto_HmacSha256(const char* key, const char* message); +const char* Crypto_RandomBytes(int n); +const char* Crypto_Base64Encode(const char* s); +const char* Crypto_HmacSha256Raw(const char* key, const char* message); +const char* Crypto_Base64Decode(const char* s); +Mutex Mutex_New(void); +void Mutex_Lock(Mutex* m); +void Mutex_Unlock(Mutex* m); +void Mutex_Free(Mutex* m); +RwLock RwLock_New(void); +void RwLock_ReadLock(RwLock* rw); +void RwLock_WriteLock(RwLock* rw); +void RwLock_Unlock(RwLock* rw); +void RwLock_Free(RwLock* rw); +void Test_Exit(int code); +void Test_Assert(bool cond); +void Test_AssertEqInt(int a, int b); +void Test_AssertTrue(bool cond); +void Test_AssertFalse(bool cond); +void Test_Fail(const char* msg); +Result Result_NewOk(int value); +Result Result_NewErr(const char* msg); +bool Result_IsOk(Result r); +bool Result_IsErr(Result r); +int Result_Unwrap(Result r); +int Result_UnwrapOr(Result r, int fallback); +Option Option_NewSome(int value); +Option Option_NewNone(void); +bool Option_IsSome(Option o); +bool Option_IsNone(Option o); +int Option_Unwrap(Option o); +int Option_UnwrapOr(Option o, int fallback); +JsonValue Json_Null(void); +JsonValue Json_Bool(bool b); +JsonValue Json_Number(double n); +JsonValue Json_String(const char* s); +JsonValue Json_Array(void); +JsonValue Json_Object(void); +unsigned int Json_ArrayLen(JsonValue v); +JsonValue Json_ArrayGet(JsonValue v, unsigned int index); +void Json_ArrayPush(JsonValue* self, JsonValue val); +unsigned int Json_ObjectLen(JsonValue v); +JsonValue Json_ObjectGet(JsonValue v, const char* key); +bool Json_ObjectHas(JsonValue v, const char* key); +void Json_ObjectSet(JsonValue* self, const char* key, JsonValue val); +bool Json_IsNull(JsonValue v); +bool Json_AsBool(JsonValue v); +double Json_AsNumber(JsonValue v); +const char* Json_AsString(JsonValue v); +int JsonParser_Peek(JsonParser* p); +void JsonParser_Advance(JsonParser* p); +void JsonParser_SkipWhitespace(JsonParser* p); +bool JsonParser_Match(JsonParser* p, const char* expected); +const char* JsonParser_ParseString(JsonParser* p); +JsonValue JsonParser_ParseNumber(JsonParser* p); +JsonValue JsonParser_ParseArray(JsonParser* p); +JsonValue JsonParser_ParseObject(JsonParser* p); +JsonValue JsonParser_ParseValue(JsonParser* p); +JsonValue Json_Parse(const char* s); +void Json_StringifyImpl(StringBuilder* sb, JsonValue v); +const char* Json_Stringify(JsonValue v); +unsigned int String_Len(const char* s); +bool String_IsNull(const char* s); +bool String_Eq(const char* a, const char* b); +const char* String_Concat(const char* a, const char* b); +const char* String_Copy(const char* s); +bool String_StartsWith(const char* s, const char* prefix); +bool String_EndsWith(const char* s, const char* suffix); +bool String_Contains(const char* s, const char* substr); +const char* String_Slice(const char* s, unsigned int start, unsigned int len); +const char* String_Trim(const char* s); +const char* String_TrimLeft(const char* s); +const char* String_TrimRight(const char* s); +const char* String_FromInt(int64_t n); +int64_t String_ToInt(const char* s); +StringBuilder StringBuilder_New(void); +StringBuilder StringBuilder_NewCap(unsigned int cap); +void StringBuilder_Append(StringBuilder* sb, const char* s); +void StringBuilder_AppendInt(StringBuilder* sb, int64_t n); +void StringBuilder_AppendFloat(StringBuilder* sb, double f); +void StringBuilder_AppendChar(StringBuilder* sb, char c); +const char* StringBuilder_Build(StringBuilder* sb); +void StringBuilder_Free(StringBuilder* sb); +unsigned int String_SplitCount(const char* s, const char* delim); +const char* String_SplitPart(const char* s, const char* delim, unsigned int index); +const char* String_Join2(const char* a, const char* b, const char* sep); +const char* String_Chars(const char* s, unsigned int index); +const char* String_Find(const char* haystack, const char* needle); +unsigned int String_Offset(const char* pos, const char* base); +const char* String_Replace(const char* s, const char* old, const char* new); +double String_ToFloat(const char* s); +const char* String_FromBool(bool b); +const char* String_FromFloat(double f); +const char* String_Format1(const char* pattern, const char* a0); +const char* String_Format2(const char* pattern, const char* a0, const char* a1); +const char* String_Format3(const char* pattern, const char* a0, const char* a1, const char* a2); +const char* Hash_Sha1(const char* data); +const char* Hash_Sha256(const char* data); +const char* Hash_Sha384(const char* data); +const char* Hash_Sha512(const char* data); +void Hash_Sha256Raw(const char* data, void* out); +void Hash_Sha384Raw(const char* data, void* out); +void Hash_Sha512Raw(const char* data, void* out); +int Hash_Sha1Size(void); +int Hash_Sha256Size(void); +int Hash_Sha384Size(void); +int Hash_Sha512Size(void); +const char* Base64_Encode(const char* s); +const char* Base64_Decode(const char* s); +const char* Base64URL_Encode(const char* s); +const char* Base64URL_Decode(const char* s); +const char* Hmac_Sha256(const char* key, const char* message); +void Hmac_Sha256Raw(const char* key, const char* message, void* out); +const char* Hmac_Sha256Base64(const char* key, const char* message); +const char* Hmac_Sha384(const char* key, const char* message); +void Hmac_Sha384Raw(const char* key, const char* message, void* out); +const char* Hmac_Sha384Base64(const char* key, const char* message); +const char* Hmac_Sha512(const char* key, const char* message); +void Hmac_Sha512Raw(const char* key, const char* message, void* out); +const char* Hmac_Sha512Base64(const char* key, const char* message); +const char* Random_Bytes(int n); +const char* Random_Hex(int n); +const char* Random_Base64(int n); +unsigned int Random_Uint32(void); +const char* Aes_GenerateKey(void); +const char* Aes_GenerateIV(void); +const char* Aes_CbcEncrypt(const char* plain, const char* key, const char* iv); +const char* Aes_CbcDecrypt(const char* cipher, const char* key, const char* iv); +const char* Aes_GcmEncrypt(const char* plain, const char* key, const char* iv, void* tag); +const char* Aes_GcmDecrypt(const char* cipher, const char* key, const char* iv, const char* tag); +const char* Jwt_MakeHeader(JwtAlg alg); +const char* Jwt_Sign(JwtAlg alg, const char* signingInput, const char* key); +bool Jwt_Verify(JwtAlg alg, const char* signingInput, const char* signatureB64, const char* key); +const char* Jwt_Encode(const char* headerJson, const char* payloadJson, JwtAlg alg, const char* key); +bool Jwt_Decode(const char* token, JwtAlg alg, const char* key, const char** headerOut, const char** payloadOut); +const char* Jwt_EncodeHS256(const char* payloadJson, const char* secret); +const char* Jwt_EncodeHS384(const char* payloadJson, const char* secret); +const char* Jwt_EncodeHS512(const char* payloadJson, const char* secret); +const char* Jwt_EncodeRS256(const char* payloadJson, const char* pemPrivateKey); +const char* Jwt_EncodeES256(const char* payloadJson, const char* pemPrivateKey); +const char* Jwt_EncodeEdDSA(const char* payloadJson, const char* rawPrivKey); +const char* Ecdsa_SignP256(const char* pemPrivateKey, const char* data); +const char* Ecdsa_SignP256Base64(const char* pemPrivateKey, const char* data); +bool Ecdsa_VerifyP256(const char* pemPublicKey, const char* data, const char* signature); +bool Ecdsa_VerifyP256Base64(const char* pemPublicKey, const char* data, const char* signatureB64); +const char* Ecdsa_SignP384(const char* pemPrivateKey, const char* data); +const char* Ecdsa_SignP384Base64(const char* pemPrivateKey, const char* data); +bool Ecdsa_VerifyP384(const char* pemPublicKey, const char* data, const char* signature); +bool Ecdsa_VerifyP384Base64(const char* pemPublicKey, const char* data, const char* signatureB64); +bool Ed25519_Keypair(void* pubKey, void* privKey); +const char* Ed25519_KeypairBase64(void); +const char* Ed25519_Sign(const char* privKey, const char* data); +const char* Ed25519_SignBase64(const char* privKey, const char* data); +bool Ed25519_Verify(const char* pubKey, const char* signature, const char* data); +bool Ed25519_VerifyBase64(const char* pubKey, const char* signatureB64, const char* data); +const char* Rsa_SignSha256(const char* pemPrivateKey, const char* data); +const char* Rsa_SignSha384(const char* pemPrivateKey, const char* data); +const char* Rsa_SignSha512(const char* pemPrivateKey, const char* data); +const char* Rsa_SignSha256Base64(const char* pemPrivateKey, const char* data); +const char* Rsa_SignSha384Base64(const char* pemPrivateKey, const char* data); +const char* Rsa_SignSha512Base64(const char* pemPrivateKey, const char* data); +bool Rsa_VerifySha256(const char* pemPublicKey, const char* data, const char* signature); +bool Rsa_VerifySha384(const char* pemPublicKey, const char* data, const char* signature); +bool Rsa_VerifySha512(const char* pemPublicKey, const char* data, const char* signature); +bool Rsa_VerifySha256Base64(const char* pemPublicKey, const char* data, const char* signatureB64); +bool Rsa_VerifySha384Base64(const char* pemPublicKey, const char* data, const char* signatureB64); +bool Rsa_VerifySha512Base64(const char* pemPublicKey, const char* data, const char* signatureB64); +int apply(int (*f)(int), int x); +int Main(void); +int __closure_10(int a); + +void Channel_SendInt(Channel_int* ch, int value) { + void* _t2; + void* _t3; + void* _t1; + _t1 = ch->handle; + _t2 = &value; + _t3 = (void*)_t2; + bux_channel_send(_t1, _t3); } -int Double(int x) { - return x * 2; - +int Channel_RecvInt(Channel_int* ch) { + void* _t5; + void* _t6; + int result; + result = 0; + void* _t4; + _t4 = ch->handle; + _t5 = &result; + _t6 = (void*)_t5; + bux_channel_recv(_t4, _t6); + return result; } -int __closure_2(int a, int b) { - return a + b; - +void Channel_SendFloat64(Channel_float64* ch, double value) { + void* _t8; + void* _t9; + void* _t7; + _t7 = ch->handle; + _t8 = &value; + _t9 = (void*)_t8; + bux_channel_send(_t7, _t9); } -int __closure_3(int x) { - return x * 3; - +double Channel_RecvFloat64(Channel_float64* ch) { + void* _t11; + void* _t12; + double result; + result = 0.0; + void* _t10; + _t10 = ch->handle; + _t11 = &result; + _t12 = (void*)_t11; + bux_channel_recv(_t10, _t12); + return result; } -int main() { - int (*add)(int, int) = &__closure_2; - int sum = add(3, 4); - PrintInt(sum); - PrintLine(""); - int result = Apply(5, &__closure_3); - PrintInt(result); - PrintLine(""); - int (*d)(int) = &Double; - PrintInt(d(7)); - PrintLine(""); +bool DirExists(const char* path) { + int _t14; + int _t13; + _t13 = bux_dir_exists(path); + _t14 = (_t13 != 0); + return _t14; +} + +bool Mkdir(const char* path) { + int _t16; + int _t15; + _t15 = bux_mkdir_if_needed(path); + _t16 = (_t15 != 0); + return _t16; +} + +const char** ListDir(const char* dir, const char* ext, int* count) { + const char** _t17; + _t17 = bux_list_dir(dir, ext, count); + return _t17; +} + +const char* ReadFile(const char* path) { + const char* _t18; + _t18 = bux_read_file(path); + return _t18; +} + +bool WriteFile(const char* path, const char* content) { + int _t20; + int r; + int _t19; + _t19 = bux_write_file(path, content); + r = _t19; + _t20 = (r != 0); + return _t20; +} + +bool FileExists(const char* path) { + int _t22; + int r; + int _t21; + _t21 = bux_file_exists(path); + r = _t21; + _t22 = (r != 0); + return _t22; +} + +double Sqrt(double x) { + double _t23; + _t23 = bux_sqrt(x); + return _t23; +} + +double Pow(double x, double y) { + double _t24; + _t24 = bux_pow(x, y); + return _t24; +} + +int64_t Abs(int64_t n) { + int64_t _t25; + _t25 = bux_abs_i64(n); + return _t25; +} + +double AbsF(double f) { + double _t26; + _t26 = bux_abs_f64(f); + return _t26; +} + +int64_t Min(int64_t a, int64_t b) { + int64_t _t27; + _t27 = bux_min_i64(a, b); + return _t27; +} + +int64_t Max(int64_t a, int64_t b) { + int64_t _t28; + _t28 = bux_max_i64(a, b); + return _t28; +} + +double MinF(double a, double b) { + double _t29; + _t29 = bux_min_f64(a, b); + return _t29; +} + +double MaxF(double a, double b) { + double _t30; + _t30 = bux_max_f64(a, b); + return _t30; +} + +void* Alloc(unsigned int size) { + void* _t31; + _t31 = bux_alloc(size); + return _t31; +} + +void* Realloc(void* ptr, unsigned int size) { + void* _t32; + _t32 = bux_realloc(ptr, size); + return _t32; +} + +void Free(void* ptr) { + bux_free(ptr); +} + +bool MemEq(void* a, void* b, unsigned int size) { + int _t34; + int _t33; + _t33 = bux_mem_eq(a, b, size); + _t34 = (_t33 != 0); + return _t34; +} + +const char* Path_Join(const char* a, const char* b) { + const char* _t35; + _t35 = bux_path_join(a, b); + return _t35; +} + +const char* Path_Parent(const char* path) { + const char* _t36; + _t36 = bux_path_parent(path); + return _t36; +} + +const char* Path_Ext(const char* path) { + const char* _t37; + _t37 = bux_path_ext(path); + return _t37; +} + +TaskHandle Task_Spawn(void* fn, void* arg) { + TaskHandle _t39; + void* _t38; + _t38 = bux_task_spawn(fn, arg); + _t39 = (TaskHandle){.handle = _t38}; + return _t39; +} + +void Task_Join(TaskHandle t) { + void* _t40; + _t40 = t.handle; + bux_task_join(_t40); +} + +void Task_Sleep(int64_t ms) { + bux_task_sleep(ms); +} + +int Os_ArgsCount(void) { + int _t41; + _t41 = bux_argc(); + return _t41; +} + +const char* Os_Args(int index) { + const char* _t42; + _t42 = bux_argv(index); + return _t42; +} + +const char* Os_GetEnv(const char* name) { + const char* _t43; + _t43 = bux_getenv(name); + return _t43; +} + +bool Os_SetEnv(const char* name, const char* value) { + int _t45; + int _t44; + _t44 = bux_setenv(name, value); + _t45 = (_t44 == 0); + return _t45; +} + +const char* Os_GetCwd(void) { + const char* _t46; + _t46 = bux_getcwd(); + return _t46; +} + +bool Os_Chdir(const char* path) { + int _t48; + int _t47; + _t47 = bux_chdir(path); + _t48 = (_t47 == 0); + return _t48; +} + +int64_t Time_NowMs(void) { + int64_t _t49; + _t49 = bux_time_ms(); + return _t49; +} + +int64_t Time_NowUs(void) { + int64_t _t50; + _t50 = bux_time_us(); + return _t50; +} + +void Time_SleepMs(int64_t ms) { + bux_sleep_ms(ms); +} + +int Process_Run(const char* cmd) { + int _t51; + _t51 = bux_process_run(cmd); + return _t51; +} + +const char* Process_Output(const char* cmd) { + const char* _t52; + _t52 = bux_process_output(cmd); + return _t52; +} + +int Net_Create(void) { + int _t53; + _t53 = bux_socket_create(); + return _t53; +} + +bool Net_SetReuse(int fd) { + int _t55; + int _t54; + _t54 = bux_socket_reuse(fd); + _t55 = (_t54 == 0); + return _t55; +} + +bool Net_Bind(int fd, const char* addr, int port) { + int _t57; + int _t56; + _t56 = bux_socket_bind(fd, addr, port); + _t57 = (_t56 == 0); + return _t57; +} + +bool Net_Listen(int fd, int backlog) { + int _t59; + int _t58; + _t58 = bux_socket_listen(fd, backlog); + _t59 = (_t58 == 0); + return _t59; +} + +int Net_Accept(int fd) { + int _t60; + _t60 = bux_socket_accept(fd); + return _t60; +} + +bool Net_Connect(int fd, const char* addr, int port) { + int _t62; + int _t61; + _t61 = bux_socket_connect(fd, addr, port); + _t62 = (_t61 == 0); + return _t62; +} + +int Net_Send(int fd, const char* data) { + int _t64; + unsigned int _t63; + _t63 = bux_strlen(data); + _t64 = (int)_t63; + int _t65; + _t65 = bux_socket_send(fd, data, _t64); + return _t65; +} + +const char* Net_Recv(int fd, int maxLen) { + const char* _t66; + _t66 = bux_socket_recv(fd, maxLen); + return _t66; +} + +bool Net_Close(int fd) { + int _t68; + int _t67; + _t67 = bux_socket_close(fd); + _t68 = (_t67 == 0); + return _t68; +} + +const char* Net_LastError(void) { + const char* _t69; + _t69 = bux_socket_error(); + return _t69; +} + +const char* Fmt_Format(const char* tmpl, const char** argStrs, int argCount) { + int _t72; + int _t75; + int _t76; + int _t79; + int64_t _t80; + int _t81; + int _t83; + int _t84; + int _t87; + unsigned int _t88; + void* _t90; + void* _t91; + int _t92; + void* _t93; + StringBuilder sb; + StringBuilder _t70; + _t70 = StringBuilder_New(); + sb = _t70; + unsigned int i; + i = 0; + unsigned int tmplLen; + unsigned int _t71; + _t71 = bux_strlen(tmpl); + tmplLen = _t71; + while1:; + _t72 = (i < tmplLen); + if (!_t72) goto wend3; + { + const char* ch; + const char* _t73; + _t73 = String_Chars(tmpl, i); + ch = _t73; + bool _t74; + _t74 = String_Eq(ch, "{"); + if (!_t74) goto endif5; + { + unsigned int digitIdx; + _t75 = i + 1; + digitIdx = _t75; + _t76 = (digitIdx < tmplLen); + if (!_t76) goto endif7; + { + const char* digitCh; + const char* _t77; + _t77 = String_Chars(tmpl, digitIdx); + digitCh = _t77; + int64_t d; + int64_t _t78; + _t78 = bux_str_to_int(digitCh); + d = _t78; + bool __and_tmp_0; + _t79 = (d >= 0); + if (!_t79) goto else8; + _t80 = (int64_t)argCount; + _t81 = (d < _t80); + *(bool*)&__and_tmp_0 = _t81; + goto endif9; + else8:; + *(bool*)&__and_tmp_0 = 0; + endif9:; + bool _t82; + _t82 = *(bool*)&__and_tmp_0; + if (!_t82) goto endif11; + { + _t83 = i + 2; + i = _t83; + _t84 = (i < tmplLen); + if (!_t84) goto endif13; + { + const char* closeCh; + const char* _t85; + _t85 = String_Chars(tmpl, i); + closeCh = _t85; + bool _t86; + _t86 = String_Eq(closeCh, "}"); + if (!_t86) goto endif15; + { + _t87 = i + 1; + i = _t87; + const char* argStr; + _t88 = (unsigned int)d; + const char* _t89; + _t89 = argStrs[_t88]; + argStr = _t89; + _t90 = &sb; + StringBuilder_Append(_t90, argStr); + goto while1; + } + endif15:; + } + endif13:; + } + endif11:; + } + endif7:; + } + endif5:; + _t91 = &sb; + StringBuilder_Append(_t91, ch); + _t92 = i + 1; + i = _t92; + } + goto while1; + wend3:; + _t93 = &sb; + const char* _t94; + _t94 = StringBuilder_Build(_t93); + return _t94; +} + +const char* Fmt_Fmt1(const char* tmpl, const char* a1) { + const char** _t97; + const char** args; + /* sizeof(const char*) */ + void* _t96; + _t96 = bux_alloc(sizeof(const char*)); + _t97 = (const char**)_t96; + args = _t97; + args[0] = a1; + const char* _t98; + _t98 = Fmt_Format(tmpl, args, 1); + return _t98; +} + +const char* Fmt_FmtInt(const char* tmpl, int64_t val) { + const char* s; + const char* _t99; + _t99 = String_FromInt(val); + s = _t99; + const char* _t100; + _t100 = Fmt_Fmt1(tmpl, s); + return _t100; +} + +const char* Fmt_FmtBool(const char* tmpl, bool val) { + const char* s; + const char* _t101; + _t101 = String_FromBool(val); + s = _t101; + const char* _t102; + _t102 = Fmt_Fmt1(tmpl, s); + return _t102; +} + +const char* Fmt_FmtFloat(const char* tmpl, double val) { + const char* s; + const char* _t103; + _t103 = String_FromFloat(val); + s = _t103; + const char* _t104; + _t104 = Fmt_Fmt1(tmpl, s); + return _t104; +} + +const char* Fmt_Fmt2(const char* tmpl, const char* a1, const char* a2) { + int _t106; + const char** _t108; + const char** args; + /* sizeof(const char*) */ + _t106 = 2 * sizeof(const char*); + void* _t107; + _t107 = bux_alloc(_t106); + _t108 = (const char**)_t107; + args = _t108; + args[0] = a1; + args[1] = a2; + const char* _t109; + _t109 = Fmt_Format(tmpl, args, 2); + return _t109; +} + +const char* Fmt_Fmt3(const char* tmpl, const char* a1, const char* a2, const char* a3) { + int _t111; + const char** _t113; + const char** args; + /* sizeof(const char*) */ + _t111 = 3 * sizeof(const char*); + void* _t112; + _t112 = bux_alloc(_t111); + _t113 = (const char**)_t112; + args = _t113; + args[0] = a1; + args[1] = a2; + args[2] = a3; + const char* _t114; + _t114 = Fmt_Format(tmpl, args, 3); + return _t114; +} + +const char* Crypto_Sha256(const char* data) { + int _t116; + void* _t118; + int len; + unsigned int _t115; + _t115 = String_Len(data); + _t116 = (int)_t115; + len = _t116; + void* hashBuf; + void* _t117; + _t117 = Alloc(32); + hashBuf = _t117; + bux_sha256(data, len, hashBuf); + const char* result; + _t118 = (void*)hashBuf; + const char* _t119; + _t119 = bux_bytes_to_hex(_t118, 32); + result = _t119; + Free(hashBuf); + return result; +} + +const char* Crypto_HmacSha256(const char* key, const char* message) { + int _t121; + int _t123; + void* _t125; + int keylen; + unsigned int _t120; + _t120 = String_Len(key); + _t121 = (int)_t120; + keylen = _t121; + int msglen; + unsigned int _t122; + _t122 = String_Len(message); + _t123 = (int)_t122; + msglen = _t123; + void* hmacBuf; + void* _t124; + _t124 = Alloc(32); + hmacBuf = _t124; + bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); + const char* result; + _t125 = (void*)hmacBuf; + const char* _t126; + _t126 = bux_bytes_to_hex(_t125, 32); + result = _t126; + Free(hmacBuf); + return result; +} + +const char* Crypto_RandomBytes(int n) { + int _t127; + unsigned int _t128; + int _t131; + const char* _t132; + _t127 = (n <= 0); + if (!_t127) goto endif17; + { + return ""; + } + endif17:; + void* buf; + _t128 = (unsigned int)n; + void* _t129; + _t129 = Alloc(_t128); + buf = _t129; + int _t130; + _t130 = bux_random_bytes(buf, n); + _t131 = (_t130 != 1); + if (!_t131) goto endif19; + { + Free(buf); + return ""; + } + endif19:; + const char* result; + _t132 = (const char*)buf; + const char* _t133; + _t133 = bux_base64_encode(_t132, n); + result = _t133; + Free(buf); + return result; +} + +const char* Crypto_Base64Encode(const char* s) { + int _t135; + unsigned int _t134; + _t134 = String_Len(s); + _t135 = (int)_t134; + const char* _t136; + _t136 = bux_base64_encode(s, _t135); + return _t136; +} + +const char* Crypto_HmacSha256Raw(const char* key, const char* message) { + int _t138; + int _t140; + const char* _t142; + int keylen; + unsigned int _t137; + _t137 = String_Len(key); + _t138 = (int)_t137; + keylen = _t138; + int msglen; + unsigned int _t139; + _t139 = String_Len(message); + _t140 = (int)_t139; + msglen = _t140; + void* hmacBuf; + void* _t141; + _t141 = Alloc(32); + hmacBuf = _t141; + bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); + const char* result; + _t142 = (const char*)hmacBuf; + const char* _t143; + _t143 = bux_base64_encode(_t142, 32); + result = _t143; + Free(hmacBuf); + return result; +} + +const char* Crypto_Base64Decode(const char* s) { + int _t145; + void* _t146; + int outlen; + outlen = 0; + unsigned int _t144; + _t144 = String_Len(s); + _t145 = (int)_t144; + _t146 = &outlen; + const char* _t147; + _t147 = bux_base64_decode(s, _t145, _t146); + return _t147; +} + +Mutex Mutex_New(void) { + Mutex _t149; + void* _t148; + _t148 = bux_mutex_new(); + _t149 = (Mutex){.handle = _t148}; + return _t149; +} + +void Mutex_Lock(Mutex* m) { + void* _t150; + _t150 = m->handle; + bux_mutex_lock(_t150); +} + +void Mutex_Unlock(Mutex* m) { + void* _t151; + _t151 = m->handle; + bux_mutex_unlock(_t151); +} + +void Mutex_Free(Mutex* m) { + void* _t152; + _t152 = m->handle; + bux_mutex_free(_t152); +} + +RwLock RwLock_New(void) { + RwLock _t154; + void* _t153; + _t153 = bux_rwlock_new(); + _t154 = (RwLock){.handle = _t153}; + return _t154; +} + +void RwLock_ReadLock(RwLock* rw) { + void* _t155; + _t155 = rw->handle; + bux_rwlock_rdlock(_t155); +} + +void RwLock_WriteLock(RwLock* rw) { + void* _t156; + _t156 = rw->handle; + bux_rwlock_wrlock(_t156); +} + +void RwLock_Unlock(RwLock* rw) { + void* _t157; + _t157 = rw->handle; + bux_rwlock_unlock(_t157); +} + +void RwLock_Free(RwLock* rw) { + void* _t158; + _t158 = rw->handle; + bux_rwlock_free(_t158); +} + +void Test_Exit(int code) { + bux_exit(code); +} + +void Test_Assert(bool cond) { + int _t159; + _t159 = (int)cond; + bux_assert(_t159, "", 0, ""); +} + +void Test_AssertEqInt(int a, int b) { + int _t160; + _t160 = (a != b); + if (!_t160) goto endif21; + { + PrintLine("ASSERT_EQ FAILED:"); + PrintInt(a); + PrintLine(" != "); + PrintInt(b); + bux_exit(1); + } + endif21:; +} + +void Test_AssertTrue(bool cond) { + int _t161; + _t161 = !cond; + if (!_t161) goto endif23; + { + PrintLine("ASSERT_TRUE FAILED"); + bux_exit(1); + } + endif23:; +} + +void Test_AssertFalse(bool cond) { + if (!cond) goto endif25; + { + PrintLine("ASSERT_FALSE FAILED"); + bux_exit(1); + } + endif25:; +} + +void Test_Fail(const char* msg) { + PrintLine("FAIL:"); + PrintLine(msg); + bux_exit(1); +} + +Result Result_NewOk(int value) { + Result _t162; + Result r; + _t162 = (Result){.tag = Result_Ok}; + r = _t162; + r.data.Ok_0 = value; + return r; +} + +Result Result_NewErr(const char* msg) { + Result _t163; + Result r; + _t163 = (Result){.tag = Result_Err}; + r = _t163; + r.data.Err_0 = msg; + return r; +} + +bool Result_IsOk(Result r) { + int _t165; + Result_Tag _t164; + _t164 = r.tag; + _t165 = (_t164 == Result_Ok); + return _t165; +} + +bool Result_IsErr(Result r) { + int _t167; + Result_Tag _t166; + _t166 = r.tag; + _t167 = (_t166 == Result_Err); + return _t167; +} + +int Result_Unwrap(Result r) { + int _t169; + Result_Tag _t168; + _t168 = r.tag; + _t169 = (_t168 != Result_Ok); + if (!_t169) goto endif27; + { + PrintLine("panic: unwrap on Err"); return 0; - + } + endif27:; + Result_Data _t170; + _t170 = r.data; + int _t171; + _t171 = _t170.Ok_0; + return _t171; } +int Result_UnwrapOr(Result r, int fallback) { + int _t173; + Result_Tag _t172; + _t172 = r.tag; + _t173 = (_t172 == Result_Ok); + if (!_t173) goto endif29; + { + Result_Data _t174; + _t174 = r.data; + int _t175; + _t175 = _t174.Ok_0; + return _t175; + } + endif29:; + return fallback; +} + +Option Option_NewSome(int value) { + Option _t176; + Option o; + _t176 = (Option){.tag = Option_Some}; + o = _t176; + o.data.Some_0 = value; + return o; +} + +Option Option_NewNone(void) { + Option _t177; + _t177 = (Option){.tag = Option_None}; + return _t177; +} + +bool Option_IsSome(Option o) { + int _t179; + Option_Tag _t178; + _t178 = o.tag; + _t179 = (_t178 == Option_Some); + return _t179; +} + +bool Option_IsNone(Option o) { + int _t181; + Option_Tag _t180; + _t180 = o.tag; + _t181 = (_t180 == Option_None); + return _t181; +} + +int Option_Unwrap(Option o) { + int _t183; + Option_Tag _t182; + _t182 = o.tag; + _t183 = (_t182 != Option_Some); + if (!_t183) goto endif31; + { + PrintLine("panic: unwrap on None"); + return 0; + } + endif31:; + Option_Data _t184; + _t184 = o.data; + int _t185; + _t185 = _t184.Some_0; + return _t185; +} + +int Option_UnwrapOr(Option o, int fallback) { + int _t187; + Option_Tag _t186; + _t186 = o.tag; + _t187 = (_t186 == Option_Some); + if (!_t187) goto endif33; + { + Option_Data _t188; + _t188 = o.data; + int _t189; + _t189 = _t188.Some_0; + return _t189; + } + endif33:; + return fallback; +} + +JsonValue Json_Null(void) { + JsonValue _t190; + _t190 = (JsonValue){.tag = JsonTagNull, .boolVal = 0, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t190; +} + +JsonValue Json_Bool(bool b) { + JsonValue _t191; + _t191 = (JsonValue){.tag = JsonTagBool, .boolVal = b, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t191; +} + +JsonValue Json_Number(double n) { + JsonValue _t192; + _t192 = (JsonValue){.tag = JsonTagNumber, .boolVal = 0, .numVal = n, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t192; +} + +JsonValue Json_String(const char* s) { + JsonValue _t193; + _t193 = (JsonValue){.tag = JsonTagString, .boolVal = 0, .numVal = 0.0, .strVal = s, .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t193; +} + +JsonValue Json_Array(void) { + JsonValue _t194; + _t194 = (JsonValue){.tag = JsonTagArray, .boolVal = 0, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t194; +} + +JsonValue Json_Object(void) { + JsonValue _t195; + _t195 = (JsonValue){.tag = JsonTagObject, .boolVal = 0, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}; + return _t195; +} + +unsigned int Json_ArrayLen(JsonValue v) { + int _t197; + int _t196; + _t196 = v.tag; + _t197 = (_t196 != JsonTagArray); + if (!_t197) goto endif35; + { + return 0; + } + endif35:; + unsigned int _t198; + _t198 = v.arrLen; + return _t198; +} + +JsonValue Json_ArrayGet(JsonValue v, unsigned int index) { + int _t200; + int _t203; + int _t199; + _t199 = v.tag; + _t200 = (_t199 != JsonTagArray); + if (!_t200) goto endif37; + { + JsonValue _t201; + _t201 = Json_Null(); + return _t201; + } + endif37:; + unsigned int _t202; + _t202 = v.arrLen; + _t203 = (index >= _t202); + if (!_t203) goto endif39; + { + JsonValue _t204; + _t204 = Json_Null(); + return _t204; + } + endif39:; + JsonValue* _t205; + _t205 = v.arrData; + JsonValue _t206; + _t206 = _t205[index]; + return _t206; +} + +void Json_ArrayPush(JsonValue* self, JsonValue val) { + int _t208; + int _t211; + int _t213; + int _t215; + JsonValue* _t217; + int _t218; + void* _t220; + int _t222; + JsonValue* _t224; + int _t228; + int _t207; + _t207 = self->tag; + _t208 = (_t207 != JsonTagArray); + if (!_t208) goto endif41; + { + return; + } + endif41:; + unsigned int _t209; + _t209 = self->arrLen; + unsigned int _t210; + _t210 = self->arrCap; + _t211 = (_t209 >= _t210); + if (!_t211) goto endif43; + { + unsigned int arrNewCap; + unsigned int _t212; + _t212 = self->arrCap; + arrNewCap = _t212; + _t213 = (arrNewCap == 0); + if (!_t213) goto else44; + { + self->arrCap = 4; + /* sizeof(JsonValue) */ + _t215 = 4 * sizeof(JsonValue); + void* _t216; + _t216 = Alloc(_t215); + _t217 = (JsonValue*)_t216; + self->arrData = _t217; + } + goto endif45; + else44:; + { + unsigned int doubleCap; + _t218 = arrNewCap * 2; + doubleCap = _t218; + self->arrCap = doubleCap; + JsonValue* _t219; + _t219 = self->arrData; + _t220 = (void*)_t219; + /* sizeof(JsonValue) */ + _t222 = doubleCap * sizeof(JsonValue); + void* _t223; + _t223 = Realloc(_t220, _t222); + _t224 = (JsonValue*)_t223; + self->arrData = _t224; + } + endif45:; + } + endif43:; + JsonValue* _t225; + _t225 = self->arrData; + unsigned int _t226; + _t226 = self->arrLen; + _t225[_t226] = val; + unsigned int _t227; + _t227 = self->arrLen; + _t228 = _t227 + 1; + self->arrLen = _t228; +} + +unsigned int Json_ObjectLen(JsonValue v) { + int _t230; + int _t229; + _t229 = v.tag; + _t230 = (_t229 != JsonTagObject); + if (!_t230) goto endif47; + { + return 0; + } + endif47:; + unsigned int _t231; + _t231 = v.objLen; + return _t231; +} + +JsonValue Json_ObjectGet(JsonValue v, const char* key) { + int _t233; + int _t236; + int _t242; + int _t232; + _t232 = v.tag; + _t233 = (_t232 != JsonTagObject); + if (!_t233) goto endif49; + { + JsonValue _t234; + _t234 = Json_Null(); + return _t234; + } + endif49:; + unsigned int i; + i = 0; + while50:; + unsigned int _t235; + _t235 = v.objLen; + _t236 = (i < _t235); + if (!_t236) goto wend52; + { + const char** _t237; + _t237 = v.objKeys; + const char* _t238; + _t238 = _t237[i]; + bool _t239; + _t239 = String_Eq(_t238, key); + if (!_t239) goto endif54; + { + JsonValue* _t240; + _t240 = v.objValues; + JsonValue _t241; + _t241 = _t240[i]; + return _t241; + } + endif54:; + _t242 = i + 1; + i = _t242; + } + goto while50; + wend52:; + JsonValue _t243; + _t243 = Json_Null(); + return _t243; +} + +bool Json_ObjectHas(JsonValue v, const char* key) { + int _t245; + int _t247; + int _t251; + int _t244; + _t244 = v.tag; + _t245 = (_t244 != JsonTagObject); + if (!_t245) goto endif56; + { + return 0; + } + endif56:; + unsigned int i; + i = 0; + while57:; + unsigned int _t246; + _t246 = v.objLen; + _t247 = (i < _t246); + if (!_t247) goto wend59; + { + const char** _t248; + _t248 = v.objKeys; + const char* _t249; + _t249 = _t248[i]; + bool _t250; + _t250 = String_Eq(_t249, key); + if (!_t250) goto endif61; + { + return 1; + } + endif61:; + _t251 = i + 1; + i = _t251; + } + goto while57; + wend59:; + return 0; +} + +void Json_ObjectSet(JsonValue* self, const char* key, JsonValue val) { + int _t253; + int _t255; + int _t260; + int _t263; + int _t265; + int _t267; + const char** _t269; + int _t271; + JsonValue* _t273; + int _t274; + void* _t276; + int _t278; + const char** _t280; + void* _t282; + int _t284; + JsonValue* _t286; + int _t292; + int _t252; + _t252 = self->tag; + _t253 = (_t252 != JsonTagObject); + if (!_t253) goto endif63; + { + return; + } + endif63:; + unsigned int i; + i = 0; + while64:; + unsigned int _t254; + _t254 = self->objLen; + _t255 = (i < _t254); + if (!_t255) goto wend66; + { + const char** _t256; + _t256 = self->objKeys; + const char* _t257; + _t257 = _t256[i]; + bool _t258; + _t258 = String_Eq(_t257, key); + if (!_t258) goto endif68; + { + JsonValue* _t259; + _t259 = self->objValues; + _t259[i] = val; + return; + } + endif68:; + _t260 = i + 1; + i = _t260; + } + goto while64; + wend66:; + unsigned int _t261; + _t261 = self->objLen; + unsigned int _t262; + _t262 = self->objCap; + _t263 = (_t261 >= _t262); + if (!_t263) goto endif70; + { + unsigned int objNewCap; + unsigned int _t264; + _t264 = self->objCap; + objNewCap = _t264; + _t265 = (objNewCap == 0); + if (!_t265) goto else71; + { + self->objCap = 4; + /* sizeof(const char*) */ + _t267 = 4 * sizeof(const char*); + void* _t268; + _t268 = Alloc(_t267); + _t269 = (const char**)_t268; + self->objKeys = _t269; + /* sizeof(JsonValue) */ + _t271 = 4 * sizeof(JsonValue); + void* _t272; + _t272 = Alloc(_t271); + _t273 = (JsonValue*)_t272; + self->objValues = _t273; + } + goto endif72; + else71:; + { + unsigned int doubleCap; + _t274 = objNewCap * 2; + doubleCap = _t274; + self->objCap = doubleCap; + const char** _t275; + _t275 = self->objKeys; + _t276 = (void*)_t275; + /* sizeof(const char*) */ + _t278 = doubleCap * sizeof(const char*); + void* _t279; + _t279 = Realloc(_t276, _t278); + _t280 = (const char**)_t279; + self->objKeys = _t280; + JsonValue* _t281; + _t281 = self->objValues; + _t282 = (void*)_t281; + /* sizeof(JsonValue) */ + _t284 = doubleCap * sizeof(JsonValue); + void* _t285; + _t285 = Realloc(_t282, _t284); + _t286 = (JsonValue*)_t285; + self->objValues = _t286; + } + endif72:; + } + endif70:; + const char** _t287; + _t287 = self->objKeys; + unsigned int _t288; + _t288 = self->objLen; + _t287[_t288] = key; + JsonValue* _t289; + _t289 = self->objValues; + unsigned int _t290; + _t290 = self->objLen; + _t289[_t290] = val; + unsigned int _t291; + _t291 = self->objLen; + _t292 = _t291 + 1; + self->objLen = _t292; +} + +bool Json_IsNull(JsonValue v) { + int _t294; + int _t293; + _t293 = v.tag; + _t294 = (_t293 == JsonTagNull); + return _t294; +} + +bool Json_AsBool(JsonValue v) { + int _t296; + int _t295; + _t295 = v.tag; + _t296 = (_t295 == JsonTagBool); + if (!_t296) goto endif74; + { + bool _t297; + _t297 = v.boolVal; + return _t297; + } + endif74:; + return 0; +} + +double Json_AsNumber(JsonValue v) { + int _t299; + int _t298; + _t298 = v.tag; + _t299 = (_t298 == JsonTagNumber); + if (!_t299) goto endif76; + { + double _t300; + _t300 = v.numVal; + return _t300; + } + endif76:; + return 0.0; +} + +const char* Json_AsString(JsonValue v) { + int _t302; + int _t301; + _t301 = v.tag; + _t302 = (_t301 == JsonTagString); + if (!_t302) goto endif78; + { + const char* _t303; + _t303 = v.strVal; + return _t303; + } + endif78:; + return ""; +} + +int JsonParser_Peek(JsonParser* p) { + int _t306; + int _t310; + unsigned int _t304; + _t304 = p->pos; + unsigned int _t305; + _t305 = p->len; + _t306 = (_t304 >= _t305); + if (!_t306) goto endif80; + { + return 0; + } + endif80:; + const char* _t307; + _t307 = p->src; + unsigned int _t308; + _t308 = p->pos; + int _t309; + _t309 = _t307[_t308]; + _t310 = (int)_t309; + return _t310; +} + +void JsonParser_Advance(JsonParser* p) { + int _t313; + int _t315; + unsigned int _t311; + _t311 = p->pos; + unsigned int _t312; + _t312 = p->len; + _t313 = (_t311 < _t312); + if (!_t313) goto endif82; + { + unsigned int _t314; + _t314 = p->pos; + _t315 = _t314 + 1; + p->pos = _t315; + } + endif82:; +} + +void JsonParser_SkipWhitespace(JsonParser* p) { + int _t317; + int _t318; + int _t320; + int _t322; + while83:; + if (!1) goto wend85; + { + int c; + int _t316; + _t316 = JsonParser_Peek(p); + c = _t316; + bool __or_tmp_1; + bool __or_tmp_2; + bool __or_tmp_3; + _t317 = (c == 32); + if (!_t317) goto else86; + *(bool*)&__or_tmp_3 = 1; + goto endif87; + else86:; + _t318 = (c == 9); + *(bool*)&__or_tmp_3 = _t318; + endif87:; + bool _t319; + _t319 = *(bool*)&__or_tmp_3; + if (!_t319) goto else88; + *(bool*)&__or_tmp_2 = 1; + goto endif89; + else88:; + _t320 = (c == 10); + *(bool*)&__or_tmp_2 = _t320; + endif89:; + bool _t321; + _t321 = *(bool*)&__or_tmp_2; + if (!_t321) goto else90; + *(bool*)&__or_tmp_1 = 1; + goto endif91; + else90:; + _t322 = (c == 13); + *(bool*)&__or_tmp_1 = _t322; + endif91:; + bool _t323; + _t323 = *(bool*)&__or_tmp_1; + if (!_t323) goto else92; + { + JsonParser_Advance(p); + } + goto endif93; + else92:; + { + return; + } + endif93:; + } + goto while83; + wend85:; +} + +bool JsonParser_Match(JsonParser* p, const char* expected) { + int _t326; + int _t328; + int _t329; + int _t332; + int _t335; + int _t336; + int _t338; + unsigned int elen; + unsigned int _t324; + _t324 = String_Len(expected); + elen = _t324; + unsigned int _t325; + _t325 = p->pos; + _t326 = _t325 + elen; + unsigned int _t327; + _t327 = p->len; + _t328 = (_t326 > _t327); + if (!_t328) goto endif95; + { + return 0; + } + endif95:; + unsigned int i; + i = 0; + while96:; + _t329 = (i < elen); + if (!_t329) goto wend98; + { + const char* _t330; + _t330 = p->src; + unsigned int _t331; + _t331 = p->pos; + _t332 = _t331 + i; + int _t333; + _t333 = _t330[_t332]; + int _t334; + _t334 = expected[i]; + _t335 = (_t333 != _t334); + if (!_t335) goto endif100; + { + return 0; + } + endif100:; + _t336 = i + 1; + i = _t336; + } + goto while96; + wend98:; + unsigned int _t337; + _t337 = p->pos; + _t338 = _t337 + elen; + p->pos = _t338; + return 1; +} + +const char* JsonParser_ParseString(JsonParser* p) { + int _t340; + int _t343; + int _t344; + int _t346; + int _t348; + void* _t349; + int _t350; + void* _t351; + char _t352; + int _t353; + void* _t354; + char _t355; + int _t356; + void* _t357; + char _t358; + int _t359; + void* _t360; + char _t361; + int _t362; + void* _t363; + char _t364; + int _t365; + void* _t366; + char _t367; + int _t368; + void* _t369; + char _t370; + void* _t371; + char _t372; + void* _t373; + char _t374; + void* _t375; + char _t376; + int _t378; + void* _t379; + void* _t380; + void* _t382; + int _t339; + _t339 = JsonParser_Peek(p); + _t340 = (_t339 != 34); + if (!_t340) goto endif102; + { + p->error = "Expected string"; + return ""; + } + endif102:; + JsonParser_Advance(p); + StringBuilder sb; + StringBuilder _t341; + _t341 = StringBuilder_New(); + sb = _t341; + while103:; + if (!1) goto wend105; + { + int c; + int _t342; + _t342 = JsonParser_Peek(p); + c = _t342; + bool __or_tmp_4; + _t343 = (c == 0); + if (!_t343) goto else106; + *(bool*)&__or_tmp_4 = 1; + goto endif107; + else106:; + _t344 = (c == 34); + *(bool*)&__or_tmp_4 = _t344; + endif107:; + bool _t345; + _t345 = *(bool*)&__or_tmp_4; + if (!_t345) goto endif109; + { + goto wend105; + } + endif109:; + _t346 = (c == 92); + if (!_t346) goto else110; + { + JsonParser_Advance(p); + int esc; + int _t347; + _t347 = JsonParser_Peek(p); + esc = _t347; + _t348 = (esc == 0); + if (!_t348) goto endif113; + { + p->error = "Unterminated string escape"; + _t349 = &sb; + StringBuilder_Free(_t349); + return ""; + } + endif113:; + _t350 = (esc == 110); + if (!_t350) goto else114; + { + _t351 = &sb; + _t352 = (char)10; + StringBuilder_AppendChar(_t351, _t352); + } + goto endif115; + else114:; + _t353 = (esc == 116); + if (!_t353) goto else116; + { + _t354 = &sb; + _t355 = (char)9; + StringBuilder_AppendChar(_t354, _t355); + } + goto endif117; + else116:; + _t356 = (esc == 114); + if (!_t356) goto else118; + { + _t357 = &sb; + _t358 = (char)13; + StringBuilder_AppendChar(_t357, _t358); + } + goto endif119; + else118:; + _t359 = (esc == 98); + if (!_t359) goto else120; + { + _t360 = &sb; + _t361 = (char)8; + StringBuilder_AppendChar(_t360, _t361); + } + goto endif121; + else120:; + _t362 = (esc == 102); + if (!_t362) goto else122; + { + _t363 = &sb; + _t364 = (char)12; + StringBuilder_AppendChar(_t363, _t364); + } + goto endif123; + else122:; + _t365 = (esc == 34); + if (!_t365) goto else124; + { + _t366 = &sb; + _t367 = (char)34; + StringBuilder_AppendChar(_t366, _t367); + } + goto endif125; + else124:; + _t368 = (esc == 92); + if (!_t368) goto else126; + { + _t369 = &sb; + _t370 = (char)92; + StringBuilder_AppendChar(_t369, _t370); + } + goto endif127; + else126:; + { + _t371 = &sb; + _t372 = (char)92; + StringBuilder_AppendChar(_t371, _t372); + _t373 = &sb; + _t374 = (char)esc; + StringBuilder_AppendChar(_t373, _t374); + } + endif127:; + endif125:; + endif123:; + endif121:; + endif119:; + endif117:; + endif115:; + JsonParser_Advance(p); + } + goto endif111; + else110:; + { + _t375 = &sb; + _t376 = (char)c; + StringBuilder_AppendChar(_t375, _t376); + JsonParser_Advance(p); + } + endif111:; + } + goto while103; + wend105:; + int _t377; + _t377 = JsonParser_Peek(p); + _t378 = (_t377 != 34); + if (!_t378) goto endif129; + { + p->error = "Unterminated string"; + _t379 = &sb; + StringBuilder_Free(_t379); + return ""; + } + endif129:; + JsonParser_Advance(p); + const char* result; + _t380 = &sb; + const char* _t381; + _t381 = StringBuilder_Build(_t380); + result = _t381; + _t382 = &sb; + StringBuilder_Free(_t382); + return result; +} + +JsonValue JsonParser_ParseNumber(JsonParser* p) { + int _t385; + int _t387; + int _t388; + int _t391; + int _t393; + int _t394; + int _t398; + unsigned int start; + unsigned int _t383; + _t383 = p->pos; + start = _t383; + int c0; + int _t384; + _t384 = JsonParser_Peek(p); + c0 = _t384; + _t385 = (c0 == 45); + if (!_t385) goto endif131; + { + JsonParser_Advance(p); + } + endif131:; + while132:; + if (!1) goto wend134; + { + int c; + int _t386; + _t386 = JsonParser_Peek(p); + c = _t386; + bool __and_tmp_5; + _t387 = (c >= 48); + if (!_t387) goto else135; + _t388 = (c <= 57); + *(bool*)&__and_tmp_5 = _t388; + goto endif136; + else135:; + *(bool*)&__and_tmp_5 = 0; + endif136:; + bool _t389; + _t389 = *(bool*)&__and_tmp_5; + if (!_t389) goto else137; + { + JsonParser_Advance(p); + } + goto endif138; + else137:; + { + goto wend134; + } + endif138:; + } + goto while132; + wend134:; + int _t390; + _t390 = JsonParser_Peek(p); + _t391 = (_t390 == 46); + if (!_t391) goto endif140; + { + JsonParser_Advance(p); + while141:; + if (!1) goto wend143; + { + int c; + int _t392; + _t392 = JsonParser_Peek(p); + c = _t392; + bool __and_tmp_6; + _t393 = (c >= 48); + if (!_t393) goto else144; + _t394 = (c <= 57); + *(bool*)&__and_tmp_6 = _t394; + goto endif145; + else144:; + *(bool*)&__and_tmp_6 = 0; + endif145:; + bool _t395; + _t395 = *(bool*)&__and_tmp_6; + if (!_t395) goto else146; + { + JsonParser_Advance(p); + } + goto endif147; + else146:; + { + goto wend143; + } + endif147:; + } + goto while141; + wend143:; + } + endif140:; + const char* numStr; + const char* _t396; + _t396 = p->src; + unsigned int _t397; + _t397 = p->pos; + _t398 = _t397 - start; + const char* _t399; + _t399 = String_Slice(_t396, start, _t398); + numStr = _t399; + double n; + double _t400; + _t400 = String_ToFloat(numStr); + n = _t400; + JsonValue _t401; + _t401 = Json_Number(n); + return _t401; +} + +JsonValue JsonParser_ParseArray(JsonParser* p) { + int _t404; + int _t407; + void* _t409; + int _t411; + int _t412; + JsonParser_Advance(p); + JsonValue arr; + JsonValue _t402; + _t402 = Json_Array(); + arr = _t402; + JsonParser_SkipWhitespace(p); + int _t403; + _t403 = JsonParser_Peek(p); + _t404 = (_t403 == 93); + if (!_t404) goto endif149; + { + JsonParser_Advance(p); + return arr; + } + endif149:; + while150:; + if (!1) goto wend152; + { + JsonParser_SkipWhitespace(p); + JsonValue val; + JsonValue _t405; + _t405 = JsonParser_ParseValue(p); + val = _t405; + const char* _t406; + _t406 = p->error; + _t407 = (_t406 != ""); + if (!_t407) goto endif154; + { + JsonValue _t408; + _t408 = Json_Null(); + return _t408; + } + endif154:; + _t409 = &arr; + Json_ArrayPush(_t409, val); + JsonParser_SkipWhitespace(p); + int c; + int _t410; + _t410 = JsonParser_Peek(p); + c = _t410; + _t411 = (c == 93); + if (!_t411) goto endif156; + { + JsonParser_Advance(p); + return arr; + } + endif156:; + _t412 = (c == 44); + if (!_t412) goto else157; + { + JsonParser_Advance(p); + } + goto endif158; + else157:; + { + p->error = "Expected ',' or ']' in array"; + JsonValue _t413; + _t413 = Json_Null(); + return _t413; + } + endif158:; + } + goto while150; + wend152:; +} + +JsonValue JsonParser_ParseObject(JsonParser* p) { + int _t416; + int _t419; + int _t422; + int _t426; + void* _t428; + int _t430; + int _t431; + JsonParser_Advance(p); + JsonValue obj; + JsonValue _t414; + _t414 = Json_Object(); + obj = _t414; + JsonParser_SkipWhitespace(p); + int _t415; + _t415 = JsonParser_Peek(p); + _t416 = (_t415 == 125); + if (!_t416) goto endif160; + { + JsonParser_Advance(p); + return obj; + } + endif160:; + while161:; + if (!1) goto wend163; + { + JsonParser_SkipWhitespace(p); + const char* key; + const char* _t417; + _t417 = JsonParser_ParseString(p); + key = _t417; + const char* _t418; + _t418 = p->error; + _t419 = (_t418 != ""); + if (!_t419) goto endif165; + { + JsonValue _t420; + _t420 = Json_Null(); + return _t420; + } + endif165:; + JsonParser_SkipWhitespace(p); + int _t421; + _t421 = JsonParser_Peek(p); + _t422 = (_t421 != 58); + if (!_t422) goto endif167; + { + p->error = "Expected ':' after object key"; + JsonValue _t423; + _t423 = Json_Null(); + return _t423; + } + endif167:; + JsonParser_Advance(p); + JsonParser_SkipWhitespace(p); + JsonValue val; + JsonValue _t424; + _t424 = JsonParser_ParseValue(p); + val = _t424; + const char* _t425; + _t425 = p->error; + _t426 = (_t425 != ""); + if (!_t426) goto endif169; + { + JsonValue _t427; + _t427 = Json_Null(); + return _t427; + } + endif169:; + _t428 = &obj; + Json_ObjectSet(_t428, key, val); + JsonParser_SkipWhitespace(p); + int c; + int _t429; + _t429 = JsonParser_Peek(p); + c = _t429; + _t430 = (c == 125); + if (!_t430) goto endif171; + { + JsonParser_Advance(p); + return obj; + } + endif171:; + _t431 = (c == 44); + if (!_t431) goto else172; + { + JsonParser_Advance(p); + } + goto endif173; + else172:; + { + p->error = "Expected ',' or '}' in object"; + JsonValue _t432; + _t432 = Json_Null(); + return _t432; + } + endif173:; + } + goto while161; + wend163:; +} + +JsonValue JsonParser_ParseValue(JsonParser* p) { + int _t434; + int _t436; + int _t439; + int _t441; + int _t443; + int _t447; + int _t451; + int _t455; + int _t456; + int _t458; + JsonParser_SkipWhitespace(p); + int c; + int _t433; + _t433 = JsonParser_Peek(p); + c = _t433; + _t434 = (c == 0); + if (!_t434) goto endif175; + { + p->error = "Unexpected end of input"; + JsonValue _t435; + _t435 = Json_Null(); + return _t435; + } + endif175:; + _t436 = (c == 34); + if (!_t436) goto endif177; + { + const char* _t437; + _t437 = JsonParser_ParseString(p); + JsonValue _t438; + _t438 = Json_String(_t437); + return _t438; + } + endif177:; + _t439 = (c == 123); + if (!_t439) goto endif179; + { + JsonValue _t440; + _t440 = JsonParser_ParseObject(p); + return _t440; + } + endif179:; + _t441 = (c == 91); + if (!_t441) goto endif181; + { + JsonValue _t442; + _t442 = JsonParser_ParseArray(p); + return _t442; + } + endif181:; + _t443 = (c == 116); + if (!_t443) goto endif183; + { + bool _t444; + _t444 = JsonParser_Match(p, "true"); + if (!_t444) goto endif185; + { + JsonValue _t445; + _t445 = Json_Bool(1); + return _t445; + } + endif185:; + p->error = "Expected 'true'"; + JsonValue _t446; + _t446 = Json_Null(); + return _t446; + } + endif183:; + _t447 = (c == 102); + if (!_t447) goto endif187; + { + bool _t448; + _t448 = JsonParser_Match(p, "false"); + if (!_t448) goto endif189; + { + JsonValue _t449; + _t449 = Json_Bool(0); + return _t449; + } + endif189:; + p->error = "Expected 'false'"; + JsonValue _t450; + _t450 = Json_Null(); + return _t450; + } + endif187:; + _t451 = (c == 110); + if (!_t451) goto endif191; + { + bool _t452; + _t452 = JsonParser_Match(p, "null"); + if (!_t452) goto endif193; + { + JsonValue _t453; + _t453 = Json_Null(); + return _t453; + } + endif193:; + p->error = "Expected 'null'"; + JsonValue _t454; + _t454 = Json_Null(); + return _t454; + } + endif191:; + bool __or_tmp_7; + bool __and_tmp_8; + _t455 = (c >= 48); + if (!_t455) goto else194; + _t456 = (c <= 57); + *(bool*)&__and_tmp_8 = _t456; + goto endif195; + else194:; + *(bool*)&__and_tmp_8 = 0; + endif195:; + bool _t457; + _t457 = *(bool*)&__and_tmp_8; + if (!_t457) goto else196; + *(bool*)&__or_tmp_7 = 1; + goto endif197; + else196:; + _t458 = (c == 45); + *(bool*)&__or_tmp_7 = _t458; + endif197:; + bool _t459; + _t459 = *(bool*)&__or_tmp_7; + if (!_t459) goto endif199; + { + JsonValue _t460; + _t460 = JsonParser_ParseNumber(p); + return _t460; + } + endif199:; + p->error = "Unexpected character"; + JsonValue _t461; + _t461 = Json_Null(); + return _t461; +} + +JsonValue Json_Parse(const char* s) { + JsonParser _t463; + void* _t464; + void* _t466; + int _t468; + int _t471; + JsonParser p; + unsigned int _t462; + _t462 = String_Len(s); + _t463 = (JsonParser){.src = s, .pos = 0, .len = _t462, .error = ""}; + p = _t463; + JsonValue result; + _t464 = &p; + JsonValue _t465; + _t465 = JsonParser_ParseValue(_t464); + result = _t465; + _t466 = &p; + JsonParser_SkipWhitespace(_t466); + bool __and_tmp_9; + const char* _t467; + _t467 = p.error; + _t468 = (_t467 == ""); + if (!_t468) goto else200; + unsigned int _t469; + _t469 = p.pos; + unsigned int _t470; + _t470 = p.len; + _t471 = (_t469 != _t470); + *(bool*)&__and_tmp_9 = _t471; + goto endif201; + else200:; + *(bool*)&__and_tmp_9 = 0; + endif201:; + bool _t472; + _t472 = *(bool*)&__and_tmp_9; + if (!_t472) goto endif203; + { + p.error = "Trailing data after JSON value"; + JsonValue _t473; + _t473 = Json_Null(); + return _t473; + } + endif203:; + return result; +} + +void Json_StringifyImpl(StringBuilder* sb, JsonValue v) { + int _t475; + int _t477; + int _t480; + int _t483; + char _t484; + char _t486; + int _t488; + char _t489; + int _t491; + int _t492; + char _t493; + int _t496; + char _t497; + int _t499; + char _t500; + int _t502; + int _t503; + char _t504; + char _t505; + char _t508; + char _t509; + int _t512; + char _t513; + int _t474; + _t474 = v.tag; + _t475 = (_t474 == JsonTagNull); + if (!_t475) goto endif205; + { + StringBuilder_Append(sb, "null"); + return; + } + endif205:; + int _t476; + _t476 = v.tag; + _t477 = (_t476 == JsonTagBool); + if (!_t477) goto endif207; + { + bool _t478; + _t478 = v.boolVal; + if (!_t478) goto else208; + { + StringBuilder_Append(sb, "true"); + } + goto endif209; + else208:; + { + StringBuilder_Append(sb, "false"); + } + endif209:; + return; + } + endif207:; + int _t479; + _t479 = v.tag; + _t480 = (_t479 == JsonTagNumber); + if (!_t480) goto endif211; + { + double _t481; + _t481 = v.numVal; + StringBuilder_AppendFloat(sb, _t481); + return; + } + endif211:; + int _t482; + _t482 = v.tag; + _t483 = (_t482 == JsonTagString); + if (!_t483) goto endif213; + { + _t484 = (char)34; + StringBuilder_AppendChar(sb, _t484); + const char* _t485; + _t485 = v.strVal; + StringBuilder_Append(sb, _t485); + _t486 = (char)34; + StringBuilder_AppendChar(sb, _t486); + return; + } + endif213:; + int _t487; + _t487 = v.tag; + _t488 = (_t487 == JsonTagArray); + if (!_t488) goto endif215; + { + _t489 = (char)91; + StringBuilder_AppendChar(sb, _t489); + unsigned int i; + i = 0; + while216:; + unsigned int _t490; + _t490 = v.arrLen; + _t491 = (i < _t490); + if (!_t491) goto wend218; + { + _t492 = (i > 0); + if (!_t492) goto endif220; + { + _t493 = (char)44; + StringBuilder_AppendChar(sb, _t493); + } + endif220:; + JsonValue* _t494; + _t494 = v.arrData; + JsonValue _t495; + _t495 = _t494[i]; + Json_StringifyImpl(sb, _t495); + _t496 = i + 1; + i = _t496; + } + goto while216; + wend218:; + _t497 = (char)93; + StringBuilder_AppendChar(sb, _t497); + return; + } + endif215:; + int _t498; + _t498 = v.tag; + _t499 = (_t498 == JsonTagObject); + if (!_t499) goto endif222; + { + _t500 = (char)123; + StringBuilder_AppendChar(sb, _t500); + unsigned int i; + i = 0; + while223:; + unsigned int _t501; + _t501 = v.objLen; + _t502 = (i < _t501); + if (!_t502) goto wend225; + { + _t503 = (i > 0); + if (!_t503) goto endif227; + { + _t504 = (char)44; + StringBuilder_AppendChar(sb, _t504); + } + endif227:; + _t505 = (char)34; + StringBuilder_AppendChar(sb, _t505); + const char** _t506; + _t506 = v.objKeys; + const char* _t507; + _t507 = _t506[i]; + StringBuilder_Append(sb, _t507); + _t508 = (char)34; + StringBuilder_AppendChar(sb, _t508); + _t509 = (char)58; + StringBuilder_AppendChar(sb, _t509); + JsonValue* _t510; + _t510 = v.objValues; + JsonValue _t511; + _t511 = _t510[i]; + Json_StringifyImpl(sb, _t511); + _t512 = i + 1; + i = _t512; + } + goto while223; + wend225:; + _t513 = (char)125; + StringBuilder_AppendChar(sb, _t513); + return; + } + endif222:; +} + +const char* Json_Stringify(JsonValue v) { + void* _t515; + void* _t516; + StringBuilder sb; + StringBuilder _t514; + _t514 = StringBuilder_New(); + sb = _t514; + _t515 = &sb; + Json_StringifyImpl(_t515, v); + _t516 = &sb; + const char* _t517; + _t517 = StringBuilder_Build(_t516); + return _t517; +} + +unsigned int String_Len(const char* s) { + unsigned int _t518; + _t518 = bux_strlen(s); + return _t518; +} + +bool String_IsNull(const char* s) { + int _t520; + int _t519; + _t519 = bux_str_is_null(s); + _t520 = (_t519 != 0); + return _t520; +} + +bool String_Eq(const char* a, const char* b) { + int _t522; + int _t521; + _t521 = bux_strcmp(a, b); + _t522 = (_t521 == 0); + return _t522; +} + +const char* String_Concat(const char* a, const char* b) { + int _t525; + int _t526; + char* _t528; + unsigned int len_a; + unsigned int _t523; + _t523 = bux_strlen(a); + len_a = _t523; + unsigned int len_b; + unsigned int _t524; + _t524 = bux_strlen(b); + len_b = _t524; + unsigned int total; + _t525 = len_a + len_b; + _t526 = _t525 + 1; + total = _t526; + char* buf; + void* _t527; + _t527 = bux_alloc(total); + _t528 = (char*)_t527; + buf = _t528; + bux_strcpy(buf, a); + bux_strcat(buf, b); + return buf; +} + +const char* String_Copy(const char* s) { + int _t530; + char* _t532; + unsigned int len; + unsigned int _t529; + _t529 = bux_strlen(s); + len = _t529; + char* buf; + _t530 = len + 1; + void* _t531; + _t531 = bux_alloc(_t530); + _t532 = (char*)_t531; + buf = _t532; + bux_strcpy(buf, s); + return buf; +} + +bool String_StartsWith(const char* s, const char* prefix) { + int _t535; + int _t537; + unsigned int s_len; + unsigned int _t533; + _t533 = bux_strlen(s); + s_len = _t533; + unsigned int p_len; + unsigned int _t534; + _t534 = bux_strlen(prefix); + p_len = _t534; + _t535 = (p_len > s_len); + if (!_t535) goto endif229; + { + return 0; + } + endif229:; + int r; + int _t536; + _t536 = bux_strncmp(s, prefix, p_len); + r = _t536; + _t537 = (r == 0); + return _t537; +} + +bool String_EndsWith(const char* s, const char* suffix) { + int _t540; + int _t541; + int _t544; + unsigned int s_len; + unsigned int _t538; + _t538 = bux_strlen(s); + s_len = _t538; + unsigned int suf_len; + unsigned int _t539; + _t539 = bux_strlen(suffix); + suf_len = _t539; + _t540 = (suf_len > s_len); + if (!_t540) goto endif231; + { + return 0; + } + endif231:; + unsigned int start; + _t541 = s_len - suf_len; + start = _t541; + const char* tail; + const char* _t542; + _t542 = bux_str_slice(s, start, suf_len); + tail = _t542; + bool eq; + int _t543; + _t543 = bux_strcmp(tail, suffix); + _t544 = (_t543 == 0); + eq = _t544; + return eq; +} + +bool String_Contains(const char* s, const char* substr) { + int _t546; + int r; + int _t545; + _t545 = bux_str_contains(s, substr); + r = _t545; + _t546 = (r != 0); + return _t546; +} + +const char* String_Slice(const char* s, unsigned int start, unsigned int len) { + const char* _t547; + _t547 = bux_str_slice(s, start, len); + return _t547; +} + +const char* String_Trim(const char* s) { + const char* _t548; + _t548 = bux_str_trim(s); + return _t548; +} + +const char* String_TrimLeft(const char* s) { + const char* _t549; + _t549 = bux_str_trim_left(s); + return _t549; +} + +const char* String_TrimRight(const char* s) { + const char* _t550; + _t550 = bux_str_trim_right(s); + return _t550; +} + +const char* String_FromInt(int64_t n) { + const char* _t551; + _t551 = bux_int_to_str(n); + return _t551; +} + +int64_t String_ToInt(const char* s) { + int64_t _t552; + _t552 = bux_str_to_int(s); + return _t552; +} + +StringBuilder StringBuilder_New(void) { + StringBuilder _t554; + void* _t553; + _t553 = bux_sb_new(64); + _t554 = (StringBuilder){.handle = _t553}; + return _t554; +} + +StringBuilder StringBuilder_NewCap(unsigned int cap) { + StringBuilder _t556; + void* _t555; + _t555 = bux_sb_new(cap); + _t556 = (StringBuilder){.handle = _t555}; + return _t556; +} + +void StringBuilder_Append(StringBuilder* sb, const char* s) { + void* _t557; + _t557 = sb->handle; + bux_sb_append(_t557, s); +} + +void StringBuilder_AppendInt(StringBuilder* sb, int64_t n) { + void* _t558; + _t558 = sb->handle; + bux_sb_append_int(_t558, n); +} + +void StringBuilder_AppendFloat(StringBuilder* sb, double f) { + void* _t559; + _t559 = sb->handle; + bux_sb_append_float(_t559, f); +} + +void StringBuilder_AppendChar(StringBuilder* sb, char c) { + void* _t560; + _t560 = sb->handle; + bux_sb_append_char(_t560, c); +} + +const char* StringBuilder_Build(StringBuilder* sb) { + void* _t561; + _t561 = sb->handle; + const char* _t562; + _t562 = bux_sb_build(_t561); + return _t562; +} + +void StringBuilder_Free(StringBuilder* sb) { + void* _t563; + _t563 = sb->handle; + bux_sb_free(_t563); +} + +unsigned int String_SplitCount(const char* s, const char* delim) { + unsigned int _t564; + _t564 = bux_str_split_count(s, delim); + return _t564; +} + +const char* String_SplitPart(const char* s, const char* delim, unsigned int index) { + const char* _t565; + _t565 = bux_str_split_part(s, delim, index); + return _t565; +} + +const char* String_Join2(const char* a, const char* b, const char* sep) { + const char* _t566; + _t566 = bux_str_join2(a, b, sep); + return _t566; +} + +const char* String_Chars(const char* s, unsigned int index) { + const char* _t567; + _t567 = bux_str_slice(s, index, 1); + return _t567; +} + +const char* String_Find(const char* haystack, const char* needle) { + const char* _t568; + _t568 = bux_strstr(haystack, needle); + return _t568; +} + +unsigned int String_Offset(const char* pos, const char* base) { + unsigned int _t569; + _t569 = bux_str_offset(pos, base); + return _t569; +} + +const char* String_Replace(const char* s, const char* old, const char* new) { + int _t575; + int _t577; + int _t578; + const char* pos; + const char* _t570; + _t570 = bux_strstr(s, old); + pos = _t570; + bool _t571; + _t571 = String_IsNull(pos); + if (!_t571) goto endif233; + { + return s; + } + endif233:; + unsigned int oldLen; + unsigned int _t572; + _t572 = bux_strlen(old); + oldLen = _t572; + unsigned int prefixLen; + unsigned int _t573; + _t573 = String_Offset(pos, s); + prefixLen = _t573; + const char* prefix; + const char* _t574; + _t574 = bux_str_slice(s, 0, prefixLen); + prefix = _t574; + const char* suffix; + _t575 = prefixLen + oldLen; + unsigned int _t576; + _t576 = bux_strlen(s); + _t577 = _t576 - prefixLen; + _t578 = _t577 - oldLen; + const char* _t579; + _t579 = bux_str_slice(s, _t575, _t578); + suffix = _t579; + const char* temp; + const char* _t580; + _t580 = String_Concat(prefix, new); + temp = _t580; + const char* result; + const char* _t581; + _t581 = String_Concat(temp, suffix); + result = _t581; + return result; +} + +double String_ToFloat(const char* s) { + double _t582; + _t582 = bux_str_to_float(s); + return _t582; +} + +const char* String_FromBool(bool b) { + if (!b) goto endif235; + { + return "true"; + } + endif235:; + return "false"; +} + +const char* String_FromFloat(double f) { + const char* _t583; + _t583 = bux_float_to_string(f); + return _t583; +} + +const char* String_Format1(const char* pattern, const char* a0) { + const char* _t584; + _t584 = bux_str_format(pattern, a0, "", "", "", "", "", "", ""); + return _t584; +} + +const char* String_Format2(const char* pattern, const char* a0, const char* a1) { + const char* _t585; + _t585 = bux_str_format(pattern, a0, a1, "", "", "", "", "", ""); + return _t585; +} + +const char* String_Format3(const char* pattern, const char* a0, const char* a1, const char* a2) { + const char* _t586; + _t586 = bux_str_format(pattern, a0, a1, a2, "", "", "", "", ""); + return _t586; +} + +const char* Hash_Sha1(const char* data) { + int _t588; + int len; + unsigned int _t587; + _t587 = String_Len(data); + _t588 = (int)_t587; + len = _t588; + void* buf; + void* _t589; + _t589 = Alloc(20); + buf = _t589; + bux_sha1(data, len, buf); + const char* result; + const char* _t590; + _t590 = bux_bytes_to_hex(buf, 20); + result = _t590; + Free(buf); + return result; +} + +const char* Hash_Sha256(const char* data) { + int _t592; + int len; + unsigned int _t591; + _t591 = String_Len(data); + _t592 = (int)_t591; + len = _t592; + void* buf; + void* _t593; + _t593 = Alloc(32); + buf = _t593; + bux_sha256(data, len, buf); + const char* result; + const char* _t594; + _t594 = bux_bytes_to_hex(buf, 32); + result = _t594; + Free(buf); + return result; +} + +const char* Hash_Sha384(const char* data) { + int _t596; + int len; + unsigned int _t595; + _t595 = String_Len(data); + _t596 = (int)_t595; + len = _t596; + void* buf; + void* _t597; + _t597 = Alloc(48); + buf = _t597; + bux_sha384(data, len, buf); + const char* result; + const char* _t598; + _t598 = bux_bytes_to_hex(buf, 48); + result = _t598; + Free(buf); + return result; +} + +const char* Hash_Sha512(const char* data) { + int _t600; + int len; + unsigned int _t599; + _t599 = String_Len(data); + _t600 = (int)_t599; + len = _t600; + void* buf; + void* _t601; + _t601 = Alloc(64); + buf = _t601; + bux_sha512(data, len, buf); + const char* result; + const char* _t602; + _t602 = bux_bytes_to_hex(buf, 64); + result = _t602; + Free(buf); + return result; +} + +void Hash_Sha256Raw(const char* data, void* out) { + int _t604; + unsigned int _t603; + _t603 = String_Len(data); + _t604 = (int)_t603; + bux_sha256(data, _t604, out); +} + +void Hash_Sha384Raw(const char* data, void* out) { + int _t606; + unsigned int _t605; + _t605 = String_Len(data); + _t606 = (int)_t605; + bux_sha384(data, _t606, out); +} + +void Hash_Sha512Raw(const char* data, void* out) { + int _t608; + unsigned int _t607; + _t607 = String_Len(data); + _t608 = (int)_t607; + bux_sha512(data, _t608, out); +} + +int Hash_Sha1Size(void) { + return 20; +} + +int Hash_Sha256Size(void) { + return 32; +} + +int Hash_Sha384Size(void) { + return 48; +} + +int Hash_Sha512Size(void) { + return 64; +} + +const char* Base64_Encode(const char* s) { + int _t610; + unsigned int _t609; + _t609 = String_Len(s); + _t610 = (int)_t609; + const char* _t611; + _t611 = bux_base64_encode(s, _t610); + return _t611; +} + +const char* Base64_Decode(const char* s) { + int _t613; + void* _t614; + int outlen; + outlen = 0; + unsigned int _t612; + _t612 = String_Len(s); + _t613 = (int)_t612; + _t614 = &outlen; + const char* _t615; + _t615 = bux_base64_decode(s, _t613, _t614); + return _t615; +} + +const char* Base64URL_Encode(const char* s) { + int _t617; + unsigned int _t616; + _t616 = String_Len(s); + _t617 = (int)_t616; + const char* _t618; + _t618 = bux_base64url_encode(s, _t617); + return _t618; +} + +const char* Base64URL_Decode(const char* s) { + int _t620; + void* _t621; + int outlen; + outlen = 0; + unsigned int _t619; + _t619 = String_Len(s); + _t620 = (int)_t619; + _t621 = &outlen; + const char* _t622; + _t622 = bux_base64url_decode(s, _t620, _t621); + return _t622; +} + +const char* Hmac_Sha256(const char* key, const char* message) { + int _t624; + int _t626; + int kl; + unsigned int _t623; + _t623 = String_Len(key); + _t624 = (int)_t623; + kl = _t624; + int ml; + unsigned int _t625; + _t625 = String_Len(message); + _t626 = (int)_t625; + ml = _t626; + void* buf; + void* _t627; + _t627 = Alloc(32); + buf = _t627; + bux_hmac_sha256(key, kl, message, ml, buf); + const char* result; + const char* _t628; + _t628 = bux_bytes_to_hex(buf, 32); + result = _t628; + Free(buf); + return result; +} + +void Hmac_Sha256Raw(const char* key, const char* message, void* out) { + int _t630; + int _t632; + unsigned int _t629; + _t629 = String_Len(key); + _t630 = (int)_t629; + unsigned int _t631; + _t631 = String_Len(message); + _t632 = (int)_t631; + bux_hmac_sha256(key, _t630, message, _t632, out); +} + +const char* Hmac_Sha256Base64(const char* key, const char* message) { + int _t634; + int _t636; + const char* _t638; + int kl; + unsigned int _t633; + _t633 = String_Len(key); + _t634 = (int)_t633; + kl = _t634; + int ml; + unsigned int _t635; + _t635 = String_Len(message); + _t636 = (int)_t635; + ml = _t636; + void* buf; + void* _t637; + _t637 = Alloc(32); + buf = _t637; + bux_hmac_sha256(key, kl, message, ml, buf); + const char* result; + _t638 = (const char*)buf; + const char* _t639; + _t639 = bux_base64_encode(_t638, 32); + result = _t639; + Free(buf); + return result; +} + +const char* Hmac_Sha384(const char* key, const char* message) { + int _t641; + int _t643; + int kl; + unsigned int _t640; + _t640 = String_Len(key); + _t641 = (int)_t640; + kl = _t641; + int ml; + unsigned int _t642; + _t642 = String_Len(message); + _t643 = (int)_t642; + ml = _t643; + void* buf; + void* _t644; + _t644 = Alloc(48); + buf = _t644; + bux_hmac_sha384(key, kl, message, ml, buf); + const char* result; + const char* _t645; + _t645 = bux_bytes_to_hex(buf, 48); + result = _t645; + Free(buf); + return result; +} + +void Hmac_Sha384Raw(const char* key, const char* message, void* out) { + int _t647; + int _t649; + unsigned int _t646; + _t646 = String_Len(key); + _t647 = (int)_t646; + unsigned int _t648; + _t648 = String_Len(message); + _t649 = (int)_t648; + bux_hmac_sha384(key, _t647, message, _t649, out); +} + +const char* Hmac_Sha384Base64(const char* key, const char* message) { + int _t651; + int _t653; + const char* _t655; + int kl; + unsigned int _t650; + _t650 = String_Len(key); + _t651 = (int)_t650; + kl = _t651; + int ml; + unsigned int _t652; + _t652 = String_Len(message); + _t653 = (int)_t652; + ml = _t653; + void* buf; + void* _t654; + _t654 = Alloc(48); + buf = _t654; + bux_hmac_sha384(key, kl, message, ml, buf); + const char* result; + _t655 = (const char*)buf; + const char* _t656; + _t656 = bux_base64_encode(_t655, 48); + result = _t656; + Free(buf); + return result; +} + +const char* Hmac_Sha512(const char* key, const char* message) { + int _t658; + int _t660; + int kl; + unsigned int _t657; + _t657 = String_Len(key); + _t658 = (int)_t657; + kl = _t658; + int ml; + unsigned int _t659; + _t659 = String_Len(message); + _t660 = (int)_t659; + ml = _t660; + void* buf; + void* _t661; + _t661 = Alloc(64); + buf = _t661; + bux_hmac_sha512(key, kl, message, ml, buf); + const char* result; + const char* _t662; + _t662 = bux_bytes_to_hex(buf, 64); + result = _t662; + Free(buf); + return result; +} + +void Hmac_Sha512Raw(const char* key, const char* message, void* out) { + int _t664; + int _t666; + unsigned int _t663; + _t663 = String_Len(key); + _t664 = (int)_t663; + unsigned int _t665; + _t665 = String_Len(message); + _t666 = (int)_t665; + bux_hmac_sha512(key, _t664, message, _t666, out); +} + +const char* Hmac_Sha512Base64(const char* key, const char* message) { + int _t668; + int _t670; + const char* _t672; + int kl; + unsigned int _t667; + _t667 = String_Len(key); + _t668 = (int)_t667; + kl = _t668; + int ml; + unsigned int _t669; + _t669 = String_Len(message); + _t670 = (int)_t669; + ml = _t670; + void* buf; + void* _t671; + _t671 = Alloc(64); + buf = _t671; + bux_hmac_sha512(key, kl, message, ml, buf); + const char* result; + _t672 = (const char*)buf; + const char* _t673; + _t673 = bux_base64_encode(_t672, 64); + result = _t673; + Free(buf); + return result; +} + +const char* Random_Bytes(int n) { + int _t674; + unsigned int _t675; + int _t678; + const char* _t679; + _t674 = (n <= 0); + if (!_t674) goto endif237; + { + return ""; + } + endif237:; + void* buf; + _t675 = (unsigned int)n; + void* _t676; + _t676 = Alloc(_t675); + buf = _t676; + int _t677; + _t677 = bux_random_bytes(buf, n); + _t678 = (_t677 != 1); + if (!_t678) goto endif239; + { + Free(buf); + return ""; + } + endif239:; + _t679 = (const char*)buf; + return _t679; +} + +const char* Random_Hex(int n) { + int _t680; + unsigned int _t681; + int _t684; + _t680 = (n <= 0); + if (!_t680) goto endif241; + { + return ""; + } + endif241:; + void* buf; + _t681 = (unsigned int)n; + void* _t682; + _t682 = Alloc(_t681); + buf = _t682; + int _t683; + _t683 = bux_random_bytes(buf, n); + _t684 = (_t683 != 1); + if (!_t684) goto endif243; + { + Free(buf); + return ""; + } + endif243:; + const char* result; + const char* _t685; + _t685 = bux_bytes_to_hex(buf, n); + result = _t685; + Free(buf); + return result; +} + +const char* Random_Base64(int n) { + int _t686; + unsigned int _t687; + int _t690; + const char* _t691; + _t686 = (n <= 0); + if (!_t686) goto endif245; + { + return ""; + } + endif245:; + void* buf; + _t687 = (unsigned int)n; + void* _t688; + _t688 = Alloc(_t687); + buf = _t688; + int _t689; + _t689 = bux_random_bytes(buf, n); + _t690 = (_t689 != 1); + if (!_t690) goto endif247; + { + Free(buf); + return ""; + } + endif247:; + const char* result; + _t691 = (const char*)buf; + const char* _t692; + _t692 = bux_base64_encode(_t691, n); + result = _t692; + Free(buf); + return result; +} + +unsigned int Random_Uint32(void) { + int _t695; + unsigned int* _t696; + unsigned int _t697; + void* buf; + void* _t693; + _t693 = Alloc(4); + buf = _t693; + int _t694; + _t694 = bux_random_bytes(buf, 4); + _t695 = (_t694 != 1); + if (!_t695) goto endif249; + { + Free(buf); + return 0; + } + endif249:; + unsigned int* ptr; + _t696 = (unsigned int*)buf; + ptr = _t696; + unsigned int val; + _t697 = *ptr; + val = _t697; + Free(buf); + return val; +} + +const char* Aes_GenerateKey(void) { + unsigned int _t698; + int _t701; + const char* _t702; + void* buf; + _t698 = (unsigned int)AES_KEY_SIZE; + void* _t699; + _t699 = Alloc(_t698); + buf = _t699; + int _t700; + _t700 = bux_random_bytes(buf, AES_KEY_SIZE); + _t701 = (_t700 != 1); + if (!_t701) goto endif251; + { + Free(buf); + return ""; + } + endif251:; + _t702 = (const char*)buf; + return _t702; +} + +const char* Aes_GenerateIV(void) { + unsigned int _t703; + int _t706; + const char* _t707; + void* buf; + _t703 = (unsigned int)AES_IV_SIZE; + void* _t704; + _t704 = Alloc(_t703); + buf = _t704; + int _t705; + _t705 = bux_random_bytes(buf, AES_IV_SIZE); + _t706 = (_t705 != 1); + if (!_t706) goto endif253; + { + Free(buf); + return ""; + } + endif253:; + _t707 = (const char*)buf; + return _t707; +} + +const char* Aes_CbcEncrypt(const char* plain, const char* key, const char* iv) { + int _t709; + void* _t710; + int outlen; + outlen = 0; + unsigned int _t708; + _t708 = String_Len(plain); + _t709 = (int)_t708; + _t710 = &outlen; + const char* _t711; + _t711 = bux_aes_256_cbc_encrypt(plain, _t709, key, iv, _t710); + return _t711; +} + +const char* Aes_CbcDecrypt(const char* cipher, const char* key, const char* iv) { + int _t713; + void* _t714; + int outlen; + outlen = 0; + unsigned int _t712; + _t712 = String_Len(cipher); + _t713 = (int)_t712; + _t714 = &outlen; + const char* _t715; + _t715 = bux_aes_256_cbc_decrypt(cipher, _t713, key, iv, _t714); + return _t715; +} + +const char* Aes_GcmEncrypt(const char* plain, const char* key, const char* iv, void* tag) { + int _t717; + void* _t718; + int outlen; + outlen = 0; + unsigned int _t716; + _t716 = String_Len(plain); + _t717 = (int)_t716; + _t718 = &outlen; + const char* _t719; + _t719 = bux_aes_256_gcm_encrypt(plain, _t717, key, iv, tag, _t718); + return _t719; +} + +const char* Aes_GcmDecrypt(const char* cipher, const char* key, const char* iv, const char* tag) { + int _t721; + void* _t722; + int outlen; + outlen = 0; + unsigned int _t720; + _t720 = String_Len(cipher); + _t721 = (int)_t720; + _t722 = &outlen; + const char* _t723; + _t723 = bux_aes_256_gcm_decrypt(cipher, _t721, key, iv, tag, _t722); + return _t723; +} + +const char* Jwt_MakeHeader(JwtAlg alg) { + int _t724; + int _t725; + int _t726; + int _t727; + int _t728; + int _t729; + int _t730; + int _t731; + int _t732; + _t724 = (alg == JwtAlg_HS256); + if (!_t724) goto endif255; + { + return "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"; + } + endif255:; + _t725 = (alg == JwtAlg_HS384); + if (!_t725) goto endif257; + { + return "{\"alg\":\"HS384\",\"typ\":\"JWT\"}"; + } + endif257:; + _t726 = (alg == JwtAlg_HS512); + if (!_t726) goto endif259; + { + return "{\"alg\":\"HS512\",\"typ\":\"JWT\"}"; + } + endif259:; + _t727 = (alg == JwtAlg_RS256); + if (!_t727) goto endif261; + { + return "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; + } + endif261:; + _t728 = (alg == JwtAlg_RS384); + if (!_t728) goto endif263; + { + return "{\"alg\":\"RS384\",\"typ\":\"JWT\"}"; + } + endif263:; + _t729 = (alg == JwtAlg_RS512); + if (!_t729) goto endif265; + { + return "{\"alg\":\"RS512\",\"typ\":\"JWT\"}"; + } + endif265:; + _t730 = (alg == JwtAlg_ES256); + if (!_t730) goto endif267; + { + return "{\"alg\":\"ES256\",\"typ\":\"JWT\"}"; + } + endif267:; + _t731 = (alg == JwtAlg_ES384); + if (!_t731) goto endif269; + { + return "{\"alg\":\"ES384\",\"typ\":\"JWT\"}"; + } + endif269:; + _t732 = (alg == JwtAlg_EdDSA); + if (!_t732) goto endif271; + { + return "{\"alg\":\"EdDSA\",\"typ\":\"JWT\"}"; + } + endif271:; + return "{\"alg\":\"none\",\"typ\":\"JWT\"}"; +} + +const char* Jwt_Sign(JwtAlg alg, const char* signingInput, const char* key) { + int _t733; + const char* _t735; + int _t737; + const char* _t739; + int _t741; + const char* _t743; + int _t745; + int _t748; + int _t750; + int _t753; + int _t755; + int _t758; + int _t760; + int _t763; + int _t765; + int _t768; + int _t770; + _t733 = (alg == JwtAlg_HS256); + if (!_t733) goto endif273; + { + void* buf; + void* _t734; + _t734 = Alloc(32); + buf = _t734; + Hmac_Sha256Raw(key, signingInput, buf); + const char* result; + _t735 = (const char*)buf; + const char* _t736; + _t736 = bux_base64_encode(_t735, 32); + result = _t736; + Free(buf); + return result; + } + endif273:; + _t737 = (alg == JwtAlg_HS384); + if (!_t737) goto endif275; + { + void* buf; + void* _t738; + _t738 = Alloc(48); + buf = _t738; + Hmac_Sha384Raw(key, signingInput, buf); + const char* result; + _t739 = (const char*)buf; + const char* _t740; + _t740 = bux_base64_encode(_t739, 48); + result = _t740; + Free(buf); + return result; + } + endif275:; + _t741 = (alg == JwtAlg_HS512); + if (!_t741) goto endif277; + { + void* buf; + void* _t742; + _t742 = Alloc(64); + buf = _t742; + Hmac_Sha512Raw(key, signingInput, buf); + const char* result; + _t743 = (const char*)buf; + const char* _t744; + _t744 = bux_base64_encode(_t743, 64); + result = _t744; + Free(buf); + return result; + } + endif277:; + _t745 = (alg == JwtAlg_RS256); + if (!_t745) goto endif279; + { + const char* raw; + const char* _t746; + _t746 = Rsa_SignSha256(key, signingInput); + raw = _t746; + unsigned int _t747; + _t747 = String_Len(raw); + _t748 = (int)_t747; + const char* _t749; + _t749 = bux_base64_encode(raw, _t748); + return _t749; + } + endif279:; + _t750 = (alg == JwtAlg_RS384); + if (!_t750) goto endif281; + { + const char* raw; + const char* _t751; + _t751 = Rsa_SignSha384(key, signingInput); + raw = _t751; + unsigned int _t752; + _t752 = String_Len(raw); + _t753 = (int)_t752; + const char* _t754; + _t754 = bux_base64_encode(raw, _t753); + return _t754; + } + endif281:; + _t755 = (alg == JwtAlg_RS512); + if (!_t755) goto endif283; + { + const char* raw; + const char* _t756; + _t756 = Rsa_SignSha512(key, signingInput); + raw = _t756; + unsigned int _t757; + _t757 = String_Len(raw); + _t758 = (int)_t757; + const char* _t759; + _t759 = bux_base64_encode(raw, _t758); + return _t759; + } + endif283:; + _t760 = (alg == JwtAlg_ES256); + if (!_t760) goto endif285; + { + const char* raw; + const char* _t761; + _t761 = Ecdsa_SignP256(key, signingInput); + raw = _t761; + unsigned int _t762; + _t762 = String_Len(raw); + _t763 = (int)_t762; + const char* _t764; + _t764 = bux_base64_encode(raw, _t763); + return _t764; + } + endif285:; + _t765 = (alg == JwtAlg_ES384); + if (!_t765) goto endif287; + { + const char* raw; + const char* _t766; + _t766 = Ecdsa_SignP384(key, signingInput); + raw = _t766; + unsigned int _t767; + _t767 = String_Len(raw); + _t768 = (int)_t767; + const char* _t769; + _t769 = bux_base64_encode(raw, _t768); + return _t769; + } + endif287:; + _t770 = (alg == JwtAlg_EdDSA); + if (!_t770) goto endif289; + { + const char* _t771; + _t771 = Ed25519_Sign(key, signingInput); + return _t771; + } + endif289:; + return ""; +} + +bool Jwt_Verify(JwtAlg alg, const char* signingInput, const char* signatureB64, const char* key) { + int _t772; + const char* _t774; + int _t777; + const char* _t779; + int _t782; + const char* _t784; + int _t787; + int _t789; + int _t791; + int _t793; + int _t795; + int _t797; + _t772 = (alg == JwtAlg_HS256); + if (!_t772) goto endif291; + { + void* expectBuf; + void* _t773; + _t773 = Alloc(32); + expectBuf = _t773; + Hmac_Sha256Raw(key, signingInput, expectBuf); + const char* expectB64; + _t774 = (const char*)expectBuf; + const char* _t775; + _t775 = bux_base64_encode(_t774, 32); + expectB64 = _t775; + Free(expectBuf); + bool _t776; + _t776 = String_Eq(expectB64, signatureB64); + return _t776; + } + endif291:; + _t777 = (alg == JwtAlg_HS384); + if (!_t777) goto endif293; + { + void* expectBuf; + void* _t778; + _t778 = Alloc(48); + expectBuf = _t778; + Hmac_Sha384Raw(key, signingInput, expectBuf); + const char* expectB64; + _t779 = (const char*)expectBuf; + const char* _t780; + _t780 = bux_base64_encode(_t779, 48); + expectB64 = _t780; + Free(expectBuf); + bool _t781; + _t781 = String_Eq(expectB64, signatureB64); + return _t781; + } + endif293:; + _t782 = (alg == JwtAlg_HS512); + if (!_t782) goto endif295; + { + void* expectBuf; + void* _t783; + _t783 = Alloc(64); + expectBuf = _t783; + Hmac_Sha512Raw(key, signingInput, expectBuf); + const char* expectB64; + _t784 = (const char*)expectBuf; + const char* _t785; + _t785 = bux_base64_encode(_t784, 64); + expectB64 = _t785; + Free(expectBuf); + bool _t786; + _t786 = String_Eq(expectB64, signatureB64); + return _t786; + } + endif295:; + _t787 = (alg == JwtAlg_RS256); + if (!_t787) goto endif297; + { + bool _t788; + _t788 = Rsa_VerifySha256(key, signingInput, signatureB64); + return _t788; + } + endif297:; + _t789 = (alg == JwtAlg_RS384); + if (!_t789) goto endif299; + { + bool _t790; + _t790 = Rsa_VerifySha384(key, signingInput, signatureB64); + return _t790; + } + endif299:; + _t791 = (alg == JwtAlg_RS512); + if (!_t791) goto endif301; + { + bool _t792; + _t792 = Rsa_VerifySha512(key, signingInput, signatureB64); + return _t792; + } + endif301:; + _t793 = (alg == JwtAlg_ES256); + if (!_t793) goto endif303; + { + bool _t794; + _t794 = Ecdsa_VerifyP256(key, signingInput, signatureB64); + return _t794; + } + endif303:; + _t795 = (alg == JwtAlg_ES384); + if (!_t795) goto endif305; + { + bool _t796; + _t796 = Ecdsa_VerifyP384(key, signingInput, signatureB64); + return _t796; + } + endif305:; + _t797 = (alg == JwtAlg_EdDSA); + if (!_t797) goto endif307; + { + bool _t798; + _t798 = Ed25519_Verify(key, signatureB64, signingInput); + return _t798; + } + endif307:; + return 0; +} + +const char* Jwt_Encode(const char* headerJson, const char* payloadJson, JwtAlg alg, const char* key) { + const char* headerB64; + const char* _t799; + _t799 = Base64URL_Encode(headerJson); + headerB64 = _t799; + const char* payloadB64; + const char* _t800; + _t800 = Base64URL_Encode(payloadJson); + payloadB64 = _t800; + const char* signingInput; + const char* _t801; + _t801 = String_Concat(headerB64, "."); + signingInput = _t801; + const char* signingInputFull; + const char* _t802; + _t802 = String_Concat(signingInput, payloadB64); + signingInputFull = _t802; + const char* sigB64; + const char* _t803; + _t803 = Jwt_Sign(alg, signingInputFull, key); + sigB64 = _t803; + const char* part1; + const char* _t804; + _t804 = String_Concat(signingInputFull, "."); + part1 = _t804; + const char* _t805; + _t805 = String_Concat(part1, sigB64); + return _t805; +} + +bool Jwt_Decode(const char* token, JwtAlg alg, const char* key, const char** headerOut, const char** payloadOut) { + int _t807; + int _t814; + unsigned int partCount; + unsigned int _t806; + _t806 = bux_str_split_count(token, "."); + partCount = _t806; + _t807 = (partCount != 3); + if (!_t807) goto endif309; + { + return 0; + } + endif309:; + const char* headerB64; + const char* _t808; + _t808 = bux_str_split_part(token, ".", 0); + headerB64 = _t808; + const char* payloadB64; + const char* _t809; + _t809 = bux_str_split_part(token, ".", 1); + payloadB64 = _t809; + const char* sigB64; + const char* _t810; + _t810 = bux_str_split_part(token, ".", 2); + sigB64 = _t810; + const char* input; + const char* _t811; + _t811 = String_Concat(headerB64, "."); + input = _t811; + const char* signingInput; + const char* _t812; + _t812 = String_Concat(input, payloadB64); + signingInput = _t812; + bool _t813; + _t813 = Jwt_Verify(alg, signingInput, sigB64, key); + _t814 = !_t813; + if (!_t814) goto endif311; + { + return 0; + } + endif311:; + const char* _t815; + _t815 = Base64URL_Decode(headerB64); + headerOut[0] = _t815; + const char* _t816; + _t816 = Base64URL_Decode(payloadB64); + payloadOut[0] = _t816; + return 1; +} + +const char* Jwt_EncodeHS256(const char* payloadJson, const char* secret) { + const char* header; + const char* _t817; + _t817 = Jwt_MakeHeader(JwtAlg_HS256); + header = _t817; + const char* _t818; + _t818 = Jwt_Encode(header, payloadJson, JwtAlg_HS256, secret); + return _t818; +} + +const char* Jwt_EncodeHS384(const char* payloadJson, const char* secret) { + const char* header; + const char* _t819; + _t819 = Jwt_MakeHeader(JwtAlg_HS384); + header = _t819; + const char* _t820; + _t820 = Jwt_Encode(header, payloadJson, JwtAlg_HS384, secret); + return _t820; +} + +const char* Jwt_EncodeHS512(const char* payloadJson, const char* secret) { + const char* header; + const char* _t821; + _t821 = Jwt_MakeHeader(JwtAlg_HS512); + header = _t821; + const char* _t822; + _t822 = Jwt_Encode(header, payloadJson, JwtAlg_HS512, secret); + return _t822; +} + +const char* Jwt_EncodeRS256(const char* payloadJson, const char* pemPrivateKey) { + const char* header; + const char* _t823; + _t823 = Jwt_MakeHeader(JwtAlg_RS256); + header = _t823; + const char* _t824; + _t824 = Jwt_Encode(header, payloadJson, JwtAlg_RS256, pemPrivateKey); + return _t824; +} + +const char* Jwt_EncodeES256(const char* payloadJson, const char* pemPrivateKey) { + const char* header; + const char* _t825; + _t825 = Jwt_MakeHeader(JwtAlg_ES256); + header = _t825; + const char* _t826; + _t826 = Jwt_Encode(header, payloadJson, JwtAlg_ES256, pemPrivateKey); + return _t826; +} + +const char* Jwt_EncodeEdDSA(const char* payloadJson, const char* rawPrivKey) { + const char* header; + const char* _t827; + _t827 = Jwt_MakeHeader(JwtAlg_EdDSA); + header = _t827; + const char* _t828; + _t828 = Jwt_Encode(header, payloadJson, JwtAlg_EdDSA, rawPrivKey); + return _t828; +} + +const char* Ecdsa_SignP256(const char* pemPrivateKey, const char* data) { + int _t830; + int _t832; + void* _t833; + int siglen; + siglen = 0; + unsigned int _t829; + _t829 = String_Len(pemPrivateKey); + _t830 = (int)_t829; + unsigned int _t831; + _t831 = String_Len(data); + _t832 = (int)_t831; + _t833 = &siglen; + const char* _t834; + _t834 = bux_ecdsa_sign_p256(pemPrivateKey, _t830, data, _t832, _t833); + return _t834; +} + +const char* Ecdsa_SignP256Base64(const char* pemPrivateKey, const char* data) { + int _t837; + const char* raw; + const char* _t835; + _t835 = Ecdsa_SignP256(pemPrivateKey, data); + raw = _t835; + unsigned int _t836; + _t836 = String_Len(raw); + _t837 = (int)_t836; + const char* _t838; + _t838 = bux_base64_encode(raw, _t837); + return _t838; +} + +bool Ecdsa_VerifyP256(const char* pemPublicKey, const char* data, const char* signature) { + int _t840; + int _t842; + int _t844; + int _t846; + int r; + unsigned int _t839; + _t839 = String_Len(pemPublicKey); + _t840 = (int)_t839; + unsigned int _t841; + _t841 = String_Len(data); + _t842 = (int)_t841; + unsigned int _t843; + _t843 = String_Len(signature); + _t844 = (int)_t843; + int _t845; + _t845 = bux_ecdsa_verify_p256(pemPublicKey, _t840, data, _t842, signature, _t844); + r = _t845; + _t846 = (r == 1); + return _t846; +} + +bool Ecdsa_VerifyP256Base64(const char* pemPublicKey, const char* data, const char* signatureB64) { + int _t848; + void* _t849; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t847; + _t847 = String_Len(signatureB64); + _t848 = (int)_t847; + _t849 = &outlen; + const char* _t850; + _t850 = bux_base64_decode(signatureB64, _t848, _t849); + sig = _t850; + bool _t851; + _t851 = Ecdsa_VerifyP256(pemPublicKey, data, sig); + return _t851; +} + +const char* Ecdsa_SignP384(const char* pemPrivateKey, const char* data) { + int _t853; + int _t855; + void* _t856; + int siglen; + siglen = 0; + unsigned int _t852; + _t852 = String_Len(pemPrivateKey); + _t853 = (int)_t852; + unsigned int _t854; + _t854 = String_Len(data); + _t855 = (int)_t854; + _t856 = &siglen; + const char* _t857; + _t857 = bux_ecdsa_sign_p384(pemPrivateKey, _t853, data, _t855, _t856); + return _t857; +} + +const char* Ecdsa_SignP384Base64(const char* pemPrivateKey, const char* data) { + int _t860; + const char* raw; + const char* _t858; + _t858 = Ecdsa_SignP384(pemPrivateKey, data); + raw = _t858; + unsigned int _t859; + _t859 = String_Len(raw); + _t860 = (int)_t859; + const char* _t861; + _t861 = bux_base64_encode(raw, _t860); + return _t861; +} + +bool Ecdsa_VerifyP384(const char* pemPublicKey, const char* data, const char* signature) { + int _t863; + int _t865; + int _t867; + int _t869; + int r; + unsigned int _t862; + _t862 = String_Len(pemPublicKey); + _t863 = (int)_t862; + unsigned int _t864; + _t864 = String_Len(data); + _t865 = (int)_t864; + unsigned int _t866; + _t866 = String_Len(signature); + _t867 = (int)_t866; + int _t868; + _t868 = bux_ecdsa_verify_p384(pemPublicKey, _t863, data, _t865, signature, _t867); + r = _t868; + _t869 = (r == 1); + return _t869; +} + +bool Ecdsa_VerifyP384Base64(const char* pemPublicKey, const char* data, const char* signatureB64) { + int _t871; + void* _t872; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t870; + _t870 = String_Len(signatureB64); + _t871 = (int)_t870; + _t872 = &outlen; + const char* _t873; + _t873 = bux_base64_decode(signatureB64, _t871, _t872); + sig = _t873; + bool _t874; + _t874 = Ecdsa_VerifyP384(pemPublicKey, data, sig); + return _t874; +} + +bool Ed25519_Keypair(void* pubKey, void* privKey) { + int _t876; + int r; + int _t875; + _t875 = bux_ed25519_keypair(pubKey, privKey); + r = _t875; + _t876 = (r == 1); + return _t876; +} + +const char* Ed25519_KeypairBase64(void) { + unsigned int _t877; + unsigned int _t879; + int _t882; + const char* _t883; + const char* _t885; + void* pubBuf; + _t877 = (unsigned int)ED25519_PUBKEY_SIZE; + void* _t878; + _t878 = Alloc(_t877); + pubBuf = _t878; + void* priv; + _t879 = (unsigned int)ED25519_PRIVKEY_SIZE; + void* _t880; + _t880 = Alloc(_t879); + priv = _t880; + int _t881; + _t881 = bux_ed25519_keypair(pubBuf, priv); + _t882 = (_t881 != 1); + if (!_t882) goto endif313; + { + Free(pubBuf); + Free(priv); + return ""; + } + endif313:; + const char* pubB64; + _t883 = (const char*)pubBuf; + const char* _t884; + _t884 = bux_base64_encode(_t883, ED25519_PUBKEY_SIZE); + pubB64 = _t884; + const char* privB64; + _t885 = (const char*)priv; + const char* _t886; + _t886 = bux_base64_encode(_t885, ED25519_PRIVKEY_SIZE); + privB64 = _t886; + Free(pubBuf); + Free(priv); + const char* pair; + const char* _t887; + _t887 = String_Concat(pubB64, ":"); + pair = _t887; + const char* _t888; + _t888 = String_Concat(pair, privB64); + return _t888; +} + +const char* Ed25519_Sign(const char* privKey, const char* data) { + unsigned int _t889; + int _t892; + int _t894; + const char* _t895; + void* sig; + _t889 = (unsigned int)ED25519_SIG_SIZE; + void* _t890; + _t890 = Alloc(_t889); + sig = _t890; + unsigned int _t891; + _t891 = String_Len(data); + _t892 = (int)_t891; + int _t893; + _t893 = bux_ed25519_sign(privKey, data, _t892, sig); + _t894 = (_t893 != 1); + if (!_t894) goto endif315; + { + Free(sig); + return ""; + } + endif315:; + _t895 = (const char*)sig; + return _t895; +} + +const char* Ed25519_SignBase64(const char* privKey, const char* data) { + int _t898; + const char* sig; + const char* _t896; + _t896 = Ed25519_Sign(privKey, data); + sig = _t896; + unsigned int _t897; + _t897 = String_Len(sig); + _t898 = (_t897 == 0); + if (!_t898) goto endif317; + { + return ""; + } + endif317:; + const char* _t899; + _t899 = bux_base64_encode(sig, ED25519_SIG_SIZE); + return _t899; +} + +bool Ed25519_Verify(const char* pubKey, const char* signature, const char* data) { + int _t901; + int _t903; + int r; + unsigned int _t900; + _t900 = String_Len(data); + _t901 = (int)_t900; + int _t902; + _t902 = bux_ed25519_verify(pubKey, signature, data, _t901); + r = _t902; + _t903 = (r == 1); + return _t903; +} + +bool Ed25519_VerifyBase64(const char* pubKey, const char* signatureB64, const char* data) { + int _t905; + void* _t906; + int _t908; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t904; + _t904 = String_Len(signatureB64); + _t905 = (int)_t904; + _t906 = &outlen; + const char* _t907; + _t907 = bux_base64_decode(signatureB64, _t905, _t906); + sig = _t907; + _t908 = (outlen != ED25519_SIG_SIZE); + if (!_t908) goto endif319; + { + return 0; + } + endif319:; + bool _t909; + _t909 = Ed25519_Verify(pubKey, sig, data); + return _t909; +} + +const char* Rsa_SignSha256(const char* pemPrivateKey, const char* data) { + int _t911; + int _t913; + void* _t914; + int siglen; + siglen = 0; + unsigned int _t910; + _t910 = String_Len(pemPrivateKey); + _t911 = (int)_t910; + unsigned int _t912; + _t912 = String_Len(data); + _t913 = (int)_t912; + _t914 = &siglen; + const char* _t915; + _t915 = bux_rsa_sign_sha256(pemPrivateKey, _t911, data, _t913, _t914); + return _t915; +} + +const char* Rsa_SignSha384(const char* pemPrivateKey, const char* data) { + int _t917; + int _t919; + void* _t920; + int siglen; + siglen = 0; + unsigned int _t916; + _t916 = String_Len(pemPrivateKey); + _t917 = (int)_t916; + unsigned int _t918; + _t918 = String_Len(data); + _t919 = (int)_t918; + _t920 = &siglen; + const char* _t921; + _t921 = bux_rsa_sign_sha384(pemPrivateKey, _t917, data, _t919, _t920); + return _t921; +} + +const char* Rsa_SignSha512(const char* pemPrivateKey, const char* data) { + int _t923; + int _t925; + void* _t926; + int siglen; + siglen = 0; + unsigned int _t922; + _t922 = String_Len(pemPrivateKey); + _t923 = (int)_t922; + unsigned int _t924; + _t924 = String_Len(data); + _t925 = (int)_t924; + _t926 = &siglen; + const char* _t927; + _t927 = bux_rsa_sign_sha512(pemPrivateKey, _t923, data, _t925, _t926); + return _t927; +} + +const char* Rsa_SignSha256Base64(const char* pemPrivateKey, const char* data) { + int _t930; + const char* raw; + const char* _t928; + _t928 = Rsa_SignSha256(pemPrivateKey, data); + raw = _t928; + unsigned int _t929; + _t929 = String_Len(raw); + _t930 = (int)_t929; + const char* _t931; + _t931 = bux_base64_encode(raw, _t930); + return _t931; +} + +const char* Rsa_SignSha384Base64(const char* pemPrivateKey, const char* data) { + int _t934; + const char* raw; + const char* _t932; + _t932 = Rsa_SignSha384(pemPrivateKey, data); + raw = _t932; + unsigned int _t933; + _t933 = String_Len(raw); + _t934 = (int)_t933; + const char* _t935; + _t935 = bux_base64_encode(raw, _t934); + return _t935; +} + +const char* Rsa_SignSha512Base64(const char* pemPrivateKey, const char* data) { + int _t938; + const char* raw; + const char* _t936; + _t936 = Rsa_SignSha512(pemPrivateKey, data); + raw = _t936; + unsigned int _t937; + _t937 = String_Len(raw); + _t938 = (int)_t937; + const char* _t939; + _t939 = bux_base64_encode(raw, _t938); + return _t939; +} + +bool Rsa_VerifySha256(const char* pemPublicKey, const char* data, const char* signature) { + int _t941; + int _t943; + int _t945; + int _t947; + int r; + unsigned int _t940; + _t940 = String_Len(pemPublicKey); + _t941 = (int)_t940; + unsigned int _t942; + _t942 = String_Len(data); + _t943 = (int)_t942; + unsigned int _t944; + _t944 = String_Len(signature); + _t945 = (int)_t944; + int _t946; + _t946 = bux_rsa_verify_sha256(pemPublicKey, _t941, data, _t943, signature, _t945); + r = _t946; + _t947 = (r == 1); + return _t947; +} + +bool Rsa_VerifySha384(const char* pemPublicKey, const char* data, const char* signature) { + int _t949; + int _t951; + int _t953; + int _t955; + int r; + unsigned int _t948; + _t948 = String_Len(pemPublicKey); + _t949 = (int)_t948; + unsigned int _t950; + _t950 = String_Len(data); + _t951 = (int)_t950; + unsigned int _t952; + _t952 = String_Len(signature); + _t953 = (int)_t952; + int _t954; + _t954 = bux_rsa_verify_sha384(pemPublicKey, _t949, data, _t951, signature, _t953); + r = _t954; + _t955 = (r == 1); + return _t955; +} + +bool Rsa_VerifySha512(const char* pemPublicKey, const char* data, const char* signature) { + int _t957; + int _t959; + int _t961; + int _t963; + int r; + unsigned int _t956; + _t956 = String_Len(pemPublicKey); + _t957 = (int)_t956; + unsigned int _t958; + _t958 = String_Len(data); + _t959 = (int)_t958; + unsigned int _t960; + _t960 = String_Len(signature); + _t961 = (int)_t960; + int _t962; + _t962 = bux_rsa_verify_sha512(pemPublicKey, _t957, data, _t959, signature, _t961); + r = _t962; + _t963 = (r == 1); + return _t963; +} + +bool Rsa_VerifySha256Base64(const char* pemPublicKey, const char* data, const char* signatureB64) { + int _t965; + void* _t966; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t964; + _t964 = String_Len(signatureB64); + _t965 = (int)_t964; + _t966 = &outlen; + const char* _t967; + _t967 = bux_base64_decode(signatureB64, _t965, _t966); + sig = _t967; + bool _t968; + _t968 = Rsa_VerifySha256(pemPublicKey, data, sig); + return _t968; +} + +bool Rsa_VerifySha384Base64(const char* pemPublicKey, const char* data, const char* signatureB64) { + int _t970; + void* _t971; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t969; + _t969 = String_Len(signatureB64); + _t970 = (int)_t969; + _t971 = &outlen; + const char* _t972; + _t972 = bux_base64_decode(signatureB64, _t970, _t971); + sig = _t972; + bool _t973; + _t973 = Rsa_VerifySha384(pemPublicKey, data, sig); + return _t973; +} + +bool Rsa_VerifySha512Base64(const char* pemPublicKey, const char* data, const char* signatureB64) { + int _t975; + void* _t976; + int outlen; + outlen = 0; + const char* sig; + unsigned int _t974; + _t974 = String_Len(signatureB64); + _t975 = (int)_t974; + _t976 = &outlen; + const char* _t977; + _t977 = bux_base64_decode(signatureB64, _t975, _t976); + sig = _t977; + bool _t978; + _t978 = Rsa_VerifySha512(pemPublicKey, data, sig); + return _t978; +} + +int apply(int (*f)(int), int x) { + int _t979; + _t979 = f(x); + return _t979; +} + +int Main(void) { + int (*_t980)(int); + int _t983; + int (*adder)(int); + _t980 = &__closure_10; + adder = _t980; + int r1; + int _t981; + _t981 = adder(5); + r1 = _t981; + int r2; + int _t982; + _t982 = apply(adder, 3); + r2 = _t982; + _t983 = r1 + r2; + return _t983; +} + +int __closure_10(int a) { + int _t984; + _t984 = a + 10; + return _t984; +} + +/* C entry point wrapper */ +extern int g_argc; +extern char** g_argv; +int main(int argc, char** argv) { + g_argc = argc; + g_argv = argv; + return Main(); +} diff --git a/bootstrap/ast.nim b/bootstrap/ast.nim index 4e512bb..a3f3681 100644 --- a/bootstrap/ast.nim +++ b/bootstrap/ast.nim @@ -233,6 +233,9 @@ type exprClosureParams*: seq[Param] exprClosureBody*: Block exprClosureReturnType*: TypeExpr + captureCount*: int + captureNames*: seq[string] + captureTypeKinds*: seq[int] # --------------------------------------------------------------------------- # Statements diff --git a/bootstrap/c_backend.nim b/bootstrap/c_backend.nim index 7a0d4aa..36af74a 100644 --- a/bootstrap/c_backend.nim +++ b/bootstrap/c_backend.nim @@ -272,6 +272,10 @@ proc emitExpr(be: var CBackend, node: HirNode): string = let base = be.emitExpr(node.fieldPtrBase) return &"(&({base}.{node.fieldName}))" + of hFieldAccess: + let base = be.emitExpr(node.fieldAccessBase) + return &"({base}.{node.fieldAccessName})" + of hArrowField: let base = be.emitExpr(node.arrowFieldBase) return &"(&({base}->{node.arrowFieldName}))" @@ -476,6 +480,18 @@ proc emitStmt(be: var CBackend, node: HirNode) = be.emitLine(&"{expr};") proc emitFunc*(be: var CBackend, hfunc: HirFunc) = + # Emit env struct and global instance for closures with captures + if hfunc.captureNames.len > 0 and hfunc.envStructName != "": + be.emitLine(&"struct {hfunc.envStructName} {{") + inc be.indent + for i in 0 ..< hfunc.captureNames.len: + let capName = hfunc.captureNames[i] + let capType = if i < hfunc.captureTypes.len: typeToC(be, hfunc.captureTypes[i]) else: "int" + be.emitLine(&"{capType} {capName};") + dec be.indent + be.emitLine("};") + be.emitLine(&"static struct {hfunc.envStructName} {hfunc.envInstanceName};") + be.emitLine("") let retType = typeToC(be, hfunc.retType) var params: seq[string] = @[] for p in hfunc.params: diff --git a/bootstrap/hir.nim b/bootstrap/hir.nim index 79a73fc..f55884e 100644 --- a/bootstrap/hir.nim +++ b/bootstrap/hir.nim @@ -23,6 +23,7 @@ type hLoad hStore hFieldPtr + hFieldAccess hArrowField hIndexPtr hSliceIndex @@ -98,6 +99,9 @@ type of hFieldPtr: fieldPtrBase*: HirNode fieldName*: string + of hFieldAccess: + fieldAccessBase*: HirNode + fieldAccessName*: string of hArrowField: arrowFieldBase*: HirNode arrowFieldName*: string @@ -166,6 +170,11 @@ type retType*: Type body*: HirNode isPublic*: bool + # Closure capture metadata + captureNames*: seq[string] + captureTypes*: seq[Type] + envStructName*: string + envInstanceName*: string HirEnumVariant* = object name*: string @@ -219,6 +228,9 @@ proc hirAlloca*(name: string, typ: Type, loc: SourceLocation): HirNode = proc hirStore*(ptrNode, value: HirNode, loc: SourceLocation): HirNode = HirNode(kind: hStore, storePtr: ptrNode, storeValue: value, typ: makeVoid(), loc: loc) +proc hirAssign*(target, value: HirNode, loc: SourceLocation): HirNode = + HirNode(kind: hAssign, assignOp: tkAssign, assignTarget: target, assignValue: value, typ: makeVoid(), loc: loc) + proc hirLoad*(ptrNode: HirNode, typ: Type, loc: SourceLocation): HirNode = HirNode(kind: hLoad, loadPtr: ptrNode, typ: typ, loc: loc) diff --git a/bootstrap/hir_lower.nim b/bootstrap/hir_lower.nim index 6d6feee..8525aaf 100644 --- a/bootstrap/hir_lower.nim +++ b/bootstrap/hir_lower.nim @@ -22,6 +22,9 @@ type generatedFuncInsts*: Table[string, bool] # Track generated function instantiations extraFuncs*: seq[HirFunc] # Monomorphized generic methods varTypeExprs*: Table[string, TypeExpr] # Track variable names -> type expr for generic method inference + closureDepth*: int + currentClosureExpr*: Expr + envInstanceName*: string proc freshName(ctx: var LowerCtx): string = inc ctx.varCounter @@ -648,6 +651,13 @@ proc lowerExpr(ctx: var LowerCtx, expr: Expr): HirNode = of ekIdent: let name = expr.exprIdent + # Capture rewriting: if inside closure and ident is captured + if ctx.closureDepth > 0 and ctx.currentClosureExpr != nil and ctx.envInstanceName != "": + let idx = ctx.currentClosureExpr.captureNames.find(name) + if idx >= 0: + let capType = if idx < ctx.currentClosureExpr.captureTypeKinds.len: Type(kind: TypeKind(ctx.currentClosureExpr.captureTypeKinds[idx])) else: makeInt() + let base = hirVar(ctx.envInstanceName, makeNamed(""), loc) + return HirNode(kind: hFieldAccess, fieldAccessName: name, fieldAccessBase: base, typ: capType, loc: loc) if ctx.importTable.hasKey(name): return hirVar(ctx.importTable[name], typ, loc) return hirVar(name, typ, loc) @@ -1202,6 +1212,22 @@ proc lowerStmt(ctx: var LowerCtx, stmt: Stmt): HirNode = if initHir != nil: let store = hirStore(varNode, initHir, loc) stmts.add(store) + # If init is a closure with captures, emit capture assignments + if stmt.stmtLetInit != nil and stmt.stmtLetInit.kind == ekClosure and stmt.stmtLetInit.captureCount > 0: + let closureIdx = ctx.varCounter - 1 + let envInst = "__closure_env_instance_" & $closureIdx + var capStmts: seq[HirNode] = @[] + for i in 0 ..< stmt.stmtLetInit.captureCount: + let capName = stmt.stmtLetInit.captureNames[i] + let capType = if i < stmt.stmtLetInit.captureTypeKinds.len: Type(kind: TypeKind(stmt.stmtLetInit.captureTypeKinds[i])) else: makeInt() + let base = hirVar(envInst, makeNamed(""), loc) + let field = HirNode(kind: hFieldAccess, fieldAccessName: capName, fieldAccessBase: base, typ: capType, loc: loc) + let val = hirVar(capName, capType, loc) + capStmts.add(hirAssign(field, val, loc)) + # Prepend capture assignments before the let + var allStmts = capStmts + allStmts.add(stmts) + return hirBlock(allStmts, nil, makeVoid(), loc) return hirBlock(stmts, nil, makeVoid(), loc) of skReturn: @@ -1491,6 +1517,13 @@ proc lowerClosureFunc(ctx: var LowerCtx, expr: Expr): HirFunc = let name = "__closure_" & $ctx.varCounter inc ctx.varCounter var f = HirFunc(name: name, isPublic: false) + # Copy capture metadata + if expr.captureCount > 0: + f.captureNames = expr.captureNames + for tk in expr.captureTypeKinds: + f.captureTypes.add(Type(kind: TypeKind(tk))) + f.envStructName = "__closure_env_" & $(ctx.varCounter - 1) + f.envInstanceName = "__closure_env_instance_" & $(ctx.varCounter - 1) # Params for p in expr.exprClosureParams: f.params.add((name: p.name, typ: if p.ptype != nil: ctx.resolveTypeExpr(p.ptype) else: makeUnknown())) @@ -1499,9 +1532,18 @@ proc lowerClosureFunc(ctx: var LowerCtx, expr: Expr): HirFunc = f.retType = ctx.resolveTypeExpr(expr.exprClosureReturnType) else: f.retType = makeVoid() - # Body + # Body with closure rewriting + let savedDepth = ctx.closureDepth + let savedExpr = ctx.currentClosureExpr + let savedEnv = ctx.envInstanceName + ctx.closureDepth = ctx.closureDepth + 1 + ctx.currentClosureExpr = expr + ctx.envInstanceName = f.envInstanceName if expr.exprClosureBody != nil: f.body = ctx.lowerBlock(expr.exprClosureBody) + ctx.closureDepth = savedDepth + ctx.currentClosureExpr = savedExpr + ctx.envInstanceName = savedEnv ctx.extraFuncs.add(f) return f diff --git a/bootstrap/lir_c_backend.nim b/bootstrap/lir_c_backend.nim index 2141cd9..77cbbfd 100644 --- a/bootstrap/lir_c_backend.nim +++ b/bootstrap/lir_c_backend.nim @@ -626,6 +626,20 @@ proc emitModule*(be: var LirCBackend, builder: LirBuilder, module: HirModule): s be.emitLine("};") be.emitLine("") + # Emit env structs for closures with captures + for f in module.funcs: + if f.captureNames.len > 0 and f.envStructName != "": + be.emitLine(&"struct {f.envStructName} {{") + be.indent += 1 + for i in 0 ..< f.captureNames.len: + let capName = f.captureNames[i] + let capType = if i < f.captureTypes.len: typeToCStr(f.captureTypes[i]) else: "int" + be.emitLine(&"{capType} {capName};") + be.indent -= 1 + be.emitLine("};") + be.emitLine(&"static struct {f.envStructName} {f.envInstanceName};") + be.emitLine("") + # Emit all LIR functions for f in builder.funcs: be.emitFunc(f, funcRetTypes, funcPtrTypes) diff --git a/bootstrap/lir_lower.nim b/bootstrap/lir_lower.nim index 515c355..713646b 100644 --- a/bootstrap/lir_lower.nim +++ b/bootstrap/lir_lower.nim @@ -345,6 +345,14 @@ proc lowerExpr(ctx: var LowerToLirCtx, node: HirNode): LirValue = b.emitRawC(&"{t.strVal} = (void*)&({lirValToC(base)}.{node.fieldName});") return t + of hFieldAccess: + let base = lowerExpr(ctx, node.fieldAccessBase) + let cType = hirTypeToC(ctx, node) + let t = b.freshTemp() + b.emitAlloca(t.strVal, cType) + b.emitRawC(&"{t.strVal} = {lirValToC(base)}.{node.fieldAccessName};") + return t + of hArrowField: let base = lowerExpr(ctx, node.arrowFieldBase) let t = b.freshTemp() @@ -549,6 +557,9 @@ proc buildLval(ctx: var LowerToLirCtx, n: HirNode): string = of hArrowField: let baseStr = buildLval(ctx, n.arrowFieldBase) return baseStr & "->" & n.arrowFieldName + of hFieldAccess: + let baseStr = buildLval(ctx, n.fieldAccessBase) + return baseStr & "." & n.fieldAccessName of hIndexPtr: let baseStr = buildLval(ctx, n.indexPtrBase) let idx = lowerExpr(ctx, n.indexPtrIndex) @@ -669,6 +680,9 @@ proc lowerStmt(ctx: var LowerToLirCtx, node: HirNode) = of hFieldPtr: let lval = buildLval(ctx, node.assignTarget) b.emitRawC(&"{lval} = {lirValToC(value)};") + of hFieldAccess: + let lval = buildLval(ctx, node.assignTarget) + b.emitRawC(&"{lval} = {lirValToC(value)};") of hArrowField: let lval = buildLval(ctx, node.assignTarget) b.emitRawC(&"{lval} = {lirValToC(value)};") diff --git a/bootstrap/scope.nim b/bootstrap/scope.nim index 5d5b387..cce98fa 100644 --- a/bootstrap/scope.nim +++ b/bootstrap/scope.nim @@ -43,4 +43,14 @@ proc lookup*(scope: Scope, name: string): Symbol = proc lookupLocal*(scope: Scope, name: string): Symbol = if scope.table.hasKey(name): return scope.table[name] + return nil + +proc lookupUpTo*(scope: Scope, name: string, limit: Scope): Symbol = + var cur = scope + while cur != nil: + if cur.table.hasKey(name): + return cur.table[name] + if cur == limit: + break + cur = cur.parent return nil \ No newline at end of file diff --git a/bootstrap/sema.nim b/bootstrap/sema.nim index 84ad050..d041a40 100644 --- a/bootstrap/sema.nim +++ b/bootstrap/sema.nim @@ -45,6 +45,9 @@ type currentFuncIsAsync*: bool ## true inside async func movedVars*: seq[string] ## variables moved in current checked function currentRetType*: Type ## return type of the function being checked + closureDepth*: int ## nesting depth inside closures + currentClosureExpr*: Expr ## current closure being analyzed + closureScope*: Scope ## scope at which the current closure was entered # --------------------------------------------------------------------------- # Helpers @@ -816,6 +819,14 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type = return makeUnknown() if sym.typ == nil: return makeUnknown() + # Capture tracking + if sema.closureDepth > 0 and sema.currentClosureExpr != nil and sema.closureScope != nil: + let localSym = scope.lookupUpTo(expr.exprIdent, sema.closureScope) + if localSym == nil and sym.kind == skVar: + if expr.exprIdent notin sema.currentClosureExpr.captureNames: + sema.currentClosureExpr.captureNames.add(expr.exprIdent) + sema.currentClosureExpr.captureTypeKinds.add(sym.typ.kind.int) + sema.currentClosureExpr.captureCount = sema.currentClosureExpr.captureNames.len return sym.typ of ekSelf: let sym = scope.lookup("self") @@ -1340,7 +1351,16 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type = return makeStr() of ekClosure: let savedRetType = sema.currentRetType + let savedClosureDepth = sema.closureDepth + let savedClosureExpr = sema.currentClosureExpr + let savedClosureScope = sema.closureScope let childScope = Scope(parent: scope) + sema.closureDepth = sema.closureDepth + 1 + sema.currentClosureExpr = expr + sema.closureScope = childScope + expr.captureCount = 0 + expr.captureNames = @[] + expr.captureTypeKinds = @[] sema.currentRetType = if expr.exprClosureReturnType != nil: sema.resolveType(expr.exprClosureReturnType) else: makeUnknown() # Register params for p in expr.exprClosureParams: @@ -1351,6 +1371,9 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type = for stmt in expr.exprClosureBody.stmts: discard sema.checkStmt(stmt, childScope) sema.currentRetType = savedRetType + sema.closureDepth = savedClosureDepth + sema.currentClosureExpr = savedClosureExpr + sema.closureScope = savedClosureScope # Build function type var params: seq[Type] = @[] for p in expr.exprClosureParams: diff --git a/src/ast.bux b/src/ast.bux index cb1c092..d9a5114 100644 --- a/src/ast.bux +++ b/src/ast.bux @@ -142,6 +142,24 @@ struct Expr { structFieldCount: int, // Closure params (for ekClosure) closureParams: *Decl, + // Captures (for ekClosure) + captureCount: int, + captureName0: String, + captureName1: String, + captureName2: String, + captureName3: String, + captureName4: String, + captureName5: String, + captureName6: String, + captureName7: String, + captureType0: int, + captureType1: int, + captureType2: int, + captureType3: int, + captureType4: int, + captureType5: int, + captureType6: int, + captureType7: int, // Call arguments (linked list for multi-arg support) callArgs: *ExprList, callArgCount: int, diff --git a/src/c_backend.bux b/src/c_backend.bux index 732b71a..d396a0c 100644 --- a/src/c_backend.bux +++ b/src/c_backend.bux @@ -445,6 +445,14 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) { return; } + // Field access on value (direct dot): obj.field + if kind == hFieldAccess { + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, "."); + StringBuilder_Append(&cbe.sb, node.strValue); + return; + } + // Field access: obj.field — use -> if base is pointer, else . if kind == hFieldPtr { CBE_EmitExpr(cbe, node.child1); @@ -1042,6 +1050,43 @@ func CBackend_Generate(mod: *HirModule) -> String { i = i + 1; continue; } + // Emit env struct and global instance for closures with captures + if mod.funcs[i].captureCount > 0 { + let envName: String = mod.funcs[i].envStructName; + let instName: String = mod.funcs[i].envInstanceName; + if !String_Eq(envName, "") { + // Emit struct definition + StringBuilder_Append(&cbe.sb, "struct "); + StringBuilder_Append(&cbe.sb, envName); + StringBuilder_Append(&cbe.sb, " {\n"); + var ci: int = 0; + while ci < mod.funcs[i].captureCount { + var capName: String = ""; + var capType: String = "int"; + if ci == 0 { capName = mod.funcs[i].captureName0; capType = CBackend_TypeToC(mod.funcs[i].captureType0); } + else if ci == 1 { capName = mod.funcs[i].captureName1; capType = CBackend_TypeToC(mod.funcs[i].captureType1); } + else if ci == 2 { capName = mod.funcs[i].captureName2; capType = CBackend_TypeToC(mod.funcs[i].captureType2); } + else if ci == 3 { capName = mod.funcs[i].captureName3; capType = CBackend_TypeToC(mod.funcs[i].captureType3); } + else if ci == 4 { capName = mod.funcs[i].captureName4; capType = CBackend_TypeToC(mod.funcs[i].captureType4); } + else if ci == 5 { capName = mod.funcs[i].captureName5; capType = CBackend_TypeToC(mod.funcs[i].captureType5); } + else if ci == 6 { capName = mod.funcs[i].captureName6; capType = CBackend_TypeToC(mod.funcs[i].captureType6); } + else if ci == 7 { capName = mod.funcs[i].captureName7; capType = CBackend_TypeToC(mod.funcs[i].captureType7); } + StringBuilder_Append(&cbe.sb, " "); + StringBuilder_Append(&cbe.sb, capType); + StringBuilder_Append(&cbe.sb, " "); + StringBuilder_Append(&cbe.sb, capName); + StringBuilder_Append(&cbe.sb, ";\n"); + ci = ci + 1; + } + StringBuilder_Append(&cbe.sb, "};\n"); + // Emit global instance + StringBuilder_Append(&cbe.sb, "static struct "); + StringBuilder_Append(&cbe.sb, envName); + StringBuilder_Append(&cbe.sb, " "); + StringBuilder_Append(&cbe.sb, instName); + StringBuilder_Append(&cbe.sb, ";\n\n"); + } + } CBE_EmitFuncDecl(cbe, &mod.funcs[i]); StringBuilder_Append(&cbe.sb, " {\n"); // Body diff --git a/src/hir.bux b/src/hir.bux index 9f9e3b9..75307b7 100644 --- a/src/hir.bux +++ b/src/hir.bux @@ -18,8 +18,9 @@ const hAlloca: int = 12; const hLoad: int = 13; const hStore: int = 14; const hFieldPtr: int = 15; -const hArrowField: int = 16; -const hIndexPtr: int = 17; +const hFieldAccess: int = 16; +const hArrowField: int = 17; +const hIndexPtr: int = 18; const hCall: int = 18; const hCallIndirect: int = 19; const hCast: int = 20; @@ -93,6 +94,26 @@ struct HirFunc { retTypeName: String; body: *HirNode; isPublic: bool; + // Closure capture metadata + captureCount: int; + captureName0: String; + captureName1: String; + captureName2: String; + captureName3: String; + captureName4: String; + captureName5: String; + captureName6: String; + captureName7: String; + captureType0: int; + captureType1: int; + captureType2: int; + captureType3: int; + captureType4: int; + captureType5: int; + captureType6: int; + captureType7: int; + envStructName: String; + envInstanceName: String; } // --------------------------------------------------------------------------- diff --git a/src/hir_lower.bux b/src/hir_lower.bux index 2c25ece..71b9ab1 100644 --- a/src/hir_lower.bux +++ b/src/hir_lower.bux @@ -15,6 +15,10 @@ struct LowerCtx { externCount: int, varCounter: int, tryCounter: int, + closureDepth: int, + currentClosureExpr: *Expr, + envInstanceName: String, + hm: *HirModule, } // --------------------------------------------------------------------------- @@ -50,6 +54,29 @@ func Lcx_ResolveTypeKindFromName(name: String) -> int { return tyNamed; } +func Lcx_TypeKindToName(kind: int) -> String { + if kind == tyVoid { return "void"; } + if kind == tyBool || kind == tyBool8 || kind == tyBool16 || kind == tyBool32 { return "bool"; } + if kind == tyChar8 { return "char"; } + if kind == tyChar16 { return "uint16"; } + if kind == tyChar32 { return "uint32"; } + if kind == tyStr { return "String"; } + if kind == tyInt8 { return "int8"; } + if kind == tyInt16 { return "int16"; } + if kind == tyInt32 { return "int32"; } + if kind == tyInt64 { return "int64"; } + if kind == tyInt { return "int"; } + if kind == tyUInt8 { return "uint8"; } + if kind == tyUInt16 { return "uint16"; } + if kind == tyUInt32 { return "uint32"; } + if kind == tyUInt64 { return "uint64"; } + if kind == tyUInt { return "uint"; } + if kind == tyFloat32 { return "float32"; } + if kind == tyFloat64 { return "float64"; } + if kind == tyPointer { return "void*"; } + return "int"; +} + func Lcx_ResolveTypeKind(te: *TypeExpr) -> int { if te == null as *TypeExpr { return tyUnknown; } @@ -122,6 +149,40 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { // Identifier → variable reference if kind == ekIdent { + // Capture rewriting: if inside closure body and this ident is captured, + // emit field access on env instance instead of bare variable + if ctx.closureDepth > 0 && ctx.currentClosureExpr != null as *Expr && !String_Eq(ctx.envInstanceName, "") { + let capCount: int = ctx.currentClosureExpr.captureCount; + var ci: int = 0; + var isCaptured: bool = false; + var capType: int = 0; + while ci < capCount { + var capName: String = ""; + if ci == 0 { capName = ctx.currentClosureExpr.captureName0; capType = ctx.currentClosureExpr.captureType0; } + else if ci == 1 { capName = ctx.currentClosureExpr.captureName1; capType = ctx.currentClosureExpr.captureType1; } + else if ci == 2 { capName = ctx.currentClosureExpr.captureName2; capType = ctx.currentClosureExpr.captureType2; } + else if ci == 3 { capName = ctx.currentClosureExpr.captureName3; capType = ctx.currentClosureExpr.captureType3; } + else if ci == 4 { capName = ctx.currentClosureExpr.captureName4; capType = ctx.currentClosureExpr.captureType4; } + else if ci == 5 { capName = ctx.currentClosureExpr.captureName5; capType = ctx.currentClosureExpr.captureType5; } + else if ci == 6 { capName = ctx.currentClosureExpr.captureName6; capType = ctx.currentClosureExpr.captureType6; } + else if ci == 7 { capName = ctx.currentClosureExpr.captureName7; capType = ctx.currentClosureExpr.captureType7; } + if String_Eq(capName, expr.strValue) { + isCaptured = true; + } + ci = ci + 1; + } + if isCaptured { + n.kind = hFieldAccess; + n.strValue = expr.strValue; + let baseNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + baseNode.kind = hVar; + baseNode.strValue = ctx.envInstanceName; + n.child1 = baseNode; + n.typeKind = capType; + n.typeName = Lcx_TypeKindToName(capType); + return n; + } + } n.kind = hVar; n.strValue = expr.strValue; let sym: Symbol = Scope_Lookup(ctx.scope, expr.strValue); @@ -500,10 +561,71 @@ func Lcx_LowerStmt(ctx: *LowerCtx, stmt: *Stmt) -> *HirNode { sym.decl = null as *Decl; discard Scope_Define(ctx.scope, sym); // store the init value - n.kind = hStore; - n.child1 = alloca; - n.child2 = init; - return n; + let storeNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + storeNode.kind = hStore; + storeNode.child1 = alloca; + storeNode.child2 = init; + + // If init is a closure with captures, emit capture assignments before the let + if stmt.child1 != null as *Expr && stmt.child1.kind == ekClosure && stmt.child1.captureCount > 0 { + let closureIdx: int = ctx.funcCount - 1; + let envInst: String = String_Concat("__closure_env_instance_", String_FromInt(closureIdx)); + // Build a block: capture assignments + let store + let blockNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + blockNode.kind = hBlock; + blockNode.line = line; + blockNode.column = col; + var firstStmt: *HirNode = null as *HirNode; + var lastStmt: *HirNode = null as *HirNode; + var ci: int = 0; + while ci < stmt.child1.captureCount { + var capName: String = ""; + if ci == 0 { capName = stmt.child1.captureName0; } + else if ci == 1 { capName = stmt.child1.captureName1; } + else if ci == 2 { capName = stmt.child1.captureName2; } + else if ci == 3 { capName = stmt.child1.captureName3; } + else if ci == 4 { capName = stmt.child1.captureName4; } + else if ci == 5 { capName = stmt.child1.captureName5; } + else if ci == 6 { capName = stmt.child1.captureName6; } + else if ci == 7 { capName = stmt.child1.captureName7; } + // Build: envInst.capName = capName; + let assignNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + assignNode.kind = hAssign; + assignNode.line = line; + assignNode.column = col; + let fieldNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + fieldNode.kind = hFieldAccess; + fieldNode.strValue = capName; + let baseNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + baseNode.kind = hVar; + baseNode.strValue = envInst; + fieldNode.child1 = baseNode; + let valNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; + valNode.kind = hVar; + valNode.strValue = capName; + assignNode.child1 = fieldNode; + assignNode.child2 = valNode; + if firstStmt == null as *HirNode { + firstStmt = assignNode; + lastStmt = assignNode; + } else { + lastStmt.child3 = assignNode; + lastStmt = assignNode; + } + ci = ci + 1; + } + // Append the let store + if firstStmt == null as *HirNode { + firstStmt = storeNode; + lastStmt = storeNode; + } else { + lastStmt.child3 = storeNode; + lastStmt = storeNode; + } + blockNode.child1 = firstStmt; + return blockNode; + } + return storeNode; } // Return @@ -830,6 +952,37 @@ func Lcx_LowerClosureFunc(ctx: *LowerCtx, expr: *Expr) -> *HirFunc { f.retTypeKind = 0; } + // Copy capture metadata from AST + f.captureCount = expr.captureCount; + f.captureName0 = expr.captureName0; + f.captureName1 = expr.captureName1; + f.captureName2 = expr.captureName2; + f.captureName3 = expr.captureName3; + f.captureName4 = expr.captureName4; + f.captureName5 = expr.captureName5; + f.captureName6 = expr.captureName6; + f.captureName7 = expr.captureName7; + f.captureType0 = expr.captureType0; + f.captureType1 = expr.captureType1; + f.captureType2 = expr.captureType2; + f.captureType3 = expr.captureType3; + f.captureType4 = expr.captureType4; + f.captureType5 = expr.captureType5; + f.captureType6 = expr.captureType6; + f.captureType7 = expr.captureType7; + + // Generate env struct and instance names if there are captures + var envStructName: String = ""; + var envInstanceName: String = ""; + if f.captureCount > 0 { + envStructName = String_Concat("__closure_env_", numStr); + envInstanceName = String_Concat("__closure_env_instance_", numStr); + f.envStructName = envStructName; + f.envInstanceName = envInstanceName; + + // Env struct is emitted directly by C backend from func capture metadata + } + // Create function scope var funcScope: Scope = Scope_NewChild(ctx.scope); var pi: int = 0; @@ -868,13 +1021,22 @@ func Lcx_LowerClosureFunc(ctx: *LowerCtx, expr: *Expr) -> *HirFunc { } let prevScope: *Scope = ctx.scope; + let prevClosureDepth: int = ctx.closureDepth; + let prevClosureExpr: *Expr = ctx.currentClosureExpr; + let prevEnvInstanceName: String = ctx.envInstanceName; ctx.scope = &funcScope; + ctx.closureDepth = ctx.closureDepth + 1; + ctx.currentClosureExpr = expr; + ctx.envInstanceName = envInstanceName; if expr.refBlock != null as *Block { f.body = Lcx_LowerBlock(ctx, expr.refBlock, -1); } else { f.body = null as *HirNode; } ctx.scope = prevScope; + ctx.closureDepth = prevClosureDepth; + ctx.currentClosureExpr = prevClosureExpr; + ctx.envInstanceName = prevEnvInstanceName; // Add to module functions ctx.funcs[ctx.funcCount] = *f; @@ -906,6 +1068,7 @@ func HirLower_LowerModule(mod: *Module, sema: *Sema) -> *HirModule { hm.enums = bux_alloc(64 as uint * sizeof(HirEnum)) as *HirEnum; hm.constCount = 0; hm.consts = bux_alloc(512 as uint * sizeof(HirConst)) as *HirConst; + ctx.hm = hm; // First pass: count structs (to allocate field arrays later) // Second pass: actually collect them diff --git a/src/scope.bux b/src/scope.bux index d9a02b1..1ba1e84 100644 --- a/src/scope.bux +++ b/src/scope.bux @@ -89,6 +89,25 @@ func Scope_LookupLocal(scope: *Scope, name: String) -> Symbol { return empty; } +func Scope_LookupUpTo(scope: *Scope, name: String, limit: *Scope) -> Symbol { + var cur: *Scope = scope; + while cur != null as *Scope { + var i: int = 0; + while i < cur.count { + if String_Eq(cur.symbols[i].name, name) { + return cur.symbols[i]; + } + i = i + 1; + } + if cur == limit { + break; + } + cur = cur.parent; + } + var empty: Symbol = Symbol { kind: 0, name: "", typeKind: 0, typeName: "", refType: null as *TypeExpr, isMutable: false, isPublic: false, decl: null as *Decl }; + return empty; +} + func Scope_Free(scope: *Scope) { bux_free(scope.symbols as *void); } diff --git a/src/sema.bux b/src/sema.bux index 6b6c312..7d3e524 100644 --- a/src/sema.bux +++ b/src/sema.bux @@ -24,6 +24,9 @@ struct Sema { movedName5: String; movedName6: String; movedName7: String; + closureDepth: int; // nesting depth inside closures + currentClosureExpr: *Expr; // current closure being analyzed (for capture tracking) + closureScope: *Scope; // scope at which the current closure was entered } struct SemaDiag { @@ -337,6 +340,42 @@ func Sema_RemoveMoved(sema: *Sema, name: String) { } } +// --------------------------------------------------------------------------- +// Capture tracking for closures +// --------------------------------------------------------------------------- + +func Sema_AddCapture(closureExpr: *Expr, name: String, typeKind: int) { + if closureExpr == null as *Expr { return; } + // Check if already captured + var i: int = 0; + while i < closureExpr.captureCount { + var capName: String = ""; + if i == 0 { capName = closureExpr.captureName0; } + else if i == 1 { capName = closureExpr.captureName1; } + else if i == 2 { capName = closureExpr.captureName2; } + else if i == 3 { capName = closureExpr.captureName3; } + else if i == 4 { capName = closureExpr.captureName4; } + else if i == 5 { capName = closureExpr.captureName5; } + else if i == 6 { capName = closureExpr.captureName6; } + else if i == 7 { capName = closureExpr.captureName7; } + if String_Eq(capName, name) { return; } + i = i + 1; + } + // Add new capture (up to 8) + if closureExpr.captureCount < 8 { + let idx: int = closureExpr.captureCount; + if idx == 0 { closureExpr.captureName0 = name; closureExpr.captureType0 = typeKind; } + else if idx == 1 { closureExpr.captureName1 = name; closureExpr.captureType1 = typeKind; } + else if idx == 2 { closureExpr.captureName2 = name; closureExpr.captureType2 = typeKind; } + else if idx == 3 { closureExpr.captureName3 = name; closureExpr.captureType3 = typeKind; } + else if idx == 4 { closureExpr.captureName4 = name; closureExpr.captureType4 = typeKind; } + else if idx == 5 { closureExpr.captureName5 = name; closureExpr.captureType5 = typeKind; } + else if idx == 6 { closureExpr.captureName6 = name; closureExpr.captureType6 = typeKind; } + else if idx == 7 { closureExpr.captureName7 = name; closureExpr.captureType7 = typeKind; } + closureExpr.captureCount = closureExpr.captureCount + 1; + } +} + // --------------------------------------------------------------------------- // Expression type checking // --------------------------------------------------------------------------- @@ -379,6 +418,16 @@ func Sema_CheckExpr(sema: *Sema, expr: *Expr) -> int { te.typeName = sym.typeName; expr.refType = te; } + // Capture tracking: if inside closure and identifier is not local but from parent scope + if sema.closureDepth > 0 && sema.currentClosureExpr != null as *Expr && sema.closureScope != null as *Scope { + let localSym: Symbol = Scope_LookupUpTo(sema.scope, expr.strValue, sema.closureScope); + if localSym.kind == 0 && !String_Eq(localSym.name, expr.strValue) { + // Not local to closure scope — check if it's a variable from outer scope + if sym.kind == skVar { + Sema_AddCapture(sema.currentClosureExpr, expr.strValue, sym.typeKind); + } + } + } return sym.typeKind; } @@ -568,9 +617,18 @@ func Sema_CheckExpr(sema: *Sema, expr: *Expr) -> int { if kind == ekClosure { let savedRetType: int = sema.currentRetType; let savedScope: *Scope = sema.scope; + let savedClosureDepth: int = sema.closureDepth; + let savedClosureExpr: *Expr = sema.currentClosureExpr; + let savedClosureScope: *Scope = sema.closureScope; let childScope: Scope = Scope_NewChild(sema.scope); sema.scope = &childScope; + // Set up closure tracking + sema.closureDepth = sema.closureDepth + 1; + sema.currentClosureExpr = expr; + sema.closureScope = &childScope; + expr.captureCount = 0; + // Set return type from annotation, or unknown for inference var closureRetType: int = tyUnknown; if expr.refType != null as *TypeExpr { @@ -621,6 +679,9 @@ func Sema_CheckExpr(sema: *Sema, expr: *Expr) -> int { // Restore sema.scope = savedScope; sema.currentRetType = savedRetType; + sema.closureDepth = savedClosureDepth; + sema.currentClosureExpr = savedClosureExpr; + sema.closureScope = savedClosureScope; // Build function type expression for later use let funcType: *TypeExpr = bux_alloc(sizeof(TypeExpr)) as *TypeExpr;