Add modular primitive libraries and fix Symbol class compatibility
- Add primitive_libs/ with modular primitive loading (core, math, image, color, color_ops, filters, geometry, drawing, blending, arrays, ascii) - Effects now explicitly declare dependencies via (require-primitives "...") - Convert ascii-fx-zone from hardcoded special form to loadable primitive - Add _is_symbol/_is_keyword helpers for duck typing to support both sexp_effects.parser.Symbol and artdag.sexp.parser.Symbol classes - Auto-inject _interp and _env for primitives that need them - Remove silent error swallowing in cell_effect evaluation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
164
sexp_effects/primitive_libs/core.py
Normal file
164
sexp_effects/primitive_libs/core.py
Normal file
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Core Primitives - Always available, minimal essential set.
|
||||
|
||||
These are the primitives that form the foundation of the language.
|
||||
They cannot be overridden by libraries.
|
||||
"""
|
||||
|
||||
|
||||
# Arithmetic
|
||||
def prim_add(*args):
|
||||
if len(args) == 0:
|
||||
return 0
|
||||
result = args[0]
|
||||
for arg in args[1:]:
|
||||
result = result + arg
|
||||
return result
|
||||
|
||||
|
||||
def prim_sub(a, b=None):
|
||||
if b is None:
|
||||
return -a
|
||||
return a - b
|
||||
|
||||
|
||||
def prim_mul(*args):
|
||||
if len(args) == 0:
|
||||
return 1
|
||||
result = args[0]
|
||||
for arg in args[1:]:
|
||||
result = result * arg
|
||||
return result
|
||||
|
||||
|
||||
def prim_div(a, b):
|
||||
return a / b
|
||||
|
||||
|
||||
def prim_mod(a, b):
|
||||
return a % b
|
||||
|
||||
|
||||
# Comparison
|
||||
def prim_lt(a, b):
|
||||
return a < b
|
||||
|
||||
|
||||
def prim_gt(a, b):
|
||||
return a > b
|
||||
|
||||
|
||||
def prim_le(a, b):
|
||||
return a <= b
|
||||
|
||||
|
||||
def prim_ge(a, b):
|
||||
return a >= b
|
||||
|
||||
|
||||
def prim_eq(a, b):
|
||||
if isinstance(a, float) or isinstance(b, float):
|
||||
return abs(a - b) < 1e-9
|
||||
return a == b
|
||||
|
||||
|
||||
def prim_ne(a, b):
|
||||
return not prim_eq(a, b)
|
||||
|
||||
|
||||
# Logic
|
||||
def prim_not(x):
|
||||
return not x
|
||||
|
||||
|
||||
def prim_and(*args):
|
||||
for a in args:
|
||||
if not a:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def prim_or(*args):
|
||||
for a in args:
|
||||
if a:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Basic data access
|
||||
def prim_get(obj, key, default=None):
|
||||
"""Get value from dict or list."""
|
||||
if isinstance(obj, dict):
|
||||
return obj.get(key, default)
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
try:
|
||||
return obj[int(key)]
|
||||
except (IndexError, ValueError):
|
||||
return default
|
||||
return default
|
||||
|
||||
|
||||
def prim_length(seq):
|
||||
return len(seq)
|
||||
|
||||
|
||||
def prim_list(*args):
|
||||
return list(args)
|
||||
|
||||
|
||||
# Type checking
|
||||
def prim_is_number(x):
|
||||
return isinstance(x, (int, float))
|
||||
|
||||
|
||||
def prim_is_string(x):
|
||||
return isinstance(x, str)
|
||||
|
||||
|
||||
def prim_is_list(x):
|
||||
return isinstance(x, (list, tuple))
|
||||
|
||||
|
||||
def prim_is_dict(x):
|
||||
return isinstance(x, dict)
|
||||
|
||||
|
||||
def prim_is_nil(x):
|
||||
return x is None
|
||||
|
||||
|
||||
# Core primitives dict
|
||||
PRIMITIVES = {
|
||||
# Arithmetic
|
||||
'+': prim_add,
|
||||
'-': prim_sub,
|
||||
'*': prim_mul,
|
||||
'/': prim_div,
|
||||
'mod': prim_mod,
|
||||
|
||||
# Comparison
|
||||
'<': prim_lt,
|
||||
'>': prim_gt,
|
||||
'<=': prim_le,
|
||||
'>=': prim_ge,
|
||||
'=': prim_eq,
|
||||
'!=': prim_ne,
|
||||
|
||||
# Logic
|
||||
'not': prim_not,
|
||||
'and': prim_and,
|
||||
'or': prim_or,
|
||||
|
||||
# Data access
|
||||
'get': prim_get,
|
||||
'length': prim_length,
|
||||
'len': prim_length,
|
||||
'list': prim_list,
|
||||
|
||||
# Type predicates
|
||||
'number?': prim_is_number,
|
||||
'string?': prim_is_string,
|
||||
'list?': prim_is_list,
|
||||
'dict?': prim_is_dict,
|
||||
'nil?': prim_is_nil,
|
||||
}
|
||||
Reference in New Issue
Block a user