Fix aser list flattening bug, add wire format test suite (41 tests)
The sync aser-call in adapter-sx.sx didn't flatten list results from map/filter in positional children — serialize(list) wrapped in parens creating ((div ...) ...) which re-parses as an invalid call. Rewrote aser-call from reduce to for-each (bootstrapper can't nest for-each inside reduce lambdas) and added list flattening in both aser-call and aser-fragment. Also adds test-aser.sx (41 tests), render-sx platform function, expanded test-render.sx (+7 map/filter children tests), and specs async-eval-slot-inner in adapter-async.sx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2015,16 +2015,49 @@ def aser_list(expr, env):
|
||||
|
||||
# aser-fragment
|
||||
def aser_fragment(children, env):
|
||||
parts = filter(lambda x: (not sx_truthy(is_nil(x))), map(lambda c: aser(c, env), children))
|
||||
parts = []
|
||||
for c in children:
|
||||
result = aser(c, env)
|
||||
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:
|
||||
if sx_truthy((not sx_truthy(is_nil(result)))):
|
||||
parts.append(serialize(result))
|
||||
if sx_truthy(empty_p(parts)):
|
||||
return ''
|
||||
else:
|
||||
return sx_str('(<> ', join(' ', map(serialize, parts)), ')')
|
||||
return sx_str('(<> ', join(' ', parts), ')')
|
||||
|
||||
# aser-call
|
||||
def aser_call(name, args, env):
|
||||
_cells = {}
|
||||
parts = [name]
|
||||
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_begin(_sx_append(parts, sx_str(':', keyword_name(arg))), _sx_append(parts, serialize(val))) if sx_truthy((not sx_truthy(is_nil(val)))) else NIL), assoc(state, 'skip', True, 'i', (get(state, 'i') + 1))))(aser(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 (lambda val: _sx_begin((_sx_append(parts, serialize(val)) if sx_truthy((not sx_truthy(is_nil(val)))) else NIL), assoc(state, 'i', (get(state, 'i') + 1))))(aser(arg, env)))))(get(state, 'skip')), {'i': 0, 'skip': False}, args)
|
||||
_cells['skip'] = False
|
||||
_cells['i'] = 0
|
||||
for arg in args:
|
||||
if sx_truthy(_cells['skip']):
|
||||
_cells['skip'] = False
|
||||
_cells['i'] = (_cells['i'] + 1)
|
||||
else:
|
||||
if sx_truthy(((type_of(arg) == 'keyword') if not sx_truthy((type_of(arg) == 'keyword')) else ((_cells['i'] + 1) < len(args)))):
|
||||
val = aser(nth(args, (_cells['i'] + 1)), env)
|
||||
if sx_truthy((not sx_truthy(is_nil(val)))):
|
||||
parts.append(sx_str(':', keyword_name(arg)))
|
||||
parts.append(serialize(val))
|
||||
_cells['skip'] = True
|
||||
_cells['i'] = (_cells['i'] + 1)
|
||||
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))
|
||||
else:
|
||||
parts.append(serialize(val))
|
||||
_cells['i'] = (_cells['i'] + 1)
|
||||
return sx_str('(', join(' ', parts), ')')
|
||||
|
||||
# SPECIAL_FORM_NAMES
|
||||
@@ -2753,4 +2786,4 @@ def render(expr, env=None):
|
||||
|
||||
def make_env(**kwargs):
|
||||
"""Create an environment with initial bindings."""
|
||||
return _Env(dict(kwargs))
|
||||
return _Env(dict(kwargs))
|
||||
|
||||
Reference in New Issue
Block a user