Add (name :as type) annotation syntax for defcomp params
parse-comp-params now recognizes (name :as type) — a 3-element list with :as keyword separator. Type annotations are stored on the Component via component-param-types and used by types.sx for call-site checking. Unannotated params default to any. 428/428 tests pass (50 types tests including 6 annotation tests). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -266,6 +266,14 @@ def component_affinity(c):
|
||||
return getattr(c, 'affinity', 'auto')
|
||||
|
||||
|
||||
def component_param_types(c):
|
||||
return getattr(c, 'param_types', None)
|
||||
|
||||
|
||||
def component_set_param_types(c, d):
|
||||
c.param_types = d
|
||||
|
||||
|
||||
def macro_params(m):
|
||||
return m.params
|
||||
|
||||
@@ -1510,8 +1518,11 @@ def sf_defcomp(args, env):
|
||||
parsed = parse_comp_params(params_raw)
|
||||
params = first(parsed)
|
||||
has_children = nth(parsed, 1)
|
||||
param_types = nth(parsed, 2)
|
||||
affinity = defcomp_kwarg(args, 'affinity', 'auto')
|
||||
comp = make_component(comp_name, params, has_children, body, env, affinity)
|
||||
if sx_truthy(((not sx_truthy(is_nil(param_types))) if not sx_truthy((not sx_truthy(is_nil(param_types)))) else (not sx_truthy(empty_p(keys(param_types)))))):
|
||||
component_set_param_types(comp, param_types)
|
||||
env[symbol_name(name_sym)] = comp
|
||||
return comp
|
||||
|
||||
@@ -1530,24 +1541,33 @@ def defcomp_kwarg(args, key, default_):
|
||||
def parse_comp_params(params_expr):
|
||||
_cells = {}
|
||||
params = []
|
||||
param_types = {}
|
||||
_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']):
|
||||
if sx_truthy(((type_of(p) == 'list') if not sx_truthy((type_of(p) == 'list')) else ((len(p) == 3) if not sx_truthy((len(p) == 3)) else ((type_of(first(p)) == 'symbol') if not sx_truthy((type_of(first(p)) == 'symbol')) else ((type_of(nth(p, 1)) == 'keyword') if not sx_truthy((type_of(nth(p, 1)) == 'keyword')) else (keyword_name(nth(p, 1)) == 'as')))))):
|
||||
name = symbol_name(first(p))
|
||||
ptype = nth(p, 2)
|
||||
type_val = (symbol_name(ptype) if sx_truthy((type_of(ptype) == 'symbol')) else ptype)
|
||||
if sx_truthy((not sx_truthy(_cells['has_children']))):
|
||||
params.append(name)
|
||||
else:
|
||||
params.append(name)
|
||||
return [params, _cells['has_children']]
|
||||
param_types[name] = type_val
|
||||
else:
|
||||
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'], param_types]
|
||||
|
||||
# sf-defisland
|
||||
def sf_defisland(args, env):
|
||||
|
||||
Reference in New Issue
Block a user