|
|
|
|
@@ -1,12 +1,10 @@
|
|
|
|
|
# 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
|
|
|
|
|
DO NOT EDIT -- regenerate with: python run_py_sx.py
|
|
|
|
|
"""
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
@@ -485,11 +483,25 @@ def is_render_expr(expr):
|
|
|
|
|
# Render dispatch -- set by adapter
|
|
|
|
|
_render_expr_fn = None
|
|
|
|
|
|
|
|
|
|
# Render mode flag -- set by render-to-html/aser, checked by eval-list
|
|
|
|
|
# When false, render expressions (HTML tags, components) fall through to eval-call
|
|
|
|
|
_render_mode = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def render_active_p():
|
|
|
|
|
return _render_mode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_render_active_b(val):
|
|
|
|
|
global _render_mode
|
|
|
|
|
_render_mode = bool(val)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def render_expr(expr, env):
|
|
|
|
|
if _render_expr_fn:
|
|
|
|
|
return _render_expr_fn(expr, env)
|
|
|
|
|
return expr
|
|
|
|
|
# No adapter — fall through to eval_call so components still evaluate
|
|
|
|
|
return eval_call(first(expr), rest(expr), env)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def strip_prefix(s, prefix):
|
|
|
|
|
@@ -711,12 +723,12 @@ 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["join"] = lambda sep, coll: sep.join(str(x) for x in 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["slice"] = lambda c, a, b=None: c[int(a):] if (b is None or b is NIL) else c[int(a):int(b)]
|
|
|
|
|
PRIMITIVES["concat"] = lambda *args: _b_sum((a for a in args if a), [])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -939,7 +951,7 @@ trampoline = lambda val: (lambda result: (trampoline(eval_expr(thunk_expr(result
|
|
|
|
|
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_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((render_active_p() if not sx_truthy(render_active_p()) else 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)))
|
|
|
|
|
@@ -1186,7 +1198,10 @@ is_render_expr = lambda expr: (False if sx_truthy(((not sx_truthy((type_of(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_to_html = _sx_fn(lambda expr, env: (
|
|
|
|
|
set_render_active_b(True),
|
|
|
|
|
_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))])
|
|
|
|
|
)[-1])
|
|
|
|
|
|
|
|
|
|
# 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)))])
|
|
|
|
|
@@ -1243,7 +1258,10 @@ serialize_island_state = lambda kwargs: (NIL if sx_truthy(is_empty_dict(kwargs))
|
|
|
|
|
render_to_sx = lambda expr, env: (lambda result: (result if sx_truthy((type_of(result) == 'string')) else serialize(result)))(aser(expr, env))
|
|
|
|
|
|
|
|
|
|
# aser
|
|
|
|
|
aser = 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)), ('list', lambda: ([] if sx_truthy(empty_p(expr)) else aser_list(expr, env))), (None, lambda: expr)])
|
|
|
|
|
aser = _sx_fn(lambda expr, env: (
|
|
|
|
|
set_render_active_b(True),
|
|
|
|
|
_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)), ('list', lambda: ([] if sx_truthy(empty_p(expr)) else aser_list(expr, env))), (None, lambda: expr)])
|
|
|
|
|
)[-1])
|
|
|
|
|
|
|
|
|
|
# aser-list
|
|
|
|
|
aser_list = lambda expr, env: (lambda head: (lambda args: (map(lambda x: aser(x, env), expr) if sx_truthy((not sx_truthy((type_of(head) == 'symbol')))) else (lambda name: (aser_fragment(args, env) if sx_truthy((name == '<>')) else (aser_call(name, args, env) if sx_truthy(starts_with_p(name, '~')) else (aser_call(name, args, env) if sx_truthy((name == 'lake')) else (aser_call(name, args, env) if sx_truthy((name == 'marsh')) else (aser_call(name, args, env) if sx_truthy(contains_p(HTML_TAGS, name)) else (aser_special(name, expr, env) if sx_truthy((is_special_form(name) if sx_truthy(is_special_form(name)) else is_ho_form(name))) else (aser(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 (lambda f: (lambda evaled_args: (apply(f, evaled_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 (trampoline(call_lambda(f, evaled_args, env)) if sx_truthy(is_lambda(f)) else (aser_call(sx_str('~', component_name(f)), args, env) if sx_truthy(is_component(f)) else (aser_call(sx_str('~', component_name(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)))))))))))(symbol_name(head))))(rest(expr)))(first(expr))
|
|
|
|
|
@@ -1509,9 +1527,14 @@ def evaluate(expr, env=None):
|
|
|
|
|
|
|
|
|
|
def render(expr, env=None):
|
|
|
|
|
"""Render expr to HTML string."""
|
|
|
|
|
global _render_mode
|
|
|
|
|
if env is None:
|
|
|
|
|
env = {}
|
|
|
|
|
return render_to_html(expr, env)
|
|
|
|
|
try:
|
|
|
|
|
_render_mode = True
|
|
|
|
|
return render_to_html(expr, env)
|
|
|
|
|
finally:
|
|
|
|
|
_render_mode = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_env(**kwargs):
|
|
|
|
|
|