Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 344 lines 11 kB view raw view rendered
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.