Merge branch 'worktree-api-urls' into macros
This commit is contained in:
@@ -775,6 +775,7 @@
|
||||
|
||||
(define-async async-aser-fragment :effects [render io]
|
||||
(fn ((children :as list) (env :as dict) ctx)
|
||||
;; Spreads are filtered — fragments have no parent element to merge into
|
||||
(let ((parts (list)))
|
||||
(for-each
|
||||
(fn (c)
|
||||
@@ -782,10 +783,10 @@
|
||||
(if (= (type-of result) "list")
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(when (and (not (nil? item)) (not (spread? item)))
|
||||
(append! parts (serialize item))))
|
||||
result)
|
||||
(when (not (nil? result))
|
||||
(when (and (not (nil? result)) (not (spread? result)))
|
||||
(append! parts (serialize result))))))
|
||||
children)
|
||||
(if (empty? parts)
|
||||
@@ -885,13 +886,21 @@
|
||||
(set! i (inc i)))
|
||||
(let ((result (async-aser arg env ctx)))
|
||||
(when (not (nil? result))
|
||||
(if (= (type-of result) "list")
|
||||
(if (spread? result)
|
||||
;; Spread child — merge attrs as keyword args into parent element
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(append! parts (serialize item))))
|
||||
result)
|
||||
(append! parts (serialize result))))
|
||||
(fn (k)
|
||||
(let ((v (dict-get (spread-attrs result) k)))
|
||||
(append! parts (str ":" k))
|
||||
(append! parts (serialize v))))
|
||||
(keys (spread-attrs result)))
|
||||
(if (= (type-of result) "list")
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(append! parts (serialize item))))
|
||||
result)
|
||||
(append! parts (serialize result)))))
|
||||
(set! i (inc i))))))
|
||||
args)
|
||||
(when token (svg-context-reset! token))
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
(fn ((children :as list) (env :as dict))
|
||||
;; Serialize (<> child1 child2 ...) to sx source string
|
||||
;; Must flatten list results (e.g. from map/filter) to avoid nested parens
|
||||
;; Spreads are filtered — fragments have no parent element to merge into
|
||||
(let ((parts (list)))
|
||||
(for-each
|
||||
(fn (c)
|
||||
@@ -117,10 +118,10 @@
|
||||
(if (= (type-of result) "list")
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(when (and (not (nil? item)) (not (spread? item)))
|
||||
(append! parts (serialize item))))
|
||||
result)
|
||||
(when (not (nil? result))
|
||||
(when (and (not (nil? result)) (not (spread? result)))
|
||||
(append! parts (serialize result))))))
|
||||
children)
|
||||
(if (empty? parts)
|
||||
@@ -151,13 +152,21 @@
|
||||
(set! i (inc i)))
|
||||
(let ((val (aser arg env)))
|
||||
(when (not (nil? val))
|
||||
(if (= (type-of val) "list")
|
||||
(if (spread? val)
|
||||
;; Spread child — merge attrs as keyword args into parent element
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(append! parts (serialize item))))
|
||||
val)
|
||||
(append! parts (serialize val))))
|
||||
(fn (k)
|
||||
(let ((v (dict-get (spread-attrs val) k)))
|
||||
(append! parts (str ":" k))
|
||||
(append! parts (serialize v))))
|
||||
(keys (spread-attrs val)))
|
||||
(if (= (type-of val) "list")
|
||||
(for-each
|
||||
(fn (item)
|
||||
(when (not (nil? item))
|
||||
(append! parts (serialize item))))
|
||||
val)
|
||||
(append! parts (serialize val)))))
|
||||
(set! i (inc i))))))
|
||||
args)
|
||||
(str "(" (join " " parts) ")"))))
|
||||
|
||||
@@ -366,6 +366,7 @@
|
||||
"list" (str "(" (join " " (map sx-serialize val)) ")")
|
||||
"dict" (sx-serialize-dict val)
|
||||
"sx-expr" (sx-expr-source val)
|
||||
"spread" (str "(make-spread " (sx-serialize-dict (spread-attrs val)) ")")
|
||||
:else (str val))))
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# WARNING: special-forms.sx declares forms not in eval.sx: reset, shift
|
||||
# WARNING: eval.sx dispatches forms not in special-forms.sx: form?, provide
|
||||
"""
|
||||
sx_ref.py -- Generated from reference SX evaluator specification.
|
||||
|
||||
@@ -2559,10 +2561,10 @@ def aser_fragment(children, env):
|
||||
result = aser(c, env)
|
||||
if sx_truthy((type_of(result) == 'list')):
|
||||
for item in result:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
if sx_truthy(((not sx_truthy(is_nil(item))) if not sx_truthy((not sx_truthy(is_nil(item)))) else (not sx_truthy(is_spread(item))))):
|
||||
parts.append(serialize(item))
|
||||
else:
|
||||
if sx_truthy((not sx_truthy(is_nil(result)))):
|
||||
if sx_truthy(((not sx_truthy(is_nil(result))) if not sx_truthy((not sx_truthy(is_nil(result)))) else (not sx_truthy(is_spread(result))))):
|
||||
parts.append(serialize(result))
|
||||
if sx_truthy(empty_p(parts)):
|
||||
return ''
|
||||
@@ -2590,12 +2592,18 @@ def aser_call(name, args, env):
|
||||
else:
|
||||
val = aser(arg, env)
|
||||
if sx_truthy((not sx_truthy(is_nil(val)))):
|
||||
if sx_truthy((type_of(val) == 'list')):
|
||||
for item in val:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
parts.append(serialize(item))
|
||||
if sx_truthy(is_spread(val)):
|
||||
for k in keys(spread_attrs(val)):
|
||||
v = dict_get(spread_attrs(val), k)
|
||||
parts.append(sx_str(':', k))
|
||||
parts.append(serialize(v))
|
||||
else:
|
||||
parts.append(serialize(val))
|
||||
if sx_truthy((type_of(val) == 'list')):
|
||||
for item in val:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
parts.append(serialize(item))
|
||||
else:
|
||||
parts.append(serialize(val))
|
||||
_cells['i'] = (_cells['i'] + 1)
|
||||
return sx_str('(', join(' ', parts), ')')
|
||||
|
||||
@@ -4140,10 +4148,10 @@ async def async_aser_fragment(children, env, ctx):
|
||||
result = (await async_aser(c, env, ctx))
|
||||
if sx_truthy((type_of(result) == 'list')):
|
||||
for item in result:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
if sx_truthy(((not sx_truthy(is_nil(item))) if not sx_truthy((not sx_truthy(is_nil(item)))) else (not sx_truthy(is_spread(item))))):
|
||||
parts.append(serialize(item))
|
||||
else:
|
||||
if sx_truthy((not sx_truthy(is_nil(result)))):
|
||||
if sx_truthy(((not sx_truthy(is_nil(result))) if not sx_truthy((not sx_truthy(is_nil(result)))) else (not sx_truthy(is_spread(result))))):
|
||||
parts.append(serialize(result))
|
||||
if sx_truthy(empty_p(parts)):
|
||||
return make_sx_expr('')
|
||||
@@ -4225,12 +4233,18 @@ async def async_aser_call(name, args, env, ctx):
|
||||
else:
|
||||
result = (await async_aser(arg, env, ctx))
|
||||
if sx_truthy((not sx_truthy(is_nil(result)))):
|
||||
if sx_truthy((type_of(result) == 'list')):
|
||||
for item in result:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
parts.append(serialize(item))
|
||||
if sx_truthy(is_spread(result)):
|
||||
for k in keys(spread_attrs(result)):
|
||||
v = dict_get(spread_attrs(result), k)
|
||||
parts.append(sx_str(':', k))
|
||||
parts.append(serialize(v))
|
||||
else:
|
||||
parts.append(serialize(result))
|
||||
if sx_truthy((type_of(result) == 'list')):
|
||||
for item in result:
|
||||
if sx_truthy((not sx_truthy(is_nil(item)))):
|
||||
parts.append(serialize(item))
|
||||
else:
|
||||
parts.append(serialize(result))
|
||||
_cells['i'] = (_cells['i'] + 1)
|
||||
if sx_truthy(token):
|
||||
svg_context_reset(token)
|
||||
|
||||
@@ -270,3 +270,21 @@
|
||||
(deftest "or returns last falsy"
|
||||
(assert-equal "false"
|
||||
(render-sx "(or false false)"))))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Spread serialization
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(defsuite "aser-spreads"
|
||||
(deftest "spread in element merges attrs"
|
||||
(assert-equal "(div :class \"card\" \"hello\")"
|
||||
(render-sx "(div (make-spread {:class \"card\"}) \"hello\")")))
|
||||
|
||||
(deftest "multiple spreads merge into element"
|
||||
(assert-equal "(div :class \"card\" :style \"color:red\" \"hello\")"
|
||||
(render-sx "(div (make-spread {:class \"card\"}) (make-spread {:style \"color:red\"}) \"hello\")")))
|
||||
|
||||
(deftest "spread in fragment is filtered"
|
||||
(assert-equal "(<> \"hello\")"
|
||||
(render-sx "(<> (make-spread {:class \"card\"}) \"hello\")"))))
|
||||
|
||||
Reference in New Issue
Block a user