# WARNING: special-forms.sx declares forms not in eval.sx: reset, shift # WARNING: eval.sx dispatches forms not in special-forms.sx: form? """ sx_ref.py -- Generated from reference SX evaluator specification. Bootstrap-compiled from shared/sx/ref/{eval,render,adapter-html,adapter-sx}.sx Compare against hand-written evaluator.py / html.py for correctness verification. DO NOT EDIT -- regenerate with: python bootstrap_py.py """ from __future__ import annotations import math from typing import Any # ========================================================================= # Types (reuse existing types) # ========================================================================= from shared.sx.types import ( NIL, Symbol, Keyword, Lambda, Component, Island, Continuation, Macro, HandlerDef, QueryDef, ActionDef, PageDef, _ShiftSignal, ) from shared.sx.parser import SxExpr # ========================================================================= # Platform interface -- Python implementation # ========================================================================= class _Thunk: """Deferred evaluation for TCO.""" __slots__ = ("expr", "env") def __init__(self, expr, env): self.expr = expr self.env = env class _RawHTML: """Marker for pre-rendered HTML that should not be escaped.""" __slots__ = ("html",) def __init__(self, html: str): self.html = html def sx_truthy(x): """SX truthiness: everything is truthy except False, None, and NIL.""" if x is False: return False if x is None or x is NIL: return False return True def sx_str(*args): """SX str: concatenate string representations, skipping nil.""" parts = [] for a in args: if a is None or a is NIL: continue parts.append(str(a)) return "".join(parts) def sx_and(*args): """SX and: return last truthy value or first falsy.""" result = True for a in args: if not sx_truthy(a): return a result = a return result def sx_or(*args): """SX or: return first truthy value or last value.""" for a in args: if sx_truthy(a): return a return args[-1] if args else False def _sx_begin(*args): """Evaluate all args (for side effects), return last.""" return args[-1] if args else NIL def _sx_case(match_val, pairs): """Case dispatch: pairs is [(test_val, body_fn), ...]. None test = else.""" for test, body_fn in pairs: if test is None: # :else clause return body_fn() if match_val == test: return body_fn() return NIL def _sx_fn(f): """Identity wrapper for multi-expression lambda bodies.""" return f def type_of(x): if x is None or x is NIL: return "nil" if isinstance(x, bool): return "boolean" if isinstance(x, (int, float)): return "number" if isinstance(x, SxExpr): return "sx-expr" if isinstance(x, str): return "string" if isinstance(x, Symbol): return "symbol" if isinstance(x, Keyword): return "keyword" if isinstance(x, _Thunk): return "thunk" if isinstance(x, Lambda): return "lambda" if isinstance(x, Component): return "component" if isinstance(x, Island): return "island" if isinstance(x, _Signal): return "signal" if isinstance(x, Macro): return "macro" if isinstance(x, _RawHTML): return "raw-html" if isinstance(x, Continuation): return "continuation" if isinstance(x, list): return "list" if isinstance(x, dict): return "dict" return "unknown" def symbol_name(s): return s.name def keyword_name(k): return k.name def make_symbol(n): return Symbol(n) def make_keyword(n): return Keyword(n) def make_lambda(params, body, env): return Lambda(params=list(params), body=body, closure=dict(env)) def make_component(name, params, has_children, body, env, affinity="auto"): return Component(name=name, params=list(params), has_children=has_children, body=body, closure=dict(env), affinity=str(affinity) if affinity else "auto") def make_island(name, params, has_children, body, env): return Island(name=name, params=list(params), has_children=has_children, body=body, closure=dict(env)) def make_macro(params, rest_param, body, env, name=None): return Macro(params=list(params), rest_param=rest_param, body=body, closure=dict(env), name=name) def make_handler_def(name, params, body, env): return HandlerDef(name=name, params=list(params), body=body, closure=dict(env)) def make_query_def(name, params, doc, body, env): return QueryDef(name=name, params=list(params), doc=doc, body=body, closure=dict(env)) def make_action_def(name, params, doc, body, env): return ActionDef(name=name, params=list(params), doc=doc, body=body, closure=dict(env)) def make_page_def(name, slots, env): path = slots.get("path", "") auth_val = slots.get("auth", "public") if isinstance(auth_val, Keyword): auth = auth_val.name elif isinstance(auth_val, list): auth = [item.name if isinstance(item, Keyword) else str(item) for item in auth_val] else: auth = str(auth_val) if auth_val else "public" layout = slots.get("layout") if isinstance(layout, Keyword): layout = layout.name cache = None stream_val = slots.get("stream") stream = bool(trampoline(eval_expr(stream_val, env))) if stream_val is not None else False return PageDef( name=name, path=path, auth=auth, layout=layout, cache=cache, data_expr=slots.get("data"), content_expr=slots.get("content"), filter_expr=slots.get("filter"), aside_expr=slots.get("aside"), menu_expr=slots.get("menu"), stream=stream, fallback_expr=slots.get("fallback"), shell_expr=slots.get("shell"), closure=dict(env), ) def make_thunk(expr, env): return _Thunk(expr, env) def lambda_params(f): return f.params def lambda_body(f): return f.body def lambda_closure(f): return f.closure def lambda_name(f): return f.name def set_lambda_name(f, n): f.name = n def component_params(c): return c.params def component_body(c): return c.body def component_closure(c): return c.closure def component_has_children(c): return c.has_children def component_name(c): return c.name def component_affinity(c): return getattr(c, 'affinity', 'auto') def macro_params(m): return m.params def macro_rest_param(m): return m.rest_param def macro_body(m): return m.body def macro_closure(m): return m.closure def is_thunk(x): return isinstance(x, _Thunk) def thunk_expr(t): return t.expr def thunk_env(t): return t.env def is_callable(x): return callable(x) or isinstance(x, Lambda) def is_lambda(x): return isinstance(x, Lambda) def is_component(x): return isinstance(x, Component) def is_macro(x): return isinstance(x, Macro) def is_island(x): return isinstance(x, Island) def is_identical(a, b): return a is b # ------------------------------------------------------------------------- # Signal platform -- reactive state primitives # ------------------------------------------------------------------------- class _Signal: """Reactive signal container.""" __slots__ = ("value", "subscribers", "deps") def __init__(self, value): self.value = value self.subscribers = [] self.deps = [] class _TrackingContext: """Context for discovering signal dependencies.""" __slots__ = ("notify_fn", "deps") def __init__(self, notify_fn): self.notify_fn = notify_fn self.deps = [] _tracking_context = None def make_signal(value): return _Signal(value) def is_signal(x): return isinstance(x, _Signal) def signal_value(s): return s.value if isinstance(s, _Signal) else s def signal_set_value(s, v): if isinstance(s, _Signal): s.value = v def signal_subscribers(s): return list(s.subscribers) if isinstance(s, _Signal) else [] def signal_add_sub(s, fn): if isinstance(s, _Signal) and fn not in s.subscribers: s.subscribers.append(fn) def signal_remove_sub(s, fn): if isinstance(s, _Signal) and fn in s.subscribers: s.subscribers.remove(fn) def signal_deps(s): return list(s.deps) if isinstance(s, _Signal) else [] def signal_set_deps(s, deps): if isinstance(s, _Signal): s.deps = list(deps) if isinstance(deps, list) else [] def set_tracking_context(ctx): global _tracking_context _tracking_context = ctx def get_tracking_context(): global _tracking_context return _tracking_context if _tracking_context is not None else NIL def make_tracking_context(notify_fn): return _TrackingContext(notify_fn) def tracking_context_deps(ctx): return ctx.deps if isinstance(ctx, _TrackingContext) else [] def tracking_context_add_dep(ctx, s): if isinstance(ctx, _TrackingContext) and s not in ctx.deps: ctx.deps.append(s) def tracking_context_notify_fn(ctx): return ctx.notify_fn if isinstance(ctx, _TrackingContext) else NIL def invoke(f, *args): """Call f with args — handles both native callables and SX lambdas. In Python, all transpiled lambdas are natively callable, so this is just a direct call. The JS host needs dispatch logic here because SX lambdas from runtime-evaluated code are objects, not functions. """ return f(*args) def json_serialize(obj): import json try: return json.dumps(obj) except (TypeError, ValueError): return "{}" def is_empty_dict(d): if not isinstance(d, dict): return True return len(d) == 0 # DOM event primitives — no-ops on server (browser-only). def dom_listen(el, name, handler): return lambda: None def dom_dispatch(el, name, detail=None): return False def event_detail(e): return None def env_has(env, name): return name in env def env_get(env, name): return env.get(name, NIL) def env_set(env, name, val): env[name] = val def env_extend(env): return dict(env) def env_merge(base, overlay): result = dict(base) result.update(overlay) return result def dict_set(d, k, v): d[k] = v def dict_get(d, k): v = d.get(k) return v if v is not None else NIL def dict_has(d, k): return k in d def dict_delete(d, k): d.pop(k, None) def is_render_expr(expr): """Placeholder — overridden by transpiled version from render.sx.""" return False # Render dispatch -- set by adapter _render_expr_fn = None def render_expr(expr, env): if _render_expr_fn: return _render_expr_fn(expr, env) return expr def strip_prefix(s, prefix): return s[len(prefix):] if s.startswith(prefix) else s def error(msg): raise EvalError(msg) def inspect(x): return repr(x) def escape_html(s): s = str(s) return s.replace("&", "&").replace("<", "<").replace(">", ">").replace('"', """) def escape_attr(s): return escape_html(s) def raw_html_content(x): return x.html def make_raw_html(s): return _RawHTML(s) def sx_expr_source(x): return x.source if isinstance(x, SxExpr) else str(x) class EvalError(Exception): pass def _sx_append(lst, item): """Append item to list, return the item (for expression context).""" lst.append(item) return item def _sx_dict_set(d, k, v): """Set key in dict, return the value (for expression context).""" d[k] = v return v def _sx_set_attr(obj, attr, val): """Set attribute on object, return the value.""" setattr(obj, attr, val) return val def _sx_cell_set(cells, name, val): """Set a mutable cell value. Returns the value.""" cells[name] = val return val def escape_string(s): """Escape a string for SX serialization.""" return (str(s) .replace("\\", "\\\\") .replace('"', '\\"') .replace("\n", "\\n") .replace("\t", "\\t") .replace(""] = lambda a, b: a > b PRIMITIVES["<="] = lambda a, b: a <= b PRIMITIVES[">="] = lambda a, b: a >= b # core.logic PRIMITIVES["not"] = lambda x: not sx_truthy(x) # core.predicates PRIMITIVES["nil?"] = lambda x: x is None or x is NIL PRIMITIVES["number?"] = lambda x: isinstance(x, (int, float)) and not isinstance(x, bool) PRIMITIVES["string?"] = lambda x: isinstance(x, str) PRIMITIVES["list?"] = lambda x: isinstance(x, _b_list) PRIMITIVES["dict?"] = lambda x: isinstance(x, _b_dict) PRIMITIVES["continuation?"] = lambda x: isinstance(x, Continuation) PRIMITIVES["empty?"] = lambda c: ( c is None or c is NIL or (isinstance(c, (_b_list, str, _b_dict)) and _b_len(c) == 0) ) PRIMITIVES["contains?"] = lambda c, k: ( str(k) in c if isinstance(c, str) else k in c ) PRIMITIVES["odd?"] = lambda n: n % 2 != 0 PRIMITIVES["even?"] = lambda n: n % 2 == 0 PRIMITIVES["zero?"] = lambda n: n == 0 # core.strings PRIMITIVES["str"] = sx_str PRIMITIVES["upper"] = lambda s: str(s).upper() PRIMITIVES["lower"] = lambda s: str(s).lower() PRIMITIVES["trim"] = lambda s: str(s).strip() PRIMITIVES["split"] = lambda s, sep=" ": str(s).split(sep) PRIMITIVES["join"] = lambda sep, coll: sep.join(coll) PRIMITIVES["replace"] = lambda s, old, new: s.replace(old, new) PRIMITIVES["index-of"] = lambda s, needle, start=0: str(s).find(needle, start) PRIMITIVES["starts-with?"] = lambda s, p: str(s).startswith(p) PRIMITIVES["ends-with?"] = lambda s, p: str(s).endswith(p) PRIMITIVES["slice"] = lambda c, a, b=None: c[a:b] if b is not None else c[a:] PRIMITIVES["concat"] = lambda *args: _b_sum((a for a in args if a), []) # core.collections PRIMITIVES["list"] = lambda *args: _b_list(args) PRIMITIVES["dict"] = lambda *args: {args[i]: args[i+1] for i in _b_range(0, _b_len(args)-1, 2)} PRIMITIVES["range"] = lambda a, b, step=1: _b_list(_b_range(_b_int(a), _b_int(b), _b_int(step))) PRIMITIVES["get"] = lambda c, k, default=NIL: c.get(k, default) if isinstance(c, _b_dict) else (c[k] if isinstance(c, (_b_list, str)) and isinstance(k, _b_int) and 0 <= k < _b_len(c) else (c.get(k, default) if hasattr(c, 'get') else default)) PRIMITIVES["len"] = lambda c: _b_len(c) if c is not None and c is not NIL else 0 PRIMITIVES["first"] = lambda c: c[0] if c and _b_len(c) > 0 else NIL PRIMITIVES["last"] = lambda c: c[-1] if c and _b_len(c) > 0 else NIL PRIMITIVES["rest"] = lambda c: c[1:] if c else [] PRIMITIVES["nth"] = lambda c, n: c[n] if c and 0 <= n < _b_len(c) else NIL PRIMITIVES["cons"] = lambda x, c: [x] + (c or []) PRIMITIVES["append"] = lambda c, x: (c or []) + [x] PRIMITIVES["chunk-every"] = lambda c, n: [c[i:i+n] for i in _b_range(0, _b_len(c), n)] PRIMITIVES["zip-pairs"] = lambda c: [[c[i], c[i+1]] for i in _b_range(_b_len(c)-1)] # core.dict PRIMITIVES["keys"] = lambda d: _b_list((d or {}).keys()) PRIMITIVES["vals"] = lambda d: _b_list((d or {}).values()) PRIMITIVES["merge"] = lambda *args: _sx_merge_dicts(*args) PRIMITIVES["has-key?"] = lambda d, k: isinstance(d, _b_dict) and k in d PRIMITIVES["assoc"] = lambda d, *kvs: _sx_assoc(d, *kvs) PRIMITIVES["dissoc"] = lambda d, *ks: {k: v for k, v in d.items() if k not in ks} PRIMITIVES["into"] = lambda target, coll: (_b_list(coll) if isinstance(target, _b_list) else {p[0]: p[1] for p in coll if isinstance(p, _b_list) and _b_len(p) >= 2}) PRIMITIVES["zip"] = lambda *colls: [_b_list(t) for t in _b_zip(*colls)] def _sx_merge_dicts(*args): out = {} for d in args: if d and d is not NIL and isinstance(d, _b_dict): out.update(d) return out def _sx_assoc(d, *kvs): out = _b_dict(d) if d and d is not NIL else {} for i in _b_range(0, _b_len(kvs) - 1, 2): out[kvs[i]] = kvs[i + 1] return out # stdlib.format PRIMITIVES["format-decimal"] = lambda v, p=2: f"{float(v):.{p}f}" PRIMITIVES["parse-int"] = lambda v, d=0: _sx_parse_int(v, d) PRIMITIVES["parse-datetime"] = lambda s: str(s) if s else NIL def _sx_parse_int(v, default=0): if v is None or v is NIL: return default s = str(v).strip() # Match JS parseInt: extract leading integer portion import re as _re m = _re.match(r'^[+-]?\d+', s) if m: return _b_int(m.group()) return default # stdlib.text PRIMITIVES["pluralize"] = lambda n, s="", p="s": s if n == 1 else p PRIMITIVES["escape"] = escape_html PRIMITIVES["strip-tags"] = lambda s: _strip_tags(str(s)) import re as _re def _strip_tags(s): return _re.sub(r"<[^>]+>", "", s) # stdlib.style — stubs (CSSX needs full runtime) # stdlib.debug PRIMITIVES["assert"] = lambda cond, msg="Assertion failed": (_ for _ in ()).throw(RuntimeError(f"Assertion error: {msg}")) if not sx_truthy(cond) else True def is_primitive(name): if name in PRIMITIVES: return True from shared.sx.primitives import get_primitive as _ext_get return _ext_get(name) is not None def get_primitive(name): p = PRIMITIVES.get(name) if p is not None: return p from shared.sx.primitives import get_primitive as _ext_get return _ext_get(name) # Higher-order helpers used by transpiled code def map(fn, coll): return [fn(x) for x in coll] def map_indexed(fn, coll): return [fn(i, item) for i, item in enumerate(coll)] def filter(fn, coll): return [x for x in coll if sx_truthy(fn(x))] def reduce(fn, init, coll): acc = init for item in coll: acc = fn(acc, item) return acc def some(fn, coll): for item in coll: r = fn(item) if sx_truthy(r): return r return NIL def every_p(fn, coll): for item in coll: if not sx_truthy(fn(item)): return False return True def for_each(fn, coll): for item in coll: fn(item) return NIL def for_each_indexed(fn, coll): for i, item in enumerate(coll): fn(i, item) return NIL def map_dict(fn, d): return {k: fn(k, v) for k, v in d.items()} # Aliases used directly by transpiled code first = PRIMITIVES["first"] last = PRIMITIVES["last"] rest = PRIMITIVES["rest"] nth = PRIMITIVES["nth"] len = PRIMITIVES["len"] is_nil = PRIMITIVES["nil?"] empty_p = PRIMITIVES["empty?"] contains_p = PRIMITIVES["contains?"] starts_with_p = PRIMITIVES["starts-with?"] ends_with_p = PRIMITIVES["ends-with?"] slice = PRIMITIVES["slice"] get = PRIMITIVES["get"] append = PRIMITIVES["append"] cons = PRIMITIVES["cons"] keys = PRIMITIVES["keys"] join = PRIMITIVES["join"] range = PRIMITIVES["range"] apply = lambda f, args: f(*args) assoc = PRIMITIVES["assoc"] concat = PRIMITIVES["concat"] split = PRIMITIVES["split"] length = PRIMITIVES["len"] merge = PRIMITIVES["merge"] trim = PRIMITIVES["trim"] replace = PRIMITIVES["replace"] parse_int = PRIMITIVES["parse-int"] upper = PRIMITIVES["upper"] has_key_p = PRIMITIVES["has-key?"] dissoc = PRIMITIVES["dissoc"] index_of = PRIMITIVES["index-of"] # ========================================================================= # Platform: deps module — component dependency analysis # ========================================================================= import re as _re def component_deps(c): """Return cached deps list for a component (may be empty).""" return list(c.deps) if hasattr(c, "deps") and c.deps else [] def component_set_deps(c, deps): """Cache deps on a component.""" c.deps = set(deps) if not isinstance(deps, set) else deps def component_css_classes(c): """Return pre-scanned CSS class list for a component.""" return list(c.css_classes) if hasattr(c, "css_classes") and c.css_classes else [] def env_components(env): """Placeholder — overridden by transpiled version from deps.sx.""" return [k for k, v in env.items() if isinstance(v, (Component, Macro))] def regex_find_all(pattern, source): """Return list of capture group 1 matches.""" return [m.group(1) for m in _re.finditer(pattern, source)] def scan_css_classes(source): """Extract CSS class strings from SX source.""" classes = set() for m in _re.finditer(r':class\s+"([^"]*)"', source): classes.update(m.group(1).split()) for m in _re.finditer(r':class\s+\(str\s+((?:"[^"]*"\s*)+)\)', source): for s in _re.findall(r'"([^"]*)"', m.group(1)): classes.update(s.split()) for m in _re.finditer(r';;\s*@css\s+(.+)', source): classes.update(m.group(1).split()) return list(classes) def component_io_refs(c): """Return cached IO refs list for a component (may be empty).""" return list(c.io_refs) if hasattr(c, "io_refs") and c.io_refs else [] def component_set_io_refs(c, refs): """Cache IO refs on a component.""" c.io_refs = set(refs) if not isinstance(refs, set) else refs # === Transpiled from eval === # trampoline trampoline = lambda val: (lambda result: (trampoline(eval_expr(thunk_expr(result), thunk_env(result))) if sx_truthy(is_thunk(result)) else result))(val) # eval-expr eval_expr = lambda expr, env: _sx_case(type_of(expr), [('number', lambda: expr), ('string', lambda: expr), ('boolean', lambda: expr), ('nil', lambda: NIL), ('symbol', lambda: (lambda name: (env_get(env, name) if sx_truthy(env_has(env, name)) else (get_primitive(name) if sx_truthy(is_primitive(name)) else (True if sx_truthy((name == 'true')) else (False if sx_truthy((name == 'false')) else (NIL if sx_truthy((name == 'nil')) else error(sx_str('Undefined symbol: ', name))))))))(symbol_name(expr))), ('keyword', lambda: keyword_name(expr)), ('dict', lambda: map_dict(lambda k, v: trampoline(eval_expr(v, env)), expr)), ('list', lambda: ([] if sx_truthy(empty_p(expr)) else eval_list(expr, env))), (None, lambda: expr)]) # eval-list eval_list = lambda expr, env: (lambda head: (lambda args: (map(lambda x: trampoline(eval_expr(x, env)), expr) if sx_truthy((not sx_truthy(((type_of(head) == 'symbol') if sx_truthy((type_of(head) == 'symbol')) else ((type_of(head) == 'lambda') if sx_truthy((type_of(head) == 'lambda')) else (type_of(head) == 'list')))))) else ((lambda name: (sf_if(args, env) if sx_truthy((name == 'if')) else (sf_when(args, env) if sx_truthy((name == 'when')) else (sf_cond(args, env) if sx_truthy((name == 'cond')) else (sf_case(args, env) if sx_truthy((name == 'case')) else (sf_and(args, env) if sx_truthy((name == 'and')) else (sf_or(args, env) if sx_truthy((name == 'or')) else (sf_let(args, env) if sx_truthy((name == 'let')) else (sf_let(args, env) if sx_truthy((name == 'let*')) else (sf_letrec(args, env) if sx_truthy((name == 'letrec')) else (sf_lambda(args, env) if sx_truthy((name == 'lambda')) else (sf_lambda(args, env) if sx_truthy((name == 'fn')) else (sf_define(args, env) if sx_truthy((name == 'define')) else (sf_defcomp(args, env) if sx_truthy((name == 'defcomp')) else (sf_defisland(args, env) if sx_truthy((name == 'defisland')) else (sf_defmacro(args, env) if sx_truthy((name == 'defmacro')) else (sf_defstyle(args, env) if sx_truthy((name == 'defstyle')) else (sf_defhandler(args, env) if sx_truthy((name == 'defhandler')) else (sf_defpage(args, env) if sx_truthy((name == 'defpage')) else (sf_defquery(args, env) if sx_truthy((name == 'defquery')) else (sf_defaction(args, env) if sx_truthy((name == 'defaction')) else (sf_begin(args, env) if sx_truthy((name == 'begin')) else (sf_begin(args, env) if sx_truthy((name == 'do')) else (sf_quote(args, env) if sx_truthy((name == 'quote')) else (sf_quasiquote(args, env) if sx_truthy((name == 'quasiquote')) else (sf_thread_first(args, env) if sx_truthy((name == '->')) else (sf_set_bang(args, env) if sx_truthy((name == 'set!')) else (sf_reset(args, env) if sx_truthy((name == 'reset')) else (sf_shift(args, env) if sx_truthy((name == 'shift')) else (sf_dynamic_wind(args, env) if sx_truthy((name == 'dynamic-wind')) else (ho_map(args, env) if sx_truthy((name == 'map')) else (ho_map_indexed(args, env) if sx_truthy((name == 'map-indexed')) else (ho_filter(args, env) if sx_truthy((name == 'filter')) else (ho_reduce(args, env) if sx_truthy((name == 'reduce')) else (ho_some(args, env) if sx_truthy((name == 'some')) else (ho_every(args, env) if sx_truthy((name == 'every?')) else (ho_for_each(args, env) if sx_truthy((name == 'for-each')) else ((lambda mac: make_thunk(expand_macro(mac, args, env), env))(env_get(env, name)) if sx_truthy((env_has(env, name) if not sx_truthy(env_has(env, name)) else is_macro(env_get(env, name)))) else (render_expr(expr, env) if sx_truthy(is_render_expr(expr)) else eval_call(head, args, env))))))))))))))))))))))))))))))))))))))))(symbol_name(head)) if sx_truthy((type_of(head) == 'symbol')) else eval_call(head, args, env))))(rest(expr)))(first(expr)) # eval-call eval_call = lambda head, args, env: (lambda f: (lambda evaluated_args: (apply(f, evaluated_args) if sx_truthy((is_callable(f) if not sx_truthy(is_callable(f)) else ((not sx_truthy(is_lambda(f))) if not sx_truthy((not sx_truthy(is_lambda(f)))) else ((not sx_truthy(is_component(f))) if not sx_truthy((not sx_truthy(is_component(f)))) else (not sx_truthy(is_island(f))))))) else (call_lambda(f, evaluated_args, env) if sx_truthy(is_lambda(f)) else (call_component(f, args, env) if sx_truthy(is_component(f)) else (call_component(f, args, env) if sx_truthy(is_island(f)) else error(sx_str('Not callable: ', inspect(f))))))))(map(lambda a: trampoline(eval_expr(a, env)), args)))(trampoline(eval_expr(head, env))) # call-lambda call_lambda = lambda f, args, caller_env: (lambda params: (lambda local: (error(sx_str((lambda_name(f) if sx_truthy(lambda_name(f)) else 'lambda'), ' expects ', len(params), ' args, got ', len(args))) if sx_truthy((len(args) != len(params))) else _sx_begin(for_each(lambda pair: _sx_dict_set(local, first(pair), nth(pair, 1)), zip(params, args)), make_thunk(lambda_body(f), local))))(env_merge(lambda_closure(f), caller_env)))(lambda_params(f)) # call-component call_component = lambda comp, raw_args, env: (lambda parsed: (lambda kwargs: (lambda children: (lambda local: _sx_begin(for_each(lambda p: _sx_dict_set(local, p, (dict_get(kwargs, p) if sx_truthy(dict_get(kwargs, p)) else NIL)), component_params(comp)), (_sx_dict_set(local, 'children', children) if sx_truthy(component_has_children(comp)) else NIL), make_thunk(component_body(comp), local)))(env_merge(component_closure(comp), env)))(nth(parsed, 1)))(first(parsed)))(parse_keyword_args(raw_args, env)) # parse-keyword-args parse_keyword_args = lambda raw_args, env: (lambda kwargs: (lambda children: (lambda i: _sx_begin(reduce(lambda state, arg: (lambda idx: (lambda skip: (assoc(state, 'skip', False, 'i', (idx + 1)) if sx_truthy(skip) else (_sx_begin(_sx_dict_set(kwargs, keyword_name(arg), trampoline(eval_expr(nth(raw_args, (idx + 1)), env))), assoc(state, 'skip', True, 'i', (idx + 1))) if sx_truthy(((type_of(arg) == 'keyword') if not sx_truthy((type_of(arg) == 'keyword')) else ((idx + 1) < len(raw_args)))) else _sx_begin(_sx_append(children, trampoline(eval_expr(arg, env))), assoc(state, 'i', (idx + 1))))))(get(state, 'skip')))(get(state, 'i')), {'i': 0, 'skip': False}, raw_args), [kwargs, children]))(0))([]))({}) # sf-if sf_if = lambda args, env: (lambda condition: (make_thunk(nth(args, 1), env) if sx_truthy((condition if not sx_truthy(condition) else (not sx_truthy(is_nil(condition))))) else (make_thunk(nth(args, 2), env) if sx_truthy((len(args) > 2)) else NIL)))(trampoline(eval_expr(first(args), env))) # sf-when sf_when = lambda args, env: (lambda condition: (_sx_begin(for_each(lambda e: trampoline(eval_expr(e, env)), slice(args, 1, (len(args) - 1))), make_thunk(last(args), env)) if sx_truthy((condition if not sx_truthy(condition) else (not sx_truthy(is_nil(condition))))) else NIL))(trampoline(eval_expr(first(args), env))) # sf-cond sf_cond = lambda args, env: (sf_cond_scheme(args, env) if sx_truthy(((type_of(first(args)) == 'list') if not sx_truthy((type_of(first(args)) == 'list')) else (len(first(args)) == 2))) else sf_cond_clojure(args, env)) # sf-cond-scheme sf_cond_scheme = lambda clauses, env: (NIL if sx_truthy(empty_p(clauses)) else (lambda clause: (lambda test: (lambda body: (make_thunk(body, env) if sx_truthy((((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else'))) if sx_truthy(((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else')))) else ((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else')))) else (make_thunk(body, env) if sx_truthy(trampoline(eval_expr(test, env))) else sf_cond_scheme(rest(clauses), env))))(nth(clause, 1)))(first(clause)))(first(clauses))) # sf-cond-clojure sf_cond_clojure = lambda clauses, env: (NIL if sx_truthy((len(clauses) < 2)) else (lambda test: (lambda body: (make_thunk(body, env) if sx_truthy((((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else')) if sx_truthy(((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else'))) else ((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else'))))) else (make_thunk(body, env) if sx_truthy(trampoline(eval_expr(test, env))) else sf_cond_clojure(slice(clauses, 2), env))))(nth(clauses, 1)))(first(clauses))) # sf-case sf_case = lambda args, env: (lambda match_val: (lambda clauses: sf_case_loop(match_val, clauses, env))(rest(args)))(trampoline(eval_expr(first(args), env))) # sf-case-loop sf_case_loop = lambda match_val, clauses, env: (NIL if sx_truthy((len(clauses) < 2)) else (lambda test: (lambda body: (make_thunk(body, env) if sx_truthy((((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else')) if sx_truthy(((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else'))) else ((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else'))))) else (make_thunk(body, env) if sx_truthy((match_val == trampoline(eval_expr(test, env)))) else sf_case_loop(match_val, slice(clauses, 2), env))))(nth(clauses, 1)))(first(clauses))) # sf-and sf_and = lambda args, env: (True if sx_truthy(empty_p(args)) else (lambda val: (val if sx_truthy((not sx_truthy(val))) else (val if sx_truthy((len(args) == 1)) else sf_and(rest(args), env))))(trampoline(eval_expr(first(args), env)))) # sf-or sf_or = lambda args, env: (False if sx_truthy(empty_p(args)) else (lambda val: (val if sx_truthy(val) else sf_or(rest(args), env)))(trampoline(eval_expr(first(args), env)))) # sf-let sf_let = lambda args, env: (sf_named_let(args, env) if sx_truthy((type_of(first(args)) == 'symbol')) else (lambda bindings: (lambda body: (lambda local: _sx_begin((for_each(lambda binding: (lambda vname: _sx_dict_set(local, vname, trampoline(eval_expr(nth(binding, 1), local))))((symbol_name(first(binding)) if sx_truthy((type_of(first(binding)) == 'symbol')) else first(binding))), bindings) if sx_truthy(((type_of(first(bindings)) == 'list') if not sx_truthy((type_of(first(bindings)) == 'list')) else (len(first(bindings)) == 2))) else (lambda i: reduce(lambda acc, pair_idx: (lambda vname: (lambda val_expr: _sx_dict_set(local, vname, trampoline(eval_expr(val_expr, local))))(nth(bindings, ((pair_idx * 2) + 1))))((symbol_name(nth(bindings, (pair_idx * 2))) if sx_truthy((type_of(nth(bindings, (pair_idx * 2))) == 'symbol')) else nth(bindings, (pair_idx * 2)))), NIL, range(0, (len(bindings) / 2))))(0)), for_each(lambda e: trampoline(eval_expr(e, local)), slice(body, 0, (len(body) - 1))), make_thunk(last(body), local)))(env_extend(env)))(rest(args)))(first(args))) # sf-named-let sf_named_let = lambda args, env: (lambda loop_name: (lambda bindings: (lambda body: (lambda params: (lambda inits: _sx_begin((for_each(_sx_fn(lambda binding: ( _sx_append(params, (symbol_name(first(binding)) if sx_truthy((type_of(first(binding)) == 'symbol')) else first(binding))), _sx_append(inits, nth(binding, 1)) )[-1]), bindings) if sx_truthy(((type_of(first(bindings)) == 'list') if not sx_truthy((type_of(first(bindings)) == 'list')) else (len(first(bindings)) == 2))) else reduce(lambda acc, pair_idx: _sx_begin(_sx_append(params, (symbol_name(nth(bindings, (pair_idx * 2))) if sx_truthy((type_of(nth(bindings, (pair_idx * 2))) == 'symbol')) else nth(bindings, (pair_idx * 2)))), _sx_append(inits, nth(bindings, ((pair_idx * 2) + 1)))), NIL, range(0, (len(bindings) / 2)))), (lambda loop_body: (lambda loop_fn: _sx_begin(_sx_set_attr(loop_fn, 'name', loop_name), _sx_dict_set(lambda_closure(loop_fn), loop_name, loop_fn), (lambda init_vals: call_lambda(loop_fn, init_vals, env))(map(lambda e: trampoline(eval_expr(e, env)), inits))))(make_lambda(params, loop_body, env)))((first(body) if sx_truthy((len(body) == 1)) else cons(make_symbol('begin'), body)))))([]))([]))(slice(args, 2)))(nth(args, 1)))(symbol_name(first(args))) # sf-lambda sf_lambda = lambda args, env: (lambda params_expr: (lambda body: (lambda param_names: make_lambda(param_names, body, env))(map(lambda p: (symbol_name(p) if sx_truthy((type_of(p) == 'symbol')) else p), params_expr)))(nth(args, 1)))(first(args)) # sf-define sf_define = lambda args, env: (lambda name_sym: (lambda value: _sx_begin((_sx_set_attr(value, 'name', symbol_name(name_sym)) if sx_truthy((is_lambda(value) if not sx_truthy(is_lambda(value)) else is_nil(lambda_name(value)))) else NIL), _sx_dict_set(env, symbol_name(name_sym), value), value))(trampoline(eval_expr(nth(args, 1), env))))(first(args)) # sf-defcomp sf_defcomp = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda body: (lambda comp_name: (lambda parsed: (lambda params: (lambda has_children: (lambda affinity: (lambda comp: _sx_begin(_sx_dict_set(env, symbol_name(name_sym), comp), comp))(make_component(comp_name, params, has_children, body, env, affinity)))(defcomp_kwarg(args, 'affinity', 'auto')))(nth(parsed, 1)))(first(parsed)))(parse_comp_params(params_raw)))(strip_prefix(symbol_name(name_sym), '~')))(last(args)))(nth(args, 1)))(first(args)) # defcomp-kwarg def defcomp_kwarg(args, key, default_): _cells = {} end = (len(args) - 1) _cells['result'] = default_ for i in range(2, end, 1): if sx_truthy(((type_of(nth(args, i)) == 'keyword') if not sx_truthy((type_of(nth(args, i)) == 'keyword')) else ((keyword_name(nth(args, i)) == key) if not sx_truthy((keyword_name(nth(args, i)) == key)) else ((i + 1) < end)))): val = nth(args, (i + 1)) _cells['result'] = (keyword_name(val) if sx_truthy((type_of(val) == 'keyword')) else val) return _cells['result'] # parse-comp-params def parse_comp_params(params_expr): _cells = {} params = [] _cells['has_children'] = False _cells['in_key'] = False for p in params_expr: if sx_truthy((type_of(p) == 'symbol')): name = symbol_name(p) if sx_truthy((name == '&key')): _cells['in_key'] = True elif sx_truthy((name == '&rest')): _cells['has_children'] = True elif sx_truthy((name == '&children')): _cells['has_children'] = True elif sx_truthy(_cells['has_children']): NIL elif sx_truthy(_cells['in_key']): params.append(name) else: params.append(name) return [params, _cells['has_children']] # sf-defisland sf_defisland = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda body: (lambda comp_name: (lambda parsed: (lambda params: (lambda has_children: (lambda island: _sx_begin(_sx_dict_set(env, symbol_name(name_sym), island), island))(make_island(comp_name, params, has_children, body, env)))(nth(parsed, 1)))(first(parsed)))(parse_comp_params(params_raw)))(strip_prefix(symbol_name(name_sym), '~')))(last(args)))(nth(args, 1)))(first(args)) # sf-defmacro sf_defmacro = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda body: (lambda parsed: (lambda params: (lambda rest_param: (lambda mac: _sx_begin(_sx_dict_set(env, symbol_name(name_sym), mac), mac))(make_macro(params, rest_param, body, env, symbol_name(name_sym))))(nth(parsed, 1)))(first(parsed)))(parse_macro_params(params_raw)))(nth(args, 2)))(nth(args, 1)))(first(args)) # parse-macro-params def parse_macro_params(params_expr): _cells = {} params = [] _cells['rest_param'] = NIL reduce(lambda state, p: (assoc(state, 'in-rest', True) if sx_truthy(((type_of(p) == 'symbol') if not sx_truthy((type_of(p) == 'symbol')) else (symbol_name(p) == '&rest'))) else (_sx_begin(_sx_cell_set(_cells, 'rest_param', (symbol_name(p) if sx_truthy((type_of(p) == 'symbol')) else p)), state) if sx_truthy(get(state, 'in-rest')) else _sx_begin(_sx_append(params, (symbol_name(p) if sx_truthy((type_of(p) == 'symbol')) else p)), state))), {'in-rest': False}, params_expr) return [params, _cells['rest_param']] # sf-defstyle sf_defstyle = lambda args, env: (lambda name_sym: (lambda value: _sx_begin(_sx_dict_set(env, symbol_name(name_sym), value), value))(trampoline(eval_expr(nth(args, 1), env))))(first(args)) # sf-begin sf_begin = lambda args, env: (NIL if sx_truthy(empty_p(args)) else _sx_begin(for_each(lambda e: trampoline(eval_expr(e, env)), slice(args, 0, (len(args) - 1))), make_thunk(last(args), env))) # sf-quote sf_quote = lambda args, env: (NIL if sx_truthy(empty_p(args)) else first(args)) # sf-quasiquote sf_quasiquote = lambda args, env: qq_expand(first(args), env) # qq-expand qq_expand = lambda template, env: (template if sx_truthy((not sx_truthy((type_of(template) == 'list')))) else ([] if sx_truthy(empty_p(template)) else (lambda head: (trampoline(eval_expr(nth(template, 1), env)) if sx_truthy(((type_of(head) == 'symbol') if not sx_truthy((type_of(head) == 'symbol')) else (symbol_name(head) == 'unquote'))) else reduce(lambda result, item: ((lambda spliced: (concat(result, spliced) if sx_truthy((type_of(spliced) == 'list')) else (result if sx_truthy(is_nil(spliced)) else append(result, spliced))))(trampoline(eval_expr(nth(item, 1), env))) if sx_truthy(((type_of(item) == 'list') if not sx_truthy((type_of(item) == 'list')) else ((len(item) == 2) if not sx_truthy((len(item) == 2)) else ((type_of(first(item)) == 'symbol') if not sx_truthy((type_of(first(item)) == 'symbol')) else (symbol_name(first(item)) == 'splice-unquote'))))) else append(result, qq_expand(item, env))), [], template)))(first(template)))) # sf-thread-first sf_thread_first = lambda args, env: (lambda val: reduce(lambda result, form: ((lambda f: (lambda rest_args: (lambda all_args: (apply(f, all_args) if sx_truthy((is_callable(f) if not sx_truthy(is_callable(f)) else (not sx_truthy(is_lambda(f))))) else (trampoline(call_lambda(f, all_args, env)) if sx_truthy(is_lambda(f)) else error(sx_str('-> form not callable: ', inspect(f))))))(cons(result, rest_args)))(map(lambda a: trampoline(eval_expr(a, env)), rest(form))))(trampoline(eval_expr(first(form), env))) if sx_truthy((type_of(form) == 'list')) else (lambda f: (f(result) if sx_truthy((is_callable(f) if not sx_truthy(is_callable(f)) else (not sx_truthy(is_lambda(f))))) else (trampoline(call_lambda(f, [result], env)) if sx_truthy(is_lambda(f)) else error(sx_str('-> form not callable: ', inspect(f))))))(trampoline(eval_expr(form, env)))), val, rest(args)))(trampoline(eval_expr(first(args), env))) # sf-set! sf_set_bang = lambda args, env: (lambda name: (lambda value: _sx_begin(_sx_dict_set(env, name, value), value))(trampoline(eval_expr(nth(args, 1), env))))(symbol_name(first(args))) # sf-letrec sf_letrec = lambda args, env: (lambda bindings: (lambda body: (lambda local: (lambda names: (lambda val_exprs: _sx_begin((for_each(lambda binding: (lambda vname: _sx_begin(_sx_append(names, vname), _sx_append(val_exprs, nth(binding, 1)), _sx_dict_set(local, vname, NIL)))((symbol_name(first(binding)) if sx_truthy((type_of(first(binding)) == 'symbol')) else first(binding))), bindings) if sx_truthy(((type_of(first(bindings)) == 'list') if not sx_truthy((type_of(first(bindings)) == 'list')) else (len(first(bindings)) == 2))) else reduce(lambda acc, pair_idx: (lambda vname: (lambda val_expr: _sx_begin(_sx_append(names, vname), _sx_append(val_exprs, val_expr), _sx_dict_set(local, vname, NIL)))(nth(bindings, ((pair_idx * 2) + 1))))((symbol_name(nth(bindings, (pair_idx * 2))) if sx_truthy((type_of(nth(bindings, (pair_idx * 2))) == 'symbol')) else nth(bindings, (pair_idx * 2)))), NIL, range(0, (len(bindings) / 2)))), (lambda values: _sx_begin(for_each(lambda pair: _sx_dict_set(local, first(pair), nth(pair, 1)), zip(names, values)), for_each(lambda val: (for_each(lambda n: _sx_dict_set(lambda_closure(val), n, env_get(local, n)), names) if sx_truthy(is_lambda(val)) else NIL), values)))(map(lambda e: trampoline(eval_expr(e, local)), val_exprs)), for_each(lambda e: trampoline(eval_expr(e, local)), slice(body, 0, (len(body) - 1))), make_thunk(last(body), local)))([]))([]))(env_extend(env)))(rest(args)))(first(args)) # sf-dynamic-wind sf_dynamic_wind = lambda args, env: (lambda before: (lambda body: (lambda after: _sx_begin(call_thunk(before, env), push_wind_b(before, after), (lambda result: _sx_begin(pop_wind_b(), call_thunk(after, env), result))(call_thunk(body, env))))(trampoline(eval_expr(nth(args, 2), env))))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # expand-macro expand_macro = lambda mac, raw_args, env: (lambda local: _sx_begin(for_each(lambda pair: _sx_dict_set(local, first(pair), (nth(raw_args, nth(pair, 1)) if sx_truthy((nth(pair, 1) < len(raw_args))) else NIL)), map_indexed(lambda i, p: [p, i], macro_params(mac))), (_sx_dict_set(local, macro_rest_param(mac), slice(raw_args, len(macro_params(mac)))) if sx_truthy(macro_rest_param(mac)) else NIL), trampoline(eval_expr(macro_body(mac), local))))(env_merge(macro_closure(mac), env)) # call-fn call_fn = lambda f, args, env: (trampoline(call_lambda(f, args, env)) if sx_truthy(is_lambda(f)) else (apply(f, args) if sx_truthy(is_callable(f)) else error(sx_str('Not callable in HO form: ', inspect(f))))) # ho-map ho_map = lambda args, env: (lambda f: (lambda coll: map(lambda item: call_fn(f, [item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-map-indexed ho_map_indexed = lambda args, env: (lambda f: (lambda coll: map_indexed(lambda i, item: call_fn(f, [i, item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-filter ho_filter = lambda args, env: (lambda f: (lambda coll: filter(lambda item: call_fn(f, [item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-reduce ho_reduce = lambda args, env: (lambda f: (lambda init: (lambda coll: reduce(lambda acc, item: call_fn(f, [acc, item], env), init, coll))(trampoline(eval_expr(nth(args, 2), env))))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-some ho_some = lambda args, env: (lambda f: (lambda coll: some(lambda item: call_fn(f, [item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-every ho_every = lambda args, env: (lambda f: (lambda coll: every_p(lambda item: call_fn(f, [item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # ho-for-each ho_for_each = lambda args, env: (lambda f: (lambda coll: for_each(lambda item: call_fn(f, [item], env), coll))(trampoline(eval_expr(nth(args, 1), env))))(trampoline(eval_expr(first(args), env))) # === Transpiled from forms (server definition forms) === # parse-key-params def parse_key_params(params_expr): _cells = {} params = [] _cells['in_key'] = False for p in params_expr: if sx_truthy((type_of(p) == 'symbol')): name = symbol_name(p) if sx_truthy((name == '&key')): _cells['in_key'] = True elif sx_truthy(_cells['in_key']): params.append(name) else: params.append(name) return params # sf-defhandler sf_defhandler = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda body: (lambda name: (lambda params: (lambda hdef: _sx_begin(_sx_dict_set(env, sx_str('handler:', name), hdef), hdef))(make_handler_def(name, params, body, env)))(parse_key_params(params_raw)))(symbol_name(name_sym)))(nth(args, 2)))(nth(args, 1)))(first(args)) # sf-defquery sf_defquery = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda name: (lambda params: (lambda has_doc: (lambda doc: (lambda body: (lambda qdef: _sx_begin(_sx_dict_set(env, sx_str('query:', name), qdef), qdef))(make_query_def(name, params, doc, body, env)))((nth(args, 3) if sx_truthy(has_doc) else nth(args, 2))))((nth(args, 2) if sx_truthy(has_doc) else '')))(((len(args) >= 4) if not sx_truthy((len(args) >= 4)) else (type_of(nth(args, 2)) == 'string'))))(parse_key_params(params_raw)))(symbol_name(name_sym)))(nth(args, 1)))(first(args)) # sf-defaction sf_defaction = lambda args, env: (lambda name_sym: (lambda params_raw: (lambda name: (lambda params: (lambda has_doc: (lambda doc: (lambda body: (lambda adef: _sx_begin(_sx_dict_set(env, sx_str('action:', name), adef), adef))(make_action_def(name, params, doc, body, env)))((nth(args, 3) if sx_truthy(has_doc) else nth(args, 2))))((nth(args, 2) if sx_truthy(has_doc) else '')))(((len(args) >= 4) if not sx_truthy((len(args) >= 4)) else (type_of(nth(args, 2)) == 'string'))))(parse_key_params(params_raw)))(symbol_name(name_sym)))(nth(args, 1)))(first(args)) # sf-defpage sf_defpage = lambda args, env: (lambda name_sym: (lambda name: (lambda slots: _sx_begin((lambda i: (lambda max_i: for_each(lambda idx: ((_sx_dict_set(slots, keyword_name(nth(args, idx)), nth(args, (idx + 1))) if sx_truthy(((idx + 1) < max_i)) else NIL) if sx_truthy(((idx < max_i) if not sx_truthy((idx < max_i)) else (type_of(nth(args, idx)) == 'keyword'))) else NIL), range(1, max_i, 2)))(len(args)))(1), (lambda pdef: _sx_begin(_sx_dict_set(env, sx_str('page:', name), pdef), pdef))(make_page_def(name, slots, env))))({}))(symbol_name(name_sym)))(first(args)) # stream-chunk-id stream_chunk_id = lambda chunk: (get(chunk, 'stream-id') if sx_truthy(has_key_p(chunk, 'stream-id')) else 'stream-content') # stream-chunk-bindings stream_chunk_bindings = lambda chunk: dissoc(chunk, 'stream-id') # normalize-binding-key normalize_binding_key = lambda key: replace(key, '_', '-') # bind-stream-chunk bind_stream_chunk = lambda chunk, base_env: (lambda env: (lambda bindings: _sx_begin(for_each(lambda key: _sx_dict_set(env, normalize_binding_key(key), get(bindings, key)), keys(bindings)), env))(stream_chunk_bindings(chunk)))(merge({}, base_env)) # validate-stream-data validate_stream_data = lambda data: ((type_of(data) == 'list') if not sx_truthy((type_of(data) == 'list')) else every_p(lambda item: (type_of(item) == 'dict'), data)) # === Transpiled from render (core) === # HTML_TAGS HTML_TAGS = ['html', 'head', 'body', 'title', 'meta', 'link', 'script', 'style', 'noscript', 'header', 'nav', 'main', 'section', 'article', 'aside', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'div', 'p', 'blockquote', 'pre', 'figure', 'figcaption', 'address', 'details', 'summary', 'a', 'span', 'em', 'strong', 'small', 'b', 'i', 'u', 's', 'mark', 'sub', 'sup', 'abbr', 'cite', 'code', 'time', 'br', 'wbr', 'hr', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'caption', 'colgroup', 'col', 'form', 'input', 'textarea', 'select', 'option', 'optgroup', 'button', 'label', 'fieldset', 'legend', 'output', 'datalist', 'img', 'video', 'audio', 'source', 'picture', 'canvas', 'iframe', 'svg', 'math', 'path', 'circle', 'ellipse', 'rect', 'line', 'polyline', 'polygon', 'text', 'tspan', 'g', 'defs', 'use', 'clipPath', 'mask', 'pattern', 'linearGradient', 'radialGradient', 'stop', 'filter', 'feGaussianBlur', 'feOffset', 'feBlend', 'feColorMatrix', 'feComposite', 'feMerge', 'feMergeNode', 'feTurbulence', 'feComponentTransfer', 'feFuncR', 'feFuncG', 'feFuncB', 'feFuncA', 'feDisplacementMap', 'feFlood', 'feImage', 'feMorphology', 'feSpecularLighting', 'feDiffuseLighting', 'fePointLight', 'feSpotLight', 'feDistantLight', 'animate', 'animateTransform', 'foreignObject', 'template', 'slot', 'dialog', 'menu'] # VOID_ELEMENTS VOID_ELEMENTS = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'] # BOOLEAN_ATTRS BOOLEAN_ATTRS = ['async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'inert', 'ismap', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected'] # definition-form? is_definition_form = lambda name: ((name == 'define') if sx_truthy((name == 'define')) else ((name == 'defcomp') if sx_truthy((name == 'defcomp')) else ((name == 'defisland') if sx_truthy((name == 'defisland')) else ((name == 'defmacro') if sx_truthy((name == 'defmacro')) else ((name == 'defstyle') if sx_truthy((name == 'defstyle')) else (name == 'defhandler')))))) # parse-element-args parse_element_args = lambda args, env: (lambda attrs: (lambda children: _sx_begin(reduce(lambda state, arg: (lambda skip: (assoc(state, 'skip', False, 'i', (get(state, 'i') + 1)) if sx_truthy(skip) else ((lambda val: _sx_begin(_sx_dict_set(attrs, keyword_name(arg), val), assoc(state, 'skip', True, 'i', (get(state, 'i') + 1))))(trampoline(eval_expr(nth(args, (get(state, 'i') + 1)), env))) if sx_truthy(((type_of(arg) == 'keyword') if not sx_truthy((type_of(arg) == 'keyword')) else ((get(state, 'i') + 1) < len(args)))) else _sx_begin(_sx_append(children, arg), assoc(state, 'i', (get(state, 'i') + 1))))))(get(state, 'skip')), {'i': 0, 'skip': False}, args), [attrs, children]))([]))({}) # render-attrs render_attrs = lambda attrs: join('', map(lambda key: (lambda val: (sx_str(' ', key) if sx_truthy((contains_p(BOOLEAN_ATTRS, key) if not sx_truthy(contains_p(BOOLEAN_ATTRS, key)) else val)) else ('' if sx_truthy((contains_p(BOOLEAN_ATTRS, key) if not sx_truthy(contains_p(BOOLEAN_ATTRS, key)) else (not sx_truthy(val)))) else ('' if sx_truthy(is_nil(val)) else sx_str(' ', key, '="', escape_attr(sx_str(val)), '"')))))(dict_get(attrs, key)), keys(attrs))) # eval-cond eval_cond = lambda clauses, env: (eval_cond_scheme(clauses, env) if sx_truthy(((not sx_truthy(empty_p(clauses))) if not sx_truthy((not sx_truthy(empty_p(clauses)))) else ((type_of(first(clauses)) == 'list') if not sx_truthy((type_of(first(clauses)) == 'list')) else (len(first(clauses)) == 2)))) else eval_cond_clojure(clauses, env)) # eval-cond-scheme eval_cond_scheme = lambda clauses, env: (NIL if sx_truthy(empty_p(clauses)) else (lambda clause: (lambda test: (lambda body: (body if sx_truthy((((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else'))) if sx_truthy(((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else')))) else ((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else')))) else (body if sx_truthy(trampoline(eval_expr(test, env))) else eval_cond_scheme(rest(clauses), env))))(nth(clause, 1)))(first(clause)))(first(clauses))) # eval-cond-clojure eval_cond_clojure = lambda clauses, env: (NIL if sx_truthy((len(clauses) < 2)) else (lambda test: (lambda body: (body if sx_truthy((((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else')) if sx_truthy(((type_of(test) == 'keyword') if not sx_truthy((type_of(test) == 'keyword')) else (keyword_name(test) == 'else'))) else ((type_of(test) == 'symbol') if not sx_truthy((type_of(test) == 'symbol')) else ((symbol_name(test) == 'else') if sx_truthy((symbol_name(test) == 'else')) else (symbol_name(test) == ':else'))))) else (body if sx_truthy(trampoline(eval_expr(test, env))) else eval_cond_clojure(slice(clauses, 2), env))))(nth(clauses, 1)))(first(clauses))) # process-bindings process_bindings = lambda bindings, env: (lambda local: _sx_begin(for_each(lambda pair: ((lambda name: _sx_dict_set(local, name, trampoline(eval_expr(nth(pair, 1), local))))((symbol_name(first(pair)) if sx_truthy((type_of(first(pair)) == 'symbol')) else sx_str(first(pair)))) if sx_truthy(((type_of(pair) == 'list') if not sx_truthy((type_of(pair) == 'list')) else (len(pair) >= 2))) else NIL), bindings), local))(merge(env)) # is-render-expr? is_render_expr = lambda expr: (False if sx_truthy(((not sx_truthy((type_of(expr) == 'list'))) if sx_truthy((not sx_truthy((type_of(expr) == 'list')))) else empty_p(expr))) else (lambda h: (False if sx_truthy((not sx_truthy((type_of(h) == 'symbol')))) else (lambda n: ((n == '<>') if sx_truthy((n == '<>')) else ((n == 'raw!') if sx_truthy((n == 'raw!')) else (starts_with_p(n, '~') if sx_truthy(starts_with_p(n, '~')) else (starts_with_p(n, 'html:') if sx_truthy(starts_with_p(n, 'html:')) else (contains_p(HTML_TAGS, n) if sx_truthy(contains_p(HTML_TAGS, n)) else ((index_of(n, '-') > 0) if not sx_truthy((index_of(n, '-') > 0)) else ((len(expr) > 1) if not sx_truthy((len(expr) > 1)) else (type_of(nth(expr, 1)) == 'keyword')))))))))(symbol_name(h))))(first(expr))) # === Transpiled from adapter-html === # render-to-html render_to_html = lambda expr, env: _sx_case(type_of(expr), [('nil', lambda: ''), ('string', lambda: escape_html(expr)), ('number', lambda: sx_str(expr)), ('boolean', lambda: ('true' if sx_truthy(expr) else 'false')), ('list', lambda: ('' if sx_truthy(empty_p(expr)) else render_list_to_html(expr, env))), ('symbol', lambda: render_value_to_html(trampoline(eval_expr(expr, env)), env)), ('keyword', lambda: escape_html(keyword_name(expr))), ('raw-html', lambda: raw_html_content(expr)), (None, lambda: render_value_to_html(trampoline(eval_expr(expr, env)), env))]) # render-value-to-html render_value_to_html = lambda val, env: _sx_case(type_of(val), [('nil', lambda: ''), ('string', lambda: escape_html(val)), ('number', lambda: sx_str(val)), ('boolean', lambda: ('true' if sx_truthy(val) else 'false')), ('list', lambda: render_list_to_html(val, env)), ('raw-html', lambda: raw_html_content(val)), (None, lambda: escape_html(sx_str(val)))]) # RENDER_HTML_FORMS RENDER_HTML_FORMS = ['if', 'when', 'cond', 'case', 'let', 'let*', 'begin', 'do', 'define', 'defcomp', 'defisland', 'defmacro', 'defstyle', 'defhandler', 'map', 'map-indexed', 'filter', 'for-each'] # render-html-form? is_render_html_form = lambda name: contains_p(RENDER_HTML_FORMS, name) # render-list-to-html render_list_to_html = lambda expr, env: ('' if sx_truthy(empty_p(expr)) else (lambda head: (join('', map(lambda x: render_value_to_html(x, env), expr)) if sx_truthy((not sx_truthy((type_of(head) == 'symbol')))) else (lambda name: (lambda args: (join('', map(lambda x: render_to_html(x, env), args)) if sx_truthy((name == '<>')) else (join('', map(lambda x: sx_str(trampoline(eval_expr(x, env))), args)) if sx_truthy((name == 'raw!')) else (render_html_element(name, args, env) if sx_truthy(contains_p(HTML_TAGS, name)) else (render_html_island(env_get(env, name), args, env) if sx_truthy((starts_with_p(name, '~') if not sx_truthy(starts_with_p(name, '~')) else (env_has(env, name) if not sx_truthy(env_has(env, name)) else is_island(env_get(env, name))))) else ((lambda val: (render_html_component(val, args, env) if sx_truthy(is_component(val)) else (render_to_html(expand_macro(val, args, env), env) if sx_truthy(is_macro(val)) else error(sx_str('Unknown component: ', name)))))(env_get(env, name)) if sx_truthy(starts_with_p(name, '~')) else (dispatch_html_form(name, expr, env) if sx_truthy(is_render_html_form(name)) else (render_to_html(expand_macro(env_get(env, name), args, env), env) if sx_truthy((env_has(env, name) if not sx_truthy(env_has(env, name)) else is_macro(env_get(env, name)))) else render_value_to_html(trampoline(eval_expr(expr, env)), env)))))))))(rest(expr)))(symbol_name(head))))(first(expr))) # dispatch-html-form dispatch_html_form = lambda name, expr, env: ((lambda cond_val: (render_to_html(nth(expr, 2), env) if sx_truthy(cond_val) else (render_to_html(nth(expr, 3), env) if sx_truthy((len(expr) > 3)) else '')))(trampoline(eval_expr(nth(expr, 1), env))) if sx_truthy((name == 'if')) else (('' if sx_truthy((not sx_truthy(trampoline(eval_expr(nth(expr, 1), env))))) else join('', map(lambda i: render_to_html(nth(expr, i), env), range(2, len(expr))))) if sx_truthy((name == 'when')) else ((lambda branch: (render_to_html(branch, env) if sx_truthy(branch) else ''))(eval_cond(rest(expr), env)) if sx_truthy((name == 'cond')) else (render_to_html(trampoline(eval_expr(expr, env)), env) if sx_truthy((name == 'case')) else ((lambda local: join('', map(lambda i: render_to_html(nth(expr, i), local), range(2, len(expr)))))(process_bindings(nth(expr, 1), env)) if sx_truthy(((name == 'let') if sx_truthy((name == 'let')) else (name == 'let*'))) else (join('', map(lambda i: render_to_html(nth(expr, i), env), range(1, len(expr)))) if sx_truthy(((name == 'begin') if sx_truthy((name == 'begin')) else (name == 'do'))) else (_sx_begin(trampoline(eval_expr(expr, env)), '') if sx_truthy(is_definition_form(name)) else ((lambda f: (lambda coll: join('', map(lambda item: (render_lambda_html(f, [item], env) if sx_truthy(is_lambda(f)) else render_to_html(apply(f, [item]), env)), coll)))(trampoline(eval_expr(nth(expr, 2), env))))(trampoline(eval_expr(nth(expr, 1), env))) if sx_truthy((name == 'map')) else ((lambda f: (lambda coll: join('', map_indexed(lambda i, item: (render_lambda_html(f, [i, item], env) if sx_truthy(is_lambda(f)) else render_to_html(apply(f, [i, item]), env)), coll)))(trampoline(eval_expr(nth(expr, 2), env))))(trampoline(eval_expr(nth(expr, 1), env))) if sx_truthy((name == 'map-indexed')) else (render_to_html(trampoline(eval_expr(expr, env)), env) if sx_truthy((name == 'filter')) else ((lambda f: (lambda coll: join('', map(lambda item: (render_lambda_html(f, [item], env) if sx_truthy(is_lambda(f)) else render_to_html(apply(f, [item]), env)), coll)))(trampoline(eval_expr(nth(expr, 2), env))))(trampoline(eval_expr(nth(expr, 1), env))) if sx_truthy((name == 'for-each')) else render_value_to_html(trampoline(eval_expr(expr, env)), env)))))))))))) # render-lambda-html render_lambda_html = lambda f, args, env: (lambda local: _sx_begin(for_each_indexed(lambda i, p: _sx_dict_set(local, p, nth(args, i)), lambda_params(f)), render_to_html(lambda_body(f), local)))(env_merge(lambda_closure(f), env)) # render-html-component render_html_component = lambda comp, args, env: (lambda kwargs: (lambda children: _sx_begin(reduce(lambda state, arg: (lambda skip: (assoc(state, 'skip', False, 'i', (get(state, 'i') + 1)) if sx_truthy(skip) else ((lambda val: _sx_begin(_sx_dict_set(kwargs, keyword_name(arg), val), assoc(state, 'skip', True, 'i', (get(state, 'i') + 1))))(trampoline(eval_expr(nth(args, (get(state, 'i') + 1)), env))) if sx_truthy(((type_of(arg) == 'keyword') if not sx_truthy((type_of(arg) == 'keyword')) else ((get(state, 'i') + 1) < len(args)))) else _sx_begin(_sx_append(children, arg), assoc(state, 'i', (get(state, 'i') + 1))))))(get(state, 'skip')), {'i': 0, 'skip': False}, args), (lambda local: _sx_begin(for_each(lambda p: _sx_dict_set(local, p, (dict_get(kwargs, p) if sx_truthy(dict_has(kwargs, p)) else NIL)), component_params(comp)), (_sx_dict_set(local, 'children', make_raw_html(join('', map(lambda c: render_to_html(c, env), children)))) if sx_truthy(component_has_children(comp)) else NIL), render_to_html(component_body(comp), local)))(env_merge(component_closure(comp), env))))([]))({}) # render-html-element render_html_element = lambda tag, args, env: (lambda parsed: (lambda attrs: (lambda children: (lambda is_void: sx_str('<', tag, render_attrs(attrs), (' />' if sx_truthy(is_void) else sx_str('>', join('', map(lambda c: render_to_html(c, env), children)), '', tag, '>'))))(contains_p(VOID_ELEMENTS, tag)))(nth(parsed, 1)))(first(parsed)))(parse_element_args(args, env)) # render-html-island render_html_island = lambda island, args, env: (lambda kwargs: (lambda children: _sx_begin(reduce(lambda state, arg: (lambda skip: (assoc(state, 'skip', False, 'i', (get(state, 'i') + 1)) if sx_truthy(skip) else ((lambda val: _sx_begin(_sx_dict_set(kwargs, keyword_name(arg), val), assoc(state, 'skip', True, 'i', (get(state, 'i') + 1))))(trampoline(eval_expr(nth(args, (get(state, 'i') + 1)), env))) if sx_truthy(((type_of(arg) == 'keyword') if not sx_truthy((type_of(arg) == 'keyword')) else ((get(state, 'i') + 1) < len(args)))) else _sx_begin(_sx_append(children, arg), assoc(state, 'i', (get(state, 'i') + 1))))))(get(state, 'skip')), {'i': 0, 'skip': False}, args), (lambda local: (lambda island_name: _sx_begin(for_each(lambda p: _sx_dict_set(local, p, (dict_get(kwargs, p) if sx_truthy(dict_has(kwargs, p)) else NIL)), component_params(island)), (_sx_dict_set(local, 'children', make_raw_html(join('', map(lambda c: render_to_html(c, env), children)))) if sx_truthy(component_has_children(island)) else NIL), (lambda body_html: (lambda state_json: sx_str('