/* generated by the Cryn compiler - do not edit */
/* Cryn source compiled to portable C11 */
#ifndef CRYN_RT_H
#define CRYN_RT_H
/*
* Minimal runtime support for compiled Cryn programs.
* Everything here exists only because it cannot be expressed as inline C
* in generated code (context management, heap headers, threads, output
* formatting). The language's semantics live in the compiler.
*/
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#if defined(__GNUC__) || defined(__clang__)
#define CRN_NORETURN __attribute__((noreturn))
#else
#define CRN_NORETURN
#endif
typedef union Val {
uint64_t u; /* unsigned, address (as integer), bool, char */
int64_t i; /* signed integers, integer literals */
double d; /* float32 (widened) and float64 */
void* p; /* focus target / data pointer */
} Val;
/* A transformation reference: function pointer + parameter count.
Indirect calls and spawns are rejected at runtime unless np == 0. */
typedef struct CrFnRef {
Val (*fn)(void);
int np;
} CrFnRef;
#define CR_FH_MAX 1024
#define CR_SPAWN_MAX 256
#define CR_FILES_MAX 256
typedef struct CrCtx {
Val* stk; /* value stack */
uint64_t sp, cap;
void* fh[CR_FH_MAX]; /* focus history */
uint64_t fh_sp;
FILE* in; /* current input stream (default stdin) */
FILE* out; /* current output stream (default stdout) */
FILE* files[CR_FILES_MAX]; /* open files; slot i has handle i+1 */
unsigned char fmodes[CR_FILES_MAX]; /* 0 read, 1 write, 2 both, 3 append */
pthread_t spawned[CR_SPAWN_MAX];
int nspawned;
} CrCtx;
extern _Thread_local CrCtx cr_ctx;
void crn_init(void);
void crn_die(const char* msg) CRN_NORETURN;
void crn_die_range(uint64_t i, uint64_t n) CRN_NORETURN;
void crn_push(Val v);
Val crn_pop(void);
void crn_focus_push(void* f);
void* crn_focus_pop(void);
void* crn_alloc(uint64_t nbytes);
void crn_free(void* p);
uint64_t crn_block_n(void* data, uint64_t elemsz);
void crn_check_block(void* data, uint64_t i, uint64_t elemsz);
void crn_check_range(uint64_t i, uint64_t n);
/* Relaxed atomic scalar access. Cryn defines a data race on an aligned
scalar cell (<= 8 bytes) as: the access yields an unspecified value of
the cell's type and never tears. To keep that promise (and avoid C data
races, which are undefined behavior), the backend performs every scalar
load/store through these helpers. Racily accessed transform-reference
cells (16 bytes) are undefined. No ordering is provided beyond wait. */
uint8_t crn_ld_u8(const uint8_t* p);
uint16_t crn_ld_u16(const uint16_t* p);
uint32_t crn_ld_u32(const uint32_t* p);
uint64_t crn_ld_u64(const uint64_t* p);
float crn_ld_f32(const float* p);
double crn_ld_f64(const double* p);
void crn_st_u8(uint8_t* p, uint8_t v);
void crn_st_u16(uint16_t* p, uint16_t v);
void crn_st_u32(uint32_t* p, uint32_t v);
void crn_st_u64(uint64_t* p, uint64_t v);
void crn_st_f32(float* p, float v);
void crn_st_f64(double* p, double v);
/* Atomic exchange (acquire-release). `exchange` swaps the working value
with the focused cell in one indivisible step and is the only ordering
primitive besides wait: an exchange that stores a value releases the
accesses that preceded it in program order, and one that loads a value
acquires for the accesses that follow it. It never tears. This is
enough to build locks (test-and-set). */
uint8_t crn_xch_u8(uint8_t* p, uint8_t v);
uint16_t crn_xch_u16(uint16_t* p, uint16_t v);
uint32_t crn_xch_u32(uint32_t* p, uint32_t v);
uint64_t crn_xch_u64(uint64_t* p, uint64_t v);
float crn_xch_f32(float* p, float v);
double crn_xch_f64(double* p, double v);
int64_t crn_d2i64(double d);
uint64_t crn_d2u64(double d);
int64_t crn_d2i8(double d);
int64_t crn_d2i16(double d);
int64_t crn_d2i32(double d);
uint64_t crn_d2u8(double d);
uint64_t crn_d2u16(double d);
uint64_t crn_d2u32(double d);
void crn_out_i64(int64_t v);
void crn_out_u64(uint64_t v);
void crn_out_f64(double v);
void crn_out_f32(float v);
void crn_out_bool(int b);
void crn_out_char(unsigned c);
void crn_out_addr(uint64_t a);
void crn_out_text(uint8_t* p);
int64_t crn_input(void);
/* open modes: 0 read, 1 write, 2 both, 3 append.
Returns a handle >= 1, or -1 on failure. A handle is an index into the
context's file table; closing a handle frees its number for reuse. */
int64_t crn_open(uint8_t* path, int mode);
/* Route this context's streams through a handle: the readable side of the
file becomes the input stream, the writable side the output stream;
sides the mode does not support keep their current stream. Handle 0 is
the standard streams (input: stdin, output: stdout). */
void crn_use(int64_t h);
void crn_flush(void);
/* Position the context's file streams at a byte offset from the start.
Applies fseek(SEEK_SET) to every current stream that belongs to an
open handle (both sides of an 'open both' stream are the same file and
are positioned once). Standard streams are not positionable; if no
current stream belongs to a handle, it is a runtime error. Returns 0
on success and -1 if the position could not be set. */
int64_t crn_seek(int64_t off);
int64_t crn_close(int64_t h);
int64_t crn_system(uint8_t* cmd);
void crn_stop(int64_t code) CRN_NORETURN;
void crn_spawn(CrFnRef* f);
void crn_wait(void);
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
_Thread_local CrCtx cr_ctx = {0};
void crn_init(void) {
memset(&cr_ctx, 0, sizeof cr_ctx);
cr_ctx.in = stdin;
cr_ctx.out = stdout;
}
void crn_die(const char* msg) {
fprintf(stderr, "cryn: runtime error: %s\n", msg);
exit(1);
}
void crn_die_range(uint64_t i, uint64_t n) {
fprintf(stderr, "cryn: runtime error: index %llu out of bounds (size %llu)\n",
(unsigned long long)i, (unsigned long long)n);
exit(1);
}
/* ---- value stack ---- */
void crn_push(Val v) {
if (cr_ctx.sp == cr_ctx.cap) {
cr_ctx.cap = cr_ctx.cap ? cr_ctx.cap * 2 : 64;
cr_ctx.stk = realloc(cr_ctx.stk, cr_ctx.cap * sizeof(Val));
if (!cr_ctx.stk) crn_die("out of memory");
}
cr_ctx.stk[cr_ctx.sp++] = v;
}
Val crn_pop(void) { return cr_ctx.stk[--cr_ctx.sp]; }
/* ---- focus ---- */
void crn_focus_push(void* f) {
if (cr_ctx.fh_sp >= CR_FH_MAX) {
char msg[64];
snprintf(msg, sizeof msg, "focus history overflow (limit %d)", CR_FH_MAX);
crn_die(msg);
}
cr_ctx.fh[cr_ctx.fh_sp++] = f;
}
void* crn_focus_pop(void) {
if (cr_ctx.fh_sp == 0) crn_die("focus history underflow");
return cr_ctx.fh[--cr_ctx.fh_sp];
}
/* ---- heap ---- */
typedef struct CrHdr {
uint64_t magic;
uint64_t size; /* data bytes */
} CrHdr;
#define CR_MAGIC 0x4352594E424C4BULL /* "CRYNBLK" */
/* Registry of live block addresses. Validation must not read the header
of a block that free() may already have returned to the allocator:
reading freed memory is undefined in C, so stale-address detection
(double free, indexing through a freed or shifted address) goes
through this table instead. One global table, mutex protected,
because blocks can be shared across spawned contexts. */
typedef struct CrReg {
void** keys; /* NULL = empty, CR_TOMB = deleted */
size_t cap; /* power of two */
size_t used; /* live + tombstones */
pthread_mutex_t mu;
} CrReg;
#define CR_TOMB ((void*)1)
static CrReg cr_reg = {0, 0, 0, PTHREAD_MUTEX_INITIALIZER};
static pthread_once_t cr_reg_once = PTHREAD_ONCE_INIT;
static size_t reg_slot(void* p, size_t cap) {
uintptr_t x = (uintptr_t)p >> 4; /* malloc blocks are 16-aligned */
x ^= x >> 17;
x *= 0x9E3779B97F4A7C15ULL;
x ^= x >> 29;
return (size_t)x & (cap - 1);
}
static void reg_init(void) {
cr_reg.cap = 256;
cr_reg.keys = malloc(cr_reg.cap * sizeof(void*));
if (!cr_reg.keys) crn_die("out of memory");
memset(cr_reg.keys, 0, cr_reg.cap * sizeof(void*));
cr_reg.used = 0;
}
static void reg_grow_locked(void) {
size_t ncap = cr_reg.cap * 2;
void** nk = malloc(ncap * sizeof(void*));
if (!nk) crn_die("out of memory");
memset(nk, 0, ncap * sizeof(void*));
for (size_t i = 0; i < cr_reg.cap; i++) {
void* k = cr_reg.keys[i];
if (!k || k == CR_TOMB) continue;
size_t j = reg_slot(k, ncap);
while (nk[j]) j = (j + 1) & (ncap - 1);
nk[j] = k;
}
free(cr_reg.keys);
cr_reg.keys = nk;
cr_reg.cap = ncap;
}
/* returns the slot of p, or cap when absent (probing stops at NULL) */
static size_t reg_find_locked(void* p) {
size_t j = reg_slot(p, cr_reg.cap);
for (;;) {
void* k = cr_reg.keys[j];
if (!k) return cr_reg.cap;
if (k == p) return j;
j = (j + 1) & (cr_reg.cap - 1);
}
}
static void reg_add(void* p) {
pthread_once(&cr_reg_once, reg_init);
pthread_mutex_lock(&cr_reg.mu);
if ((cr_reg.used + 1) * 10 >= cr_reg.cap * 7) {
reg_grow_locked();
/* collapse tombstones into the new table */
cr_reg.used = 0;
for (size_t i = 0; i < cr_reg.cap; i++)
if (cr_reg.keys[i]) cr_reg.used++;
}
size_t j = reg_slot(p, cr_reg.cap);
while (cr_reg.keys[j] && cr_reg.keys[j] != CR_TOMB) j = (j + 1) & (cr_reg.cap - 1);
cr_reg.keys[j] = p;
cr_reg.used++;
pthread_mutex_unlock(&cr_reg.mu);
}
static int reg_has(void* p) {
pthread_once(&cr_reg_once, reg_init);
pthread_mutex_lock(&cr_reg.mu);
int found = reg_find_locked(p) != cr_reg.cap;
pthread_mutex_unlock(&cr_reg.mu);
return found;
}
static int reg_take(void* p) {
pthread_once(&cr_reg_once, reg_init);
pthread_mutex_lock(&cr_reg.mu);
size_t j = reg_find_locked(p);
if (j == cr_reg.cap) {
pthread_mutex_unlock(&cr_reg.mu);
return 0;
}
cr_reg.keys[j] = CR_TOMB;
pthread_mutex_unlock(&cr_reg.mu);
return 1;
}
void* crn_alloc(uint64_t nbytes) {
/* the header and padding additions must not wrap */
if (nbytes > (uint64_t)-32) crn_die("allocation too large");
CrHdr* h = malloc(sizeof(CrHdr) + (size_t)nbytes + 16);
if (!h) crn_die("out of memory");
h->magic = CR_MAGIC;
h->size = nbytes;
unsigned char* p = (unsigned char*)h;
p += sizeof(CrHdr);
/* keep data 16-aligned: sizeof(CrHdr)==16 on 64-bit */
memset(p, 0, (size_t)nbytes);
reg_add(p);
return p;
}
void crn_free(void* p) {
if (!p) crn_die("free of the null address");
if (!reg_take(p)) {
crn_die("free of an address that is not a heap block "
"(only live blocks made with 'make <size> of <type>' or anonymous "
"'make' can be freed)");
}
CrHdr* h = (CrHdr*)((unsigned char*)p - sizeof(CrHdr));
h->magic = 0;
free(h);
}
uint64_t crn_block_n(void* data, uint64_t elemsz) {
if (elemsz == 0) elemsz = 1;
if (!reg_has(data)) {
crn_die("index into memory that is not a heap block "
"(only the base address of a live block made with "
"'make <size> of <type>' is bounds checked)");
}
CrHdr* h = (CrHdr*)((unsigned char*)data - sizeof(CrHdr));
return h->size / elemsz;
}
void crn_check_block(void* data, uint64_t i, uint64_t elemsz) {
uint64_t n = crn_block_n(data, elemsz);
if (i >= n) crn_die_range(i, n);
}
void crn_check_range(uint64_t i, uint64_t n) {
if (i >= n) crn_die_range(i, n);
}
/* ---- relaxed atomic scalar access ---- */
#if defined(__GNUC__) || defined(__clang__)
#define CRN_LD(P) __atomic_load_n((P), __ATOMIC_RELAXED)
#define CRN_ST(P, V) __atomic_store_n((P), (V), __ATOMIC_RELAXED)
#else
/* fallback for hosts without the builtins: plain access (single aligned
scalar loads/stores do not tear on such hosts in practice) */
#define CRN_LD(P) (*(P))
#define CRN_ST(P, V) (*(P) = (V))
#endif
uint8_t crn_ld_u8(const uint8_t* p) { return CRN_LD((uint8_t*)p); }
uint16_t crn_ld_u16(const uint16_t* p) { return CRN_LD((uint16_t*)p); }
uint32_t crn_ld_u32(const uint32_t* p) { return CRN_LD((uint32_t*)p); }
uint64_t crn_ld_u64(const uint64_t* p) { return CRN_LD((uint64_t*)p); }
float crn_ld_f32(const float* p) {
uint32_t b = crn_ld_u32((const uint32_t*)(const void*)p);
float v;
memcpy(&v, &b, sizeof v);
return v;
}
double crn_ld_f64(const double* p) {
uint64_t b = crn_ld_u64((const uint64_t*)(const void*)p);
double v;
memcpy(&v, &b, sizeof v);
return v;
}
void crn_st_u8(uint8_t* p, uint8_t v) { CRN_ST(p, v); }
void crn_st_u16(uint16_t* p, uint16_t v) { CRN_ST(p, v); }
void crn_st_u32(uint32_t* p, uint32_t v) { CRN_ST(p, v); }
void crn_st_u64(uint64_t* p, uint64_t v) { CRN_ST(p, v); }
void crn_st_f32(float* p, float v) {
uint32_t b;
memcpy(&b, &v, sizeof b);
crn_st_u32((uint32_t*)(void*)p, b);
}
void crn_st_f64(double* p, double v) {
uint64_t b;
memcpy(&b, &v, sizeof b);
crn_st_u64((uint64_t*)(void*)p, b);
}
/* ---- atomic exchange (acquire-release) ---- */
uint8_t crn_xch_u8(uint8_t* p, uint8_t v) {
#if defined(__GNUC__) || defined(__clang__)
return __atomic_exchange_n(p, v, __ATOMIC_ACQ_REL);
#else
/* fallback for hosts without the builtins: a plain swap (correct for
a single context; such hosts are not targets for racing programs) */
uint8_t t = *p;
*p = v;
return t;
#endif
}
uint16_t crn_xch_u16(uint16_t* p, uint16_t v) {
#if defined(__GNUC__) || defined(__clang__)
return __atomic_exchange_n(p, v, __ATOMIC_ACQ_REL);
#else
uint16_t t = *p;
*p = v;
return t;
#endif
}
uint32_t crn_xch_u32(uint32_t* p, uint32_t v) {
#if defined(__GNUC__) || defined(__clang__)
return __atomic_exchange_n(p, v, __ATOMIC_ACQ_REL);
#else
uint32_t t = *p;
*p = v;
return t;
#endif
}
uint64_t crn_xch_u64(uint64_t* p, uint64_t v) {
#if defined(__GNUC__) || defined(__clang__)
return __atomic_exchange_n(p, v, __ATOMIC_ACQ_REL);
#else
uint64_t t = *p;
*p = v;
return t;
#endif
}
float crn_xch_f32(float* p, float v) {
uint32_t b, nv;
memcpy(&nv, &v, sizeof nv);
b = crn_xch_u32((uint32_t*)(void*)p, nv);
float r;
memcpy(&r, &b, sizeof r);
return r;
}
double crn_xch_f64(double* p, double v) {
uint64_t b, nv;
memcpy(&nv, &v, sizeof nv);
b = crn_xch_u64((uint64_t*)(void*)p, nv);
double r;
memcpy(&r, &b, sizeof r);
return r;
}
/* ---- conversions ---- */
int64_t crn_d2i64(double d) {
if (d >= 9223372036854775808.0) return INT64_MAX;
if (d <= -9223372036854775808.0) return INT64_MIN;
return (int64_t)d;
}
uint64_t crn_d2u64(double d) {
if (d >= 18446744073709551616.0) return UINT64_MAX;
if (d <= 0.0) return 0;
return (uint64_t)d;
}
int64_t crn_d2i8(double d) {
if (d >= 127.0) return 127;
if (d <= -128.0) return -128;
return (int64_t)(int8_t)d;
}
int64_t crn_d2i16(double d) {
if (d >= 32767.0) return 32767;
if (d <= -32768.0) return -32768;
return (int64_t)(int16_t)d;
}
int64_t crn_d2i32(double d) {
if (d >= 2147483648.0) return 2147483647;
if (d <= -2147483649.0) return -2147483648;
return (int64_t)(int32_t)d;
}
uint64_t crn_d2u8(double d) {
if (d >= 255.0) return 255;
if (d <= 0.0) return 0;
return (uint64_t)(uint8_t)d;
}
uint64_t crn_d2u16(double d) {
if (d >= 65535.0) return 65535;
if (d <= 0.0) return 0;
return (uint64_t)(uint16_t)d;
}
uint64_t crn_d2u32(double d) {
if (d >= 4294967296.0) return 4294967295ULL;
if (d <= 0.0) return 0;
return (uint64_t)(uint32_t)d;
}
/* ---- output ---- */
static void crn_out_str(const char* s) { fputs(s, cr_ctx.out); }
void crn_out_i64(int64_t v) { fprintf(cr_ctx.out, "%lld", (long long)v); }
void crn_out_u64(uint64_t v) { fprintf(cr_ctx.out, "%llu", (unsigned long long)v); }
static void crn_out_f(double v, int maxprec) {
char buf[64];
if (v != v) { /* NaN: the sign is meaningless; print one spelling */
crn_out_str("nan");
return;
}
for (int prec = 1; prec <= maxprec; prec++) {
snprintf(buf, sizeof buf, "%.*g", prec, v);
if (strtod(buf, NULL) == v) break;
}
crn_out_str(buf);
}
void crn_out_f64(double v) { crn_out_f(v, 17); }
void crn_out_f32(float v) {
char buf[64];
if (v != v) {
crn_out_str("nan");
return;
}
for (int prec = 1; prec <= 9; prec++) {
snprintf(buf, sizeof buf, "%.*g", prec, v);
if ((float)strtod(buf, NULL) == v) break;
}
crn_out_str(buf);
}
void crn_out_bool(int b) { crn_out_str(b ? "true" : "false"); }
void crn_out_char(unsigned c) { fputc((int)(c & 0xFF), cr_ctx.out); }
void crn_out_addr(uint64_t a) { fprintf(cr_ctx.out, "0x%llx", (unsigned long long)a); }
void crn_out_text(uint8_t* p) {
FILE* f = cr_ctx.out;
while (*p) fputc(*p++, f);
}
/* ---- input / files / system ---- */
int64_t crn_input(void) {
int c = fgetc(cr_ctx.in);
if (c == EOF) return -1;
return c;
}
int64_t crn_open(uint8_t* path, int mode) {
const char* m;
switch (mode) {
case 0: m = "rb"; break;
case 1: m = "wb"; break;
case 2: m = "w+b"; break;
case 3: m = "ab"; break;
default: return -1;
}
FILE* f = fopen((const char*)path, m);
if (!f) return -1;
/* find a free slot; handles are slot+1 */
for (int i = 0; i < CR_FILES_MAX; i++) {
if (cr_ctx.files[i]) continue;
cr_ctx.files[i] = f;
cr_ctx.fmodes[i] = (unsigned char)mode;
return i + 1;
}
fclose(f);
return -1; /* table full */
}
void crn_use(int64_t h) {
if (h == 0) {
cr_ctx.in = stdin;
cr_ctx.out = stdout;
return;
}
if (h < 1 || h > CR_FILES_MAX || !cr_ctx.files[h - 1])
crn_die("use of a handle that is not open in this context "
"(handles come from 'open'; 0 means the standard streams)");
FILE* f = cr_ctx.files[h - 1];
switch (cr_ctx.fmodes[h - 1]) {
case 0: cr_ctx.in = f; break; /* read */
case 2: cr_ctx.in = f; cr_ctx.out = f; break; /* both */
default: cr_ctx.out = f; break; /* write / append */
}
}
void crn_flush(void) {
if (fflush(cr_ctx.out) != 0) crn_die("flush failed");
}
int64_t crn_seek(int64_t off) {
FILE* a = cr_ctx.in;
FILE* b = cr_ctx.out;
int any = 0;
int bad = 0;
/* standard streams are not positionable; only handle streams are */
if (a && a != stdin) {
any = 1;
if (fseek(a, (long)off, SEEK_SET) != 0) bad = 1;
}
if (b && b != a && b != stdout) {
any = 1;
if (fseek(b, (long)off, SEEK_SET) != 0) bad = 1;
}
if (!any)
crn_die("seek requires a stream routed through an open handle "
"('use' a handle from 'open' first)");
return bad ? -1 : 0;
}
int64_t crn_close(int64_t h) {
if (h == 0)
crn_die("close of handle 0 (the standard streams cannot be closed)");
if (h < 1 || h > CR_FILES_MAX || !cr_ctx.files[h - 1])
crn_die("close of a handle that is not open in this context "
"(handles come from 'open' and are closed once)");
FILE* f = cr_ctx.files[h - 1];
cr_ctx.files[h - 1] = NULL;
if (cr_ctx.in == f) cr_ctx.in = stdin;
if (cr_ctx.out == f) cr_ctx.out = stdout;
return fclose(f) == 0 ? 0 : -1;
}
int64_t crn_system(uint8_t* cmd) { return (int64_t)system((const char*)cmd); }
void crn_stop(int64_t code) { exit((int)(code & 0xFF)); }
/* ---- concurrency ---- */
typedef struct CrSpawnArg {
CrFnRef* fn;
} CrSpawnArg;
static void* crn_thread_main(void* argp) {
CrSpawnArg* a = argp;
CrFnRef* fn = a->fn;
free(a);
crn_init();
fn->fn();
return NULL;
}
void crn_spawn(CrFnRef* f) {
if (f->np != 0)
crn_die("spawn of a transformation that takes parameters");
if (cr_ctx.nspawned >= CR_SPAWN_MAX) {
char msg[80];
snprintf(msg, sizeof msg,
"too many outstanding spawned contexts (limit %d)", CR_SPAWN_MAX);
crn_die(msg);
}
CrSpawnArg* a = malloc(sizeof(CrSpawnArg));
if (!a) crn_die("out of memory");
a->fn = f;
if (pthread_create(&cr_ctx.spawned[cr_ctx.nspawned++], NULL, crn_thread_main, a) != 0)
crn_die("thread creation failed");
}
void crn_wait(void) {
for (int i = 0; i < cr_ctx.nspawned; i++)
pthread_join(cr_ctx.spawned[i], NULL);
cr_ctx.nspawned = 0;
}
static uint8_t g_nl[2] = {0};
static int8_t g_c8 = 0;
static uint8_t g_u8 = 0;
static int16_t g_c16 = 0;
static uint16_t g_u16 = 0;
static int32_t g_c32 = 0;
static uint32_t g_u32 = 0;
static int64_t g_c64 = 0;
static uint64_t g_u64 = 0;
static uint8_t g_b = 0;
static uint8_t g_ch = 0;
static float g_f32 = 0;
static double g_f64 = 0;
static const uint8_t g_nl_init[] = "\n\000";
static Val cr_fn_newline(void);
static Val cr_fn_main(void);
static CrFnRef cr_ref_newline = {(Val(*)(void))cr_fn_newline, 0};
static CrFnRef cr_ref_main = {(Val(*)(void))cr_fn_main, 0};
static void crn_init_world(void) {
memcpy(g_nl, g_nl_init, 2);
}
static Val cr_fn_newline(void) {
uint64_t cr_fh0 = cr_ctx.fh_sp;
int cr_cmp = 0;
Val wv; wv.u = 0;
void* F = 0;
wv.u = (uint64_t)(uintptr_t)&g_nl;
crn_out_text((uint8_t*)(uintptr_t)wv.u);
wv.u = (uint64_t)0ULL;
cr_ctx.fh_sp = cr_fh0; return wv;
cr_ctx.fh_sp = cr_fh0; return wv;
}
static Val cr_fn_main(void) {
uint64_t cr_fh0 = cr_ctx.fh_sp;
int cr_cmp = 0;
Val wv; wv.u = 0;
void* F = 0;
wv.u = (uint64_t)18446744073709551607ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c8;
crn_st_u8((uint8_t*)F, (uint8_t)(int64_t)wv.u);
wv.u = (uint64_t)47ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c8;
wv.i = (int64_t)(int8_t)wv.u;
wv.i = (int64_t)(int8_t)crn_xch_u8((uint8_t*)F, (int8_t)wv.i);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
cr_ctx.fh_sp = cr_fh0; F = &g_c8;
wv.i = (int64_t)(int8_t)crn_ld_u8((const uint8_t*)F);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)200ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u8;
crn_st_u8((uint8_t*)F, (uint8_t)(int64_t)wv.u);
wv.u = (uint64_t)1ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u8;
wv.u = (uint64_t)(uint8_t)wv.u;
wv.u = (uint64_t)(uint8_t)crn_xch_u8((uint8_t*)F, (uint8_t)wv.u);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
cr_ctx.fh_sp = cr_fh0; F = &g_u8;
wv.u = (uint64_t)crn_ld_u8((const uint8_t*)F);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)18446744073709550616ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c16;
crn_st_u16((uint16_t*)F, (uint16_t)(int64_t)wv.u);
wv.u = (uint64_t)1000ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c16;
wv.i = (int64_t)(int16_t)wv.u;
wv.i = (int64_t)(int16_t)crn_xch_u16((uint16_t*)F, (int16_t)wv.i);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)60000ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u16;
crn_st_u16((uint16_t*)F, (uint16_t)(int64_t)wv.u);
wv.u = (uint64_t)60001ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u16;
wv.u = (uint64_t)(uint16_t)wv.u;
wv.u = (uint64_t)(uint16_t)crn_xch_u16((uint16_t*)F, (uint16_t)wv.u);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)18446744071709551616ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c32;
crn_st_u32((uint32_t*)F, (uint32_t)(int64_t)wv.u);
wv.u = (uint64_t)7ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c32;
wv.i = (int64_t)(int32_t)wv.u;
wv.i = (int64_t)(int32_t)crn_xch_u32((uint32_t*)F, (int32_t)wv.i);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)4000000000ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u32;
crn_st_u32((uint32_t*)F, (uint32_t)(int64_t)wv.u);
wv.u = (uint64_t)8ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u32;
wv.u = (uint64_t)(uint32_t)wv.u;
wv.u = (uint64_t)(uint32_t)crn_xch_u32((uint32_t*)F, (uint32_t)wv.u);
wv.i = (int64_t)(int64_t)wv.u;
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)18446744068709551616ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c64;
crn_st_u64((uint64_t*)F, (uint64_t)(int64_t)wv.u);
wv.u = (uint64_t)5000000000ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_c64;
wv.i = (int64_t)(int64_t)wv.u;
wv.i = (int64_t)(int64_t)crn_xch_u64((uint64_t*)F, (int64_t)wv.i);
crn_out_i64((int64_t)wv.u);
cr_fn_newline();
wv.u = (uint64_t)18000000000000000000ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u64;
crn_st_u64((uint64_t*)F, (uint64_t)(int64_t)wv.u);
wv.u = (uint64_t)2ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_u64;
wv.u = (uint64_t)(uint64_t)wv.u;
wv.u = (uint64_t)(uint64_t)crn_xch_u64((uint64_t*)F, (uint64_t)wv.u);
crn_out_u64(wv.u);
cr_fn_newline();
wv.u = (uint64_t)0ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_b;
crn_st_u8((uint8_t*)F, (uint8_t)wv.u);
wv.u = (uint64_t)1ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_b;
wv.u = (uint64_t)(uint8_t)crn_xch_u8((uint8_t*)F, (uint8_t)wv.u);
crn_out_bool((int)wv.u);
cr_fn_newline();
cr_ctx.fh_sp = cr_fh0; F = &g_b;
wv.u = (uint64_t)crn_ld_u8((const uint8_t*)F);
crn_out_bool((int)wv.u);
cr_fn_newline();
wv.u = (uint64_t)81ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_ch;
crn_st_u8((uint8_t*)F, (uint8_t)wv.u);
wv.u = (uint64_t)90ULL;
cr_ctx.fh_sp = cr_fh0; F = &g_ch;
wv.u = (uint64_t)(uint8_t)crn_xch_u8((uint8_t*)F, (uint8_t)wv.u);
crn_out_char((unsigned)wv.u);
cr_fn_newline();
wv.d = (double)1.5;
cr_ctx.fh_sp = cr_fh0; F = &g_f32;
crn_st_f32((float*)F, (float)wv.d);
wv.d = (double)2.75;
cr_ctx.fh_sp = cr_fh0; F = &g_f32;
wv.d = (double)(float)wv.d;
wv.d = (double)crn_xch_f32((float*)F, (float)wv.d);
crn_out_f32((float)wv.d);
cr_fn_newline();
cr_ctx.fh_sp = cr_fh0; F = &g_f32;
wv.d = (double)crn_ld_f32((const float*)F);
crn_out_f32((float)wv.d);
cr_fn_newline();
wv.d = (double)0.125;
cr_ctx.fh_sp = cr_fh0; F = &g_f64;
crn_st_f64((double*)F, wv.d);
wv.d = (double)6.5;
cr_ctx.fh_sp = cr_fh0; F = &g_f64;
wv.d = crn_xch_f64((double*)F, wv.d);
crn_out_f64(wv.d);
cr_fn_newline();
wv.u = (uint64_t)0ULL;
cr_ctx.fh_sp = cr_fh0; return wv;
cr_ctx.fh_sp = cr_fh0; return wv;
}
int main(void) {
crn_init();
crn_init_world();
cr_fn_main();
fflush(NULL);
return 0;
}