Monorepo for Aesthetic.Computer
aesthetic.computer
1# KidLisp Integration with Aesthetic Computer Painting API
2
3## Executive Summary
4
5This document outlines a comprehensive plan to integrate kidlisp support into the aesthetic computer's common painting API. The goal is to enable a new `kidlisp()` function that creates isolated kidlisp rendering contexts within normal JavaScript pieces, allowing for dynamic lisp-based graphics generation.
6
7## Current Architecture Analysis
8
9### 1. KidLisp System (`/lib/kidlisp.mjs`)
10
11**Core Components:**
12- `KidLisp` class: Main interpreter with environment management
13- Global environment with painting commands (`ink`, `wipe`, `line`, `box`, etc.)
14- Embedded layer system with buffer isolation
15- Performance optimizations and caching
16- Source code compilation and evaluation
17
18**Key Features:**
19- Multiple environment support with `getGlobalEnv()`
20- Embedded buffer rendering via `createEmbeddedLayerFromSource()`
21- API wrapping with buffer switching via `page()` function
22- Color processing and graphic primitives
23- Isolation through separate `kidlispInstance` per layer
24
25### 2. Common Painting API (`/lib/disk.mjs`)
26
27**Core Components:**
28- `$commonApi`: Main API object with all system functions
29- `$paintApi`: Core painting functions (`write`, `form`, etc.)
30- `$paintApiUnwrapped`: Direct graphics functions (`ink`, `wipe`, `line`, etc.)
31- `Painting` class: Buffer management with `api.painting()` factory
32
33**Key Features:**
34- `painting(width, height, callback)`: Creates isolated paint buffers
35- `page(buffer)`: Switches active painting context
36- API composition with buffer-specific wrappers
37- Screen and buffer management through `$activePaintApi`
38
39### 3. Piece Structure (e.g., `wipppps.mjs`)
40
41**Interaction Pattern:**
42```javascript
43function paint({ wipe, ink, line, box, painting, page, paste, ... }) {
44 // Pieces receive destructured painting functions
45 // Functions operate on current active buffer
46}
47```
48
49## Implementation Plan
50
51### Phase 1: Core `kidlisp()` Function
52
53#### 1.1 Function Signature
54```javascript
55kidlisp(x, y, width, height, source, options = {})
56```
57
58**Parameters:**
59- `x, y`: Position to paste the kidlisp buffer
60- `width, height`: Dimensions of the kidlisp rendering buffer
61- `source`: KidLisp source code string
62- `options`: Configuration object
63
64#### 1.2 Integration Point
65Add to `$paintApiUnwrapped` in `/lib/disk.mjs`:
66
67```javascript
68const $paintApiUnwrapped = {
69 // ... existing functions
70 kidlisp: function(x, y, width, height, source, options = {}) {
71 return renderKidLispBuffer(x, y, width, height, source, options);
72 }
73};
74```
75
76### Phase 2: KidLisp Buffer Manager
77
78#### 2.1 Buffer Creation and Isolation
79
80```javascript
81function renderKidLispBuffer(x, y, width, height, source, options = {}) {
82 // 1. Create isolated kidlisp instance
83 const kidlispInstance = new KidLisp();
84
85 // 2. Create isolated painting buffer
86 const kidlispBuffer = $activePaintApi.painting(width, height, (bufferApi) => {
87 // 3. Create wrapped API for kidlisp
88 const kidlispAPI = createKidLispAPIWrapper(bufferApi, options);
89
90 // 4. Execute kidlisp code in isolated context
91 try {
92 const parsedCode = kidlispInstance.parse(source);
93 kidlispInstance.evaluate(parsedCode, kidlispAPI, kidlispInstance.getGlobalEnv());
94 } catch (error) {
95 console.error('KidLisp execution error:', error);
96 // Render error message in buffer
97 bufferApi.wipe(64, 0, 0); // Dark red background
98 bufferApi.ink(255, 255, 255).write('ERROR', 10, 10);
99 }
100 });
101
102 // 5. Paste buffer to main canvas
103 $activePaintApi.paste(kidlispBuffer, x, y);
104
105 return kidlispBuffer; // Allow for further manipulation
106}
107```
108
109#### 2.2 API Wrapper Creation
110
111```javascript
112function createKidLispAPIWrapper(bufferApi, options = {}) {
113 const kidlispEnv = new KidLisp().getGlobalEnv();
114
115 // Merge buffer API with kidlisp environment
116 const wrappedAPI = {
117 // Core graphics from buffer API
118 ...bufferApi,
119
120 // KidLisp-specific commands
121 ...kidlispEnv,
122
123 // Screen context (bounded to kidlisp buffer)
124 screen: {
125 width: bufferApi.screen?.width || 256,
126 height: bufferApi.screen?.height || 256,
127 pixels: bufferApi.screen?.pixels
128 },
129
130 // Restricted API (no system access)
131 system: undefined,
132 net: undefined,
133
134 // Configurable options
135 ...options.additionalAPI
136 };
137
138 return wrappedAPI;
139}
140```
141
142### Phase 3: Enhanced Features
143
144#### 3.1 Caching System
145```javascript
146const kidlispCache = new Map();
147
148function getCachedKidLispResult(source, width, height) {
149 const cacheKey = `${source}-${width}x${height}`;
150 return kidlispCache.get(cacheKey);
151}
152
153function setCachedKidLispResult(source, width, height, buffer) {
154 const cacheKey = `${source}-${width}x${height}`;
155 kidlispCache.set(cacheKey, buffer);
156}
157```
158
159#### 3.2 Animation Support
160```javascript
161kidlisp(x, y, width, height, source, {
162 frame: paintCount, // Pass frame number for animations
163 time: performance.now(), // Pass time for time-based effects
164 animated: true // Enable per-frame evaluation
165});
166```
167
168#### 3.3 Error Handling and Debugging
169```javascript
170kidlisp(x, y, width, height, source, {
171 debug: true, // Show debug info
172 errorMode: 'visual', // 'visual', 'console', 'silent'
173 fallback: '(wipe red)' // Fallback code on error
174});
175```
176
177### Phase 4: Performance Optimizations
178
179#### 4.1 Lazy Evaluation
180- Only recompile kidlisp when source changes
181- Cache parsed AST for repeated calls
182- Implement dirty checking for animated content
183
184#### 4.2 Buffer Pooling
185```javascript
186const bufferPool = [];
187
188function getPooledBuffer(width, height) {
189 const existing = bufferPool.find(b => b.width === width && b.height === height);
190 if (existing) {
191 bufferPool.splice(bufferPool.indexOf(existing), 1);
192 // Clear buffer for reuse
193 existing.api.wipe(0, 0, 0, 0);
194 return existing;
195 }
196 return createNewBuffer(width, height);
197}
198```
199
200#### 4.3 Selective Rendering
201```javascript
202kidlisp(x, y, width, height, source, {
203 renderWhen: (frame) => frame % 10 === 0, // Only render every 10th frame
204 staticCache: true // Cache static content
205});
206```
207
208## Implementation Sequence
209
210### Step 1: Basic Integration (Week 1)
2111. Add basic `kidlisp()` function to `$paintApiUnwrapped`
2122. Implement `renderKidLispBuffer()` with minimal features
2133. Create `createKidLispAPIWrapper()` for API isolation
2144. Test with simple kidlisp programs: `(wipe blue)`, `(ink red) (box 10 10 50 50)`
215
216### Step 2: Buffer Management (Week 2)
2171. Implement proper buffer isolation using existing `painting()` system
2182. Add error handling and visual error reporting
2193. Test buffer compositing and transparency
2204. Validate API isolation (no system access from kidlisp context)
221
222### Step 3: Advanced Features (Week 3)
2231. Add caching system for performance
2242. Implement animation support with frame/time parameters
2253. Add debugging and error visualization options
2264. Performance profiling and optimization
227
228### Step 4: Integration Testing (Week 4)
2291. Test with complex kidlisp programs
2302. Validate integration with existing pieces like `wipppps.mjs`
2313. Performance testing with multiple concurrent kidlisp buffers
2324. Memory leak detection and cleanup
233
234## Usage Examples
235
236### Basic Usage
237```javascript
238// In any aesthetic computer piece
239function paint({ kidlisp, ... }) {
240 // Simple static kidlisp graphic
241 kidlisp(100, 100, 64, 64, '(wipe blue) (ink yellow) (box 10 10 40 40)');
242}
243```
244
245### Animation
246```javascript
247function paint({ kidlisp, paintCount, ... }) {
248 // Animated kidlisp content
249 kidlisp(0, 0, 256, 256, `
250 (wipe black)
251 (ink rainbow)
252 (def t ${paintCount})
253 (circle (+ 128 (* 50 (cos (* t 0.1)))) 128 20)
254 `, { frame: paintCount });
255}
256```
257
258### Multiple Buffers
259```javascript
260function paint({ kidlisp, ... }) {
261 // Background layer
262 kidlisp(0, 0, screen.width, screen.height, '(wipe "fade:blue-purple")');
263
264 // Foreground elements
265 kidlisp(50, 50, 100, 100, '(ink white) (circle 50 50 30)');
266 kidlisp(200, 50, 100, 100, '(ink red) (box 0 0 100 100)');
267}
268```
269
270## Technical Considerations
271
272### Security
273- KidLisp contexts must be isolated from system APIs
274- No access to `net`, `system`, `store`, or other sensitive functions
275- File system access restrictions
276
277### Performance
278- Buffer creation overhead mitigation through pooling
279- Smart caching based on source code and parameters
280- Frame-rate-aware rendering for animations
281
282### Memory Management
283- Automatic cleanup of unused buffers
284- Garbage collection integration
285- Memory usage monitoring and limits
286
287### Compatibility
288- Maintain backward compatibility with existing pieces
289- No breaking changes to current painting API
290- Progressive enhancement model
291
292## TODO Progress Tracking
293
294### Current Sprint: Basic Prototype Testing ✅ STARTED
295- [x] Create kidlisp-in-js.mjs based on blank.mjs template
296- [x] Add KidLisp import and initialization
297- [x] Implement basic kidlispBasic() prototype function
298- [x] Add buffer creation with kidlisp evaluation
299- [ ] Test the piece in browser and debug any issues
300- [ ] Validate kidlisp parsing and evaluation works
301- [ ] Test API isolation and error boundaries
302- [ ] Confirm painting buffer integration works
303
304### Next Sprint: Core Functionality
305- [ ] Refine kidlisp() function signature and behavior
306- [ ] Add proper error handling and visual feedback
307- [ ] Implement buffer caching for performance
308- [ ] Test complex kidlisp programs and graphics
309- [ ] Validate memory management and cleanup
310- [ ] Performance profiling and optimization
311
312### Future Sprints: Production Integration
313- [ ] Integrate kidlisp() into common API (disk.mjs)
314- [ ] Add to $paintApiUnwrapped for all pieces
315- [ ] Documentation and examples
316- [ ] Integration testing across multiple pieces
317- [ ] Performance benchmarks and optimization
318
319## Implementation Notes
320
321### Phase Status
322- **Phase 1: Basic Prototype** - ✅ IN PROGRESS
323- **Phase 2: API Integration** - ⏳ PENDING
324- **Phase 3: Production Implementation** - ⏳ PLANNED
325
326### Current Prototype: kidlisp-in-js.mjs
327Created a test piece that:
328- Imports KidLisp class from ../lib/kidlisp.mjs
329- Initializes kidlisp instance in boot()
330- Tests buffer creation with kidlisp evaluation
331- Implements prototype kidlispBasic() function
332- Includes error handling and visual feedback
333
334Ready to test in browser and iterate on the implementation!
335
336## Future Enhancements
337
3381. **Interactive KidLisp**: Mouse/touch event forwarding to kidlisp buffers
3392. **3D KidLisp**: Integration with form system for 3D graphics
3403. **Network KidLisp**: Remote kidlisp code execution and sharing
3414. **KidLisp Compiler**: AOT compilation for performance-critical applications
3425. **Visual KidLisp Editor**: In-browser code editor with live preview
343
344This integration would provide a powerful way to embed dynamic, programmable graphics within aesthetic computer pieces while maintaining isolation and performance.